@manuscripts/transform 3.0.21-LEAN-4076.1 → 3.0.21

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 (40) hide show
  1. package/dist/cjs/index.js +1 -2
  2. package/dist/cjs/jats/exporter/jats-exporter.js +7 -7
  3. package/dist/cjs/jats/importer/jats-dom-parser.js +972 -948
  4. package/dist/cjs/jats/importer/jats-transformations.js +9 -14
  5. package/dist/cjs/jats/importer/parse-jats-article.js +7 -5
  6. package/dist/cjs/lib/{section-group-type.js → section-categories.js} +4 -14
  7. package/dist/cjs/schema/index.js +0 -2
  8. package/dist/cjs/schema/migration/migration-scripts/3.0.21.js +25 -0
  9. package/dist/cjs/schema/migration/migration-scripts/index.js +2 -0
  10. package/dist/cjs/transformer/index.js +0 -1
  11. package/dist/cjs/version.js +1 -1
  12. package/dist/es/index.js +1 -2
  13. package/dist/es/jats/exporter/jats-exporter.js +8 -8
  14. package/dist/es/jats/importer/jats-dom-parser.js +970 -947
  15. package/dist/es/jats/importer/jats-transformations.js +9 -14
  16. package/dist/es/jats/importer/parse-jats-article.js +8 -6
  17. package/dist/es/lib/{section-group-type.js → section-categories.js} +2 -13
  18. package/dist/es/schema/index.js +0 -2
  19. package/dist/es/schema/migration/migration-scripts/3.0.21.js +23 -0
  20. package/dist/es/schema/migration/migration-scripts/index.js +2 -0
  21. package/dist/es/transformer/index.js +0 -1
  22. package/dist/es/version.js +1 -1
  23. package/dist/types/index.d.ts +1 -2
  24. package/dist/types/jats/importer/jats-dom-parser.d.ts +24 -9
  25. package/dist/types/jats/importer/jats-transformations.d.ts +2 -1
  26. package/dist/types/jats/importer/parse-jats-article.d.ts +2 -2
  27. package/dist/types/lib/{section-group-type.d.ts → section-categories.d.ts} +3 -9
  28. package/dist/types/schema/index.d.ts +0 -2
  29. package/dist/types/schema/migration/migration-scripts/3.0.21.d.ts +9 -0
  30. package/dist/types/schema/migration/migration-scripts/index.d.ts +2 -1
  31. package/dist/types/schema/types.d.ts +21 -1
  32. package/dist/types/transformer/index.d.ts +0 -1
  33. package/dist/types/version.d.ts +1 -1
  34. package/package.json +1 -1
  35. package/dist/cjs/lib/table-cell-styles.js +0 -52
  36. package/dist/cjs/transformer/section-category.js +0 -263
  37. package/dist/es/lib/table-cell-styles.js +0 -47
  38. package/dist/es/transformer/section-category.js +0 -249
  39. package/dist/types/lib/table-cell-styles.d.ts +0 -27
  40. package/dist/types/transformer/section-category.d.ts +0 -31
