@retorquere/bibtex-parser 8.0.0 → 8.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.
- package/package.json +3 -3
- package/verbatim.d.ts +75 -0
- package/verbatim.js +432 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retorquere/bibtex-parser",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.1",
|
|
4
4
|
"description": "BibTeX parser",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "./index.d.ts",
|
|
@@ -77,8 +77,8 @@
|
|
|
77
77
|
"package.json",
|
|
78
78
|
"grammar.js",
|
|
79
79
|
"grammar.d.ts",
|
|
80
|
-
"
|
|
81
|
-
"
|
|
80
|
+
"verbatim.d.ts",
|
|
81
|
+
"verbatim.js",
|
|
82
82
|
"index.d.ts",
|
|
83
83
|
"index.js",
|
|
84
84
|
"jabref.d.ts",
|
package/verbatim.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export type Entry = {
|
|
2
|
+
input: string;
|
|
3
|
+
type: string;
|
|
4
|
+
key: string;
|
|
5
|
+
fields: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
export interface ParseError {
|
|
8
|
+
error: string;
|
|
9
|
+
input: string;
|
|
10
|
+
location?: {
|
|
11
|
+
line: number;
|
|
12
|
+
column: number;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface ParserOptions {
|
|
16
|
+
/**
|
|
17
|
+
* stop parsing after `max_entries` entries have been found. Useful for quick detection if a text file is in fact a bibtex file
|
|
18
|
+
*/
|
|
19
|
+
max_entries?: number;
|
|
20
|
+
}
|
|
21
|
+
declare class Parser {
|
|
22
|
+
parsing: string;
|
|
23
|
+
entries: Entry[];
|
|
24
|
+
strings: Record<string, string>;
|
|
25
|
+
comments: string[];
|
|
26
|
+
errors: ParseError[];
|
|
27
|
+
preambles: string[];
|
|
28
|
+
private default_strings;
|
|
29
|
+
/**
|
|
30
|
+
* error found, if any.
|
|
31
|
+
*/
|
|
32
|
+
error?: string;
|
|
33
|
+
private pos;
|
|
34
|
+
private linebreaks;
|
|
35
|
+
private input;
|
|
36
|
+
private max_entries;
|
|
37
|
+
private keywords;
|
|
38
|
+
constructor(input: string, options?: ParserOptions);
|
|
39
|
+
location(pos: number): {
|
|
40
|
+
line: number;
|
|
41
|
+
column: number;
|
|
42
|
+
};
|
|
43
|
+
parse(): void;
|
|
44
|
+
parseAsync(): Promise<void>;
|
|
45
|
+
private isWhitespace;
|
|
46
|
+
private match;
|
|
47
|
+
private tryMatch;
|
|
48
|
+
private skipWhitespace;
|
|
49
|
+
private value_braces;
|
|
50
|
+
private value_quotes;
|
|
51
|
+
private single_value;
|
|
52
|
+
private value;
|
|
53
|
+
private key;
|
|
54
|
+
private key_equals_value;
|
|
55
|
+
private entry;
|
|
56
|
+
private directive;
|
|
57
|
+
private string;
|
|
58
|
+
private preamble;
|
|
59
|
+
private comment;
|
|
60
|
+
private hasMore;
|
|
61
|
+
private bibtex;
|
|
62
|
+
private bibtexAsync;
|
|
63
|
+
private matchGuard;
|
|
64
|
+
private parseNext;
|
|
65
|
+
}
|
|
66
|
+
export type Bibliography = Parser;
|
|
67
|
+
/**
|
|
68
|
+
* Parses a bibtex source in verbatim mode. Good for detection of bibtex and for later LaTeX-reparsing.
|
|
69
|
+
*/
|
|
70
|
+
export declare function parse(input: string, options?: ParserOptions): Bibliography;
|
|
71
|
+
export declare const promises: {
|
|
72
|
+
parse(input: string, options?: ParserOptions): Promise<Bibliography>;
|
|
73
|
+
};
|
|
74
|
+
export {};
|
|
75
|
+
//# sourceMappingURL=verbatim.d.ts.map
|
package/verbatim.js
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
|
+
// Original work by Henrik Muehe (c) 2010
|
|
4
|
+
//
|
|
5
|
+
// CommonJS port by Mikola Lysenko 2013
|
|
6
|
+
//
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.promises = exports.parse = void 0;
|
|
9
|
+
class ParsingError extends Error {
|
|
10
|
+
constructor(message, parser) {
|
|
11
|
+
message += ` @ ${parser.pos}`;
|
|
12
|
+
if (parser.parsing)
|
|
13
|
+
message += ` in ${JSON.stringify(parser.parsing)}`;
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'ParsingError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// eslint-disable-next-line prefer-template
|
|
19
|
+
const letter = new RegExp('[' + [
|
|
20
|
+
// Letter, Uppercase
|
|
21
|
+
/\u0041-\u005A\u00C0-\u00D6\u00D8-\u00DE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178-\u0179\u017B\u017D\u0181-\u0182\u0184\u0186-\u0187\u0189-\u018B\u018E-\u0191\u0193-\u0194\u0196-\u0198\u019C-\u019D\u019F-\u01A0\u01A2\u01A4\u01A6-\u01A7\u01A9\u01AC\u01AE-\u01AF\u01B1-\u01B3\u01B5\u01B7-\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A-\u023B\u023D-\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E-\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9-\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0-\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E-\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D-\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AD\uA7B0-\uA7B4\uA7B6\uFF21-\uFF3A/.source,
|
|
22
|
+
// Letter, Titlecase
|
|
23
|
+
/\u01C5\u01C8\u01CB\u01F2\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FBC\u1FCC\u1FFC/.source,
|
|
24
|
+
// Letter, Lowercase
|
|
25
|
+
/\u0061-\u007A\u00B5\u00DF-\u00F6\u00F8-\u00FF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137-\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148-\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C-\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA-\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9-\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC-\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF-\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F-\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0-\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB-\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE-\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0561-\u0587\u13F8-\u13FD\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6-\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FC7\u1FD0-\u1FD3\u1FD6-\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6-\u1FF7\u210A\u210E-\u210F\u2113\u212F\u2134\u2139\u213C-\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65-\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73-\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3-\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7B5\uA7B7\uA7FA\uAB30-\uAB5A\uAB60-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A/.source,
|
|
26
|
+
// Letter, Modifier
|
|
27
|
+
/\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5-\u06E6\u07F4-\u07F5\u07FA\u081A\u0824\u0828\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1AA7\u1C78-\u1C7D\u1D2C-\u1D6A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\u2D6F\u2E2F\u3005\u3031-\u3035\u303B\u309D-\u309E\u30FC-\u30FE\uA015\uA4F8-\uA4FD\uA60C\uA67F\uA69C-\uA69D\uA717-\uA71F\uA770\uA788\uA7F8-\uA7F9\uA9CF\uA9E6\uAA70\uAADD\uAAF3-\uAAF4\uAB5C-\uAB5F\uFF70\uFF9E-\uFF9F/.source,
|
|
28
|
+
// Letter, Other
|
|
29
|
+
/\u00AA\u00BA\u01BB\u01C0-\u01C3\u0294\u05D0-\u05EA\u05F0-\u05F2\u0620-\u063F\u0641-\u064A\u066E-\u066F\u0671-\u06D3\u06D5\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u0800-\u0815\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0972-\u0980\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0-\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0-\u0CE1\u0CF1-\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065-\u1066\u106E-\u1070\u1075-\u1081\u108E\u10D0-\u10FA\u10FD-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17DC\u1820-\u1842\u1844-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE-\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C77\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5-\u1CF6\u2135-\u2138\u2D30-\u2D67\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3006\u303C\u3041-\u3096\u309F\u30A1-\u30FA\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA014\uA016-\uA48C\uA4D0-\uA4F7\uA500-\uA60B\uA610-\uA61F\uA62A-\uA62B\uA66E\uA6A0-\uA6E5\uA78F\uA7F7\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9E0-\uA9E4\uA9E7-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA6F\uAA71-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADC\uAAE0-\uAAEA\uAAF2\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF66-\uFF6F\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC/.source,
|
|
30
|
+
].join('') + ']');
|
|
31
|
+
class Parser {
|
|
32
|
+
constructor(input, options = {}) {
|
|
33
|
+
this.entries = [];
|
|
34
|
+
this.strings = {};
|
|
35
|
+
this.comments = [];
|
|
36
|
+
this.errors = [];
|
|
37
|
+
this.preambles = [];
|
|
38
|
+
this.default_strings = {
|
|
39
|
+
JAN: '01',
|
|
40
|
+
JANUARY: '01',
|
|
41
|
+
FEB: '02',
|
|
42
|
+
FEBRUARY: '02',
|
|
43
|
+
MAR: '03',
|
|
44
|
+
MARCH: '03',
|
|
45
|
+
APR: '04',
|
|
46
|
+
APRIL: '04',
|
|
47
|
+
MAY: '05',
|
|
48
|
+
JUN: '06',
|
|
49
|
+
JUNE: '06',
|
|
50
|
+
JUL: '07',
|
|
51
|
+
JULY: '07',
|
|
52
|
+
AUG: '08',
|
|
53
|
+
AUGUST: '08',
|
|
54
|
+
SEP: '09',
|
|
55
|
+
SEPTEMBER: '09',
|
|
56
|
+
OCT: '10',
|
|
57
|
+
OCTOBER: '10',
|
|
58
|
+
NOV: '11',
|
|
59
|
+
NOVEMBER: '11',
|
|
60
|
+
DEC: '12',
|
|
61
|
+
DECEMBER: '12',
|
|
62
|
+
ACMCS: 'ACM Computing Surveys',
|
|
63
|
+
ACTA: 'Acta Informatica',
|
|
64
|
+
CACM: 'Communications of the ACM',
|
|
65
|
+
IBMJRD: 'IBM Journal of Research and Development',
|
|
66
|
+
IBMSJ: 'IBM Systems Journal',
|
|
67
|
+
IEEESE: 'IEEE Transactions on Software Engineering',
|
|
68
|
+
IEEETC: 'IEEE Transactions on Computers',
|
|
69
|
+
IEEETCAD: 'IEEE Transactions on Computer-Aided Design of Integrated Circuits',
|
|
70
|
+
IPL: 'Information Processing Letters',
|
|
71
|
+
JACM: 'Journal of the ACM',
|
|
72
|
+
JCSS: 'Journal of Computer and System Sciences',
|
|
73
|
+
SCP: 'Science of Computer Programming',
|
|
74
|
+
SICOMP: 'SIAM Journal on Computing',
|
|
75
|
+
TOCS: 'ACM Transactions on Computer Systems',
|
|
76
|
+
TODS: 'ACM Transactions on Database Systems',
|
|
77
|
+
TOG: 'ACM Transactions on Graphics',
|
|
78
|
+
TOMS: 'ACM Transactions on Mathematical Software',
|
|
79
|
+
TOOIS: 'ACM Transactions on Office Information Systems',
|
|
80
|
+
TOPLAS: 'ACM Transactions on Programming Languages and Systems',
|
|
81
|
+
TCS: 'Theoretical Computer Science',
|
|
82
|
+
};
|
|
83
|
+
this.pos = 0;
|
|
84
|
+
this.linebreaks = [];
|
|
85
|
+
this.max_entries = options.max_entries || 0;
|
|
86
|
+
this.input = input;
|
|
87
|
+
this.parsing = null;
|
|
88
|
+
this.keywords = 0;
|
|
89
|
+
let pos = input.indexOf('\n');
|
|
90
|
+
while (pos !== -1) {
|
|
91
|
+
this.linebreaks.push(pos);
|
|
92
|
+
pos = input.indexOf('\n', pos + 1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
location(pos) {
|
|
96
|
+
let line = 1;
|
|
97
|
+
let column = 1;
|
|
98
|
+
for (const linebreak of this.linebreaks) {
|
|
99
|
+
if (pos < linebreak)
|
|
100
|
+
break;
|
|
101
|
+
line++;
|
|
102
|
+
column = pos - linebreak;
|
|
103
|
+
}
|
|
104
|
+
return { line, column };
|
|
105
|
+
}
|
|
106
|
+
parse() {
|
|
107
|
+
this.bibtex();
|
|
108
|
+
this.entries.reverse();
|
|
109
|
+
}
|
|
110
|
+
async parseAsync() {
|
|
111
|
+
await this.bibtexAsync();
|
|
112
|
+
this.entries.reverse();
|
|
113
|
+
}
|
|
114
|
+
isWhitespace(s, horizontalOnly = false) {
|
|
115
|
+
return (s === ' ' || s === '\t' || (!horizontalOnly && (s === '\r' || s === '\n')));
|
|
116
|
+
}
|
|
117
|
+
match(s, sws = true) {
|
|
118
|
+
this.skipWhitespace();
|
|
119
|
+
if (this.input.substr(this.pos, s.length) !== s) {
|
|
120
|
+
throw new ParsingError(`Token mismatch, expected ${JSON.stringify(s)}, found ${JSON.stringify(this.input.substr(this.pos, 20))}...`, this); // eslint-disable-line no-magic-numbers
|
|
121
|
+
}
|
|
122
|
+
this.pos += s.length;
|
|
123
|
+
if (sws)
|
|
124
|
+
this.skipWhitespace();
|
|
125
|
+
}
|
|
126
|
+
tryMatch(s, consume = false) {
|
|
127
|
+
this.skipWhitespace();
|
|
128
|
+
const match = (this.input.substr(this.pos, s.length) === s);
|
|
129
|
+
if (match && consume)
|
|
130
|
+
this.pos += s.length;
|
|
131
|
+
return match;
|
|
132
|
+
// this.skipWhitespace()
|
|
133
|
+
}
|
|
134
|
+
skipWhitespace() {
|
|
135
|
+
while (this.pos < this.input.length && this.input[this.pos].match(/[ \t\r\n%]/)) {
|
|
136
|
+
// test for '%' is shady
|
|
137
|
+
if (this.input[this.pos] === '%') {
|
|
138
|
+
while (this.pos < this.input.length && this.input[this.pos] !== '\n')
|
|
139
|
+
this.pos++;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
this.pos++;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/*
|
|
147
|
+
private fix_path() {
|
|
148
|
+
// workaround for https://github.com/siefkenj/unified-latex/issues/94
|
|
149
|
+
const path = '\\path|'
|
|
150
|
+
const verb = path.replace('path', 'verb')
|
|
151
|
+
if (this.input.substring(this.pos).startsWith(path)) {
|
|
152
|
+
console.log('replacing path')
|
|
153
|
+
// eslint-disable-next-line prefer-template, no-magic-numbers
|
|
154
|
+
this.input = this.input.substring(0, this.pos) + verb + this.input.substring(this.pos + path.length)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
*/
|
|
158
|
+
value_braces() {
|
|
159
|
+
let bracecount = 0;
|
|
160
|
+
this.match('{', false);
|
|
161
|
+
const start = this.pos;
|
|
162
|
+
let math = false;
|
|
163
|
+
while (true) { // eslint-disable-line no-constant-condition
|
|
164
|
+
// this.fix_path()
|
|
165
|
+
switch (this.input[this.pos]) {
|
|
166
|
+
case '\\':
|
|
167
|
+
this.pos += 1;
|
|
168
|
+
break;
|
|
169
|
+
case '{':
|
|
170
|
+
bracecount++;
|
|
171
|
+
break;
|
|
172
|
+
case '}':
|
|
173
|
+
if (bracecount === 0) {
|
|
174
|
+
if (math)
|
|
175
|
+
throw new ParsingError('Unclosed math section', this);
|
|
176
|
+
this.pos++;
|
|
177
|
+
return this.input.substring(start, this.pos - 1);
|
|
178
|
+
}
|
|
179
|
+
bracecount--;
|
|
180
|
+
break;
|
|
181
|
+
case '$':
|
|
182
|
+
math = !math;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
this.pos++;
|
|
186
|
+
if (this.pos >= this.input.length) {
|
|
187
|
+
throw new ParsingError(`Unterminated brace-value ${JSON.stringify(this.input.substr(start, 20))}`, this); // eslint-disable-line no-magic-numbers
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
value_quotes() {
|
|
192
|
+
this.match('"', false);
|
|
193
|
+
const start = this.pos;
|
|
194
|
+
let bracecount = 0;
|
|
195
|
+
while (true) { // eslint-disable-line no-constant-condition
|
|
196
|
+
// this.fix_path()
|
|
197
|
+
switch (this.input[this.pos]) {
|
|
198
|
+
case '\\':
|
|
199
|
+
this.pos += 1;
|
|
200
|
+
break;
|
|
201
|
+
case '{':
|
|
202
|
+
bracecount++;
|
|
203
|
+
break;
|
|
204
|
+
case '}':
|
|
205
|
+
bracecount--;
|
|
206
|
+
break;
|
|
207
|
+
case '"':
|
|
208
|
+
if (bracecount <= 0) {
|
|
209
|
+
this.pos++;
|
|
210
|
+
return this.input.substring(start, this.pos - 1);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
this.pos++;
|
|
214
|
+
if (this.pos >= this.input.length) {
|
|
215
|
+
throw new ParsingError(`Unterminated quote-value ${JSON.stringify(this.input.substr(start, 20))}`, this); // eslint-disable-line no-magic-numbers
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
single_value() {
|
|
220
|
+
if (this.tryMatch('{')) {
|
|
221
|
+
return this.value_braces();
|
|
222
|
+
}
|
|
223
|
+
else if (this.tryMatch('"')) {
|
|
224
|
+
return this.value_quotes();
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
const bare = this.key();
|
|
228
|
+
if (bare.match(/^\d+$/))
|
|
229
|
+
return bare;
|
|
230
|
+
const u_bare = bare.toUpperCase();
|
|
231
|
+
const resolved = this.strings[u_bare] || this.default_strings[u_bare];
|
|
232
|
+
if (typeof resolved === 'undefined') {
|
|
233
|
+
this.errors.push({
|
|
234
|
+
error: `Unresolved @string reference ${JSON.stringify(bare)}`,
|
|
235
|
+
location: this.location(this.pos),
|
|
236
|
+
input: bare,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return resolved || `{{${bare}}}`;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
value() {
|
|
243
|
+
const values = [];
|
|
244
|
+
values.push(this.single_value());
|
|
245
|
+
while (this.tryMatch('#')) {
|
|
246
|
+
this.match('#');
|
|
247
|
+
values.push(this.single_value());
|
|
248
|
+
}
|
|
249
|
+
return values.join('');
|
|
250
|
+
}
|
|
251
|
+
key(allow = '') {
|
|
252
|
+
const start = this.pos;
|
|
253
|
+
while (true) { // eslint-disable-line no-constant-condition
|
|
254
|
+
if (this.pos === this.input.length) {
|
|
255
|
+
throw new ParsingError('Runaway key', this);
|
|
256
|
+
}
|
|
257
|
+
if (this.input[this.pos].match(/[+'a-zA-Z0-9&;_:\\./-]/) || this.input[this.pos].match(letter) || allow.includes(this.input[this.pos])) {
|
|
258
|
+
this.pos++;
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
return this.input.substring(start, this.pos);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
key_equals_value(key) {
|
|
266
|
+
key = key || this.key();
|
|
267
|
+
if (!key)
|
|
268
|
+
return; // no key found, stray comma
|
|
269
|
+
if (!this.tryMatch('=')) {
|
|
270
|
+
throw new ParsingError(`${key} = value expected, equals sign missing: ${JSON.stringify(this.input.substr(this.pos, 20))}...`, this); // eslint-disable-line no-magic-numbers
|
|
271
|
+
}
|
|
272
|
+
this.match('=');
|
|
273
|
+
const val = this.value();
|
|
274
|
+
if (this.parsing === 'string') {
|
|
275
|
+
this.strings[key.toUpperCase()] = val;
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
key = key.toLowerCase();
|
|
279
|
+
if (key.toLowerCase() === 'keywords' && this.entries[0].fields.keywords) { // #873... the things people do with bibtex
|
|
280
|
+
this.keywords++;
|
|
281
|
+
key = `keywords[${this.keywords}]`;
|
|
282
|
+
}
|
|
283
|
+
this.entries[0].fields[key] = val;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
entry(d, guard) {
|
|
287
|
+
if (this.tryMatch(guard))
|
|
288
|
+
return; // empty entry
|
|
289
|
+
let key;
|
|
290
|
+
// mendeley end endnote can output entries without key... sure...
|
|
291
|
+
if (this.tryMatch(',')) {
|
|
292
|
+
// mendeley absurdity which outputs keyless entries, but at least have the decency to put a comma there
|
|
293
|
+
key = '';
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
// so maybe a real key?
|
|
297
|
+
key = this.key('*"');
|
|
298
|
+
}
|
|
299
|
+
if (this.tryMatch('=')) {
|
|
300
|
+
// nope; endnote just skips the comma; we can infer we're in this moronic situation because we've been dumped into field-parsing
|
|
301
|
+
this.key_equals_value(key);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
// so we did find the real key earlier
|
|
305
|
+
this.entries[0].key = key;
|
|
306
|
+
}
|
|
307
|
+
this.tryMatch(',', true);
|
|
308
|
+
if (this.tryMatch(guard))
|
|
309
|
+
return; // no fields
|
|
310
|
+
this.key_equals_value();
|
|
311
|
+
while (this.tryMatch(',', true)) {
|
|
312
|
+
// fixes problems with commas at the end of a list
|
|
313
|
+
if (this.tryMatch(guard))
|
|
314
|
+
return;
|
|
315
|
+
this.key_equals_value();
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
directive() {
|
|
319
|
+
this.match('@');
|
|
320
|
+
return this.key().toLowerCase();
|
|
321
|
+
}
|
|
322
|
+
string() {
|
|
323
|
+
this.key_equals_value();
|
|
324
|
+
}
|
|
325
|
+
preamble() {
|
|
326
|
+
this.preambles.push(this.value());
|
|
327
|
+
}
|
|
328
|
+
comment() {
|
|
329
|
+
while (this.isWhitespace(this.input[this.pos], true))
|
|
330
|
+
this.pos++;
|
|
331
|
+
if (this.input[this.pos] === '{') {
|
|
332
|
+
this.comments.push(this.value_braces());
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
const start = this.pos;
|
|
336
|
+
while (this.input[this.pos] !== '\n' && this.pos < this.input.length)
|
|
337
|
+
this.pos++;
|
|
338
|
+
this.comments.push(this.input.substring(start, this.pos));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
hasMore() {
|
|
342
|
+
if (this.max_entries && this.entries.length >= this.max_entries)
|
|
343
|
+
return false;
|
|
344
|
+
return (this.pos < this.input.length);
|
|
345
|
+
}
|
|
346
|
+
bibtex() {
|
|
347
|
+
while (this.hasMore()) {
|
|
348
|
+
this.parseNext();
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
bibtexAsync() {
|
|
352
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
353
|
+
return this.hasMore() ? (new Promise(resolve => resolve(this.parseNext()))).then(() => this.bibtexAsync()) : Promise.resolve(null);
|
|
354
|
+
}
|
|
355
|
+
matchGuard() {
|
|
356
|
+
for (const guard of ['{}', '()']) {
|
|
357
|
+
if (this.tryMatch(guard[0])) {
|
|
358
|
+
this.match(guard[0]);
|
|
359
|
+
return guard[1];
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
throw new ParsingError(`Token mismatch, expected '{' or '(', found ${JSON.stringify(this.input.substr(this.pos, 20))}...`, this); // eslint-disable-line no-magic-numbers
|
|
363
|
+
}
|
|
364
|
+
parseNext() {
|
|
365
|
+
this.skipWhitespace();
|
|
366
|
+
while (this.pos < this.input.length && this.input[this.pos] !== '@') {
|
|
367
|
+
if (this.input[this.pos] === '%') {
|
|
368
|
+
while (this.pos < this.input.length && this.input[this.pos] !== '\n')
|
|
369
|
+
this.pos++;
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
this.pos++;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
if (this.pos >= this.input.length)
|
|
376
|
+
return;
|
|
377
|
+
let guard = '';
|
|
378
|
+
const start = this.pos;
|
|
379
|
+
try {
|
|
380
|
+
const d = this.parsing = this.directive();
|
|
381
|
+
switch (d) {
|
|
382
|
+
case 'string':
|
|
383
|
+
guard = this.matchGuard();
|
|
384
|
+
this.string();
|
|
385
|
+
this.match(guard);
|
|
386
|
+
break;
|
|
387
|
+
case 'preamble':
|
|
388
|
+
this.preamble();
|
|
389
|
+
break;
|
|
390
|
+
case 'comment':
|
|
391
|
+
this.comment();
|
|
392
|
+
break;
|
|
393
|
+
default:
|
|
394
|
+
guard = this.matchGuard();
|
|
395
|
+
this.entries.unshift({ input: '', type: d, key: '', fields: {} });
|
|
396
|
+
this.entry(d, guard);
|
|
397
|
+
this.match(guard);
|
|
398
|
+
this.entries[0].input = this.input.substring(start, this.pos).trim();
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
catch (err) {
|
|
403
|
+
if (err.name !== 'ParsingError')
|
|
404
|
+
throw err;
|
|
405
|
+
// skip ahead to the next @ and try again
|
|
406
|
+
this.pos = start + 1;
|
|
407
|
+
while (this.pos < this.input.length && this.input[this.pos] !== '@')
|
|
408
|
+
this.pos++;
|
|
409
|
+
this.errors.push({
|
|
410
|
+
error: err.message,
|
|
411
|
+
input: this.input.substring(start, this.pos),
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Parses a bibtex source in verbatim mode. Good for detection of bibtex and for later LaTeX-reparsing.
|
|
418
|
+
*/
|
|
419
|
+
function parse(input, options = {}) {
|
|
420
|
+
const parser = new Parser(input, options);
|
|
421
|
+
parser.parse();
|
|
422
|
+
return parser;
|
|
423
|
+
}
|
|
424
|
+
exports.parse = parse;
|
|
425
|
+
exports.promises = {
|
|
426
|
+
async parse(input, options = {}) {
|
|
427
|
+
const parser = new Parser(input, options);
|
|
428
|
+
await parser.parseAsync();
|
|
429
|
+
return parser;
|
|
430
|
+
},
|
|
431
|
+
};
|
|
432
|
+
//# sourceMappingURL=verbatim.js.map
|