@retorquere/bibtex-parser 6.4.3 → 6.4.5

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/index.d.ts CHANGED
@@ -63,6 +63,13 @@ export interface Entry {
63
63
  * will be set to `true` if sentence casing was applied to the entry
64
64
  */
65
65
  sentenceCased?: boolean;
66
+ /**
67
+ * list of fields that have been inherited/donated using crossref/xdata
68
+ */
69
+ crossref: {
70
+ donated: string[];
71
+ inherited: string[];
72
+ };
66
73
  }
67
74
  /**
68
75
  * Markup mapping. As the bibtex file is parsed, markup will be transformed according to this table
package/index.js CHANGED
@@ -11,6 +11,7 @@ exports.jabref = jabref;
11
11
  const jabref_1 = require("./jabref");
12
12
  const unicode2latex_1 = require("unicode2latex");
13
13
  const crossref_json_1 = tslib_1.__importDefault(require("./crossref.json"));
14
+ const fields_json_1 = tslib_1.__importDefault(require("./fields.json"));
14
15
  const xregexp_1 = tslib_1.__importDefault(require("xregexp"));
15
16
  function restore(text, orig, preserve) {
16
17
  for (const { start, end } of preserve) {
@@ -386,6 +387,46 @@ class Parser {
386
387
  }
387
388
  return this.parsed();
388
389
  }
390
+ applyCrossrefField(parent, parentfield, child, childfield) {
391
+ let applied = false;
392
+ for (const field of ['fields', 'creators']) {
393
+ if (!child[field][childfield] && parent[field][parentfield]) {
394
+ child[field][childfield] = parent[field][parentfield];
395
+ applied = true;
396
+ if (!child.crossref.inherited.includes(childfield))
397
+ child.crossref.inherited.push(childfield);
398
+ if (!parent.crossref.donated.includes(parentfield))
399
+ parent.crossref.donated.push(parentfield);
400
+ }
401
+ }
402
+ return applied;
403
+ }
404
+ applyCrossref(entry, entries) {
405
+ for (const xref of ['crossref', 'xdata']) {
406
+ if (!entry.fields[xref])
407
+ continue;
408
+ for (const parents of entry.fields[xref]) {
409
+ let applied = false;
410
+ for (const parent of parents.split(/\s*,\s*/).map(key => entries[key]).filter(p => p)) {
411
+ this.applyCrossref(parent, entries);
412
+ for (const mappings of [crossref_json_1.default[entry.type], crossref_json_1.default['*']].filter(m => m)) {
413
+ for (const mapping of [mappings[parent.type], mappings['*']].filter(m => m)) {
414
+ for (const [target, source] of Object.entries(mapping)) {
415
+ if (this.applyCrossrefField(parent, source, entry, target))
416
+ applied = true;
417
+ }
418
+ for (const field of (fields_json_1.default[entry.type] || [])) {
419
+ if (this.applyCrossrefField(parent, field, entry, field))
420
+ applied = true;
421
+ }
422
+ }
423
+ }
424
+ }
425
+ if (applied)
426
+ delete entry.fields[xref];
427
+ }
428
+ }
429
+ }
389
430
  parsed() {
390
431
  this.field = null;
391
432
  const strings = {};
@@ -411,24 +452,7 @@ class Parser {
411
452
  return acc;
412
453
  }, {});
413
454
  for (const entry of this.entries) {
414
- if (entry.fields.crossref) {
415
- let applied;
416
- for (const parent_key of entry.fields.crossref) {
417
- const parent = entries[parent_key];
418
- if (!parent)
419
- continue;
420
- for (const mapping of crossref_json_1.default.filter(xref => xref.source.includes(parent.type) && xref.target.includes(entry.type))) {
421
- for (const { source, target } of mapping.fields) {
422
- if (parent.fields[source] && !entry.fields[target]) {
423
- applied = true;
424
- entry.fields[target] = JSON.parse(JSON.stringify(parent.fields[source]));
425
- }
426
- }
427
- }
428
- }
429
- if (applied)
430
- delete entry.fields.crossref;
431
- }
455
+ this.applyCrossref(entry, entries);
432
456
  }
