@retorquere/bibtex-parser 12.1.13 → 13.0.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.
Files changed (76) hide show
  1. package/README.md +14 -10
  2. package/dist/esm/crossref.d.ts.map +1 -0
  3. package/dist/esm/crossref.js.map +1 -1
  4. package/dist/esm/fields.d.ts.map +1 -0
  5. package/dist/esm/fields.js.map +1 -1
  6. package/dist/{types → esm}/index.d.ts +41 -12
  7. package/dist/esm/index.d.ts.map +1 -0
  8. package/dist/esm/index.js +27 -3
  9. package/dist/esm/index.js.map +3 -3
  10. package/dist/{types → esm}/jabref.d.ts +9 -21
  11. package/dist/esm/jabref.d.ts.map +1 -0
  12. package/dist/esm/jabref.js +2 -3
  13. package/dist/esm/jabref.js.map +3 -3
  14. package/dist/esm/merge.d.ts.map +1 -0
  15. package/dist/esm/merge.js.map +1 -1
  16. package/dist/esm/prepositions.d.ts.map +1 -0
  17. package/dist/esm/prepositions.js.map +1 -1
  18. package/dist/{types → esm}/sentence-case.d.ts +1 -0
  19. package/dist/esm/sentence-case.d.ts.map +1 -0
  20. package/dist/esm/sentence-case.js +126 -28
  21. package/dist/esm/sentence-case.js.map +3 -3
  22. package/dist/esm/tokenizer.d.ts.map +1 -0
  23. package/dist/esm/tokenizer.js.map +1 -1
  24. package/dist/esm/verbatim.d.ts +90 -0
  25. package/dist/esm/verbatim.d.ts.map +1 -0
  26. package/dist/esm/verbatim.js +10 -0
  27. package/dist/esm/verbatim.js.map +3 -3
  28. package/dist/esm/yield.d.ts.map +1 -0
  29. package/dist/esm/yield.js.map +1 -1
  30. package/dist/wasm/bibtex_parser.d.ts +12 -9
  31. package/dist/wasm/bibtex_parser.js +13 -23
  32. package/dist/wasm/bibtex_parser_bg.wasm +0 -0
  33. package/dist/wasm/bibtex_parser_bg.wasm.d.ts +2 -3
  34. package/dist/wasm/english.json +27 -0
  35. package/dist/wasm/index.d.ts +105 -29
  36. package/dist/wasm/index.js +54 -51
  37. package/dist/wasm/jabref.d.ts +9 -21
  38. package/dist/wasm/jabref.js +3 -3
  39. package/package.json +25 -26
  40. package/dist/cjs/crossref.js +0 -201
  41. package/dist/cjs/crossref.js.map +0 -7
  42. package/dist/cjs/fields.js +0 -7186
  43. package/dist/cjs/fields.js.map +0 -7
  44. package/dist/cjs/index.js +0 -1126
  45. package/dist/cjs/index.js.map +0 -7
  46. package/dist/cjs/jabref.js +0 -135
  47. package/dist/cjs/jabref.js.map +0 -7
  48. package/dist/cjs/merge.js +0 -37
  49. package/dist/cjs/merge.js.map +0 -7
  50. package/dist/cjs/prepositions.js +0 -111
  51. package/dist/cjs/prepositions.js.map +0 -7
  52. package/dist/cjs/sentence-case.js +0 -98
  53. package/dist/cjs/sentence-case.js.map +0 -7
  54. package/dist/cjs/tokenizer.js +0 -194
  55. package/dist/cjs/tokenizer.js.map +0 -7
  56. package/dist/cjs/verbatim.js +0 -403
  57. package/dist/cjs/verbatim.js.map +0 -7
  58. package/dist/cjs/yield.js +0 -26
  59. package/dist/cjs/yield.js.map +0 -7
  60. package/dist/types/crossref.d.ts.map +0 -1
  61. package/dist/types/fields.d.ts.map +0 -1
  62. package/dist/types/index.d.ts.map +0 -1
  63. package/dist/types/jabref.d.ts.map +0 -1
  64. package/dist/types/merge.d.ts.map +0 -1
  65. package/dist/types/prepositions.d.ts.map +0 -1
  66. package/dist/types/sentence-case.d.ts.map +0 -1
  67. package/dist/types/tokenizer.d.ts.map +0 -1
  68. package/dist/types/verbatim.d.ts +0 -66
  69. package/dist/types/verbatim.d.ts.map +0 -1
  70. package/dist/types/yield.d.ts.map +0 -1
  71. /package/dist/{types → esm}/crossref.d.ts +0 -0
  72. /package/dist/{types → esm}/fields.d.ts +0 -0
  73. /package/dist/{types → esm}/merge.d.ts +0 -0
  74. /package/dist/{types → esm}/prepositions.d.ts +0 -0
  75. /package/dist/{types → esm}/tokenizer.d.ts +0 -0
  76. /package/dist/{types → esm}/yield.d.ts +0 -0
