@manuscripts/transform 1.2.4-LEAN-2066 → 1.2.5
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/importer/jats-body-dom-parser.js +1 -33
- package/dist/cjs/jats/importer/jats-body-transformations.js +53 -26
- package/dist/cjs/jats/importer/jats-comments.js +0 -24
- package/dist/cjs/jats/importer/jats-front-parser.js +25 -0
- package/dist/cjs/jats/importer/parse-jats-article.js +6 -3
- package/dist/cjs/jats/jats-exporter.js +54 -19
- package/dist/cjs/schema/index.js +0 -2
- package/dist/cjs/schema/nodes/keyword.js +2 -1
- package/dist/cjs/schema/nodes/keywords_element.js +1 -2
- package/dist/cjs/schema/nodes/keywords_section.js +1 -1
- package/dist/cjs/schema/nodes/section.js +1 -1
- package/dist/cjs/transformer/decode.js +23 -29
- package/dist/cjs/transformer/encode.js +13 -9
- package/dist/cjs/transformer/node-types.js +0 -1
- package/dist/cjs/transformer/object-types.js +1 -2
- package/dist/cjs/transformer/section-category.js +23 -1
- package/dist/es/jats/importer/jats-body-dom-parser.js +1 -33
- package/dist/es/jats/importer/jats-body-transformations.js +54 -27
- package/dist/es/jats/importer/jats-comments.js +1 -25
- package/dist/es/jats/importer/jats-front-parser.js +26 -1
- package/dist/es/jats/importer/parse-jats-article.js +6 -3
- package/dist/es/jats/jats-exporter.js +54 -19
- package/dist/es/schema/index.js +0 -2
- package/dist/es/schema/nodes/keyword.js +2 -1
- package/dist/es/schema/nodes/keywords_element.js +1 -2
- package/dist/es/schema/nodes/keywords_section.js +1 -1
- package/dist/es/schema/nodes/section.js +1 -1
- package/dist/es/transformer/decode.js +23 -29
- package/dist/es/transformer/encode.js +14 -10
- package/dist/es/transformer/node-types.js +0 -1
- package/dist/es/transformer/object-types.js +0 -1
- package/dist/es/transformer/section-category.js +19 -1
- package/dist/types/jats/importer/jats-body-transformations.d.ts +7 -2
- package/dist/types/jats/importer/jats-front-parser.d.ts +11 -6
- package/dist/types/jats/jats-exporter.d.ts +2 -0
- package/dist/types/schema/types.d.ts +1 -1
- package/dist/types/transformer/decode.d.ts +0 -1
- package/dist/types/transformer/object-types.d.ts +1 -2
- package/dist/types/transformer/section-category.d.ts +3 -2
- package/package.json +2 -2
- package/dist/cjs/schema/nodes/keywords_group.js +0 -48
- package/dist/es/schema/nodes/keywords_group.js +0 -44
- package/dist/types/schema/nodes/keywords_group.d.ts +0 -26
|
@@ -14,8 +14,12 @@
|
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
17
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.chooseSectionCategoryFromTitle = exports.chooseSectionCategory = exports.chooseSectionCategoryByType = exports.chooseSecType = exports.buildSectionCategory = exports.guessSectionCategory = exports.chooseSectionLableName = exports.chooseSectionNodeType = exports.isAnySectionNode = void 0;
|
|
21
|
+
exports.chooseSectionCategoryFromTitle = exports.chooseSectionCategory = exports.chooseSectionCategoryByType = exports.chooseSecType = exports.buildSectionCategory = exports.guessSectionCategory = exports.chooseSectionLableName = exports.chooseSectionNodeType = exports.isAnySectionNode = exports.getSectionTitles = void 0;
|
|
22
|
+
const section_categories_json_1 = __importDefault(require("@manuscripts/data/dist/shared/section-categories.json"));
|
|
19
23
|
const json_schema_1 = require("@manuscripts/json-schema");
|
|
20
24
|
const schema_1 = require("../schema");
|
|
21
25
|
const sectionNodeTypes = [
|
|
@@ -25,6 +29,18 @@ const sectionNodeTypes = [
|
|
|
25
29
|
schema_1.schema.nodes.section,
|
|
26
30
|
schema_1.schema.nodes.toc_section,
|
|
27
31
|
];
|
|
32
|
+
const sectionCategoriesMap = new Map(section_categories_json_1.default.map((section) => [
|
|
33
|
+
section._id,
|
|
34
|
+
section,
|
|
35
|
+
]));
|
|
36
|
+
const getSectionTitles = (sectionCategory) => {
|
|
37
|
+
const category = sectionCategoriesMap.get(sectionCategory);
|
|
38
|
+
if (category) {
|
|
39
|
+
return category.titles.length ? category.titles : [' '];
|
|
40
|
+
}
|
|
41
|
+
throw new Error(`${sectionCategory} not found in section categories`);
|
|
42
|
+
};
|
|
43
|
+
exports.getSectionTitles = getSectionTitles;
|
|
28
44
|
const isAnySectionNode = (node) => sectionNodeTypes.includes(node.type);
|
|
29
45
|
exports.isAnySectionNode = isAnySectionNode;
|
|
30
46
|
const chooseSectionNodeType = (category) => {
|
|
@@ -161,6 +177,12 @@ const chooseSectionCategoryByType = (secType) => {
|
|
|
161
177
|
return 'MPSectionCategory:supported-by';
|
|
162
178
|
case 'ethics-statement':
|
|
163
179
|
return 'MPSectionCategory:ethics-statement';
|
|
180
|
+
case 'body':
|
|
181
|
+
return 'MPSectionCategory:body';
|
|
182
|
+
case 'backmatter':
|
|
183
|
+
return 'MPSectionCategory:backmatter';
|
|
184
|
+
case 'abstracts':
|
|
185
|
+
return 'MPSectionCategory:abstracts';
|
|
164
186
|
default:
|
|
165
187
|
return undefined;
|
|
166
188
|
}
|
|
@@ -499,22 +499,6 @@ const nodes = [
|
|
|
499
499
|
};
|
|
500
500
|
},
|
|
501
501
|
},
|
|
502
|
-
{
|
|
503
|
-
tag: 'sec[sec-type="keywords"]',
|
|
504
|
-
node: 'keywords_section',
|
|
505
|
-
getAttrs: (node) => {
|
|
506
|
-
const element = node;
|
|
507
|
-
return {
|
|
508
|
-
id: element.getAttribute('id'),
|
|
509
|
-
category: chooseSectionCategory(element),
|
|
510
|
-
};
|
|
511
|
-
},
|
|
512
|
-
},
|
|
513
|
-
{
|
|
514
|
-
tag: 'kwd-group-list',
|
|
515
|
-
context: 'keywords_section/',
|
|
516
|
-
node: 'keywords_element',
|
|
517
|
-
},
|
|
518
502
|
{
|
|
519
503
|
tag: 'sec',
|
|
520
504
|
node: 'section',
|
|
@@ -526,22 +510,6 @@ const nodes = [
|
|
|
526
510
|
};
|
|
527
511
|
},
|
|
528
512
|
},
|
|
529
|
-
{
|
|
530
|
-
tag: 'kwd-group',
|
|
531
|
-
context: 'keywords_element/',
|
|
532
|
-
node: 'keywords_group',
|
|
533
|
-
getAttrs: (node) => {
|
|
534
|
-
const element = node;
|
|
535
|
-
return {
|
|
536
|
-
type: element.getAttribute('kwd-group-type'),
|
|
537
|
-
};
|
|
538
|
-
},
|
|
539
|
-
},
|
|
540
|
-
{
|
|
541
|
-
tag: 'kwd',
|
|
542
|
-
context: 'keywords_group//',
|
|
543
|
-
node: 'keyword',
|
|
544
|
-
},
|
|
545
513
|
{
|
|
546
514
|
tag: 'label',
|
|
547
515
|
context: 'section/',
|
|
@@ -594,7 +562,7 @@ const nodes = [
|
|
|
594
562
|
{
|
|
595
563
|
tag: 'title',
|
|
596
564
|
node: 'section_title',
|
|
597
|
-
context: 'section/|footnotes_section/|bibliography_section
|
|
565
|
+
context: 'section/|footnotes_section/|bibliography_section/',
|
|
598
566
|
},
|
|
599
567
|
{
|
|
600
568
|
tag: 'title',
|
|
@@ -13,9 +13,20 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { chooseSectionCategoryByType, chooseSecType } from '../../transformer';
|
|
16
|
+
import { chooseSectionCategoryByType, chooseSecType, getSectionTitles, } from '../../transformer';
|
|
17
17
|
const removeNodeFromParent = (node) => node.parentNode && node.parentNode.removeChild(node);
|
|
18
18
|
const capitalizeFirstLetter = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
19
|
+
const createSectionContainer = (type, createElement) => {
|
|
20
|
+
const sectionContainer = createElement('sec');
|
|
21
|
+
const sectionCategory = chooseSectionCategoryByType(type);
|
|
22
|
+
sectionContainer.setAttribute('sec-type', sectionCategory ? chooseSecType(sectionCategory) : '');
|
|
23
|
+
const title = createElement('title');
|
|
24
|
+
title.textContent = sectionCategory
|
|
25
|
+
? getSectionTitles(sectionCategory)[0]
|
|
26
|
+
: ' ';
|
|
27
|
+
sectionContainer.appendChild(title);
|
|
28
|
+
return sectionContainer;
|
|
29
|
+
};
|
|
19
30
|
export const jatsBodyTransformations = {
|
|
20
31
|
ensureSection(body, createElement) {
|
|
21
32
|
let section = createElement('sec');
|
|
@@ -143,34 +154,64 @@ export const jatsBodyTransformations = {
|
|
|
143
154
|
section.append(...floatsGroup.children);
|
|
144
155
|
return section;
|
|
145
156
|
},
|
|
146
|
-
|
|
157
|
+
moveAbstractsIntoContainer(doc, abstractsContainer, createElement) {
|
|
147
158
|
const abstractNodes = doc.querySelectorAll('front > article-meta > abstract');
|
|
148
|
-
|
|
159
|
+
abstractNodes.forEach((abstractNode) => {
|
|
149
160
|
const abstract = this.createAbstract(abstractNode, createElement);
|
|
150
161
|
removeNodeFromParent(abstractNode);
|
|
151
|
-
|
|
152
|
-
}
|
|
162
|
+
abstractsContainer.appendChild(abstract);
|
|
163
|
+
});
|
|
164
|
+
},
|
|
165
|
+
wrapBodySections(doc, bodyContainer) {
|
|
166
|
+
const bodySections = doc.querySelectorAll('body > sec:not([sec-type="backmatter"]), body > sec:not([sec-type])');
|
|
167
|
+
bodySections.forEach((section) => {
|
|
168
|
+
removeNodeFromParent(section);
|
|
169
|
+
bodyContainer.appendChild(section);
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
moveBackSectionsIntoContainer(doc, backmatterContainer) {
|
|
153
173
|
for (const section of doc.querySelectorAll('back > sec')) {
|
|
154
174
|
removeNodeFromParent(section);
|
|
155
|
-
|
|
175
|
+
backmatterContainer.appendChild(section);
|
|
156
176
|
}
|
|
177
|
+
},
|
|
178
|
+
moveAcknowledgmentsIntoContainer(doc, backmatterContainer, createElement) {
|
|
157
179
|
const ackNode = doc.querySelector('back > ack');
|
|
158
180
|
if (ackNode) {
|
|
159
181
|
const acknowledgements = this.createAcknowledgments(ackNode, createElement);
|
|
160
182
|
removeNodeFromParent(ackNode);
|
|
161
|
-
|
|
183
|
+
backmatterContainer.appendChild(acknowledgements);
|
|
162
184
|
}
|
|
185
|
+
},
|
|
186
|
+
moveAppendicesIntoContainer(doc, backmatterContainer, createElement) {
|
|
163
187
|
const appGroup = doc.querySelectorAll('back > app-group > app');
|
|
164
188
|
for (const app of appGroup) {
|
|
165
189
|
const appendix = this.createAppendixSection(app, createElement);
|
|
166
190
|
removeNodeFromParent(app);
|
|
167
|
-
|
|
191
|
+
backmatterContainer.appendChild(appendix);
|
|
168
192
|
}
|
|
193
|
+
},
|
|
194
|
+
moveBibliographyIntoContainer(doc, backmatterContainer, references, createElement) {
|
|
169
195
|
if (references) {
|
|
170
|
-
|
|
196
|
+
backmatterContainer.appendChild(this.createBibliography(doc, references, createElement));
|
|
171
197
|
}
|
|
172
198
|
},
|
|
173
|
-
|
|
199
|
+
moveSectionsToBody(doc, body, references, createElement) {
|
|
200
|
+
const bodyContainer = createSectionContainer('body', createElement);
|
|
201
|
+
const abstractsContainer = createSectionContainer('abstracts', createElement);
|
|
202
|
+
const backmatterContainer = createSectionContainer('backmatter', createElement);
|
|
203
|
+
this.mapFootnotesToSections(doc, backmatterContainer, createElement);
|
|
204
|
+
this.wrapBodySections(doc, bodyContainer);
|
|
205
|
+
this.moveAbstractsIntoContainer(doc, abstractsContainer, createElement);
|
|
206
|
+
this.moveBackSectionsIntoContainer(doc, backmatterContainer);
|
|
207
|
+
this.moveAcknowledgmentsIntoContainer(doc, backmatterContainer, createElement);
|
|
208
|
+
this.moveAppendicesIntoContainer(doc, backmatterContainer, createElement);
|
|
209
|
+
this.moveBibliographyIntoContainer(doc, backmatterContainer, references, createElement);
|
|
210
|
+
body.insertBefore(abstractsContainer, body.firstChild);
|
|
211
|
+
body.insertBefore(bodyContainer, abstractsContainer.nextSibling);
|
|
212
|
+
body.append(backmatterContainer);
|
|
213
|
+
},
|
|
214
|
+
mapFootnotesToSections(doc, backmatterContainer, createElement) {
|
|
174
215
|
const footnoteGroups = [...doc.querySelectorAll('fn[fn-type]')];
|
|
175
216
|
for (const footnote of footnoteGroups) {
|
|
176
217
|
const type = footnote.getAttribute('fn-type') || '';
|
|
@@ -187,7 +228,7 @@ export const jatsBodyTransformations = {
|
|
|
187
228
|
section.append(...footnote.children);
|
|
188
229
|
removeNodeFromParent(footnote);
|
|
189
230
|
section.setAttribute('sec-type', chooseSecType(category));
|
|
190
|
-
|
|
231
|
+
backmatterContainer.append(section);
|
|
191
232
|
}
|
|
192
233
|
}
|
|
193
234
|
const footnotes = [...doc.querySelectorAll('fn')];
|
|
@@ -202,7 +243,7 @@ export const jatsBodyTransformations = {
|
|
|
202
243
|
}
|
|
203
244
|
if (!footnotesSection && containingGroup.innerHTML) {
|
|
204
245
|
const section = this.createFootnotes([containingGroup], createElement);
|
|
205
|
-
|
|
246
|
+
backmatterContainer.append(section);
|
|
206
247
|
}
|
|
207
248
|
let regularFootnoteGroups = [
|
|
208
249
|
...doc.querySelectorAll('back > fn-group:not([fn-type])'),
|
|
@@ -215,7 +256,7 @@ export const jatsBodyTransformations = {
|
|
|
215
256
|
if (regularFootnoteGroups.length > 0) {
|
|
216
257
|
regularFootnoteGroups.map((g) => removeNodeFromParent(g));
|
|
217
258
|
const footnotes = this.createFootnotes(regularFootnoteGroups, createElement);
|
|
218
|
-
|
|
259
|
+
backmatterContainer.appendChild(footnotes);
|
|
219
260
|
}
|
|
220
261
|
},
|
|
221
262
|
moveCaptionsToEnd(body) {
|
|
@@ -263,18 +304,4 @@ export const jatsBodyTransformations = {
|
|
|
263
304
|
paragraph === null || paragraph === void 0 ? void 0 : paragraph.replaceWith(parent);
|
|
264
305
|
});
|
|
265
306
|
},
|
|
266
|
-
moveKeywordsToBody(document, body, createElement) {
|
|
267
|
-
const keywordGroups = [...document.querySelectorAll('kwd-group')];
|
|
268
|
-
if (keywordGroups.length > 0) {
|
|
269
|
-
const section = createElement('sec');
|
|
270
|
-
section.setAttribute('sec-type', 'keywords');
|
|
271
|
-
const title = createElement('title');
|
|
272
|
-
title.textContent = 'Keywords';
|
|
273
|
-
section.append(title);
|
|
274
|
-
const kwdGroupsEl = createElement('kwd-group-list');
|
|
275
|
-
kwdGroupsEl.append(keywordGroups[0]);
|
|
276
|
-
section.append(kwdGroupsEl);
|
|
277
|
-
body.prepend(section);
|
|
278
|
-
}
|
|
279
|
-
},
|
|
280
307
|
};
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import { v4 as uuidv4 } from 'uuid';
|
|
17
|
-
import { buildComment, buildContribution, isCommentAnnotation, isHighlightableModel,
|
|
17
|
+
import { buildComment, buildContribution, isCommentAnnotation, isHighlightableModel, } from '../../transformer';
|
|
18
18
|
const DEFAULT_ANNOTATION_COLOR = 'rgb(250, 224, 150)';
|
|
19
19
|
const DEFAULT_PROFILE_ID = 'MPUserProfile:0000000000000000000000000000000000000001';
|
|
20
20
|
export const parseProcessingInstruction = (node) => {
|
|
@@ -58,21 +58,6 @@ const insertToken = (doc, processingInstructionNode, authorQueriesMap) => {
|
|
|
58
58
|
return parentElement.insertBefore(tokenNode, processingInstructionNode);
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
|
-
const extractCommentsFromKeywords = (tokens, model, authorQueriesMap) => {
|
|
62
|
-
var _a;
|
|
63
|
-
const commentAnnotations = [];
|
|
64
|
-
const name = model.name;
|
|
65
|
-
const filteredTokens = filterAndSortTokens(tokens, name);
|
|
66
|
-
let content = name;
|
|
67
|
-
for (const token of filteredTokens) {
|
|
68
|
-
content = name.replace(token, '');
|
|
69
|
-
const query = authorQueriesMap.get(token);
|
|
70
|
-
const commentAnnotation = buildComment((_a = model.containedGroup) !== null && _a !== void 0 ? _a : uuidv4(), `${query}`, undefined, [buildContribution(DEFAULT_PROFILE_ID)], DEFAULT_ANNOTATION_COLOR);
|
|
71
|
-
model['name'] = content;
|
|
72
|
-
commentAnnotations.push(commentAnnotation);
|
|
73
|
-
}
|
|
74
|
-
return commentAnnotations;
|
|
75
|
-
};
|
|
76
61
|
export const createComments = (authorQueriesMap, manuscriptModels) => {
|
|
77
62
|
const tokens = [...authorQueriesMap.keys()];
|
|
78
63
|
const commentAnnotations = [];
|
|
@@ -81,18 +66,9 @@ export const createComments = (authorQueriesMap, manuscriptModels) => {
|
|
|
81
66
|
const comments = addCommentsFromMarkedProcessingInstructions(tokens, model, authorQueriesMap);
|
|
82
67
|
commentAnnotations.push(...comments);
|
|
83
68
|
}
|
|
84
|
-
else if (isKeyword(model)) {
|
|
85
|
-
const comments = extractCommentsFromKeywords(tokens, model, authorQueriesMap);
|
|
86
|
-
commentAnnotations.push(...comments);
|
|
87
|
-
}
|
|
88
69
|
}
|
|
89
70
|
return commentAnnotations;
|
|
90
71
|
};
|
|
91
|
-
function filterAndSortTokens(tokens, content) {
|
|
92
|
-
return tokens
|
|
93
|
-
.filter((token) => content.indexOf(token) >= 0)
|
|
94
|
-
.sort((a, b) => content.indexOf(a) - content.indexOf(b));
|
|
95
|
-
}
|
|
96
72
|
const addCommentsFromMarkedProcessingInstructions = (tokens, model, authorQueriesMap) => {
|
|
97
73
|
const commentAnnotations = [];
|
|
98
74
|
for (const field of ['contents', 'caption', 'title']) {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import debug from 'debug';
|
|
17
|
-
import { buildAffiliation, buildBibliographicName, buildContributor, buildCorresp, buildFootnote, buildSupplementaryMaterial, } from '../../transformer/builders';
|
|
17
|
+
import { buildAffiliation, buildBibliographicName, buildContributor, buildCorresp, buildFootnote, buildKeyword, buildKeywordGroup, buildSupplementaryMaterial, } from '../../transformer/builders';
|
|
18
18
|
import { parseJournalMeta } from './jats-journal-meta-parser';
|
|
19
19
|
const warn = debug('manuscripts-transform');
|
|
20
20
|
const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';
|
|
@@ -62,6 +62,31 @@ export const jatsFrontParser = {
|
|
|
62
62
|
}
|
|
63
63
|
return parseJournalMeta(journalMeta);
|
|
64
64
|
},
|
|
65
|
+
parseKeywords(keywordGroupNodes) {
|
|
66
|
+
var _a, _b;
|
|
67
|
+
if (!keywordGroupNodes) {
|
|
68
|
+
return { groups: [], keywords: [] };
|
|
69
|
+
}
|
|
70
|
+
let keywordPriority = 1;
|
|
71
|
+
const keywordGroups = { groups: [], keywords: [] };
|
|
72
|
+
for (const keywordGroupNode of keywordGroupNodes) {
|
|
73
|
+
const manuscriptKeywordGroup = buildKeywordGroup({
|
|
74
|
+
title: ((_a = keywordGroupNode.querySelector('title')) === null || _a === void 0 ? void 0 : _a.textContent) || undefined,
|
|
75
|
+
label: ((_b = keywordGroupNode.querySelector('label')) === null || _b === void 0 ? void 0 : _b.textContent) || undefined,
|
|
76
|
+
type: keywordGroupNode.getAttribute('kwd-group-type') || undefined,
|
|
77
|
+
});
|
|
78
|
+
keywordGroups.groups.push(manuscriptKeywordGroup);
|
|
79
|
+
for (const keywordNode of keywordGroupNode.querySelectorAll('kwd')) {
|
|
80
|
+
if (keywordNode.textContent) {
|
|
81
|
+
const keyword = buildKeyword(keywordNode.textContent);
|
|
82
|
+
keyword.priority = keywordPriority++;
|
|
83
|
+
keyword.containedGroup = manuscriptKeywordGroup._id;
|
|
84
|
+
keywordGroups.keywords.push(keyword);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return keywordGroups;
|
|
89
|
+
},
|
|
65
90
|
parseDates(historyNode) {
|
|
66
91
|
if (!historyNode) {
|
|
67
92
|
return undefined;
|
|
@@ -51,6 +51,9 @@ export const parseJATSFront = async (front) => {
|
|
|
51
51
|
const manuscriptMeta = Object.assign({ title: title ? inlineContentsFromJATSTitle(title) : undefined, subtitle: subtitle ? inlineContentsFromJATSTitle(subtitle) : undefined, runningTitle: runningTitle
|
|
52
52
|
? inlineContentsFromJATSTitle(runningTitle)
|
|
53
53
|
: undefined }, jatsFrontParser.parseCounts(articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('counts')));
|
|
54
|
+
const keywordGroupNodes = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelectorAll('kwd-group');
|
|
55
|
+
const { keywords, groups: keywordGroups } = jatsFrontParser.parseKeywords(keywordGroupNodes);
|
|
56
|
+
const manuscript_keywordIDs = keywords.length > 0 ? keywords.map((k) => k._id) : undefined;
|
|
54
57
|
const { affiliations, affiliationIDs } = jatsFrontParser.parseAffiliationNodes([
|
|
55
58
|
...front.querySelectorAll('article-meta > contrib-group > aff'),
|
|
56
59
|
]);
|
|
@@ -67,12 +70,14 @@ export const parseJATSFront = async (front) => {
|
|
|
67
70
|
const supplements = jatsFrontParser.parseSupplements([
|
|
68
71
|
...front.querySelectorAll('article-meta > supplementary-material'),
|
|
69
72
|
]);
|
|
70
|
-
const manuscript = Object.assign(Object.assign(Object.assign({}, buildManuscript()), manuscriptMeta), history);
|
|
73
|
+
const manuscript = Object.assign(Object.assign(Object.assign(Object.assign({}, buildManuscript()), manuscriptMeta), { keywordIDs: manuscript_keywordIDs }), history);
|
|
71
74
|
return {
|
|
72
75
|
models: generateModelIDs([
|
|
73
76
|
manuscript,
|
|
77
|
+
...keywords,
|
|
74
78
|
...affiliations,
|
|
75
79
|
...authors,
|
|
80
|
+
...keywordGroups,
|
|
76
81
|
...footnotes,
|
|
77
82
|
...correspondingList,
|
|
78
83
|
journal,
|
|
@@ -106,12 +111,10 @@ export const parseJATSBody = (document, body, bibliographyItems, refModels, refe
|
|
|
106
111
|
const orderedFootnotesIDs = createOrderedFootnotesIDs(document);
|
|
107
112
|
jatsBodyTransformations.moveFloatsGroupToBody(document, body, createElement);
|
|
108
113
|
jatsBodyTransformations.ensureSection(body, createElement);
|
|
109
|
-
jatsBodyTransformations.mapFootnotesToSections(document, body, createElement);
|
|
110
114
|
jatsBodyTransformations.moveSectionsToBody(document, body, bibliographyItems, createElement);
|
|
111
115
|
jatsBodyTransformations.moveCaptionsToEnd(body);
|
|
112
116
|
jatsBodyTransformations.moveTableFooterToEnd(body);
|
|
113
117
|
jatsBodyTransformations.moveBlockNodesFromParagraph(document, body, createElement);
|
|
114
|
-
jatsBodyTransformations.moveKeywordsToBody(document, body, createElement);
|
|
115
118
|
const node = jatsBodyDOMParser.parse(body);
|
|
116
119
|
if (!node.firstChild) {
|
|
117
120
|
throw new Error('No content was parsed from the JATS article body');
|
|
@@ -129,8 +129,10 @@ export class JATSExporter {
|
|
|
129
129
|
article.appendChild(body);
|
|
130
130
|
const back = this.buildBack(body);
|
|
131
131
|
article.appendChild(back);
|
|
132
|
+
this.unwrapBody(body);
|
|
132
133
|
this.moveAbstracts(front, body);
|
|
133
134
|
this.moveFloatsGroup(body, article);
|
|
135
|
+
this.removeBackContainer(body);
|
|
134
136
|
}
|
|
135
137
|
await this.rewriteIDs(idGenerator);
|
|
136
138
|
if (mediaPathGenerator) {
|
|
@@ -391,7 +393,9 @@ export class JATSExporter {
|
|
|
391
393
|
if (history.childElementCount) {
|
|
392
394
|
articleMeta.appendChild(history);
|
|
393
395
|
}
|
|
394
|
-
|
|
396
|
+
if (manuscript.keywordIDs) {
|
|
397
|
+
this.buildKeywords(articleMeta, manuscript.keywordIDs);
|
|
398
|
+
}
|
|
395
399
|
let countingElements = [];
|
|
396
400
|
if (manuscript.genericCounts) {
|
|
397
401
|
const elements = manuscript.genericCounts.map((el) => {
|
|
@@ -615,7 +619,6 @@ export class JATSExporter {
|
|
|
615
619
|
bibliography_element: () => '',
|
|
616
620
|
bibliography_item: () => '',
|
|
617
621
|
comment_list: () => '',
|
|
618
|
-
keywords_group: () => '',
|
|
619
622
|
bibliography_section: (node) => [
|
|
620
623
|
'ref-list',
|
|
621
624
|
{ id: normalizeID(node.attrs.id) },
|
|
@@ -1384,21 +1387,49 @@ export class JATSExporter {
|
|
|
1384
1387
|
table.insertBefore(tfoot, tbody);
|
|
1385
1388
|
}
|
|
1386
1389
|
};
|
|
1387
|
-
this.
|
|
1388
|
-
const
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
}
|
|
1396
|
-
const sectionTitle = section.querySelector(':scope > title');
|
|
1397
|
-
if (!sectionTitle) {
|
|
1398
|
-
return false;
|
|
1399
|
-
}
|
|
1400
|
-
return sectionTitle.textContent === 'Abstract';
|
|
1390
|
+
this.unwrapBody = (body) => {
|
|
1391
|
+
const container = body.querySelector(':scope > sec[sec-type="body"]');
|
|
1392
|
+
if (!container) {
|
|
1393
|
+
return;
|
|
1394
|
+
}
|
|
1395
|
+
const sections = container.querySelectorAll(':scope > sec');
|
|
1396
|
+
sections.forEach((section) => {
|
|
1397
|
+
body.appendChild(section.cloneNode(true));
|
|
1401
1398
|
});
|
|
1399
|
+
body.removeChild(container);
|
|
1400
|
+
};
|
|
1401
|
+
this.removeBackContainer = (body) => {
|
|
1402
|
+
const container = body.querySelector(':scope > sec[sec-type="backmatter"]');
|
|
1403
|
+
if (!container) {
|
|
1404
|
+
return;
|
|
1405
|
+
}
|
|
1406
|
+
const isContainerEmpty = container.children.length === 0;
|
|
1407
|
+
if (!isContainerEmpty) {
|
|
1408
|
+
warn('Backmatter section is not empty.');
|
|
1409
|
+
}
|
|
1410
|
+
body.removeChild(container);
|
|
1411
|
+
};
|
|
1412
|
+
this.moveAbstracts = (front, body) => {
|
|
1413
|
+
const container = body.querySelector(':scope > sec[sec-type="abstracts"]');
|
|
1414
|
+
let abstractSections;
|
|
1415
|
+
if (container) {
|
|
1416
|
+
abstractSections = Array.from(container.querySelectorAll(':scope > sec'));
|
|
1417
|
+
}
|
|
1418
|
+
else {
|
|
1419
|
+
abstractSections = Array.from(body.querySelectorAll(':scope > sec')).filter((section) => {
|
|
1420
|
+
const sectionType = section.getAttribute('sec-type');
|
|
1421
|
+
if (sectionType === 'abstract' ||
|
|
1422
|
+
sectionType === 'abstract-teaser' ||
|
|
1423
|
+
sectionType === 'abstract-graphical') {
|
|
1424
|
+
return true;
|
|
1425
|
+
}
|
|
1426
|
+
const sectionTitle = section.querySelector(':scope > title');
|
|
1427
|
+
if (!sectionTitle) {
|
|
1428
|
+
return false;
|
|
1429
|
+
}
|
|
1430
|
+
return sectionTitle.textContent === 'Abstract';
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1402
1433
|
if (abstractSections.length) {
|
|
1403
1434
|
for (const abstractSection of abstractSections) {
|
|
1404
1435
|
const abstractNode = this.document.createElement('abstract');
|
|
@@ -1419,6 +1450,9 @@ export class JATSExporter {
|
|
|
1419
1450
|
}
|
|
1420
1451
|
}
|
|
1421
1452
|
}
|
|
1453
|
+
if (container) {
|
|
1454
|
+
body.removeChild(container);
|
|
1455
|
+
}
|
|
1422
1456
|
};
|
|
1423
1457
|
this.moveSectionsToBack = (back, body) => {
|
|
1424
1458
|
const availabilitySection = body.querySelector('sec[sec-type="availability"]');
|
|
@@ -1521,8 +1555,10 @@ export class JATSExporter {
|
|
|
1521
1555
|
return name;
|
|
1522
1556
|
};
|
|
1523
1557
|
}
|
|
1524
|
-
buildKeywords(articleMeta) {
|
|
1525
|
-
const keywords =
|
|
1558
|
+
buildKeywords(articleMeta, keywordIDs) {
|
|
1559
|
+
const keywords = keywordIDs
|
|
1560
|
+
.map((id) => this.modelMap.get(id))
|
|
1561
|
+
.filter((model) => model && model.name);
|
|
1526
1562
|
const keywordGroups = new Map();
|
|
1527
1563
|
keywords.forEach((keyword) => {
|
|
1528
1564
|
const containedGroup = keyword.containedGroup || '';
|
|
@@ -1556,7 +1592,6 @@ export class JATSExporter {
|
|
|
1556
1592
|
kwd.textContent = keyword.name;
|
|
1557
1593
|
kwdGroup.appendChild(kwd);
|
|
1558
1594
|
}
|
|
1559
|
-
articleMeta.appendChild(kwdGroup);
|
|
1560
1595
|
}
|
|
1561
1596
|
}
|
|
1562
1597
|
}
|
package/dist/es/schema/index.js
CHANGED
|
@@ -42,7 +42,6 @@ import { inlineEquation } from './nodes/inline_equation';
|
|
|
42
42
|
import { inlineFootnote } from './nodes/inline_footnote';
|
|
43
43
|
import { keyword } from './nodes/keyword';
|
|
44
44
|
import { keywordsElement } from './nodes/keywords_element';
|
|
45
|
-
import { keywordsGroup } from './nodes/keywords_group';
|
|
46
45
|
import { keywordsSection } from './nodes/keywords_section';
|
|
47
46
|
import { link } from './nodes/link';
|
|
48
47
|
import { bulletList, listItem, orderedList } from './nodes/list';
|
|
@@ -157,7 +156,6 @@ export const schema = new Schema({
|
|
|
157
156
|
keyword,
|
|
158
157
|
keywords_element: keywordsElement,
|
|
159
158
|
keywords_section: keywordsSection,
|
|
160
|
-
keywords_group: keywordsGroup,
|
|
161
159
|
link,
|
|
162
160
|
list_item: listItem,
|
|
163
161
|
listing,
|
|
@@ -15,12 +15,11 @@
|
|
|
15
15
|
*/
|
|
16
16
|
export const keywordsElement = {
|
|
17
17
|
atom: true,
|
|
18
|
-
content: '
|
|
18
|
+
content: 'keyword*',
|
|
19
19
|
attrs: {
|
|
20
20
|
id: { default: '' },
|
|
21
21
|
contents: { default: '' },
|
|
22
22
|
paragraphStyle: { default: '' },
|
|
23
|
-
type: { default: '' },
|
|
24
23
|
dataTracked: { default: null },
|
|
25
24
|
},
|
|
26
25
|
group: 'block element',
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
export const keywordsSection = {
|
|
17
|
-
content: '
|
|
17
|
+
content: 'section_title_plain (keywords_element | placeholder_element)',
|
|
18
18
|
attrs: {
|
|
19
19
|
id: { default: '' },
|
|
20
20
|
dataTracked: { default: null },
|
|
@@ -32,7 +32,7 @@ const choosePageBreakStyle = (element) => {
|
|
|
32
32
|
return PAGE_BREAK_NONE;
|
|
33
33
|
};
|
|
34
34
|
export const section = {
|
|
35
|
-
content: 'section_label? section_title (paragraph | element)*
|
|
35
|
+
content: 'section_label? section_title (paragraph | element)* sections*',
|
|
36
36
|
attrs: {
|
|
37
37
|
id: { default: '' },
|
|
38
38
|
category: { default: '' },
|
|
@@ -265,11 +265,11 @@ export class Decoder {
|
|
|
265
265
|
},
|
|
266
266
|
[ObjectTypes.KeywordsElement]: (data) => {
|
|
267
267
|
const model = data;
|
|
268
|
-
const
|
|
268
|
+
const keywords = this.getKeywords();
|
|
269
269
|
return schema.nodes.keywords_element.create({
|
|
270
270
|
id: model._id,
|
|
271
271
|
paragraphStyle: model.paragraphStyle,
|
|
272
|
-
},
|
|
272
|
+
}, keywords);
|
|
273
273
|
},
|
|
274
274
|
[ObjectTypes.Keyword]: (data) => {
|
|
275
275
|
const model = data;
|
|
@@ -416,7 +416,9 @@ export class Decoder {
|
|
|
416
416
|
const elementNodes = elements
|
|
417
417
|
.map(this.decode)
|
|
418
418
|
.filter(isManuscriptNode);
|
|
419
|
-
const sectionTitle =
|
|
419
|
+
const sectionTitle = isKeywordsSection
|
|
420
|
+
? 'section_title_plain'
|
|
421
|
+
: 'section_title';
|
|
420
422
|
const sectionTitleNode = model.title
|
|
421
423
|
? this.parseContents(model.title, 'h1', this.getComments(model), {
|
|
422
424
|
topNode: schema.nodes[sectionTitle].create(),
|
|
@@ -560,6 +562,19 @@ export class Decoder {
|
|
|
560
562
|
id: generateNodeID(schema.nodes.section),
|
|
561
563
|
}));
|
|
562
564
|
}
|
|
565
|
+
const keywordsSection = getSections(this.modelMap).filter((section) => section.category === 'MPSectionCategory:keywords');
|
|
566
|
+
const keywords = this.getKeywords();
|
|
567
|
+
if (keywordsSection.length === 0 && keywords.length > 0) {
|
|
568
|
+
const keywordsSection = schema.nodes.keywords_section.createAndFill({
|
|
569
|
+
id: generateNodeID(schema.nodes.keywords_section),
|
|
570
|
+
}, [
|
|
571
|
+
schema.nodes.section_title_plain.create({}, schema.text('Keywords')),
|
|
572
|
+
schema.nodes.keywords_element.create({
|
|
573
|
+
id: generateNodeID(schema.nodes.keywords_element),
|
|
574
|
+
}, keywords),
|
|
575
|
+
]);
|
|
576
|
+
rootSectionNodes.unshift(keywordsSection);
|
|
577
|
+
}
|
|
563
578
|
const contents = rootSectionNodes;
|
|
564
579
|
if (this.comments.size) {
|
|
565
580
|
const comments = schema.nodes.comment_list.createAndFill({
|
|
@@ -607,16 +622,17 @@ export class Decoder {
|
|
|
607
622
|
}
|
|
608
623
|
return parser.parse(template.content.firstElementChild, options);
|
|
609
624
|
};
|
|
610
|
-
this.getKeywords = (
|
|
625
|
+
this.getKeywords = () => {
|
|
611
626
|
const keywordsOfKind = [];
|
|
612
|
-
const
|
|
613
|
-
|
|
614
|
-
|
|
627
|
+
for (const model of this.modelMap.values()) {
|
|
628
|
+
const commentNodes = this.createCommentsNode(model);
|
|
629
|
+
commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
|
|
615
630
|
if (isKeyword(model)) {
|
|
616
631
|
const keyword = this.parseContents(model.name || '', 'div', this.getComments(model), {
|
|
617
632
|
topNode: schema.nodes.keyword.create({
|
|
618
633
|
id: model._id,
|
|
619
634
|
contents: model.name,
|
|
635
|
+
comments: commentNodes.map((c) => c.attrs.id),
|
|
620
636
|
}),
|
|
621
637
|
});
|
|
622
638
|
keywordsOfKind.push(keyword);
|
|
@@ -663,26 +679,4 @@ export class Decoder {
|
|
|
663
679
|
this.modelMap = modelMap;
|
|
664
680
|
this.allowMissingElements = allowMissingElements;
|
|
665
681
|
}
|
|
666
|
-
getKeywordGroups() {
|
|
667
|
-
const kwdGroupNodes = [];
|
|
668
|
-
const kwdGroupsModels = [
|
|
669
|
-
...this.modelMap.values(),
|
|
670
|
-
].filter((model) => model.objectType === ObjectTypes.KeywordGroup);
|
|
671
|
-
if (kwdGroupsModels.length > 0) {
|
|
672
|
-
for (const kwdGroupModel of kwdGroupsModels) {
|
|
673
|
-
const keywords = this.getKeywords(kwdGroupModel._id);
|
|
674
|
-
const commentNodes = this.createCommentsNode(kwdGroupModel);
|
|
675
|
-
commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
|
|
676
|
-
const contents = [];
|
|
677
|
-
contents.push(...keywords);
|
|
678
|
-
const kwdGroupNode = schema.nodes.keywords_group.create({
|
|
679
|
-
id: kwdGroupModel._id,
|
|
680
|
-
type: kwdGroupModel.type,
|
|
681
|
-
comments: commentNodes.map((c) => c.attrs.id),
|
|
682
|
-
}, contents);
|
|
683
|
-
kwdGroupNodes.push(kwdGroupNode);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
return kwdGroupNodes;
|
|
687
|
-
}
|
|
688
682
|
}
|