433
457
  }
434
458
  const { comments, jabref } = (0, jabref_1.parse)(this.comments); // eslint-disable-line @typescript-eslint/no-shadow
@@ -1277,6 +1301,10 @@ class Parser {
1277
1301
  type: node.type,
1278
1302
  fields: {},
1279
1303
  creators: {},
1304
+ crossref: {
1305
+ inherited: [],
1306
+ donated: [],
1307
+ },
1280
1308
  };
1281
1309
  this.entries.push(this.entry);
1282
1310
  // order these first for language-dependent sentence casing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retorquere/bibtex-parser",
3
- "version": "6.4.3",
3
+ "version": "6.4.5",
4
4
  "description": "BibTeX parser",
5
5
  "main": "index.js",
6
6
  "typings": "./index.d.ts",
@@ -13,7 +13,7 @@
13
13
  "test": "tap test/tap --no-timeout --no-coverage",
14
14
  "snap": "npm test --snapshot",
15
15
  "snap:big": "npm test --snapshot --big",
16
- "minitest": "peggy grammar.peggy && tsc -d && node i.js",
16
+ "minitest": "peggy grammar.peggy && ./build/crossref.py && tsc -d && node i.js",
17
17
  "list": "tar tvf $(npm pack)",
18
18
  "prepublishOnly": "npm start",
19
19
  "abbr": "./build/abbr.py",
@@ -22,7 +22,7 @@
22
22
  "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/",
23
23
  "x-docs": "rm -rf docs temp && typedoc --name 'BibTeX parser' index.ts && touch docs/.nojekyll",
24
24
  "docs": "mkdir -p etc temp && npm run api-extractor && npm run api-documenter",
25
- "ncu": "./build/submodules.py && ncu -u && npm i && git add package.json package-lock.json && npm audit fix && git commit -m ncu",
25
+ "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",
26
26
  "api-documenter": "api-documenter markdown --input temp --output docs",
27
27
  "api-extractor": "api-extractor run --local --verbose"
28
28
  },
@@ -39,14 +39,14 @@
39
39
  "@microsoft/api-documenter": "^7.19.27",
40
40
  "@microsoft/api-extractor": "^7.33.7",
41
41
  "@types/node": "^18.11.18",
42
- "@typescript-eslint/eslint-plugin": "^5.48.0",
43
- "@typescript-eslint/parser": "^5.48.0",
42
+ "@typescript-eslint/eslint-plugin": "^5.48.1",
43
+ "@typescript-eslint/parser": "^5.48.1",
44
44
  "command-line-args": "^5.2.1",
45
45
  "csv": "^6.2.5",
46
46
  "digital-tree": "^2.0.4",
47
47
  "ejs": "^3.1.8",
48
48
  "eslint": "^8.31.0",
49
- "eslint-plugin-import": "^2.26.0",
49
+ "eslint-plugin-import": "^2.27.4",
50
50
  "eslint-plugin-prefer-arrow": "^1.2.3",
51
51
  "glob": "^8.0.3",
52
52
  "mkdirp": "^1.0.4",
@@ -54,7 +54,7 @@
54
54
  "peggy": "^2.0.1",
55
55
  "piscina": "^3.2.0",
56
56
  "slug": "^8.2.2",
57
- "tap": "^16.3.2",
57
+ "tap": "^16.3.3",
58
58
  "ts-node": "^10.9.1",
59
59
  "tslib": "^2.4.1",
60
60
  "typescript": "^4.9.4"
@@ -75,6 +75,7 @@
75
75
  "jabref.js",
76
76
  "README.md",
77
77
  "crossref.json",
78
+ "fields.json",
78
79
  "strings.bib",
79
80
  "unabbrev.json"
80
81
  ],