@manuscripts/transform 2.3.38-LEAN-3911.0 → 2.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 (126) hide show
  1. package/dist/cjs/__tests__/data/project-dump.json +825 -0
  2. package/dist/cjs/index.js +6 -6
  3. package/dist/cjs/jats/importer/index.js +22 -0
  4. package/dist/cjs/jats/importer/{jats-dom-parser.js → jats-body-dom-parser.js} +34 -273
  5. package/dist/cjs/jats/importer/jats-body-transformations.js +22 -74
  6. package/dist/cjs/jats/importer/jats-comments.js +104 -27
  7. package/dist/cjs/jats/importer/jats-front-parser.js +321 -0
  8. package/dist/cjs/jats/importer/jats-journal-meta-parser.js +1 -8
  9. package/dist/cjs/jats/importer/jats-parser-utils.js +5 -43
  10. package/dist/cjs/jats/importer/jats-reference-parser.js +23 -16
  11. package/dist/cjs/jats/importer/jats-references.js +18 -18
  12. package/dist/cjs/jats/importer/parse-jats-article.js +79 -40
  13. package/dist/cjs/jats/index.js +7 -7
  14. package/dist/cjs/jats/{exporter/jats-exporter.js → jats-exporter.js} +398 -264
  15. package/dist/cjs/jats/{exporter/jats-versions.js → jats-versions.js} +3 -1
  16. package/dist/cjs/lib/utils.js +1 -12
  17. package/dist/cjs/transformer/__tests__/__helpers__/doc.js +37 -0
  18. package/dist/cjs/transformer/builders.js +219 -0
  19. package/dist/cjs/transformer/decode.js +898 -0
  20. package/dist/cjs/transformer/document-object-types.js +31 -0
  21. package/dist/cjs/transformer/encode.js +674 -0
  22. package/dist/cjs/{jats/importer/create-article-node.js → transformer/filename.js} +9 -10
  23. package/dist/cjs/transformer/footnote-category.js +20 -0
  24. package/dist/cjs/transformer/footnotes-order.js +60 -0
  25. package/dist/cjs/transformer/highlight-markers.js +138 -0
  26. package/dist/cjs/transformer/html.js +400 -0
  27. package/dist/cjs/transformer/id.js +5 -10
  28. package/dist/cjs/transformer/index.js +18 -0
  29. package/dist/cjs/{jats/exporter → transformer}/labels.js +5 -4
  30. package/dist/cjs/transformer/manuscript-dependencies.js +21 -0
  31. package/dist/cjs/transformer/model-map.js +26 -0
  32. package/dist/cjs/{lib/deafults.js → transformer/models.js} +1 -3
  33. package/dist/cjs/transformer/node-names.js +1 -0
  34. package/dist/cjs/transformer/object-types.js +57 -0
  35. package/dist/cjs/transformer/project-bundle.js +94 -0
  36. package/dist/cjs/transformer/serializer.js +23 -0
  37. package/dist/cjs/transformer/timestamp.js +20 -0
  38. package/dist/cjs/transformer/update-identifiers.js +93 -0
  39. package/dist/cjs/version.js +1 -1
  40. package/dist/es/__tests__/data/project-dump.json +825 -0
  41. package/dist/es/index.js +5 -5
  42. package/dist/{types/jats/importer/create-article-node.d.ts → es/jats/importer/index.js} +2 -3
  43. package/dist/es/jats/importer/{jats-dom-parser.js → jats-body-dom-parser.js} +35 -274
  44. package/dist/es/jats/importer/jats-body-transformations.js +22 -74
  45. package/dist/es/jats/importer/jats-comments.js +101 -26
  46. package/dist/es/jats/importer/jats-front-parser.js +315 -0
  47. package/dist/es/jats/importer/jats-journal-meta-parser.js +0 -6
  48. package/dist/es/jats/importer/jats-parser-utils.js +6 -44
  49. package/dist/es/jats/importer/jats-reference-parser.js +23 -16
  50. package/dist/es/jats/importer/jats-references.js +18 -18
  51. package/dist/es/jats/importer/parse-jats-article.js +78 -41
  52. package/dist/es/jats/index.js +3 -5
  53. package/dist/es/jats/{exporter/jats-exporter.js → jats-exporter.js} +392 -258
  54. package/dist/es/jats/{exporter/jats-versions.js → jats-versions.js} +1 -0
  55. package/dist/es/lib/utils.js +0 -9
  56. package/dist/es/transformer/__tests__/__helpers__/doc.js +29 -0
  57. package/dist/es/transformer/builders.js +186 -0
  58. package/dist/es/transformer/decode.js +888 -0
  59. package/dist/es/transformer/document-object-types.js +28 -0
  60. package/dist/es/transformer/encode.js +664 -0
  61. package/dist/es/transformer/filename.js +23 -0
  62. package/dist/es/transformer/footnote-category.js +16 -0
  63. package/dist/es/transformer/footnotes-order.js +55 -0
  64. package/dist/es/transformer/highlight-markers.js +132 -0
  65. package/dist/es/transformer/html.js +393 -0
  66. package/dist/es/transformer/id.js +3 -8
  67. package/dist/es/transformer/index.js +16 -0
  68. package/dist/es/{jats/exporter → transformer}/labels.js +5 -4
  69. package/dist/es/transformer/manuscript-dependencies.js +17 -0
  70. package/dist/es/transformer/model-map.js +22 -0
  71. package/dist/es/{lib/deafults.js → transformer/models.js} +2 -2
  72. package/dist/es/transformer/node-names.js +1 -0
  73. package/dist/es/transformer/object-types.js +52 -0
  74. package/dist/es/transformer/project-bundle.js +85 -0
  75. package/dist/es/transformer/serializer.js +17 -0
  76. package/dist/es/transformer/timestamp.js +16 -0
  77. package/dist/es/transformer/update-identifiers.js +87 -0
  78. package/dist/es/version.js +1 -1
  79. package/dist/types/index.d.ts +6 -6
  80. package/dist/types/jats/importer/index.d.ts +16 -0
  81. package/dist/types/jats/importer/{jats-dom-parser.d.ts → jats-body-dom-parser.d.ts} +1 -1
  82. package/dist/types/jats/importer/jats-body-transformations.d.ts +1 -5
  83. package/dist/types/jats/importer/jats-comments.d.ts +10 -4
  84. package/dist/types/jats/importer/jats-front-parser.d.ts +84 -0
  85. package/dist/types/jats/importer/jats-journal-meta-parser.d.ts +0 -10
  86. package/dist/types/jats/importer/jats-references.d.ts +8 -19
  87. package/dist/types/jats/importer/parse-jats-article.d.ts +5 -12
  88. package/dist/types/jats/index.d.ts +3 -5
  89. package/dist/types/jats/{exporter/jats-exporter.d.ts → jats-exporter.d.ts} +29 -15
  90. package/dist/types/jats/{exporter/jats-versions.d.ts → jats-versions.d.ts} +1 -0
  91. package/dist/types/lib/utils.d.ts +0 -2
  92. package/dist/types/schema/nodes/bibliography_item.d.ts +3 -3
  93. package/dist/types/schema/nodes/contributor.d.ts +0 -10
  94. package/dist/types/schema/nodes/keyword_group.d.ts +0 -1
  95. package/dist/types/schema/nodes/manuscript.d.ts +7 -8
  96. package/dist/types/schema/nodes/title.d.ts +3 -0
  97. package/dist/types/transformer/__tests__/__helpers__/doc.d.ts +18 -0
  98. package/dist/types/transformer/builders.d.ts +61 -0
  99. package/dist/types/transformer/decode.d.ts +52 -0
  100. package/dist/types/transformer/document-object-types.d.ts +17 -0
  101. package/dist/types/transformer/encode.d.ts +29 -0
  102. package/dist/types/transformer/filename.d.ts +16 -0
  103. package/dist/types/transformer/footnote-category.d.ts +17 -0
  104. package/dist/{es/jats/importer/create-article-node.js → types/transformer/footnotes-order.d.ts} +8 -10
  105. package/dist/types/transformer/highlight-markers.d.ts +31 -0
  106. package/dist/types/transformer/html.d.ts +36 -0
  107. package/dist/types/transformer/id.d.ts +2 -5
  108. package/dist/types/transformer/index.d.ts +16 -0
  109. package/dist/types/{jats/exporter → transformer}/labels.d.ts +2 -2
  110. package/dist/types/transformer/manuscript-dependencies.d.ts +4 -0
  111. package/dist/types/transformer/model-map.d.ts +19 -0
  112. package/dist/types/transformer/models.d.ts +48 -0
  113. package/dist/types/transformer/object-types.d.ts +30 -0
  114. package/dist/types/transformer/project-bundle.d.ts +30 -0
  115. package/dist/types/transformer/serializer.d.ts +19 -0
  116. package/dist/types/{lib/deafults.d.ts → transformer/timestamp.d.ts} +2 -2
  117. package/dist/types/transformer/update-identifiers.d.ts +23 -0
  118. package/dist/types/types.d.ts +2 -0
  119. package/dist/types/version.d.ts +1 -1
  120. package/package.json +1 -2
  121. package/dist/cjs/jats/importer/jats-front-transformations.js +0 -79
  122. package/dist/es/jats/importer/jats-front-transformations.js +0 -76
  123. package/dist/types/jats/importer/jats-front-transformations.d.ts +0 -22
  124. package/dist/types/jats/types.d.ts +0 -1
  125. /package/dist/cjs/{jats/types.js → types.js} +0 -0
  126. /package/dist/es/{jats/types.js → types.js} +0 -0
