@retorquere/bibtex-parser 12.1.2 → 12.1.4

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.
@@ -1,122 +1,99 @@
1
- import init, {
2
- initSync,
3
- parseNormalized as parseNormalizedWasm,
4
- parseVerbatim as parseVerbatimWasm,
5
- tokenize as tokenizeWasm,
6
- toSentenceCase as toSentenceCaseWasm,
7
- } from './bibtex_parser.js'
8
-
9
- export { init, initSync }
10
- export default init
11
-
12
- const english = [
13
- '', 'american', 'british', 'canadian', 'english', 'australian', 'newzealand',
14
- 'usenglish', 'ukenglish', 'en', 'eng', 'en-au', 'en-bz', 'en-ca', 'en-cb',
15
- 'en-gb', 'en-ie', 'en-jm', 'en-nz', 'en-ph', 'en-tt', 'en-us', 'en-za', 'en-zw', 'anglais',
16
- ]
17
-
18
- function rustOptions(options = {}) {
19
- const rust = Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined))
20
-
21
- if (rust.unsupported !== undefined && typeof rust.unsupported !== 'string') {
22
- throw new TypeError('unsupported must be ignore, keep, or throw')
23
- }
24
- if (rust.unsupported !== undefined && !['ignore', 'keep', 'throw'].includes(rust.unsupported)) {
25
- throw new TypeError('unsupported must be ignore, keep, or throw')
26
- }
27
-
28
- if (typeof rust.strings === 'string') {
29
- rust.stringsSource = rust.strings
30
- delete rust.strings
31
- }
32
- else if (!rust.strings) {
33
- delete rust.strings
34
- }
35
- if (typeof rust.english === 'boolean') {
36
- rust.english = rust.english ? english : []
37
- }
38
- else if (Array.isArray(rust.english)) {
39
- const configured = rust.english
40
- rust.english = [...english]
41
- configured.forEach((language, index) => {
42
- rust.english[index] = language
43
- })
44
- }
45
- if (rust.sentenceCase === false) {
46
- rust.english = []
47
- rust.sentenceCase = { guess: false, subSentence: false, preserveQuoted: false }
48
- }
49
- if (rust.caseProtection === false) rust.caseProtection = 'off'
50
- if (rust.caseProtection === true) rust.caseProtection = 'as-needed'
51
- if (Array.isArray(rust.verbatimFields)) {
52
- rust.verbatimFields = rust.verbatimFields.filter(field => typeof field === 'string')
53
- }
54
- if (rust.unsupported === 'ignore') rust.ignoreUnsupported = true
55
- delete rust.unsupported
56
- return rust
57
- }
58
-
59
- function library(result) {
60
- if (Array.isArray(result.preambles)) {
61
- result.preamble = result.preambles
62
- delete result.preambles
63
- }
64
- return result
1
+ /** @module wasm */
2
+ import init, { initSync, parse as parseWasm, parseAsync as parseAsyncWasm, parseVerbatim as parseVerbatimWasm, parseVerbatimAsync as parseVerbatimAsyncWasm, tokenize as tokenizeWasm, toSentenceCase as toSentenceCaseWasm } from './bibtex_parser.js';
3
+ /** Initializes the WebAssembly parser; await this before using its exports. */
4
+ export { init, initSync };
5
+ export default init;
6
+ /** Default language identifiers treated as English. */
7
+ export const english = [
8
+ '',
9
+ 'american',
10
+ 'british',
11
+ 'canadian',
12
+ 'english',
13
+ 'australian',
14
+ 'newzealand',
15
+ 'usenglish',
16
+ 'ukenglish',
17
+ 'en',
18
+ 'eng',
19
+ 'en-au',
20
+ 'en-bz',
21
+ 'en-ca',
22
+ 'en-cb',
23
+ 'en-gb',
24
+ 'en-ie',
25
+ 'en-jm',
26
+ 'en-nz',
27
+ 'en-ph',
28
+ 'en-tt',
29
+ 'en-us',
30
+ 'en-za',
31
+ 'en-zw',
32
+ 'anglais',
33
+ ];
34
+ function prepare(input, options = {}) {
35
+ const parserOptions = Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined));
36
+ if (typeof parserOptions.strings === 'string') {
37
+ input = `${parserOptions.strings}\n${input}`;
38
+ delete parserOptions.strings;
39
+ }
40
+ if (parserOptions.unsupported && !['ignore', 'keep', 'throw'].includes(parserOptions.unsupported)) {
41
+ throw new TypeError('unsupported must be ignore, keep, or throw');
42
+ }
43
+ if (parserOptions.unsupported === 'ignore')
44
+ parserOptions.ignoreUnsupported = true;
45
+ delete parserOptions.unsupported;
46
+ if (Array.isArray(parserOptions.verbatimFields)) {
47
+ parserOptions.verbatimFields = parserOptions.verbatimFields.map((field) => {
48
+ if (typeof field === 'string')
49
+ return field;
50
+ const flags = `${field.multiline ? 'm' : ''}${field.dotAll ? 's' : ''}`;
51
+ const source = flags ? `(?${flags}:${field.source})` : field.source;
52
+ return { source: field.sticky ? `\\A(?:${source})` : source };
53
+ });
54
+ }
55
+ return { input, options: parserOptions };
65
56
  }
