@manuscripts/transform 4.3.53 → 4.4.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-roundtrip.test.js +3 -3
- package/dist/cjs/version.js +1 -1
- package/dist/es/jats/__tests__/jats-roundtrip.test.js +3 -3
- package/dist/es/version.js +1 -1
- package/dist/types/jats/__tests__/utils.d.ts +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +22 -21
- package/src/errors.ts +28 -0
- package/src/getVersion.ts +21 -0
- package/src/index.ts +28 -0
- package/src/jats/__tests__/__fixtures__/debug-example.xml +136 -0
- package/src/jats/__tests__/__fixtures__/jats-abstract-no-body.xml +163 -0
- package/src/jats/__tests__/__fixtures__/jats-citations.xml +472 -0
- package/src/jats/__tests__/__fixtures__/jats-comments.xml +46 -0
- package/src/jats/__tests__/__fixtures__/jats-document.xml +134 -0
- package/src/jats/__tests__/__fixtures__/jats-example-doc.xml +1235 -0
- package/src/jats/__tests__/__fixtures__/jats-example-front-only.xml +26 -0
- package/src/jats/__tests__/__fixtures__/jats-example-full.xml +209 -0
- package/src/jats/__tests__/__fixtures__/jats-example-no-back.xml +156 -0
- package/src/jats/__tests__/__fixtures__/jats-example-no-body.xml +91 -0
- package/src/jats/__tests__/__fixtures__/jats-example.xml +221 -0
- package/src/jats/__tests__/__fixtures__/jats-fn-group.xml +60 -0
- package/src/jats/__tests__/__fixtures__/jats-import-no-refs.xml +1077 -0
- package/src/jats/__tests__/__fixtures__/jats-import.xml +1561 -0
- package/src/jats/__tests__/__fixtures__/jats-roundtrip.xml +133 -0
- package/src/jats/__tests__/__fixtures__/jats-tables-example.xml +2043 -0
- package/src/jats/__tests__/__fixtures__/math-fragment.xml +12 -0
- package/src/jats/__tests__/__snapshots__/citeproc.test.ts.snap +57 -0
- package/src/jats/__tests__/__snapshots__/create-article-node.test.ts.snap +65 -0
- package/src/jats/__tests__/__snapshots__/jats-exporter.test.ts.snap +7 -0
- package/src/jats/__tests__/__snapshots__/jats-importer.test.ts.snap +59605 -0
- package/src/jats/__tests__/__snapshots__/jats-roundtrip.test.ts.snap +18 -0
- package/src/jats/__tests__/citations.ts +25 -0
- package/src/jats/__tests__/citeproc.test.ts +195 -0
- package/src/jats/__tests__/create-article-node.test.ts +29 -0
- package/src/jats/__tests__/data/section-categories.ts +212 -0
- package/src/jats/__tests__/files.ts +24 -0
- package/src/jats/__tests__/jats-exporter.test.ts +223 -0
- package/src/jats/__tests__/jats-importer.test.ts +567 -0
- package/src/jats/__tests__/jats-roundtrip.test.ts +66 -0
- package/src/jats/__tests__/utils.ts +90 -0
- package/src/jats/exporter/citeproc.ts +265 -0
- package/src/jats/exporter/jats-exporter.ts +2090 -0
- package/src/jats/exporter/jats-versions.ts +50 -0
- package/src/jats/exporter/labels.ts +101 -0
- package/src/jats/importer/create-article-node.ts +52 -0
- package/src/jats/importer/jats-comments.ts +111 -0
- package/src/jats/importer/jats-dom-parser.ts +1260 -0
- package/src/jats/importer/jats-parser-utils.ts +234 -0
- package/src/jats/importer/jats-transformations.ts +591 -0
- package/src/jats/importer/parse-jats-article.ts +106 -0
- package/src/jats/index.ts +21 -0
- package/src/jats/types.ts +16 -0
- package/src/lib/__tests__/footnotes.test.ts +36 -0
- package/src/lib/citeproc.ts +30 -0
- package/src/lib/credit-roles.ts +91 -0
- package/src/lib/deafults.ts +17 -0
- package/src/lib/footnotes.ts +85 -0
- package/src/lib/html.ts +56 -0
- package/src/lib/section-categories.ts +27 -0
- package/src/lib/utils.ts +145 -0
- package/src/lib/xml.ts +28 -0
- package/src/schema/__tests__/docs.ts +1911 -0
- package/src/schema/__tests__/groups.test.ts +61 -0
- package/src/schema/__tests__/migration.test.ts +23 -0
- package/src/schema/groups.ts +36 -0
- package/src/schema/index.ts +286 -0
- package/src/schema/marks.ts +254 -0
- package/src/schema/migration/migrate.ts +77 -0
- package/src/schema/migration/migration-script.ts +26 -0
- package/src/schema/migration/migration-scripts/1.2.5.ts +44 -0
- package/src/schema/migration/migration-scripts/2.3.22.ts +52 -0
- package/src/schema/migration/migration-scripts/3.0.12.ts +33 -0
- package/src/schema/migration/migration-scripts/3.0.21.ts +50 -0
- package/src/schema/migration/migration-scripts/3.0.30.ts +65 -0
- package/src/schema/migration/migration-scripts/3.0.31.ts +40 -0
- package/src/schema/migration/migration-scripts/3.0.41.ts +37 -0
- package/src/schema/migration/migration-scripts/3.0.55.ts +42 -0
- package/src/schema/migration/migration-scripts/3.0.56.ts +114 -0
- package/src/schema/migration/migration-scripts/4.2.13.ts +37 -0
- package/src/schema/migration/migration-scripts/4.2.15.ts +48 -0
- package/src/schema/migration/migration-scripts/4.3.23.ts +55 -0
- package/src/schema/migration/migration-scripts/4.3.34.ts +132 -0
- package/src/schema/migration/migration-scripts/4.3.35.ts +41 -0
- package/src/schema/migration/migration-scripts/index.ts +49 -0
- package/src/schema/nodes/abstracts.ts +29 -0
- package/src/schema/nodes/affiliation.ts +88 -0
- package/src/schema/nodes/affiliations.ts +30 -0
- package/src/schema/nodes/alt_text.ts +36 -0
- package/src/schema/nodes/alt_title.ts +40 -0
- package/src/schema/nodes/alt_titles_section.ts +58 -0
- package/src/schema/nodes/attachment.ts +46 -0
- package/src/schema/nodes/attachments.ts +45 -0
- package/src/schema/nodes/attribution.ts +38 -0
- package/src/schema/nodes/author_notes.ts +44 -0
- package/src/schema/nodes/award.ts +52 -0
- package/src/schema/nodes/awards.ts +45 -0
- package/src/schema/nodes/backmatter.ts +31 -0
- package/src/schema/nodes/bibliography_element.ts +58 -0
- package/src/schema/nodes/bibliography_item.ts +108 -0
- package/src/schema/nodes/bibliography_section.ts +60 -0
- package/src/schema/nodes/blockquote_element.ts +79 -0
- package/src/schema/nodes/body.ts +29 -0
- package/src/schema/nodes/box_element.ts +67 -0
- package/src/schema/nodes/caption.ts +67 -0
- package/src/schema/nodes/caption_title.ts +67 -0
- package/src/schema/nodes/citation.ts +70 -0
- package/src/schema/nodes/comment.ts +50 -0
- package/src/schema/nodes/comments.ts +28 -0
- package/src/schema/nodes/contributor.ts +87 -0
- package/src/schema/nodes/contributors.ts +40 -0
- package/src/schema/nodes/core_section.ts +27 -0
- package/src/schema/nodes/corresp.ts +49 -0
- package/src/schema/nodes/cross_reference.ts +64 -0
- package/src/schema/nodes/doc.ts +21 -0
- package/src/schema/nodes/embed.ts +55 -0
- package/src/schema/nodes/equation.ts +65 -0
- package/src/schema/nodes/equation_element.ts +61 -0
- package/src/schema/nodes/figure.ts +65 -0
- package/src/schema/nodes/figure_element.ts +73 -0
- package/src/schema/nodes/footnote.ts +95 -0
- package/src/schema/nodes/footnotes_element.ts +69 -0
- package/src/schema/nodes/footnotes_section.ts +61 -0
- package/src/schema/nodes/general_table_footnote.ts +42 -0
- package/src/schema/nodes/graphical_abstract_section.ts +62 -0
- package/src/schema/nodes/hard_break.ts +36 -0
- package/src/schema/nodes/hero_image.ts +46 -0
- package/src/schema/nodes/highlight_marker.ts +68 -0
- package/src/schema/nodes/image_element.ts +49 -0
- package/src/schema/nodes/inline_equation.ts +68 -0
- package/src/schema/nodes/inline_footnote.ts +66 -0
- package/src/schema/nodes/keyword.ts +61 -0
- package/src/schema/nodes/keyword_group.ts +63 -0
- package/src/schema/nodes/keywords.ts +59 -0
- package/src/schema/nodes/keywords_element.ts +64 -0
- package/src/schema/nodes/link.ts +79 -0
- package/src/schema/nodes/list.ts +134 -0
- package/src/schema/nodes/listing.ts +91 -0
- package/src/schema/nodes/listing_element.ts +61 -0
- package/src/schema/nodes/long_desc.ts +36 -0
- package/src/schema/nodes/manuscript.ts +86 -0
- package/src/schema/nodes/missing_figure.ts +59 -0
- package/src/schema/nodes/paragraph.ts +77 -0
- package/src/schema/nodes/placeholder.ts +62 -0
- package/src/schema/nodes/placeholder_element.ts +60 -0
- package/src/schema/nodes/pullquote_element.ts +81 -0
- package/src/schema/nodes/quote_image.ts +64 -0
- package/src/schema/nodes/section.ts +69 -0
- package/src/schema/nodes/section_label.ts +39 -0
- package/src/schema/nodes/section_title.ts +58 -0
- package/src/schema/nodes/subtitle.ts +40 -0
- package/src/schema/nodes/subtitles.ts +51 -0
- package/src/schema/nodes/supplement.ts +77 -0
- package/src/schema/nodes/supplements.ts +60 -0
- package/src/schema/nodes/table.ts +144 -0
- package/src/schema/nodes/table_col.ts +76 -0
- package/src/schema/nodes/table_element.ts +67 -0
- package/src/schema/nodes/table_element_footer.ts +42 -0
- package/src/schema/nodes/text.ts +31 -0
- package/src/schema/nodes/title.ts +43 -0
- package/src/schema/nodes/trans_abstract.ts +58 -0
- package/src/schema/nodes/trans_graphical_abstract.ts +67 -0
- package/src/schema/types.ts +240 -0
- package/src/tests.ts +33 -0
- package/src/transformer/id.ts +23 -0
- package/src/transformer/index.ts +21 -0
- package/src/transformer/node-names.ts +73 -0
- package/src/transformer/node-title.ts +111 -0
- package/src/transformer/node-types.ts +39 -0
- package/src/transformer/node-validator.ts +82 -0
- package/src/types.ts +25 -0
- package/src/version.ts +1 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import Citeproc from 'citeproc'
|
|
17
|
+
|
|
18
|
+
import { buildCiteprocCitation } from '../../lib/citeproc'
|
|
19
|
+
import { BibliographyItemAttrs } from '../../schema'
|
|
20
|
+
import { initJats, jatsVariableWrapper } from '../exporter/citeproc'
|
|
21
|
+
import { ama, chicago, DEFAULT_CSL_OPTIONS } from './citations'
|
|
22
|
+
|
|
23
|
+
const bib1: BibliographyItemAttrs = {
|
|
24
|
+
id: 'bib1',
|
|
25
|
+
type: 'article-journal',
|
|
26
|
+
author: [
|
|
27
|
+
{ given: 'John', family: 'Doe' },
|
|
28
|
+
{ given: 'Jane', family: 'Smith' },
|
|
29
|
+
],
|
|
30
|
+
DOI: '10.1000/xyz123',
|
|
31
|
+
issued: { 'date-parts': [[2021]] },
|
|
32
|
+
'container-title': 'AI Research Journal',
|
|
33
|
+
volume: '18',
|
|
34
|
+
issue: '2',
|
|
35
|
+
supplement: 'Suppl. 1',
|
|
36
|
+
page: '45-60',
|
|
37
|
+
title: 'Advancements in Artificial Intelligence',
|
|
38
|
+
locator: 'e012345',
|
|
39
|
+
URL: 'https://doi.org/10.1000/xyz123',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const bib2: BibliographyItemAttrs = {
|
|
43
|
+
id: 'bib2',
|
|
44
|
+
type: 'book',
|
|
45
|
+
author: [
|
|
46
|
+
{ given: 'Michael', family: 'Brown' },
|
|
47
|
+
{ given: 'Anna', family: 'Green' },
|
|
48
|
+
],
|
|
49
|
+
issued: { 'date-parts': [[2020]] },
|
|
50
|
+
'container-title': 'Introduction to Data Science',
|
|
51
|
+
volume: '1',
|
|
52
|
+
'collection-title': 'Data Science Series',
|
|
53
|
+
edition: '2nd',
|
|
54
|
+
publisher: 'Springer',
|
|
55
|
+
'publisher-place': 'New York, USA',
|
|
56
|
+
editor: [
|
|
57
|
+
{ given: 'David', family: 'Williams' },
|
|
58
|
+
{ given: 'Sophia', family: 'Taylor' },
|
|
59
|
+
],
|
|
60
|
+
'number-of-pages': '350',
|
|
61
|
+
URL: 'https://doi.org/10.1000/xyz123',
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const bib3: BibliographyItemAttrs = {
|
|
65
|
+
id: 'bib3',
|
|
66
|
+
type: 'chapter',
|
|
67
|
+
author: [{ given: 'Susan', family: 'Miller' }],
|
|
68
|
+
issued: { 'date-parts': [[2022]] },
|
|
69
|
+
'container-title': 'Handbook of AI',
|
|
70
|
+
page: '105-120',
|
|
71
|
+
title: 'Machine Learning Applications',
|
|
72
|
+
publisher: 'Oxford University Press',
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const bib4: BibliographyItemAttrs = {
|
|
76
|
+
id: 'bib4',
|
|
77
|
+
type: 'confproc',
|
|
78
|
+
author: [{ given: 'Emily', family: 'Johnson' }],
|
|
79
|
+
issued: { 'date-parts': [[2019]] },
|
|
80
|
+
'container-title':
|
|
81
|
+
'Proceedings of the International Conference on Machine Learning',
|
|
82
|
+
page: '223-230',
|
|
83
|
+
title: 'Deep Learning in Image Processing',
|
|
84
|
+
publisher: 'IEEE',
|
|
85
|
+
'publisher-place': 'New York, USA',
|
|
86
|
+
event: 'ICML 2019',
|
|
87
|
+
'event-place': 'San Francisco, USA',
|
|
88
|
+
'event-date': { 'date-parts': [[2019, 6, 20]] },
|
|
89
|
+
URL: 'https://icml2019.org/papers/223',
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const bib5: BibliographyItemAttrs = {
|
|
93
|
+
id: 'bib5',
|
|
94
|
+
type: 'thesis',
|
|
95
|
+
author: [{ given: 'Daniel', family: 'Garcia' }],
|
|
96
|
+
DOI: '10.1234/thesis2021',
|
|
97
|
+
issued: { 'date-parts': [[2021]] },
|
|
98
|
+
title: 'Neural Networks for Natural Language Processing',
|
|
99
|
+
institution: 'University of California, Berkeley',
|
|
100
|
+
'number-of-pages': '350',
|
|
101
|
+
URL: 'https://escholarship.org/uc/item/xyz123',
|
|
102
|
+
comment:
|
|
103
|
+
'Located at: Modern Manuscripts Collection,\n' +
|
|
104
|
+
' History of Medicine Division, National Library of\n' +
|
|
105
|
+
' Medicine, Bethesda, MD; MS F 179',
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const bib6: BibliographyItemAttrs = {
|
|
109
|
+
id: 'bib6',
|
|
110
|
+
type: 'webpage',
|
|
111
|
+
author: [{ given: 'Sarah', family: 'Jones' }],
|
|
112
|
+
issued: { 'date-parts': [[2023]] },
|
|
113
|
+
'container-title': 'Data Science Blog',
|
|
114
|
+
title: 'Big Data Trends in 2023',
|
|
115
|
+
accessed: { 'date-parts': [[2024, 2, 15]] },
|
|
116
|
+
URL: 'https://www.datascienceblog.com/big-data-2023',
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const bib7: BibliographyItemAttrs = {
|
|
120
|
+
id: 'bib7',
|
|
121
|
+
type: 'other',
|
|
122
|
+
author: [{ given: 'Lisa', family: 'Adams' }],
|
|
123
|
+
DOI: undefined,
|
|
124
|
+
issued: { 'date-parts': [[2022]] },
|
|
125
|
+
'container-title': 'Internal Research Report',
|
|
126
|
+
title: 'Private Research Report on AI Ethics',
|
|
127
|
+
publisher: 'AI Ethics Initiative',
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const buildCitation = (id: string) =>
|
|
131
|
+
buildCiteprocCitation({
|
|
132
|
+
id: `${id}-citation`,
|
|
133
|
+
rids: [id],
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
describe('Export formatted references', () => {
|
|
137
|
+
initJats()
|
|
138
|
+
|
|
139
|
+
const data = [
|
|
140
|
+
['AMA', ama],
|
|
141
|
+
['Chicago Author Date', chicago],
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
test.each(data)('Export references in %s style', async (name, style) => {
|
|
145
|
+
const bibitems: Map<string, BibliographyItemAttrs> = new Map()
|
|
146
|
+
bibitems.set(bib1.id, bib1)
|
|
147
|
+
bibitems.set(bib2.id, bib2)
|
|
148
|
+
bibitems.set(bib3.id, bib3)
|
|
149
|
+
bibitems.set(bib4.id, bib4)
|
|
150
|
+
bibitems.set(bib5.id, bib5)
|
|
151
|
+
bibitems.set(bib6.id, bib6)
|
|
152
|
+
bibitems.set(bib7.id, bib7)
|
|
153
|
+
|
|
154
|
+
const citations: Citeproc.Citation[] = [
|
|
155
|
+
buildCitation(bib1.id),
|
|
156
|
+
buildCitation(bib2.id),
|
|
157
|
+
buildCitation(bib3.id),
|
|
158
|
+
buildCitation(bib4.id),
|
|
159
|
+
buildCitation(bib5.id),
|
|
160
|
+
buildCitation(bib6.id),
|
|
161
|
+
buildCitation(bib7.id),
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
initJats()
|
|
165
|
+
const engine = new Citeproc.Engine(
|
|
166
|
+
{
|
|
167
|
+
retrieveLocale: () => DEFAULT_CSL_OPTIONS.locale,
|
|
168
|
+
retrieveItem: (id: string) => {
|
|
169
|
+
const item = bibitems.get(id)
|
|
170
|
+
if (!item) {
|
|
171
|
+
throw Error(`Missing bibliography item with id ${id}`)
|
|
172
|
+
}
|
|
173
|
+
return item as CSL.Data
|
|
174
|
+
},
|
|
175
|
+
variableWrapper: jatsVariableWrapper,
|
|
176
|
+
},
|
|
177
|
+
style
|
|
178
|
+
)
|
|
179
|
+
engine.setOutputFormat('jats')
|
|
180
|
+
|
|
181
|
+
const citationTexts = engine.rebuildProcessorState(citations)
|
|
182
|
+
const [meta, bibliography] = engine.makeBibliography()
|
|
183
|
+
|
|
184
|
+
//eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
185
|
+
for (const [id, _, text] of citationTexts) {
|
|
186
|
+
expect(text).toMatchSnapshot(id)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
for (let i = 0; i < bibliography.length; i++) {
|
|
190
|
+
const id = meta.entry_ids[i][0]
|
|
191
|
+
const fragment = bibliography[i]
|
|
192
|
+
expect(fragment).toMatchSnapshot(id)
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2024 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { createArticleNode } from '../importer/create-article-node'
|
|
18
|
+
import { changeIDs } from './utils'
|
|
19
|
+
|
|
20
|
+
describe('Create empty document', () => {
|
|
21
|
+
it('should create an empty document', () => {
|
|
22
|
+
const doc = createArticleNode({
|
|
23
|
+
id: 'manuscript:123',
|
|
24
|
+
articleType: 'research-article',
|
|
25
|
+
})
|
|
26
|
+
changeIDs(doc)
|
|
27
|
+
expect(doc).toMatchSnapshot()
|
|
28
|
+
})
|
|
29
|
+
})
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2024 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { SectionCategory } from '../../../schema'
|
|
18
|
+
|
|
19
|
+
export const sectionCategories: SectionCategory[] = [
|
|
20
|
+
{
|
|
21
|
+
id: 'abstract',
|
|
22
|
+
titles: ['Abstract'],
|
|
23
|
+
synonyms: [''],
|
|
24
|
+
group: 'abstracts',
|
|
25
|
+
isUnique: true,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: 'abstract-graphical',
|
|
29
|
+
titles: ['Graphical Abstract'],
|
|
30
|
+
synonyms: [''],
|
|
31
|
+
group: 'abstracts-graphic',
|
|
32
|
+
isUnique: true,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'abstract-key-image',
|
|
36
|
+
titles: ['Key Image'],
|
|
37
|
+
synonyms: [''],
|
|
38
|
+
group: 'abstracts-graphic',
|
|
39
|
+
isUnique: true,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'abstract-short',
|
|
43
|
+
titles: ['Short'],
|
|
44
|
+
synonyms: [''],
|
|
45
|
+
group: 'abstracts',
|
|
46
|
+
isUnique: true,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'abstract-teaser',
|
|
50
|
+
titles: ['Abstract Teaser'],
|
|
51
|
+
synonyms: [''],
|
|
52
|
+
isUnique: true,
|
|
53
|
+
group: 'abstracts',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'abstract-toc',
|
|
57
|
+
titles: ['Table of contents'],
|
|
58
|
+
synonyms: [''],
|
|
59
|
+
group: 'abstracts',
|
|
60
|
+
isUnique: true,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 'acknowledgements',
|
|
64
|
+
synonyms: ['acknowledgements', 'acknowledgments'],
|
|
65
|
+
titles: ['Acknowledgements'],
|
|
66
|
+
group: 'backmatter',
|
|
67
|
+
isUnique: true,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: 'appendices',
|
|
71
|
+
titles: ['Appendices'],
|
|
72
|
+
synonyms: ['appendices'],
|
|
73
|
+
isUnique: false,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 'availability',
|
|
77
|
+
titles: ['Availability'],
|
|
78
|
+
synonyms: ['availability', 'data-availability', 'data availability'],
|
|
79
|
+
group: 'backmatter',
|
|
80
|
+
isUnique: true,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: 'coi-statement',
|
|
84
|
+
synonyms: [
|
|
85
|
+
'coi-statement',
|
|
86
|
+
'competing-interests',
|
|
87
|
+
'conflict',
|
|
88
|
+
'conflict of interest',
|
|
89
|
+
'competing interests',
|
|
90
|
+
],
|
|
91
|
+
label: 'Conflict of Interest',
|
|
92
|
+
titles: [
|
|
93
|
+
'Conflict of Interest Statement',
|
|
94
|
+
'COI Statement',
|
|
95
|
+
'Competing Interests',
|
|
96
|
+
],
|
|
97
|
+
group: 'backmatter',
|
|
98
|
+
isUnique: true,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: 'con',
|
|
102
|
+
synonyms: ['con'],
|
|
103
|
+
titles: ['Contributed-by information'],
|
|
104
|
+
group: 'backmatter',
|
|
105
|
+
isUnique: true,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: 'conclusions',
|
|
109
|
+
synonyms: ['conclusions'],
|
|
110
|
+
titles: ['Conclusions'],
|
|
111
|
+
group: 'body',
|
|
112
|
+
isUnique: false,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: 'deceased',
|
|
116
|
+
titles: ['Deceased'],
|
|
117
|
+
synonyms: ['deceased'],
|
|
118
|
+
isUnique: false,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: 'discussion',
|
|
122
|
+
synonyms: ['discussion'],
|
|
123
|
+
titles: ['Discussion'],
|
|
124
|
+
group: 'body',
|
|
125
|
+
isUnique: false,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: 'equal',
|
|
129
|
+
titles: ['Equal'],
|
|
130
|
+
synonyms: ['equal'],
|
|
131
|
+
isUnique: false,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'ethics-statement',
|
|
135
|
+
synonyms: ['ethics-statement'],
|
|
136
|
+
titles: ['Ethics Statement'],
|
|
137
|
+
group: 'backmatter',
|
|
138
|
+
isUnique: true,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: 'financial-disclosure',
|
|
142
|
+
synonyms: ['financial-disclosure', 'funding information'],
|
|
143
|
+
titles: ['Financial Disclosure'],
|
|
144
|
+
group: 'backmatter',
|
|
145
|
+
isUnique: true,
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: 'intro',
|
|
149
|
+
synonyms: ['intro', 'introduction'],
|
|
150
|
+
titles: ['Introduction'],
|
|
151
|
+
group: 'body',
|
|
152
|
+
isUnique: false,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: 'methods',
|
|
156
|
+
synonyms: [
|
|
157
|
+
'materials',
|
|
158
|
+
'methods',
|
|
159
|
+
'materials and methods',
|
|
160
|
+
'materials & methods',
|
|
161
|
+
],
|
|
162
|
+
titles: ['Materials & Methods'],
|
|
163
|
+
group: 'body',
|
|
164
|
+
isUnique: false,
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: 'present-address',
|
|
168
|
+
titles: ['Present Address'],
|
|
169
|
+
synonyms: ['present-address'],
|
|
170
|
+
isUnique: false,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
id: 'presented-at',
|
|
174
|
+
titles: ['Presented at'],
|
|
175
|
+
synonyms: ['presented-at'],
|
|
176
|
+
isUnique: false,
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
id: 'previously-at',
|
|
180
|
+
titles: ['Previously at'],
|
|
181
|
+
synonyms: ['previously-at'],
|
|
182
|
+
isUnique: false,
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: 'results',
|
|
186
|
+
synonyms: ['results'],
|
|
187
|
+
titles: ['Results'],
|
|
188
|
+
group: 'body',
|
|
189
|
+
isUnique: false,
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
id: 'review',
|
|
193
|
+
titles: ['Review'],
|
|
194
|
+
synonyms: [],
|
|
195
|
+
group: 'body',
|
|
196
|
+
isUnique: false,
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: 'supplementary-material',
|
|
200
|
+
synonyms: ['supplementary-material'],
|
|
201
|
+
titles: ['Supplementary Material'],
|
|
202
|
+
group: 'backmatter',
|
|
203
|
+
isUnique: true,
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
id: 'supported-by',
|
|
207
|
+
synonyms: ['supported-by'],
|
|
208
|
+
titles: ['Supported By'],
|
|
209
|
+
group: 'backmatter',
|
|
210
|
+
isUnique: true,
|
|
211
|
+
},
|
|
212
|
+
]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2020 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import fs from 'fs'
|
|
18
|
+
import { join } from 'path'
|
|
19
|
+
|
|
20
|
+
export const readFixture = (filename: string) =>
|
|
21
|
+
fs.promises.readFile(join(__dirname, '/__fixtures__/', filename), 'utf-8')
|
|
22
|
+
|
|
23
|
+
export const readAndParseFixture = async (filename: string) =>
|
|
24
|
+
new DOMParser().parseFromString(await readFixture(filename), 'text/xml')
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2019 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { Element as XMLElement, parseXml } from 'libxmljs2'
|
|
18
|
+
|
|
19
|
+
import { JATSExporter } from '../exporter/jats-exporter'
|
|
20
|
+
import { Version } from '../exporter/jats-versions'
|
|
21
|
+
import { parseJATSArticle } from '../importer/parse-jats-article'
|
|
22
|
+
import { DEFAULT_CSL_OPTIONS } from './citations'
|
|
23
|
+
import { sectionCategories } from './data/section-categories'
|
|
24
|
+
import { readAndParseFixture } from './files'
|
|
25
|
+
import { BibliographyItemNode, isBibliographyItemNode } from '../../schema'
|
|
26
|
+
|
|
27
|
+
const parseXMLWithDTD = (data: string) =>
|
|
28
|
+
parseXml(data, {
|
|
29
|
+
dtdload: true,
|
|
30
|
+
dtdvalid: true,
|
|
31
|
+
nonet: true,
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
describe('JATS exporter', () => {
|
|
35
|
+
test('export latest version', async () => {
|
|
36
|
+
const transformer = new JATSExporter()
|
|
37
|
+
const input = await readAndParseFixture('jats-example-full.xml')
|
|
38
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
39
|
+
const result = await transformer.serializeToJATS(node, {
|
|
40
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
expect(result).toMatchSnapshot('jats-export')
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('export with & and < in bibliography metadata', async () => {
|
|
47
|
+
const transformer = new JATSExporter()
|
|
48
|
+
const input = await readAndParseFixture('jats-example-full.xml')
|
|
49
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
50
|
+
|
|
51
|
+
let biblio: BibliographyItemNode | null = null
|
|
52
|
+
node.descendants((n) => {
|
|
53
|
+
if (isBibliographyItemNode(n)) {
|
|
54
|
+
biblio = n
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
biblio!.attrs.title += ' & Sons 55 < 135'
|
|
59
|
+
|
|
60
|
+
const result = await transformer.serializeToJATS(node, {
|
|
61
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
expect(result).toMatchSnapshot('jats-export-with-xml-unsafe-in-biblios')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('export v1.1', async () => {
|
|
68
|
+
const transformer = new JATSExporter()
|
|
69
|
+
const input = await readAndParseFixture('jats-example-full.xml')
|
|
70
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
71
|
+
const result = await transformer.serializeToJATS(node, {
|
|
72
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
73
|
+
version: '1.1',
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
expect(result).toMatchSnapshot('jats-export-1.1')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('export unknown version', async () => {
|
|
80
|
+
const transformer = new JATSExporter()
|
|
81
|
+
const input = await readAndParseFixture('jats-example-full.xml')
|
|
82
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
83
|
+
|
|
84
|
+
await expect(async () => {
|
|
85
|
+
await transformer.serializeToJATS(node, {
|
|
86
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
87
|
+
version: '1.0' as unknown as Version,
|
|
88
|
+
})
|
|
89
|
+
}).rejects.toThrow(Error)
|
|
90
|
+
})
|
|
91
|
+
test('export table-wrap-foot', async () => {
|
|
92
|
+
const transformer = new JATSExporter()
|
|
93
|
+
const input = await readAndParseFixture('jats-tables-example.xml')
|
|
94
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
95
|
+
const xml = await transformer.serializeToJATS(node, {
|
|
96
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
const resultDoc = parseXMLWithDTD(xml)
|
|
100
|
+
const tableWrapFoot = resultDoc.get('//table-wrap/table-wrap-foot')
|
|
101
|
+
const paragraph = resultDoc.get('//table-wrap/table-wrap-foot/p')
|
|
102
|
+
expect(paragraph).not.toBeUndefined()
|
|
103
|
+
expect(tableWrapFoot).not.toBeUndefined()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test('DTD validation', async () => {
|
|
107
|
+
const transformer = new JATSExporter()
|
|
108
|
+
const input = await readAndParseFixture('jats-import.xml')
|
|
109
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
110
|
+
const xml = await transformer.serializeToJATS(node, {
|
|
111
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
const { errors } = parseXMLWithDTD(xml)
|
|
115
|
+
|
|
116
|
+
expect(errors).toHaveLength(0)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
test('DTD validation: article with title markup and citations', async () => {
|
|
120
|
+
const transformer = new JATSExporter()
|
|
121
|
+
const input = await readAndParseFixture('jats-document.xml')
|
|
122
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
123
|
+
const xml = await transformer.serializeToJATS(node, {
|
|
124
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
125
|
+
})
|
|
126
|
+
const { errors } = parseXMLWithDTD(xml)
|
|
127
|
+
|
|
128
|
+
expect(errors).toHaveLength(0)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
test('Export link', async () => {
|
|
132
|
+
const transformer = new JATSExporter()
|
|
133
|
+
const input = await readAndParseFixture('jats-import.xml')
|
|
134
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
135
|
+
const xml = await transformer.serializeToJATS(node, {
|
|
136
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
const output = parseXMLWithDTD(xml)
|
|
140
|
+
const link = output.get<XMLElement>('//ext-link[@ext-link-type="uri"]')
|
|
141
|
+
expect(link).not.toBeNull()
|
|
142
|
+
expect(link!.text()).toBe('https//orcid.org/0000-0003-2217-5904')
|
|
143
|
+
|
|
144
|
+
const attrs: { [key: string]: string } = {}
|
|
145
|
+
|
|
146
|
+
for (const attr of link!.attrs()) {
|
|
147
|
+
attrs[attr.name()] = attr.value()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
expect(attrs.href).toBe('https://orcid.org/0000-0003-2217-5904')
|
|
151
|
+
expect(attrs['ext-link-type']).toBe('uri')
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
test('DTD validation for MathML representation', async () => {
|
|
155
|
+
const transformer = new JATSExporter()
|
|
156
|
+
const input = await readAndParseFixture('jats-example-doc.xml')
|
|
157
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
158
|
+
const xml = await transformer.serializeToJATS(node, {
|
|
159
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
const { errors } = parseXMLWithDTD(xml)
|
|
163
|
+
|
|
164
|
+
expect(errors).toHaveLength(0)
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
test('export with supplement', async () => {
|
|
168
|
+
const transformer = new JATSExporter()
|
|
169
|
+
const input = await readAndParseFixture('jats-import.xml')
|
|
170
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
171
|
+
const xml = await transformer.serializeToJATS(node, {
|
|
172
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
173
|
+
})
|
|
174
|
+
const resultDoc = parseXMLWithDTD(xml)
|
|
175
|
+
const supplementaryMaterial = resultDoc.get('//supplementary-material')
|
|
176
|
+
if (!supplementaryMaterial) {
|
|
177
|
+
throw new Error('No supplementary material found')
|
|
178
|
+
}
|
|
179
|
+
//@ts-ignore
|
|
180
|
+
const textContent = supplementaryMaterial.text().trim()
|
|
181
|
+
//@ts-ignore
|
|
182
|
+
const mimeTypeAttr = supplementaryMaterial.attr('mimetype')
|
|
183
|
+
//@ts-ignore
|
|
184
|
+
const mimeSubtypeAttr = supplementaryMaterial.attr('mime-subtype')
|
|
185
|
+
//@ts-ignore
|
|
186
|
+
const hrefAttr = supplementaryMaterial.attr('href')
|
|
187
|
+
|
|
188
|
+
expect(textContent).toBe(
|
|
189
|
+
'final manuscript-hum-huili-dbh-suicide-20200707_figures (9)'
|
|
190
|
+
)
|
|
191
|
+
expect(mimeTypeAttr?.value()).toBe('application')
|
|
192
|
+
expect(mimeSubtypeAttr?.value()).toBe(
|
|
193
|
+
'vnd.openxmlformats-officedocument.wordprocessingml.document'
|
|
194
|
+
)
|
|
195
|
+
expect(hrefAttr?.value()).toBe(
|
|
196
|
+
'attachment:7d9d686b-5488-44a5-a1c5-46351e7f9312'
|
|
197
|
+
)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
test('export footnotes', async () => {
|
|
201
|
+
const transformer = new JATSExporter()
|
|
202
|
+
const input = await readAndParseFixture('jats-fn-group.xml')
|
|
203
|
+
const node = parseJATSArticle(input, sectionCategories)
|
|
204
|
+
const xml = await transformer.serializeToJATS(node, {
|
|
205
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
206
|
+
})
|
|
207
|
+
const footnoteCategories = [
|
|
208
|
+
'con',
|
|
209
|
+
'deceased',
|
|
210
|
+
'equal',
|
|
211
|
+
'financial-disclosure',
|
|
212
|
+
]
|
|
213
|
+
|
|
214
|
+
const resultDoc = parseXMLWithDTD(xml)
|
|
215
|
+
|
|
216
|
+
for (const category of footnoteCategories) {
|
|
217
|
+
const fn = resultDoc.get(
|
|
218
|
+
`/article/back/fn-group/fn[@fn-type="${category}"]`
|
|
219
|
+
)
|
|
220
|
+
expect(fn).not.toBeUndefined()
|
|
221
|
+
}
|
|
222
|
+
})
|
|
223
|
+
})
|