@@ -13,22 +13,48 @@
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
19
  import { DOMParser as ProsemirrorDOMParser, DOMSerializer, } from 'prosemirror-model';
20
- import { findChildrenByAttr, findChildrenByType } from 'prosemirror-utils';
21
20
  import serializeToXML from 'w3c-xmlserializer';
22
- import { nodeFromHTML, textFromHTML } from '../../lib/html';
23
- import { generateAttachmentFilename } from '../../lib/utils';
24
- import { isCitationNode, schema, } from '../../schema';
25
- import { chooseJatsFnType, chooseSecType, isExecutableNodeType, isNodeType, } from '../../transformer';
21
+ import { nodeFromHTML, textFromHTML } from '../lib/html';
22
+ import { normalizeStyleName } from '../lib/styled-content';
23
+ import { iterateChildren } from '../lib/utils';
24
+ import { isCitationNode, schema, } from '../schema';
25
+ import { generateAttachmentFilename } from '../transformer/filename';
26
+ import { buildTargets } from '../transformer/labels';
27
+ import { isExecutableNodeType, isNodeType } from '../transformer/node-types';
28
+ import { hasObjectType } from '../transformer/object-types';
29
+ import { findManuscript, findManuscriptById, findTitles, } from '../transformer/project-bundle';
30
+ import { chooseJatsFnType, chooseSecType, } from '../transformer/section-category';
26
31
  import { selectVersionIds } from './jats-versions';
27
- import { buildTargets } from './labels';
28
32
  const warn = debug('manuscripts-transform');
29
33
  const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';
30
34
  const normalizeID = (id) => id.replace(/:/g, '_');
31
35
  const parser = ProsemirrorDOMParser.fromSchema(schema);