package/dist/cjs/index.js DELETED
@@ -1,1126 +0,0 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
- var index_exports = {};
29
- __export(index_exports, {
30
- English: () => English,
31
- FieldMode: () => FieldMode,
32
- JabRefMetadata: () => import_jabref.JabRefMetadata,
33
- VerbatimLibrary: () => import_verbatim.Library,
34
- parse: () => parse2,
35
- parseAsync: () => parseAsync,
36
- parseVerbatim: () => import_verbatim.parse,
37
- toSentenceCase: () => import_sentence_case2.toSentenceCase,
38
- tokenize: () => import_tokenizer2.tokenize
39
- });
40
- module.exports = __toCommonJS(index_exports);
41
- var import_unified_latex_util_pegjs = require("@unified-latex/unified-latex-util-pegjs");
42
- var import_unified_latex_util_print_raw = require("@unified-latex/unified-latex-util-print-raw");
43
- var import_unified_latex_util_replace = require("@unified-latex/unified-latex-util-replace");
44
- var import_unified_latex_util_visit = require("@unified-latex/unified-latex-util-visit");
45
- var import_unicode2latex = require("unicode2latex");
46
- var JabRef = __toESM(require("./jabref.js"), 1);
47
- var bibtex = __toESM(require("./verbatim.js"), 1);
48
- var import_jabref = require("./jabref.js");
49
- var import_verbatim = require("./verbatim.js");
50
- var import_sentence_case = require("./sentence-case.js");
51
- var import_sentence_case2 = require("./sentence-case.js");
52
- var import_tokenizer = require("./tokenizer.js");
53
- var import_tokenizer2 = require("./tokenizer.js");
54
- var import_yield = require("./yield.js");
55
- var import_crossref = require("./crossref.js");
56
- var import_fields = require("./fields.js");
57
- var import_merge = require("./merge.js");
58
- function latexMode(node) {
59
- return node._renderInfo.mode;
60
- }
61
- const macroAliases = {
62
- sb: "textsubscript",
63
- sp: "textsuperscript"
64
- };
65
- function latex2unicode(tex, node) {
66
- if (node.type === "macro" && macroAliases[node.content]) {
67
- tex = `\\${macroAliases[node.content]}${tex.slice(node.content.length + 1)}`;
68
- }
69
- const text = import_unicode2latex.latex2unicode[tex];
70
- if (typeof text === "string") return text;
71
- return text && text[latexMode(node)];
72
- }
73
- const open = {};
74
- const close = {};
75
- for (const tag of ["i", "b", "sc", "nc", "ncx", "br", "p", "li", "code"]) {
76
- open[tag] = `${tag}`;
77
- close[tag] = `/${tag}`;
78
- }
79
- const collapsable = /\x0E\/([a-z]+)\x0F(\s*)\x0E\1\x0F/ig;
80
- const Month = {
81
- jan: "1",
82
- january: "1",
83
- feb: "2",
84
- february: "2",
85
- mar: "3",
86
- march: "3",
87
- apr: "4",
88
- april: "4",
89
- may: "5",
90
- jun: "6",
91
- june: "6",
92
- jul: "7",
93
- july: "7",
94
- aug: "8",
95
- august: "8",
96
- sep: "9",
97
- september: "9",
98
- oct: "10",
99
- october: "10",
100
- nov: "11",
101
- november: "11",
102
- dec: "12",
103
- december: "12"
104
- };
105
- const FieldMode = {
106
- creatorlist: [
107
- "author",
108
- "bookauthor",
109
- "collaborator",
110
- "commentator",
111
- "director",
112
- "editor",
113
- "editora",
114
- "editorb",
115
- "editors",
116
- "holder",
117
- "scriptwriter",
118
- "translator"
119
- ],
120
- title: [
121
- "title",
122
- "subtitle",
123
- "series",
124
- "shorttitle",
125
- "booktitle",
126
- // 'type',
127
- "origtitle",
128
- "maintitle",
129
- "eventtitle"
130
- ],
131
- verbatim: [
132
- "doi",
133
- "eprint",
134
- "file",
135
- "files",
136
- "pdf",
137
- "groups",
138
- // jabref unilaterally decided to make this non-standard field verbatim
139
- "ids",
140
- "url",
141
- "verba",
142
- "verbb",
143
- "verbc",
144
- /^keywords([+]duplicate-\d+)?$/,
145
- /^citeulike-linkout-[0-9]+$/,
146
- /^bdsk-url-[0-9]+$/
147
- ],
148
- richtext: [
149
- "annotation",
150
- "comment",
151
- "annote",
152
- "review",
153
- "notes",
154
- "note"
155
- ],
156
- literallist: [
157
- "institution",
158
- "publisher",
159
- "origpublisher",
160
- "organization",
161
- "location",
162
- "origlocation"
163
- ]
164
- };
165
- const English = [
166
- "",
167
- "american",
168
- "british",
169
- "canadian",
170
- "english",
171
- "australian",
172
- "newzealand",
173
- "usenglish",
174
- "ukenglish",
175
- "en",
176
- "eng",
177
- "en-au",
178
- "en-bz",
179
- "en-ca",
180
- "en-cb",
181
- "en-gb",
182
- "en-ie",
183
- "en-jm",
184
- "en-nz",
185
- "en-ph",
186
- "en-tt",
187
- "en-us",
188
- "en-za",
189
- "en-zw",
190
- "anglais"
191
- // don't do this people
192
- ];
193
- const FieldAction = {
194
- removeOuterBraces: [
195
- "doi"
196
- // 'publisher',
197
- // 'location',
198
- ],
199
- parseInt: [
200
- "year",
201
- "month"
202
- ]
203
- };
204
- const narguments = {
205
- advance: 1,
206
- allcaps: 1,
207
- ElsevierGlyph: 1,
208
- bar: 1,
209
- bibcyr: 1,
210
- bibstring: 1,
211
- chsf: 1,
212
- cite: 1,
213
- citeauthor: 1,
214
- cyrchar: 1,
215
- discretionary: 3,
216
- ding: 1,
217
- emph: 1,
218
- enquote: 1,
219
- frac: 2,
220
- hbox: 1,
221
- href: 2,
222
- hskip: 1,
223
- hspace: 1,
224
- ht: 1,
225
- mathrm: 1,
226
- mbox: 1,
227
- mkbibbold: 1,
228
- mkbibemph: 1,
229
- mkbibitalic: 1,
230
- mkbibquote: 1,
231
- newcommand: 2,
232
- noopsort: 1,
233
- ocirc: 1,
234
- overline: 1,
235
- ProvideTextCommandDefault: 2,
236
- rlap: 1,
237
- sb: 1,
238
- section: 1,
239
- symbol: 1,
240
- sp: 1,
241
- subsection: 1,
242
- subsubsection: 1,
243
- subsubsubsection: 1,
244
- t: 1,
245
- textbf: 1,
246
- textcite: 1,
247
- textit: 1,
248
- textrm: 1,
249
- textsc: 1,
250
- textsl: 1,
251
- textsubscript: 1,
252
- textsuperscript: 1,
253
- texttt: 1,
254
- textup: 1,
255
- url: 1,
256
- vphantom: 1,
257
- vspace: 1,
258
- wd: 1,
259
- // math
260
- "math _": 1,
261
- "math ^": 1
262
- };
263
- for (const m in import_unicode2latex.combining.tounicode) {
264
- narguments[m] = 1;
265
- }
266
- class UnsupportedError extends Error {
267
- }
268
- class BibTeXParser {
269
- current;
270
- english;
271
- options;
272
- fieldMode;
273
- newcommands = {};
274
- bib;
275
- unhandled = /* @__PURE__ */ new Set();
276
- split(ast, sep, split) {
277
- const roots = [];
278
- const nodes = [...ast.content];
279
- const types = nodes.map((node) => {
280
- if (node.type === "whitespace") return " ";
281
- if (node.type === "string" && node.content.match(sep)) return "&";
282
- return ".";
283
- }).join("");
284
- types.split(split).forEach((match, i) => {
285
- const content = match.length ? nodes.splice(0, match.length) : [];
286
- if (i % 2 === 0) roots.push({ type: "root", content });
287
- });
288
- return roots;
289
- }
290
- trimCreator(cr) {
291
- return JSON.parse(JSON.stringify(cr, (k, v) => typeof v === "string" ? v.trim() || void 0 : v));
292
- }
293
- parseCreator(ast) {
294
- if (ast.content.length === 1 && ast.content[0].type === "group") return this.trimCreator({ name: this.stringify(ast, { mode: "creatorlist" }) });
295
- const { parts, extended } = this.commaSeparatedCreator(ast);
296
- if (extended) {
297
- const name = {};
298
- for (const [attr, value] of Object.entries(extended)) {
299
- const rendered = this.stringify(value, { mode: "creatorlist" }).trim();
300
- switch (attr) {
301
- case "":
302
- break;
303
- case "given":
304
- name.firstName = rendered;
305
- break;
306
- case "family":
307
- name.lastName = rendered;
308
- break;
309
- case "given-i":
310
- name.initial = rendered;
311
- break;
312
- case "useprefix":
313
- case "juniorcomma":
314
- name[attr] = rendered.toLowerCase() === "true";
315
- break;
316
- default:
317
- name[attr] = rendered;
318
- break;
319
- }
320
- }
321
- return this.trimCreator(name);
322
- } else if (parts.length) {
323
- const nameparts = parts.map((part) => this.stringify(part, { mode: "creatorlist" }).trim());
324
- if (nameparts.length === 3 && nameparts[2] === "") nameparts.pop();
325
- if (nameparts.length > 3) {
326
- const key = this.current.key ? `@${this.current.key}: ` : "";
327
- this.bib.errors.push({
328
- error: `${key}unexpected ${nameparts.length}-part name "${nameparts.join(", ")}", dropping "${nameparts.slice(3).join(", ")}"`,
329
- input: nameparts.join(", ")
330
- });
331
- }
332
- let [lastName, suffix, firstName] = nameparts.length === 2 ? [nameparts[0], void 0, nameparts[1]] : nameparts.slice(0, 3);
333
- let prefix;
334
- const m = lastName.match(/^([a-z'. ]+) (.+)/);
335
- if (m) {
336
- prefix = m[1];
337
- lastName = m[2];
338
- }
339
- return this.trimCreator({
340
- lastName,
341
- firstName,
342
- prefix,
343
- suffix
344
- });
345
- } else {
346
- const nameparts = this.split(ast, /^$/, /( )/).map((part) => this.stringify(part, { mode: "creatorlist" })).filter((n) => n);
347
- if (nameparts.length === 1) return this.trimCreator({ lastName: nameparts[0] });
348
- const prefix = nameparts.findIndex((n) => n.match(/^[a-z]/));
349
- const postfix = prefix <= 0 ? -1 : nameparts.findIndex((n, i) => i > prefix && !n.match(/^[a-z]/));
350
- if (postfix === -1) {
351
- const lastName = nameparts.pop();
352
- return this.trimCreator({ lastName, firstName: nameparts.join(" ") });
353
- }
354
- return this.trimCreator({
355
- firstName: nameparts.slice(0, prefix).join(" "),
356
- prefix: nameparts.slice(prefix, postfix).join(" "),
357
- lastName: nameparts.slice(postfix).join(" ")
358
- });
359
- }
360
- }
361
- ligature(nodes) {
362
- if (latexMode(nodes[0]) !== "text") return null;
363
- const max = 3;
364
- const slice = nodes.slice(0, max);
365
- const type = slice.map((n) => n.type === "string" ? "s" : " ").join("");
366
- if (type[0] !== "s") return null;
367
- const content = slice.map((n) => n.type === "string" ? n.content : "");
368
- let latex;
369
- while (content.length) {
370
- if (type.startsWith("s".repeat(content.length)) && (latex = latex2unicode(content.join(""), slice[0]))) {
371
- try {
372
- return { type: "string", content: latex, _renderInfo: {} };
373
- } finally {
374
- nodes.splice(0, content.length);
375
- }
376
- }
377
- content.pop();
378
- }
379
- return null;
380
- }
381
- wraparg(node, macro) {
382
- if (macro.content.match(/^(itshape|textsl|textit|emph|mkbibemph)$/)) node._renderInfo.emph = true;
383
- if (macro.content.match(/^(textbf|mkbibbold|bfseries)$/)) node._renderInfo.bold = true;
384
- if (macro.content.match(/^(textsc)$/)) node._renderInfo.smallCaps = true;
385
- if (macro.content.match(/^(texttt)$/)) node._renderInfo.code = true;
386
- return { type: "argument", content: [node], openMark: "", closeMark: "", _renderInfo: { mode: node._renderInfo.mode } };
387
- }
388
- argtogroup(node) {
389
- if (node.content.length === 1 && node.content[0].type === "group") return node.content[0];
390
- return { type: "group", content: node.content };
391
- }
392
- argument(nodes, macro) {
393
- if (!nodes.length) return null;
394
- if (nodes[0].type === "whitespace") nodes.shift();
395
- if (!nodes.length) return null;
396
- if (nodes[0].type === "string") {
397
- const char = nodes[0].content[0];
398
- nodes[0].content = nodes[0].content.substr(1);
399
- const arg = { ...nodes[0], content: char };
400
- if (!nodes[0].content) nodes.shift();
401
- return this.wraparg(arg, macro);
402
- }
403
- return this.wraparg(nodes.shift(), macro);
404
- }
405
- unsupported(node) {
406
- const tex = (0, import_unified_latex_util_print_raw.printRaw)(node);
407
- if (this.options.unsupported === "throw") throw new UnsupportedError(`unhandled ${node.type} ${tex}`);
408
- let id;
409
- switch (node.type) {
410
- case "macro":
411
- id = `${node.type}.${node.content}`;
412
- if (!this.unhandled.has(id)) {
413
- this.unhandled.add(id);
414
- this.bib.errors.push({ error: `unhandled ${node.type} ${(0, import_unified_latex_util_print_raw.printRaw)(node)}`, input: (0, import_unified_latex_util_print_raw.printRaw)(node) });
415
- }
416
- break;
417
- case "environment":
418
- id = `${node.type}.${node.env}`;
419
- if (!this.unhandled.has(id)) {
420
- this.unhandled.add(id);
421
- this.bib.errors.push({ error: `unhandled ${node.type} ${node.env} (${(0, import_unified_latex_util_print_raw.printRaw)(node)})`, input: (0, import_unified_latex_util_print_raw.printRaw)(node) });
422
- }
423
- break;
424
- default:
425
- this.bib.errors.push({ error: `unhandled ${node.type} (${(0, import_unified_latex_util_print_raw.printRaw)(node)})`, input: (0, import_unified_latex_util_print_raw.printRaw)(node) });
426
- break;
427
- }
428
- const command = node.type === "macro" ? `\\${node.content}` : tex;
429
- switch (this.options.unsupported) {
430
- case "ignore":
431
- return "";
432
- case "text":
433
- return command.replace(/^\\/, "");
434
- case "tex":
435
- return `<script>${command}<\/script>`;
436
- default:
437
- return tex;
438
- }
439
- }
440
- wrap(text, tag, wrap = true) {
441
- if (!text || !wrap) return text || "";
442
- return `${tag}${text}/${tag}`;
443
- }
444
- registercommand(node) {
445
- const types = (nodes) => nodes.map((n) => n.type).join(".");
446
- const group = (arg, kind) => {
447
- if (!arg) throw new Error(`missing ${kind} for ${(0, import_unified_latex_util_print_raw.printRaw)(node)} @ ${JSON.stringify(node.position)}`);
448
- if (types(arg.content) !== "group") throw new Error(`Malformed ${kind} for ${(0, import_unified_latex_util_print_raw.printRaw)(node)} @ ${JSON.stringify(node.position)}`);
449
- return arg.content[0].content;
450
- };
451
- if (!node.args) throw new Error(`No arguments for ${(0, import_unified_latex_util_print_raw.printRaw)(node)} @ ${JSON.stringify(node.position)}`);
452
- const namearg = group(node.args[0], "name");
453
- if (types(namearg) !== "macro") throw new Error(`Unexpected name for ${(0, import_unified_latex_util_print_raw.printRaw)(node)} @ ${JSON.stringify(node.position)}`);
454
- this.newcommands[namearg[0].content] = node.args[1];
455
- return "";
456
- }
457
- subp(text, mode) {
458
- const macro = { sub: "_", sup: "^" }[mode];
459
- let subp = "";
460
- for (let char of text) {
461
- const mapped = import_unicode2latex.latex2unicode[`${macro}{${char}}`];
462
- switch (typeof mapped) {
463
- case "string":
464
- subp += mapped;
465
- break;
466
- case "undefined":
467
- return `${mode}${text}/${mode}`;
468
- default:
469
- subp += mapped.math;
470
- }
471
- }
472
- return subp;
473
- }
474
- macro(node, context) {
475
- var _a, _b, _c;
476
- const name = macroAliases[node.content] ?? node.content;
477
- if (name === "discretionary") {
478
- return ((_a = node.args) == null ? void 0 : _a[2]) ? this.stringify(node.args[2], context) : "";
479
- }
480
- if (name === "symbol") {
481
- const argument = ((_c = (_b = node.args) == null ? void 0 : _b[0]) == null ? void 0 : _c.content) ?? [];
482
- const content = argument.length === 1 && argument[0].type === "group" ? argument[0].content : argument;
483
- const code = content.map((n) => this.stringify(n, context)).join("").trim();
484
- const value = /^\d+$/.test(code) ? Number(code) : NaN;
485
- if (Number.isSafeInteger(value) && value <= 1114111 && !(value >= 55296 && value <= 57343)) {
486
- return String.fromCodePoint(value);
487
- }
488
- return this.unsupported(node);
489
- }
490
- const text = latex2unicode((0, import_unified_latex_util_print_raw.printRaw)(node), node);
491
- if (text) return text;
492
- let url;
493
- let label;
494
- let arg;
495
- switch (name) {
496
- case "newcommand":
497
- case "ProvideTextCommandDefault":
498
- return this.registercommand(node);
499
- // too complex to deal with these
500
- case "raise":
501
- case "accent":
502
- case "def":
503
- case "hss":
504
- case "ifmmode":
505
- case "makeatletter":
506
- case "makeatother":
507
- case "scriptscriptstyle":
508
- case "setbox":
509
- case "dimen":
510
- case "advance":
511
- return "";
512
- case "vphantom":
513
- case "noopsort":
514
- case "left":
515
- case "right":
516
- case "ensuremath":
517
- case "wd":
518
- case "ht":
519
- return "";
520
- case "path":
521
- return "";
522
- // until https://github.com/siefkenj/unified-latex/issues/94 is fixed
523
- case "hspace":
524
- case "hskip":
525
- if (node.args && node.args.length) {
526
- if ((0, import_unified_latex_util_print_raw.printRaw)(node.args).match(/^[{]?0[a-z]*$/)) return "";
527
- return " ";
528
- }
529
- return "";
530
- case "overline":
531
- case "bar":
532
- return node.args.map((a) => this.stringify(a, context)).join("").replace(/[a-z0-9]/ig, (m) => `${m}\u0305`);
533
- // accents dealt with by preprocessor
534
- case "textup":
535
- case "textsc":
536
- case "textrm":
537
- case "texttt":
538
- case "mathrm":
539
- case "mbox":
540
- case "hbox":
541
- case "rlap":
542
- return node.args.map((n) => this.stringify(n, context)).join("");
543
- case "href":
544
- case "url":
545
- if (node.args) {
546
- url = node.args[0];
547
- label = node.args[node.content === "url" ? 0 : 1];
548
- }
549
- return `<a href="${this.stringify(url, context)}">${this.stringify(label, context)}</a>`;
550
- case "relax":
551
- case "aftergroup":
552
- case "ignorespaces":
553
- case "undefined":
554
- case "em":
555
- case "it":
556
- case "tt":
557
- case "sl":
558
- case "if":
559
- case "ifx":
560
- case "else":
561
- return "";
562
- case "rm":
563
- case "sc":
564
- return "";
565
- // bold/emph/smallcaps is handled in the wrapper
566
- case "textbf":
567
- case "mkbibbold":
568
- case "textit":
569
- case "emph":
570
- case "mkbibemph":
571
- return this.stringify(node.args[0], context);
572
- case "textsuperscript":
573
- return this.subp(this.stringify(node.args[0], context), "sup");
574
- case "textsubscript":
575
- return this.subp(this.stringify(node.args[0], context), "sub");
576
- case "allcaps":
577
- return this.wrap(this.stringify(node.args[0], { ...context, caseProtected: true }), "nc", this.english && context.mode === "title");
578
- case "_":
579
- case "^":
580
- switch (latexMode(node)) {
581
- case "math":
582
- return this.subp(this.stringify(node.args[0], context), node.content === "^" ? "sup" : "sub");
583
- default:
584
- return node.content;
585
- }
586
- case "LaTeX":
587
- return this.wrap(`L${this.subp("A", "sup")}T${this.subp("E", "sub")}X`, "ncx");
588
- case "enquote":
589
- case "mkbibquote":
590
- return this.wrap(this.stringify(node.args[0], context), "enquote");
591
- case "\\":
592
- return context.mode === "richtext" ? open.br : " ";
593
- case " ":
594
- return " ";
595
- case "par":
596
- return context.mode === "richtext" ? open.p : " ";
597
- case "item":
598
- return context.mode === "richtext" ? open.li : " ";
599
- case "section":
600
- case "subsection":
601
- case "subsubsection":
602
- case "subsubsubsection":
603
- return this.wrap(this.stringify(node.args[0], context), `h${node.content.split("sub").length}`);
604
- case "frac":
605
- arg = node.args.map((a) => this.stringify(a, context));
606
- if (arg.length === 2) {
607
- const resolved = import_unicode2latex.latex2unicode[`\\frac${arg.map((a) => `{${a}}`).join("")}`];
608
- if (resolved) return typeof resolved === "string" ? resolved : resolved.math || resolved.text;
609
- }
610
- return arg.map((part, i) => this.subp(part, i ? "sub" : "sup")).join("\u2044");
611
- case "chsf":
612
- case "bibstring":
613
- case "cite":
614
- case "textcite":
615
- case "citeauthor":
616
- return this.wrap(this.stringify(node.args[0], context), "ncx", context.mode === "title");
617
- default:
618
- if (this.newcommands[node.content]) return this.stringify(this.newcommands[node.content], context);
619
- return this.unsupported(node);
620
- }
621
- }
622
- what(node) {
623
- if (!node) return "";
624
- switch (node.type) {
625
- case "macro":
626
- return `macro:${node._renderInfo.mode ?? "text"}:${node.content}`;
627
- case "environment":
628
- return `env:${node.env}`;
629
- default:
630
- return node.type;
631
- }
632
- }
633
- environment(node, context) {
634
- while (node.content.length && this.what(node.content[0]).match(/^parbreak|whitespace|macro:text:par$/)) node.content.shift();
635
- while (node.content.length && this.what(node.content[node.content.length - 1]).match(/^parbreak|whitespace|macro:text:par$/)) node.content.pop();
636
- switch (node.env) {
637
- case "quotation":
638
- return this.wrap(node.content.map((n) => this.stringify(n, context)).join(""), "blockquote", context.mode === "richtext");
639
- case "itemize":
640
- return this.wrap(node.content.map((n) => this.stringify(n, context)).join(""), "ul", context.mode === "richtext");
641
- case "em":
642
- return this.wrap(node.content.map((n) => this.stringify(n, context)).join(""), "i", context.mode === "richtext");
643
- default:
644
- return this.unsupported(node);
645
- }
646
- }
647
- stringify(node, context) {
648
- let content = this.stringifyContent(node, context);
649
- if (content && node._renderInfo) {
650
- if (node._renderInfo.emph) content = `${open.i}${content}${close.i}`;
651
- if (node._renderInfo.bold) content = `${open.b}${content}${close.b}`;
652
- if (node._renderInfo.smallCaps) content = `${open.sc}${content}${close.sc}`;
653
- if (node._renderInfo.code) content = `${open.code}${content}${close.code}`;
654
- if (this.english && node._renderInfo.protectCase && !context.caseProtected) content = `${open.nc}${content}${close.nc}`;
655
- }
656
- return content;
657
- }
658
- stringifyContent(node, context) {
659
- if (!node) return "";
660
- switch (node.type) {
661
- case "root":
662
- case "argument":
663
- case "group":
664
- case "inlinemath":
665
- return node.content.map((n) => this.stringify(n, context)).join("");
666
- case "string":
667
- case "verbatim":
668
- return node.content;
669
- case "macro":
670
- return this.macro(node, context);
671
- case "parbreak":
672
- return context.mode === "richtext" ? open.p : " ";
673
- case "whitespace":
674
- return node._renderInfo.mode === "math" ? "" : " ";
675
- case "comment":
676
- return "";
677
- case "environment":
678
- return this.environment(node, context);
679
- case "verb":
680
- return node.content;
681
- default:
682
- return this.unsupported(node);
683
- }
684
- }
685
- protect(node) {
686
- if (node.type === "inlinemath") return true;
687
- if (node.type !== "group") return false;
688
- if (!node.content.length) return false;
689
- return node.content[0].type !== "macro";
690
- }
691
- mode(field) {
692
- if (this.options.verbatimFields && this.options.verbatimFields.find((name) => typeof name === "string" ? name === field : field.match(name))) return "verbatim";
693
- let mode = "literal";
694
- for (const [selected, fields] of Object.entries(this.fieldMode)) {
695
- if (fields.find((match) => typeof match === "string" ? field === match : field.match(match))) mode = selected;
696
- }
697
- return mode;
698
- }
699
- restoreMarkup(s) {
700
- if (!s.includes("")) return s;
701
- const restored = [s.replace(/\x0E\/?ncx\x0F/ig, "")];
702
- while (restored[0] !== restored[1]) {
703
- restored.unshift(restored[0].replace(collapsable, "$2"));
704
- }
705
- return restored[0].replace(/(\x0Ep\x0F\s*){2,}/ig, "p").replace(/\s*(\x0E\/p\x0F){2,}/ig, "/p").replace(/\x0Eenquote\x0F/ig, "\u201C").replace(/\x0E\/enquote\x0F/ig, "\u201D").replace(/\x0Esc\x0F/ig, '<span style="font-variant:small-caps;">').replace(/\x0E\/sc\x0F/ig, "</span>").replace(/\x0Enc\x0F/ig, '<span class="nocase">').replace(/\x0E\/nc\x0F/ig, "</span>").replace(/\x0E/ig, "<").replace(/\x0F/ig, ">");
706
- }
707
- stringField(field, value, mode, guessSC) {
708
- if (field === "crossref") return value;
709
- if (FieldAction.parseInt.includes(field) && value.trim().match(/^-?\d+$/)) return `${parseInt(value)}`;
710
- if (this.english && mode === "title") {
711
- value = (0, import_sentence_case.toSentenceCase)(value, {
712
- preserveQuoted: this.options.sentenceCase && this.options.sentenceCase.preserveQuoted,
713
- subSentenceCapitalization: this.options.sentenceCase && this.options.sentenceCase.subSentence,
714
- markup: /\x0E\/?([a-z]+)\x0F/ig,
715
- nocase: /\x0E(ncx?)\x0F.*?\x0E\/\1\x0F/ig,
716
- guess: guessSC
717
- });
718
- let cancel = (_match, stripped) => stripped;
719
- switch (this.options.caseProtection) {
720
- case "strict":
721
- cancel = (match, _stripped) => match;
722
- break;
723
- case "as-needed":
724
- cancel = (match, stripped) => {
725
- const words = (0, import_tokenizer.tokenize)(stripped, /\x0E\/?([a-z]+)\x0F/ig);
726
- return words.find((w) => w.shape.match(/^(?!.*X).*x.*$/)) ? match : this.wrap(stripped, "ncx");
727
- };
728
- break;
729
- }
730
- return value.replace(/\x0Enc\x0F(.*?)\x0E\/nc\x0F/ig, cancel);
731
- }
732
- return value;
733
- }
734
- commaSeparatedCreator(ast) {
735
- var _a;
736
- const result = {
737
- parts: []
738
- };
739
- if (!ast.content.find((node) => node.type === "string" && node.content === ",")) return result;
740
- result.parts = this.split(ast, /^,$/, /(&)/);
741
- result.extended = {};
742
- for (const part of result.parts) {
743
- const start = ((_a = part.content[0]) == null ? void 0 : _a.type) === "whitespace" ? 1 : 0;
744
- let signature = part.content.slice(start, start + 4).map((node, i) => node._renderInfo.mode === "text" && node.type === "string" ? node.content.replace(i % 2 ? /[^=-]/g : /[^a-z]/gi, ".") : ".").join("");
745
- if (signature.match(/^[a-z]+(-[a-z]+)?=/i)) {
746
- signature = signature.replace(/=.*/, "").toLowerCase();
747
- result.extended[signature] = { type: "root", content: part.content.slice(signature.includes("-") ? start + 4 : start + 2) };
748
- } else {
749
- delete result.extended;
750
- break;
751
- }
752
- }
753
- return result;
754
- }
755
- field(entry, field, value) {
756
- const mode = entry.mode[field] = this.mode(field);
757
- const caseProtection = {
758
- present: false,
759
- intuitive: 0
760
- // a lot of people don't realise `some text \textit{in italics}` will protect 'in italics'
761
- };
762
- const ast = import_unified_latex_util_pegjs.LatexPegParser.parse(value);
763
- if (this.options.removeOuterBraces.includes(field) && ast.content.length === 1 && ast.content[0].type === "group") {
764
- ast.content = ast.content[0].content;
765
- }
766
- if (mode === "verbatim") {
767
- entry.fields[field] = (0, import_unified_latex_util_print_raw.printRaw)(ast);
768
- return;
769
- }
770
- if (this.english && mode === "title") {
771
- let root = [...ast.content];
772
- while (root.length) {
773
- const node = root.shift();
774
- if (this.protect(node)) node._renderInfo = { root: true };
775
- if (node.type === "environment") root = [...root, ...node.content];
776
- }
777
- }
778
- (0, import_unified_latex_util_visit.visit)(ast, (node, info) => {
779
- if (!node._renderInfo) node._renderInfo = {};
780
- node._renderInfo.mode = info.context.inMathMode ? "math" : "text";
781
- if (mode === "title" && node.type === "inlinemath" && !info.parents.find((p) => p._renderInfo.protectCase)) node._renderInfo.protectCase = true;
782
- if (!info.context.inMathMode) {
783
- if (mode === "title" && node._renderInfo.root && (node.type !== "group" || node.content[0].type !== "macro")) {
784
- node._renderInfo.protectCase = true;
785
- if (node.type === "group") {
786
- caseProtection.present = true;
787
- caseProtection.intuitive += 1;
788
- }
789
- }
790
- if (node.type === "macro" && typeof node.escapeToken !== "string") node.escapeToken = "\\";
791
- if (node.type === "environment" && node.env === "em") node._renderInfo.emph = true;
792
- }
793
- });
794
- if (this.options.raw) {
795
- switch (mode) {
796
- case "creatorlist":
797
- entry.fields[field] = this.split(ast, /^and$/i, /(^& | & | &$)/).map((cr) => {
798
- const { parts, extended } = this.commaSeparatedCreator(cr);
799
- if (parts.length === 2 && !extended) {
800
- return this.trimCreator({ lastName: (0, import_unified_latex_util_print_raw.printRaw)(parts[0]), firstName: (0, import_unified_latex_util_print_raw.printRaw)(parts[1]) });
801
- }
802
- if (!parts.length) {
803
- const nameparts = this.split(ast, /^$/, /( )/);
804
- if (nameparts.length === 2) {
805
- return this.trimCreator({
806
- lastName: (0, import_unified_latex_util_print_raw.printRaw)(nameparts[1]),
807
- firstName: (0, import_unified_latex_util_print_raw.printRaw)(nameparts[0])
808
- });
809
- }
810
- }
811
- return { name: (0, import_unified_latex_util_print_raw.printRaw)(cr) };
812
- });
813
- return;
814
- case "literallist":
815
- entry.fields[field] = this.split(ast, /^and$/i, /(^& | & | &$)/).map((elt) => (0, import_unified_latex_util_print_raw.printRaw)(elt));
816
- return;
817
- default:
818
- entry.fields[field] = (0, import_unified_latex_util_print_raw.printRaw)(ast);
819
- return;
820
- }
821
- }
822
- (0, import_unified_latex_util_visit.visit)(ast, (nodes, info) => {
823
- var _a;
824
- const compacted = [];
825
- let inif = 0;
826
- while (nodes.length) {
827
- const ligatureResult = this.ligature(nodes);
828
- if (ligatureResult) {
829
- compacted.push(ligatureResult);
830
- continue;
831
- }
832
- const node = nodes.shift();
833
- if (node.type === "macro" && node.content === "ifdefined") {
834
- inif += 1;
835
- continue;
836
- } else if (node.type === "macro" && node.content === "else") {
837
- continue;
838
- } else if (node.type === "macro" && node.content === "fi") {
839
- inif = Math.max(inif - 1, 0);
840
- continue;
841
- } else if (inif) {
842
- continue;
843
- }
844
- const nargs = node.type === "macro" ? narguments[node.content] || narguments[`${info.context.inMathMode ? "math" : "text"} ${node.content}`] : 0;
845
- if (node.type === "macro" && nargs) {
846
- const args = Array(nargs).fill(void 0).map((_i) => this.argument(nodes, node)).filter((arg) => arg !== null);
847
- node.args = args;
848
- if (node.content.match(/^(url|href)$/) && args.length) {
849
- let url = args[0].content;
850
- if (url.length === 1 && url[0].type === "group") url = url[0].content;
851
- args[0] = this.wraparg({ type: "string", content: (0, import_unified_latex_util_print_raw.printRaw)(url), _renderInfo: { mode: url[0]._renderInfo.mode } }, node);
852
- }
853
- caseProtection.intuitive -= args.filter((arg) => arg.content[0].type === "group" && arg.content[0]._renderInfo.protectCase).length;
854
- } else if (node.type === "macro" && node.content.match(/^[a-z]+$/i) && ((_a = nodes[0]) == null ? void 0 : _a.type) === "whitespace") {
855
- nodes.shift();
856
- }
857
- compacted.push(node);
858
- }
859
- if (!info.context.inMathMode) {
860
- for (const [macro, markup] of Object.entries({ em: "emph", it: "emph", sl: "emph", bf: "bold", sc: "smallCaps", tt: "code" })) {
861
- if (info.parents.find((p) => {
862
- var _a2;
863
- return (_a2 = p._renderInfo) == null ? void 0 : _a2[markup];
864
- })) continue;
865
- compacted.forEach((markup_node, i) => {
866
- if (markup_node.type === "macro" && markup_node.content === macro) {
867
- compacted.slice(i + 1).forEach((n) => n._renderInfo[markup] = true);
868
- }
869
- });
870
- }
871
- }
872
- nodes.push(...compacted);
873
- }, { test: Array.isArray, includeArrays: true });
874
- (0, import_unified_latex_util_replace.replaceNode)(ast, (node, _info) => {
875
- var _a;
876
- if (node.type !== "macro") return;
877
- if (node.escapeToken && import_unicode2latex.combining.tounicode[node.content]) {
878
- let arg;
879
- if (!node.args || node.args.length === 0 || node.args[0].content.length === 0) {
880
- arg = { type: "string", content: " ", _renderInfo: {} };
881
- } else if (node.args.length !== 1 || node.args[0].content.length !== 1) {
882
- return;
883
- } else {
884
- arg = node.args[0].content[0];
885
- }
886
- if (arg.type === "group") {
887
- switch (arg.content.length) {
888
- case 0:
889
- arg = { type: "string", content: " ", _renderInfo: {} };
890
- break;
891
- case 1:
892
- arg = arg.content[0];
893
- break;
894
- default:
895
- return;
896
- }
897
- }
898
- switch (arg.type) {
899
- case "verbatim":
900
- case "string":
901
- return { type: "string", content: `${arg.content}${import_unicode2latex.combining.tounicode[node.content]}`, _renderInfo: {} };
902
- case "macro":
903
- if (arg.escapeToken && /^[A-Za-z]$/.test(arg.content) && !((_a = arg.args) == null ? void 0 : _a.length)) {
904
- const command = `${arg.escapeToken}${arg.content}`;
905
- if (!(command in import_unicode2latex.latex2unicode)) {
906
- return { type: "string", content: `${arg.content}${import_unicode2latex.combining.tounicode[node.content]}`, _renderInfo: {} };
907
- }
908
- }
909
- return;
910
- default:
911
- return;
912
- }
913
- }
914
- let latex = `${node.escapeToken}${node.content}`;
915
- latex += (node.args || []).map((arg) => (0, import_unified_latex_util_print_raw.printRaw)(this.argtogroup(arg))).join("");
916
- if (latex in import_unicode2latex.latex2unicode) return { type: "string", content: latex2unicode(latex, node), _renderInfo: {} };
917
- });
918
- switch (mode) {
919
- case "creatorlist":
920
- entry.fields[field] = this.split(ast, /^and$/i, /(^& | & | &$)/).map((cr) => this.parseCreator(cr)).filter((cr) => Object.keys(cr).length);
921
- break;
922
- case "literallist":
923
- entry.fields[field] = this.split(ast, /^and$/i, /(^& | & | &$)/).map((elt) => this.stringify(elt, { mode: "literal" }).trim());
924
- break;
925
- default:
926
- entry.fields[field] = this.stringField(
927
- field,
928
- this.stringify(ast, { mode }),
929
- mode,
930
- !!(this.options.sentenceCase && this.options.sentenceCase.guess)
931
- // && (!caseProtection.present || caseProtection.intuitive > 0)
932
- );
933
- break;
934
- }
935
- entry.fields[field] = JSON.parse(JSON.stringify(entry.fields[field], (k, v) => typeof v === "string" ? this.restoreMarkup(v) : v));
936
- }
937
- reset(options = {}) {
938
- if (options.sentenceCase === false) {
939
- options = {
940
- ...options,
941
- english: false,
942
- sentenceCase: {
943
- guess: false,
944
- subSentence: false,
945
- preserveQuoted: false
946
- }
947
- };
948
- }
949
- this.options = (0, import_merge.merge)(options, {
950
- caseProtection: "as-needed",
951
- applyCrossRef: options.applyCrossRef ?? true,
952
- fieldMode: {},
953
- english: English,
954
- sentenceCase: {
955
- guess: true,
956
- preserveQuoted: true
957
- }
958
- });
959
- if (this.options.caseProtection === true) this.options.caseProtection = "as-needed";
960
- if (this.options.verbatimFields) this.options.verbatimFields = this.options.verbatimFields.map((f) => typeof f === "string" ? f.toLowerCase() : new RegExp(f.source, f.flags + (f.flags.includes("i") ? "" : "i")));
961
- if (typeof this.options.english === "boolean") this.options.english = this.options.english ? English : [];
962
- this.options.english = this.options.english.map((langid) => langid.toLowerCase());
963
- this.fieldMode = Object.entries(FieldMode).reduce((acc, [mode, test]) => {
964
- const strings = test.filter((fieldname_or_regex) => typeof fieldname_or_regex === "string" && !this.options.fieldMode[fieldname_or_regex]);
965
- const regexes = test.filter((fieldname_or_regex) => typeof fieldname_or_regex !== "string");
966
- acc[mode] = [...strings, ...regexes];
967
- return acc;
968
- }, {});
969
- for (const [field, mode] of Object.entries(this.options.fieldMode)) {
970
- this.fieldMode[mode].unshift(field);
971
- }
972
- if (!this.options.removeOuterBraces) {
973
- this.options.removeOuterBraces = [
974
- ...FieldAction.removeOuterBraces,
975
- ...this.fieldMode.title,
976
- ...this.fieldMode.verbatim
977
- ].filter((field) => typeof field === "string");
978
- }
979
- if (options.unsupported !== void 0 && !["tex", "text", "ignore", "throw"].includes(options.unsupported)) {
980
- throw new TypeError("unsupported must be tex, text, ignore, or throw");
981
- }
982
- this.bib = {
983
- errors: [],
984
- entries: [],
985
- comments: [],
986
- strings: {},
987
- preambles: [],
988
- jabref: new JabRef.JabRefMetadata()
989
- };
990
- }
991
- reparse(verbatim) {
992
- let langid = (verbatim.fields.langid || verbatim.fields.hyphenation || "").toLowerCase();
993
- if (!langid && this.options.languageAsLangid && verbatim.fields.language) langid = verbatim.fields.language.toLowerCase();
994
- this.english = this.options.english.includes(langid);
995
- const entry = this.current = {
996
- type: verbatim.type,
997
- key: verbatim.key,
998
- fields: {},
999
- mode: {},
1000
- input: verbatim.input
1001
- };
1002
- let keywords = [];
1003
- try {
1004
- for (let [field, value] of Object.entries(verbatim.fields)) {
1005
- if (!value.trim()) continue;
1006
- if (field.match(/^keywords([+]duplicate-\d+)?$/)) field = "keywords";
1007
- this.field(entry, field, value);
1008
- if (field === "keywords") {
1009
- keywords = [...keywords, ...entry.fields.keywords.split(/\s*[,;]\s*/)].map((k) => k.trim()).filter((k) => k);
1010
- delete entry.fields.keywords;
1011
- }
1012
- if (!this.options.raw && typeof entry.fields[field] === "string") {
1013
- entry.fields[field] = entry.fields[field].trim();
1014
- if (field === "month") entry.fields[field] = Month[entry.fields[field].toLowerCase()] || entry.fields[field];
1015
- }
1016
- }
1017
- if (keywords.length) {
1018
- entry.fields.keywords = keywords;
1019
- entry.mode.keywords = "verbatimlist";
1020
- }
1021
- this.bib.entries.push(entry);
1022
- } catch (err) {
1023
- if (err instanceof UnsupportedError) throw err;
1024
- this.bib.errors.push({ error: `${err.message}
1025
- ${entry.input}`, input: entry.input });
1026
- }
1027
- }
1028
- content(tex) {
1029
- const entry = { key: "", type: "", fields: {}, mode: {}, input: tex };
1030
- const english = this.english;
1031
- this.english = false;
1032
- this.field(entry, "tex", tex);
1033
- this.english = english;
1034
- return entry.fields.tex;
1035
- }
1036
- prep(base) {
1037
- for (const preamble of base.preambles) {
1038
- try {
1039
- this.content(preamble);
1040
- } catch (err) {
1041
- if (err instanceof UnsupportedError) throw err;
1042
- }
1043
- }
1044
- for (const [k, v] of Object.entries(base.strings)) {
1045
- this.bib.strings[k] = this.content(v);
1046
- }
1047
- }
1048
- finalize(base) {
1049
- var _a;
1050
- if (this.options.applyCrossRef) {
1051
- const entries = {};
1052
- for (const entry of this.bib.entries) {
1053
- if (entry.key) entries[entry.key.toUpperCase()] = entry;
1054
- }
1055
- const order = [];
1056
- for (const entry of this.bib.entries) {
1057
- if (!entry.key || typeof entry.fields.crossref !== "string") continue;
1058
- const crossref = entry.fields.crossref.toUpperCase();
1059
- if (!entries[crossref]) continue;
1060
- const key = entry.key.toUpperCase();
1061
- if (!order.includes(crossref)) order.unshift(crossref);
1062
- if (!order.includes(key)) order.push(key);
1063
- }
1064
- for (const key of order) {
1065
- const child = entries[key.toUpperCase()];
1066
- const parent = entries[(_a = child.fields.crossref) == null ? void 0 : _a.toUpperCase()];
1067
- if (!parent) continue;
1068
- for (const mappings of [import_crossref.crossref[child.type], import_crossref.crossref["*"]].filter((m) => m)) {
1069
- for (const mapping of [mappings[parent.type], mappings["*"]].filter((m) => m)) {
1070
- for (const [childfield, parentfield] of Object.entries(mapping)) {
1071
- if (!child.fields[childfield] && parent.fields[parentfield]) {
1072
- child.fields[childfield] = parent.fields[parentfield];
1073
- child.crossref ??= {};
1074
- child.crossref[childfield] = { parent: parent.key, field: parentfield };
1075
- }
1076
- }
1077
- for (const field of import_fields.allowed[child.type] || []) {
1078
- if (import_fields.noCrossRef.includes(field)) continue;
1079
- if (!child.fields[field] && parent.fields[field]) {
1080
- child.fields[field] = parent.fields[field];
1081
- child.crossref ??= {};
1082
- child.crossref[field] = { parent: parent.key, field };
1083
- }
1084
- }
1085
- }
1086
- }
1087
- }
1088
- }
1089
- const { comments, jabref } = JabRef.parse(base.comments);
1090
- this.bib.comments = comments;
1091
- this.bib.jabref = jabref;
1092
- this.bib.preambles = base.preambles;
1093
- this.bib.errors = [...base.errors, ...this.bib.errors];
1094
- }
1095
- parse(input, options = {}) {
1096
- this.reset(options);
1097
- const base = bibtex.parse(input, { strings: options.strings });
1098
- this.prep(base);
1099
- for (const entry of base.entries) {
1100
- this.reparse(entry);
1101
- }
1102
- this.finalize(base);
1103
- return this.bib;
1104
- }
1105
- async parseAsync(input, options = {}) {
1106
- this.reset(options);
1107
- const base = await bibtex.promises.parse(input, { strings: options.strings });
1108
- this.prep(base);
1109
- let n = 1;
1110
- for (const entry of base.entries) {
1111
- this.reparse(entry);
1112
- if (n++ % 1e3 === 0) await (0, import_yield.playnice)();
1113
- }
1114
- this.finalize(base);
1115
- return this.bib;
1116
- }
1117
- }
1118
- function parse2(input, options = {}) {
1119
- const parser = new BibTeXParser();
1120
- return parser.parse(input, options);
1121
- }
1122
- async function parseAsync(input, options = {}) {
1123
- const parser = new BibTeXParser();
1124
- return await parser.parseAsync(input, options);
1125
- }
1126
- //# sourceMappingURL=index.js.map