@uniweb/scholar 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -1
- package/src/bibliography/formatters/index.js +62 -23
- package/src/bibliography/index.js +8 -29
- package/src/bibliography/normalize.js +234 -0
- package/src/bibliography/parsers/index.js +35 -1
- package/src/citations/Bibliography.jsx +26 -54
- package/src/citations/Citation.jsx +35 -145
- package/src/citations/CitationProvider.jsx +83 -85
- package/src/components/AuthorList.jsx +65 -40
- package/src/components/BibtexBlock.jsx +1 -1
- package/src/components/CiteButton.jsx +78 -45
- package/src/components/DoiLink.jsx +27 -21
- package/src/index.js +9 -3
- package/src/bibliography/formatters/apa.js +0 -352
- package/src/bibliography/formatters/chicago.js +0 -339
- package/src/bibliography/formatters/ieee.js +0 -332
- package/src/bibliography/formatters/mla.js +0 -335
- package/src/bibliography/parsers/bibtex.js +0 -405
- package/src/bibliography/utils/authors.js +0 -277
- package/src/bibliography/utils/dates.js +0 -228
- package/src/bibliography/utils/index.js +0 -8
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Date Formatting Utilities
|
|
3
|
-
*
|
|
4
|
-
* Functions for formatting dates in various citation styles.
|
|
5
|
-
*
|
|
6
|
-
* @module @uniweb/scholar/bibliography/utils/dates
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Month names for formatting
|
|
11
|
-
*/
|
|
12
|
-
const MONTHS_FULL = [
|
|
13
|
-
'January',
|
|
14
|
-
'February',
|
|
15
|
-
'March',
|
|
16
|
-
'April',
|
|
17
|
-
'May',
|
|
18
|
-
'June',
|
|
19
|
-
'July',
|
|
20
|
-
'August',
|
|
21
|
-
'September',
|
|
22
|
-
'October',
|
|
23
|
-
'November',
|
|
24
|
-
'December',
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
const MONTHS_SHORT = [
|
|
28
|
-
'Jan.',
|
|
29
|
-
'Feb.',
|
|
30
|
-
'Mar.',
|
|
31
|
-
'Apr.',
|
|
32
|
-
'May',
|
|
33
|
-
'June',
|
|
34
|
-
'July',
|
|
35
|
-
'Aug.',
|
|
36
|
-
'Sep.',
|
|
37
|
-
'Oct.',
|
|
38
|
-
'Nov.',
|
|
39
|
-
'Dec.',
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Parse a date from various formats
|
|
44
|
-
*
|
|
45
|
-
* @param {string|number|Date|Object} date - Date input
|
|
46
|
-
* @returns {{ year?: number, month?: number, day?: number }}
|
|
47
|
-
*/
|
|
48
|
-
export function parseDate(date) {
|
|
49
|
-
if (!date) return {}
|
|
50
|
-
|
|
51
|
-
// Already structured
|
|
52
|
-
if (typeof date === 'object' && !(date instanceof Date)) {
|
|
53
|
-
return {
|
|
54
|
-
year: date.year ?? date.Year,
|
|
55
|
-
month: date.month ?? date.Month,
|
|
56
|
-
day: date.day ?? date.Day,
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// JavaScript Date
|
|
61
|
-
if (date instanceof Date) {
|
|
62
|
-
return {
|
|
63
|
-
year: date.getFullYear(),
|
|
64
|
-
month: date.getMonth() + 1,
|
|
65
|
-
day: date.getDate(),
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Number (year only)
|
|
70
|
-
if (typeof date === 'number') {
|
|
71
|
-
return { year: date }
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// String parsing
|
|
75
|
-
const str = String(date).trim()
|
|
76
|
-
|
|
77
|
-
// ISO format: YYYY-MM-DD
|
|
78
|
-
const isoMatch = str.match(/^(\d{4})(?:-(\d{1,2})(?:-(\d{1,2}))?)?/)
|
|
79
|
-
if (isoMatch) {
|
|
80
|
-
return {
|
|
81
|
-
year: parseInt(isoMatch[1], 10),
|
|
82
|
-
month: isoMatch[2] ? parseInt(isoMatch[2], 10) : undefined,
|
|
83
|
-
day: isoMatch[3] ? parseInt(isoMatch[3], 10) : undefined,
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Year only
|
|
88
|
-
const yearMatch = str.match(/^\d{4}$/)
|
|
89
|
-
if (yearMatch) {
|
|
90
|
-
return { year: parseInt(str, 10) }
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Month Year: "January 2024", "Jan 2024"
|
|
94
|
-
const monthYearMatch = str.match(
|
|
95
|
-
/^(\w+)\s+(\d{4})$/
|
|
96
|
-
)
|
|
97
|
-
if (monthYearMatch) {
|
|
98
|
-
const monthName = monthYearMatch[1].toLowerCase()
|
|
99
|
-
const monthIndex = MONTHS_FULL.findIndex(
|
|
100
|
-
(m) => m.toLowerCase().startsWith(monthName.slice(0, 3))
|
|
101
|
-
)
|
|
102
|
-
return {
|
|
103
|
-
year: parseInt(monthYearMatch[2], 10),
|
|
104
|
-
month: monthIndex !== -1 ? monthIndex + 1 : undefined,
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return {}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Format date for APA style
|
|
113
|
-
*
|
|
114
|
-
* @param {Object} date - Parsed date object
|
|
115
|
-
* @returns {string}
|
|
116
|
-
*/
|
|
117
|
-
export function formatApaDate(date) {
|
|
118
|
-
const parsed = parseDate(date)
|
|
119
|
-
|
|
120
|
-
if (!parsed.year) return 'n.d.'
|
|
121
|
-
|
|
122
|
-
if (parsed.month && parsed.day) {
|
|
123
|
-
return `${parsed.year}, ${MONTHS_FULL[parsed.month - 1]} ${parsed.day}`
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (parsed.month) {
|
|
127
|
-
return `${parsed.year}, ${MONTHS_FULL[parsed.month - 1]}`
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return String(parsed.year)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Format date for MLA style
|
|
135
|
-
*
|
|
136
|
-
* @param {Object} date - Parsed date object
|
|
137
|
-
* @returns {string}
|
|
138
|
-
*/
|
|
139
|
-
export function formatMlaDate(date) {
|
|
140
|
-
const parsed = parseDate(date)
|
|
141
|
-
|
|
142
|
-
if (!parsed.year) return ''
|
|
143
|
-
|
|
144
|
-
if (parsed.month && parsed.day) {
|
|
145
|
-
return `${parsed.day} ${MONTHS_SHORT[parsed.month - 1]} ${parsed.year}`
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (parsed.month) {
|
|
149
|
-
return `${MONTHS_SHORT[parsed.month - 1]} ${parsed.year}`
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return String(parsed.year)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Format date for Chicago style
|
|
157
|
-
*
|
|
158
|
-
* @param {Object} date - Parsed date object
|
|
159
|
-
* @returns {string}
|
|
160
|
-
*/
|
|
161
|
-
export function formatChicagoDate(date) {
|
|
162
|
-
const parsed = parseDate(date)
|
|
163
|
-
|
|
164
|
-
if (!parsed.year) return 'n.d.'
|
|
165
|
-
|
|
166
|
-
if (parsed.month && parsed.day) {
|
|
167
|
-
return `${MONTHS_FULL[parsed.month - 1]} ${parsed.day}, ${parsed.year}`
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (parsed.month) {
|
|
171
|
-
return `${MONTHS_FULL[parsed.month - 1]} ${parsed.year}`
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return String(parsed.year)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Format date for IEEE style
|
|
179
|
-
*
|
|
180
|
-
* @param {Object} date - Parsed date object
|
|
181
|
-
* @returns {string}
|
|
182
|
-
*/
|
|
183
|
-
export function formatIeeeDate(date) {
|
|
184
|
-
const parsed = parseDate(date)
|
|
185
|
-
|
|
186
|
-
if (!parsed.year) return ''
|
|
187
|
-
|
|
188
|
-
if (parsed.month) {
|
|
189
|
-
return `${MONTHS_SHORT[parsed.month - 1]} ${parsed.year}`
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return String(parsed.year)
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Format date for a specific style
|
|
197
|
-
*
|
|
198
|
-
* @param {any} date - Date input
|
|
199
|
-
* @param {Object} [options]
|
|
200
|
-
* @param {string} [options.style='apa'] - Citation style
|
|
201
|
-
* @returns {string}
|
|
202
|
-
*/
|
|
203
|
-
export function formatDate(date, options = {}) {
|
|
204
|
-
const { style = 'apa' } = options
|
|
205
|
-
|
|
206
|
-
switch (style) {
|
|
207
|
-
case 'apa':
|
|
208
|
-
return formatApaDate(date)
|
|
209
|
-
case 'mla':
|
|
210
|
-
return formatMlaDate(date)
|
|
211
|
-
case 'chicago':
|
|
212
|
-
return formatChicagoDate(date)
|
|
213
|
-
case 'ieee':
|
|
214
|
-
return formatIeeeDate(date)
|
|
215
|
-
default:
|
|
216
|
-
return formatApaDate(date)
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Get year from date
|
|
222
|
-
*
|
|
223
|
-
* @param {any} date - Date input
|
|
224
|
-
* @returns {number|undefined}
|
|
225
|
-
*/
|
|
226
|
-
export function getYear(date) {
|
|
227
|
-
return parseDate(date).year
|
|
228
|
-
}
|