@manuscripts/transform 2.1.3 → 2.1.5-LEAN-3376-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 (68) hide show
  1. package/dist/cjs/index.js +0 -1
  2. package/dist/cjs/jats/importer/jats-body-dom-parser.js +29 -88
  3. package/dist/cjs/jats/importer/jats-body-transformations.js +10 -17
  4. package/dist/cjs/jats/importer/jats-front-parser.js +39 -1
  5. package/dist/cjs/jats/importer/jats-parser-utils.js +6 -0
  6. package/dist/cjs/jats/importer/parse-jats-article.js +3 -6
  7. package/dist/cjs/jats/jats-exporter.js +116 -86
  8. package/dist/cjs/schema/index.js +5 -6
  9. package/dist/cjs/{mathjax/mathjax-packages.js → schema/nodes/author_notes.js} +10 -3
  10. package/dist/cjs/schema/nodes/contributors.js +1 -1
  11. package/dist/cjs/schema/nodes/equation.js +12 -14
  12. package/dist/cjs/schema/nodes/equation_element.js +4 -5
  13. package/dist/cjs/schema/nodes/inline_equation.js +13 -15
  14. package/dist/cjs/schema/nodes/table.js +52 -30
  15. package/dist/cjs/schema/nodes/table_element.js +1 -1
  16. package/dist/cjs/transformer/builders.js +11 -14
  17. package/dist/cjs/transformer/decode.js +43 -25
  18. package/dist/cjs/transformer/encode.js +10 -26
  19. package/dist/cjs/transformer/node-types.js +2 -1
  20. package/dist/cjs/transformer/object-types.js +0 -1
  21. package/dist/es/index.js +0 -1
  22. package/dist/es/jats/importer/jats-body-dom-parser.js +30 -89
  23. package/dist/es/jats/importer/jats-body-transformations.js +10 -17
  24. package/dist/es/jats/importer/jats-front-parser.js +40 -2
  25. package/dist/es/jats/importer/jats-parser-utils.js +6 -0
  26. package/dist/es/jats/importer/parse-jats-article.js +3 -6
  27. package/dist/es/jats/jats-exporter.js +119 -89
  28. package/dist/es/schema/index.js +4 -5
  29. package/dist/{types/mathjax/mathjax-packages.d.ts → es/schema/nodes/author_notes.js} +9 -1
  30. package/dist/es/schema/nodes/contributors.js +1 -1
  31. package/dist/es/schema/nodes/equation.js +12 -14
  32. package/dist/es/schema/nodes/equation_element.js +4 -5
  33. package/dist/es/schema/nodes/inline_equation.js +13 -15
  34. package/dist/es/schema/nodes/table.js +51 -29
  35. package/dist/es/schema/nodes/table_element.js +1 -1
  36. package/dist/es/transformer/builders.js +9 -12
  37. package/dist/es/transformer/decode.js +43 -25
  38. package/dist/es/transformer/encode.js +10 -26
  39. package/dist/es/transformer/node-types.js +2 -1
  40. package/dist/es/transformer/object-types.js +0 -1
  41. package/dist/types/index.d.ts +0 -1
  42. package/dist/types/jats/importer/jats-front-parser.d.ts +10 -1
  43. package/dist/types/jats/jats-exporter.d.ts +5 -0
  44. package/dist/types/schema/index.d.ts +0 -2
  45. package/dist/{es/mathjax/mathjax-packages.js → types/schema/nodes/author_notes.d.ts} +10 -2
  46. package/dist/types/schema/nodes/equation.d.ts +3 -4
  47. package/dist/types/schema/nodes/equation_element.d.ts +1 -2
  48. package/dist/types/schema/nodes/inline_equation.d.ts +4 -3
  49. package/dist/types/schema/nodes/table.d.ts +5 -12
  50. package/dist/types/schema/types.d.ts +1 -1
  51. package/dist/types/transformer/builders.d.ts +3 -3
  52. package/dist/types/transformer/decode.d.ts +1 -0
  53. package/package.json +5 -5
  54. package/dist/cjs/mathjax/index.js +0 -41
  55. package/dist/cjs/mathjax/mathml-to-svg.js +0 -70
  56. package/dist/cjs/mathjax/tex-to-mathml.js +0 -49
  57. package/dist/cjs/mathjax/tex-to-svg.js +0 -59
  58. package/dist/cjs/schema/nodes/table_row.js +0 -123
  59. package/dist/es/mathjax/index.js +0 -12
  60. package/dist/es/mathjax/mathml-to-svg.js +0 -66
  61. package/dist/es/mathjax/tex-to-mathml.js +0 -45
  62. package/dist/es/mathjax/tex-to-svg.js +0 -55
  63. package/dist/es/schema/nodes/table_row.js +0 -120
  64. package/dist/types/mathjax/index.d.ts +0 -3
  65. package/dist/types/mathjax/mathml-to-svg.d.ts +0 -17
  66. package/dist/types/mathjax/tex-to-mathml.d.ts +0 -17
  67. package/dist/types/mathjax/tex-to-svg.d.ts +0 -17
  68. package/dist/types/schema/nodes/table_row.d.ts +0 -41