36
+ const findChildNodeOfType = (node, nodeType) => {
37
+ for (const child of iterateChildren(node)) {
38
+ if (child.type === nodeType) {
39
+ return child;
40
+ }
41
+ }
42
+ };
43
+ const isContributor = hasObjectType(ObjectTypes.Contributor);
44
+ const CREDIT_VOCAB_IDENTIFIER = 'https://dictionary.casrai.org/Contributor_Roles';
45
+ const chooseRoleVocabAttributes = (role) => {
46
+ if (role.uri && role.uri.startsWith(CREDIT_VOCAB_IDENTIFIER)) {
47
+ return {
48
+ vocab: 'credit',
49
+ 'vocab-identifier': CREDIT_VOCAB_IDENTIFIER,
50
+ 'vocab-term': role.name,
51
+ 'vocab-term-identifier': role.uri,
52
+ };
53
+ }
54
+ return {
55
+ vocab: 'uncontrolled',
56
+ };
57
+ };
32
58
  const insertAbstractNode = (articleMeta, abstractNode) => {
33
59
  const siblings = [
34
60
  'kwd-group',
@@ -65,24 +91,24 @@ const createDefaultIdGenerator = () => {
65
91
  return `${element.localName}-${value}`;
66
92
  };
67
93
  };
68
- const chooseRefType = (type) => {
69
- switch (type) {
70
- case schema.nodes.figure:
71
- case schema.nodes.figure_element:
94
+ const chooseRefType = (objectType) => {
95
+ switch (objectType) {
96
+ case ObjectTypes.Figure:
97
+ case ObjectTypes.FigureElement:
72
98
  return 'fig';
73
- case schema.nodes.footnote:
99
+ case ObjectTypes.Footnote:
74
100
  return 'fn';
75
- case schema.nodes.table:
76
- case schema.nodes.table_element:
101
+ case ObjectTypes.Table:
102
+ case ObjectTypes.TableElement:
77
103
  return 'table';
78
- case schema.nodes.section:
104
+ case ObjectTypes.Section:
79
105
  return 'sec';
80
- case schema.nodes.equation:
81
- case schema.nodes.equation_element:
106
+ case ObjectTypes.Equation:
107
+ case ObjectTypes.EquationElement:
82
108
  return 'disp-formula';
83
109
  }
84
110
  };
85
- const sortContributors = (a, b) => Number(a.attrs.priority) - Number(b.attrs.priority);
111
+ const sortContributors = (a, b) => Number(a.priority) - Number(b.priority);
86
112
  export const buildCitations = (citations) => citations.map((citation) => ({
87
113
  citationID: citation.attrs.id,
88
114
  citationItems: citation.attrs.rids.map((rid) => ({
@@ -94,57 +120,39 @@ export const buildCitations = (citations) => citations.map((citation) => ({
94
120
  }));
95
121
  export class JATSExporter {
96
122
  constructor() {
97
- this.getLibraryItem = (manuscriptID) => {
98
- return (id) => {
99
- var _a;
100
- const node = (_a = findChildrenByAttr(this.manuscriptNode, (attrs) => attrs.id === id)[0]) === null || _a === void 0 ? void 0 : _a.node;
101
- if (!node) {
102
- return undefined;
103
- }
104
- return {
105
- _id: node.attrs.id,
106
- issued: node.attrs.issued,
107
- DOI: node.attrs.doi,
108
- manuscriptID,
109
- objectType: ObjectTypes.BibliographyItem,
110
- author: node.attrs.author,
111
- 'container-title': node.attrs.containerTitle,
112
- volume: node.attrs.volume,
113
- issue: node.attrs.issue,
114
- supplement: node.attrs.supplement,
115
- page: node.attrs.page,
116
- title: node.attrs.title,
117
- literal: node.attrs.literal,
118
- type: node.attrs.type,
119
- };
120
- };
121
- };
122
- this.serializeToJATS = async (manuscriptNode, options) => {
123
- var _a;
124
- this.manuscriptNode = manuscriptNode;
125
- this.generateCitationTexts(options.csl, manuscriptNode.attrs.id);
123
+ this.serializeToJATS = async (fragment, modelMap, manuscriptID, options) => {
124
+ const { version = '1.2', doi, id, frontMatterOnly = false, links, idGenerator, mediaPathGenerator, csl, } = options;
125
+ this.modelMap = modelMap;
126
+ this.models = Array.from(this.modelMap.values());
127
+ this.generateCitationTexts(fragment, csl);
126
128
  this.createSerializer();
127
- const versionIds = selectVersionIds((_a = options.version) !== null && _a !== void 0 ? _a : '1.2');
129
+ const versionIds = selectVersionIds(version);
128
130
  this.document = document.implementation.createDocument(null, 'article', document.implementation.createDocumentType('article', versionIds.publicId, versionIds.systemId));
129
131
  const article = this.document.documentElement;
130
132
  article.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', XLINK_NAMESPACE);
131
- const front = this.buildFront(options.journal);
133
+ const front = this.buildFront(doi, id, links);
132
134
  article.appendChild(front);
133
- article.setAttribute('article-type', manuscriptNode.attrs.articleType || 'other');
134
- this.labelTargets = buildTargets(manuscriptNode);
135
- const body = this.buildBody();
136
- article.appendChild(body);
137
- const back = this.buildBack(body);
138
- this.moveCoiStatementToAuthorNotes(back, front);
139
- article.appendChild(back);
140
- this.unwrapBody(body);
141
- this.moveAbstracts(front, body);
142
- this.moveFloatsGroup(body, article);
143
- this.removeBackContainer(body);
144
- this.updateFootnoteTypes(front, back);
145
- this.fillEmptyTableFooters(article);
146
- this.fillEmptyFootnotes(article);
147
- await this.rewriteIDs();
135
+ const manuscript = findManuscriptById(this.modelMap, manuscriptID);
136
+ article.setAttribute('article-type', manuscript.articleType || 'other');
137
+ if (!frontMatterOnly) {
138
+ this.labelTargets = buildTargets(fragment);
139
+ const body = this.buildBody(fragment);
140
+ article.appendChild(body);
141
+ const back = this.buildBack(body);
142
+ this.moveCoiStatementToAuthorNotes(back, front);
143
+ article.appendChild(back);
144
+ this.unwrapBody(body);
145
+ this.moveAbstracts(front, body);
146
+ this.moveFloatsGroup(body, article);
147
+ this.removeBackContainer(body);
148
+ this.updateFootnoteTypes(front, back);
149
+ this.fillEmptyTableFooters(article);
150
+ this.fillEmptyFootnotes(article);
151
+ }
152
+ await this.rewriteIDs(idGenerator);
153
+ if (mediaPathGenerator) {
154
+ await this.rewriteMediaPaths(mediaPathGenerator);
155
+ }
148
156
  return serializeToXML(this.document);
149
157
  };
150
158
  this.nodeFromJATS = (JATSFragment) => {
@@ -157,6 +165,19 @@ export class JATSExporter {
157
165
  template.innerHTML = JATSFragment;
158
166
  return template.firstChild;
159
167
  };
168
+ this.rewriteMediaPaths = async (generator) => {
169
+ const doc = this.document;
170
+ for (const fig of doc.querySelectorAll('fig')) {
171
+ for (const graphic of fig.querySelectorAll('graphic')) {
172
+ const newHref = await generator(graphic, fig.id);
173
+ graphic.setAttributeNS(XLINK_NAMESPACE, 'href', newHref);
174
+ }
175
+ }
176
+ for (const suppl of doc.querySelectorAll('supplementary-material')) {
177
+ const newHref = await generator(suppl, suppl.id);
178
+ suppl.setAttributeNS(XLINK_NAMESPACE, 'href', newHref);
179
+ }
180
+ };
160
181
  this.rewriteIDs = async (generator = createDefaultIdGenerator()) => {
161
182
  const ids = new Map();
162
183
  for (const element of this.document.querySelectorAll('[id]')) {
@@ -198,14 +219,16 @@ export class JATSExporter {
198
219
  }
199
220
  }
200
221
  };
201
- this.buildFront = (journal) => {
202
- var _a;
203
- const titleNode = (_a = findChildrenByType(this.manuscriptNode, schema.nodes.title)[0]) === null || _a === void 0 ? void 0 : _a.node;
222
+ this.buildFront = (doi, id, links) => {
223
+ var _a, _b, _c, _d, _e;
224
+ const manuscript = findManuscript(this.modelMap);
225
+ const titles = findTitles(this.modelMap);
204
226
  const front = this.document.createElement('front');
205
227
  const journalMeta = this.document.createElement('journal-meta');
206
228
  front.appendChild(journalMeta);
207
229
  const articleMeta = this.document.createElement('article-meta');
208
230
  front.appendChild(articleMeta);
231
+ const journal = [...this.modelMap.values()].find((model) => model.objectType === ObjectTypes.Journal);
209
232
  if (journal) {
210
233
  if (journal.journalIdentifiers) {
211
234
  for (const item of journal.journalIdentifiers) {
@@ -254,47 +277,109 @@ export class JATSExporter {
254
277
  journalMeta.appendChild(publisher);
255
278
  }
256
279
  }
257
- if (this.manuscriptNode.attrs.doi) {
280
+ if (id) {
281
+ const articleID = this.document.createElement('article-id');
282
+ articleID.setAttribute('pub-id-type', 'publisher-id');
283
+ articleID.textContent = id;
284
+ articleMeta.appendChild(articleID);
285
+ }
286
+ if (doi || manuscript.DOI) {
258
287
  const articleID = this.document.createElement('article-id');
259
288
  articleID.setAttribute('pub-id-type', 'doi');
260
- articleID.textContent = this.manuscriptNode.attrs.doi;
289
+ articleID.textContent = (_a = manuscript.DOI) !== null && _a !== void 0 ? _a : doi;
261
290
  articleMeta.appendChild(articleID);
262
291
  }
263
292
  const titleGroup = this.document.createElement('title-group');
264
293
  articleMeta.appendChild(titleGroup);
265
294
  this.buildContributors(articleMeta);
266
- if (titleNode) {
295
+ if (links && links.self) {
296
+ for (const [key, value] of Object.entries(links.self)) {
297
+ const link = this.document.createElement('self-uri');
298
+ link.setAttribute('content-type', key);
299
+ link.setAttributeNS(XLINK_NAMESPACE, 'href', value);
300
+ articleMeta.appendChild(link);
301
+ }
302
+ }
303
+ if (titles.title) {
267
304
  const element = this.document.createElement('article-title');
268
- this.setTitleContent(element, titleNode.textContent);
305
+ this.setTitleContent(element, titles.title);
269
306
  titleGroup.appendChild(element);
270
307
  }
271
- const supplementsNodes = findChildrenByType(this.manuscriptNode, schema.nodes.supplement);
272
- supplementsNodes.forEach(({ node }) => {
273
- var _a, _b, _c, _d;
274
- const supplementaryMaterial = this.document.createElement('supplementary-material');
275
- supplementaryMaterial.setAttribute('id', normalizeID(node.attrs.id));
276
- supplementaryMaterial.setAttributeNS(XLINK_NAMESPACE, 'href', (_a = node.attrs.href) !== null && _a !== void 0 ? _a : '');
277
- supplementaryMaterial.setAttribute('mimetype', (_b = node.attrs.mimeType) !== null && _b !== void 0 ? _b : '');
278
- supplementaryMaterial.setAttribute('mime-subtype', (_c = node.attrs.mimeSubType) !== null && _c !== void 0 ? _c : '');
279
- const caption = this.document.createElement('caption');
280
- const title = this.document.createElement('title');
281
- title.textContent = (_d = node.attrs.title) !== null && _d !== void 0 ? _d : '';
282
- caption.append(title);
283
- supplementaryMaterial.append(caption);
284
- articleMeta.append(supplementaryMaterial);
285
- });
308
+ if (titles.subtitle) {
309
+ const element = this.document.createElement('subtitle');
310
+ this.setTitleContent(element, titles.subtitle);
311
+ titleGroup.appendChild(element);
312
+ }
313
+ if (titles.runningTitle) {
314
+ const element = this.document.createElement('alt-title');
315
+ element.setAttribute('alt-title-type', 'right-running');
316
+ this.setTitleContent(element, titles.runningTitle);
317
+ titleGroup.appendChild(element);
318
+ }
319
+ const supplements = [...this.modelMap.values()].filter((model) => model.objectType === ObjectTypes.Supplement);
320
+ if (supplements && supplements.length > 0) {
321
+ for (const supplement of supplements) {
322
+ const supplementaryMaterial = this.document.createElement('supplementary-material');
323
+ supplementaryMaterial.setAttribute('id', normalizeID(supplement._id));
324
+ supplementaryMaterial.setAttributeNS(XLINK_NAMESPACE, 'href', (_b = supplement.href) !== null && _b !== void 0 ? _b : '');
325
+ const mimeType = (_c = supplement.MIME) === null || _c === void 0 ? void 0 : _c.split('/')[0];
326
+ const mimeSubType = (_d = supplement.MIME) === null || _d === void 0 ? void 0 : _d.split('/')[1];
327
+ supplementaryMaterial.setAttribute('mimetype', mimeType !== null && mimeType !== void 0 ? mimeType : '');
328
+ supplementaryMaterial.setAttribute('mime-subtype', mimeSubType !== null && mimeSubType !== void 0 ? mimeSubType : '');
329
+ const caption = this.document.createElement('caption');
330
+ const title = this.document.createElement('title');
331
+ title.textContent = (_e = supplement.title) !== null && _e !== void 0 ? _e : '';
332
+ caption.append(title);
333
+ supplementaryMaterial.append(caption);
334
+ articleMeta.append(supplementaryMaterial);
335
+ }
336
+ }
337
+ const history = articleMeta.querySelector('history') ||
338
+ this.document.createElement('history');
339
+ if (manuscript.acceptanceDate) {
340
+ const date = this.buildDateElement(manuscript.acceptanceDate, 'accepted');
341
+ history.appendChild(date);
342
+ }
343
+ if (manuscript.correctionDate) {
344
+ const date = this.buildDateElement(manuscript.correctionDate, 'corrected');
345
+ history.appendChild(date);
346
+ }
347
+ if (manuscript.retractionDate) {
348
+ const date = this.buildDateElement(manuscript.retractionDate, 'retracted');
349
+ history.appendChild(date);
350
+ }
351
+ if (manuscript.receiveDate) {
352
+ const date = this.buildDateElement(manuscript.receiveDate, 'received');
353
+ history.appendChild(date);
354
+ }
355
+ if (manuscript.revisionReceiveDate) {
356
+ const date = this.buildDateElement(manuscript.revisionReceiveDate, 'rev-recd');
357
+ history.appendChild(date);
358
+ }
359
+ if (manuscript.revisionRequestDate) {
360
+ const date = this.buildDateElement(manuscript.revisionRequestDate, 'rev-request');
361
+ history.appendChild(date);
362
+ }
363
+ if (history.childElementCount) {
364
+ articleMeta.appendChild(history);
365
+ }
286
366
  this.buildKeywords(articleMeta);
287
367
  let countingElements = [];
288
- const figureCount = findChildrenByType(this.manuscriptNode, schema.nodes.figure).length;
289
- countingElements.push(this.buildCountingElement('fig-count', figureCount));
290
- const equationCount = findChildrenByType(this.manuscriptNode, schema.nodes.equation_element).length;
291
- countingElements.push(this.buildCountingElement('equation-count', equationCount));
292
- const tableCount = findChildrenByType(this.manuscriptNode, schema.nodes.table).length;
293
- countingElements.push(this.buildCountingElement('table-count', tableCount));
294
- const referencesCount = findChildrenByType(this.manuscriptNode, schema.nodes.bibliography_item).length;
295
- countingElements.push(this.buildCountingElement('ref-count', referencesCount));
296
- const wordCount = this.manuscriptNode.textContent.split(/\s+/).length;
297
- countingElements.push(this.buildCountingElement('word-count', wordCount));
368
+ if (manuscript.genericCounts) {
369
+ const elements = manuscript.genericCounts.map((el) => {
370
+ const countingElement = this.buildCountingElement('count', el.count);
371
+ if (countingElement) {
372
+ countingElement.setAttribute('count-type', el.countType);
373
+ }
374
+ return countingElement;
375
+ });
376
+ countingElements.push(...elements);
377
+ }
378
+ countingElements.push(this.buildCountingElement('fig-count', manuscript.figureCount));
379
+ countingElements.push(this.buildCountingElement('table-count', manuscript.tableCount));
380
+ countingElements.push(this.buildCountingElement('equation-count', manuscript.equationCount));
381
+ countingElements.push(this.buildCountingElement('ref-count', manuscript.referencesCount));
382
+ countingElements.push(this.buildCountingElement('word-count', manuscript.wordCount));
298
383
  countingElements = countingElements.filter((el) => el);
299
384
  if (countingElements.length > 0) {
300
385
  const counts = this.document.createElement('counts');
@@ -329,17 +414,16 @@ export class JATSExporter {
329
414
  return wordCount;
330
415
  }
331
416
  };
332
- this.buildBody = () => {
417
+ this.buildBody = (fragment) => {
333
418
  const body = this.document.createElement('body');
334
- this.manuscriptNode.forEach((cFragment) => {
419
+ fragment.forEach((cFragment) => {
335
420
  const serializedNode = this.serializeNode(cFragment);
336
421
  body.append(...serializedNode.childNodes);
337
422
  });
338
- this.fixBody(body);
423
+ this.fixBody(body, fragment);
339
424
  return body;
340
425
  };
341
426
  this.buildBack = (body) => {
342
- var _a;
343
427
  const back = this.document.createElement('back');
344
428
  this.moveSectionsToBack(back, body);
345
429
  const footnotesElements = this.document.querySelectorAll('sec > fn-group');
@@ -364,7 +448,7 @@ export class JATSExporter {
364
448
  back.appendChild(refList);
365
449
  const [meta] = this.citationProvider.makeBibliography();
366
450
  for (const id of meta.entry_ids) {
367
- const bibliographyNode = (_a = findChildrenByType(this.manuscriptNode, schema.nodes.bibliography_item).find(({ node }) => node.attrs.id === id[0])) === null || _a === void 0 ? void 0 : _a.node;
451
+ const bibliographyItem = this.modelMap.get(id[0]);
368
452
  const ref = this.document.createElement('ref');
369
453
  ref.setAttribute('id', normalizeID(id[0]));
370
454
  const updateCitationPubType = (citationEl, pubType) => {
@@ -383,21 +467,21 @@ export class JATSExporter {
383
467
  citationEl.setAttribute('publication-type', 'journal');
384
468
  }
385
469
  };
386
- if (bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.literal) {
470
+ if (bibliographyItem.literal) {
387
471
  const mixedCitation = this.document.createElement('mixed-citation');
388
- updateCitationPubType(mixedCitation, bibliographyNode.attrs.type);
389
- mixedCitation.textContent = bibliographyNode.attrs.literal;
472
+ updateCitationPubType(mixedCitation, bibliographyItem.type);
473
+ mixedCitation.textContent = bibliographyItem.literal;
390
474
  ref.appendChild(mixedCitation);
391
475
  refList.appendChild(ref);
392
476
  }
393
477
  else {
394
478
  const citation = this.document.createElement('element-citation');
395
- updateCitationPubType(citation, bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.type);
396
- if (bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.author) {
479
+ updateCitationPubType(citation, bibliographyItem.type);
480
+ if (bibliographyItem.author) {
397
481
  const personGroupNode = this.document.createElement('person-group');
398
482
  personGroupNode.setAttribute('person-group-type', 'author');
399
483
  citation.appendChild(personGroupNode);
400
- bibliographyNode.attrs.author.forEach((author) => {
484
+ bibliographyItem.author.forEach((author) => {
401
485
  const name = this.document.createElement('string-name');
402
486
  if (author.family) {
403
487
  const node = this.document.createElement('surname');
@@ -419,8 +503,8 @@ export class JATSExporter {
419
503
  }
420
504
  });
421
505
  }
422
- if (bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.issued) {
423
- const dateParts = bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.issued['date-parts'];
506
+ if (bibliographyItem.issued) {
507
+ const dateParts = bibliographyItem.issued['date-parts'];
424
508
  if (dateParts && dateParts.length) {
425
509
  const [[year, month, day]] = dateParts;
426
510
  if (year) {
@@ -440,33 +524,33 @@ export class JATSExporter {
440
524
  }
441
525
  }
442
526
  }
443
- if (bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.title) {
527
+ if (bibliographyItem.title) {
444
528
  const node = this.document.createElement('article-title');
445
- this.setTitleContent(node, bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.title);
529
+ this.setTitleContent(node, bibliographyItem.title);
446
530
  citation.appendChild(node);
447
531
  }
448
- if (bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.containerTitle) {
532
+ if (bibliographyItem['container-title']) {
449
533
  const node = this.document.createElement('source');
450
- node.textContent = bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.containerTitle;
534
+ node.textContent = bibliographyItem['container-title'];
451
535
  citation.appendChild(node);
452
536
  }
453
- if (bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.volume) {
537
+ if (bibliographyItem.volume) {
454
538
  const node = this.document.createElement('volume');
455
- node.textContent = String(bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.volume);
539
+ node.textContent = String(bibliographyItem.volume);
456
540
  citation.appendChild(node);
457
541
  }
458
- if (bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.issue) {
542
+ if (bibliographyItem.issue) {
459
543
  const node = this.document.createElement('issue');
460
- node.textContent = String(bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.issue);
544
+ node.textContent = String(bibliographyItem.issue);
461
545
  citation.appendChild(node);
462
546
  }
463
- if (bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.supplement) {
547
+ if (bibliographyItem.supplement) {
464
548
  const node = this.document.createElement('supplement');
465
- node.textContent = bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.supplement;
549
+ node.textContent = bibliographyItem.supplement;
466
550
  citation.appendChild(node);
467
551
  }
468
- if (bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.page) {
469
- const pageString = String(bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.page);
552
+ if (bibliographyItem.page) {
553
+ const pageString = String(bibliographyItem.page);
470
554
  if (/^\d+$/.test(pageString)) {
471
555
  const node = this.document.createElement('fpage');
472
556
  node.textContent = pageString;
@@ -487,10 +571,10 @@ export class JATSExporter {
487
571
  citation.appendChild(node);
488
572
  }
489
573
  }
490
- if (bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.doi) {
574
+ if (bibliographyItem.DOI) {
491
575
  const node = this.document.createElement('pub-id');
492
576
  node.setAttribute('pub-id-type', 'doi');
493
- node.textContent = String(bibliographyNode === null || bibliographyNode === void 0 ? void 0 : bibliographyNode.attrs.doi);
577
+ node.textContent = String(bibliographyItem.DOI);
494
578
  citation.appendChild(node);
495
579
  }
496
580
  ref.appendChild(citation);
@@ -500,10 +584,11 @@ export class JATSExporter {
500
584
  return back;
501
585
  };
502
586
  this.createSerializer = () => {
587
+ const getModel = (id) => id ? this.modelMap.get(id) : undefined;
503
588
  const nodes = {
504
589
  award: () => '',
505
590
  awards: () => '',
506
- box_element: () => ['boxed-text', 0],
591
+ box_element: (node) => createBoxElement(node),
507
592
  author_notes: () => '',
508
593
  corresp: () => '',
509
594
  title: () => '',
@@ -564,25 +649,24 @@ export class JATSExporter {
564
649
  return xref;
565
650
  },
566
651
  cross_reference: (node) => {
567
- var _a;
568
652
  const cross = node;
569
653
  const rids = cross.attrs.rids;
570
654
  if (!rids.length) {
571
655
  return cross.attrs.label;
572
656
  }
573
657
  const text = cross.attrs.customLabel || cross.attrs.label;
574
- const target = (_a = findChildrenByAttr(this.manuscriptNode, (attrs) => attrs.id === rids[0])[0]) === null || _a === void 0 ? void 0 : _a.node;
575
- if (!target) {
658
+ const model = getModel(rids[0]);
659
+ if (!model) {
576
660
  warn('');
577
661
  return text;
578
662
  }
579
663
  const xref = this.document.createElement('xref');
580
- const type = chooseRefType(target.type);
664
+ const type = chooseRefType(model.objectType);
581
665
  if (type) {
582
666
  xref.setAttribute('ref-type', type);
583
667
  }
584
668
  else {
585
- warn(`Unset ref-type for schema type ${target.type.name}`);
669
+ warn(`Unset ref-type for objectType ${model.objectType}`);
586
670
  }
587
671
  xref.setAttribute('rid', normalizeID(rids.join(' ')));
588
672
  xref.textContent = text;
@@ -654,10 +738,7 @@ export class JATSExporter {
654
738
  hard_break: () => '',
655
739
  highlight_marker: () => '',
656
740
  inline_footnote: (node) => {
657
- const rids = node.attrs.rids.filter((rid) => {
658
- var _a;
659
- return (_a = findChildrenByAttr(this.manuscriptNode, (attrs) => attrs.id === rid)[0]) === null || _a === void 0 ? void 0 : _a.node;
660
- });
741
+ const rids = node.attrs.rids.filter(getModel);
661
742
  if (rids.length == 0) {
662
743
  return '';
663
744
  }
@@ -776,7 +857,14 @@ export class JATSExporter {
776
857
  italic: () => ['italic'],
777
858
  smallcaps: () => ['sc'],
778
859
  strikethrough: () => ['strike'],
779
- styled: () => ['styled-content'],
860
+ styled: (mark) => {
861
+ const inlineStyle = getModel(mark.attrs.rid);
862
+ const attrs = {};
863
+ if (inlineStyle && inlineStyle.title) {
864
+ attrs.style = normalizeStyleName(inlineStyle.title);
865
+ }
866
+ return ['styled-content', attrs];
867
+ },
780
868
  superscript: () => ['sup'],
781
869
  subscript: () => ['sub'],
782
870
  underline: () => ['underline'],
@@ -827,16 +915,14 @@ export class JATSExporter {
827
915
  }
828
916
  };
829
917
  const appendChildNodeOfType = (element, node, type) => {
830
- var _a;
831
- const childNode = (_a = findChildrenByType(node, type)[0]) === null || _a === void 0 ? void 0 : _a.node;
918
+ const childNode = findChildNodeOfType(node, type);
832
919
  if (childNode) {
833
920
  element.appendChild(this.serializeNode(childNode));
834
921
  }
835
922
  };
836
923
  const appendTable = (element, node) => {
837
- var _a, _b;
838
- const tableNode = (_a = findChildrenByType(node, node.type.schema.nodes.table)[0]) === null || _a === void 0 ? void 0 : _a.node;
839
- const colGroupNode = (_b = findChildrenByType(node, node.type.schema.nodes.table_colgroup)[0]) === null || _b === void 0 ? void 0 : _b.node;
924
+ const tableNode = findChildNodeOfType(node, node.type.schema.nodes.table);
925
+ const colGroupNode = findChildNodeOfType(node, node.type.schema.nodes.table_colgroup);
840
926
  if (!tableNode) {
841
927
  return;
842
928
  }
@@ -854,6 +940,13 @@ export class JATSExporter {
854
940
  }
855
941
  element.appendChild(table);
856
942
  };
943
+ const createBoxElement = (node) => {
944
+ const element = createElement(node, 'boxed-text');
945
+ appendLabels(element, node);
946
+ appendChildNodeOfType(element, node, node.type.schema.nodes.figcaption);
947
+ processChildNodes(element, node, node.type.schema.nodes.section);
948
+ return element;
949
+ };
857
950
  const createFigureElement = (node, nodeName, contentNodeType, figType) => {
858
951
  const element = createElement(node, nodeName);
859
952
  if (figType) {
@@ -882,8 +975,7 @@ export class JATSExporter {
882
975
  return element;
883
976
  };
884
977
  const processExecutableNode = (node, element) => {
885
- var _a;
886
- const listingNode = (_a = findChildrenByType(node, node.type.schema.nodes.listing)[0]) === null || _a === void 0 ? void 0 : _a.node;
978
+ const listingNode = findChildNodeOfType(node, node.type.schema.nodes.listing);
887
979
  if (listingNode) {
888
980
  const { contents, languageKey } = listingNode.attrs;
889
981
  if (contents && languageKey) {
@@ -917,25 +1009,25 @@ export class JATSExporter {
917
1009
  }
918
1010
  };
919
1011
  };
1012
+ this.serializeFragment = (fragment) => this.serializer.serializeFragment(fragment, {
1013
+ document: this.document,
1014
+ });
920
1015
  this.serializeNode = (node) => this.serializer.serializeNode(node, {
921
1016
  document: this.document,
922
1017
  });
923
1018
  this.validateContributor = (contributor) => {
924
- if (!contributor.attrs.bibliographicName) {
925
- throw new Error(`${contributor.attrs.id} has no bibliographicName`);
1019
+ if (!contributor.bibliographicName) {
1020
+ throw new Error(`${contributor._id} has no bibliographicName`);
926
1021
  }
927
- const { family, given } = contributor.attrs.bibliographicName;
1022
+ const { family, given } = contributor.bibliographicName;
928
1023
  if (!family && !given) {
929
- throw new Error(`${contributor.attrs.id} has neither family nor given name`);
1024
+ throw new Error(`${contributor._id} has neither family nor given name`);
930
1025
  }
931
1026
  };
932
1027
  this.buildContributors = (articleMeta) => {
933
- const contributorNodes = findChildrenByType(this.manuscriptNode, schema.nodes.contributor).map((result) => result.node);
934
- const authorContributorNodes = contributorNodes
935
- .filter((n) => n.attrs.role === 'author')
936
- .sort(sortContributors);
937
- const otherContributorsNodes = contributorNodes
938
- .filter((n) => n.attrs.role !== 'author')
1028
+ const contributors = this.models.filter(isContributor);
1029
+ const authorContributors = contributors
1030
+ .filter((contributor) => contributor.role === 'author')
939
1031
  .sort(sortContributors);
940
1032
  const affiliationLabels = new Map();
941
1033
  const creatAffiliationLabel = (rid) => {
@@ -953,11 +1045,11 @@ export class JATSExporter {
953
1045
  sup.textContent = String(content);
954
1046
  return sup;
955
1047
  };
956
- if (authorContributorNodes.length) {
1048
+ if (authorContributors.length) {
957
1049
  const contribGroup = this.document.createElement('contrib-group');
958
1050
  contribGroup.setAttribute('content-type', 'authors');
959
1051
  articleMeta.appendChild(contribGroup);
960
- authorContributorNodes.forEach((contributor) => {
1052
+ authorContributors.forEach((contributor) => {
961
1053
  try {
962
1054
  this.validateContributor(contributor);
963
1055
  }
@@ -967,25 +1059,39 @@ export class JATSExporter {
967
1059
  }
968
1060
  const contrib = this.document.createElement('contrib');
969
1061
  contrib.setAttribute('contrib-type', 'author');
970
- contrib.setAttribute('id', normalizeID(contributor.attrs.id));
971
- if (contributor.attrs.isCorresponding) {
1062
+ contrib.setAttribute('id', normalizeID(contributor._id));
1063
+ if (contributor.isCorresponding) {
972
1064
  contrib.setAttribute('corresp', 'yes');
973
1065
  }
974
- if (contributor.attrs.ORCIDIdentifier) {
1066
+ if (contributor.ORCIDIdentifier) {
975
1067
  const identifier = this.document.createElement('contrib-id');
976
1068
  identifier.setAttribute('contrib-id-type', 'orcid');
977
- identifier.textContent = contributor.attrs.ORCIDIdentifier;
1069
+ identifier.textContent = contributor.ORCIDIdentifier;
978
1070
  contrib.appendChild(identifier);
979
1071
  }
980
1072
  const name = this.buildContributorName(contributor);
981
1073
  contrib.appendChild(name);
982
- if (contributor.attrs.email) {
1074
+ if (contributor.email) {
983
1075
  const email = this.document.createElement('email');
984
- email.textContent = contributor.attrs.email;
1076
+ email.textContent = contributor.email;
985
1077
  contrib.appendChild(email);
986
1078
  }
987
- if (contributor.attrs.affiliations) {
988
- contributor.attrs.affiliations.forEach((rid) => {
1079
+ if (contributor.roles) {
1080
+ contributor.roles.forEach((rid) => {
1081
+ const contributorRole = this.modelMap.get(rid);
1082
+ if (contributorRole) {
1083
+ const role = this.document.createElement('role');
1084
+ const attributes = chooseRoleVocabAttributes(contributorRole);
1085
+ for (const [key, value] of Object.entries(attributes)) {
1086
+ role.setAttribute(key, value);
1087
+ }
1088
+ role.textContent = contributorRole.name;
1089
+ contrib.appendChild(role);
1090
+ }
1091
+ });
1092
+ }
1093
+ if (contributor.affiliations) {
1094
+ contributor.affiliations.forEach((rid) => {
989
1095
  const xref = this.document.createElement('xref');
990
1096
  xref.setAttribute('ref-type', 'aff');
991
1097
  xref.setAttribute('rid', normalizeID(rid));
@@ -993,8 +1099,8 @@ export class JATSExporter {
993
1099
  contrib.appendChild(xref);
994
1100
  });
995
1101
  }
996
- if (contributor.attrs.footnote) {
997
- contributor.attrs.footnote.map((note) => {
1102
+ if (contributor.footnote) {
1103
+ contributor.footnote.map((note) => {
998
1104
  const xref = this.document.createElement('xref');
999
1105
  xref.setAttribute('ref-type', 'fn');
1000
1106
  xref.setAttribute('rid', normalizeID(note.noteID));
@@ -1002,8 +1108,8 @@ export class JATSExporter {
1002
1108
  contrib.appendChild(xref);
1003
1109
  });
1004
1110
  }
1005
- if (contributor.attrs.corresp) {
1006
- contributor.attrs.corresp.map((corresp) => {
1111
+ if (contributor.corresp) {
1112
+ contributor.corresp.map((corresp) => {
1007
1113
  const xref = this.document.createElement('xref');
1008
1114
  xref.setAttribute('ref-type', 'corresp');
1009
1115
  xref.setAttribute('rid', normalizeID(corresp.correspID));
@@ -1013,10 +1119,13 @@ export class JATSExporter {
1013
1119
  }
1014
1120
  contribGroup.appendChild(contrib);
1015
1121
  });
1016
- if (otherContributorsNodes.length) {
1122
+ const otherContributors = contributors
1123
+ .filter((contributor) => contributor.role !== 'author')
1124
+ .sort(sortContributors);
1125
+ if (otherContributors.length) {
1017
1126
  const contribGroup = this.document.createElement('contrib-group');
1018
1127
  articleMeta.appendChild(contribGroup);
1019
- otherContributorsNodes.forEach((contributor) => {
1128
+ otherContributors.forEach((contributor) => {
1020
1129
  try {
1021
1130
  this.validateContributor(contributor);
1022
1131
  }
@@ -1025,16 +1134,30 @@ export class JATSExporter {
1025
1134
  return;
1026
1135
  }
1027
1136
  const contrib = this.document.createElement('contrib');
1028
- contrib.setAttribute('id', normalizeID(contributor.attrs.id));
1137
+ contrib.setAttribute('id', normalizeID(contributor._id));
1029
1138
  const name = this.buildContributorName(contributor);
1030
1139
  contrib.appendChild(name);
1031
- if (contributor.attrs.email) {
1140
+ if (contributor.email) {
1032
1141
  const email = this.document.createElement('email');
1033
- email.textContent = contributor.attrs.email;
1142
+ email.textContent = contributor.email;
1034
1143
  contrib.appendChild(email);
1035
1144
  }
1036
- if (contributor.attrs.affiliations) {
1037
- contributor.attrs.affiliations.forEach((rid) => {
1145
+ if (contributor.roles) {
1146
+ contributor.roles.forEach((rid) => {
1147
+ const contributorRole = this.modelMap.get(rid);
1148
+ if (contributorRole) {
1149
+ const role = this.document.createElement('role');
1150
+ const attributes = chooseRoleVocabAttributes(contributorRole);
1151
+ for (const [key, value] of Object.entries(attributes)) {
1152
+ role.setAttribute(key, value);
1153
+ }
1154
+ role.textContent = contributorRole.name;
1155
+ contrib.appendChild(role);
1156
+ }
1157
+ });
1158
+ }
1159
+ if (contributor.affiliations) {
1160
+ contributor.affiliations.forEach((rid) => {
1038
1161
  const xref = this.document.createElement('xref');
1039
1162
  xref.setAttribute('ref-type', 'aff');
1040
1163
  xref.setAttribute('rid', normalizeID(rid));
@@ -1042,8 +1165,8 @@ export class JATSExporter {
1042
1165
  contrib.appendChild(xref);
1043
1166
  });
1044
1167
  }
1045
- if (contributor.attrs.footnote) {
1046
- contributor.attrs.footnote.map((note) => {
1168
+ if (contributor.footnote) {
1169
+ contributor.footnote.map((note) => {
1047
1170
  const xref = this.document.createElement('xref');
1048
1171
  xref.setAttribute('ref-type', 'fn');
1049
1172
  xref.setAttribute('rid', normalizeID(note.noteID));
@@ -1055,68 +1178,64 @@ export class JATSExporter {
1055
1178
  });
1056
1179
  }
1057
1180
  const affiliationRIDs = [];
1058
- const sortedContributors = [
1059
- ...authorContributorNodes,
1060
- ...otherContributorsNodes,
1061
- ];
1181
+ const sortedContributors = [...authorContributors, ...otherContributors];
1062
1182
  for (const contributor of sortedContributors) {
1063
- if (contributor.attrs.affiliations) {
1064
- affiliationRIDs.push(...contributor.attrs.affiliations);
1183
+ if (contributor.affiliations) {
1184
+ affiliationRIDs.push(...contributor.affiliations);
1065
1185
  }
1066
1186
  }
1067
- const affiliations = findChildrenByType(this.manuscriptNode, schema.nodes.affiliation).map((result) => result.node);
1187
+ const affiliations = this.models.filter(hasObjectType(ObjectTypes.Affiliation));
1068
1188
  if (affiliations) {
1069
- const usedAffiliations = affiliations.filter((affiliation) => affiliationRIDs.includes(affiliation.attrs.id));
1070
- usedAffiliations.sort((a, b) => affiliationRIDs.indexOf(a.attrs.id) -
1071
- affiliationRIDs.indexOf(b.attrs.id));
1189
+ const usedAffiliations = affiliations.filter((affiliation) => affiliationRIDs.includes(affiliation._id));
1190
+ usedAffiliations.sort((a, b) => affiliationRIDs.indexOf(a._id) - affiliationRIDs.indexOf(b._id));
1072
1191
  usedAffiliations.forEach((affiliation) => {
1073
1192
  var _a, _b;
1074
1193
  const aff = this.document.createElement('aff');
1075
- aff.setAttribute('id', normalizeID(affiliation.attrs.id));
1194
+ aff.setAttribute('id', normalizeID(affiliation._id));
1076
1195
  contribGroup.appendChild(aff);
1077
- if (affiliation.attrs.department) {
1196
+ if (affiliation.department) {
1078
1197
  const department = this.document.createElement('institution');
1079
1198
  department.setAttribute('content-type', 'dept');
1080
- department.textContent = affiliation.attrs.department;
1199
+ department.textContent = affiliation.department;
1081
1200
  aff.appendChild(department);
1082
1201
  }
1083
- if (affiliation.attrs.institution) {
1202
+ if (affiliation.institution) {
1084
1203
  const institution = this.document.createElement('institution');
1085
- institution.textContent = affiliation.attrs.institution;
1204
+ institution.textContent = affiliation.institution;
1086
1205
  aff.appendChild(institution);
1087
1206
  }
1088
- if (affiliation.attrs.addressLine1) {
1207
+ if (affiliation.addressLine1) {
1089
1208
  const addressLine = this.document.createElement('addr-line');
1090
- addressLine.textContent = affiliation.attrs.addressLine1;
1209
+ addressLine.textContent = affiliation.addressLine1;
1091
1210
  aff.appendChild(addressLine);
1092
1211
  }
1093
- if (affiliation.attrs.addressLine2) {
1212
+ if (affiliation.addressLine2) {
1094
1213
  const addressLine = this.document.createElement('addr-line');
1095
- addressLine.textContent = affiliation.attrs.addressLine2;
1214
+ addressLine.textContent = affiliation.addressLine2;
1096
1215
  aff.appendChild(addressLine);
1097
1216
  }
1098
- if (affiliation.attrs.addressLine3) {
1217
+ if (affiliation.addressLine3) {
1099
1218
  const addressLine = this.document.createElement('addr-line');
1100
- addressLine.textContent = affiliation.attrs.addressLine3;
1219
+ addressLine.textContent = affiliation.addressLine3;
1101
1220
  aff.appendChild(addressLine);
1102
1221
  }
1103
- if (affiliation.attrs.city) {
1222
+ if (affiliation.city) {
1104
1223
  const city = this.document.createElement('city');
1105
- city.textContent = affiliation.attrs.city;
1224
+ city.textContent = affiliation.city;
1106
1225
  aff.appendChild(city);
1107
1226
  }
1108
- if (affiliation.attrs.country) {
1227
+ if (affiliation.country) {
1109
1228
  const country = this.document.createElement('country');
1110
- country.textContent = affiliation.attrs.country;
1229
+ country.textContent = affiliation.country;
1111
1230
  aff.appendChild(country);
1112
1231
  }
1113
- if (affiliation.attrs.email) {
1232
+ if (affiliation.email) {
1114
1233
  const email = this.document.createElement('email');
1115
- email.setAttributeNS(XLINK_NAMESPACE, 'href', (_a = affiliation.attrs.email.href) !== null && _a !== void 0 ? _a : '');
1116
- email.textContent = (_b = affiliation.attrs.email.text) !== null && _b !== void 0 ? _b : '';
1234
+ email.setAttributeNS(XLINK_NAMESPACE, 'href', (_a = affiliation.email.href) !== null && _a !== void 0 ? _a : '');
1235
+ email.textContent = (_b = affiliation.email.text) !== null && _b !== void 0 ? _b : '';
1117
1236
  aff.appendChild(email);
1118
1237
  }
1119
- const labelNumber = affiliationLabels.get(affiliation.attrs.id);
1238
+ const labelNumber = affiliationLabels.get(affiliation._id);
1120
1239
  if (labelNumber) {
1121
1240
  const label = this.document.createElement('label');
1122
1241
  label.textContent = String(labelNumber);
@@ -1133,48 +1252,41 @@ export class JATSExporter {
1133
1252
  this.createAuthorNotesElement = () => {
1134
1253
  var _a;
1135
1254
  const authorNotesEl = this.document.createElement('author-notes');
1136
- const authorNotesNode = (_a = findChildrenByType(this.manuscriptNode, schema.nodes.author_notes)[0]) === null || _a === void 0 ? void 0 : _a.node;
1137
- if (authorNotesNode) {
1138
- this.appendModelsToAuthorNotes(authorNotesEl, authorNotesNode);
1255
+ const authorNotes = (_a = getModelsByType(this.modelMap, ObjectTypes.AuthorNotes)) === null || _a === void 0 ? void 0 : _a[0];
1256
+ if (authorNotes) {
1257
+ this.appendModelsToAuthorNotes(authorNotesEl, authorNotes.containedObjectIDs);
1139
1258
  }
1140
1259
  return authorNotesEl;
1141
1260
  };
1142
1261
  this.appendCorrespondingToElement = (corresponding, element) => {
1143
1262
  const correspondingEl = this.document.createElement('corresp');
1144
- correspondingEl.setAttribute('id', normalizeID(corresponding.attrs.id));
1145
- if (corresponding.attrs.label) {
1263
+ correspondingEl.setAttribute('id', normalizeID(corresponding._id));
1264
+ if (corresponding.label) {
1146
1265
  const labelEl = this.document.createElement('label');
1147
- labelEl.textContent = corresponding.attrs.label;
1266
+ labelEl.textContent = corresponding.label;
1148
1267
  correspondingEl.appendChild(labelEl);
1149
1268
  }
1150
- correspondingEl.append(corresponding.textContent);
1269
+ correspondingEl.append(corresponding.contents);
1151
1270
  element.appendChild(correspondingEl);
1152
1271
  };
1153
1272
  this.appendParagraphToElement = (paragraph, element) => {
1154
- const parsedDoc = new DOMParser().parseFromString(paragraph.textContent, 'text/html');
1273
+ const parsedDoc = new DOMParser().parseFromString(paragraph.contents, 'text/html');
1155
1274
  const parsedParagraph = parsedDoc.body.querySelector('p');
1156
1275
  if (parsedParagraph) {
1157
1276
  const paragraphEl = this.document.createElement('p');
1158
1277
  paragraphEl.innerHTML = parsedParagraph.innerHTML;
1159
- paragraphEl.setAttribute('id', normalizeID(paragraph.attrs.id));
1278
+ paragraphEl.setAttribute('id', normalizeID(paragraph._id));
1160
1279
  element.appendChild(paragraphEl);
1161
1280
  }
1162
1281
  };
1163
1282
  this.appendFootnoteToElement = (footnote, element) => {
1164
1283
  const footnoteEl = this.document.createElement('fn');
1165
- footnoteEl.setAttribute('id', normalizeID(footnote.attrs.id));
1166
- if (!footnote.textContent.includes('<p>')) {
1167
- const p = this.document.createElement('p');
1168
- p.innerHTML = footnote.textContent;
1169
- footnoteEl.appendChild(p);
1170
- }
1171
- else {
1172
- footnoteEl.innerHTML = footnote.textContent;
1173
- }
1284
+ footnoteEl.setAttribute('id', normalizeID(footnote._id));
1285
+ footnoteEl.innerHTML = footnote.contents;
1174
1286
  element.appendChild(footnoteEl);
1175
1287
  };
1176
- this.fixBody = (body) => {
1177
- this.manuscriptNode.descendants((node) => {
1288
+ this.fixBody = (body, fragment) => {
1289
+ fragment.descendants((node) => {
1178
1290
  if (node.attrs.id) {
1179
1291
  if (node.attrs.titleSuppressed) {
1180
1292
  const title = body.querySelector(`#${normalizeID(node.attrs.id)} > title`);
@@ -1435,36 +1547,36 @@ export class JATSExporter {
1435
1547
  };
1436
1548
  this.buildContributorName = (contributor) => {
1437
1549
  const name = this.document.createElement('name');
1438
- if (contributor.attrs.bibliographicName.family) {
1550
+ if (contributor.bibliographicName.family) {
1439
1551
  const surname = this.document.createElement('surname');
1440
- surname.textContent = contributor.attrs.bibliographicName.family;
1552
+ surname.textContent = contributor.bibliographicName.family;
1441
1553
  name.appendChild(surname);
1442
1554
  }
1443
- if (contributor.attrs.bibliographicName.given) {
1555
+ if (contributor.bibliographicName.given) {
1444
1556
  const givenNames = this.document.createElement('given-names');
1445
- givenNames.textContent = contributor.attrs.bibliographicName.given;
1557
+ givenNames.textContent = contributor.bibliographicName.given;
1446
1558
  name.appendChild(givenNames);
1447
1559
  }
1448
1560
  return name;
1449
1561
  };
1450
1562
  }
1451
- generateCitations() {
1563
+ generateCitations(fragment) {
1452
1564
  const nodes = [];
1453
- this.manuscriptNode.descendants((node) => {
1565
+ fragment.descendants((node) => {
1454
1566
  if (isCitationNode(node)) {
1455
1567
  nodes.push(node);
1456
1568
  }
1457
1569
  });
1458
1570
  return buildCitations(nodes);
1459
1571
  }
1460
- generateCitationTexts(csl, manuscriptID) {
1572
+ generateCitationTexts(fragment, csl) {
1461
1573
  this.citationTexts = new Map();
1462
1574
  this.citationProvider = new CitationProvider({
1463
- getLibraryItem: this.getLibraryItem(manuscriptID),
1575
+ getLibraryItem: (id) => this.modelMap.get(id),
1464
1576
  locale: csl.locale,
1465
1577
  citationStyle: csl.style,
1466
1578
  });
1467
- const citations = this.generateCitations();
1579
+ const citations = this.generateCitations(fragment);
1468
1580
  this.citationProvider.rebuildState(citations).forEach(([id, , output]) => {
1469
1581
  this.citationTexts.set(id, output);
1470
1582
  });
@@ -1491,50 +1603,72 @@ export class JATSExporter {
1491
1603
  return mathml;
1492
1604
  }
1493
1605
  }
1494
- appendModelsToAuthorNotes(authorNotesEl, authorNotesNode) {
1495
- const contributorsNodes = findChildrenByType(this.manuscriptNode, schema.nodes.contributor).map((result) => result.node);
1496
- const usedCorrespondings = this.getUsedCorrespondings(contributorsNodes);
1497
- authorNotesNode.descendants((node) => {
1498
- switch (node.type) {
1499
- case schema.nodes.paragraph:
1500
- this.appendParagraphToElement(node, authorNotesEl);
1606
+ appendModelsToAuthorNotes(authorNotesEl, containedObjectIDs) {
1607
+ const contributors = this.models.filter(isContributor);
1608
+ const usedCorrespondings = this.getUsedCorrespondings(contributors);
1609
+ containedObjectIDs.forEach((id) => {
1610
+ const model = this.modelMap.get(id);
1611
+ if (!model) {
1612
+ return;
1613
+ }
1614
+ switch (model.objectType) {
1615
+ case ObjectTypes.ParagraphElement:
1616
+ this.appendParagraphToElement(model, authorNotesEl);
1501
1617
  break;
1502
- case schema.nodes.footnote:
1503
- this.appendFootnoteToElement(node, authorNotesEl);
1618
+ case ObjectTypes.Footnote:
1619
+ this.appendFootnoteToElement(model, authorNotesEl);
1504
1620
  break;
1505
- case schema.nodes.corresp:
1506
- if (usedCorrespondings.includes(node)) {
1507
- this.appendCorrespondingToElement(node, authorNotesEl);
1621
+ case ObjectTypes.Corresponding:
1622
+ if (usedCorrespondings.includes(model)) {
1623
+ this.appendCorrespondingToElement(model, authorNotesEl);
1508
1624
  }
1509
1625
  break;
1510
1626
  }
1511
- return false;
1512
1627
  });
1513
1628
  }
1514
1629
  getUsedCorrespondings(contributors) {
1515
1630
  return contributors
1516
- .flatMap((c) => { var _a; return (_a = c.attrs.corresp) !== null && _a !== void 0 ? _a : []; })
1517
- .map((corresp) => {
1518
- var _a;
1519
- return (_a = findChildrenByAttr(this.manuscriptNode, (attr) => attr.id === corresp.correspID)[0]) === null || _a === void 0 ? void 0 : _a.node;
1520
- })
1631
+ .flatMap((c) => { var _a; return (_a = c.corresp) !== null && _a !== void 0 ? _a : []; })
1632
+ .map((corresp) => this.modelMap.get(corresp.correspID))
1521
1633
  .filter((corresp) => !!corresp);
1522
1634
  }
1523
1635
  buildKeywords(articleMeta) {
1524
- const keywordGroups = findChildrenByType(this.manuscriptNode, schema.nodes.keyword_group).map((result) => result.node);
1525
- keywordGroups.forEach((group) => {
1636
+ const keywords = [...this.modelMap.values()].filter((model) => model.objectType === ObjectTypes.Keyword);
1637
+ const keywordGroups = new Map();
1638
+ keywords.forEach((keyword) => {
1639
+ const containedGroup = keyword.containedGroup || '';
1640
+ const group = keywordGroups.get(containedGroup);
1641
+ if (group) {
1642
+ group.push(keyword);
1643
+ }
1644
+ else {
1645
+ keywordGroups.set(containedGroup, [keyword]);
1646
+ }
1647
+ });
1648
+ for (const [groupID, keywords] of keywordGroups) {
1649
+ const keywordGroup = (this.modelMap.get(groupID) || {});
1526
1650
  const kwdGroup = this.document.createElement('kwd-group');
1527
- if (group.attrs.type) {
1528
- kwdGroup.setAttribute('kwd-group-type', group.attrs.type);
1651
+ if (keywordGroup.type) {
1652
+ kwdGroup.setAttribute('kwd-group-type', keywordGroup.type);
1653
+ }
1654
+ if (keywordGroup.label) {
1655
+ const label = this.document.createElement('label');
1656
+ label.textContent = keywordGroup.label;
1657
+ kwdGroup.appendChild(label);
1658
+ }
1659
+ if (keywordGroup.title) {
1660
+ const title = this.document.createElement('title');
1661
+ title.textContent = keywordGroup.title;
1662
+ kwdGroup.appendChild(title);
1529
1663
  }
1530
1664
  articleMeta.appendChild(kwdGroup);
1531
- group.content.forEach((keyword) => {
1665
+ for (const keyword of keywords) {
1532
1666
  const kwd = this.document.createElement('kwd');
1533
- kwd.textContent = keyword.textContent;
1667
+ kwd.textContent = keyword.name;
1534
1668
  kwdGroup.appendChild(kwd);
1535
- });
1669
+ }
1536
1670
  articleMeta.appendChild(kwdGroup);
1537
- });
1671
+ }
1538
1672
  }
1539
1673
  moveCoiStatementToAuthorNotes(back, front) {
1540
1674
  const fnGroups = back.querySelectorAll('fn-group');