@manuscripts/transform 4.5.7 → 4.6.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 (63) hide show
  1. package/dist/cjs/jats/__tests__/jats-exporter.test.js +50 -20
  2. package/dist/cjs/jats/__tests__/jats-importer.test.js +26 -0
  3. package/dist/cjs/jats/__tests__/jats-roundtrip.test.js +6 -1
  4. package/dist/cjs/jats/exporter/JATSExporterBase.js +118 -0
  5. package/dist/cjs/jats/exporter/jats-exporter.js +227 -349
  6. package/dist/cjs/jats/exporter/lib.js +62 -0
  7. package/dist/cjs/jats/importer/jats-dom-parser.js +11 -3
  8. package/dist/cjs/schema/index.js +4 -1
  9. package/dist/cjs/schema/migration/migration-scripts/4.5.9.js +30 -0
  10. package/dist/cjs/schema/migration/migration-scripts/index.js +3 -1
  11. package/dist/cjs/schema/nodes/bibliography_element.js +0 -1
  12. package/dist/cjs/schema/nodes/bio.js +24 -0
  13. package/dist/cjs/schema/nodes/contributor.js +1 -2
  14. package/dist/cjs/schema/nodes/keywords_element.js +0 -1
  15. package/dist/cjs/types.js +1 -1
  16. package/dist/cjs/version.js +1 -1
  17. package/dist/es/jats/__tests__/jats-exporter.test.js +47 -20
  18. package/dist/es/jats/__tests__/jats-importer.test.js +26 -0
  19. package/dist/es/jats/__tests__/jats-roundtrip.test.js +3 -1
  20. package/dist/es/jats/exporter/JATSExporterBase.js +114 -0
  21. package/dist/es/jats/exporter/jats-exporter.js +201 -319
  22. package/dist/es/jats/exporter/lib.js +55 -0
  23. package/dist/es/jats/importer/jats-dom-parser.js +11 -3
  24. package/dist/es/schema/index.js +4 -1
  25. package/dist/es/schema/migration/migration-scripts/4.5.9.js +28 -0
  26. package/dist/es/schema/migration/migration-scripts/index.js +3 -1
  27. package/dist/es/schema/nodes/bibliography_element.js +0 -1
  28. package/dist/es/schema/nodes/bio.js +20 -0
  29. package/dist/es/schema/nodes/contributor.js +1 -2
  30. package/dist/es/schema/nodes/keywords_element.js +0 -1
  31. package/dist/es/types.js +1 -1
  32. package/dist/es/version.js +1 -1
  33. package/dist/types/jats/exporter/JATSExporterBase.d.ts +35 -0
  34. package/dist/types/jats/exporter/jats-exporter.d.ts +23 -19
  35. package/dist/types/jats/exporter/lib.d.ts +23 -0
  36. package/dist/types/schema/index.d.ts +2 -1
  37. package/dist/types/schema/migration/migration-scripts/4.5.9.d.ts +8 -0
  38. package/dist/types/schema/migration/migration-scripts/index.d.ts +3 -2
  39. package/dist/types/schema/nodes/bio.d.ts +10 -0
  40. package/dist/types/schema/types.d.ts +1 -1
  41. package/dist/types/types.d.ts +1 -1
  42. package/dist/types/version.d.ts +1 -1
  43. package/package.json +4 -4
  44. package/src/jats/__tests__/__fixtures__/jats-import.xml +7 -0
  45. package/src/jats/__tests__/__snapshots__/jats-importer.test.ts.snap +272 -151
  46. package/src/jats/__tests__/__snapshots__/jats-roundtrip.test.ts.snap +2 -2
  47. package/src/jats/__tests__/jats-exporter.test.ts +60 -20
  48. package/src/jats/__tests__/jats-importer.test.ts +37 -0
  49. package/src/jats/__tests__/jats-roundtrip.test.ts +3 -1
  50. package/src/jats/exporter/JATSExporterBase.ts +164 -0
  51. package/src/jats/exporter/jats-exporter.ts +217 -386
  52. package/src/jats/exporter/lib.ts +69 -0
  53. package/src/jats/importer/jats-dom-parser.ts +15 -5
  54. package/src/schema/index.ts +4 -1
  55. package/src/schema/migration/migration-scripts/4.5.9.ts +62 -0
  56. package/src/schema/migration/migration-scripts/index.ts +3 -1
  57. package/src/schema/nodes/bibliography_element.ts +0 -1
  58. package/src/schema/nodes/bio.ts +48 -0
  59. package/src/schema/nodes/contributor.ts +1 -2
  60. package/src/schema/nodes/keywords_element.ts +0 -1
  61. package/src/schema/types.ts +1 -0
  62. package/src/types.ts +1 -1
  63. package/src/version.ts +1 -1
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*!
3
- * © 2019 Atypon Systems LLC
3
+ * © 2026 Atypon Systems LLC
4
4
  *
5
5
  * Licensed under the Apache License, Version 2.0 (the "License");
6
6
  * you may not use this file except in compliance with the License.
@@ -47,15 +47,11 @@ var __importStar = (this && this.__importStar) || (function () {
47
47
  return result;
48
48
  };
49
49
  })();
50
- var __importDefault = (this && this.__importDefault) || function (mod) {
51
- return (mod && mod.__esModule) ? mod : { "default": mod };
52
- };
53
50
  Object.defineProperty(exports, "__esModule", { value: true });
54
- exports.JATSExporter = exports.createCounter = void 0;
51
+ exports.JATSExporter = void 0;
55
52
  const Citeproc = __importStar(require("citeproc"));
56
53
  const prosemirror_model_1 = require("prosemirror-model");
57
54
  const prosemirror_utils_1 = require("prosemirror-utils");
58
- const w3c_xmlserializer_1 = __importDefault(require("w3c-xmlserializer"));
59
55
  const citeproc_1 = require("../../lib/citeproc");
60
56
  const credit_roles_1 = require("../../lib/credit-roles");
61
57
  const footnotes_1 = require("../../lib/footnotes");
@@ -66,59 +62,13 @@ const transformer_1 = require("../../transformer");
66
62
  const citeproc_2 = require("./citeproc");