@@ -15,10 +15,8 @@
15
15
  */
16
16
  import mime from 'mime';
17
17
  import { DOMParser, Fragment } from 'prosemirror-model';
18
- import { convertMathMLToSVG } from '../../mathjax/mathml-to-svg';
19
- import { convertTeXToSVG } from '../../mathjax/tex-to-svg';
20
18
  import { schema } from '../../schema';
21
- import { chooseSectionCategory, xmlSerializer } from '../../transformer';
19
+ import { chooseSectionCategory } from '../../transformer';
22
20
  const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';
23
21
  const chooseContentType = (graphicNode) => {
24
22
  if (graphicNode) {
@@ -33,6 +31,28 @@ const chooseContentType = (graphicNode) => {
33
31
  }
34
32
  }
35
33
  };
34
+ const getEquationContent = (p) => {
35
+ var _a;
36
+ const element = p;
37
+ const id = element.getAttribute('id');
38
+ const container = (_a = element.querySelector('alternatives')) !== null && _a !== void 0 ? _a : element;
39
+ let contents = '';
40
+ let format = '';
41
+ for (const child of container.childNodes) {
42
+ const nodeName = child.nodeName.replace(/^[a-z]:/, '');
43
+ switch (nodeName) {
44
+ case 'tex-math':
45
+ contents = child.innerHTML;
46
+ format = 'tex';
47
+ break;
48
+ case 'mml:math':
49
+ contents = child.outerHTML;
50
+ format = 'mathml';
51
+ break;
52
+ }
53
+ }
54
+ return { id, format, contents };
55
+ };
36
56
  const marks = [
37
57
  {
38
58
  tag: 'bold',
@@ -141,91 +161,26 @@ const nodes = [
141
161
  tag: 'inline-formula',
142
162
  node: 'inline_equation',
143
163
  getAttrs: (node) => {
144
- var _a, _b, _c, _d, _e;
145
164
  const element = node;
146
- const attrs = {
147
- id: element.getAttribute('id'),
148
- MathMLRepresentation: '',
149
- SVGRepresentation: '',
150
- TeXRepresentation: '',
151
- };
152
- const container = (_a = element.querySelector('alternatives')) !== null && _a !== void 0 ? _a : element;
153
- for (const child of container.childNodes) {
154
- const nodeName = child.nodeName.replace(/^[a-z]:/, '');
155
- switch (nodeName) {
156
- case 'tex-math':
157
- attrs.TeXRepresentation = (_c = (_b = child.textContent) === null || _b === void 0 ? void 0 : _b.trim()) !== null && _c !== void 0 ? _c : '';
158
- if (attrs.TeXRepresentation) {
159
- attrs.SVGRepresentation =
160
- (_d = convertTeXToSVG(attrs.TeXRepresentation, true)) !== null && _d !== void 0 ? _d : '';
161
- }
162
- break;
163
- case 'mml:math':
164
- ;
165
- child.removeAttribute('id');
166
- attrs.MathMLRepresentation = xmlSerializer.serializeToString(child);
167
- if (attrs.MathMLRepresentation) {
168
- attrs.SVGRepresentation =
169
- (_e = convertMathMLToSVG(attrs.MathMLRepresentation, true)) !== null && _e !== void 0 ? _e : '';
170
- }
171
- break;
172
- }
173
- }
174
- return attrs;
165
+ return getEquationContent(element);
175
166
  },
176
167
  },
177
168
  {
178
169
  tag: 'disp-formula',
179
170
  node: 'equation_element',
180
171
  getAttrs: (node) => {
172
+ var _a, _b;
181
173
  const element = node;
182
- const caption = element.querySelector('figcaption');
183
174
  return {
184
175
  id: element.getAttribute('id'),
185
- suppressCaption: !caption,
176
+ label: (_b = (_a = element.querySelector('label')) === null || _a === void 0 ? void 0 : _a.textContent) !== null && _b !== void 0 ? _b : '',
186
177
  };
187
178
  },
188
179
  getContent: (node, schema) => {
189
- var _a, _b, _c, _d, _e;
190
180
  const element = node;
191
- const attrs = {
192
- MathMLStringRepresentation: '',
193
- SVGStringRepresentation: '',
194
- TeXRepresentation: '',
195
- };
196
- const container = (_a = element.querySelector('alternatives')) !== null && _a !== void 0 ? _a : element;
197
- for (const child of container.childNodes) {
198
- const nodeName = child.nodeName.replace(/^[a-z]:/, '');
199
- switch (nodeName) {
200
- case 'tex-math':
201
- attrs.TeXRepresentation = (_c = (_b = child.textContent) === null || _b === void 0 ? void 0 : _b.trim()) !== null && _c !== void 0 ? _c : '';
202
- if (attrs.TeXRepresentation) {
203
- attrs.SVGStringRepresentation =
204
- (_d = convertTeXToSVG(attrs.TeXRepresentation, true)) !== null && _d !== void 0 ? _d : '';
205
- }
206
- break;
207
- case 'mml:math':
208
- ;
209
- child.removeAttribute('id');
210
- attrs.MathMLStringRepresentation =
211
- xmlSerializer.serializeToString(child);
212
- if (attrs.MathMLStringRepresentation) {
213
- attrs.SVGStringRepresentation =
214
- (_e = convertMathMLToSVG(attrs.MathMLStringRepresentation, true)) !== null && _e !== void 0 ? _e : '';
215
- }
216
- break;
217
- }
218
- }
219
- const caption = element.querySelector('figcaption');
220
- const figcaption = schema.nodes.figcaption.create();
181
+ const attrs = getEquationContent(element);
221
182
  return Fragment.from([
222
- schema.nodes.equation.createChecked(attrs),
223
- caption
224
- ?
225
- jatsBodyDOMParser.parse(caption, {
226
- topNode: figcaption,
227
- })
228
- : figcaption,
183
+ schema.nodes.equation.createChecked(Object.assign({}, attrs)),
229
184
  ]);
230
185
  },
231
186
  },
@@ -519,23 +474,9 @@ const nodes = [
519
474
  const element = node;
520
475
  return {
521
476
  id: element.getAttribute('id'),
522
- suppressFooter: !element.querySelector('table > tfoot > tr'),
523
- suppressHeader: !element.querySelector('table > thead > tr'),
524
477
  };
525
478
  },
526
479
  },
527
- {
528
- tag: 'tbody',
529
- skip: true,
530
- },
531
- {
532
- tag: 'tfoot',
533
- skip: true,
534
- },
535
- {
536
- tag: 'thead',
537
- skip: true,
538
- },
539
480
  {
540
481
  tag: 'title',
541
482
  node: 'section_title',
@@ -562,12 +503,12 @@ const nodes = [
562
503
  },
563
504
  {
564
505
  tag: 'th',
565
- node: 'table_cell',
506
+ node: 'table_header',
566
507
  getAttrs: (node) => {
567
508
  const element = node;
568
509
  const colspan = element.getAttribute('colspan');
569
510
  const rowspan = element.getAttribute('rowspan');
570
- return Object.assign(Object.assign(Object.assign({ celltype: 'th' }, (colspan && { colspan })), (rowspan && { rowspan })), { valign: element.getAttribute('valign'), align: element.getAttribute('align'), scope: element.getAttribute('scope'), style: element.getAttribute('style') });
511
+ return Object.assign(Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })), { valign: element.getAttribute('valign'), align: element.getAttribute('align'), scope: element.getAttribute('scope'), style: element.getAttribute('style') });
571
512
  },
