@retorquere/bibtex-parser 9.0.26 → 10.0.0

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 (47) hide show
  1. package/dist/cjs/crossref.js +3 -11
  2. package/dist/cjs/crossref.js.map +2 -2
  3. package/dist/cjs/fields.js +227 -2
  4. package/dist/cjs/fields.js.map +2 -2
  5. package/dist/cjs/index.js +34 -40
  6. package/dist/cjs/index.js.map +3 -3
  7. package/dist/cjs/jabref.js +1 -1
  8. package/dist/cjs/jabref.js.map +2 -2
  9. package/dist/cjs/sentence-case.js.map +2 -2
  10. package/dist/cjs/tokenizer.js +5 -5
  11. package/dist/cjs/tokenizer.js.map +2 -2
  12. package/dist/cjs/verbatim.js.map +2 -2
  13. package/dist/data/crossref.json +1 -9
  14. package/dist/data/fields.json +7144 -6918
  15. package/dist/esm/crossref.js +3 -11
  16. package/dist/esm/crossref.js.map +2 -2
  17. package/dist/esm/fields.js +227 -2
  18. package/dist/esm/fields.js.map +2 -2
  19. package/dist/esm/index.js +31 -38
  20. package/dist/esm/index.js.map +2 -2
  21. package/dist/esm/jabref.js +1 -1
  22. package/dist/esm/jabref.js.map +2 -2
  23. package/dist/esm/sentence-case.js.map +2 -2
  24. package/dist/esm/tokenizer.js +5 -5
  25. package/dist/esm/tokenizer.js.map +2 -2
  26. package/dist/esm/verbatim.js.map +2 -2
  27. package/package.json +22 -20
  28. package/dist/types/crossref.d.ts +0 -188
  29. package/dist/types/crossref.d.ts.map +0 -1
  30. package/dist/types/fields.d.ts +0 -55
  31. package/dist/types/fields.d.ts.map +0 -1
  32. package/dist/types/index.d.ts +0 -194
  33. package/dist/types/index.d.ts.map +0 -1
  34. package/dist/types/jabref.d.ts +0 -58
  35. package/dist/types/jabref.d.ts.map +0 -1
  36. package/dist/types/merge.d.ts +0 -2
  37. package/dist/types/merge.d.ts.map +0 -1
  38. package/dist/types/prepositions.d.ts +0 -3
  39. package/dist/types/prepositions.d.ts.map +0 -1
  40. package/dist/types/sentence-case.d.ts +0 -9
  41. package/dist/types/sentence-case.d.ts.map +0 -1
  42. package/dist/types/tokenizer.d.ts +0 -13
  43. package/dist/types/tokenizer.d.ts.map +0 -1
  44. package/dist/types/verbatim.d.ts +0 -66
  45. package/dist/types/verbatim.d.ts.map +0 -1
  46. package/dist/types/yield.d.ts +0 -2
  47. package/dist/types/yield.d.ts.map +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../jabref.ts"],