67
63
  const jats_versions_1 = require("./jats-versions");
68
64
  const labels_1 = require("./labels");
69
- const normalizeID = (id) => id.replace(/:/g, '_');
70
- const createCounter = () => {
71
- const counts = new Map();
72
- return {
73
- increment: (field) => {
74
- const value = counts.get(field);
75
- const newValue = value === undefined ? 1 : value + 1;
76
- counts.set(field, newValue);
77
- return newValue;
78
- },
79
- };
80
- };
81
- exports.createCounter = createCounter;
82
- const createDefaultIDGenerator = () => {
83
- const counter = (0, exports.createCounter)();
84
- return async (element) => {
85
- const value = String(counter.increment(element.nodeName));
86
- return `${element.localName}-${value}`;
87
- };
88
- };
89
- const chooseRefType = (type) => {
90
- switch (type) {
91
- case schema_1.schema.nodes.figure:
92
- case schema_1.schema.nodes.figure_element:
93
- return 'fig';
94
- case schema_1.schema.nodes.footnote:
95
- return 'fn';
96
- case schema_1.schema.nodes.table:
97
- case schema_1.schema.nodes.table_element:
98
- return 'table';
99
- case schema_1.schema.nodes.section:
100
- case schema_1.schema.nodes.abstract:
101
- return 'sec';
102
- case schema_1.schema.nodes.equation:
103
- case schema_1.schema.nodes.equation_element:
104
- return 'disp-formula';
105
- case schema_1.schema.nodes.supplement:
106
- return 'supplementary-material';
107
- }
108
- };
109
- class JATSExporter {
65
+ const JATSExporterBase_1 = require("./JATSExporterBase");
66
+ const lib_1 = require("./lib");
67
+ class JATSExporter extends JATSExporterBase_1.JATSExporterBase {
110
68
  constructor() {
111
- this.nodesMap = new Map();
69
+ super(...arguments);
112
70
  this.contributorLabels = new Map();
113
- this.populateNodesMap = () => {
114
- this.manuscriptNode.descendants((node) => {
115
- const type = node.type;
116
- const nodes = this.nodesMap.get(type) ?? [];
117
- nodes.push(node);
118
- this.nodesMap.set(type, nodes);
119
- });
120
- };
121
- this.serializeToJATS = async (manuscriptNode, options) => {
71
+ this.export = async (manuscriptNode, options) => {
122
72
  this.manuscriptNode = manuscriptNode;
123
73
  this.populateNodesMap();
124
74
  this.initCiteprocEngine(options);
@@ -149,7 +99,7 @@ class JATSExporter {
149
99
  $article.appendChild($floatsGroup);
150
100
  }
151
101
  await this.rewriteIDs();
152
- return (0, w3c_xmlserializer_1.default)(this.document);
102
+ return this.document;
153
103
  };
154
104
  this.appendChildNodeOfType = ($element, node, type) => {
155
105
  const childNode = this.getFirstChildOfType(type, node);
@@ -213,7 +163,7 @@ class JATSExporter {
213
163
  $template.innerHTML = fragment;
214
164
  return $template.firstChild;
215
165
  };
216
- this.rewriteIDs = async (generator = createDefaultIDGenerator()) => {
166
+ this.rewriteIDs = async (generator = (0, lib_1.createDefaultIDGenerator)()) => {
217
167
  const ids = new Map();
218
168
  for (const $element of this.document.querySelectorAll('[id]')) {
219
169
  const oldID = $element.getAttribute('id');
@@ -440,7 +390,7 @@ class JATSExporter {
440
390
  const [, bibliography] = this.engine.makeBibliography();
441
391
  const parser = new DOMParser();
442
392
  bibliography.forEach((item) => {
443
- const fragment = `<template xmlns:xlink="${xml_1.XLINK_NAMESPACE}">${(0, xml_1.sanitizeXmlString)(item)}</template>`;
393
+ const fragment = `<wrapper xmlns:xlink="${xml_1.XLINK_NAMESPACE}">${(0, xml_1.sanitizeXmlString)(item)}</wrapper>`;
444
394
  const $ref = parser
445
395
  .parseFromString(fragment, 'text/xml')
446
396
  .querySelector('ref');
@@ -450,32 +400,13 @@ class JATSExporter {
450
400
  });
451
401
  return $refList;
452
402
  };
453
- this.createElement = (tag, content, attrs) => {
454
- const $element = this.document.createElement(tag);
455
- if (content) {
456
- $element.textContent = content;
457
- }
458
- if (attrs) {
459
- Object.entries(attrs).forEach(([k, v]) => {
460
- if (v) {
461
- $element.setAttribute(k, v);
462
- }
463
- });
464
- }
465
- return $element;
466
- };
467
- this.appendElement = ($parent, tag, content, attrs) => {
468
- const $element = this.createElement(tag, content, attrs);
469
- $parent.appendChild($element);
470
- return $element;
471
- };
472
403
  this.createSerializer = () => {
473
404
  const nodes = {
474
- trans_abstract: (node) => createTransAbstract(node),
475
- trans_graphical_abstract: (node) => createTransAbstract(node),
405
+ trans_abstract: (node) => this.createTransAbstract(node),
406
+ trans_graphical_abstract: (node) => this.createTransAbstract(node),
476
407
  hero_image: () => '',
477
408
  headshot_grid: () => ['p', { 'content-type': 'headshots' }, 0],
478
- headshot_element: (node) => createImage(node),
409
+ headshot_element: (node) => this.createImage(node),
479
410
  headshot_image: () => '',
480
411
  alt_text: (node) => {
481
412
  if (node.textContent) {
@@ -500,14 +431,14 @@ class JATSExporter {
500
431
  return $selfUri;
501
432
  },
502
433
  attachments: () => '',
503
- image_element: (node) => createImage(node),
434
+ image_element: (node) => this.createImage(node),
504
435
  embed: (node) => {
505
436
  const { id, href, mimetype, mimeSubtype, extLinks } = node.attrs;
506
437
  if (!href) {
507
438
  return '';
508
439
  }
509
440
  const $media = this.createElement('media');
510
- $media.setAttribute('id', normalizeID(id));
441
+ $media.setAttribute('id', (0, lib_1.normalizeID)(id));
511
442
  $media.setAttributeNS(xml_1.XLINK_NAMESPACE, 'show', 'embed');
512
443
  $media.setAttributeNS(xml_1.XLINK_NAMESPACE, 'href', href);
513
444
  if (mimetype) {
@@ -516,7 +447,7 @@ class JATSExporter {
516
447
  if (mimeSubtype) {
517
448
  $media.setAttribute('mime-subtype', node.attrs.mimeSubtype);
518
449
  }
519
- appendLabels($media, node);
450
+ this.appendLabels($media, node);
520
451
  this.appendChildNodeOfType($media, node, schema_1.schema.nodes.alt_text);
521
452
  this.appendChildNodeOfType($media, node, schema_1.schema.nodes.long_desc);
522
453
  this.appendCaption($media, node);
@@ -542,15 +473,15 @@ class JATSExporter {
542
473
  award: (node) => {
543
474
  const awardGroup = node;
544
475
  const $awardGroup = this.createElement('award-group');
545
- $awardGroup.setAttribute('id', normalizeID(awardGroup.attrs.id));
546
- appendChildIfPresent($awardGroup, 'funding-source', awardGroup.attrs.source);
476
+ $awardGroup.setAttribute('id', (0, lib_1.normalizeID)(awardGroup.attrs.id));
477
+ this.appendChildIfPresent($awardGroup, 'funding-source', awardGroup.attrs.source);
547
478
  awardGroup.attrs.code
548
479
  ?.split(';')
549
- .forEach((code) => appendChildIfPresent($awardGroup, 'award-id', code));
550
- appendChildIfPresent($awardGroup, 'principal-award-recipient', awardGroup.attrs.recipient);
480
+ .forEach((code) => this.appendChildIfPresent($awardGroup, 'award-id', code));
481
+ this.appendChildIfPresent($awardGroup, 'principal-award-recipient', awardGroup.attrs.recipient);
551
482
  return $awardGroup;
552
483
  },
553
- box_element: (node) => createBoxElement(node),
484
+ box_element: (node) => this.createBoxElement(node),
554
485
  author_notes: () => '',
555
486
  corresp: () => '',
556
487
  title: () => ['article-title', 0],
@@ -569,6 +500,7 @@ class JATSExporter {
569
500
  ? ['table-wrap-foot', ['fn-group', ['fn', ['p']]]]
570
501
  : ['table-wrap-foot', 0],
571
502
  contributor: (node) => this.buildContributorElement(node),
503
+ bio: () => ['bio', 0],
572
504
  affiliation: (node) => this.buildAffiliationElement(node),
573
505
  attribution: () => ['attrib', 0],
574
506
  bibliography_element: () => '',
@@ -586,11 +518,11 @@ class JATSExporter {
586
518
  backmatter: () => ['backmatter', 0],
587
519
  supplement: (node) => {
588
520
  const $supplementaryMaterial = this.createElement('supplementary-material');
589
- $supplementaryMaterial.setAttribute('id', normalizeID(node.attrs.id));
521
+ $supplementaryMaterial.setAttribute('id', (0, lib_1.normalizeID)(node.attrs.id));
590
522
  $supplementaryMaterial.setAttributeNS(xml_1.XLINK_NAMESPACE, 'href', node.attrs.href ?? '');
591
523
  $supplementaryMaterial.setAttribute('mimetype', node.attrs.mimeType ?? '');
592
524
  $supplementaryMaterial.setAttribute('mime-subtype', node.attrs.mimeSubType ?? '');
593
- appendLabels($supplementaryMaterial, node);
525
+ this.appendLabels($supplementaryMaterial, node);
594
526
  this.appendCaption($supplementaryMaterial, node);
595
527
  return $supplementaryMaterial;
596
528
  },
@@ -619,7 +551,7 @@ class JATSExporter {
619
551
  }
620
552
  const $xref = this.createElement('xref');
621
553
  $xref.setAttribute('ref-type', 'bibr');
622
- $xref.setAttribute('rid', normalizeID(rids.join(' ')));
554
+ $xref.setAttribute('rid', (0, lib_1.normalizeID)(rids.join(' ')));
623
555
  const fragment = this.renderedCitations.get(node.attrs.id);
624
556
  if (fragment) {
625
557
  $xref.innerHTML = fragment;
@@ -645,11 +577,11 @@ class JATSExporter {
645
577
  return text;
646
578
  }
647
579
  const $xref = this.createElement('xref');
648
- const type = chooseRefType(target.type);
580
+ const type = (0, lib_1.chooseRefType)(target.type);
649
581
  if (type) {
650
582
  $xref.setAttribute('ref-type', type);
651
583
  }
652
- $xref.setAttribute('rid', normalizeID(rids.join(' ')));
584
+ $xref.setAttribute('rid', (0, lib_1.normalizeID)(rids.join(' ')));
653
585
  $xref.textContent = text ?? '';
654
586
  return $xref;
655
587
  },
@@ -675,17 +607,17 @@ class JATSExporter {
675
607
  },
676
608
  equation_element: (node) => {
677
609
  const $dispFormula = this.createElement('disp-formula');
678
- $dispFormula.setAttribute('id', normalizeID(node.attrs.id));
679
- appendLabels($dispFormula, node);
680
- processChildNodes($dispFormula, node, schema_1.schema.nodes.equation);
610
+ $dispFormula.setAttribute('id', (0, lib_1.normalizeID)(node.attrs.id));
611
+ this.appendLabels($dispFormula, node);
612
+ this.processChildNodes($dispFormula, node, schema_1.schema.nodes.equation);
681
613
  return $dispFormula;
682
614
  },
683
- figure: (node) => createGraphic(node),
684
- figure_element: (node) => createFigureElement(node, node.type.schema.nodes.figure),
615
+ figure: (node) => this.createGraphic(node),
616
+ figure_element: (node) => this.createFigureElement(node, node.type.schema.nodes.figure),
685
617
  footnote: (node) => {
686
618
  const attrs = {};
687
619
  if (node.attrs.id) {
688
- attrs.id = normalizeID(node.attrs.id);
620
+ attrs.id = (0, lib_1.normalizeID)(node.attrs.id);
689
621
  }
690
622
  if (node.attrs.category) {
691
623
  attrs['fn-type'] = node.attrs.category;
@@ -693,11 +625,11 @@ class JATSExporter {
693
625
  return ['fn', attrs, 0];
694
626
  },
695
627
  footnotes_element: (node) => node.childCount == 0
696
- ? ['fn-group', { id: normalizeID(node.attrs.id) }, ['fn', ['p']]]
697
- : ['fn-group', { id: normalizeID(node.attrs.id) }, 0],
628
+ ? ['fn-group', { id: (0, lib_1.normalizeID)(node.attrs.id) }, ['fn', ['p']]]
629
+ : ['fn-group', { id: (0, lib_1.normalizeID)(node.attrs.id) }, 0],
698
630
  footnotes_section: (node) => {
699
631
  const $fnGroup = this.createElement('fn-group', undefined, {
700
- id: normalizeID(node.attrs.id),
632
+ id: (0, lib_1.normalizeID)(node.attrs.id),
701
633
  });
702
634
  const titleNode = this.getFirstChildOfType(schema_1.schema.nodes.section_title, node);
703
635
  if (titleNode) {
@@ -722,7 +654,7 @@ class JATSExporter {
722
654
  const rids = node.attrs.rids;
723
655
  const $xref = this.createElement('xref');
724
656
  $xref.setAttribute('ref-type', 'fn');
725
- $xref.setAttribute('rid', normalizeID(rids.join(' ')));
657
+ $xref.setAttribute('rid', (0, lib_1.normalizeID)(rids.join(' ')));
726
658
  $xref.textContent = rids
727
659
  .map((rid) => this.footnoteLabels.get(rid))
728
660
  .join(', ');
@@ -751,13 +683,13 @@ class JATSExporter {
751
683
  list_item: () => ['list-item', 0],
752
684
  listing: (node) => {
753
685
  const $code = this.createElement('code');
754
- $code.setAttribute('id', normalizeID(node.attrs.id));
686
+ $code.setAttribute('id', (0, lib_1.normalizeID)(node.attrs.id));
755
687
  $code.setAttribute('language', node.attrs.languageKey);
756
688
  $code.textContent = node.attrs.contents;
757
689
  return $code;
758
690
  },
759
- listing_element: (node) => createFigureElement(node, node.type.schema.nodes.listing),
760
- manuscript: (node) => ['article', { id: normalizeID(node.attrs.id) }, 0],
691
+ listing_element: (node) => this.createFigureElement(node, node.type.schema.nodes.listing),
692
+ manuscript: (node) => ['article', { id: (0, lib_1.normalizeID)(node.attrs.id) }, 0],
761
693
  missing_figure: () => {
762
694
  const $graphic = this.createElement('graphic');
763
695
  $graphic.setAttribute('specific-use', 'MISSING');
@@ -770,7 +702,7 @@ class JATSExporter {
770
702
  }
771
703
  const attrs = {};
772
704
  if (node.attrs.id) {
773
- attrs.id = normalizeID(node.attrs.id);
705
+ attrs.id = (0, lib_1.normalizeID)(node.attrs.id);
774
706
  }
775
707
  if (node.attrs.contentType) {
776
708
  attrs['content-type'] = node.attrs.contentType;
@@ -793,27 +725,27 @@ class JATSExporter {
793
725
  quote_image: (node) => {
794
726
  const img = node;
795
727
  if (img.attrs.src) {
796
- return createGraphic(node);
728
+ return this.createGraphic(node);
797
729
  }
798
730
  return '';
799
731
  },
800
- graphical_abstract_section: (node) => createAbstract(node),
732
+ graphical_abstract_section: (node) => this.createAbstract(node),
801
733
  section: (node) => {
802
734
  const attrs = {
803
- id: normalizeID(node.attrs.id),
735
+ id: (0, lib_1.normalizeID)(node.attrs.id),
804
736
  };
805
737
  if (node.attrs.category) {
806
738
  attrs['sec-type'] = node.attrs.category;
807
739
  }
808
740
  return ['sec', attrs, 0];
809
741
  },
810
- abstract: (node) => createAbstract(node),
742
+ abstract: (node) => this.createAbstract(node),
811
743
  section_label: () => ['label', 0],
812
744
  section_title: () => ['title', 0],
813
745
  section_title_plain: () => ['title', 0],
814
- table: (node) => ['table', { id: normalizeID(node.attrs.id) }, 0],
746
+ table: (node) => ['table', { id: (0, lib_1.normalizeID)(node.attrs.id) }, 0],
815
747
  table_element: (node) => {
816
- const $tableWrap = createTableElement(node);
748
+ const $tableWrap = this.createTableElement(node);
817
749
  $tableWrap.setAttribute('position', 'anchor');
818
750
  if (node.attrs.type) {
819
751
  $tableWrap.setAttribute('content-type', node.attrs.type);
@@ -864,210 +796,7 @@ class JATSExporter {
864
796
  tracked_delete: () => ['del'],
865
797
  };
866
798
  this.serializer = new prosemirror_model_1.DOMSerializer(nodes, marks);
867
- const appendChildIfPresent = ($parent, tagName, textContent) => {
868
- if (!textContent) {
869
- return;
870
- }
871
- const $element = this.createElement(tagName);
872
- $element.textContent = textContent;
873
- $parent.appendChild($element);
874
- };
875
- const processChildNodes = ($element, node, contentNodeType) => {
876
- node.forEach((childNode) => {
877
- if (childNode.type === contentNodeType) {
878
- if (childNode.attrs.id) {
879
- $element.appendChild(this.serializeNode(childNode));
880
- }
881
- }
882
- else if (childNode.type === node.type.schema.nodes.paragraph) {
883
- $element.appendChild(this.serializeNode(childNode));
884
- }
885
- else if (childNode.type === node.type.schema.nodes.missing_figure) {
886
- $element.appendChild(this.serializeNode(childNode));
887
- }
888
- });
889
- };
890
- const createElement = (node, nodeName) => {
891
- const $element = this.createElement(nodeName);
892
- $element.setAttribute('id', normalizeID(node.attrs.id));
893
- return $element;
894
- };
895
- const appendLabels = ($element, node) => {
896
- if (this.labelTargets) {
897
- const target = this.labelTargets.get(node.attrs.id);
898
- if (target) {
899
- const $label = this.createElement('label');
900
- $label.textContent = target.label;
901
- $element.appendChild($label);
902
- }
903
- }
904
- };
905
- const appendAttributions = ($element, node) => {
906
- if (node.attrs.attribution) {
907
- const $attrib = this.createElement('attrib');
908
- $attrib.textContent = node.attrs.attribution.literal;
909
- $element.appendChild($attrib);
910
- }
911
- };
912
- const appendTable = ($element, node) => {
913
- const tableNode = this.getFirstChildOfType(schema_1.schema.nodes.table, node);
914
- const colGroupNode = this.getFirstChildOfType(schema_1.schema.nodes.table_colgroup, node);
915
- if (!tableNode) {
916
- return;
917
- }
918
- const $table = this.serializeNode(tableNode);
919
- const $tbody = this.createElement('tbody');
920
- while ($table.firstChild) {
921
- const $child = $table.firstChild;
922
- $table.removeChild($child);
923
- $tbody.appendChild($child);
924
- }
925
- $table.appendChild($tbody);
926
- this.normalizeTable($table);
927
- if (colGroupNode) {
928
- const $colGroup = this.serializeNode(colGroupNode);
929
- $table.insertBefore($colGroup, $table.firstChild);
930
- }
931
- $element.appendChild($table);
932
- };
933
- const createBoxElement = (node) => {
934
- const $boxedText = createElement(node, 'boxed-text');
935
- if (node.attrs.type) {
936
- $boxedText.setAttribute('content-type', node.attrs.type);
937
- }
938
- appendLabels($boxedText, node);
939
- const child = node.firstChild;
940
- if (child?.type === schema_1.schema.nodes.caption_title) {
941
- this.appendCaption($boxedText, node);
942
- }
943
- processChildNodes($boxedText, node, node.type.schema.nodes.section);
944
- return $boxedText;
945
- };
946
- const abstractTypeAttrs = (category) => category && category !== 'abstract' ? { 'abstract-type': category } : {};
947
- const createAbstract = (node) => [
948
- 'abstract',
949
- abstractTypeAttrs(node.attrs.category),
950
- 0,
951
- ];
952
- const createTransAbstract = (node) => [
953
- 'trans-abstract',
954
- {
955
- [`${xml_1.XML_NAMESPACE} lang`]: node.attrs.lang ?? '',
956
- ...abstractTypeAttrs(node.attrs.category),
957
- },
958
- 0,
959
- ];
960
- const isChildOfNodeType = (targetID, type, descend = false) => {
961
- const nodes = this.getChildrenOfType(type);
962
- return nodes.some((node) => {
963
- const result = (0, prosemirror_utils_1.findChildrenByAttr)(node, (attrs) => attrs.id === targetID, descend)[0];
964
- return !!result;
965
- });
966
- };
967
- const findParentHeroImage = (targetID) => {
968
- const heroes = this.getChildrenOfType(schema_1.schema.nodes.hero_image);
969
- return heroes.find((hero) => !!(0, prosemirror_utils_1.findChildrenByAttr)(hero, (attrs) => attrs.id === targetID)[0]);
970
- };
971
- const createImage = (node) => {
972
- const graphicNode = node.content.firstChild;
973
- if (!graphicNode) {
974
- return '';
975
- }
976
- const $graphic = createGraphic(graphicNode);
977
- if (node.attrs.extLink) {
978
- const $extLink = this.appendElement($graphic, 'ext-link');
979
- $extLink.setAttributeNS(xml_1.XLINK_NAMESPACE, 'href', node.attrs.extLink);
980
- }
981
- this.appendCaption($graphic, node);
982
- this.appendChildNodeOfType($graphic, node, schema_1.schema.nodes.alt_text);
983
- this.appendChildNodeOfType($graphic, node, schema_1.schema.nodes.long_desc);
984
- return $graphic;
985
- };
986
- const createGraphic = (node) => {
987
- const $graphic = this.createElement('graphic');
988
- $graphic.setAttributeNS(xml_1.XLINK_NAMESPACE, 'xlink:href', node.attrs.src);
989
- const hero = findParentHeroImage(node.attrs.id);
990
- if (hero) {
991
- $graphic.setAttribute('content-type', hero.attrs.type || 'leading');
992
- }
993
- else if (!isChildOfNodeType(node.attrs.id, schema_1.schema.nodes.figure_element) &&
994
- node.attrs.type) {
995
- $graphic.setAttribute('content-type', node.attrs.type);
996
- }
997
- return $graphic;
998
- };
999
- const createFigureElement = (node, contentNodeType) => {
1000
- const $fig = createElement(node, 'fig');
1001
- const figNode = this.getFirstChildOfType(schema_1.schema.nodes.figure, node);
1002
- const figType = figNode?.attrs.type;
1003
- if (figType) {
1004
- $fig.setAttribute('fig-type', figType);
1005
- }
1006
- appendLabels($fig, node);
1007
- this.appendCaption($fig, node);
1008
- this.appendChildNodeOfType($fig, node, schema_1.schema.nodes.alt_text);
1009
- this.appendChildNodeOfType($fig, node, schema_1.schema.nodes.long_desc);
1010
- this.appendChildNodeOfType($fig, node, node.type.schema.nodes.footnotes_element);
1011
- processChildNodes($fig, node, contentNodeType);
1012
- appendAttributions($fig, node);
1013
- if ((0, transformer_1.isExecutableNodeType)(node.type)) {
1014
- processExecutableNode(node, $fig);
1015
- }
1016
- moveAltTextAndLongDescToGraphics($fig);
1017
- return $fig;
1018
- };
1019
- const moveAltTextAndLongDescToGraphics = ($element) => {
1020
- const $altText = $element.querySelector('alt-text');
1021
- const $longDesc = $element.querySelector('long-desc');
1022
- const $graphics = $element.querySelectorAll('graphic');
1023
- if ($graphics.length === 0) {
1024
- return;
1025
- }
1026
- $graphics.forEach(($graphic) => {
1027
- if ($longDesc) {
1028
- $graphic.prepend($longDesc.cloneNode(true));
1029
- }
1030
- if ($altText) {
1031
- $graphic.prepend($altText.cloneNode(true));
1032
- }
1033
- });
1034
- $altText?.remove();
1035
- $longDesc?.remove();
1036
- };
1037
- const createTableElement = (node) => {
1038
- const nodeName = 'table-wrap';
1039
- const $tableWrap = createElement(node, nodeName);
1040
- appendLabels($tableWrap, node);
1041
- this.appendCaption($tableWrap, node);
1042
- this.appendChildNodeOfType($tableWrap, node, schema_1.schema.nodes.alt_text);
1043
- this.appendChildNodeOfType($tableWrap, node, schema_1.schema.nodes.long_desc);
1044
- appendTable($tableWrap, node);
1045
- this.appendChildNodeOfType($tableWrap, node, node.type.schema.nodes.table_element_footer);
1046
- if ((0, transformer_1.isExecutableNodeType)(node.type)) {
1047
- processExecutableNode(node, $tableWrap);
1048
- }
1049
- return $tableWrap;
1050
- };
1051
- const processExecutableNode = (node, $element) => {
1052
- const listingNode = this.getFirstChildOfType(schema_1.schema.nodes.listing, node);
1053
- if (listingNode) {
1054
- const { contents, languageKey } = listingNode.attrs;
1055
- if (contents && languageKey) {
1056
- const $fig = this.createElement('fig');
1057
- $fig.setAttribute('specific-use', 'source');
1058
- $element.appendChild($fig);
1059
- const $code = this.createElement('code');
1060
- $code.setAttribute('executable', 'true');
1061
- $code.setAttribute('language', languageKey);
1062
- $code.textContent = contents;
1063
- $fig.appendChild($code);
1064
- }
1065
- }
1066
- };
1067
799
  };
1068
- this.serializeNode = (node) => this.serializer.serializeNode(node, {
1069
- document: this.document,
1070
- });
1071
800
  this.buildContributorGroup = (contributors) => {
1072
801
  if (!contributors.length) {
1073
802
  return;
@@ -1126,7 +855,7 @@ class JATSExporter {
1126
855
  this.buildContributorElement = (contributor) => {
1127
856
  const $contrib = this.createElement('contrib');
1128
857
  $contrib.setAttribute('contrib-type', 'author');
1129
- $contrib.setAttribute('id', normalizeID(contributor.attrs.id));
858
+ $contrib.setAttribute('id', (0, lib_1.normalizeID)(contributor.attrs.id));
1130
859
  if (contributor.attrs.isCorresponding) {
1131
860
  $contrib.setAttribute('corresp', 'yes');
1132
861
  }
@@ -1156,21 +885,21 @@ class JATSExporter {
1156
885
  contributor.attrs.affiliationIDs?.forEach((rid) => {
1157
886
  const $xref = this.appendElement($contrib, 'xref', '', {
1158
887
  'ref-type': 'aff',
1159
- rid: normalizeID(rid),
888
+ rid: (0, lib_1.normalizeID)(rid),
1160
889
  });
1161
890
  $xref.appendChild(this.createLabelSup(rid));
1162
891
  });
1163
892
  contributor.attrs.footnoteIDs?.forEach((rid) => {
1164
893
  const $xref = this.appendElement($contrib, 'xref', '', {
1165
894
  'ref-type': 'fn',
1166
- rid: normalizeID(rid),
895
+ rid: (0, lib_1.normalizeID)(rid),
1167
896
  });
1168
897
  $xref.appendChild(this.createLabelSup(rid));
1169
898
  });
1170
899
  contributor.attrs.correspIDs?.forEach((rid) => {
1171
900
  const $xref = this.appendElement($contrib, 'xref', '', {
1172
901
  'ref-type': 'corresp',
1173
- rid: normalizeID(rid),
902
+ rid: (0, lib_1.normalizeID)(rid),
1174
903
  });
1175
904
  $xref.appendChild(this.createLabelSup(rid));
1176
905
  });
@@ -1186,6 +915,10 @@ class JATSExporter {
1186
915
  'vocab-term-identifier': url,
1187
916
  });
1188
917
  });
918
+ const bio = this.getFirstChildOfType(schema_1.schema.nodes.bio, contributor);
919
+ if (bio?.childCount) {
920
+ $contrib.appendChild(this.serializeNode(bio));
921
+ }
1189
922
  return $contrib;
1190
923
  };
1191
924
  this.buildAffiliationElement = (affiliation) => {
@@ -1220,7 +953,7 @@ class JATSExporter {
1220
953
  $content.push(this.createElement('postal-code', affiliation.attrs.postCode));
1221
954
  }
1222
955
  const $aff = this.createElement('aff');
1223
- $aff.setAttribute('id', normalizeID(affiliation.attrs.id));
956
+ $aff.setAttribute('id', (0, lib_1.normalizeID)(affiliation.attrs.id));
1224
957
  const label = this.contributorLabels.get(affiliation.attrs.id);
1225
958
  if (label) {
1226
959
  this.appendElement($aff, 'label', String(label));
@@ -1252,7 +985,7 @@ class JATSExporter {
1252
985
  };
1253
986
  this.writeCorresp = (corresp) => {
1254
987
  const $corresp = this.createElement('corresp');
1255
- $corresp.setAttribute('id', normalizeID(corresp.attrs.id));
988
+ $corresp.setAttribute('id', (0, lib_1.normalizeID)(corresp.attrs.id));
1256
989
  if (corresp.attrs.label) {
1257
990
  this.appendElement($corresp, 'label', corresp.attrs.label);
1258
991
  }
@@ -1262,7 +995,7 @@ class JATSExporter {
1262
995
  this.writeParagraph = (paragraph) => {
1263
996
  const dom = new DOMParser().parseFromString(paragraph.textContent, 'text/html');
1264
997
  const $p = this.createElement('p');
1265
- $p.setAttribute('id', normalizeID(paragraph.attrs.id));
998
+ $p.setAttribute('id', (0, lib_1.normalizeID)(paragraph.attrs.id));
1266
999
  if (dom.body.innerHTML.length) {
1267
1000
  $p.innerHTML = dom.body.innerHTML;
1268
1001
  }
@@ -1270,7 +1003,7 @@ class JATSExporter {
1270
1003
  };
1271
1004
  this.writeFootnote = (footnote) => {
1272
1005
  const $fn = this.createElement('fn');
1273
- $fn.setAttribute('id', normalizeID(footnote.attrs.id));
1006
+ $fn.setAttribute('id', (0, lib_1.normalizeID)(footnote.attrs.id));
1274
1007
  let content = footnote.textContent;
1275
1008
  if (!content.includes('<p>')) {
1276
1009
  content = `<p>${content}</p>`;
@@ -1300,17 +1033,6 @@ class JATSExporter {
1300
1033
  });
1301
1034
  };
1302
1035
  this.buildKeywords = () => this.getChildrenOfType(schema_1.schema.nodes.keyword_group).map((group) => this.serializeNode(group));
1303
- this.changeTag = ($node, tag) => {
1304
- const $clone = this.createElement(tag);
1305
- for (const attr of $node.attributes) {
1306
- $clone.setAttributeNS(null, attr.name, attr.value);
1307
- }
1308
- while ($node.firstChild) {
1309
- $clone.appendChild($node.firstChild);
1310
- }
1311
- $node.replaceWith($clone);
1312
- return $clone;
1313
- };
1314
1036
  this.normalizeTable = ($table) => {
1315
1037
  let $tbody;
1316
1038
  Array.from($table.childNodes).forEach(($child) => {
@@ -1395,14 +1117,174 @@ class JATSExporter {
1395
1117
  }
1396
1118
  };
1397
1119
  }
1398
- getFirstChildOfType(type, node) {
1399
- return this.getChildrenOfType(type, node)[0];
1120
+ appendLabels($element, node) {
1121
+ if (this.labelTargets) {
1122
+ const target = this.labelTargets.get(node.attrs.id);
1123
+ if (target) {
1124
+ const $label = this.createElement('label');
1125
+ $label.textContent = target.label;
1126
+ $element.appendChild($label);
1127
+ }
1128
+ }
1129
+ }
1130
+ appendAttributions($element, node) {
1131
+ if (node.attrs.attribution) {
1132
+ const $attrib = this.createElement('attrib');
1133
+ $attrib.textContent = node.attrs.attribution.literal;
1134
+ $element.appendChild($attrib);
1135
+ }
1136
+ }
1137
+ appendTable($element, node) {
1138
+ const tableNode = this.getFirstChildOfType(schema_1.schema.nodes.table, node);
1139
+ const colGroupNode = this.getFirstChildOfType(schema_1.schema.nodes.table_colgroup, node);
1140
+ if (!tableNode) {
1141
+ return;
1142
+ }
1143
+ const $table = this.serializeNode(tableNode);
1144
+ const $tbody = this.createElement('tbody');
1145
+ while ($table.firstChild) {
1146
+ const $child = $table.firstChild;
1147
+ $table.removeChild($child);
1148
+ $tbody.appendChild($child);
1149
+ }
1150
+ $table.appendChild($tbody);
1151
+ this.normalizeTable($table);
1152
+ if (colGroupNode) {
1153
+ const $colGroup = this.serializeNode(colGroupNode);
1154
+ $table.insertBefore($colGroup, $table.firstChild);
1155
+ }
1156
+ $element.appendChild($table);
1157
+ }
1158
+ createBoxElement(node) {
1159
+ const $boxedText = this.createElementWithID(node, 'boxed-text');
1160
+ if (node.attrs.type) {
1161
+ $boxedText.setAttribute('content-type', node.attrs.type);
1162
+ }
1163
+ this.appendLabels($boxedText, node);
1164
+ const child = node.firstChild;
1165
+ if (child?.type === schema_1.schema.nodes.caption_title) {
1166
+ this.appendCaption($boxedText, node);
1167
+ }
1168
+ this.processChildNodes($boxedText, node, node.type.schema.nodes.section);
1169
+ return $boxedText;
1170
+ }
1171
+ abstractTypeAttrs(category) {
1172
+ return category && category !== 'abstract'
1173
+ ? { 'abstract-type': category }
1174
+ : {};
1175
+ }
1176
+ createAbstract(node) {
1177
+ return ['abstract', this.abstractTypeAttrs(node.attrs.category), 0];
1178
+ }
1179
+ createTransAbstract(node) {
1180
+ return [
1181
+ 'trans-abstract',
1182
+ {
1183
+ [`${xml_1.XML_NAMESPACE} lang`]: node.attrs.lang ?? '',
1184
+ ...this.abstractTypeAttrs(node.attrs.category),
1185
+ },
1186
+ 0,
1187
+ ];
1188
+ }
1189
+ createGraphic(node) {
1190
+ const $graphic = this.createElement('graphic');
1191
+ $graphic.setAttributeNS(xml_1.XLINK_NAMESPACE, 'xlink:href', node.attrs.src);
1192
+ const findParentHeroImage = (targetID) => {
1193
+ const heroes = this.getChildrenOfType(schema_1.schema.nodes.hero_image);
1194
+ return heroes.find((hero) => !!(0, prosemirror_utils_1.findChildrenByAttr)(hero, (attrs) => attrs.id === targetID)[0]);
1195
+ };
1196
+ const hero = findParentHeroImage(node.attrs.id);
1197
+ if (hero) {
1198
+ $graphic.setAttribute('content-type', hero.attrs.type || 'leading');
1199
+ }
1200
+ else if (!this.isChildOfNodeType(node.attrs.id, schema_1.schema.nodes.figure_element) &&
1201
+ node.attrs.type) {
1202
+ $graphic.setAttribute('content-type', node.attrs.type);
1203
+ }
1204
+ return $graphic;
1205
+ }
1206
+ createImage(node) {
1207
+ const graphicNode = node.content.firstChild;
1208
+ if (!graphicNode) {
1209
+ return '';
1210
+ }
1211
+ const $graphic = this.createGraphic(graphicNode);
1212
+ if (node.attrs.extLink) {
1213
+ const $extLink = this.appendElement($graphic, 'ext-link');
1214
+ $extLink.setAttributeNS(xml_1.XLINK_NAMESPACE, 'href', node.attrs.extLink);
1215
+ }
1216
+ this.appendCaption($graphic, node);
1217
+ this.appendChildNodeOfType($graphic, node, schema_1.schema.nodes.alt_text);
1218
+ this.appendChildNodeOfType($graphic, node, schema_1.schema.nodes.long_desc);
1219
+ return $graphic;
1400
1220
  }
1401
- getChildrenOfType(type, node) {
1402
- const nodes = node
1403
- ? (0, prosemirror_utils_1.findChildrenByType)(node, type).map(({ node }) => node)
1404
- : this.nodesMap.get(type);
1405
- return (nodes ?? []).filter((n) => (0, schema_1.isNodeOfType)(n, type));
1221
+ createFigureElement(node, contentNodeType) {
1222
+ const $fig = this.createElementWithID(node, 'fig');
1223
+ const figNode = this.getFirstChildOfType(schema_1.schema.nodes.figure, node);
1224
+ const figType = figNode?.attrs.type;
1225
+ if (figType) {
1226
+ $fig.setAttribute('fig-type', figType);
1227
+ }
1228
+ this.appendLabels($fig, node);
1229
+ this.appendCaption($fig, node);
1230
+ this.appendChildNodeOfType($fig, node, schema_1.schema.nodes.alt_text);
1231
+ this.appendChildNodeOfType($fig, node, schema_1.schema.nodes.long_desc);
1232
+ this.appendChildNodeOfType($fig, node, node.type.schema.nodes.footnotes_element);
1233
+ this.processChildNodes($fig, node, contentNodeType);
1234
+ this.appendAttributions($fig, node);
1235
+ if ((0, transformer_1.isExecutableNodeType)(node.type)) {
1236
+ this.processExecutableNode(node, $fig);
1237
+ }
1238
+ this.moveAltTextAndLongDescToGraphics($fig);
1239
+ return $fig;
1240
+ }
1241
+ moveAltTextAndLongDescToGraphics($element) {
1242
+ const $altText = $element.querySelector('alt-text');
1243
+ const $longDesc = $element.querySelector('long-desc');
1244
+ const $graphics = $element.querySelectorAll('graphic');
1245
+ if ($graphics.length === 0) {
1246
+ return;
1247
+ }
1248
+ $graphics.forEach(($graphic) => {
1249
+ if ($longDesc) {
1250
+ $graphic.prepend($longDesc.cloneNode(true));
1251
+ }
1252
+ if ($altText) {
1253
+ $graphic.prepend($altText.cloneNode(true));
1254
+ }
1255
+ });
1256
+ $altText?.remove();
1257
+ $longDesc?.remove();
1258
+ }
1259
+ createTableElement(node) {
1260
+ const nodeName = 'table-wrap';
1261
+ const $tableWrap = this.createElementWithID(node, nodeName);
1262
+ this.appendLabels($tableWrap, node);
1263
+ this.appendCaption($tableWrap, node);
1264
+ this.appendChildNodeOfType($tableWrap, node, schema_1.schema.nodes.alt_text);
1265
+ this.appendChildNodeOfType($tableWrap, node, schema_1.schema.nodes.long_desc);
1266
+ this.appendTable($tableWrap, node);
1267
+ this.appendChildNodeOfType($tableWrap, node, node.type.schema.nodes.table_element_footer);
1268
+ if ((0, transformer_1.isExecutableNodeType)(node.type)) {
1269
+ this.processExecutableNode(node, $tableWrap);
1270
+ }
1271
+ return $tableWrap;
1272
+ }
1273
+ processExecutableNode(node, $element) {
1274
+ const listingNode = this.getFirstChildOfType(schema_1.schema.nodes.listing, node);
1275
+ if (listingNode) {
1276
+ const { contents, languageKey } = listingNode.attrs;
1277
+ if (contents && languageKey) {
1278
+ const $fig = this.createElement('fig');
1279
+ $fig.setAttribute('specific-use', 'source');
1280
+ $element.appendChild($fig);
1281
+ const $code = this.createElement('code');
1282
+ $code.setAttribute('executable', 'true');
1283
+ $code.setAttribute('language', languageKey);
1284
+ $code.textContent = contents;
1285
+ $fig.appendChild($code);
1286
+ }
1287
+ }
1406
1288
  }
1407
1289
  createEquation(node, isInline = false) {
1408
1290
  if (node.attrs.format === 'tex') {
@@ -1421,15 +1303,11 @@ class JATSExporter {
1421
1303
  const math = this.nodeFromJATS(node.attrs.contents);
1422
1304
  const $mathml = math;
1423
1305
  if (!isInline) {
1424
- $mathml.setAttribute('id', normalizeID(node.attrs.id));
1306
+ $mathml.setAttribute('id', (0, lib_1.normalizeID)(node.attrs.id));
1425
1307
  }
1426
1308
  return $mathml;
1427
1309
  }
1428
1310
  }
1429
- fillEmptyElements($article, selector, tagName = 'p') {
1430
- const $empty = Array.from($article.querySelectorAll(selector)).filter(($el) => !$el.innerHTML);
1431
- $empty.forEach(($element) => $element.appendChild(this.createElement(tagName)));
1432
- }
1433
1311
  addParagraphsToSections($article) {
1434
1312
  const $sections = $article.querySelectorAll('sec, abstract');
1435
1313
  const TITLE_TAGS = new Set(['title', 'label', 'sec-meta']);