572
513
  },
573
514
  {
@@ -199,7 +199,9 @@ export const jatsBodyTransformations = {
199
199
  }
200
200
  },
201
201
  moveFootnotes(doc, group, createElement) {
202
- const footnotes = [...doc.querySelectorAll('fn:not(table-wrap-foot fn)')];
202
+ const footnotes = [
203
+ ...doc.querySelectorAll('fn:not(table-wrap-foot fn, author-notes fn)'),
204
+ ];
203
205
  const footnotesSection = doc.querySelector('sec[sec-type="endnotes"]');
204
206
  const footnotesSectionGroup = footnotesSection === null || footnotesSection === void 0 ? void 0 : footnotesSection.querySelector('fn-group');
205
207
  const containingGroup = footnotesSectionGroup || createElement('fn-group');
@@ -236,8 +238,12 @@ export const jatsBodyTransformations = {
236
238
  }
237
239
  },
238
240
  fixTables(body, createElement) {
239
- const tables = body.querySelectorAll('table-wrap > table');
240
- tables.forEach((table) => {
241
+ const tableWraps = body.querySelectorAll('table-wrap');
242
+ tableWraps.forEach((tableWrap) => {
243
+ const table = tableWrap.querySelector('table');
244
+ if (!table) {
245
+ return;
246
+ }
241
247
  const colgroup = table.querySelector('colgroup');
242
248
  const cols = table.querySelectorAll('col');
243
249
  if (!colgroup && table.firstChild && cols.length > 0) {
@@ -245,20 +251,7 @@ export const jatsBodyTransformations = {
245
251
  for (const col of cols) {
246
252
  colgroup.appendChild(col);
247
253
  }
248
- table.insertBefore(colgroup, table.firstChild);
249
- }
250
- const tbody = table.querySelector('tbody');
251
- if (tbody) {
252
- const headerRow = table.querySelector('thead > tr');
253
- if (!headerRow) {
254
- const tr = createElement('tr');
255
- tbody.insertBefore(tr, tbody.firstElementChild);
256
- }
257
- const footerRow = table.querySelector('tfoot > tr');
258
- if (!footerRow) {
259
- const tr = createElement('tr');
260
- tbody.appendChild(tr);
261
- }
254
+ tableWrap.insertBefore(colgroup, table.nextSibling);
262
255
  }
263
256
  });
264
257
  },
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import debug from 'debug';
17
17
  import { getTrimmedTextContent } from '../../lib/utils';
18
- import { buildAffiliation, buildBibliographicName, buildContributor, buildCorresp, buildFootnote, buildJournal, buildTitles, } from '../../transformer';
18
+ import { buildAffiliation, buildAuthorNotes, buildBibliographicName, buildContributor, buildCorresp, buildFootnote, buildJournal, buildParagraph, buildTitles, } from '../../transformer';
19
19
  import { parseJournalMeta } from './jats-journal-meta-parser';
20
20
  import { htmlFromJatsNode } from './jats-parser-utils';
21
21
  const warn = debug('manuscripts-transform');
@@ -173,7 +173,45 @@ export const jatsFrontParser = {
173
173
  affiliationIDs,
174
174
  };
175
175
  },
176
- parseAuthorNotes(elements) {
176
+ parseAuthorNotes(element) {
177
+ if (!element) {
178
+ return {
179
+ footnotes: [],
180
+ footnoteIDs: new Map(),
181
+ authorNotes: [],
182
+ authorNotesParagraphs: [],
183
+ correspondingIDs: new Map(),
184
+ correspondingList: [],
185
+ };
186
+ }
187
+ const { footnotes, footnoteIDs } = this.parseFootnotes([
188
+ ...element.querySelectorAll('fn:not([fn-type])'),
189
+ ]);
190
+ const authorNotesParagraphs = this.parseParagraphs([
191
+ ...element.querySelectorAll(':scope > p'),
192
+ ]);
193
+ const { correspondingList, correspondingIDs } = this.parseCorresp([
194
+ ...element.querySelectorAll('corresp'),
195
+ ]);
196
+ const authorNotes = [
197
+ buildAuthorNotes([
198
+ ...footnoteIDs.values(),
199
+ ...authorNotesParagraphs.map((p) => p._id),
200
+ ]),
201
+ ];
202
+ return {
203
+ footnotes,
204
+ footnoteIDs,
205
+ authorNotesParagraphs,
206
+ authorNotes,
207
+ correspondingIDs,
208
+ correspondingList,
209
+ };
210
+ },
211
+ parseParagraphs(elements) {
212
+ return elements.map((p) => buildParagraph(p.innerHTML));
213
+ },
214
+ parseFootnotes(elements) {
177
215
  const footnoteIDs = new Map();
178
216
  const footnotes = elements.map((element) => {
179
217
  const fn = buildFootnote('', element.innerHTML);
@@ -13,6 +13,8 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { v4 as uuidv4 } from 'uuid';
17
+ import { schema } from '../../schema';
16
18
  import { generateID, nodeTypesMap } from '../../transformer';
17
19
  export const updateDocumentIDs = (node, replacements) => {
18
20
  const warnings = [];
@@ -26,6 +28,10 @@ function recurseDoc(node, fn) {
26
28
  node.descendants((n) => fn(n));
27
29
  }
28
30
  const updateNodeID = (node, replacements, warnings) => {
31
+ if (node.type === schema.nodes.inline_equation) {
32
+ node.attrs = Object.assign(Object.assign({}, node.attrs), { id: `InlineMathFragment:${uuidv4()}` });
33
+ return;
34
+ }
29
35
  if (!('id' in node.attrs)) {
30
36
  return;
31
37
  }
@@ -32,12 +32,7 @@ export const parseJATSFront = (doc, front) => {
32
32
  const { affiliations, affiliationIDs } = jatsFrontParser.parseAffiliations([
33
33
  ...front.querySelectorAll('article-meta > contrib-group > aff'),
34
34
  ]);
35
- const { footnotes, footnoteIDs } = jatsFrontParser.parseAuthorNotes([
36
- ...front.querySelectorAll('article-meta > author-notes > fn:not([fn-type])'),
37
- ]);
38
- const { correspondingList, correspondingIDs } = jatsFrontParser.parseCorresp([
39
- ...front.querySelectorAll('article-meta > author-notes > corresp'),
40
- ]);
35
+ const { footnotes, footnoteIDs, authorNotes, authorNotesParagraphs, correspondingIDs, correspondingList, } = jatsFrontParser.parseAuthorNotes(front.querySelector('article-meta > author-notes'));
41
36
  const authors = jatsFrontParser.parseContributors([
42
37
  ...front.querySelectorAll('article-meta > contrib-group > contrib[contrib-type="author"]'),
43
38
  ], affiliationIDs, footnoteIDs, correspondingIDs);
@@ -48,6 +43,8 @@ export const parseJATSFront = (doc, front) => {
48
43
  manuscript,
49
44
  titles,
50
45
  journal,
46
+ ...authorNotesParagraphs,
47
+ ...authorNotes,
51
48
  ...footnotes,
52
49
  ...authors,
53
50
  ...affiliations,
@@ -13,10 +13,10 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { ObjectTypes, } from '@manuscripts/json-schema';
16
+ import { getModelsByType, ObjectTypes, } from '@manuscripts/json-schema';
17
17
  import { CitationProvider } from '@manuscripts/library';
18
18
  import debug from 'debug';
19
- import { DOMParser, DOMSerializer } from 'prosemirror-model';
19
+ import { DOMParser as ProseMirrorDOMParser, DOMSerializer, } from 'prosemirror-model';
20
20
  import serializeToXML from 'w3c-xmlserializer';
21
21
  import { nodeFromHTML, textFromHTML } from '../lib/html';
22
22
  import { normalizeStyleName } from '../lib/styled-content';
@@ -32,7 +32,7 @@ import { selectVersionIds } from './jats-versions';
32
32
  const warn = debug('manuscripts-transform');
33
33
  const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';
34
34
  const normalizeID = (id) => id.replace(/:/g, '_');
35
- const parser = DOMParser.fromSchema(schema);
35
+ const parser = ProseMirrorDOMParser.fromSchema(schema);
36
36
  const findChildNodeOfType = (node, nodeType) => {
37
37
  for (const child of iterateChildren(node)) {
38
38
  if (child.type === nodeType) {
@@ -88,7 +88,7 @@ const createDefaultIdGenerator = () => {
88
88
  const counter = createCounter();
89
89
  return async (element) => {
90
90
  const value = String(counter.increment(element.nodeName));
91
- return `${element.nodeName}-${value}`;
91
+ return `${element.localName}-${value}`;
92
92
  };
93
93
  };
94
94
  const chooseRefType = (objectType) => {
@@ -156,6 +156,7 @@ export class JATSExporter {
156
156
  };
157
157
  this.nodeFromJATS = (JATSFragment) => {
158
158
  JATSFragment = JATSFragment.trim();
159
+ JATSFragment = JATSFragment.replace(' ', ' ');
159
160
  if (!JATSFragment.length) {
160
161
  return null;
161
162
  }
@@ -606,6 +607,7 @@ export class JATSExporter {
606
607
  this.createSerializer = () => {
607
608
  const getModel = (id) => id ? this.modelMap.get(id) : undefined;
608
609
  const nodes = {
610
+ author_notes: () => ['author-notes', 0],
609
611
  title: () => '',
610
612
  affiliations: () => '',
611
613
  contributors: () => '',
@@ -678,22 +680,20 @@ export class JATSExporter {
678
680
  },
679
681
  doc: () => '',
680
682
  equation: (node) => {
681
- const formula = this.document.createElement('disp-formula');
682
- formula.setAttribute('id', normalizeID(node.attrs.id));
683
- if (node.attrs.TeXRepresentation) {
684
- const math = this.document.createElement('tex-math');
685
- math.textContent = node.attrs.TeXRepresentation;
686
- formula.appendChild(math);
687
- }
688
- else if (node.attrs.MathMLStringRepresentation) {
689
- const math = this.nodeFromJATS(node.attrs.MathMLStringRepresentation);
690
- if (math) {
691
- formula.appendChild(math);
692
- }
693
- }
694
- return formula;
683
+ return this.createEquation(node);
684
+ },
685
+ inline_equation: (node) => {
686
+ const eqElement = this.document.createElement('inline-formula');
687
+ const equation = this.createEquation(node, true);
688
+ eqElement.append(equation);
689
+ return eqElement;
690
+ },
691
+ equation_element: (node) => {
692
+ const eqElement = this.document.createElement('disp-formula');
693
+ eqElement.setAttribute('id', normalizeID(node.attrs.id));
694
+ processChildNodes(eqElement, node, schema.nodes.equation);
695
+ return eqElement;
695
696
  },
696
- equation_element: (node) => createFigureElement(node, 'fig', node.type.schema.nodes.equation, 'equation'),
697
697
  figcaption: (node) => {
698
698
  if (!node.textContent) {
699
699
  return '';
@@ -743,28 +743,6 @@ export class JATSExporter {
743
743
  },
744
744
  hard_break: () => '',
745
745
  highlight_marker: () => '',
746
- inline_equation: (node) => {
747
- const formula = this.document.createElement('inline-formula');
748
- formula.setAttribute('id', normalizeID(node.attrs.id));
749
- if (node.attrs.TeXRepresentation) {
750
- const math = this.document.createElement('tex-math');
751
- math.textContent = node.attrs.TeXRepresentation;
752
- formula.appendChild(math);
753
- }
754
- else if (node.attrs.MathMLRepresentation) {
755
- const math = this.nodeFromJATS(node.attrs.MathMLRepresentation);
756
- if (math) {
757
- formula.appendChild(math);
758
- }
759
- }
760
- else if (node.attrs.SVGRepresentation) {
761
- const math = this.nodeFromJATS(node.attrs.SVGRepresentation);
762
- if (math) {
763
- formula.appendChild(math);
764
- }
765
- }
766
- return formula;
767
- },
768
746
  inline_footnote: (node) => {
769
747
  const xref = this.document.createElement('xref');
770
748
  xref.setAttribute('ref-type', 'fn');
@@ -865,9 +843,13 @@ export class JATSExporter {
865
843
  element.setAttribute('position', 'anchor');
866
844
  return element;
867
845
  },
868
- table_body: () => ['tbody', 0],
869
846
  table_cell: (node) => [
870
- node.attrs.celltype,
847
+ 'td',
848
+ Object.assign(Object.assign({ valign: node.attrs.valign, align: node.attrs.align, scope: node.attrs.scope, style: node.attrs.style }, (node.attrs.rowspan > 1 && { rowspan: node.attrs.rowspan })), (node.attrs.colspan > 1 && { colspan: node.attrs.colspan })),
849
+ 0,
850
+ ],
851
+ table_header: (node) => [
852
+ 'th',
871
853
  Object.assign(Object.assign({ valign: node.attrs.valign, align: node.attrs.align, scope: node.attrs.scope, style: node.attrs.style }, (node.attrs.rowspan > 1 && { rowspan: node.attrs.rowspan })), (node.attrs.colspan > 1 && { colspan: node.attrs.colspan })),
872
854
  0,
873
855
  ],
@@ -948,6 +930,26 @@ export class JATSExporter {
948
930
  element.appendChild(this.serializeNode(childNode));
949
931
  }
950
932
  };
933
+ const appendTable = (element, node) => {
934
+ const tableNode = findChildNodeOfType(node, node.type.schema.nodes.table);
935
+ const colGroupNode = findChildNodeOfType(node, node.type.schema.nodes.table_colgroup);
936
+ if (!tableNode) {
937
+ return;
938
+ }
939
+ const table = this.serializeNode(tableNode);
940
+ const tbodyElement = this.document.createElement('tbody');
941
+ while (table.firstChild) {
942
+ const child = table.firstChild;
943
+ table.removeChild(child);
944
+ tbodyElement.appendChild(child);
945
+ }
946
+ table.appendChild(tbodyElement);
947
+ if (colGroupNode) {
948
+ const colGroup = this.serializeNode(colGroupNode);
949
+ table.insertBefore(colGroup, table.firstChild);
950
+ }
951
+ element.appendChild(table);
952
+ };
951
953
  const createFigureElement = (node, nodeName, contentNodeType, figType) => {
952
954
  const element = createElement(node, nodeName);
953
955
  if (figType) {
@@ -968,7 +970,7 @@ export class JATSExporter {
968
970
  const element = createElement(node, nodeName);
969
971
  appendLabels(element, node);
970
972
  appendChildNodeOfType(element, node, node.type.schema.nodes.figcaption);
971
- appendChildNodeOfType(element, node, node.type.schema.nodes.table);
973
+ appendTable(element, node);
972
974
  appendChildNodeOfType(element, node, node.type.schema.nodes.table_element_footer);
973
975
  if (isExecutableNodeType(node.type)) {
974
976
  processExecutableNode(node, element);
@@ -1026,6 +1028,7 @@ export class JATSExporter {
1026
1028
  }
1027
1029
  };
1028
1030
  this.buildContributors = (articleMeta) => {
1031
+ var _a;
1029
1032
  const contributors = this.models.filter(isContributor);
1030
1033
  const authorContributors = contributors
1031
1034
  .filter((contributor) => contributor.role === 'author')
@@ -1244,56 +1247,59 @@ export class JATSExporter {
1244
1247
  }
1245
1248
  });
1246
1249
  }
1247
- const noteIDs = [];
1248
- for (const contributor of [...authorContributors, ...otherContributors]) {
1249
- if (contributor.footnote) {
1250
- const ids = contributor.footnote.map((note) => {
1251
- return note.noteID;
1252
- });
1253
- noteIDs.push(...ids);
1254
- }
1255
- if (contributor.corresp) {
1256
- const ids = contributor.corresp.map((corresp) => {
1257
- return corresp.correspID;
1258
- });
1259
- noteIDs.push(...ids);
1260
- }
1261
- }
1262
- const footnotes = [];
1263
- footnotes.push(...this.models.filter(hasObjectType(ObjectTypes.Footnote)));
1264
- const correspodings = [];
1265
- correspodings.push(...this.models.filter(hasObjectType(ObjectTypes.Corresponding)));
1266
- if (footnotes || correspodings) {
1267
- const authorNotesEl = this.document.createElement('author-notes');
1268
- const usedFootnotes = footnotes.filter((footnote) => {
1269
- return noteIDs.includes(footnote._id);
1270
- });
1271
- const usedCorrespodings = correspodings.filter((corresp) => {
1272
- return noteIDs.includes(corresp._id);
1273
- });
1274
- usedFootnotes.forEach((footnote) => {
1275
- const authorFootNote = this.document.createElement('fn');
1276
- authorFootNote.setAttribute('id', normalizeID(footnote._id));
1277
- authorFootNote.innerHTML = footnote.contents;
1278
- authorNotesEl.appendChild(authorFootNote);
1279
- });
1280
- usedCorrespodings.forEach((corresponding) => {
1281
- const correspondingEl = this.document.createElement('corresp');
1282
- correspondingEl.setAttribute('id', normalizeID(corresponding._id));
1283
- if (corresponding.label) {
1284
- const labelEl = this.document.createElement('label');
1285
- labelEl.textContent = corresponding.label;
1286
- correspondingEl.appendChild(labelEl);
1250
+ const authorNotesEl = this.document.createElement('author-notes');
1251
+ const usedCorrespodings = this.getUsedCorrespondings([
1252
+ ...authorContributors,
1253
+ ...otherContributors,
1254
+ ]);
1255
+ usedCorrespodings.forEach((corresp) => {
1256
+ this.appendCorrespondingToElement(corresp, authorNotesEl);
1257
+ });
1258
+ const authorNotes = (_a = getModelsByType(this.modelMap, ObjectTypes.AuthorNotes)) === null || _a === void 0 ? void 0 : _a[0];
1259
+ if (authorNotes) {
1260
+ authorNotes.containedObjectIDs.forEach((id) => {
1261
+ const model = this.modelMap.get(id);
1262
+ if (!model) {
1263
+ return;
1264
+ }
1265
+ if (id.startsWith('MPParagraphElement')) {
1266
+ this.appendParagraphToElement(model, authorNotesEl);
1267
+ }
1268
+ else if (id.startsWith('MPFootnote')) {
1269
+ this.appendFootnoteToElement(model, authorNotesEl);
1287
1270
  }
1288
- correspondingEl.append(corresponding.contents);
1289
- authorNotesEl.appendChild(correspondingEl);
1290
1271
  });
1291
- if (authorNotesEl.childNodes.length > 0) {
1292
- articleMeta.insertBefore(authorNotesEl, contribGroup.nextSibling);
1293
- }
1294
1272
  }
1273
+ if (authorNotesEl.childNodes.length > 0) {
1274
+ articleMeta.insertBefore(authorNotesEl, contribGroup.nextSibling);
1275
+ }
1276
+ }
1277
+ };
1278
+ this.appendCorrespondingToElement = (corresponding, element) => {
1279
+ const correspondingEl = this.document.createElement('corresp');
1280
+ correspondingEl.setAttribute('id', normalizeID(corresponding._id));
1281
+ if (corresponding.label) {
1282
+ const labelEl = this.document.createElement('label');
1283
+ labelEl.textContent = corresponding.label;
1284
+ correspondingEl.appendChild(labelEl);
1285
+ }
1286
+ correspondingEl.append(corresponding.contents);
1287
+ element.appendChild(correspondingEl);
1288
+ };
1289
+ this.appendParagraphToElement = (paragraph, element) => {
1290
+ const parser = new DOMParser();
1291
+ const xmlDoc = parser.parseFromString(paragraph.contents, 'text/xml');
1292
+ const paragraphEl = xmlDoc.firstChild;
1293
+ if (paragraphEl && paragraphEl.nodeName === 'p') {
1294
+ element.appendChild(paragraphEl);
1295
1295
  }
1296
1296
  };
1297
+ this.appendFootnoteToElement = (footnote, element) => {
1298
+ const footnoteEl = this.document.createElement('fn');
1299
+ footnoteEl.setAttribute('id', normalizeID(footnote._id));
1300
+ footnoteEl.innerHTML = footnote.contents;
1301
+ element.appendChild(footnoteEl);
1302
+ };
1297
1303
  this.fixBody = (body, fragment) => {
1298
1304
  fragment.descendants((node) => {
1299
1305
  if (node.attrs.id) {
@@ -1581,6 +1587,27 @@ export class JATSExporter {
1581
1587
  this.citationTexts.set(id, output);
1582
1588
  });
1583
1589
  }
1590
+ createEquation(node, isInline = false) {
1591
+ if (node.attrs.format === 'tex') {
1592
+ const texMath = this.document.createElement('tex-math');
1593
+ texMath.innerHTML = node.attrs.contents;
1594
+ return texMath;
1595
+ }
1596
+ else {
1597
+ const math = this.nodeFromJATS(node.attrs.contents);
1598
+ const mathml = math;
1599
+ if (!isInline) {
1600
+ mathml.setAttribute('id', normalizeID(node.attrs.id));
1601
+ }
1602
+ return mathml;
1603
+ }
1604
+ }
1605
+ getUsedCorrespondings(contributors) {
1606
+ return contributors
1607
+ .flatMap((c) => { var _a; return (_a = c.corresp) !== null && _a !== void 0 ? _a : []; })
1608
+ .map((corresp) => this.modelMap.get(corresp.correspID))
1609
+ .filter((corresp) => !!corresp);
1610
+ }
1584
1611
  buildKeywords(articleMeta) {
1585
1612
  const keywords = [...this.modelMap.values()].filter((model) => model.objectType === ObjectTypes.Keyword);
1586
1613
  const keywordGroups = new Map();
@@ -1652,6 +1679,9 @@ export class JATSExporter {
1652
1679
  }
1653
1680
  }
1654
1681
  }
1682
+ if (!fnGroup.hasChildNodes()) {
1683
+ fnGroup.remove();
1684
+ }
1655
1685
  }
1656
1686
  }
1657
1687
  });