@@ -17,971 +17,994 @@ import { buildBibliographicDate, buildBibliographicName, buildContribution, Obje
17
17
  import mime from 'mime';
18
18
  import { DOMParser, Fragment } from 'prosemirror-model';
19
19
  import { dateToTimestamp, getTrimmedTextContent } from '../../lib/utils';
20
- import { schema, } from '../../schema';
21
- import { chooseSectionCategory } from '../../transformer';
22
20
  import { DEFAULT_PROFILE_ID } from './jats-comments';
23
21
  import { htmlFromJatsNode } from './jats-parser-utils';
24
- const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';
25
- const chooseContentType = (graphicNode) => {
26
- if (graphicNode) {
27
- const mimetype = graphicNode.getAttribute('mimetype');
28
- const subtype = graphicNode.getAttribute('mime-subtype');
29
- if (mimetype && subtype) {
30
- return [mimetype, subtype].join('/');
31
- }
32
- const href = graphicNode.getAttributeNS(XLINK_NAMESPACE, 'href');
33
- if (href) {
34
- return mime.getType(href) || undefined;
35
- }
36
- }
37
- };
38
- const parsePriority = (priority) => {
39
- if (!priority) {
40
- return undefined;
41
- }
42
- return parseInt(priority);
43
- };
44
- const getEquationContent = (p) => {
45
- var _a;
46
- const element = p;
47
- const id = element.getAttribute('id');
48
- const container = (_a = element.querySelector('alternatives')) !== null && _a !== void 0 ? _a : element;
49
- let contents = '';
50
- let format = '';
51
- for (const child of container.childNodes) {
52
- const nodeName = child.nodeName.replace(/^[a-z]:/, '');
53
- switch (nodeName) {
54
- case 'tex-math':
55
- contents = child.textContent;
56
- format = 'tex';
57
- break;
58
- case 'mml:math':
59
- contents = child.outerHTML;
60
- format = 'mathml';
61
- break;
62
- }
63
- }
64
- return { id, format, contents };
65
- };
66
- const parseDates = (historyNode) => {
67
- if (!historyNode) {
68
- return undefined;
69
- }
70
- const history = {};
71
- for (const date of historyNode.children) {
72
- const dateType = date.getAttribute('date-type');
73
- switch (dateType) {
74
- case 'received': {
75
- history.receiveDate = dateToTimestamp(date);
76
- break;
77
- }
78
- case 'rev-recd': {
79
- history.revisionReceiveDate = dateToTimestamp(date);
80
- break;
22
+ export class JATSDOMParser {
23
+ constructor(sectionCategories, schema) {
24
+ this.sectionCategories = sectionCategories;
25
+ this.schema = schema;
26
+ this.XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';
27
+ this.chooseContentType = (graphicNode) => {
28
+ if (graphicNode) {
29
+ const mimetype = graphicNode.getAttribute('mimetype');
30
+ const subtype = graphicNode.getAttribute('mime-subtype');
31
+ if (mimetype && subtype) {
32
+ return [mimetype, subtype].join('/');
33
+ }
34
+ const href = graphicNode.getAttributeNS(this.XLINK_NAMESPACE, 'href');
35
+ if (href) {
36
+ return mime.getType(href) || undefined;
37
+ }
81
38
  }
82
- case 'accepted': {
83
- history.acceptanceDate = dateToTimestamp(date);
84
- break;
39
+ };
40
+ this.parsePriority = (priority) => {
41
+ if (!priority) {
42
+ return undefined;
85
43
  }
86
- case 'rev-request': {
87
- history.revisionRequestDate = dateToTimestamp(date);
88
- break;
44
+ return parseInt(priority);
45
+ };
46
+ this.getEquationContent = (p) => {
47
+ var _a;
48
+ const element = p;
49
+ const id = element.getAttribute('id');
50
+ const container = (_a = element.querySelector('alternatives')) !== null && _a !== void 0 ? _a : element;
51
+ let contents = '';
52
+ let format = '';
53
+ for (const child of container.childNodes) {
54
+ const nodeName = child.nodeName.replace(/^[a-z]:/, '');
55
+ switch (nodeName) {
56
+ case 'tex-math':
57
+ contents = child.textContent;
58
+ format = 'tex';
59
+ break;
60
+ case 'mml:math':
61
+ contents = child.outerHTML;
62
+ format = 'mathml';
63
+ break;
64
+ }
89
65
  }
90
- case 'retracted': {
91
- history.retractionDate = dateToTimestamp(date);
92
- break;
66
+ return { id, format, contents };
67
+ };
68
+ this.parseDates = (historyNode) => {
69
+ if (!historyNode) {
70
+ return undefined;
93
71
  }
94
- case 'corrected': {
95
- history.correctionDate = dateToTimestamp(date);
96
- break;
72
+ const history = {};
73
+ for (const date of historyNode.children) {
74
+ const dateType = date.getAttribute('date-type');
75
+ switch (dateType) {
76
+ case 'received': {
77
+ history.receiveDate = dateToTimestamp(date);
78
+ break;
79
+ }
80
+ case 'rev-recd': {
81
+ history.revisionReceiveDate = dateToTimestamp(date);
82
+ break;
83
+ }
84
+ case 'accepted': {
85
+ history.acceptanceDate = dateToTimestamp(date);
86
+ break;
87
+ }
88
+ case 'rev-request': {
89
+ history.revisionRequestDate = dateToTimestamp(date);
90
+ break;
91
+ }
92
+ case 'retracted': {
93
+ history.retractionDate = dateToTimestamp(date);
94
+ break;
95
+ }
96
+ case 'corrected': {
97
+ history.correctionDate = dateToTimestamp(date);
98
+ break;
99
+ }
100
+ }
97
101
  }
98
- }
99
- }
100
- return history;
101
- };
102
- const getEmail = (element) => {
103
- var _a, _b;
104
- const email = element.querySelector('email');
105
- if (email) {
106
- return {
107
- href: (_a = email.getAttributeNS(XLINK_NAMESPACE, 'href')) !== null && _a !== void 0 ? _a : '',
108
- text: (_b = getTrimmedTextContent(email)) !== null && _b !== void 0 ? _b : '',
102
+ return history;
109
103
  };
110
- }
111
- };
112
- const getInstitutionDetails = (element) => {
113
- let department = '';
114
- let institution = '';
115
- for (const node of element.querySelectorAll('institution')) {
116
- const content = getTrimmedTextContent(node);
117
- if (!content) {
118
- continue;
119
- }
120
- const type = node.getAttribute('content-type');
121
- if (type === 'dept') {
122
- department = content;
123
- }
124
- else {
125
- institution = content;
126
- }
127
- }
128
- return { department, institution };
129
- };
130
- const getAddressLine = (element, index) => {
131
- return getTrimmedTextContent(element, `addr-line:nth-of-type(${index})`) || '';
132
- };
133
- const getHTMLContent = (node, querySelector) => {
134
- return htmlFromJatsNode(node.querySelector(querySelector));
135
- };
136
- const chooseBibliographyItemType = (publicationType) => {
137
- switch (publicationType) {
138
- case 'book':
139
- case 'thesis':
140
- return publicationType;
141
- case 'journal':
142
- default:
143
- return 'article-journal';
144
- }
145
- };
146
- const parseRef = (element) => {
147
- const publicationType = element.getAttribute('publication-type');
148
- const authorNodes = [
149
- ...element.querySelectorAll('person-group[person-group-type="author"] > *'),
150
- ];
151
- const id = element.id;
152
- const attrs = {
153
- id,
154
- type: chooseBibliographyItemType(publicationType),
155
- };
156
- const title = getHTMLContent(element, 'article-title');
157
- if (title) {
158
- attrs.title = title;
159
- }
160
- const mixedCitation = element.querySelector('mixed-citation');
161
- if (authorNodes.length <= 0) {
162
- mixedCitation === null || mixedCitation === void 0 ? void 0 : mixedCitation.childNodes.forEach((item) => {
104
+ this.getEmail = (element) => {
163
105
  var _a, _b;
164
- if (item.nodeType === Node.TEXT_NODE &&
165
- ((_a = item.textContent) === null || _a === void 0 ? void 0 : _a.match(/[A-Za-z]+/g))) {
166
- attrs.literal = (_b = getTrimmedTextContent(mixedCitation)) !== null && _b !== void 0 ? _b : '';
167
- return attrs;
106
+ const email = element.querySelector('email');
107
+ if (email) {
108
+ return {
109
+ href: (_a = email.getAttributeNS(this.XLINK_NAMESPACE, 'href')) !== null && _a !== void 0 ? _a : '',
110
+ text: (_b = getTrimmedTextContent(email)) !== null && _b !== void 0 ? _b : '',
111
+ };
168
112
  }
169
- });
170
- }
171
- const source = getHTMLContent(element, 'source');
172
- if (source) {
173
- attrs.containerTitle = source;
174
- }
175
- const volume = getTrimmedTextContent(element, 'volume');
176
- if (volume) {
177
- attrs.volume = volume;
178
- }
179
- const issue = getTrimmedTextContent(element, 'issue');
180
- if (issue) {
181
- attrs.issue = issue;
182
- }
183
- const supplement = getTrimmedTextContent(element, 'supplement');
184
- if (supplement) {
185
- attrs.supplement = supplement;
186
- }
187
- const fpage = getTrimmedTextContent(element, 'fpage');
188
- const lpage = getTrimmedTextContent(element, 'lpage');
189
- if (fpage) {
190
- attrs.page = lpage ? `${fpage}-${lpage}` : fpage;
191
- }
192
- const year = getTrimmedTextContent(element, 'year');
193
- if (year) {
194
- attrs.issued = buildBibliographicDate({
195
- 'date-parts': [[year]],
196
- });
197
- }
198
- const doi = getTrimmedTextContent(element, 'pub-id[pub-id-type="doi"]');
199
- if (doi) {
200
- attrs.doi = doi;
201
- }
202
- const authors = [];
203
- authorNodes.forEach((authorNode) => {
204
- const name = buildBibliographicName({});
205
- const given = getTrimmedTextContent(authorNode, 'given-names');
206
- if (given) {
207
- name.given = given;
208
- }
209
- const family = getTrimmedTextContent(authorNode, 'surname');
210
- if (family) {
211
- name.family = family;
212
- }
213
- if (authorNode.nodeName === 'collab') {
214
- name.literal = getTrimmedTextContent(authorNode);
215
- }
216
- authors.push(name);
217
- });
218
- if (authors.length) {
219
- attrs.author = authors;
220
- }
221
- return attrs;
222
- };
223
- const marks = [
224
- {
225
- tag: 'bold',
226
- mark: 'bold',
227
- },
228
- {
229
- tag: 'code',
230
- mark: 'code',
231
- },
232
- {
233
- tag: 'italic',
234
- mark: 'italic',
235
- },
236
- {
237
- tag: 'sc',
238
- mark: 'smallcaps',
239
- },
240
- {
241
- tag: 'strike',
242
- mark: 'strikethrough',
243
- },
244
- {
245
- tag: 'styled-content',
246
- mark: 'styled',
247
- getAttrs: (node) => ({
248
- style: node.getAttribute('style'),
249
- }),
250
- },
251
- {
252
- tag: 'sub',
253
- mark: 'subscript',
254
- },
255
- {
256
- tag: 'sup',
257
- mark: 'superscript',
258
- },
259
- {
260
- tag: 'underline',
261
- mark: 'underline',
262
- },
263
- ];
264
- const nodes = [
265
- {
266
- tag: 'article',
267
- node: 'manuscript',
268
- getAttrs: (node) => {
269
- var _a, _b;
270
- const element = node;
271
- const doi = element.querySelector('front > article-meta > article-id[pub-id-type="doi"]');
272
- const history = element.querySelector('history');
273
- const dates = parseDates(history);
274
- return Object.assign({ doi: getTrimmedTextContent(doi), articleType: (_a = element.getAttribute('article-type')) !== null && _a !== void 0 ? _a : '', primaryLanguageCode: (_b = element.getAttribute('lang')) !== null && _b !== void 0 ? _b : '' }, dates);
275
- },
276
- },
277
- {
278
- tag: 'article-title',
279
- node: 'title',
280
- getAttrs: (node) => {
281
- const element = node;
282
- return {
283
- id: element.getAttribute('id'),
284
- };
285
- },
286
- },
287
- {
288
- tag: 'highlight-marker',
289
- node: 'highlight_marker',
290
- getAttrs: (node) => {
291
- const element = node;
292
- return {
293
- id: element.id,
294
- position: element.getAttribute('position'),
295
- };
296
- },
297
- },
298
- {
299
- tag: 'comment',
300
- node: 'comment',
301
- getAttrs: (node) => {
302
- const element = node;
303
- return {
304
- id: element.getAttribute('id'),
305
- target: element.getAttribute('target-id'),
306
- contents: getTrimmedTextContent(element),
307
- contributions: [buildContribution(DEFAULT_PROFILE_ID)],
308
- };
309
- },
310
- },
311
- {
312
- tag: 'author-notes',
313
- node: 'author_notes',
314
- getAttrs: (node) => {
315
- const element = node;
316
- return {
317
- id: element.getAttribute('id'),
318
- };
319
- },
320
- },
321
- {
322
- tag: 'funding-group',
323
- node: 'awards',
324
- },
325
- {
326
- tag: 'award-group',
327
- node: 'award',
328
- getAttrs: (node) => {
329
- const element = node;
330
- return {
331
- id: element.getAttribute('id'),
332
- recipient: getTrimmedTextContent(element, 'principal-award-recipient'),
333
- code: Array.from(element.querySelectorAll('award-id'))
334
- .map((awardID) => getTrimmedTextContent(awardID))
335
- .reduce((acc, text) => (acc ? `${acc};${text}` : text), ''),
336
- source: getTrimmedTextContent(element, 'funding-source'),
337
- };
338
- },
339
- },
340
- {
341
- tag: 'fn:not([fn-type])',
342
- node: 'footnote',
343
- context: 'author_notes/',
344
- getAttrs: (node) => {
345
- const element = node;
346
- return {
347
- id: element.getAttribute('id'),
348
- kind: 'footnote',
349
- };
350
- },
351
- },
352
- {
353
- tag: 'corresp',
354
- node: 'corresp',
355
- getAttrs: (node) => {
356
- const element = node;
357
- const label = element.querySelector('label');
358
- if (label) {
359
- label.remove();
360
- }
361
- return {
362
- id: element.getAttribute('id'),
363
- label: getTrimmedTextContent(label),
364
- };
365
- },
366
- getContent: (node) => {
367
- const element = node;
368
- return Fragment.from(schema.text(getTrimmedTextContent(element) || ''));
369
- },
370
- },
371
- {
372
- tag: 'contrib[contrib-type="author"]',
373
- node: 'contributor',
374
- getAttrs: (node) => {
375
- const element = node;
376
- const footnote = [];
377
- const affiliations = [];
378
- const corresp = [];
379
- const xrefs = element.querySelectorAll('xref');
380
- for (const xref of xrefs) {
381
- const rid = xref.getAttribute('rid');
382
- const type = xref.getAttribute('ref-type');
383
- if (!rid) {
113
+ };
114
+ this.getInstitutionDetails = (element) => {
115
+ let department = '';
116
+ let institution = '';
117
+ for (const node of element.querySelectorAll('institution')) {
118
+ const content = getTrimmedTextContent(node);
119
+ if (!content) {
384
120
  continue;
385
121
  }
386
- switch (type) {
387
- case 'fn':
388
- footnote.push({
389
- noteID: rid,
390
- noteLabel: getTrimmedTextContent(xref) || '',
391
- });
392
- break;
393
- case 'corresp':
394
- corresp.push({
395
- correspID: rid,
396
- correspLabel: getTrimmedTextContent(xref) || '',
397
- });
398
- break;
399
- case 'aff':
400
- affiliations.push(rid);
401
- break;
122
+ const type = node.getAttribute('content-type');
123
+ if (type === 'dept') {
124
+ department = content;
125
+ }
126
+ else {
127
+ institution = content;
402
128
  }
403
129
  }
404
- return {
405
- id: element.getAttribute('id'),
406
- role: 'author',
407
- affiliations,
408
- corresp,
409
- footnote,
410
- isCorresponding: element.getAttribute('corresp')
411
- ? element.getAttribute('corresp') === 'yes'
412
- : undefined,
413
- bibliographicName: {
414
- given: getTrimmedTextContent(element, 'name > given-names'),
415
- family: getTrimmedTextContent(element, 'name > surname'),
416
- ObjectType: ObjectTypes.BibliographicName,
417
- },
418
- ORCIDIdentifier: getTrimmedTextContent(element, 'contrib-id[contrib-id-type="orcid"]'),
419
- priority: parsePriority(element.getAttribute('priority')),
420
- };
421
- },
422
- getContent: () => {
423
- return Fragment.from(schema.text('_'));
424
- },
425
- },
426
- {
427
- tag: 'affiliations',
428
- node: 'affiliations',
429
- },
430
- {
431
- tag: 'aff',
432
- node: 'affiliation',
433
- context: 'affiliations/',
434
- getAttrs: (node) => {
435
- var _a, _b;
436
- const element = node;
437
- const { department, institution } = getInstitutionDetails(element);
438
- return {
439
- id: element.getAttribute('id'),
440
- institution: institution !== null && institution !== void 0 ? institution : '',
441
- department: department !== null && department !== void 0 ? department : '',
442
- addressLine1: getAddressLine(element, 1),
443
- addressLine2: getAddressLine(element, 2),
444
- addressLine3: getAddressLine(element, 3),
445
- postCode: (_a = getTrimmedTextContent(element, 'postal-code')) !== null && _a !== void 0 ? _a : '',
446
- country: (_b = getTrimmedTextContent(element, 'country')) !== null && _b !== void 0 ? _b : '',
447
- email: getEmail(element),
448
- priority: parsePriority(element.getAttribute('priority')),
449
- };
450
- },
451
- getContent: () => {
452
- return Fragment.from(schema.text('_'));
453
- },
454
- },
455
- {
456
- tag: 'attrib',
457
- node: 'attribution',
458
- },
459
- {
460
- tag: 'back',
461
- ignore: true,
462
- },
463
- {
464
- tag: 'history',
465
- ignore: true,
466
- },
467
- {
468
- tag: 'break',
469
- node: 'hard_break',
470
- },
471
- {
472
- tag: 'caption',
473
- node: 'figcaption',
474
- context: 'figure/',
475
- },
476
- {
477
- tag: 'caption',
478
- node: 'figcaption',
479
- context: 'figure_element/',
480
- getContent: (node, schema) => {
481
- const element = node;
482
- const content = [];
483
- const title = element.querySelector('title');
130
+ return { department, institution };
131
+ };
132
+ this.getAddressLine = (element, index) => {
133
+ return (getTrimmedTextContent(element, `addr-line:nth-of-type(${index})`) || '');
134
+ };
135
+ this.getHTMLContent = (node, querySelector) => {
136
+ return htmlFromJatsNode(node.querySelector(querySelector));
137
+ };
138
+ this.chooseBibliographyItemType = (publicationType) => {
139
+ switch (publicationType) {
140
+ case 'book':
141
+ case 'thesis':
142
+ return publicationType;
143
+ case 'journal':
144
+ default:
145
+ return 'article-journal';
146
+ }
147
+ };
148
+ this.parseRef = (element) => {
149
+ const publicationType = element.getAttribute('publication-type');
150
+ const authorNodes = [
151
+ ...element.querySelectorAll('person-group[person-group-type="author"] > *'),
152
+ ];
153
+ const id = element.id;
154
+ const attrs = {
155
+ id,
156
+ type: this.chooseBibliographyItemType(publicationType),
157
+ };
158
+ const title = this.getHTMLContent(element, 'article-title');
484
159
  if (title) {
485
- const captionTitle = schema.nodes.caption_title.create();
486
- content.push(jatsDOMParser.parse(title, { topNode: captionTitle }));
160
+ attrs.title = title;
487
161
  }
488
- const paragraphs = element.querySelectorAll('p');
489
- if (paragraphs.length) {
490
- const figcaption = schema.nodes.caption.create();
491
- for (const paragraph of paragraphs) {
492
- content.push(jatsDOMParser.parse(paragraph, { topNode: figcaption }));
493
- }
162
+ const mixedCitation = element.querySelector('mixed-citation');
163
+ if (authorNodes.length <= 0) {
164
+ mixedCitation === null || mixedCitation === void 0 ? void 0 : mixedCitation.childNodes.forEach((item) => {
165
+ var _a, _b;
166
+ if (item.nodeType === Node.TEXT_NODE &&
167
+ ((_a = item.textContent) === null || _a === void 0 ? void 0 : _a.match(/[A-Za-z]+/g))) {
168
+ attrs.literal = (_b = getTrimmedTextContent(mixedCitation)) !== null && _b !== void 0 ? _b : '';
169
+ return attrs;
170
+ }
171
+ });
494
172
  }
495
- return Fragment.from(content);
496
- },
497
- },
498
- {
499
- tag: 'caption',
500
- node: 'figcaption',
501
- context: 'table_element/',
502
- },
503
- {
504
- tag: 'caption',
505
- node: 'figcaption',
506
- context: 'box_element/',
507
- getAttrs: (node) => {
508
- const element = node;
509
- return {
510
- id: element.getAttribute('id'),
511
- };
512
- },
513
- },
514
- {
515
- tag: 'code',
516
- node: 'listing',
517
- context: 'listing_element/',
518
- getAttrs: (node) => {
519
- var _a;
520
- const element = node;
521
- return {
522
- id: element.getAttribute('id'),
523
- language: (_a = element.getAttribute('language')) !== null && _a !== void 0 ? _a : '',
524
- contents: getTrimmedTextContent(element),
525
- };
526
- },
527
- },
528
- {
529
- tag: 'inline-formula',
530
- node: 'inline_equation',
531
- getAttrs: (node) => {
532
- const element = node;
533
- return getEquationContent(element);
534
- },
535
- },
536
- {
537
- tag: 'disp-formula',
538
- node: 'equation_element',
539
- getAttrs: (node) => {
540
- var _a;
541
- const element = node;
542
- return {
543
- id: element.getAttribute('id'),
544
- label: (_a = getTrimmedTextContent(element, 'label')) !== null && _a !== void 0 ? _a : '',
545
- };
546
- },
547
- getContent: (node, schema) => {
548
- const element = node;
549
- const attrs = getEquationContent(element);
550
- return Fragment.from([
551
- schema.nodes.equation.createChecked(Object.assign({}, attrs)),
552
- ]);
553
- },
554
- },
555
- {
556
- tag: 'disp-quote[content-type=quote]',
557
- node: 'blockquote_element',
558
- getAttrs: (node) => {
559
- const element = node;
560
- return {
561
- id: element.getAttribute('id'),
562
- };
563
- },
564
- },
565
- {
566
- tag: 'disp-quote[content-type=pullquote]',
567
- node: 'pullquote_element',
568
- getAttrs: (node) => {
569
- const element = node;
570
- return {
571
- id: element.getAttribute('id'),
572
- };
573
- },
574
- },
575
- {
576
- tag: 'ext-link',
577
- node: 'link',
578
- getAttrs: (node) => {
579
- const element = node;
580
- return {
581
- href: element.getAttributeNS(XLINK_NAMESPACE, 'href') || '',
582
- title: element.getAttributeNS(XLINK_NAMESPACE, 'title') || '',
583
- };
584
- },
585
- },
586
- {
587
- tag: 'fig[fig-type=equation]',
588
- node: 'equation_element',
589
- getAttrs: (node) => {
590
- const element = node;
591
- return {
592
- id: element.getAttribute('id'),
593
- };
594
- },
595
- },
596
- {
597
- tag: 'fig[fig-type=listing]',
598
- node: 'listing_element',
599
- getAttrs: (node) => {
600
- const element = node;
601
- return {
602
- id: element.getAttribute('id'),
603
- };
604
- },
605
- },
606
- {
607
- tag: 'graphic[specific-use=MISSING]',
608
- node: 'missing_figure',
609
- context: 'figure_element/',
610
- getAttrs: (node) => {
611
- const element = node;
612
- return {
613
- id: element.getAttribute('id'),
614
- };
615
- },
616
- },
617
- {
618
- tag: 'graphic',
619
- node: 'figure',
620
- context: 'figure_element/',
621
- getAttrs: (node) => {
622
- const element = node;
623
- const position = element.getAttribute('position');
624
- const src = element.getAttributeNS(XLINK_NAMESPACE, 'href');
625
- return {
626
- id: element.getAttribute('id'),
627
- contentType: chooseContentType(element || undefined) || '',
628
- src,
629
- position,
630
- };
631
- },
632
- },
633
- {
634
- tag: 'fig',
635
- node: 'figure_element',
636
- getAttrs: (node) => {
637
- var _a, _b;
638
- const element = node;
639
- const labelNode = element.querySelector('label');
640
- if (labelNode) {
641
- element.removeChild(labelNode);
173
+ const source = this.getHTMLContent(element, 'source');
174
+ if (source) {
175
+ attrs.containerTitle = source;
642
176
  }
643
- const attrib = element.querySelector('attrib');
644
- const attribution = attrib
645
- ? {
646
- literal: (_a = getTrimmedTextContent(attrib)) !== null && _a !== void 0 ? _a : '',
647
- }
648
- : undefined;
649
- return {
650
- id: element.getAttribute('id'),
651
- label: (_b = getTrimmedTextContent(labelNode)) !== null && _b !== void 0 ? _b : '',
652
- attribution,
653
- type: element.getAttribute('fig-type'),
654
- };
655
- },
656
- },
657
- {
658
- tag: 'fn-group',
659
- node: 'footnotes_element',
660
- context: 'footnotes_section/|table_element_footer/',
661
- getAttrs: (node) => {
662
- const element = node;
663
- return {
664
- id: element.getAttribute('id'),
665
- kind: 'footnote',
666
- };
667
- },
668
- },
669
- {
670
- tag: 'table-wrap-foot',
671
- node: 'table_element_footer',
672
- getAttrs: (node) => {
673
- const element = node;
674
- return {
675
- id: element.getAttribute('id'),
676
- };
677
- },
678
- },
679
- {
680
- tag: 'general-table-footnote',
681
- node: 'general_table_footnote',
682
- context: 'table_element_footer/',
683
- getAttrs: (node) => {
684
- const element = node;
685
- return {
686
- id: element.getAttribute('id'),
687
- };
688
- },
689
- getContent: (node) => {
690
- const paragraphs = [];
691
- node.childNodes.forEach((p) => {
692
- const paragraph = schema.nodes.paragraph.create();
693
- const content = jatsDOMParser.parse(p, {
694
- topNode: paragraph,
177
+ const volume = getTrimmedTextContent(element, 'volume');
178
+ if (volume) {
179
+ attrs.volume = volume;
180
+ }
181
+ const issue = getTrimmedTextContent(element, 'issue');
182
+ if (issue) {
183
+ attrs.issue = issue;
184
+ }
185
+ const supplement = getTrimmedTextContent(element, 'supplement');
186
+ if (supplement) {
187
+ attrs.supplement = supplement;
188
+ }
189
+ const fpage = getTrimmedTextContent(element, 'fpage');
190
+ const lpage = getTrimmedTextContent(element, 'lpage');
191
+ if (fpage) {
192
+ attrs.page = lpage ? `${fpage}-${lpage}` : fpage;
193
+ }
194
+ const year = getTrimmedTextContent(element, 'year');
195
+ if (year) {
196
+ attrs.issued = buildBibliographicDate({
197
+ 'date-parts': [[year]],
695
198
  });
696
- paragraphs.push(content);
199
+ }
200
+ const doi = getTrimmedTextContent(element, 'pub-id[pub-id-type="doi"]');
201
+ if (doi) {
202
+ attrs.doi = doi;
203
+ }
204
+ const authors = [];
205
+ authorNodes.forEach((authorNode) => {
206
+ const name = buildBibliographicName({});
207
+ const given = getTrimmedTextContent(authorNode, 'given-names');
208
+ if (given) {
209
+ name.given = given;
210
+ }
211
+ const family = getTrimmedTextContent(authorNode, 'surname');
212
+ if (family) {
213
+ name.family = family;
214
+ }
215
+ if (authorNode.nodeName === 'collab') {
216
+ name.literal = getTrimmedTextContent(authorNode);
217
+ }
218
+ authors.push(name);
697
219
  });
698
- return Fragment.from([...paragraphs]);
699
- },
700
- },
701
- {
702
- tag: 'fn',
703
- node: 'footnote',
704
- context: 'footnotes_element/|table_element_footer/',
705
- getAttrs: (node) => {
706
- const element = node;
707
- return {
708
- id: element.getAttribute('id'),
709
- kind: 'footnote',
710
- };
711
- },
712
- },
713
- {
714
- tag: 'front',
715
- ignore: true,
716
- },
717
- {
718
- tag: 'list',
719
- node: 'list',
720
- getAttrs: (node) => {
721
- const element = node;
722
- return {
723
- id: element.getAttribute('id'),
724
- listStyleType: element.getAttribute('list-type'),
725
- };
726
- },
727
- },
728
- {
729
- tag: 'list-item',
730
- node: 'list_item',
731
- },
732
- {
733
- tag: 'p',
734
- node: 'paragraph',
735
- context: 'section/',
736
- getAttrs: (node) => {
737
- const element = node;
738
- return {
739
- id: element.getAttribute('id'),
740
- };
741
- },
742
- },
743
- {
744
- tag: 'p',
745
- node: 'paragraph',
746
- },
747
- {
748
- tag: 'sec[sec-type="endnotes"]',
749
- node: 'footnotes_section',
750
- getAttrs: (node) => {
751
- const element = node;
752
- return {
753
- id: element.getAttribute('id'),
754
- };
755
- },
756
- },
757
- {
758
- tag: 'sec[sec-type="keywords"]',
759
- node: 'keywords',
760
- },
761
- {
762
- tag: 'sec[sec-type="supplementary-material"]',
763
- node: 'supplements',
764
- },
765
- {
766
- tag: 'supplementary-material',
767
- node: 'supplement',
768
- getAttrs: (node) => {
769
- const element = node;
770
- return {
771
- id: element.getAttribute('id'),
772
- href: element.getAttributeNS(XLINK_NAMESPACE, 'href'),
773
- mimeType: element.getAttribute('mimetype'),
774
- mimeSubType: element.getAttribute('mime-subtype'),
775
- title: getTrimmedTextContent(element, 'title'),
776
- };
777
- },
778
- },
779
- {
780
- tag: 'sec[sec-type="abstracts"]',
781
- node: 'abstracts',
782
- },
783
- {
784
- tag: 'sec[sec-type="body"]',
785
- node: 'body',
786
- },
787
- {
788
- tag: 'sec[sec-type="backmatter"]',
789
- node: 'backmatter',
790
- },
791
- {
792
- tag: 'sec[sec-type="box-element"]',
793
- node: 'box_element',
794
- getAttrs: (node) => {
795
- const element = node;
796
- return {
797
- id: element.getAttribute('id'),
798
- label: getTrimmedTextContent(element, 'label'),
799
- };
800
- },
801
- },
802
- {
803
- tag: 'sec[sec-type="bibliography"]',
804
- node: 'bibliography_section',
805
- },
806
- {
807
- tag: 'ref-list',
808
- context: 'bibliography_section/',
809
- node: 'bibliography_element',
810
- },
811
- {
812
- tag: 'ref',
813
- context: 'bibliography_element/',
814
- node: 'bibliography_item',
815
- getAttrs: (node) => parseRef(node),
816
- },
817
- {
818
- tag: 'sec[sec-type="abstract-graphical"]',
819
- node: 'graphical_abstract_section',
820
- },
821
- {
822
- tag: 'sec',
823
- node: 'section',
824
- getAttrs: (node) => {
825
- var _a, _b;
826
- const element = node;
827
- const grandParentNodeName = (_b = (_a = element.parentNode) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.nodeName.toLowerCase();
828
- if (grandParentNodeName && grandParentNodeName !== 'body') {
829
- element.setAttribute('sec-type', 'subsection');
220
+ if (authors.length) {
221
+ attrs.author = authors;
830
222
  }
831
- return {
832
- id: element.getAttribute('id'),
833
- category: chooseSectionCategory(element),
834
- };
835
- },
836
- },
837
- {
838
- tag: 'kwd-group-list',
839
- context: 'keywords/',
840
- node: 'keywords_element',
841
- },
842
- {
843
- tag: 'kwd-group',
844
- context: 'keywords_element/',
845
- node: 'keyword_group',
846
- getAttrs: (node) => {
847
- const element = node;
848
- return {
849
- id: element.id,
850
- type: element.getAttribute('kwd-group-type'),
851
- };
852
- },
853
- },
854
- {
855
- tag: 'kwd',
856
- context: 'keyword_group//',
857
- node: 'keyword',
858
- },
859
- {
860
- tag: 'label',
861
- context: 'box_element/',
862
- ignore: true,
863
- },
864
- {
865
- tag: 'boxed-text',
866
- ignore: true,
867
- },
868
- {
869
- tag: 'label',
870
- context: 'section/',
871
- node: 'section_label',
872
- },
873
- {
874
- tag: 'label',
875
- context: 'table_element/',
876
- ignore: true,
877
- },
878
- {
879
- tag: 'label',
880
- context: 'figure/',
881
- ignore: true,
882
- },
883
- {
884
- tag: 'table',
885
- node: 'table',
886
- getAttrs: (node) => {
887
- const element = node;
888
- return {
889
- id: element.getAttribute('id'),
890
- };
891
- },
892
- },
893
- {
894
- tag: 'table-wrap',
895
- node: 'table_element',
896
- getAttrs: (node) => {
897
- const element = node;
898
- return {
899
- id: element.getAttribute('id'),
900
- };
901
- },
902
- },
903
- {
904
- tag: 'title',
905
- node: 'section_title',
906
- context: 'section/|footnotes_section/|bibliography_section/|keywords/|supplements/|author_notes/|graphical_abstract_section/',
907
- },
908
- {
909
- tag: 'title',
910
- node: 'caption_title',
911
- context: 'figcaption/',
912
- },
913
- {
914
- tag: 'tr',
915
- node: 'table_row',
916
- },
917
- {
918
- tag: 'td',
919
- node: 'table_cell',
920
- getAttrs: (node) => {
921
- const element = node;
922
- const colspan = parseInt(element.getAttribute('colspan') || '1');
923
- const rowspan = parseInt(element.getAttribute('rowspan') || '1');
924
- 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') });
925
- },
926
- },
927
- {
928
- tag: 'th',
929
- node: 'table_header',
930
- getAttrs: (node) => {
931
- const element = node;
932
- const colspan = parseInt(element.getAttribute('colspan') || '1');
933
- const rowspan = parseInt(element.getAttribute('rowspan') || '1');
934
- 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') });
935
- },
936
- },
937
- {
938
- tag: 'col',
939
- node: 'table_col',
940
- getAttrs: (node) => {
941
- const element = node;
942
- return {
943
- width: element.getAttribute('width'),
944
- };
945
- },
946
- },
947
- {
948
- tag: 'colgroup',
949
- node: 'table_colgroup',
950
- },
951
- {
952
- tag: 'xref[ref-type="bibr"]',
953
- node: 'citation',
954
- getAttrs: (node) => {
955
- var _a;
956
- const element = node;
957
- return {
958
- rids: ((_a = element.getAttribute('rid')) === null || _a === void 0 ? void 0 : _a.split(/\s+/)) || [],
959
- contents: getTrimmedTextContent(element),
960
- };
961
- },
962
- },
963
- {
964
- tag: 'xref[ref-type="fn"]',
965
- node: 'inline_footnote',
966
- getAttrs: (node) => {
967
- var _a;
968
- const element = node;
969
- return {
970
- rids: ((_a = element.getAttribute('rid')) === null || _a === void 0 ? void 0 : _a.split(/\s+/)) || [],
971
- };
972
- },
973
- },
974
- {
975
- tag: 'xref',
976
- node: 'cross_reference',
977
- getAttrs: (node) => {
978
- var _a;
979
- const element = node;
980
- return {
981
- rids: ((_a = element.getAttribute('rid')) === null || _a === void 0 ? void 0 : _a.split(/\s+/)) || [],
982
- label: getTrimmedTextContent(element),
983
- };
984
- },
985
- },
986
- ];
987
- export const jatsDOMParser = new DOMParser(schema, [...marks, ...nodes]);
223
+ return attrs;
224
+ };
225
+ this.nodes = [
226
+ {
227
+ tag: 'article',
228
+ node: 'manuscript',
229
+ getAttrs: (node) => {
230
+ var _a, _b;
231
+ const element = node;
232
+ const doi = element.querySelector('front > article-meta > article-id[pub-id-type="doi"]');
233
+ const history = element.querySelector('history');
234
+ const dates = this.parseDates(history);
235
+ return Object.assign({ doi: getTrimmedTextContent(doi), articleType: (_a = element.getAttribute('article-type')) !== null && _a !== void 0 ? _a : '', primaryLanguageCode: (_b = element.getAttribute('lang')) !== null && _b !== void 0 ? _b : '' }, dates);
236
+ },
237
+ },
238
+ {
239
+ tag: 'article-title',
240
+ node: 'title',
241
+ getAttrs: (node) => {
242
+ const element = node;
243
+ return {
244
+ id: element.getAttribute('id'),
245
+ };
246
+ },
247
+ },
248
+ {
249
+ tag: 'highlight-marker',
250
+ node: 'highlight_marker',
251
+ getAttrs: (node) => {
252
+ const element = node;
253
+ return {
254
+ id: element.id,
255
+ position: element.getAttribute('position'),
256
+ };
257
+ },
258
+ },
259
+ {
260
+ tag: 'comment',
261
+ node: 'comment',
262
+ getAttrs: (node) => {
263
+ const element = node;
264
+ return {
265
+ id: element.getAttribute('id'),
266
+ target: element.getAttribute('target-id'),
267
+ contents: getTrimmedTextContent(element),
268
+ contributions: [buildContribution(DEFAULT_PROFILE_ID)],
269
+ };
270
+ },
271
+ },
272
+ {
273
+ tag: 'author-notes',
274
+ node: 'author_notes',
275
+ getAttrs: (node) => {
276
+ const element = node;
277
+ return {
278
+ id: element.getAttribute('id'),
279
+ };
280
+ },
281
+ },
282
+ {
283
+ tag: 'funding-group',
284
+ node: 'awards',
285
+ },
286
+ {
287
+ tag: 'award-group',
288
+ node: 'award',
289
+ getAttrs: (node) => {
290
+ const element = node;
291
+ return {
292
+ id: element.getAttribute('id'),
293
+ recipient: getTrimmedTextContent(element, 'principal-award-recipient'),
294
+ code: Array.from(element.querySelectorAll('award-id'))
295
+ .map((awardID) => getTrimmedTextContent(awardID))
296
+ .reduce((acc, text) => (acc ? `${acc};${text}` : text), ''),
297
+ source: getTrimmedTextContent(element, 'funding-source'),
298
+ };
299
+ },
300
+ },
301
+ {
302
+ tag: 'fn:not([fn-type])',
303
+ node: 'footnote',
304
+ context: 'author_notes/',
305
+ getAttrs: (node) => {
306
+ const element = node;
307
+ return {
308
+ id: element.getAttribute('id'),
309
+ kind: 'footnote',
310
+ };
311
+ },
312
+ },
313
+ {
314
+ tag: 'corresp',
315
+ node: 'corresp',
316
+ getAttrs: (node) => {
317
+ const element = node;
318
+ const label = element.querySelector('label');
319
+ if (label) {
320
+ label.remove();
321
+ }
322
+ return {
323
+ id: element.getAttribute('id'),
324
+ label: getTrimmedTextContent(label),
325
+ };
326
+ },
327
+ getContent: (node) => {
328
+ const element = node;
329
+ return Fragment.from(this.schema.text(getTrimmedTextContent(element) || ''));
330
+ },
331
+ },
332
+ {
333
+ tag: 'contrib[contrib-type="author"]',
334
+ node: 'contributor',
335
+ getAttrs: (node) => {
336
+ const element = node;
337
+ const footnote = [];
338
+ const affiliations = [];
339
+ const corresp = [];
340
+ const xrefs = element.querySelectorAll('xref');
341
+ for (const xref of xrefs) {
342
+ const rid = xref.getAttribute('rid');
343
+ const type = xref.getAttribute('ref-type');
344
+ if (!rid) {
345
+ continue;
346
+ }
347
+ switch (type) {
348
+ case 'fn':
349
+ footnote.push({
350
+ noteID: rid,
351
+ noteLabel: getTrimmedTextContent(xref) || '',
352
+ });
353
+ break;
354
+ case 'corresp':
355
+ corresp.push({
356
+ correspID: rid,
357
+ correspLabel: getTrimmedTextContent(xref) || '',
358
+ });
359
+ break;
360
+ case 'aff':
361
+ affiliations.push(rid);
362
+ break;
363
+ }
364
+ }
365
+ return {
366
+ id: element.getAttribute('id'),
367
+ role: 'author',
368
+ affiliations,
369
+ corresp,
370
+ footnote,
371
+ isCorresponding: element.getAttribute('corresp')
372
+ ? element.getAttribute('corresp') === 'yes'
373
+ : undefined,
374
+ bibliographicName: {
375
+ given: getTrimmedTextContent(element, 'name > given-names'),
376
+ family: getTrimmedTextContent(element, 'name > surname'),
377
+ ObjectType: ObjectTypes.BibliographicName,
378
+ },
379
+ ORCIDIdentifier: getTrimmedTextContent(element, 'contrib-id[contrib-id-type="orcid"]'),
380
+ priority: this.parsePriority(element.getAttribute('priority')),
381
+ };
382
+ },
383
+ getContent: () => {
384
+ return Fragment.from(this.schema.text('_'));
385
+ },
386
+ },
387
+ {
388
+ tag: 'affiliations',
389
+ node: 'affiliations',
390
+ },
391
+ {
392
+ tag: 'aff',
393
+ node: 'affiliation',
394
+ context: 'affiliations/',
395
+ getAttrs: (node) => {
396
+ var _a, _b;
397
+ const element = node;
398
+ const { department, institution } = this.getInstitutionDetails(element);
399
+ return {
400
+ id: element.getAttribute('id'),
401
+ institution: institution !== null && institution !== void 0 ? institution : '',
402
+ department: department !== null && department !== void 0 ? department : '',
403
+ addressLine1: this.getAddressLine(element, 1),
404
+ addressLine2: this.getAddressLine(element, 2),
405
+ addressLine3: this.getAddressLine(element, 3),
406
+ postCode: (_a = getTrimmedTextContent(element, 'postal-code')) !== null && _a !== void 0 ? _a : '',
407
+ country: (_b = getTrimmedTextContent(element, 'country')) !== null && _b !== void 0 ? _b : '',
408
+ email: this.getEmail(element),
409
+ priority: this.parsePriority(element.getAttribute('priority')),
410
+ };
411
+ },
412
+ getContent: () => {
413
+ return Fragment.from(this.schema.text('_'));
414
+ },
415
+ },
416
+ {
417
+ tag: 'attrib',
418
+ node: 'attribution',
419
+ },
420
+ {
421
+ tag: 'back',
422
+ ignore: true,
423
+ },
424
+ {
425
+ tag: 'history',
426
+ ignore: true,
427
+ },
428
+ {
429
+ tag: 'break',
430
+ node: 'hard_break',
431
+ },
432
+ {
433
+ tag: 'caption',
434
+ node: 'figcaption',
435
+ context: 'figure/',
436
+ },
437
+ {
438
+ tag: 'caption',
439
+ node: 'figcaption',
440
+ context: 'figure_element/',
441
+ getContent: (node, schema) => {
442
+ const element = node;
443
+ const content = [];
444
+ const title = element.querySelector('title');
445
+ if (title) {
446
+ const captionTitle = schema.nodes.caption_title.create();
447
+ content.push(this.parse(title, { topNode: captionTitle }));
448
+ }
449
+ const paragraphs = element.querySelectorAll('p');
450
+ if (paragraphs.length) {
451
+ const figcaption = schema.nodes.caption.create();
452
+ for (const paragraph of paragraphs) {
453
+ content.push(this.parse(paragraph, { topNode: figcaption }));
454
+ }
455
+ }
456
+ return Fragment.from(content);
457
+ },
458
+ },
459
+ {
460
+ tag: 'caption',
461
+ node: 'figcaption',
462
+ context: 'table_element/',
463
+ },
464
+ {
465
+ tag: 'caption',
466
+ node: 'figcaption',
467
+ context: 'box_element/',
468
+ getAttrs: (node) => {
469
+ const element = node;
470
+ return {
471
+ id: element.getAttribute('id'),
472
+ };
473
+ },
474
+ },
475
+ {
476
+ tag: 'code',
477
+ node: 'listing',
478
+ context: 'listing_element/',
479
+ getAttrs: (node) => {
480
+ var _a;
481
+ const element = node;
482
+ return {
483
+ id: element.getAttribute('id'),
484
+ language: (_a = element.getAttribute('language')) !== null && _a !== void 0 ? _a : '',
485
+ contents: getTrimmedTextContent(element),
486
+ };
487
+ },
488
+ },
489
+ {
490
+ tag: 'inline-formula',
491
+ node: 'inline_equation',
492
+ getAttrs: (node) => {
493
+ const element = node;
494
+ return this.getEquationContent(element);
495
+ },
496
+ },
497
+ {
498
+ tag: 'disp-formula',
499
+ node: 'equation_element',
500
+ getAttrs: (node) => {
501
+ var _a;
502
+ const element = node;
503
+ return {
504
+ id: element.getAttribute('id'),
505
+ label: (_a = getTrimmedTextContent(element, 'label')) !== null && _a !== void 0 ? _a : '',
506
+ };
507
+ },
508
+ getContent: (node, schema) => {
509
+ const element = node;
510
+ const attrs = this.getEquationContent(element);
511
+ return Fragment.from([
512
+ schema.nodes.equation.createChecked(Object.assign({}, attrs)),
513
+ ]);
514
+ },
515
+ },
516
+ {
517
+ tag: 'disp-quote[content-type=quote]',
518
+ node: 'blockquote_element',
519
+ getAttrs: (node) => {
520
+ const element = node;
521
+ return {
522
+ id: element.getAttribute('id'),
523
+ };
524
+ },
525
+ },
526
+ {
527
+ tag: 'disp-quote[content-type=pullquote]',
528
+ node: 'pullquote_element',
529
+ getAttrs: (node) => {
530
+ const element = node;
531
+ return {
532
+ id: element.getAttribute('id'),
533
+ };
534
+ },
535
+ },
536
+ {
537
+ tag: 'ext-link',
538
+ node: 'link',
539
+ getAttrs: (node) => {
540
+ const element = node;
541
+ return {
542
+ href: element.getAttributeNS(this.XLINK_NAMESPACE, 'href') || '',
543
+ title: element.getAttributeNS(this.XLINK_NAMESPACE, 'title') || '',
544
+ };
545
+ },
546
+ },
547
+ {
548
+ tag: 'fig[fig-type=equation]',
549
+ node: 'equation_element',
550
+ getAttrs: (node) => {
551
+ const element = node;
552
+ return {
553
+ id: element.getAttribute('id'),
554
+ };
555
+ },
556
+ },
557
+ {
558
+ tag: 'fig[fig-type=listing]',
559
+ node: 'listing_element',
560
+ getAttrs: (node) => {
561
+ const element = node;
562
+ return {
563
+ id: element.getAttribute('id'),
564
+ };
565
+ },
566
+ },
567
+ {
568
+ tag: 'graphic[specific-use=MISSING]',
569
+ node: 'missing_figure',
570
+ context: 'figure_element/',
571
+ getAttrs: (node) => {
572
+ const element = node;
573
+ return {
574
+ id: element.getAttribute('id'),
575
+ };
576
+ },
577
+ },
578
+ {
579
+ tag: 'graphic',
580
+ node: 'figure',
581
+ context: 'figure_element/',
582
+ getAttrs: (node) => {
583
+ const element = node;
584
+ const position = element.getAttribute('position');
585
+ const src = element.getAttributeNS(this.XLINK_NAMESPACE, 'href');
586
+ return {
587
+ id: element.getAttribute('id'),
588
+ contentType: this.chooseContentType(element || undefined) || '',
589
+ src,
590
+ position,
591
+ };
592
+ },
593
+ },
594
+ {
595
+ tag: 'fig',
596
+ node: 'figure_element',
597
+ getAttrs: (node) => {
598
+ var _a, _b;
599
+ const element = node;
600
+ const labelNode = element.querySelector('label');
601
+ if (labelNode) {
602
+ element.removeChild(labelNode);
603
+ }
604
+ const attrib = element.querySelector('attrib');
605
+ const attribution = attrib
606
+ ? {
607
+ literal: (_a = getTrimmedTextContent(attrib)) !== null && _a !== void 0 ? _a : '',
608
+ }
609
+ : undefined;
610
+ return {
611
+ id: element.getAttribute('id'),
612
+ label: (_b = getTrimmedTextContent(labelNode)) !== null && _b !== void 0 ? _b : '',
613
+ attribution,
614
+ type: element.getAttribute('fig-type'),
615
+ };
616
+ },
617
+ },
618
+ {
619
+ tag: 'fn-group',
620
+ node: 'footnotes_element',
621
+ context: 'footnotes_section/|table_element_footer/',
622
+ getAttrs: (node) => {
623
+ const element = node;
624
+ return {
625
+ id: element.getAttribute('id'),
626
+ kind: 'footnote',
627
+ };
628
+ },
629
+ },
630
+ {
631
+ tag: 'table-wrap-foot',
632
+ node: 'table_element_footer',
633
+ getAttrs: (node) => {
634
+ const element = node;
635
+ return {
636
+ id: element.getAttribute('id'),
637
+ };
638
+ },
639
+ },
640
+ {
641
+ tag: 'general-table-footnote',
642
+ node: 'general_table_footnote',
643
+ context: 'table_element_footer/',
644
+ getAttrs: (node) => {
645
+ const element = node;
646
+ return {
647
+ id: element.getAttribute('id'),
648
+ };
649
+ },
650
+ getContent: (node) => {
651
+ const paragraphs = [];
652
+ node.childNodes.forEach((p) => {
653
+ const paragraph = this.schema.nodes.paragraph.create();
654
+ const content = this.parse(p, {
655
+ topNode: paragraph,
656
+ });
657
+ paragraphs.push(content);
658
+ });
659
+ return Fragment.from([...paragraphs]);
660
+ },
661
+ },
662
+ {
663
+ tag: 'fn',
664
+ node: 'footnote',
665
+ context: 'footnotes_element/|table_element_footer/',
666
+ getAttrs: (node) => {
667
+ const element = node;
668
+ return {
669
+ id: element.getAttribute('id'),
670
+ kind: 'footnote',
671
+ };
672
+ },
673
+ },
674
+ {
675
+ tag: 'front',
676
+ ignore: true,
677
+ },
678
+ {
679
+ tag: 'list',
680
+ node: 'list',
681
+ getAttrs: (node) => {
682
+ const element = node;
683
+ return {
684
+ id: element.getAttribute('id'),
685
+ listStyleType: element.getAttribute('list-type'),
686
+ };
687
+ },
688
+ },
689
+ {
690
+ tag: 'list-item',
691
+ node: 'list_item',
692
+ },
693
+ {
694
+ tag: 'p',
695
+ node: 'paragraph',
696
+ context: 'section/',
697
+ getAttrs: (node) => {
698
+ const element = node;
699
+ return {
700
+ id: element.getAttribute('id'),
701
+ };
702
+ },
703
+ },
704
+ {
705
+ tag: 'p',
706
+ node: 'paragraph',
707
+ },
708
+ {
709
+ tag: 'sec[sec-type="endnotes"]',
710
+ node: 'footnotes_section',
711
+ getAttrs: (node) => {
712
+ const element = node;
713
+ return {
714
+ id: element.getAttribute('id'),
715
+ };
716
+ },
717
+ },
718
+ {
719
+ tag: 'sec[sec-type="keywords"]',
720
+ node: 'keywords',
721
+ },
722
+ {
723
+ tag: 'sec[sec-type="supplementary-material"]',
724
+ node: 'supplements',
725
+ },
726
+ {
727
+ tag: 'supplementary-material',
728
+ node: 'supplement',
729
+ getAttrs: (node) => {
730
+ const element = node;
731
+ return {
732
+ id: element.getAttribute('id'),
733
+ href: element.getAttributeNS(this.XLINK_NAMESPACE, 'href'),
734
+ mimeType: element.getAttribute('mimetype'),
735
+ mimeSubType: element.getAttribute('mime-subtype'),
736
+ title: getTrimmedTextContent(element, 'title'),
737
+ };
738
+ },
739
+ },
740
+ {
741
+ tag: 'sec[sec-type="abstracts"]',
742
+ node: 'abstracts',
743
+ },
744
+ {
745
+ tag: 'sec[sec-type="body"]',
746
+ node: 'body',
747
+ },
748
+ {
749
+ tag: 'sec[sec-type="backmatter"]',
750
+ node: 'backmatter',
751
+ },
752
+ {
753
+ tag: 'sec[sec-type="box-element"]',
754
+ node: 'box_element',
755
+ getAttrs: (node) => {
756
+ const element = node;
757
+ return {
758
+ id: element.getAttribute('id'),
759
+ label: getTrimmedTextContent(element, 'label'),
760
+ };
761
+ },
762
+ },
763
+ {
764
+ tag: 'sec[sec-type="bibliography"]',
765
+ node: 'bibliography_section',
766
+ },
767
+ {
768
+ tag: 'ref-list',
769
+ context: 'bibliography_section/',
770
+ node: 'bibliography_element',
771
+ },
772
+ {
773
+ tag: 'ref',
774
+ context: 'bibliography_element/',
775
+ node: 'bibliography_item',
776
+ getAttrs: (node) => this.parseRef(node),
777
+ },
778
+ {
779
+ tag: 'sec[sec-type="abstract-graphical"]',
780
+ node: 'graphical_abstract_section',
781
+ },
782
+ {
783
+ tag: 'sec',
784
+ node: 'section',
785
+ getAttrs: (node) => {
786
+ const element = node;
787
+ return {
788
+ id: element.getAttribute('id'),
789
+ category: this.chooseSectionCategory(element),
790
+ };
791
+ },
792
+ },
793
+ {
794
+ tag: 'kwd-group-list',
795
+ context: 'keywords/',
796
+ node: 'keywords_element',
797
+ },
798
+ {
799
+ tag: 'kwd-group',
800
+ context: 'keywords_element/',
801
+ node: 'keyword_group',
802
+ getAttrs: (node) => {
803
+ const element = node;
804
+ return {
805
+ id: element.id,
806
+ type: element.getAttribute('kwd-group-type'),
807
+ };
808
+ },
809
+ },
810
+ {
811
+ tag: 'kwd',
812
+ context: 'keyword_group//',
813
+ node: 'keyword',
814
+ },
815
+ {
816
+ tag: 'label',
817
+ context: 'box_element/',
818
+ ignore: true,
819
+ },
820
+ {
821
+ tag: 'boxed-text',
822
+ ignore: true,
823
+ },
824
+ {
825
+ tag: 'label',
826
+ context: 'section/',
827
+ node: 'section_label',
828
+ },
829
+ {
830
+ tag: 'label',
831
+ context: 'table_element/',
832
+ ignore: true,
833
+ },
834
+ {
835
+ tag: 'label',
836
+ context: 'figure/',
837
+ ignore: true,
838
+ },
839
+ {
840
+ tag: 'table',
841
+ node: 'table',
842
+ getAttrs: (node) => {
843
+ const element = node;
844
+ return {
845
+ id: element.getAttribute('id'),
846
+ };
847
+ },
848
+ },
849
+ {
850
+ tag: 'table-wrap',
851
+ node: 'table_element',
852
+ getAttrs: (node) => {
853
+ const element = node;
854
+ return {
855
+ id: element.getAttribute('id'),
856
+ };
857
+ },
858
+ },
859
+ {
860
+ tag: 'title',
861
+ node: 'section_title',
862
+ context: 'section/|footnotes_section/|bibliography_section/|keywords/|supplements/|author_notes/|graphical_abstract_section/',
863
+ },
864
+ {
865
+ tag: 'title',
866
+ node: 'caption_title',
867
+ context: 'figcaption/',
868
+ },
869
+ {
870
+ tag: 'tr',
871
+ node: 'table_row',
872
+ },
873
+ {
874
+ tag: 'td',
875
+ node: 'table_cell',
876
+ getAttrs: (node) => {
877
+ const element = node;
878
+ const colspan = parseInt(element.getAttribute('colspan') || '1');
879
+ const rowspan = parseInt(element.getAttribute('rowspan') || '1');
880
+ 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') });
881
+ },
882
+ },
883
+ {
884
+ tag: 'th',
885
+ node: 'table_header',
886
+ getAttrs: (node) => {
887
+ const element = node;
888
+ const colspan = parseInt(element.getAttribute('colspan') || '1');
889
+ const rowspan = parseInt(element.getAttribute('rowspan') || '1');
890
+ 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') });
891
+ },
892
+ },
893
+ {
894
+ tag: 'col',
895
+ node: 'table_col',
896
+ getAttrs: (node) => {
897
+ const element = node;
898
+ return {
899
+ width: element.getAttribute('width'),
900
+ };
901
+ },
902
+ },
903
+ {
904
+ tag: 'colgroup',
905
+ node: 'table_colgroup',
906
+ },
907
+ {
908
+ tag: 'xref[ref-type="bibr"]',
909
+ node: 'citation',
910
+ getAttrs: (node) => {
911
+ var _a;
912
+ const element = node;
913
+ return {
914
+ rids: ((_a = element.getAttribute('rid')) === null || _a === void 0 ? void 0 : _a.split(/\s+/)) || [],
915
+ contents: getTrimmedTextContent(element),
916
+ };
917
+ },
918
+ },
919
+ {
920
+ tag: 'xref[ref-type="fn"]',
921
+ node: 'inline_footnote',
922
+ getAttrs: (node) => {
923
+ var _a;
924
+ const element = node;
925
+ return {
926
+ rids: ((_a = element.getAttribute('rid')) === null || _a === void 0 ? void 0 : _a.split(/\s+/)) || [],
927
+ };
928
+ },
929
+ },
930
+ {
931
+ tag: 'xref',
932
+ node: 'cross_reference',
933
+ getAttrs: (node) => {
934
+ var _a;
935
+ const element = node;
936
+ return {
937
+ rids: ((_a = element.getAttribute('rid')) === null || _a === void 0 ? void 0 : _a.split(/\s+/)) || [],
938
+ label: getTrimmedTextContent(element),
939
+ };
940
+ },
941
+ },
942
+ ];
943
+ this.marks = [
944
+ {
945
+ tag: 'bold',
946
+ mark: 'bold',
947
+ },
948
+ {
949
+ tag: 'code',
950
+ mark: 'code',
951
+ },
952
+ {
953
+ tag: 'italic',
954
+ mark: 'italic',
955
+ },
956
+ {
957
+ tag: 'sc',
958
+ mark: 'smallcaps',
959
+ },
960
+ {
961
+ tag: 'strike',
962
+ mark: 'strikethrough',
963
+ },
964
+ {
965
+ tag: 'styled-content',
966
+ mark: 'styled',
967
+ getAttrs: (node) => ({
968
+ style: node.getAttribute('style'),
969
+ }),
970
+ },
971
+ {
972
+ tag: 'sub',
973
+ mark: 'subscript',
974
+ },
975
+ {
976
+ tag: 'sup',
977
+ mark: 'superscript',
978
+ },
979
+ {
980
+ tag: 'underline',
981
+ mark: 'underline',
982
+ },
983
+ ];
984
+ this.parser = new DOMParser(this.schema, [...this.marks, ...this.nodes]);
985
+ }
986
+ parse(doc, options) {
987
+ return this.parser.parse(doc, options);
988
+ }
989
+ isMatchingCategory(secType, titleNode, category) {
990
+ if (secType && category.synonyms.includes(secType)) {
991
+ return true;
992
+ }
993
+ if (titleNode && titleNode.nodeName === 'title' && titleNode.textContent) {
994
+ const textContent = titleNode.textContent.trim().toLowerCase();
995
+ if (category.synonyms.includes(textContent)) {
996
+ return true;
997
+ }
998
+ }
999
+ return false;
1000
+ }
1001
+ chooseSectionCategory(section) {
1002
+ const secType = section.getAttribute('sec-type');
1003
+ const titleNode = section.firstElementChild;
1004
+ for (const category of this.sectionCategories) {
1005
+ if (this.isMatchingCategory(secType, titleNode, category)) {
1006
+ return category.id;
1007
+ }
1008
+ }
1009
+ }
1010
+ }