@retorquere/bibtex-parser 11.0.0 → 12.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.
- package/README.md +66 -5
- package/dist/cjs/index.js +11 -6
- package/dist/cjs/index.js.map +2 -2
- package/dist/esm/index.js +11 -6
- package/dist/esm/index.js.map +2 -2
- package/dist/types/index.d.ts +4 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/wasm/bibtex_parser.d.ts +62 -0
- package/dist/wasm/bibtex_parser.js +584 -0
- package/dist/wasm/bibtex_parser_bg.wasm +0 -0
- package/dist/wasm/bibtex_parser_bg.wasm.d.ts +15 -0
- package/dist/wasm/index.d.ts +122 -0
- package/dist/wasm/index.js +122 -0
- package/package.json +12 -3
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { InitInput, InitOutput, SyncInitInput } from './bibtex_parser.js'
|
|
2
|
+
|
|
3
|
+
export type { InitInput, InitOutput, SyncInitInput }
|
|
4
|
+
export { initSync } from './bibtex_parser.js'
|
|
5
|
+
export { default as init } from './bibtex_parser.js'
|
|
6
|
+
export { default } from './bibtex_parser.js'
|
|
7
|
+
|
|
8
|
+
export type ParseMode = 'creatorlist' | 'title' | 'verbatim' | 'richtext' | 'literallist' | 'literal' | 'verbatimlist'
|
|
9
|
+
|
|
10
|
+
export interface Creator {
|
|
11
|
+
name?: string
|
|
12
|
+
lastName?: string
|
|
13
|
+
firstName?: string
|
|
14
|
+
prefix?: string
|
|
15
|
+
suffix?: string
|
|
16
|
+
initial?: string
|
|
17
|
+
useprefix?: boolean
|
|
18
|
+
juniorcomma?: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type FieldValue = string | string[] | Creator[]
|
|
22
|
+
|
|
23
|
+
export interface Entry {
|
|
24
|
+
type: string
|
|
25
|
+
key: string
|
|
26
|
+
fields: Record<string, FieldValue>
|
|
27
|
+
mode: Record<string, ParseMode>
|
|
28
|
+
crossref?: Record<string, { parent: string; field: string }>
|
|
29
|
+
input: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ParseError {
|
|
33
|
+
error: string
|
|
34
|
+
input?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface JabRefGroup {
|
|
38
|
+
name: string
|
|
39
|
+
entries: string[]
|
|
40
|
+
groups: JabRefGroup[]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface JabRefMetadata {
|
|
44
|
+
root: JabRefGroup[]
|
|
45
|
+
groups: Record<string, JabRefGroup>
|
|
46
|
+
fileDirectory?: string
|
|
47
|
+
groupsversion?: number
|
|
48
|
+
databaseType?: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface Library {
|
|
52
|
+
errors: ParseError[]
|
|
53
|
+
entries: Entry[]
|
|
54
|
+
comments: string[]
|
|
55
|
+
strings: Record<string, string>
|
|
56
|
+
preamble: string[]
|
|
57
|
+
jabref: JabRefMetadata
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface SentenceCaseOptions {
|
|
61
|
+
guess?: boolean
|
|
62
|
+
subSentence?: boolean
|
|
63
|
+
preserveQuoted?: boolean
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface Token {
|
|
67
|
+
type: 'word' | 'domain' | 'whitespace' | 'number' | 'email' | 'handle' | 'website' | 'markup' | 'other' | 'punctuation'
|
|
68
|
+
subtype: '' | 'preposition' | 'acronym' | 'contraction' | 'ordinal' | 'word' | 'end' | 'colon' | 'ellipsis'
|
|
69
|
+
text: string
|
|
70
|
+
start: number
|
|
71
|
+
end: number
|
|
72
|
+
shape: string
|
|
73
|
+
sentenceStart: boolean
|
|
74
|
+
subSentenceStart: boolean
|
|
75
|
+
hyphenated?: Token[]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface Options {
|
|
79
|
+
english?: string[] | boolean
|
|
80
|
+
languageAsLangid?: boolean
|
|
81
|
+
sentenceCase?: false | SentenceCaseOptions
|
|
82
|
+
caseProtection?: 'as-needed' | 'strict' | boolean
|
|
83
|
+
unsupported?: 'ignore' | 'keep' | 'throw'
|
|
84
|
+
verbatimFields?: (string | RegExp)[]
|
|
85
|
+
removeOuterBraces?: string[]
|
|
86
|
+
fieldMode?: Record<string, ParseMode>
|
|
87
|
+
raw?: boolean
|
|
88
|
+
strings?: Record<string, string> | string
|
|
89
|
+
applyCrossRef?: boolean
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface ParserOptions {
|
|
93
|
+
maxEntries?: number
|
|
94
|
+
strings?: Record<string, string> | string
|
|
95
|
+
stringsSource?: string
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface VerbatimEntry {
|
|
99
|
+
input: string
|
|
100
|
+
type: string
|
|
101
|
+
key: string
|
|
102
|
+
fields: Record<string, string>
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface VerbatimLibrary {
|
|
106
|
+
entries: VerbatimEntry[]
|
|
107
|
+
strings: Record<string, string>
|
|
108
|
+
comments: string[]
|
|
109
|
+
errors: ParseError[]
|
|
110
|
+
preambles: string[]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function parseVerbatim(input: string, options?: ParserOptions): VerbatimLibrary
|
|
114
|
+
export function parseNormalized(input: string, options?: Options): Library
|
|
115
|
+
export function parse(input: string, options?: Options): Library
|
|
116
|
+
export function parseAsync(input: string, options?: Options): Promise<Library>
|
|
117
|
+
export function toSentenceCase(input: string, options?: {
|
|
118
|
+
preserveQuoted?: boolean
|
|
119
|
+
subSentenceCapitalization?: boolean
|
|
120
|
+
guess?: boolean
|
|
121
|
+
}): string
|
|
122
|
+
export function tokenize(input: string, markup?: RegExp): Token[]
|
|
@@ -0,0 +1,122 @@
|
|
|
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
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
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
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function parseVerbatim(input, options = {}) {
|
|
74
|
+
const result = parseVerbatimWasm(input, rustOptions(options))
|
|
75
|
+
delete result.jabref
|
|
76
|
+
return result
|
|
77
|
+
}
|
|
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
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function parse(input, options = {}) {
|
|
107
|
+
return parseNormalized(input, options)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export async function parseAsync(input, options = {}) {
|
|
111
|
+
return parseNormalized(input, options)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function toSentenceCase(input, options = {}) {
|
|
115
|
+
return toSentenceCaseWasm(input, options)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
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
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retorquere/bibtex-parser",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.0",
|
|
4
4
|
"description": "BibTeX parser",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -16,7 +16,12 @@
|
|
|
16
16
|
"types": "./dist/types/index.d.ts",
|
|
17
17
|
"default": "./dist/cjs/index.js"
|
|
18
18
|
}
|
|
19
|
-
}
|
|
19
|
+
},
|
|
20
|
+
"./wasm": {
|
|
21
|
+
"types": "./dist/wasm/index.d.ts",
|
|
22
|
+
"import": "./dist/wasm/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./wasm/bibtex_parser_bg.wasm": "./dist/wasm/bibtex_parser_bg.wasm"
|
|
20
25
|
},
|
|
21
26
|
"typings": "./index.d.ts",
|
|
22
27
|
"scripts": {
|
|
@@ -27,10 +32,13 @@
|
|
|
27
32
|
"build:esm": "rm -rf dist/esm && esbuild *.ts --outdir=dist/esm --format=esm --sourcemap --target=es2020 --loader:.ts=ts",
|
|
28
33
|
"build:cjs": "rm -rf dist/cjs && esbuild *.ts --outdir=dist/cjs --format=cjs --sourcemap --target=node16 --loader:.ts=ts",
|
|
29
34
|
"build:types": "rm -rf dist/esm dist/types && tsc -d -p tsconfig.esm.json",
|
|
35
|
+
"build:ts": "npm run build:types && npm run build:cjs && npm run build:esm",
|
|
36
|
+
"build:wasm": "node rust/build-wasm.mjs",
|
|
30
37
|
"prebuild": "rm -rf dist && mkdir -p dist/data && cp data/*.json dist/data && ./build/abbr.py && ./build/prepositions.py",
|
|
31
|
-
"build": "npm run build:
|
|
38
|
+
"build": "npm run build:ts && npm run build:wasm",
|
|
32
39
|
"pretest": "npm start",
|
|
33
40
|
"test": "node test/run.js",
|
|
41
|
+
"test:package": "npm run build && node --test test/package.test.js",
|
|
34
42
|
"minitest": "./build/crossref.py && npm run build && node i.js",
|
|
35
43
|
"list": "tar tvf $(npm pack)",
|
|
36
44
|
"prepublishOnly": "npm start",
|
|
@@ -41,6 +49,7 @@
|
|
|
41
49
|
"predocs": "npm start",
|
|
42
50
|
"docs": "typedoc --tsconfig tsconfig.cjs.json",
|
|
43
51
|
"modules": "git submodule update --init --recursive",
|
|
52
|
+
"wasm:test": "npm run build:wasm && node --test test/wasm.js test/rust-wasm-parity.test.js",
|
|
44
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"
|
|
45
54
|
},
|
|
46
55
|
"repository": {
|