66
-
67
57
  function throwOnUnsupported(result) {
68
- const unsupported = result.errors.find(error => error.error.startsWith('unhandled macro ') || error.error.startsWith('unhandled environment '))
69
- if (unsupported) throw new Error(unsupported.error)
70
- return result
58
+ const unsupported = result.errors.find(error => error.error.startsWith('unhandled macro ') || error.error.startsWith('unhandled environment '));
59
+ if (unsupported)
60
+ throw new Error(unsupported.error);
61
+ return result;
71
62
  }
72
-
63
+ /** Parses BibTeX while leaving field contents uninterpreted. */
73
64
  export function parseVerbatim(input, options = {}) {
74
- const result = parseVerbatimWasm(input, rustOptions(options))
75
- delete result.jabref
76
- return result
65
+ const prepared = prepare(input, options);
66
+ return parseVerbatimWasm(prepared.input, prepared.options);
77
67
  }
78
-
79
- export function parseNormalized(input, options = {}) {
80
- const selectors = options.verbatimFields || []
81
- const patterns = selectors.filter(selector => selector instanceof RegExp)
82
- let normalizedOptions = options
83
- if (patterns.length) {
84
- const exactFields = new Set(selectors.filter(selector => typeof selector === 'string'))
85
- const raw = parseVerbatimWasm(input, rustOptions({
86
- ...options,
87
- verbatimFields: [...exactFields],
88
- }))
89
- for (const entry of raw.entries) {
90
- for (const field of Object.keys(entry.fields)) {
91
- if (patterns.some(pattern => field.match(new RegExp(
92
- pattern.source,
93
- pattern.flags.includes('i') ? pattern.flags : `${pattern.flags}i`,
94
- )))) {
95
- exactFields.add(field)
96
- }
97
- }
98
- }
99
- normalizedOptions = { ...options, verbatimFields: [...exactFields] }
100
- }
101
- const result = library(parseNormalizedWasm(input, rustOptions(normalizedOptions)))
102
- if (options.unsupported === 'throw') return throwOnUnsupported(result)
103
- return result
68
+ /** Asynchronous variant of {@link parseVerbatim}. */
69
+ export async function parseVerbatimAsync(input, options = {}) {
70
+ const prepared = prepare(input, options);
71
+ return await parseVerbatimAsyncWasm(prepared.input, prepared.options);
104
72
  }
105
-
73
+ /** Parses BibTeX or BibLaTeX source into a normalized library. */
106
74
  export function parse(input, options = {}) {
107
- return parseNormalized(input, options)
75
+ const prepared = prepare(input, options);
76
+ const result = parseWasm(prepared.input, prepared.options);
77
+ if (options.unsupported === 'throw')
78
+ return throwOnUnsupported(result);
79
+ return result;
108
80
  }
109
-
81
+ /** Asynchronous variant of {@link parse}, yielding during large parses. */
110
82
  export async function parseAsync(input, options = {}) {
111
- return parseNormalized(input, options)
83
+ const prepared = prepare(input, options);
84
+ const result = await parseAsyncWasm(prepared.input, prepared.options);
85
+ if (options.unsupported === 'throw')
86
+ return throwOnUnsupported(result);
87
+ return result;
112
88
  }
113
-
89
+ /** Converts a title to sentence case using heuristic token classification. */
114
90
  export function toSentenceCase(input, options = {}) {
115
- return toSentenceCaseWasm(input, options)
91
+ return toSentenceCaseWasm(input, options);
116
92
  }
117
-
93
+ /** Splits text into classified tokens with source offsets. */
118
94
  export function tokenize(input, markup) {
119
- if (!(markup instanceof RegExp)) return tokenizeWasm(input)
120
- const masked = input.replace(markup, match => '\u2060'.repeat(match.length))
121
- return tokenizeWasm(masked)
122
- }
95
+ if (!(markup instanceof RegExp))
96
+ return tokenizeWasm(input);
97
+ const masked = input.replace(markup, match => '\u2060'.repeat(match.length));
98
+ return tokenizeWasm(masked);
99
+ }
@@ -0,0 +1 @@
1
+ export function playnice() { return new Promise(resolve => setTimeout(resolve, 0)); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retorquere/bibtex-parser",
3
- "version": "12.1.2",
3
+ "version": "12.1.4",
4
4
  "description": "BibTeX parser",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -47,7 +47,7 @@
47
47
  "postversion": "git push --follow-tags",
48
48
  "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/",
49
49
  "predocs": "npm start",
50
- "docs": "typedoc --tsconfig tsconfig.cjs.json",
50
+ "docs": "typedoc --tsconfig tsconfig.typedoc.json",
51
51
  "modules": "git submodule update --init --recursive",
52
52
  "wasm:test": "npm run build:wasm && node --test test/wasm.js test/rust-wasm-parity.test.js",
53
53
  "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"
@@ -62,22 +62,22 @@
62
62
  "author": "Emiliano Heyns",
63
63
  "license": "ISC",
64
64
  "devDependencies": {
65
- "@types/node": "^26.2.0",
65
+ "@types/node": "^26.6.5",
66
66
  "@unified-latex/unified-latex-types": "^1.8.4",
67
67
  "command-line-args": "^6.0.2",
68
- "csv": "^6.6.3",
68
+ "csv": "^6.6.4",
69
69
  "digital-tree": "^2.0.4",
70
- "dprint": "^0.55.2",
71
- "ejs": "^6.0.1",
70
+ "dprint": "^0.63.0",
71
+ "ejs": "^7.0.1",
72
72
  "esbuild": "^0.28.2",
73
73
  "glob": "^13.0.6",
74
- "js-yaml": "^5.2.3",
74
+ "js-yaml": "^5.4.3",
75
75
  "minimist": "^1.2.8",
76
76
  "mkdirp": "^3.0.1",
77
77
  "node-fetch": "^3.3.2",
78
- "piscina": "^5.3.0",
78
+ "piscina": "^5.3.2",
79
79
  "slug": "^12.0.1",
80
- "tap": "^21.7.5",
80
+ "tap": "^21.8.0",
81
81
  "ts-node": "^10.9.2",
82
82
  "tslib": "^2.8.1",
83
83
  "typedoc": "^0.28.20",
@@ -92,7 +92,7 @@
92
92
  "lodash.merge": "^4.6.2",
93
93
  "moo": "^0.5.3",
94
94
  "nearley": "^2.20.1",
95
- "unicode2latex": "^7.0.33",
95
+ "unicode2latex": "^7.0.37",
96
96
  "wink-eng-lite-web-model": "^1.8.1",
97
97
  "wink-nlp": "^2.4.0"
98
98
  },
@@ -103,5 +103,9 @@
103
103
  ],
104
104
  "publishConfig": {
105
105
  "access": "public"
106
+ },
107
+ "allowScripts": {
108
+ "esbuild@0.28.2": true,
109
+ "dprint@0.63.0": true
106
110
  }
107
111
  }