@manuscripts/transform 4.5.7 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/jats/__tests__/jats-exporter.test.js +50 -20
- package/dist/cjs/jats/__tests__/jats-importer.test.js +26 -0
- package/dist/cjs/jats/__tests__/jats-roundtrip.test.js +6 -1
- package/dist/cjs/jats/exporter/JATSExporterBase.js +118 -0
- package/dist/cjs/jats/exporter/jats-exporter.js +227 -349
- package/dist/cjs/jats/exporter/lib.js +62 -0
- package/dist/cjs/jats/importer/jats-dom-parser.js +11 -3
- package/dist/cjs/schema/index.js +4 -1
- package/dist/cjs/schema/migration/migration-scripts/4.5.9.js +30 -0
- package/dist/cjs/schema/migration/migration-scripts/index.js +3 -1
- package/dist/cjs/schema/nodes/bibliography_element.js +0 -1
- package/dist/cjs/schema/nodes/bio.js +24 -0
- package/dist/cjs/schema/nodes/contributor.js +1 -2
- package/dist/cjs/schema/nodes/keywords_element.js +0 -1
- package/dist/cjs/types.js +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/es/jats/__tests__/jats-exporter.test.js +47 -20
- package/dist/es/jats/__tests__/jats-importer.test.js +26 -0
- package/dist/es/jats/__tests__/jats-roundtrip.test.js +3 -1
- package/dist/es/jats/exporter/JATSExporterBase.js +114 -0
- package/dist/es/jats/exporter/jats-exporter.js +201 -319
- package/dist/es/jats/exporter/lib.js +55 -0
- package/dist/es/jats/importer/jats-dom-parser.js +11 -3
- package/dist/es/schema/index.js +4 -1
- package/dist/es/schema/migration/migration-scripts/4.5.9.js +28 -0
- package/dist/es/schema/migration/migration-scripts/index.js +3 -1
- package/dist/es/schema/nodes/bibliography_element.js +0 -1
- package/dist/es/schema/nodes/bio.js +20 -0
- package/dist/es/schema/nodes/contributor.js +1 -2
- package/dist/es/schema/nodes/keywords_element.js +0 -1
- package/dist/es/types.js +1 -1
- package/dist/es/version.js +1 -1
- package/dist/types/jats/exporter/JATSExporterBase.d.ts +35 -0
- package/dist/types/jats/exporter/jats-exporter.d.ts +23 -19
- package/dist/types/jats/exporter/lib.d.ts +23 -0
- package/dist/types/schema/index.d.ts +2 -1
- package/dist/types/schema/migration/migration-scripts/4.5.9.d.ts +8 -0
- package/dist/types/schema/migration/migration-scripts/index.d.ts +3 -2
- package/dist/types/schema/nodes/bio.d.ts +10 -0
- package/dist/types/schema/types.d.ts +1 -1
- package/dist/types/types.d.ts +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +4 -4
- package/src/jats/__tests__/__fixtures__/jats-import.xml +7 -0
- package/src/jats/__tests__/__snapshots__/jats-importer.test.ts.snap +272 -151
- package/src/jats/__tests__/__snapshots__/jats-roundtrip.test.ts.snap +2 -2
- package/src/jats/__tests__/jats-exporter.test.ts +60 -20
- package/src/jats/__tests__/jats-importer.test.ts +37 -0
- package/src/jats/__tests__/jats-roundtrip.test.ts +3 -1
- package/src/jats/exporter/JATSExporterBase.ts +164 -0
- package/src/jats/exporter/jats-exporter.ts +217 -386
- package/src/jats/exporter/lib.ts +69 -0
- package/src/jats/importer/jats-dom-parser.ts +15 -5
- package/src/schema/index.ts +4 -1
- package/src/schema/migration/migration-scripts/4.5.9.ts +62 -0
- package/src/schema/migration/migration-scripts/index.ts +3 -1
- package/src/schema/nodes/bibliography_element.ts +0 -1
- package/src/schema/nodes/bio.ts +48 -0
- package/src/schema/nodes/contributor.ts +1 -2
- package/src/schema/nodes/keywords_element.ts +0 -1
- package/src/schema/types.ts +1 -0
- package/src/types.ts +1 -1
- package/src/version.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* ©
|
|
2
|
+
* © 2026 Atypon Systems LLC
|
|
3
3
|
*
|
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
5
|
* you may not use this file except in compliance with the License.
|
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import * as Citeproc from 'citeproc'
|
|
18
|
-
import { DOMOutputSpec, DOMSerializer
|
|
19
|
-
import { findChildrenByAttr
|
|
20
|
-
import serializeToXML from 'w3c-xmlserializer'
|
|
18
|
+
import { DOMOutputSpec, DOMSerializer } from 'prosemirror-model'
|
|
19
|
+
import { findChildrenByAttr } from 'prosemirror-utils'
|
|
21
20
|
|
|
22
21
|
import { buildCiteprocCitation } from '../../lib/citeproc'
|
|
23
22
|
import { CreditRoleUrls } from '../../lib/credit-roles'
|
|
@@ -41,7 +40,6 @@ import {
|
|
|
41
40
|
FootnoteNode,
|
|
42
41
|
isBibliographyItemNode,
|
|
43
42
|
isCitationNode,
|
|
44
|
-
isNodeOfType,
|
|
45
43
|
ManuscriptMark,
|
|
46
44
|
ManuscriptNode,
|
|
47
45
|
ManuscriptNodeType,
|
|
@@ -50,12 +48,15 @@ import {
|
|
|
50
48
|
ParagraphNode,
|
|
51
49
|
QuoteImageNode,
|
|
52
50
|
schema,
|
|
51
|
+
BioNode,
|
|
53
52
|
} from '../../schema'
|
|
54
53
|
import { isExecutableNodeType } from '../../transformer'
|
|
55
54
|
import { IDGenerator } from '../types'
|
|
56
55
|
import { initJats, jatsVariableWrapper } from './citeproc'
|
|
57
56
|
import { selectVersionIDs, Version } from './jats-versions'
|
|
58
57
|
import { buildTargets, Target } from './labels'
|
|
58
|
+
import { JATSExporterBase } from './JATSExporterBase'
|
|
59
|
+
import { chooseRefType, createDefaultIDGenerator, normalizeID } from './lib'
|
|
59
60
|
|
|
60
61
|
interface Attrs {
|
|
61
62
|
[key: string]: string
|
|
@@ -67,56 +68,6 @@ type MarkSpecs = {
|
|
|
67
68
|
[key in Marks]: (mark: ManuscriptMark, inline: boolean) => DOMOutputSpec
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
const normalizeID = (id: string) => id.replace(/:/g, '_')
|
|
71
|
-
|
|
72
|
-
export const createCounter = () => {
|
|
73
|
-
const counts = new Map<string, number>()
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
increment: (field: string) => {
|
|
77
|
-
const value = counts.get(field)
|
|
78
|
-
const newValue = value === undefined ? 1 : value + 1
|
|
79
|
-
counts.set(field, newValue)
|
|
80
|
-
return newValue
|
|
81
|
-
},
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const createDefaultIDGenerator = (): IDGenerator => {
|
|
86
|
-
const counter = createCounter()
|
|
87
|
-
|
|
88
|
-
return async (element: Element) => {
|
|
89
|
-
const value = String(counter.increment(element.nodeName))
|
|
90
|
-
|
|
91
|
-
return `${element.localName}-${value}`
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const chooseRefType = (type: ManuscriptNodeType): string | undefined => {
|
|
96
|
-
switch (type) {
|
|
97
|
-
case schema.nodes.figure:
|
|
98
|
-
case schema.nodes.figure_element:
|
|
99
|
-
return 'fig'
|
|
100
|
-
|
|
101
|
-
case schema.nodes.footnote:
|
|
102
|
-
return 'fn'
|
|
103
|
-
|
|
104
|
-
case schema.nodes.table:
|
|
105
|
-
case schema.nodes.table_element:
|
|
106
|
-
return 'table'
|
|
107
|
-
|
|
108
|
-
case schema.nodes.section:
|
|
109
|
-
case schema.nodes.abstract:
|
|
110
|
-
return 'sec'
|
|
111
|
-
|
|
112
|
-
case schema.nodes.equation:
|
|
113
|
-
case schema.nodes.equation_element:
|
|
114
|
-
return 'disp-formula'
|
|
115
|
-
|
|
116
|
-
case schema.nodes.supplement:
|
|
117
|
-
return 'supplementary-material'
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
71
|
export type CSLOptions = {
|
|
121
72
|
style: string
|
|
122
73
|
locale: string
|
|
@@ -126,47 +77,19 @@ export type ExportOptions = {
|
|
|
126
77
|
csl: CSLOptions
|
|
127
78
|
}
|
|
128
79
|
|
|
129
|
-
export class JATSExporter {
|
|
130
|
-
protected document: Document
|
|
131
|
-
protected serializer: DOMSerializer
|
|
80
|
+
export class JATSExporter extends JATSExporterBase {
|
|
132
81
|
protected labelTargets: Map<string, Target>
|
|
133
82
|
protected footnoteLabels: Map<string, string>
|
|
134
83
|
protected manuscriptNode: ActualManuscriptNode
|
|
135
84
|
private engine: Citeproc.Engine
|
|
136
85
|
private renderedCitations: Map<string, string>
|
|
137
|
-
private nodesMap: Map<NodeType, ManuscriptNode[]> = new Map()
|
|
138
|
-
private contributorLabels: Map<string, number> = new Map()
|
|
139
|
-
|
|
140
|
-
private populateNodesMap = () => {
|
|
141
|
-
this.manuscriptNode.descendants((node) => {
|
|
142
|
-
const type = node.type
|
|
143
|
-
const nodes = this.nodesMap.get(type) ?? []
|
|
144
|
-
nodes.push(node)
|
|
145
|
-
this.nodesMap.set(type, nodes)
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
protected getFirstChildOfType<T extends ManuscriptNode>(
|
|
150
|
-
type: NodeType,
|
|
151
|
-
node?: ManuscriptNode
|
|
152
|
-
): T | undefined {
|
|
153
|
-
return this.getChildrenOfType<T>(type, node)[0]
|
|
154
|
-
}
|
|
155
86
|
|
|
156
|
-
|
|
157
|
-
type: NodeType,
|
|
158
|
-
node?: ManuscriptNode
|
|
159
|
-
): T[] {
|
|
160
|
-
const nodes = node
|
|
161
|
-
? findChildrenByType(node, type).map(({ node }) => node)
|
|
162
|
-
: this.nodesMap.get(type)
|
|
163
|
-
return (nodes ?? []).filter((n): n is T => isNodeOfType<T>(n, type))
|
|
164
|
-
}
|
|
87
|
+
private contributorLabels: Map<string, number> = new Map()
|
|
165
88
|
|
|
166
|
-
public
|
|
89
|
+
public export = async (
|
|
167
90
|
manuscriptNode: ActualManuscriptNode,
|
|
168
91
|
options: ExportOptions
|
|
169
|
-
): Promise<
|
|
92
|
+
): Promise<Document> => {
|
|
170
93
|
this.manuscriptNode = manuscriptNode
|
|
171
94
|
this.populateNodesMap()
|
|
172
95
|
this.initCiteprocEngine(options)
|
|
@@ -184,7 +107,6 @@ export class JATSExporter {
|
|
|
184
107
|
)
|
|
185
108
|
|
|
186
109
|
const $article = this.document.documentElement
|
|
187
|
-
|
|
188
110
|
$article.setAttributeNS(
|
|
189
111
|
'http://www.w3.org/2000/xmlns/',
|
|
190
112
|
'xmlns:xlink',
|
|
@@ -223,7 +145,7 @@ export class JATSExporter {
|
|
|
223
145
|
$article.appendChild($floatsGroup)
|
|
224
146
|
}
|
|
225
147
|
await this.rewriteIDs()
|
|
226
|
-
return
|
|
148
|
+
return this.document
|
|
227
149
|
}
|
|
228
150
|
|
|
229
151
|
private appendChildNodeOfType = (
|
|
@@ -616,9 +538,9 @@ export class JATSExporter {
|
|
|
616
538
|
const [, bibliography] = this.engine.makeBibliography()
|
|
617
539
|
const parser = new DOMParser()
|
|
618
540
|
bibliography.forEach((item) => {
|
|
619
|
-
const fragment = `<
|
|
541
|
+
const fragment = `<wrapper xmlns:xlink="${XLINK_NAMESPACE}">${sanitizeXmlString(
|
|
620
542
|
item
|
|
621
|
-
)}</
|
|
543
|
+
)}</wrapper>`
|
|
622
544
|
const $ref = parser
|
|
623
545
|
.parseFromString(fragment, 'text/xml')
|
|
624
546
|
.querySelector('ref')
|
|
@@ -629,43 +551,13 @@ export class JATSExporter {
|
|
|
629
551
|
return $refList
|
|
630
552
|
}
|
|
631
553
|
|
|
632
|
-
private createElement = (
|
|
633
|
-
tag: string,
|
|
634
|
-
content?: string,
|
|
635
|
-
attrs?: Record<string, string | undefined>
|
|
636
|
-
) => {
|
|
637
|
-
const $element = this.document.createElement(tag)
|
|
638
|
-
if (content) {
|
|
639
|
-
$element.textContent = content
|
|
640
|
-
}
|
|
641
|
-
if (attrs) {
|
|
642
|
-
Object.entries(attrs).forEach(([k, v]) => {
|
|
643
|
-
if (v) {
|
|
644
|
-
$element.setAttribute(k, v)
|
|
645
|
-
}
|
|
646
|
-
})
|
|
647
|
-
}
|
|
648
|
-
return $element
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
private appendElement = (
|
|
652
|
-
$parent: Element,
|
|
653
|
-
tag: string,
|
|
654
|
-
content?: string,
|
|
655
|
-
attrs?: Record<string, string | undefined>
|
|
656
|
-
) => {
|
|
657
|
-
const $element = this.createElement(tag, content, attrs)
|
|
658
|
-
$parent.appendChild($element)
|
|
659
|
-
return $element
|
|
660
|
-
}
|
|
661
|
-
|
|
662
554
|
protected createSerializer = () => {
|
|
663
555
|
const nodes: NodeSpecs = {
|
|
664
|
-
trans_abstract: (node) => createTransAbstract(node),
|
|
665
|
-
trans_graphical_abstract: (node) => createTransAbstract(node),
|
|
556
|
+
trans_abstract: (node) => this.createTransAbstract(node),
|
|
557
|
+
trans_graphical_abstract: (node) => this.createTransAbstract(node),
|
|
666
558
|
hero_image: () => '',
|
|
667
559
|
headshot_grid: () => ['p', { 'content-type': 'headshots' }, 0],
|
|
668
|
-
headshot_element: (node) => createImage(node),
|
|
560
|
+
headshot_element: (node) => this.createImage(node),
|
|
669
561
|
headshot_image: () => '',
|
|
670
562
|
alt_text: (node) => {
|
|
671
563
|
if (node.textContent) {
|
|
@@ -690,7 +582,7 @@ export class JATSExporter {
|
|
|
690
582
|
return $selfUri
|
|
691
583
|
},
|
|
692
584
|
attachments: () => '',
|
|
693
|
-
image_element: (node) => createImage(node),
|
|
585
|
+
image_element: (node) => this.createImage(node),
|
|
694
586
|
embed: (node) => {
|
|
695
587
|
const { id, href, mimetype, mimeSubtype, extLinks } = node.attrs
|
|
696
588
|
if (!href) {
|
|
@@ -706,7 +598,7 @@ export class JATSExporter {
|
|
|
706
598
|
if (mimeSubtype) {
|
|
707
599
|
$media.setAttribute('mime-subtype', node.attrs.mimeSubtype)
|
|
708
600
|
}
|
|
709
|
-
appendLabels($media, node)
|
|
601
|
+
this.appendLabels($media, node)
|
|
710
602
|
this.appendChildNodeOfType($media, node, schema.nodes.alt_text)
|
|
711
603
|
this.appendChildNodeOfType($media, node, schema.nodes.long_desc)
|
|
712
604
|
this.appendCaption($media, node)
|
|
@@ -715,9 +607,17 @@ export class JATSExporter {
|
|
|
715
607
|
if (extLink.href) {
|
|
716
608
|
const extLinkElement = this.createElement('ext-link')
|
|
717
609
|
extLinkElement.setAttribute('ext-link-type', extLink.type)
|
|
718
|
-
extLinkElement.setAttributeNS(
|
|
610
|
+
extLinkElement.setAttributeNS(
|
|
611
|
+
XLINK_NAMESPACE,
|
|
612
|
+
'href',
|
|
613
|
+
extLink.href
|
|
614
|
+
)
|
|
719
615
|
if (extLink.lang) {
|
|
720
|
-
extLinkElement.setAttributeNS(
|
|
616
|
+
extLinkElement.setAttributeNS(
|
|
617
|
+
XML_NAMESPACE,
|
|
618
|
+
'lang',
|
|
619
|
+
extLink.lang
|
|
620
|
+
)
|
|
721
621
|
}
|
|
722
622
|
if (extLink.label) {
|
|
723
623
|
extLinkElement.textContent = extLink.label
|
|
@@ -733,7 +633,7 @@ export class JATSExporter {
|
|
|
733
633
|
const awardGroup = node as AwardNode
|
|
734
634
|
const $awardGroup = this.createElement('award-group')
|
|
735
635
|
$awardGroup.setAttribute('id', normalizeID(awardGroup.attrs.id))
|
|
736
|
-
appendChildIfPresent(
|
|
636
|
+
this.appendChildIfPresent(
|
|
737
637
|
$awardGroup,
|
|
738
638
|
'funding-source',
|
|
739
639
|
awardGroup.attrs.source
|
|
@@ -741,9 +641,9 @@ export class JATSExporter {
|
|
|
741
641
|
awardGroup.attrs.code
|
|
742
642
|
?.split(';')
|
|
743
643
|
.forEach((code) =>
|
|
744
|
-
appendChildIfPresent($awardGroup, 'award-id', code)
|
|
644
|
+
this.appendChildIfPresent($awardGroup, 'award-id', code)
|
|
745
645
|
)
|
|
746
|
-
appendChildIfPresent(
|
|
646
|
+
this.appendChildIfPresent(
|
|
747
647
|
$awardGroup,
|
|
748
648
|
'principal-award-recipient',
|
|
749
649
|
awardGroup.attrs.recipient
|
|
@@ -751,7 +651,7 @@ export class JATSExporter {
|
|
|
751
651
|
|
|
752
652
|
return $awardGroup
|
|
753
653
|
},
|
|
754
|
-
box_element: (node) => createBoxElement(node),
|
|
654
|
+
box_element: (node) => this.createBoxElement(node),
|
|
755
655
|
author_notes: () => '',
|
|
756
656
|
corresp: () => '',
|
|
757
657
|
title: () => ['article-title', 0],
|
|
@@ -772,6 +672,7 @@ export class JATSExporter {
|
|
|
772
672
|
: ['table-wrap-foot', 0],
|
|
773
673
|
contributor: (node) =>
|
|
774
674
|
this.buildContributorElement(node as ContributorNode),
|
|
675
|
+
bio: () => ['bio', 0],
|
|
775
676
|
affiliation: (node) =>
|
|
776
677
|
this.buildAffiliationElement(node as AffiliationNode),
|
|
777
678
|
attribution: () => ['attrib', 0],
|
|
@@ -806,7 +707,7 @@ export class JATSExporter {
|
|
|
806
707
|
'mime-subtype',
|
|
807
708
|
node.attrs.mimeSubType ?? ''
|
|
808
709
|
)
|
|
809
|
-
appendLabels($supplementaryMaterial, node)
|
|
710
|
+
this.appendLabels($supplementaryMaterial, node)
|
|
810
711
|
this.appendCaption($supplementaryMaterial, node)
|
|
811
712
|
return $supplementaryMaterial
|
|
812
713
|
},
|
|
@@ -852,8 +753,7 @@ export class JATSExporter {
|
|
|
852
753
|
|
|
853
754
|
const rid = rids[0]
|
|
854
755
|
const labelTarget = this.labelTargets.get(rid)
|
|
855
|
-
const isSupplement =
|
|
856
|
-
labelTarget?.type === schema.nodes.supplement.name
|
|
756
|
+
const isSupplement = labelTarget?.type === schema.nodes.supplement.name
|
|
857
757
|
const text =
|
|
858
758
|
cross.attrs.label ||
|
|
859
759
|
(isSupplement
|
|
@@ -905,13 +805,13 @@ export class JATSExporter {
|
|
|
905
805
|
equation_element: (node) => {
|
|
906
806
|
const $dispFormula = this.createElement('disp-formula')
|
|
907
807
|
$dispFormula.setAttribute('id', normalizeID(node.attrs.id))
|
|
908
|
-
appendLabels($dispFormula, node)
|
|
909
|
-
processChildNodes($dispFormula, node, schema.nodes.equation)
|
|
808
|
+
this.appendLabels($dispFormula, node)
|
|
809
|
+
this.processChildNodes($dispFormula, node, schema.nodes.equation)
|
|
910
810
|
return $dispFormula
|
|
911
811
|
},
|
|
912
|
-
figure: (node) => createGraphic(node),
|
|
812
|
+
figure: (node) => this.createGraphic(node),
|
|
913
813
|
figure_element: (node) =>
|
|
914
|
-
createFigureElement(node, node.type.schema.nodes.figure),
|
|
814
|
+
this.createFigureElement(node, node.type.schema.nodes.figure),
|
|
915
815
|
footnote: (node) => {
|
|
916
816
|
const attrs: Attrs = {}
|
|
917
817
|
|
|
@@ -1004,7 +904,7 @@ export class JATSExporter {
|
|
|
1004
904
|
return $code
|
|
1005
905
|
},
|
|
1006
906
|
listing_element: (node) =>
|
|
1007
|
-
createFigureElement(node, node.type.schema.nodes.listing),
|
|
907
|
+
this.createFigureElement(node, node.type.schema.nodes.listing),
|
|
1008
908
|
manuscript: (node) => ['article', { id: normalizeID(node.attrs.id) }, 0],
|
|
1009
909
|
missing_figure: () => {
|
|
1010
910
|
const $graphic = this.createElement('graphic')
|
|
@@ -1045,11 +945,11 @@ export class JATSExporter {
|
|
|
1045
945
|
quote_image: (node) => {
|
|
1046
946
|
const img = node as QuoteImageNode
|
|
1047
947
|
if (img.attrs.src) {
|
|
1048
|
-
return createGraphic(node)
|
|
948
|
+
return this.createGraphic(node)
|
|
1049
949
|
}
|
|
1050
950
|
return ''
|
|
1051
951
|
},
|
|
1052
|
-
graphical_abstract_section: (node) => createAbstract(node),
|
|
952
|
+
graphical_abstract_section: (node) => this.createAbstract(node),
|
|
1053
953
|
section: (node) => {
|
|
1054
954
|
const attrs: { [key: string]: string } = {
|
|
1055
955
|
id: normalizeID(node.attrs.id),
|
|
@@ -1061,13 +961,13 @@ export class JATSExporter {
|
|
|
1061
961
|
|
|
1062
962
|
return ['sec', attrs, 0]
|
|
1063
963
|
},
|
|
1064
|
-
abstract: (node) => createAbstract(node),
|
|
964
|
+
abstract: (node) => this.createAbstract(node),
|
|
1065
965
|
section_label: () => ['label', 0],
|
|
1066
966
|
section_title: () => ['title', 0],
|
|
1067
967
|
section_title_plain: () => ['title', 0],
|
|
1068
968
|
table: (node) => ['table', { id: normalizeID(node.attrs.id) }, 0],
|
|
1069
969
|
table_element: (node) => {
|
|
1070
|
-
const $tableWrap = createTableElement(node)
|
|
970
|
+
const $tableWrap = this.createTableElement(node)
|
|
1071
971
|
$tableWrap.setAttribute('position', 'anchor')
|
|
1072
972
|
if (node.attrs.type) {
|
|
1073
973
|
$tableWrap.setAttribute('content-type', node.attrs.type)
|
|
@@ -1121,134 +1021,93 @@ export class JATSExporter {
|
|
|
1121
1021
|
}
|
|
1122
1022
|
|
|
1123
1023
|
this.serializer = new DOMSerializer(nodes, marks)
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
appendLabels($element: Element, node: ManuscriptNode) {
|
|
1027
|
+
if (this.labelTargets) {
|
|
1028
|
+
const target = this.labelTargets.get(node.attrs.id)
|
|
1029
|
+
|
|
1030
|
+
if (target) {
|
|
1031
|
+
const $label = this.createElement('label')
|
|
1032
|
+
$label.textContent = target.label
|
|
1033
|
+
$element.appendChild($label)
|
|
1131
1034
|
}
|
|
1132
|
-
const $element = this.createElement(tagName)
|
|
1133
|
-
$element.textContent = textContent
|
|
1134
|
-
$parent.appendChild($element)
|
|
1135
|
-
}
|
|
1136
|
-
const processChildNodes = (
|
|
1137
|
-
$element: Element,
|
|
1138
|
-
node: ManuscriptNode,
|
|
1139
|
-
contentNodeType: ManuscriptNodeType
|
|
1140
|
-
) => {
|
|
1141
|
-
node.forEach((childNode) => {
|
|
1142
|
-
if (childNode.type === contentNodeType) {
|
|
1143
|
-
if (childNode.attrs.id) {
|
|
1144
|
-
$element.appendChild(this.serializeNode(childNode))
|
|
1145
|
-
}
|
|
1146
|
-
} else if (childNode.type === node.type.schema.nodes.paragraph) {
|
|
1147
|
-
$element.appendChild(this.serializeNode(childNode))
|
|
1148
|
-
} else if (childNode.type === node.type.schema.nodes.missing_figure) {
|
|
1149
|
-
$element.appendChild(this.serializeNode(childNode))
|
|
1150
|
-
}
|
|
1151
|
-
})
|
|
1152
1035
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1036
|
+
}
|
|
1037
|
+
appendAttributions($element: Element, node: ManuscriptNode) {
|
|
1038
|
+
if (node.attrs.attribution) {
|
|
1039
|
+
const $attrib = this.createElement('attrib')
|
|
1040
|
+
$attrib.textContent = node.attrs.attribution.literal
|
|
1041
|
+
$element.appendChild($attrib)
|
|
1157
1042
|
}
|
|
1043
|
+
}
|
|
1158
1044
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1045
|
+
appendTable($element: Element, node: ManuscriptNode) {
|
|
1046
|
+
const tableNode = this.getFirstChildOfType(schema.nodes.table, node)
|
|
1047
|
+
const colGroupNode = this.getFirstChildOfType(
|
|
1048
|
+
schema.nodes.table_colgroup,
|
|
1049
|
+
node
|
|
1050
|
+
)
|
|
1051
|
+
if (!tableNode) {
|
|
1052
|
+
return
|
|
1053
|
+
}
|
|
1054
|
+
const $table = this.serializeNode(tableNode)
|
|
1055
|
+
const $tbody = this.createElement('tbody')
|
|
1162
1056
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
}
|
|
1168
|
-
}
|
|
1057
|
+
while ($table.firstChild) {
|
|
1058
|
+
const $child = $table.firstChild
|
|
1059
|
+
$table.removeChild($child)
|
|
1060
|
+
$tbody.appendChild($child)
|
|
1169
1061
|
}
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
}
|
|
1062
|
+
$table.appendChild($tbody)
|
|
1063
|
+
this.normalizeTable($table)
|
|
1064
|
+
if (colGroupNode) {
|
|
1065
|
+
const $colGroup = this.serializeNode(colGroupNode)
|
|
1066
|
+
$table.insertBefore($colGroup, $table.firstChild)
|
|
1176
1067
|
}
|
|
1177
1068
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
const colGroupNode = this.getFirstChildOfType(
|
|
1181
|
-
schema.nodes.table_colgroup,
|
|
1182
|
-
node
|
|
1183
|
-
)
|
|
1184
|
-
if (!tableNode) {
|
|
1185
|
-
return
|
|
1186
|
-
}
|
|
1187
|
-
const $table = this.serializeNode(tableNode)
|
|
1188
|
-
const $tbody = this.createElement('tbody')
|
|
1189
|
-
|
|
1190
|
-
while ($table.firstChild) {
|
|
1191
|
-
const $child = $table.firstChild
|
|
1192
|
-
$table.removeChild($child)
|
|
1193
|
-
$tbody.appendChild($child)
|
|
1194
|
-
}
|
|
1195
|
-
$table.appendChild($tbody)
|
|
1196
|
-
this.normalizeTable($table)
|
|
1197
|
-
if (colGroupNode) {
|
|
1198
|
-
const $colGroup = this.serializeNode(colGroupNode)
|
|
1199
|
-
$table.insertBefore($colGroup, $table.firstChild)
|
|
1200
|
-
}
|
|
1069
|
+
$element.appendChild($table)
|
|
1070
|
+
}
|
|
1201
1071
|
|
|
1202
|
-
|
|
1072
|
+
createBoxElement(node: ManuscriptNode) {
|
|
1073
|
+
const $boxedText = this.createElementWithID(node, 'boxed-text')
|
|
1074
|
+
if (node.attrs.type) {
|
|
1075
|
+
$boxedText.setAttribute('content-type', node.attrs.type)
|
|
1203
1076
|
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
}
|
|
1209
|
-
appendLabels($boxedText, node)
|
|
1210
|
-
const child = node.firstChild
|
|
1211
|
-
if (child?.type === schema.nodes.caption_title) {
|
|
1212
|
-
this.appendCaption($boxedText, node)
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
processChildNodes($boxedText, node, node.type.schema.nodes.section)
|
|
1216
|
-
return $boxedText
|
|
1077
|
+
this.appendLabels($boxedText, node)
|
|
1078
|
+
const child = node.firstChild
|
|
1079
|
+
if (child?.type === schema.nodes.caption_title) {
|
|
1080
|
+
this.appendCaption($boxedText, node)
|
|
1217
1081
|
}
|
|
1218
1082
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1083
|
+
this.processChildNodes($boxedText, node, node.type.schema.nodes.section)
|
|
1084
|
+
return $boxedText
|
|
1085
|
+
}
|
|
1221
1086
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1087
|
+
abstractTypeAttrs(category: string) {
|
|
1088
|
+
return category && category !== 'abstract'
|
|
1089
|
+
? { 'abstract-type': category }
|
|
1090
|
+
: {}
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
createAbstract(node: ManuscriptNode): DOMOutputSpec {
|
|
1094
|
+
return ['abstract', this.abstractTypeAttrs(node.attrs.category), 0]
|
|
1095
|
+
}
|
|
1227
1096
|
|
|
1228
|
-
|
|
1097
|
+
createTransAbstract(node: ManuscriptNode): DOMOutputSpec {
|
|
1098
|
+
return [
|
|
1229
1099
|
'trans-abstract',
|
|
1230
1100
|
{
|
|
1231
1101
|
[`${XML_NAMESPACE} lang`]: node.attrs.lang ?? '',
|
|
1232
|
-
...abstractTypeAttrs(node.attrs.category),
|
|
1102
|
+
...this.abstractTypeAttrs(node.attrs.category),
|
|
1233
1103
|
},
|
|
1234
1104
|
0,
|
|
1235
1105
|
]
|
|
1106
|
+
}
|
|
1236
1107
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
descend = false
|
|
1241
|
-
) => {
|
|
1242
|
-
const nodes = this.getChildrenOfType(type)
|
|
1243
|
-
return nodes.some((node) => {
|
|
1244
|
-
const result = findChildrenByAttr(
|
|
1245
|
-
node,
|
|
1246
|
-
(attrs) => attrs.id === targetID,
|
|
1247
|
-
descend
|
|
1248
|
-
)[0]
|
|
1249
|
-
return !!result
|
|
1250
|
-
})
|
|
1251
|
-
}
|
|
1108
|
+
private createGraphic(node: ManuscriptNode) {
|
|
1109
|
+
const $graphic = this.createElement('graphic')
|
|
1110
|
+
$graphic.setAttributeNS(XLINK_NAMESPACE, 'xlink:href', node.attrs.src)
|
|
1252
1111
|
|
|
1253
1112
|
const findParentHeroImage = (targetID: string) => {
|
|
1254
1113
|
const heroes = this.getChildrenOfType(schema.nodes.hero_image)
|
|
@@ -1258,122 +1117,118 @@ export class JATSExporter {
|
|
|
1258
1117
|
)
|
|
1259
1118
|
}
|
|
1260
1119
|
|
|
1261
|
-
const
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
$extLink.setAttributeNS(XLINK_NAMESPACE, 'href', node.attrs.extLink)
|
|
1270
|
-
}
|
|
1271
|
-
this.appendCaption($graphic, node)
|
|
1272
|
-
this.appendChildNodeOfType($graphic, node, schema.nodes.alt_text)
|
|
1273
|
-
this.appendChildNodeOfType($graphic, node, schema.nodes.long_desc)
|
|
1274
|
-
return $graphic
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
const createGraphic = (node: ManuscriptNode) => {
|
|
1278
|
-
const $graphic = this.createElement('graphic')
|
|
1279
|
-
$graphic.setAttributeNS(XLINK_NAMESPACE, 'xlink:href', node.attrs.src)
|
|
1280
|
-
|
|
1281
|
-
const hero = findParentHeroImage(node.attrs.id)
|
|
1282
|
-
if (hero) {
|
|
1283
|
-
$graphic.setAttribute('content-type', hero.attrs.type || 'leading')
|
|
1284
|
-
} else if (
|
|
1285
|
-
!isChildOfNodeType(node.attrs.id, schema.nodes.figure_element) &&
|
|
1286
|
-
node.attrs.type
|
|
1287
|
-
) {
|
|
1288
|
-
$graphic.setAttribute('content-type', node.attrs.type)
|
|
1289
|
-
}
|
|
1290
|
-
return $graphic
|
|
1291
|
-
}
|
|
1292
|
-
const createFigureElement = (
|
|
1293
|
-
node: ManuscriptNode,
|
|
1294
|
-
contentNodeType: ManuscriptNodeType
|
|
1295
|
-
) => {
|
|
1296
|
-
const $fig = createElement(node, 'fig')
|
|
1297
|
-
const figNode = this.getFirstChildOfType(schema.nodes.figure, node)
|
|
1298
|
-
const figType = figNode?.attrs.type
|
|
1299
|
-
if (figType) {
|
|
1300
|
-
$fig.setAttribute('fig-type', figType)
|
|
1301
|
-
}
|
|
1302
|
-
appendLabels($fig, node)
|
|
1303
|
-
this.appendCaption($fig, node)
|
|
1304
|
-
this.appendChildNodeOfType($fig, node, schema.nodes.alt_text)
|
|
1305
|
-
this.appendChildNodeOfType($fig, node, schema.nodes.long_desc)
|
|
1306
|
-
this.appendChildNodeOfType(
|
|
1307
|
-
$fig,
|
|
1308
|
-
node,
|
|
1309
|
-
node.type.schema.nodes.footnotes_element
|
|
1310
|
-
)
|
|
1311
|
-
processChildNodes($fig, node, contentNodeType)
|
|
1312
|
-
appendAttributions($fig, node)
|
|
1313
|
-
if (isExecutableNodeType(node.type)) {
|
|
1314
|
-
processExecutableNode(node, $fig)
|
|
1315
|
-
}
|
|
1316
|
-
moveAltTextAndLongDescToGraphics($fig)
|
|
1317
|
-
return $fig
|
|
1120
|
+
const hero = findParentHeroImage(node.attrs.id)
|
|
1121
|
+
if (hero) {
|
|
1122
|
+
$graphic.setAttribute('content-type', hero.attrs.type || 'leading')
|
|
1123
|
+
} else if (
|
|
1124
|
+
!this.isChildOfNodeType(node.attrs.id, schema.nodes.figure_element) &&
|
|
1125
|
+
node.attrs.type
|
|
1126
|
+
) {
|
|
1127
|
+
$graphic.setAttribute('content-type', node.attrs.type)
|
|
1318
1128
|
}
|
|
1129
|
+
return $graphic
|
|
1130
|
+
}
|
|
1319
1131
|
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1132
|
+
createImage(node: ManuscriptNode) {
|
|
1133
|
+
const graphicNode = node.content.firstChild
|
|
1134
|
+
if (!graphicNode) {
|
|
1135
|
+
return ''
|
|
1136
|
+
}
|
|
1137
|
+
const $graphic = this.createGraphic(graphicNode)
|
|
1138
|
+
if (node.attrs.extLink) {
|
|
1139
|
+
const $extLink = this.appendElement($graphic, 'ext-link')
|
|
1140
|
+
$extLink.setAttributeNS(XLINK_NAMESPACE, 'href', node.attrs.extLink)
|
|
1141
|
+
}
|
|
1142
|
+
this.appendCaption($graphic, node)
|
|
1143
|
+
this.appendChildNodeOfType($graphic, node, schema.nodes.alt_text)
|
|
1144
|
+
this.appendChildNodeOfType($graphic, node, schema.nodes.long_desc)
|
|
1145
|
+
return $graphic
|
|
1146
|
+
}
|
|
1324
1147
|
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1148
|
+
createFigureElement(
|
|
1149
|
+
node: ManuscriptNode,
|
|
1150
|
+
contentNodeType: ManuscriptNodeType
|
|
1151
|
+
) {
|
|
1152
|
+
const $fig = this.createElementWithID(node, 'fig')
|
|
1153
|
+
const figNode = this.getFirstChildOfType(schema.nodes.figure, node)
|
|
1154
|
+
const figType = figNode?.attrs.type
|
|
1155
|
+
if (figType) {
|
|
1156
|
+
$fig.setAttribute('fig-type', figType)
|
|
1157
|
+
}
|
|
1158
|
+
this.appendLabels($fig, node)
|
|
1159
|
+
this.appendCaption($fig, node)
|
|
1160
|
+
this.appendChildNodeOfType($fig, node, schema.nodes.alt_text)
|
|
1161
|
+
this.appendChildNodeOfType($fig, node, schema.nodes.long_desc)
|
|
1162
|
+
this.appendChildNodeOfType(
|
|
1163
|
+
$fig,
|
|
1164
|
+
node,
|
|
1165
|
+
node.type.schema.nodes.footnotes_element
|
|
1166
|
+
)
|
|
1167
|
+
this.processChildNodes($fig, node, contentNodeType)
|
|
1168
|
+
this.appendAttributions($fig, node)
|
|
1169
|
+
if (isExecutableNodeType(node.type)) {
|
|
1170
|
+
this.processExecutableNode(node, $fig)
|
|
1171
|
+
}
|
|
1172
|
+
this.moveAltTextAndLongDescToGraphics($fig)
|
|
1173
|
+
return $fig
|
|
1174
|
+
}
|
|
1328
1175
|
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
if ($altText) {
|
|
1334
|
-
$graphic.prepend($altText.cloneNode(true))
|
|
1335
|
-
}
|
|
1336
|
-
})
|
|
1176
|
+
moveAltTextAndLongDescToGraphics($element: Element) {
|
|
1177
|
+
const $altText = $element.querySelector('alt-text')
|
|
1178
|
+
const $longDesc = $element.querySelector('long-desc')
|
|
1179
|
+
const $graphics = $element.querySelectorAll('graphic')
|
|
1337
1180
|
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
appendLabels($tableWrap, node)
|
|
1346
|
-
this.appendCaption($tableWrap, node)
|
|
1347
|
-
this.appendChildNodeOfType($tableWrap, node, schema.nodes.alt_text)
|
|
1348
|
-
this.appendChildNodeOfType($tableWrap, node, schema.nodes.long_desc)
|
|
1349
|
-
appendTable($tableWrap, node)
|
|
1350
|
-
this.appendChildNodeOfType(
|
|
1351
|
-
$tableWrap,
|
|
1352
|
-
node,
|
|
1353
|
-
node.type.schema.nodes.table_element_footer
|
|
1354
|
-
)
|
|
1355
|
-
if (isExecutableNodeType(node.type)) {
|
|
1356
|
-
processExecutableNode(node, $tableWrap)
|
|
1181
|
+
if ($graphics.length === 0) {
|
|
1182
|
+
return
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
$graphics.forEach(($graphic) => {
|
|
1186
|
+
if ($longDesc) {
|
|
1187
|
+
$graphic.prepend($longDesc.cloneNode(true))
|
|
1357
1188
|
}
|
|
1358
|
-
|
|
1189
|
+
if ($altText) {
|
|
1190
|
+
$graphic.prepend($altText.cloneNode(true))
|
|
1191
|
+
}
|
|
1192
|
+
})
|
|
1193
|
+
|
|
1194
|
+
$altText?.remove()
|
|
1195
|
+
$longDesc?.remove()
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
createTableElement(node: ManuscriptNode) {
|
|
1199
|
+
const nodeName = 'table-wrap'
|
|
1200
|
+
const $tableWrap = this.createElementWithID(node, nodeName)
|
|
1201
|
+
this.appendLabels($tableWrap, node)
|
|
1202
|
+
this.appendCaption($tableWrap, node)
|
|
1203
|
+
this.appendChildNodeOfType($tableWrap, node, schema.nodes.alt_text)
|
|
1204
|
+
this.appendChildNodeOfType($tableWrap, node, schema.nodes.long_desc)
|
|
1205
|
+
this.appendTable($tableWrap, node)
|
|
1206
|
+
this.appendChildNodeOfType(
|
|
1207
|
+
$tableWrap,
|
|
1208
|
+
node,
|
|
1209
|
+
node.type.schema.nodes.table_element_footer
|
|
1210
|
+
)
|
|
1211
|
+
if (isExecutableNodeType(node.type)) {
|
|
1212
|
+
this.processExecutableNode(node, $tableWrap)
|
|
1359
1213
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1214
|
+
return $tableWrap
|
|
1215
|
+
}
|
|
1216
|
+
processExecutableNode(node: ManuscriptNode, $element: Element) {
|
|
1217
|
+
const listingNode = this.getFirstChildOfType(schema.nodes.listing, node)
|
|
1362
1218
|
|
|
1363
|
-
|
|
1364
|
-
|
|
1219
|
+
if (listingNode) {
|
|
1220
|
+
const { contents, languageKey } = listingNode.attrs
|
|
1365
1221
|
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1222
|
+
if (contents && languageKey) {
|
|
1223
|
+
const $fig = this.createElement('fig')
|
|
1224
|
+
$fig.setAttribute('specific-use', 'source')
|
|
1225
|
+
$element.appendChild($fig)
|
|
1370
1226
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
}
|
|
1227
|
+
const $code = this.createElement('code')
|
|
1228
|
+
$code.setAttribute('executable', 'true')
|
|
1229
|
+
$code.setAttribute('language', languageKey)
|
|
1230
|
+
$code.textContent = contents
|
|
1231
|
+
$fig.appendChild($code)
|
|
1377
1232
|
}
|
|
1378
1233
|
}
|
|
1379
1234
|
}
|
|
@@ -1399,11 +1254,6 @@ export class JATSExporter {
|
|
|
1399
1254
|
}
|
|
1400
1255
|
}
|
|
1401
1256
|
|
|
1402
|
-
protected serializeNode = (node: ManuscriptNode) =>
|
|
1403
|
-
this.serializer.serializeNode(node, {
|
|
1404
|
-
document: this.document,
|
|
1405
|
-
})
|
|
1406
|
-
|
|
1407
1257
|
private buildContributorGroup = (contributors: ContributorNode[]) => {
|
|
1408
1258
|
if (!contributors.length) {
|
|
1409
1259
|
return
|
|
@@ -1553,6 +1403,11 @@ export class JATSExporter {
|
|
|
1553
1403
|
})
|
|
1554
1404
|
})
|
|
1555
1405
|
|
|
1406
|
+
const bio = this.getFirstChildOfType<BioNode>(schema.nodes.bio, contributor)
|
|
1407
|
+
if (bio?.childCount) {
|
|
1408
|
+
$contrib.appendChild(this.serializeNode(bio))
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1556
1411
|
return $contrib
|
|
1557
1412
|
}
|
|
1558
1413
|
|
|
@@ -1718,18 +1573,6 @@ export class JATSExporter {
|
|
|
1718
1573
|
this.serializeNode(group)
|
|
1719
1574
|
)
|
|
1720
1575
|
|
|
1721
|
-
private changeTag = ($node: Element, tag: string) => {
|
|
1722
|
-
const $clone = this.createElement(tag)
|
|
1723
|
-
for (const attr of $node.attributes) {
|
|
1724
|
-
$clone.setAttributeNS(null, attr.name, attr.value)
|
|
1725
|
-
}
|
|
1726
|
-
while ($node.firstChild) {
|
|
1727
|
-
$clone.appendChild($node.firstChild)
|
|
1728
|
-
}
|
|
1729
|
-
$node.replaceWith($clone)
|
|
1730
|
-
return $clone
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
1576
|
private normalizeTable = ($table: Node) => {
|
|
1734
1577
|
let $tbody: Element | undefined
|
|
1735
1578
|
|
|
@@ -1828,18 +1671,6 @@ export class JATSExporter {
|
|
|
1828
1671
|
}
|
|
1829
1672
|
}
|
|
1830
1673
|
|
|
1831
|
-
private fillEmptyElements(
|
|
1832
|
-
$article: Element,
|
|
1833
|
-
selector: string,
|
|
1834
|
-
tagName = 'p'
|
|
1835
|
-
) {
|
|
1836
|
-
const $empty = Array.from($article.querySelectorAll(selector)).filter(
|
|
1837
|
-
($el) => !$el.innerHTML
|
|
1838
|
-
)
|
|
1839
|
-
$empty.forEach(($element) =>
|
|
1840
|
-
$element.appendChild(this.createElement(tagName))
|
|
1841
|
-
)
|
|
1842
|
-
}
|
|
1843
1674
|
private addParagraphsToSections($article: Element) {
|
|
1844
1675
|
const $sections = $article.querySelectorAll('sec, abstract')
|
|
1845
1676
|
const TITLE_TAGS = new Set(['title', 'label', 'sec-meta'])
|