4
- "sourcesContent": ["function decode(s, sep = ';') {\n s = s.replace(/\\r?\\n/g, '')\n let pos = 0\n const records = ['']\n while (pos < s.length) {\n switch (s[pos]) {\n case '\\\\':\n pos++\n records[0] += s[pos]\n break\n\n case sep:\n records.unshift('')\n break\n\n default:\n records[0] += s[pos]\n }\n pos++\n }\n return records.reverse().filter(record => record)\n}\n\n/**\n * A JabRef group.\n */\nexport interface Group {\n /**\n * the group name\n */\n name: string\n\n /**\n * The citation keys which are specified to belong to this group, after intersection calculation has been applied\n */\n entries: string[]\n\n /**\n * Sub-groups under this group\n */\n groups: Group[]\n}\n\nexport interface JabRefMetadata {\n /**\n * The root groups. You can find the nested groups in their `groups` property\n */\n root: Group[]\n\n /**\n * JabRef since 3.8 has changed their groups format. Entries have a `groups` field which has the names of the groups they belong to -- this name does not have to be unique in the groups hierarchy so if you\n * have multiple groups with the same name, it's not well-defined where the entries should end up. This property gives you the for each group name the first time the group showed up in the hierarchy. Note that\n * keys from the entries themselves have *not* yet been added to the [[Group]]s. You need to combine this yourself as you're parsing the entries.\n */\n groups: { [key: string]: Group }\n\n /**\n * The base path for file paths\n */\n fileDirectory?: string\n\n /**\n * The JabRef metadata format version\n */\n groupsversion?: number\n\n /**\n * The JabRef metadata database type\n */\n databaseType?: string\n}\n\n/**\n * Import the JabRef groups from the `@string` comments in which they were stored. You would typically pass the comments parsed by [[bibtex.parse]] in here.\n *\n * JabRef knows several group types, and this parser parses most, but not all of them:\n *\n * * independent group: the keys listed in the group are the entries that are considered to belong to it\n * * intersection: the keys listed in the group are considered to belong to the group if they're also in the parent group\n * * union: the keys listed in the group are considered to belong to the group, and also the keys that are in the parent group\n * * query: not supported by this parser\n */\nexport function parse(comments: string[]): { comments: string[]; jabref: JabRefMetadata } {\n const result: JabRefMetadata = {\n root: [],\n groups: {},\n }\n\n const levels: Group[] = []\n\n const decoded = {\n fileDirectory: null,\n groupsversion: null,\n groupstree: null,\n grouping: null,\n databaseType: null,\n }\n\n comments = comments.filter(comment => {\n const m = comment.match(/^jabref-meta:\\s*([^:]+):([\\s\\S]*)/) // use \\s\\S because mozilla doesn't understand /s\n if (m) {\n decoded[m[1]] = decode(m[2])\n return false\n }\n return true\n })\n\n if (decoded.groupsversion) result.groupsversion = parseInt(decoded.groupsversion[0].trim()) || decoded.groupsversion[0] // eslint-disable-line @typescript-eslint/no-unsafe-argument\n if (decoded.fileDirectory) result.fileDirectory = decoded.fileDirectory[0]\n if (decoded.databaseType) result.databaseType = decoded.databaseType[0]\n\n for (const tree of ['groupstree', 'grouping']) {\n if (!decoded[tree]) continue\n\n for (const encoded of decoded[tree]) {\n const fields = decode(encoded)\n\n const level_type_name = decode(fields.shift(), ':')\n const m = /^([0-9]+) (.+)/.exec(level_type_name[0])\n if (!m) break\n\n const level = parseInt(m[1])\n const type = m[2] // test for StaticGroup?\n\n if (type === 'AllEntriesGroup') continue // root\n\n const name = level_type_name[1]\n const intersection = decode(fields.shift())[0]\n const keys = tree === 'grouping' ? [] : fields.map(field => decode(field)[0])\n\n const group = {\n name,\n entries: keys,\n groups: [],\n }\n\n result.groups[name] = result.groups[name] || group\n\n if (levels.length < level) {\n levels.push(group)\n }\n else {\n levels[level - 1] = group\n }\n\n if (level === 1) {\n result.root.push(group)\n }\n else {\n const parent: Group = levels[level - 2]\n switch (intersection) {\n case '0': // independent\n break\n case '1': // intersect\n group.entries = group.entries.filter(key => parent.entries.includes(key))\n break\n case '2': // union\n group.entries = group.entries.concat(parent.entries.filter(key => !group.entries.includes(key)))\n break\n }\n\n levels[level - 2].groups.push(group)\n }\n }\n }\n\n return { comments, jabref: result }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["function decode(s, sep = ';') {\n s = s.replace(/\\r?\\n/g, '')\n let pos = 0\n const records = ['']\n while (pos < s.length) {\n switch (s[pos]) {\n case '\\\\':\n pos++\n records[0] += s[pos]\n break\n\n case sep:\n records.unshift('')\n break\n\n default:\n records[0] += s[pos]\n }\n pos++\n }\n return records.reverse().filter(record => record)\n}\n\n/**\n * A JabRef group.\n */\nexport interface Group {\n /**\n * the group name\n */\n name: string\n\n /**\n * The citation keys which are specified to belong to this group, after intersection calculation has been applied\n */\n entries: string[]\n\n /**\n * Sub-groups under this group\n */\n groups: Group[]\n}\n\nexport interface JabRefMetadata {\n /**\n * The root groups. You can find the nested groups in their `groups` property\n */\n root: Group[]\n\n /**\n * JabRef since 3.8 has changed their groups format. Entries have a `groups` field which has the names of the groups they belong to -- this name does not have to be unique in the groups hierarchy so if you\n * have multiple groups with the same name, it's not well-defined where the entries should end up. This property gives you the for each group name the first time the group showed up in the hierarchy. Note that\n * keys from the entries themselves have *not* yet been added to the [[Group]]s. You need to combine this yourself as you're parsing the entries.\n */\n groups: { [key: string]: Group }\n\n /**\n * The base path for file paths\n */\n fileDirectory?: string\n\n /**\n * The JabRef metadata format version\n */\n groupsversion?: number\n\n /**\n * The JabRef metadata database type\n */\n databaseType?: string\n}\n\n/**\n * Import the JabRef groups from the `@string` comments in which they were stored. You would typically pass the comments parsed by [[bibtex.parse]] in here.\n *\n * JabRef knows several group types, and this parser parses most, but not all of them:\n *\n * * independent group: the keys listed in the group are the entries that are considered to belong to it\n * * intersection: the keys listed in the group are considered to belong to the group if they're also in the parent group\n * * union: the keys listed in the group are considered to belong to the group, and also the keys that are in the parent group\n * * query: not supported by this parser\n */\nexport function parse(comments: string[]): { comments: string[]; jabref: JabRefMetadata } {\n const result: JabRefMetadata = {\n root: [],\n groups: {},\n }\n\n const levels: Group[] = []\n\n const decoded = {\n fileDirectory: null as string[] | null,\n groupsversion: null as string[] | null,\n groupstree: null as string[] | null,\n grouping: null as string[] | null,\n databaseType: null as string[] | null,\n }\n\n comments = comments.filter(comment => {\n const m = comment.match(/^jabref-meta:\\s*([^:]+):([\\s\\S]*)/) // use \\s\\S because mozilla doesn't understand /s\n if (m) {\n decoded[m[1]] = decode(m[2])\n return false\n }\n return true\n })\n\n if (decoded.groupsversion) result.groupsversion = parseInt(decoded.groupsversion[0].trim()) // eslint-disable-line @typescript-eslint/no-unsafe-argument\n if (decoded.fileDirectory) result.fileDirectory = decoded.fileDirectory[0]\n if (decoded.databaseType) result.databaseType = decoded.databaseType[0]\n\n for (const tree of ['groupstree', 'grouping']) {\n if (!decoded[tree]) continue\n\n for (const encoded of decoded[tree]) {\n const fields = decode(encoded)\n\n const level_type_name = decode(fields.shift(), ':')\n const m = /^([0-9]+) (.+)/.exec(level_type_name[0])\n if (!m) break\n\n const level = parseInt(m[1])\n const type = m[2] // test for StaticGroup?\n\n if (type === 'AllEntriesGroup') continue // root\n\n const name = level_type_name[1]\n const intersection = decode(fields.shift())[0]\n const keys = tree === 'grouping' ? [] : fields.map(field => decode(field)[0])\n\n const group = {\n name,\n entries: keys,\n groups: [],\n }\n\n result.groups[name] = result.groups[name] || group\n\n if (levels.length < level) {\n levels.push(group)\n }\n else {\n levels[level - 1] = group\n }\n\n if (level === 1) {\n result.root.push(group)\n }\n else {\n const parent: Group = levels[level - 2]\n switch (intersection) {\n case '0': // independent\n break\n case '1': // intersect\n group.entries = group.entries.filter(key => parent.entries.includes(key))\n break\n case '2': // union\n group.entries = group.entries.concat(parent.entries.filter(key => !group.entries.includes(key)))\n break\n }\n\n levels[level - 2].groups.push(group)\n }\n }\n }\n\n return { comments, jabref: result }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../sentence-case.ts"],
4
- "sourcesContent": ["import { merge } from './merge.js'\nimport type { Token } from './tokenizer.js'\nimport { tokenize } from './tokenizer.js'\n\nconst connectedInnerWord = /-\\p{Lu}\\p{Ll}*(?=-|$)/ug\n\n// const show = (obj: any): string => JSON.stringify(obj, null, 2).replace(/[\\u007F-\\uFFFF]/g, chr => `\\\\u${(`0000${chr.charCodeAt(0).toString(16)}`).substr(-4)}`)\n\nfunction titleCase(s: string): string {\n return s.replace(/^(.)(.+)/, (match, car, cdr) => `${car}${cdr.toLowerCase()}`)\n}\n\nfunction wordSC(token: Token, allCaps: boolean, subSentence: boolean, hyphenated: boolean): string {\n // domains are case-insensitive\n if (token.type === 'domain') return token.text.toLowerCase()\n\n // punctuation needs no handling, and websites can have case-sensitive stuff in the URL\n if (token.type !== 'word') return token.text\n\n // I'll, I'm\n if (token.text.match(/^I'/)) return titleCase(token.text)\n\n // starting 'a'\n if (subSentence && token.subSentenceStart && token.text.match(/^a$/i)) return 'a'\n\n // (sub)sentence start\n if ((subSentence && token.subSentenceStart) || token.sentenceStart) {\n return allCaps ? titleCase(token.text) : token.text.replace(connectedInnerWord, match => match.toLowerCase())\n }\n\n // prepositions should already have been lowercased, but OK\n if (token.subtype === 'preposition') return token.text.toLowerCase()\n\n // keep acronyms\n if (token.subtype === 'acronym') return token.text\n\n // if (!allCaps && token.shape.match(/^[Xxd]+(-[Xxd]+)+/)) return XRegExp.replace(token.text, connectedWord, match => match.toLowerCase())\n\n // single-letter capitals are usually some kind of noun, but not when they're part of an hyphenated word\n if (token.text.match(/^[B-Z]$/)) return hyphenated ? token.text.toLowerCase() : token.text\n\n // ?? if (!allCaps && token.shape.match(/^[-X]+$/)) return token.text\n\n const shape = token.shape.replace(/[^-Xxd]/g, '')\n // ?? if (!allCaps && shape.match(/^[Xd-]+$/)) return token.text\n\n // hyphenated ?? if (shape.match(/^X[xd]*(-[Xxd]*)*$/)) return token.text.toLowerCase()\n\n // all-caps and numbers\n if (shape.match(/^[Xd]+$/)) return allCaps ? token.text.toLowerCase() : token.text\n\n // domain ?? if (token.text.includes('.')) return token.text\n if (shape.match(/x.*X/)) return token.text\n\n return token.text.toLowerCase()\n}\n\nexport type Options = {\n preserveQuoted?: boolean\n subSentenceCapitalization?: boolean\n markup?: RegExp\n nocase?: RegExp\n guess?: boolean\n}\n\nexport function toSentenceCase(title: string, options: Options = {}): string {\n options = merge(options, {\n preserveQuoted: true,\n subSentenceCapitalization: true,\n guess: false,\n })\n\n const allCaps = title === title.toUpperCase()\n const allLower = title === title.toLowerCase()\n if (options.guess && !allCaps && !allLower) {\n let $title = title\n if (options.nocase) $title = $title.replace(options.nocase, match => match.match(/\\s/) ? ' ' : '')\n if (options.markup) $title = $title.replace(options.markup, '')\n\n const guess = {\n words: tokenize($title),\n sc: 0,\n other: 0,\n }\n\n guess.words.forEach((token, i) => {\n if (token.type === 'word' && token.text.length > 1 && !token.subtype.match(/preposition|acronym|ordinal/) && (i === 0 || guess.words[i - 1].type === 'whitespace')) {\n guess[token.shape.match(/^[^X]*x[^X]*$/) ? 'sc' : 'other'] += 1\n }\n })\n if (guess.sc && guess.sc >= guess.other) return title\n }\n\n if (allCaps && !title.match(/\\s/)) return title\n\n const tokens = tokenize(title, options.markup)\n\n let sentenceCased = ''\n for (const token of tokens) {\n if (token.hyphenated && token.shape[0] === 'x') {\n sentenceCased += token.text\n }\n else if (token.hyphenated) {\n for (const t of token.hyphenated) {\n sentenceCased += wordSC(t, allCaps, options.subSentenceCapitalization, true)\n }\n }\n else {\n sentenceCased += wordSC(token, allCaps, options.subSentenceCapitalization, false)\n }\n }\n\n if (options.markup) {\n for (const match of title.matchAll(options.markup)) {\n sentenceCased = sentenceCased.substring(0, match.index) + match[0] + sentenceCased.substring(match.index + match[0].length)\n }\n }\n\n if (options.nocase) {\n sentenceCased = sentenceCased\n .replace(options.nocase, (match: string, tag: string, offset: number) => title.substring(offset, offset + match.length))\n }\n\n if (options.preserveQuoted) {\n for (const q of [/\u201C.*?\u201D/g, /\u2018.*?\u2019/g, /\".*?\"/g]) {\n sentenceCased = sentenceCased.replace(q, (match: string, offset: number) => title.substring(offset, offset + match.length))\n }\n }\n\n return sentenceCased\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { merge } from './merge.js'\nimport type { Token } from './tokenizer.js'\nimport { tokenize } from './tokenizer.js'\n\nconst connectedInnerWord = /-\\p{Lu}\\p{Ll}*(?=-|$)/ug\n\n// const show = (obj: any): string => JSON.stringify(obj, null, 2).replace(/[\\u007F-\\uFFFF]/g, chr => `\\\\u${(`0000${chr.charCodeAt(0).toString(16)}`).substr(-4)}`)\n\nfunction titleCase(s: string): string {\n return s.replace(/^(.)(.+)/, (match, car, cdr) => `${car}${cdr.toLowerCase()}`)\n}\n\nfunction wordSC(token: Token, allCaps: boolean, subSentence: boolean, hyphenated: boolean): string {\n // domains are case-insensitive\n if (token.type === 'domain') return token.text.toLowerCase()\n\n // punctuation needs no handling, and websites can have case-sensitive stuff in the URL\n if (token.type !== 'word') return token.text\n\n // I'll, I'm\n if (token.text.match(/^I'/)) return titleCase(token.text)\n\n // starting 'a'\n if (subSentence && token.subSentenceStart && token.text.match(/^a$/i)) return 'a'\n\n // (sub)sentence start\n if ((subSentence && token.subSentenceStart) || token.sentenceStart) {\n return allCaps ? titleCase(token.text) : token.text.replace(connectedInnerWord, match => match.toLowerCase())\n }\n\n // prepositions should already have been lowercased, but OK\n if (token.subtype === 'preposition') return token.text.toLowerCase()\n\n // keep acronyms\n if (token.subtype === 'acronym') return token.text\n\n // if (!allCaps && token.shape.match(/^[Xxd]+(-[Xxd]+)+/)) return XRegExp.replace(token.text, connectedWord, match => match.toLowerCase())\n\n // single-letter capitals are usually some kind of noun, but not when they're part of an hyphenated word\n if (token.text.match(/^[B-Z]$/)) return hyphenated ? token.text.toLowerCase() : token.text\n\n // ?? if (!allCaps && token.shape.match(/^[-X]+$/)) return token.text\n\n const shape = token.shape.replace(/[^-Xxd]/g, '')\n // ?? if (!allCaps && shape.match(/^[Xd-]+$/)) return token.text\n\n // hyphenated ?? if (shape.match(/^X[xd]*(-[Xxd]*)*$/)) return token.text.toLowerCase()\n\n // all-caps and numbers\n if (shape.match(/^[Xd]+$/)) return allCaps ? token.text.toLowerCase() : token.text\n\n // domain ?? if (token.text.includes('.')) return token.text\n if (shape.match(/x.*X/)) return token.text\n\n return token.text.toLowerCase()\n}\n\nexport type Options = {\n preserveQuoted?: boolean\n subSentenceCapitalization?: boolean\n markup?: RegExp\n nocase?: RegExp\n guess?: boolean\n}\n\nexport function toSentenceCase(title: string, options: Options = {}): string {\n options = merge(options, {\n preserveQuoted: true,\n subSentenceCapitalization: true,\n guess: false,\n })\n\n const allCaps = title === title.toUpperCase()\n const allLower = title === title.toLowerCase()\n if (options.guess && !allCaps && !allLower) {\n let $title = title\n if (options.nocase) $title = $title.replace(options.nocase, match => match.match(/\\s/) ? ' ' : '')\n if (options.markup) $title = $title.replace(options.markup, '')\n\n const guess = {\n words: tokenize($title),\n sc: 0,\n other: 0,\n }\n\n guess.words.forEach((token, i) => {\n if (token.type === 'word' && token.text.length > 1 && !token.subtype.match(/preposition|acronym|ordinal/) && (i === 0 || guess.words[i - 1].type === 'whitespace')) {\n guess[token.shape.match(/^[^X]*x[^X]*$/) ? 'sc' : 'other'] += 1\n }\n })\n if (guess.sc && guess.sc >= guess.other) return title\n }\n\n if (allCaps && !title.match(/\\s/)) return title\n\n const tokens = tokenize(title, options.markup)\n\n let sentenceCased = ''\n for (const token of tokens) {\n if (token.hyphenated && token.shape[0] === 'x') {\n sentenceCased += token.text\n }\n else if (token.hyphenated) {\n for (const t of token.hyphenated) {\n sentenceCased += wordSC(t, allCaps, options.subSentenceCapitalization!, true)\n }\n }\n else {\n sentenceCased += wordSC(token, allCaps, options.subSentenceCapitalization!, false)\n }\n }\n\n if (options.markup) {\n for (const match of title.matchAll(options.markup)) {\n sentenceCased = sentenceCased.substring(0, match.index) + match[0] + sentenceCased.substring(match.index + match[0].length)\n }\n }\n\n if (options.nocase) {\n sentenceCased = sentenceCased\n .replace(options.nocase, (match: string, tag: string, offset: number) => title.substring(offset, offset + match.length))\n }\n\n if (options.preserveQuoted) {\n for (const q of [/\u201C.*?\u201D/g, /\u2018.*?\u2019/g, /\".*?\"/g]) {\n sentenceCased = sentenceCased.replace(q, (match: string, offset: number) => title.substring(offset, offset + match.length))\n }\n }\n\n return sentenceCased\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -57,7 +57,7 @@ const lexer = moo.compile({
57
57
  });
58
58
  const Shape = new class {
59
59
  constructor() {
60
- __publicField(this, "shapes", {});
60
+ __publicField(this, "shapes", /* @__PURE__ */ new Map());
61
61
  __publicField(this, "re", {
62
62
  X: /[\p{Lu}\p{Lt}]/u,
63
63
  x: /[\p{Ll}\p{Lm}\p{Lo}]/u,
@@ -75,12 +75,12 @@ const Shape = new class {
75
75
  return c;
76
76
  }
77
77
  fetch(c) {
78
- if (typeof this.shapes[c] === "undefined") this.shapes[c] = this.match(c);
79
- return this.shapes[c];
78
+ if (!this.shapes.has(c)) this.shapes.set(c, this.match(c));
79
+ return this.shapes.get(c);
80
80
  }
81
81
  shape(t) {
82
- if (!this.shapes[t]) this.shapes[t] = Array.from(t).map((c) => this.fetch(c)).join("");
83
- return this.shapes[t];
82
+ if (!this.shapes.has(t)) this.shapes.set(t, Array.from(t).map((c) => this.fetch(c)).join(""));
83
+ return this.shapes.get(t);
84
84
  }
85
85
  }();
86
86
  function combine(tokens) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../tokenizer.ts"],
4
- "sourcesContent": ["import moo from 'moo'\n\nimport prepositions from './prepositions.js'\n\n// const show = (obj: any): string => JSON.stringify(obj, null, 2).replace(/[\\u007F-\\uFFFF]/g, chr => `\\\\u${(`0000${chr.charCodeAt(0).toString(16)}`).substr(-4)}`)\n\nconst RE = new class {\n public Acronym: RegExp\n public Word: RegExp\n public Contraction: RegExp\n public Whitespace = /[ \\t\\n\\r\\u00A0]+/u\n public Ordinal: RegExp\n public Email: RegExp\n public Handle: RegExp\n public IntOrVersion: RegExp\n public Domain: RegExp\n public Website: RegExp\n public Preposition: RegExp\n public ComplexPreposition = /^([^ \\t\\n\\r\\u00A0]+)([ \\t\\n\\r\\u00A0]+)([^ \\t\\n\\r\\u00A0]+)(?:([ \\t\\n\\r\\u00A0]+)([^ \\t\\n\\r\\u00A0]+))?$/u\n public P = /\\p{P}/u\n\n constructor() {\n const B = '(?=(?:[^\\\\p{L}\\\\p{N}\\\\p{M}\\\\u00AD\\\\u2060]|$))'\n const LNM = '[\\\\p{L}\\\\p{N}\\\\p{M}\\u00AD\\u2060]'\n const W = `${LNM}*?\\\\p{L}${LNM}*`\n\n this.Acronym = new RegExp(`(?:(?:(?:[\\\\p{Lu}\\\\p{Lt}][.]){2,}${B})|(?:(?:vs?[.])(?=[ \\t\\n\\r\\u00A0])))`, 'u')\n this.Word = new RegExp(`${W}${B}`, 'u')\n\n this.Contraction = new RegExp(`${W}['\u2019]${W}${B}`, 'u')\n this.Ordinal = new RegExp(`\\\\d+(?:st|nd|rd|th)${B}`, 'u')\n this.Email = new RegExp(`[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:[.][A-Za-z0-9-]+)+${B}`, 'u')\n this.Handle = new RegExp(`@[A-Za-z0-9-]{2,}${B}`, 'u')\n this.IntOrVersion = new RegExp(`v?\\\\d+(?:\\\\.\\\\d+)*${B}`, 'u')\n this.Domain = new RegExp(`${W}(?:[.]${W})+${B}`, 'u')\n this.Website = new RegExp(`https?://${W}(?:[.]${W})+(?:[^.!? \\t\\n\\r\\u00A0]+|[.!?]${LNM})+`, 'u')\n\n const ci = (s: string): string =>\n s\n .replace(/[a-z]/ig, match => `[${match.toUpperCase()}${match.toLowerCase()}]`)\n .replace(' ', this.Whitespace.source)\n\n this.Preposition = new RegExp(`(?:${prepositions.sort().reverse().map(ci).join('|')})${B}`, 'u')\n }\n}()\n\nconst lexer = moo.compile({\n 'word-preposition': RE.Preposition,\n 'word-acronym': RE.Acronym,\n 'word-contraction': RE.Contraction,\n 'word-ordinal': RE.Ordinal,\n email: RE.Email,\n handle: RE.Handle,\n website: RE.Website,\n domain: RE.Domain,\n word: RE.Word,\n number: RE.IntOrVersion, // eslint-disable-line id-blacklist\n 'punctuation-end': /[?.!](?=[ \\t\\n\\r\\u00A0]|$)/u,\n 'punctuation-colon': /:(?=[ \\t\\n\\r\\u00A0])/u,\n 'punctuation-ellipsis': /[.][.][.]/u,\n punctuation: RE.P,\n whitespace: { match: /[ \\t\\n\\r\\u00A0]/u, lineBreaks: true },\n other: { match: /[\\s\\S]/u, lineBreaks: true },\n})\n\nconst Shape = new class {\n private shapes: Record<string, string> = {}\n private re: Record<string, RegExp> = {\n X: /[\\p{Lu}\\p{Lt}]/u,\n x: /[\\p{Ll}\\p{Lm}\\p{Lo}]/u,\n d: /\\p{N}/u,\n }\n\n private match(c: string): string {\n if (c.match(this.re.d)) return 'd'\n if (c.toLowerCase() === c.toUpperCase()) return c\n if (c.match(this.re.X)) return 'X'\n if (c.match(this.re.x)) return 'x'\n if (c === '\u2019') return \"'\"\n if (c === '\u2013') return '-'\n if (c === '\\u2060' || c === '\\u00AD') return ''\n return c\n }\n\n private fetch(c: string): string {\n if (typeof this.shapes[c] === 'undefined') this.shapes[c] = this.match(c)\n return this.shapes[c]\n }\n\n shape(t: string) {\n if (!this.shapes[t]) this.shapes[t] = Array.from(t).map(c => this.fetch(c)).join('')\n return this.shapes[t]\n }\n}()\n\nexport type Token = {\n type: 'word' | 'domain' | 'whitespace'\n subtype: '' | 'preposition' | 'acronym' | 'whitespace' | 'word' | 'domain'\n text: string\n start: number\n end: number\n shape: string\n sentenceStart: boolean\n subSentenceStart: boolean\n hyphenated?: Token[]\n}\n\nfunction combine(tokens: Token[]) {\n const combined = { ...tokens[0] }\n for (const t of tokens.slice(1)) {\n combined.text += t.text\n combined.end = t.end\n combined.shape += t.shape\n }\n return combined\n}\n\nfunction hyphenate(t: Token) {\n if (t.type === 'word') return 'w'\n if (t.text === '-' || t.text === '\u2013') return '-'\n return ' '\n}\n\nexport function tokenize(title: string, markup?: RegExp): Token[] {\n if (markup) title = title.replace(markup, match => '\\u2060'.repeat(match.length))\n\n lexer.reset(title)\n const tokens: Token[] = []\n let sentenceStart = true\n let subSentenceStart = false\n for (const token of lexer) {\n const [type, subtype] = (token.type.includes('-') ? token.type : `${token.type}-`).split('-')\n\n tokens.push({\n type,\n subtype,\n text: token.text,\n start: token.offset,\n end: token.offset + token.text.length - 1,\n shape: Shape.shape(<string> token.text),\n sentenceStart: type === 'word' && sentenceStart,\n subSentenceStart: type === 'word' && subSentenceStart,\n })\n\n switch (token.type) {\n case 'punctuation-end':\n sentenceStart = true\n break\n case 'punctuation-colon':\n subSentenceStart = true\n break\n default:\n if (type.match(/word|number|handle|domain|website/)) {\n sentenceStart = false\n subSentenceStart = false\n }\n break\n }\n }\n\n const stack = tokens.splice(0)\n\n let cpt: RegExpMatchArray\n let cps: RegExpMatchArray\n while (stack.length) {\n if (stack[0].subtype === 'preposition' && (cpt = stack[0].text.match(RE.ComplexPreposition)) && (cps = stack[0].shape.match(RE.ComplexPreposition))) {\n const complex = stack.shift()\n\n let start = complex.start\n let end\n for (const i of Array.from({ length: 5 }, (_, n) => n + 1)) {\n if (!cpt[i]) break\n\n end = start + cps[i].length - 1\n tokens.push({\n ...complex,\n text: cpt[i],\n shape: cps[i],\n start,\n end,\n type: i % 2 ? complex.type : 'whitespace',\n subtype: i % 2 ? complex.type : '',\n })\n start = end + 1\n }\n continue\n }\n\n // hyphenated words\n const pat = stack.map(t => hyphenate(t)).join('')\n if (cpt = pat.match(/^w(-w)+(?= |$)/)) {\n const hyphenated = stack.splice(0, cpt[0].length)\n tokens.push({ ...combine(hyphenated), hyphenated })\n continue\n }\n\n tokens.push(stack.shift())\n }\n\n return markup ? tokens.map(token => ({ ...token, text: title.substring(token.start, token.end + 1) })) : tokens\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import moo from 'moo'\n\nimport prepositions from './prepositions.js'\n\n// const show = (obj: any): string => JSON.stringify(obj, null, 2).replace(/[\\u007F-\\uFFFF]/g, chr => `\\\\u${(`0000${chr.charCodeAt(0).toString(16)}`).substr(-4)}`)\n\nconst RE = new class {\n public Acronym: RegExp\n public Word: RegExp\n public Contraction: RegExp\n public Whitespace = /[ \\t\\n\\r\\u00A0]+/u\n public Ordinal: RegExp\n public Email: RegExp\n public Handle: RegExp\n public IntOrVersion: RegExp\n public Domain: RegExp\n public Website: RegExp\n public Preposition: RegExp\n public ComplexPreposition = /^([^ \\t\\n\\r\\u00A0]+)([ \\t\\n\\r\\u00A0]+)([^ \\t\\n\\r\\u00A0]+)(?:([ \\t\\n\\r\\u00A0]+)([^ \\t\\n\\r\\u00A0]+))?$/u\n public P = /\\p{P}/u\n\n constructor() {\n const B = '(?=(?:[^\\\\p{L}\\\\p{N}\\\\p{M}\\\\u00AD\\\\u2060]|$))'\n const LNM = '[\\\\p{L}\\\\p{N}\\\\p{M}\\u00AD\\u2060]'\n const W = `${LNM}*?\\\\p{L}${LNM}*`\n\n this.Acronym = new RegExp(`(?:(?:(?:[\\\\p{Lu}\\\\p{Lt}][.]){2,}${B})|(?:(?:vs?[.])(?=[ \\t\\n\\r\\u00A0])))`, 'u')\n this.Word = new RegExp(`${W}${B}`, 'u')\n\n this.Contraction = new RegExp(`${W}['\u2019]${W}${B}`, 'u')\n this.Ordinal = new RegExp(`\\\\d+(?:st|nd|rd|th)${B}`, 'u')\n this.Email = new RegExp(`[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:[.][A-Za-z0-9-]+)+${B}`, 'u')\n this.Handle = new RegExp(`@[A-Za-z0-9-]{2,}${B}`, 'u')\n this.IntOrVersion = new RegExp(`v?\\\\d+(?:\\\\.\\\\d+)*${B}`, 'u')\n this.Domain = new RegExp(`${W}(?:[.]${W})+${B}`, 'u')\n this.Website = new RegExp(`https?://${W}(?:[.]${W})+(?:[^.!? \\t\\n\\r\\u00A0]+|[.!?]${LNM})+`, 'u')\n\n const ci = (s: string): string =>\n s\n .replace(/[a-z]/ig, match => `[${match.toUpperCase()}${match.toLowerCase()}]`)\n .replace(' ', this.Whitespace.source)\n\n this.Preposition = new RegExp(`(?:${prepositions.sort().reverse().map(ci).join('|')})${B}`, 'u')\n }\n}()\n\nconst lexer = moo.compile({\n 'word-preposition': RE.Preposition,\n 'word-acronym': RE.Acronym,\n 'word-contraction': RE.Contraction,\n 'word-ordinal': RE.Ordinal,\n email: RE.Email,\n handle: RE.Handle,\n website: RE.Website,\n domain: RE.Domain,\n word: RE.Word,\n number: RE.IntOrVersion, // eslint-disable-line id-blacklist\n 'punctuation-end': /[?.!](?=[ \\t\\n\\r\\u00A0]|$)/u,\n 'punctuation-colon': /:(?=[ \\t\\n\\r\\u00A0])/u,\n 'punctuation-ellipsis': /[.][.][.]/u,\n punctuation: RE.P,\n whitespace: { match: /[ \\t\\n\\r\\u00A0]/u, lineBreaks: true },\n other: { match: /[\\s\\S]/u, lineBreaks: true },\n})\n\nconst Shape = new class {\n private shapes: Map<string, string> = new Map()\n private re: Record<string, RegExp> = {\n X: /[\\p{Lu}\\p{Lt}]/u,\n x: /[\\p{Ll}\\p{Lm}\\p{Lo}]/u,\n d: /\\p{N}/u,\n }\n\n private match(c: string): string {\n if (c.match(this.re.d)) return 'd'\n if (c.toLowerCase() === c.toUpperCase()) return c\n if (c.match(this.re.X)) return 'X'\n if (c.match(this.re.x)) return 'x'\n if (c === '\u2019') return \"'\"\n if (c === '\u2013') return '-'\n if (c === '\\u2060' || c === '\\u00AD') return ''\n return c\n }\n\n private fetch(c: string): string {\n if (!this.shapes.has(c)) this.shapes.set(c, this.match(c))\n return this.shapes.get(c)!\n }\n\n shape(t: string) {\n if (!this.shapes.has(t)) this.shapes.set(t, Array.from(t).map(c => this.fetch(c)).join(''))\n return this.shapes.get(t)!\n }\n}()\n\nexport type Token = {\n type: 'word' | 'domain' | 'whitespace'\n subtype: '' | 'preposition' | 'acronym' | 'whitespace' | 'word' | 'domain'\n text: string\n start: number\n end: number\n shape: string\n sentenceStart: boolean\n subSentenceStart: boolean\n hyphenated?: Token[]\n}\n\nfunction combine(tokens: Token[]) {\n const combined = { ...tokens[0] }\n for (const t of tokens.slice(1)) {\n combined.text += t.text\n combined.end = t.end\n combined.shape += t.shape\n }\n return combined\n}\n\nfunction hyphenate(t: Token) {\n if (t.type === 'word') return 'w'\n if (t.text === '-' || t.text === '\u2013') return '-'\n return ' '\n}\n\nexport function tokenize(title: string, markup?: RegExp): Token[] {\n if (markup) title = title.replace(markup, match => '\\u2060'.repeat(match.length))\n\n lexer.reset(title)\n const tokens: Token[] = []\n let sentenceStart = true\n let subSentenceStart = false\n for (const token of lexer) {\n const [type, subtype] = (token.type.includes('-') ? token.type : `${token.type}-`).split('-')\n\n tokens.push({\n type,\n subtype,\n text: token.text,\n start: token.offset,\n end: token.offset + token.text.length - 1,\n shape: Shape.shape(<string> token.text)!,\n sentenceStart: type === 'word' && sentenceStart,\n subSentenceStart: type === 'word' && subSentenceStart,\n })\n\n switch (token.type) {\n case 'punctuation-end':\n sentenceStart = true\n break\n case 'punctuation-colon':\n subSentenceStart = true\n break\n default:\n if (type.match(/word|number|handle|domain|website/)) {\n sentenceStart = false\n subSentenceStart = false\n }\n break\n }\n }\n\n const stack = tokens.splice(0)\n\n let cpt: RegExpMatchArray | null\n let cps: RegExpMatchArray | null\n while (stack.length) {\n if (stack[0].subtype === 'preposition' && (cpt = stack[0].text.match(RE.ComplexPreposition)) && (cps = stack[0].shape.match(RE.ComplexPreposition))) {\n const complex = stack.shift()!\n\n let start = complex.start\n let end\n for (const i of Array.from({ length: 5 }, (_, n) => n + 1)) {\n if (!cpt[i]) break\n\n end = start + cps[i].length - 1\n tokens.push({\n ...complex,\n text: cpt[i],\n shape: cps[i],\n start,\n end,\n type: i % 2 ? complex.type : 'whitespace',\n subtype: i % 2 ? complex.type : '',\n })\n start = end + 1\n }\n continue\n }\n\n // hyphenated words\n const pat = stack.map(t => hyphenate(t)).join('')\n if (cpt = pat.match(/^w(-w)+(?= |$)/)) {\n const hyphenated = stack.splice(0, cpt[0].length)\n tokens.push({ ...combine(hyphenated), hyphenated })\n continue\n }\n\n tokens.push(stack.shift()!)\n }\n\n return markup ? tokens.map(token => ({ ...token, text: title.substring(token.start, token.end + 1) })) : tokens\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../verbatim.ts"],
4
- "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-argument */\n// Original work by Henrik Muehe (c) 2010\n//\n// CommonJS port by Mikola Lysenko 2013\n//\n// error recovery and unicode handling by Emiliano Heyns (c) 2017-2024\n\nimport { playnice } from './yield.js'\n\nclass ParsingError extends Error {\n public source: string\n\n constructor(message, parser) {\n message += ` at ${parser.location()}`\n if (parser.parsing) message += ` in ${JSON.stringify(parser.parsing)}`\n super(message)\n this.name = 'ParsingError'\n }\n}\n\nconst letter = /[\\p{Lu}\\p{Lt}\\p{Ll}\\p{Lm}\\p{Lo}]/u\n\nexport type Entry = {\n input: string\n type: string\n key: string\n fields: Record<string, string>\n}\n\nexport interface ParseError {\n error: string\n input?: string\n}\n\nexport interface ParserOptions {\n /**\n * stop parsing after `max_entries` entries have been found. Useful for quick detection if a text file is in fact a bibtex file\n */\n max_entries?: number\n\n /**\n * preload these strings\n */\n strings?: string | Record<string, string>\n}\n\nexport class Library {\n public parsing: string\n\n public entries: Entry[] = []\n public strings: Record<string, string> = {}\n public comments: string[] = []\n public errors: ParseError[] = []\n public preambles: string[] = []\n\n private default_strings: Record<string, string> = {\n JAN: '01',\n JANUARY: '01',\n FEB: '02',\n FEBRUARY: '02',\n MAR: '03',\n MARCH: '03',\n APR: '04',\n APRIL: '04',\n MAY: '05',\n JUN: '06',\n JUNE: '06',\n JUL: '07',\n JULY: '07',\n AUG: '08',\n AUGUST: '08',\n SEP: '09',\n SEPTEMBER: '09',\n OCT: '10',\n OCTOBER: '10',\n NOV: '11',\n NOVEMBER: '11',\n DEC: '12',\n DECEMBER: '12',\n ACMCS: 'ACM Computing Surveys',\n ACTA: 'Acta Informatica',\n CACM: 'Communications of the ACM',\n IBMJRD: 'IBM Journal of Research and Development',\n IBMSJ: 'IBM Systems Journal',\n IEEESE: 'IEEE Transactions on Software Engineering',\n IEEETC: 'IEEE Transactions on Computers',\n IEEETCAD: 'IEEE Transactions on Computer-Aided Design of Integrated Circuits',\n IPL: 'Information Processing Letters',\n JACM: 'Journal of the ACM',\n JCSS: 'Journal of Computer and System Sciences',\n SCP: 'Science of Computer Programming',\n SICOMP: 'SIAM Journal on Computing',\n TOCS: 'ACM Transactions on Computer Systems',\n TODS: 'ACM Transactions on Database Systems',\n TOG: 'ACM Transactions on Graphics',\n TOMS: 'ACM Transactions on Mathematical Software',\n TOOIS: 'ACM Transactions on Office Information Systems',\n TOPLAS: 'ACM Transactions on Programming Languages and Systems',\n TCS: 'Theoretical Computer Science',\n }\n\n private pos = 0\n private linebreaks: number[] = []\n private input: string\n\n private max_entries: number\n\n constructor(input: string, options: ParserOptions = {}) {\n this.max_entries = options.max_entries || 0\n this.input = input\n this.parsing = null\n\n if (typeof options.strings === 'string') {\n this.input = options.strings + '\\n' + input // eslint-disable-line prefer-template\n }\n else if (options.strings) {\n for (const [k, v] of Object.entries(options.strings)) {\n this.default_strings[k.toUpperCase()] = v\n }\n }\n\n let pos = input.indexOf('\\n')\n while (pos !== -1) {\n this.linebreaks.push(pos)\n pos = input.indexOf('\\n', pos + 1)\n }\n }\n\n public parse(): void {\n this.bibtex()\n this.entries.reverse()\n }\n\n public async parseAsync(): Promise<void> {\n await this.bibtexAsync()\n this.entries.reverse()\n }\n\n private isWhitespace(s, horizontalOnly = false) {\n return (s === ' ' || s === '\\t' || (!horizontalOnly && (s === '\\r' || s === '\\n')))\n }\n\n private match(s, sws = true) {\n this.skipWhitespace()\n if (this.input.substr(this.pos, s.length) !== s) {\n throw new ParsingError(`Token mismatch, expected ${JSON.stringify(s)}, found ${JSON.stringify(this.input.substr(this.pos, 20))}...`, this)\n }\n\n this.pos += s.length\n if (sws) this.skipWhitespace()\n }\n\n private tryMatch(s, consume = false) {\n this.skipWhitespace()\n const match = this.input.substr(this.pos, s.length) === s\n if (match && consume) this.pos += s.length\n return match\n // this.skipWhitespace()\n }\n\n private skipWhitespace() {\n while (this.pos < this.input.length && this.input[this.pos].match(/[ \\t\\r\\n%]/)) {\n // test for '%' is shady\n if (this.input[this.pos] === '%') {\n while (this.pos < this.input.length && this.input[this.pos] !== '\\n') this.pos++\n }\n else {\n this.pos++\n }\n }\n }\n\n /*\n private fix_path() {\n // workaround for https://github.com/siefkenj/unified-latex/issues/94\n const path = '\\\\path|'\n const verb = path.replace('path', 'verb')\n if (this.input.substring(this.pos).startsWith(path)) {\n // eslint-disable-next-line prefer-template\n this.input = this.input.substring(0, this.pos) + verb + this.input.substring(this.pos + path.length)\n }\n }\n */\n\n private value_braces() {\n let bracecount = 0\n this.match('{', false)\n const start = this.pos\n let math = false\n\n while (true) {\n // this.fix_path()\n\n switch (this.input[this.pos]) {\n case '\\\\':\n this.pos += 1\n break\n\n case '{':\n bracecount++\n break\n\n case '}':\n if (bracecount === 0) {\n if (math) throw new ParsingError('Unclosed math section', this)\n this.pos++\n return this.input.substring(start, this.pos - 1)\n }\n bracecount--\n break\n\n case '$':\n math = !math\n break\n }\n\n this.pos++\n\n if (this.pos >= this.input.length) {\n throw new ParsingError(`Unterminated brace-value ${JSON.stringify(this.input.substr(start, 20))}`, this)\n }\n }\n }\n\n private value_quotes() {\n this.match('\"', false)\n const start = this.pos\n let bracecount = 0\n while (true) {\n // this.fix_path()\n\n switch (this.input[this.pos]) {\n case '\\\\':\n this.pos += 1\n break\n\n case '{':\n bracecount++\n break\n\n case '}':\n bracecount--\n break\n\n case '\"':\n if (bracecount <= 0) {\n this.pos++\n return this.input.substring(start, this.pos - 1)\n }\n }\n\n this.pos++\n\n if (this.pos >= this.input.length) {\n throw new ParsingError(`Unterminated quote-value ${JSON.stringify(this.input.substr(start, 20))}`, this)\n }\n }\n }\n\n private single_value() {\n if (this.tryMatch('{')) {\n return this.value_braces()\n }\n else if (this.tryMatch('\"')) {\n return this.value_quotes()\n }\n else {\n const bare = this.key()\n if (bare.match(/^\\d+$/)) return bare\n\n const u_bare = bare.toUpperCase()\n const resolved = this.strings[u_bare] || this.default_strings[u_bare]\n if (typeof resolved === 'undefined') {\n this.error({\n error: `Unresolved @string reference ${JSON.stringify(bare)}`,\n input: '',\n })\n }\n return resolved || `{{${bare}}}`\n }\n }\n\n location(): string {\n const lines = this.input.substring(0, this.pos).split('\\n')\n return `line ${lines.length}, column ${lines[lines.length - 1].length + 1}`\n }\n\n error(err: ParseError): void {\n if (this.errors.find(e => e.error === err.error)) return\n this.errors.push(err)\n }\n\n private value() {\n const values = []\n values.push(this.single_value())\n while (this.tryMatch('#')) {\n this.match('#')\n values.push(this.single_value())\n }\n return values.join('')\n }\n\n private key(allow = ''): string {\n const start = this.pos\n while (true) {\n if (this.pos === this.input.length) {\n throw new ParsingError('Runaway key', this)\n }\n\n if (this.input[this.pos].match(/[+'a-zA-Z0-9&;_:\\\\./-]/) || this.input[this.pos].match(letter) || allow.includes(this.input[this.pos])) {\n this.pos++\n }\n else {\n return this.input.substring(start, this.pos)\n }\n }\n }\n\n private key_equals_value(key?: string) {\n key = key || this.key()\n if (!key) return // no key found, stray comma\n\n if (!this.tryMatch('=')) {\n throw new ParsingError(`${key} = value expected, equals sign missing: ${JSON.stringify(this.input.substr(this.pos, 20))}...`, this)\n }\n\n this.match('=')\n const val = this.value()\n\n if (this.parsing === 'string') {\n this.strings[key.toUpperCase()] = val\n }\n else {\n const bare = key.toLowerCase()\n let postfix = 0\n while (typeof this.entries[0].fields[key = postfix ? `${bare}+duplicate-${postfix}` : bare] === 'string') {\n postfix++\n }\n this.entries[0].fields[key] = val\n }\n }\n\n private entry(d: string, guard: string) {\n if (this.tryMatch(guard)) return // empty entry\n\n let key: string\n // mendeley end endnote can output entries without key... sure...\n if (this.tryMatch(',')) {\n // mendeley absurdity which outputs keyless entries, but at least have the decency to put a comma there\n key = ''\n }\n else {\n // so maybe a real key?\n key = this.key('[]*\"')\n }\n\n if (this.tryMatch('=')) {\n // nope; endnote just skips the comma; we can infer we're in this moronic situation because we've been dumped into field-parsing\n this.key_equals_value(key)\n }\n else {\n // so we did find the real key earlier\n this.entries[0].key = key\n }\n this.tryMatch(',', true)\n if (this.tryMatch(guard)) return // no fields\n\n this.key_equals_value()\n while (this.tryMatch(',', true)) {\n // fixes problems with commas at the end of a list\n if (this.tryMatch(guard)) return\n\n this.key_equals_value()\n }\n }\n\n private directive() {\n this.match('@')\n return this.key().toLowerCase()\n }\n\n private string() { // eslint-disable-line id-blacklist\n this.key_equals_value()\n }\n\n private preamble() {\n this.preambles.push(this.value())\n }\n\n private comment() {\n while (this.isWhitespace(this.input[this.pos], true)) this.pos++\n\n if (this.input[this.pos] === '{') {\n this.comments.push(this.value_braces())\n }\n else {\n const start = this.pos\n while (this.input[this.pos] !== '\\n' && this.pos < this.input.length) this.pos++\n this.comments.push(this.input.substring(start, this.pos))\n }\n }\n\n private hasMore() {\n if (this.max_entries && this.entries.length >= this.max_entries) return false\n return (this.pos < this.input.length)\n }\n\n private bibtex() {\n while (this.hasMore()) {\n this.parseNext()\n }\n }\n\n private async bibtexAsync() {\n let n = 1\n while (this.hasMore()) {\n this.parseNext()\n if ((n++ % 1000) === 0) await playnice()\n }\n }\n\n private matchGuard() {\n for (const guard of ['{}', '()']) {\n if (this.tryMatch(guard[0])) {\n this.match(guard[0])\n return guard[1]\n }\n }\n\n throw new ParsingError(`Token mismatch, expected '{' or '(', found ${JSON.stringify(this.input.substr(this.pos, 20))}...`, this)\n }\n\n private parseNext() {\n this.skipWhitespace()\n\n while (this.pos < this.input.length && this.input[this.pos] !== '@') {\n if (this.input[this.pos] === '%') {\n while (this.pos < this.input.length && this.input[this.pos] !== '\\n') this.pos++\n }\n else {\n this.pos++\n }\n }\n if (this.pos >= this.input.length) return\n\n let guard = ''\n const start = this.pos\n try {\n const d = this.parsing = this.directive()\n switch (d) {\n case 'string':\n guard = this.matchGuard()\n this.string()\n this.match(guard)\n break\n\n case 'preamble':\n this.preamble()\n break\n\n case 'comment':\n this.comment()\n break\n\n default:\n guard = this.matchGuard()\n this.entries.unshift({ input: '', type: d, key: '', fields: {} })\n this.entry(d, guard)\n this.match(guard)\n this.entries[0].input = this.input.substring(start, this.pos).trim()\n break\n }\n }\n catch (err) {\n if (err.name !== 'ParsingError') throw err\n // skip ahead to the next @ and try again\n this.pos = start + 1\n while (this.pos < this.input.length && this.input[this.pos] !== '@') this.pos++\n this.error({\n error: err.message,\n input: this.input.substring(start, this.pos),\n })\n }\n }\n}\n\n/**\n * Parses a bibtex source in verbatim mode. Good for detection of bibtex and for later LaTeX-reparsing.\n */\nexport function parse(input: string, options: ParserOptions = {}): Library {\n const parser = new Library(input, options)\n parser.parse()\n return parser\n}\n\nexport const promises = {\n async parse(input: string, options: ParserOptions = {}): Promise<Library> {\n const parser = new Library(input, options)\n await parser.parseAsync()\n return parser\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable @typescript-eslint/no-unsafe-argument */\n// Original work by Henrik Muehe (c) 2010\n//\n// CommonJS port by Mikola Lysenko 2013\n//\n// error recovery and unicode handling by Emiliano Heyns (c) 2017-2024\n\nimport { playnice } from './yield.js'\n\nclass ParsingError extends Error {\n public source!: string\n\n constructor(message, parser) {\n message += ` at ${parser.location()}`\n if (parser.parsing) message += ` in ${JSON.stringify(parser.parsing)}`\n super(message)\n this.name = 'ParsingError'\n }\n}\n\nconst letter = /[\\p{Lu}\\p{Lt}\\p{Ll}\\p{Lm}\\p{Lo}]/u\n\nexport type Entry = {\n input: string\n type: string\n key: string\n fields: Record<string, string>\n}\n\nexport interface ParseError {\n error: string\n input?: string\n}\n\nexport interface ParserOptions {\n /**\n * stop parsing after `max_entries` entries have been found. Useful for quick detection if a text file is in fact a bibtex file\n */\n max_entries?: number\n\n /**\n * preload these strings\n */\n strings?: string | Record<string, string>\n}\n\nexport class Library {\n public parsing: string | null\n\n public entries: Entry[] = []\n public strings: Record<string, string> = {}\n public comments: string[] = []\n public errors: ParseError[] = []\n public preambles: string[] = []\n\n private default_strings: Record<string, string> = {\n JAN: '01',\n JANUARY: '01',\n FEB: '02',\n FEBRUARY: '02',\n MAR: '03',\n MARCH: '03',\n APR: '04',\n APRIL: '04',\n MAY: '05',\n JUN: '06',\n JUNE: '06',\n JUL: '07',\n JULY: '07',\n AUG: '08',\n AUGUST: '08',\n SEP: '09',\n SEPTEMBER: '09',\n OCT: '10',\n OCTOBER: '10',\n NOV: '11',\n NOVEMBER: '11',\n DEC: '12',\n DECEMBER: '12',\n ACMCS: 'ACM Computing Surveys',\n ACTA: 'Acta Informatica',\n CACM: 'Communications of the ACM',\n IBMJRD: 'IBM Journal of Research and Development',\n IBMSJ: 'IBM Systems Journal',\n IEEESE: 'IEEE Transactions on Software Engineering',\n IEEETC: 'IEEE Transactions on Computers',\n IEEETCAD: 'IEEE Transactions on Computer-Aided Design of Integrated Circuits',\n IPL: 'Information Processing Letters',\n JACM: 'Journal of the ACM',\n JCSS: 'Journal of Computer and System Sciences',\n SCP: 'Science of Computer Programming',\n SICOMP: 'SIAM Journal on Computing',\n TOCS: 'ACM Transactions on Computer Systems',\n TODS: 'ACM Transactions on Database Systems',\n TOG: 'ACM Transactions on Graphics',\n TOMS: 'ACM Transactions on Mathematical Software',\n TOOIS: 'ACM Transactions on Office Information Systems',\n TOPLAS: 'ACM Transactions on Programming Languages and Systems',\n TCS: 'Theoretical Computer Science',\n }\n\n private pos = 0\n private linebreaks: number[] = []\n private input: string\n\n private max_entries: number\n\n constructor(input: string, options: ParserOptions = {}) {\n this.max_entries = options.max_entries || 0\n this.input = input\n this.parsing = null\n\n if (typeof options.strings === 'string') {\n this.input = options.strings + '\\n' + input // eslint-disable-line prefer-template\n }\n else if (options.strings) {\n for (const [k, v] of Object.entries(options.strings)) {\n this.default_strings[k.toUpperCase()] = v\n }\n }\n\n let pos = input.indexOf('\\n')\n while (pos !== -1) {\n this.linebreaks.push(pos)\n pos = input.indexOf('\\n', pos + 1)\n }\n }\n\n public parse(): void {\n this.bibtex()\n this.entries.reverse()\n }\n\n public async parseAsync(): Promise<void> {\n await this.bibtexAsync()\n this.entries.reverse()\n }\n\n private isWhitespace(s, horizontalOnly = false) {\n return (s === ' ' || s === '\\t' || (!horizontalOnly && (s === '\\r' || s === '\\n')))\n }\n\n private match(s, sws = true) {\n this.skipWhitespace()\n if (this.input.substr(this.pos, s.length) !== s) {\n throw new ParsingError(`Token mismatch, expected ${JSON.stringify(s)}, found ${JSON.stringify(this.input.substr(this.pos, 20))}...`, this)\n }\n\n this.pos += s.length\n if (sws) this.skipWhitespace()\n }\n\n private tryMatch(s, consume = false) {\n this.skipWhitespace()\n const match = this.input.substr(this.pos, s.length) === s\n if (match && consume) this.pos += s.length\n return match\n // this.skipWhitespace()\n }\n\n private skipWhitespace() {\n while (this.pos < this.input.length && this.input[this.pos].match(/[ \\t\\r\\n%]/)) {\n // test for '%' is shady\n if (this.input[this.pos] === '%') {\n while (this.pos < this.input.length && this.input[this.pos] !== '\\n') this.pos++\n }\n else {\n this.pos++\n }\n }\n }\n\n /*\n private fix_path() {\n // workaround for https://github.com/siefkenj/unified-latex/issues/94\n const path = '\\\\path|'\n const verb = path.replace('path', 'verb')\n if (this.input.substring(this.pos).startsWith(path)) {\n // eslint-disable-next-line prefer-template\n this.input = this.input.substring(0, this.pos) + verb + this.input.substring(this.pos + path.length)\n }\n }\n */\n\n private value_braces() {\n let bracecount = 0\n this.match('{', false)\n const start = this.pos\n let math = false\n\n while (true) {\n // this.fix_path()\n\n switch (this.input[this.pos]) {\n case '\\\\':\n this.pos += 1\n break\n\n case '{':\n bracecount++\n break\n\n case '}':\n if (bracecount === 0) {\n if (math) throw new ParsingError('Unclosed math section', this)\n this.pos++\n return this.input.substring(start, this.pos - 1)\n }\n bracecount--\n break\n\n case '$':\n math = !math\n break\n }\n\n this.pos++\n\n if (this.pos >= this.input.length) {\n throw new ParsingError(`Unterminated brace-value ${JSON.stringify(this.input.substr(start, 20))}`, this)\n }\n }\n }\n\n private value_quotes() {\n this.match('\"', false)\n const start = this.pos\n let bracecount = 0\n while (true) {\n // this.fix_path()\n\n switch (this.input[this.pos]) {\n case '\\\\':\n this.pos += 1\n break\n\n case '{':\n bracecount++\n break\n\n case '}':\n bracecount--\n break\n\n case '\"':\n if (bracecount <= 0) {\n this.pos++\n return this.input.substring(start, this.pos - 1)\n }\n }\n\n this.pos++\n\n if (this.pos >= this.input.length) {\n throw new ParsingError(`Unterminated quote-value ${JSON.stringify(this.input.substr(start, 20))}`, this)\n }\n }\n }\n\n private single_value() {\n if (this.tryMatch('{')) {\n return this.value_braces()\n }\n else if (this.tryMatch('\"')) {\n return this.value_quotes()\n }\n else {\n const bare = this.key()\n if (bare.match(/^\\d+$/)) return bare\n\n const u_bare = bare.toUpperCase()\n const resolved = this.strings[u_bare] || this.default_strings[u_bare]\n if (typeof resolved === 'undefined') {\n this.error({\n error: `Unresolved @string reference ${JSON.stringify(bare)}`,\n input: '',\n })\n }\n return resolved || `{{${bare}}}`\n }\n }\n\n location(): string {\n const lines = this.input.substring(0, this.pos).split('\\n')\n return `line ${lines.length}, column ${lines[lines.length - 1].length + 1}`\n }\n\n error(err: ParseError): void {\n if (this.errors.find(e => e.error === err.error)) return\n this.errors.push(err)\n }\n\n private value() {\n const values: string[] = []\n values.push(this.single_value())\n while (this.tryMatch('#')) {\n this.match('#')\n values.push(this.single_value())\n }\n return values.join('')\n }\n\n private key(allow = ''): string {\n const start = this.pos\n while (true) {\n if (this.pos === this.input.length) {\n throw new ParsingError('Runaway key', this)\n }\n\n if (this.input[this.pos].match(/[+'a-zA-Z0-9&;_:\\\\./-]/) || this.input[this.pos].match(letter) || allow.includes(this.input[this.pos])) {\n this.pos++\n }\n else {\n return this.input.substring(start, this.pos)\n }\n }\n }\n\n private key_equals_value(key?: string) {\n key = key || this.key()\n if (!key) return // no key found, stray comma\n\n if (!this.tryMatch('=')) {\n throw new ParsingError(`${key} = value expected, equals sign missing: ${JSON.stringify(this.input.substr(this.pos, 20))}...`, this)\n }\n\n this.match('=')\n const val = this.value()\n\n if (this.parsing === 'string') {\n this.strings[key.toUpperCase()] = val\n }\n else {\n const bare = key.toLowerCase()\n let postfix = 0\n while (typeof this.entries[0].fields[key = postfix ? `${bare}+duplicate-${postfix}` : bare] === 'string') {\n postfix++\n }\n this.entries[0].fields[key] = val\n }\n }\n\n private entry(d: string, guard: string) {\n if (this.tryMatch(guard)) return // empty entry\n\n let key: string\n // mendeley end endnote can output entries without key... sure...\n if (this.tryMatch(',')) {\n // mendeley absurdity which outputs keyless entries, but at least have the decency to put a comma there\n key = ''\n }\n else {\n // so maybe a real key?\n key = this.key('[]*\"')\n }\n\n if (this.tryMatch('=')) {\n // nope; endnote just skips the comma; we can infer we're in this moronic situation because we've been dumped into field-parsing\n this.key_equals_value(key)\n }\n else {\n // so we did find the real key earlier\n this.entries[0].key = key\n }\n this.tryMatch(',', true)\n if (this.tryMatch(guard)) return // no fields\n\n this.key_equals_value()\n while (this.tryMatch(',', true)) {\n // fixes problems with commas at the end of a list\n if (this.tryMatch(guard)) return\n\n this.key_equals_value()\n }\n }\n\n private directive() {\n this.match('@')\n return this.key().toLowerCase()\n }\n\n private string() { // eslint-disable-line id-blacklist\n this.key_equals_value()\n }\n\n private preamble() {\n this.preambles.push(this.value())\n }\n\n private comment() {\n while (this.isWhitespace(this.input[this.pos], true)) this.pos++\n\n if (this.input[this.pos] === '{') {\n this.comments.push(this.value_braces())\n }\n else {\n const start = this.pos\n while (this.input[this.pos] !== '\\n' && this.pos < this.input.length) this.pos++\n this.comments.push(this.input.substring(start, this.pos))\n }\n }\n\n private hasMore() {\n if (this.max_entries && this.entries.length >= this.max_entries) return false\n return (this.pos < this.input.length)\n }\n\n private bibtex() {\n while (this.hasMore()) {\n this.parseNext()\n }\n }\n\n private async bibtexAsync() {\n let n = 1\n while (this.hasMore()) {\n this.parseNext()\n if ((n++ % 1000) === 0) await playnice()\n }\n }\n\n private matchGuard() {\n for (const guard of ['{}', '()']) {\n if (this.tryMatch(guard[0])) {\n this.match(guard[0])\n return guard[1]\n }\n }\n\n throw new ParsingError(`Token mismatch, expected '{' or '(', found ${JSON.stringify(this.input.substr(this.pos, 20))}...`, this)\n }\n\n private parseNext() {\n this.skipWhitespace()\n\n while (this.pos < this.input.length && this.input[this.pos] !== '@') {\n if (this.input[this.pos] === '%') {\n while (this.pos < this.input.length && this.input[this.pos] !== '\\n') this.pos++\n }\n else {\n this.pos++\n }\n }\n if (this.pos >= this.input.length) return\n\n let guard = ''\n const start = this.pos\n try {\n const d = this.parsing = this.directive()\n switch (d) {\n case 'string':\n guard = this.matchGuard()\n this.string()\n this.match(guard)\n break\n\n case 'preamble':\n this.preamble()\n break\n\n case 'comment':\n this.comment()\n break\n\n default:\n guard = this.matchGuard()\n this.entries.unshift({ input: '', type: d, key: '', fields: {} })\n this.entry(d, guard)\n this.match(guard)\n this.entries[0].input = this.input.substring(start, this.pos).trim()\n break\n }\n }\n catch (err) {\n if ((err as any).name !== 'ParsingError') throw err\n // skip ahead to the next @ and try again\n this.pos = start + 1\n while (this.pos < this.input.length && this.input[this.pos] !== '@') this.pos++\n this.error({\n error: err.message,\n input: this.input.substring(start, this.pos),\n })\n }\n }\n}\n\n/**\n * Parses a bibtex source in verbatim mode. Good for detection of bibtex and for later LaTeX-reparsing.\n */\nexport function parse(input: string, options: ParserOptions = {}): Library {\n const parser = new Library(input, options)\n parser.parse()\n return parser\n}\n\nexport const promises = {\n async parse(input: string, options: ParserOptions = {}): Promise<Library> {\n const parser = new Library(input, options)\n await parser.parseAsync()\n return parser\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retorquere/bibtex-parser",
3
- "version": "9.0.26",
3
+ "version": "10.0.0",
4
4
  "description": "BibTeX parser",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -26,7 +26,7 @@
26
26
  "start": "npm run build",
27
27
  "build:esm": "rm -rf dist/esm && esbuild *.ts --outdir=dist/esm --format=esm --sourcemap --target=es2020 --loader:.ts=ts",
28
28
  "build:cjs": "rm -rf dist/cjs && esbuild *.ts --outdir=dist/cjs --format=cjs --sourcemap --target=node16 --loader:.ts=ts",
29
- "build:types": "rm -rf dist/cjs dist/types && tsc -d -p tsconfig.cjs.json",
29
+ "build:types": "rm -rf dist/esm dist/types && tsc -d -p tsconfig.esm.json",
30
30
  "prebuild": "rm -rf dist && mkdir -p dist/data && cp data/*.json dist/data && ./build/abbr.py && ./build/prepositions.py",
31
31
  "build": "npm run build:types && npm run build:cjs && npm run build:esm",
32
32
  "pretest": "npm start",
@@ -40,6 +40,7 @@
40
40
  "update-cases": "curl -s https://raw.githubusercontent.com/retorquere/zotero-better-bibtex/master/test/loaded.json | jq -r '.[] | select(test(\"\\\\.bib((la)?tex)?$\"))' | rsync -av --delete -m --files-from=- ../better-bibtex/test/fixtures/ test/better-bibtex/",
41
41
  "predocs": "npm start",
42
42
  "docs": "typedoc --tsconfig tsconfig.cjs.json",
43
+ "modules": "git submodule update --init --recursive",
43
44
  "ncu": "./build/submodules.py && ./build/crossref.py && ncu -u && npm i && git add package.json package-lock.json && npm audit fix && git commit -m ncu"
44
45
  },
45
46
  "repository": {
@@ -52,36 +53,37 @@
52
53
  "author": "Emiliano Heyns",
53
54
  "license": "ISC",
54
55
  "devDependencies": {
55
- "@types/node": "^24.9.2",
56
- "command-line-args": "^6.0.1",
57
- "csv": "^6.4.1",
56
+ "@types/node": "^25.8.0",
57
+ "@unified-latex/unified-latex-types": "^1.8.4",
58
+ "command-line-args": "^6.0.2",
59
+ "csv": "^6.5.1",
58
60
  "digital-tree": "^2.0.4",
59
- "dprint": "^0.50.2",
60
- "ejs": "^3.1.10",
61
- "esbuild": "^0.25.12",
62
- "glob": "^11.0.3",
63
- "js-yaml": "^4.1.0",
61
+ "dprint": "^0.54.0",
62
+ "ejs": "^5.0.2",
63
+ "esbuild": "^0.28.0",
64
+ "glob": "^13.0.6",
65
+ "js-yaml": "^4.1.1",
64
66
  "minimist": "^1.2.8",
65
67
  "mkdirp": "^3.0.1",
66
68
  "node-fetch": "^3.3.2",
67
- "piscina": "^5.1.3",
69
+ "piscina": "^5.1.4",
68
70
  "slug": "^11.0.1",
69
- "tap": "^21.1.3",
71
+ "tap": "^21.7.3",
70
72
  "ts-node": "^10.9.2",
71
73
  "tslib": "^2.8.1",
72
- "typedoc": "^0.28.14",
73
- "typescript": "^5.9.3"
74
+ "typedoc": "^0.28.19",
75
+ "typescript": "^6.0.3"
74
76
  },
75
77
  "dependencies": {
76
- "@unified-latex/unified-latex-util-pegjs": "^1.8.1",
77
- "@unified-latex/unified-latex-util-print-raw": "^1.8.0",
78
- "@unified-latex/unified-latex-util-replace": "^1.8.3",
79
- "@unified-latex/unified-latex-util-visit": "^1.8.3",
78
+ "@unified-latex/unified-latex-util-pegjs": "^1.8.4",
79
+ "@unified-latex/unified-latex-util-print-raw": "^1.8.4",
80
+ "@unified-latex/unified-latex-util-replace": "^1.8.4",
81
+ "@unified-latex/unified-latex-util-visit": "^1.8.4",
80
82
  "i": "^0.3.7",
81
83
  "lodash.merge": "^4.6.2",
82
- "moo": "^0.5.2",
84
+ "moo": "^0.5.3",
83
85
  "nearley": "^2.20.1",
84
- "unicode2latex": "^7.0.25",
86
+ "unicode2latex": "^7.0.30",
85
87
  "wink-eng-lite-web-model": "^1.8.1",
86
88
  "wink-nlp": "^2.4.0"
87
89
  },
@@ -1,188 +0,0 @@
1
- declare const _default: {
2
- '*': {
3
- '*': {
4
- verbb: string;
5
- };
6
- };
7
- article: {
8
- periodical: {
9
- journalsubtitle: string;
10
- journaltitle: string;
11
- };
12
- };
13
- book: {
14
- mvbook: {
15
- mainsubtitle: string;
16
- maintitle: string;
17
- maintitleaddon: string;
18
- };
19
- };
20
- bookinbook: {
21
- book: {
22
- author: string;
23
- bookauthor: string;
24
- booksubtitle: string;
25
- booktitle: string;
26
- booktitleaddon: string;
27
- };
28
- mvbook: {
29
- author: string;
30
- bookauthor: string;
31
- mainsubtitle: string;
32
- maintitle: string;
33
- maintitleaddon: string;
34
- };
35
- };
36
- collection: {
37
- mvcollection: {
38
- mainsubtitle: string;
39
- maintitle: string;
40
- maintitleaddon: string;
41
- };
42
- mvreference: {
43
- mainsubtitle: string;
44
- maintitle: string;
45
- maintitleaddon: string;
46
- };
47
- };
48
- inbook: {
49
- '*': {
50
- bookauthor: string;
51
- };
52
- book: {
53
- author: string;
54
- bookauthor: string;
55
- booksubtitle: string;
56
- booktitle: string;
57
- booktitleaddon: string;
58
- };
59
- mvbook: {
60
- author: string;
61
- bookauthor: string;
62
- mainsubtitle: string;
63
- maintitle: string;
64
- maintitleaddon: string;
65
- };
66
- };
67
- incollection: {
68
- collection: {
69
- booksubtitle: string;
70
- booktitle: string;
71
- booktitleaddon: string;
72
- };
73
- mvcollection: {
74
- mainsubtitle: string;
75
- maintitle: string;
76
- maintitleaddon: string;
77
- };
78
- mvreference: {
79
- mainsubtitle: string;
80
- maintitle: string;
81
- maintitleaddon: string;
82
- };
83
- reference: {
84
- booksubtitle: string;
85
- booktitle: string;
86
- booktitleaddon: string;
87
- };
88
- };
89
- inproceedings: {
90
- mvproceedings: {
91
- mainsubtitle: string;
92
- maintitle: string;
93
- maintitleaddon: string;
94
- };
95
- proceedings: {
96
- booksubtitle: string;
97
- booktitle: string;
98
- booktitleaddon: string;
99
- };
100
- };
101
- inreference: {
102
- collection: {
103
- booksubtitle: string;
104
- booktitle: string;
105
- booktitleaddon: string;
106
- };
107
- mvcollection: {
108
- mainsubtitle: string;
109
- maintitle: string;
110
- maintitleaddon: string;
111
- };
112
- mvreference: {
113
- mainsubtitle: string;
114
- maintitle: string;
115
- maintitleaddon: string;
116
- };
117
- reference: {
118
- booksubtitle: string;
119
- booktitle: string;
120
- booktitleaddon: string;
121
- };
122
- };
123
- proceedings: {
124
- mvproceedings: {
125
- mainsubtitle: string;
126
- maintitle: string;
127
- maintitleaddon: string;
128
- };
129
- };
130
- reference: {
131
- mvcollection: {
132
- mainsubtitle: string;
133
- maintitle: string;
134
- maintitleaddon: string;
135
- };
136
- mvreference: {
137
- mainsubtitle: string;
138
- maintitle: string;
139
- maintitleaddon: string;
140
- };
141
- };
142
- suppbook: {
143
- book: {
144
- author: string;
145
- bookauthor: string;
146
- booksubtitle: string;
147
- booktitle: string;
148
- booktitleaddon: string;
149
- };
150
- mvbook: {
151
- author: string;
152
- bookauthor: string;
153
- mainsubtitle: string;
154
- maintitle: string;
155
- maintitleaddon: string;
156
- };
157
- };
158
- suppcollection: {
159
- collection: {
160
- booksubtitle: string;
161
- booktitle: string;
162
- booktitleaddon: string;
163
- };
164
- mvcollection: {
165
- mainsubtitle: string;
166
- maintitle: string;
167
- maintitleaddon: string;
168
- };
169
- mvreference: {
170
- mainsubtitle: string;
171
- maintitle: string;
172
- maintitleaddon: string;
173
- };
174
- reference: {
175
- booksubtitle: string;
176
- booktitle: string;
177
- booktitleaddon: string;
178
- };
179
- };
180
- suppperiodical: {
181
- periodical: {
182
- journalsubtitle: string;
183
- journaltitle: string;
184
- };
185
- };
186
- };
187
- export default _default;
188
- //# sourceMappingURL=crossref.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crossref.d.ts","sourceRoot":"","sources":["../../crossref.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAyLC"}
@@ -1,55 +0,0 @@
1
- declare const _default: {
2
- article: string[];
3
- artwork: string[];
4
- audio: string[];
5
- bibnote: string[];
6
- book: string[];
7
- bookinbook: string[];
8
- booklet: string[];
9
- collection: string[];
10
- commentary: string[];
11
- customa: string[];
12
- customb: string[];
13
- customc: string[];
14
- customd: string[];
15
- custome: string[];
16
- customf: string[];
17
- dataset: string[];
18
- image: string[];
19
- inbook: string[];
20
- incollection: string[];
21
- inproceedings: string[];
22
- inreference: string[];
23
- jurisdiction: string[];
24
- legal: string[];
25
- legislation: string[];
26
- letter: string[];
27
- manual: string[];
28
- misc: string[];
29
- movie: string[];
30
- music: string[];
31
- mvbook: string[];
32
- mvcollection: string[];
33
- mvproceedings: string[];
34
- mvreference: string[];
35
- online: string[];
36
- patent: string[];
37
- performance: string[];
38
- periodical: string[];
39
- proceedings: string[];
40
- reference: string[];
41
- report: string[];
42
- review: string[];
43
- set: string[];
44
- software: string[];
45
- standard: string[];
46
- suppbook: string[];
47
- suppcollection: string[];
48
- suppperiodical: string[];
49
- thesis: string[];
50
- unpublished: string[];
51
- video: string[];
52
- xdata: string[];
53
- };
54
- export default _default;
55
- //# sourceMappingURL=fields.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../fields.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAyxNC"}