@manuscripts/transform 1.2.4 → 1.2.5-LEAN-2066
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 +33 -1
- package/dist/cjs/jats/importer/jats-body-transformations.js +67 -12
- package/dist/cjs/jats/importer/jats-comments.js +24 -0
- package/dist/cjs/jats/importer/jats-front-parser.js +0 -25
- package/dist/cjs/jats/importer/parse-jats-article.js +2 -7
- package/dist/cjs/jats/jats-exporter.js +52 -21
- package/dist/cjs/schema/index.js +2 -0
- package/dist/cjs/schema/nodes/keyword.js +1 -2
- package/dist/cjs/schema/nodes/keywords_element.js +2 -1
- package/dist/cjs/schema/nodes/keywords_group.js +48 -0
- 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 +29 -23
- package/dist/cjs/transformer/encode.js +16 -6
- package/dist/cjs/transformer/node-types.js +1 -0
- package/dist/cjs/transformer/object-types.js +2 -1
- package/dist/cjs/transformer/section-category.js +23 -1
- package/dist/es/jats/importer/jats-body-dom-parser.js +33 -1
- package/dist/es/jats/importer/jats-body-transformations.js +68 -13
- package/dist/es/jats/importer/jats-comments.js +25 -1
- package/dist/es/jats/importer/jats-front-parser.js +1 -26
- package/dist/es/jats/importer/parse-jats-article.js +2 -7
- package/dist/es/jats/jats-exporter.js +52 -21
- package/dist/es/schema/index.js +2 -0
- package/dist/es/schema/nodes/keyword.js +1 -2
- package/dist/es/schema/nodes/keywords_element.js +2 -1
- package/dist/es/schema/nodes/keywords_group.js +44 -0
- 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 +29 -23
- package/dist/es/transformer/encode.js +17 -7
- package/dist/es/transformer/node-types.js +1 -0
- package/dist/es/transformer/object-types.js +1 -0
- package/dist/es/transformer/section-category.js +19 -1
- package/dist/types/jats/importer/jats-body-transformations.d.ts +8 -1
- package/dist/types/jats/importer/jats-front-parser.d.ts +6 -11
- package/dist/types/jats/jats-exporter.d.ts +2 -0
- package/dist/types/schema/nodes/keywords_group.d.ts +26 -0
- package/dist/types/schema/types.d.ts +1 -1
- package/dist/types/transformer/decode.d.ts +1 -0
- package/dist/types/transformer/object-types.d.ts +2 -1
- package/dist/types/transformer/section-category.d.ts +3 -2
- package/package.json +2 -2
|
@@ -162,6 +162,15 @@ const childElements = (node) => {
|
|
|
162
162
|
});
|
|
163
163
|
return nodes;
|
|
164
164
|
};
|
|
165
|
+
const sectionChildElementIds = (node) => {
|
|
166
|
+
const nodes = [];
|
|
167
|
+
node.forEach((childNode) => {
|
|
168
|
+
if (!(0, schema_1.hasGroup)(childNode.type, 'sections')) {
|
|
169
|
+
nodes.push(childNode);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
return nodes.map((childNode) => childNode.attrs.id).filter((id) => id);
|
|
173
|
+
};
|
|
165
174
|
const attributeOfNodeType = (node, type, attribute) => {
|
|
166
175
|
for (const child of (0, utils_1.iterateChildren)(node)) {
|
|
167
176
|
if (child.type.name === type) {
|
|
@@ -401,18 +410,21 @@ const encoders = {
|
|
|
401
410
|
SVGGlyphs: svgDefs(node.attrs.SVGRepresentation),
|
|
402
411
|
}),
|
|
403
412
|
keyword: (node, parent) => ({
|
|
404
|
-
|
|
413
|
+
containedGroup: parent.attrs.id,
|
|
405
414
|
name: keywordContents(node),
|
|
406
415
|
}),
|
|
407
416
|
keywords_element: (node) => ({
|
|
408
|
-
contents:
|
|
417
|
+
contents: '<div></div>',
|
|
409
418
|
elementType: 'div',
|
|
410
419
|
paragraphStyle: node.attrs.paragraphStyle || undefined,
|
|
411
420
|
}),
|
|
421
|
+
keywords_group: (node) => ({
|
|
422
|
+
type: node.attrs.type,
|
|
423
|
+
}),
|
|
412
424
|
keywords_section: (node, parent, path, priority) => ({
|
|
413
425
|
category: (0, section_category_1.buildSectionCategory)(node),
|
|
414
426
|
priority: priority.value++,
|
|
415
|
-
title: inlineContentsOfNodeType(node, node.type.schema.nodes.
|
|
427
|
+
title: inlineContentsOfNodeType(node, node.type.schema.nodes.section_title),
|
|
416
428
|
path: path.concat([node.attrs.id]),
|
|
417
429
|
elementIDs: childElements(node)
|
|
418
430
|
.map((childNode) => childNode.attrs.id)
|
|
@@ -449,9 +461,7 @@ const encoders = {
|
|
|
449
461
|
label: inlineContentsOfNodeType(node, node.type.schema.nodes.section_label) ||
|
|
450
462
|
undefined,
|
|
451
463
|
path: path.concat([node.attrs.id]),
|
|
452
|
-
elementIDs:
|
|
453
|
-
.map((childNode) => childNode.attrs.id)
|
|
454
|
-
.filter((id) => id),
|
|
464
|
+
elementIDs: sectionChildElementIds(node),
|
|
455
465
|
titleSuppressed: node.attrs.titleSuppressed || undefined,
|
|
456
466
|
generatedLabel: node.attrs.generatedLabel || undefined,
|
|
457
467
|
pageBreakStyle: node.attrs.pageBreakStyle || undefined,
|
|
@@ -41,6 +41,7 @@ exports.nodeTypesMap = new Map([
|
|
|
41
41
|
[schema_1.schema.nodes.keyword, json_schema_1.ObjectTypes.Keyword],
|
|
42
42
|
[schema_1.schema.nodes.keywords_element, json_schema_1.ObjectTypes.KeywordsElement],
|
|
43
43
|
[schema_1.schema.nodes.keywords_section, json_schema_1.ObjectTypes.Section],
|
|
44
|
+
[schema_1.schema.nodes.keywords_group, json_schema_1.ObjectTypes.KeywordGroup],
|
|
44
45
|
[schema_1.schema.nodes.listing, json_schema_1.ObjectTypes.Listing],
|
|
45
46
|
[schema_1.schema.nodes.listing_element, json_schema_1.ObjectTypes.ListingElement],
|
|
46
47
|
[schema_1.schema.nodes.manuscript, json_schema_1.ObjectTypes.Manuscript],
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.isCommentAnnotation = exports.isUserProfile = exports.isTable = exports.isManuscript = exports.isFigure = exports.hasObjectType = exports.isManuscriptModel = exports.manuscriptObjects = exports.elementObjects = exports.ExtraObjectTypes = void 0;
|
|
18
|
+
exports.isKeyword = exports.isCommentAnnotation = exports.isUserProfile = exports.isTable = exports.isManuscript = exports.isFigure = exports.hasObjectType = exports.isManuscriptModel = exports.manuscriptObjects = exports.elementObjects = exports.ExtraObjectTypes = void 0;
|
|
19
19
|
const json_schema_1 = require("@manuscripts/json-schema");
|
|
20
20
|
var ExtraObjectTypes;
|
|
21
21
|
(function (ExtraObjectTypes) {
|
|
@@ -55,3 +55,4 @@ exports.isManuscript = (0, exports.hasObjectType)(json_schema_1.ObjectTypes.Manu
|
|
|
55
55
|
exports.isTable = (0, exports.hasObjectType)(json_schema_1.ObjectTypes.Table);
|
|
56
56
|
exports.isUserProfile = (0, exports.hasObjectType)(json_schema_1.ObjectTypes.UserProfile);
|
|
57
57
|
exports.isCommentAnnotation = (0, exports.hasObjectType)(json_schema_1.ObjectTypes.CommentAnnotation);
|
|
58
|
+
exports.isKeyword = (0, exports.hasObjectType)(json_schema_1.ObjectTypes.Keyword);
|
|
@@ -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,6 +499,22 @@ 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
|
+
},
|
|
502
518
|
{
|
|
503
519
|
tag: 'sec',
|
|
504
520
|
node: 'section',
|
|
@@ -510,6 +526,22 @@ const nodes = [
|
|
|
510
526
|
};
|
|
511
527
|
},
|
|
512
528
|
},
|
|
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
|
+
},
|
|
513
545
|
{
|
|
514
546
|
tag: 'label',
|
|
515
547
|
context: 'section/',
|
|
@@ -562,7 +594,7 @@ const nodes = [
|
|
|
562
594
|
{
|
|
563
595
|
tag: 'title',
|
|
564
596
|
node: 'section_title',
|
|
565
|
-
context: 'section/|footnotes_section/|bibliography_section/',
|
|
597
|
+
context: 'section/|footnotes_section/|bibliography_section/|keywords_section/',
|
|
566
598
|
},
|
|
567
599
|
{
|
|
568
600
|
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,4 +304,18 @@ export const jatsBodyTransformations = {
|
|
|
263
304
|
paragraph === null || paragraph === void 0 ? void 0 : paragraph.replaceWith(parent);
|
|
264
305
|
});
|
|
265
306
|
},
|
|
307
|
+
moveKeywordsToBody(document, body, createElement) {
|
|
308
|
+
const keywordGroups = [...document.querySelectorAll('kwd-group')];
|
|
309
|
+
if (keywordGroups.length > 0) {
|
|
310
|
+
const section = createElement('sec');
|
|
311
|
+
section.setAttribute('sec-type', 'keywords');
|
|
312
|
+
const title = createElement('title');
|
|
313
|
+
title.textContent = 'Keywords';
|
|
314
|
+
section.append(title);
|
|
315
|
+
const kwdGroupsEl = createElement('kwd-group-list');
|
|
316
|
+
kwdGroupsEl.append(keywordGroups[0]);
|
|
317
|
+
section.append(kwdGroupsEl);
|
|
318
|
+
body.prepend(section);
|
|
319
|
+
}
|
|
320
|
+
},
|
|
266
321
|
};
|
|
@@ -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, } from '../../transformer';
|
|
17
|
+
import { buildComment, buildContribution, isCommentAnnotation, isHighlightableModel, isKeyword, } 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,6 +58,21 @@ 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
|
+
};
|
|
61
76
|
export const createComments = (authorQueriesMap, manuscriptModels) => {
|
|
62
77
|
const tokens = [...authorQueriesMap.keys()];
|
|
63
78
|
const commentAnnotations = [];
|
|
@@ -66,9 +81,18 @@ export const createComments = (authorQueriesMap, manuscriptModels) => {
|
|
|
66
81
|
const comments = addCommentsFromMarkedProcessingInstructions(tokens, model, authorQueriesMap);
|
|
67
82
|
commentAnnotations.push(...comments);
|
|
68
83
|
}
|
|
84
|
+
else if (isKeyword(model)) {
|
|
85
|
+
const comments = extractCommentsFromKeywords(tokens, model, authorQueriesMap);
|
|
86
|
+
commentAnnotations.push(...comments);
|
|
87
|
+
}
|
|
69
88
|
}
|
|
70
89
|
return commentAnnotations;
|
|
71
90
|
};
|
|
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
|
+
}
|
|
72
96
|
const addCommentsFromMarkedProcessingInstructions = (tokens, model, authorQueriesMap) => {
|
|
73
97
|
const commentAnnotations = [];
|
|
74
98
|
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,
|
|
17
|
+
import { buildAffiliation, buildBibliographicName, buildContributor, buildCorresp, buildFootnote, 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,31 +62,6 @@ 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
|
-
},
|
|
90
65
|
parseDates(historyNode) {
|
|
91
66
|
if (!historyNode) {
|
|
92
67
|
return undefined;
|
|
@@ -51,9 +51,6 @@ 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;
|
|
57
54
|
const { affiliations, affiliationIDs } = jatsFrontParser.parseAffiliationNodes([
|
|
58
55
|
...front.querySelectorAll('article-meta > contrib-group > aff'),
|
|
59
56
|
]);
|
|
@@ -70,14 +67,12 @@ export const parseJATSFront = async (front) => {
|
|
|
70
67
|
const supplements = jatsFrontParser.parseSupplements([
|
|
71
68
|
...front.querySelectorAll('article-meta > supplementary-material'),
|
|
72
69
|
]);
|
|
73
|
-
const manuscript = Object.assign(Object.assign(Object.assign(
|
|
70
|
+
const manuscript = Object.assign(Object.assign(Object.assign({}, buildManuscript()), manuscriptMeta), history);
|
|
74
71
|
return {
|
|
75
72
|
models: generateModelIDs([
|
|
76
73
|
manuscript,
|
|
77
|
-
...keywords,
|
|
78
74
|
...affiliations,
|
|
79
75
|
...authors,
|
|
80
|
-
...keywordGroups,
|
|
81
76
|
...footnotes,
|
|
82
77
|
...correspondingList,
|
|
83
78
|
journal,
|
|
@@ -111,11 +106,11 @@ export const parseJATSBody = (document, body, bibliographyItems, refModels, refe
|
|
|
111
106
|
const orderedFootnotesIDs = createOrderedFootnotesIDs(document);
|
|
112
107
|
jatsBodyTransformations.moveFloatsGroupToBody(document, body, createElement);
|
|
113
108
|
jatsBodyTransformations.ensureSection(body, createElement);
|
|
114
|
-
jatsBodyTransformations.mapFootnotesToSections(document, body, createElement);
|
|
115
109
|
jatsBodyTransformations.moveSectionsToBody(document, body, bibliographyItems, createElement);
|
|
116
110
|
jatsBodyTransformations.moveCaptionsToEnd(body);
|
|
117
111
|
jatsBodyTransformations.moveTableFooterToEnd(body);
|
|
118
112
|
jatsBodyTransformations.moveBlockNodesFromParagraph(document, body, createElement);
|
|
113
|
+
jatsBodyTransformations.moveKeywordsToBody(document, body, createElement);
|
|
119
114
|
const node = jatsBodyDOMParser.parse(body);
|
|
120
115
|
if (!node.firstChild) {
|
|
121
116
|
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,9 +393,7 @@ export class JATSExporter {
|
|
|
391
393
|
if (history.childElementCount) {
|
|
392
394
|
articleMeta.appendChild(history);
|
|
393
395
|
}
|
|
394
|
-
|
|
395
|
-
this.buildKeywords(articleMeta, manuscript.keywordIDs);
|
|
396
|
-
}
|
|
396
|
+
this.buildKeywords(articleMeta);
|
|
397
397
|
let countingElements = [];
|
|
398
398
|
if (manuscript.genericCounts) {
|
|
399
399
|
const elements = manuscript.genericCounts.map((el) => {
|
|
@@ -617,6 +617,7 @@ export class JATSExporter {
|
|
|
617
617
|
bibliography_element: () => '',
|
|
618
618
|
bibliography_item: () => '',
|
|
619
619
|
comment_list: () => '',
|
|
620
|
+
keywords_group: () => '',
|
|
620
621
|
bibliography_section: (node) => [
|
|
621
622
|
'ref-list',
|
|
622
623
|
{ id: normalizeID(node.attrs.id) },
|
|
@@ -1385,21 +1386,49 @@ export class JATSExporter {
|
|
|
1385
1386
|
table.insertBefore(tfoot, tbody);
|
|
1386
1387
|
}
|
|
1387
1388
|
};
|
|
1388
|
-
this.
|
|
1389
|
-
const
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
}
|
|
1397
|
-
const sectionTitle = section.querySelector(':scope > title');
|
|
1398
|
-
if (!sectionTitle) {
|
|
1399
|
-
return false;
|
|
1400
|
-
}
|
|
1401
|
-
return sectionTitle.textContent === 'Abstract';
|
|
1389
|
+
this.unwrapBody = (body) => {
|
|
1390
|
+
const container = body.querySelector(':scope > sec[sec-type="body"]');
|
|
1391
|
+
if (!container) {
|
|
1392
|
+
return;
|
|
1393
|
+
}
|
|
1394
|
+
const sections = container.querySelectorAll(':scope > sec');
|
|
1395
|
+
sections.forEach((section) => {
|
|
1396
|
+
body.appendChild(section.cloneNode(true));
|
|
1402
1397
|
});
|
|
1398
|
+
body.removeChild(container);
|
|
1399
|
+
};
|
|
1400
|
+
this.removeBackContainer = (body) => {
|
|
1401
|
+
const container = body.querySelector(':scope > sec[sec-type="backmatter"]');
|
|
1402
|
+
if (!container) {
|
|
1403
|
+
return;
|
|
1404
|
+
}
|
|
1405
|
+
const isContainerEmpty = container.children.length === 0;
|
|
1406
|
+
if (!isContainerEmpty) {
|
|
1407
|
+
warn('Backmatter section is not empty.');
|
|
1408
|
+
}
|
|
1409
|
+
body.removeChild(container);
|
|
1410
|
+
};
|
|
1411
|
+
this.moveAbstracts = (front, body) => {
|
|
1412
|
+
const container = body.querySelector(':scope > sec[sec-type="abstracts"]');
|
|
1413
|
+
let abstractSections;
|
|
1414
|
+
if (container) {
|
|
1415
|
+
abstractSections = Array.from(container.querySelectorAll(':scope > sec'));
|
|
1416
|
+
}
|
|
1417
|
+
else {
|
|
1418
|
+
abstractSections = Array.from(body.querySelectorAll(':scope > sec')).filter((section) => {
|
|
1419
|
+
const sectionType = section.getAttribute('sec-type');
|
|
1420
|
+
if (sectionType === 'abstract' ||
|
|
1421
|
+
sectionType === 'abstract-teaser' ||
|
|
1422
|
+
sectionType === 'abstract-graphical') {
|
|
1423
|
+
return true;
|
|
1424
|
+
}
|
|
1425
|
+
const sectionTitle = section.querySelector(':scope > title');
|
|
1426
|
+
if (!sectionTitle) {
|
|
1427
|
+
return false;
|
|
1428
|
+
}
|
|
1429
|
+
return sectionTitle.textContent === 'Abstract';
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1403
1432
|
if (abstractSections.length) {
|
|
1404
1433
|
for (const abstractSection of abstractSections) {
|
|
1405
1434
|
const abstractNode = this.document.createElement('abstract');
|
|
@@ -1420,6 +1449,9 @@ export class JATSExporter {
|
|
|
1420
1449
|
}
|
|
1421
1450
|
}
|
|
1422
1451
|
}
|
|
1452
|
+
if (container) {
|
|
1453
|
+
body.removeChild(container);
|
|
1454
|
+
}
|
|
1423
1455
|
};
|
|
1424
1456
|
this.moveSectionsToBack = (back, body) => {
|
|
1425
1457
|
const availabilitySection = body.querySelector('sec[sec-type="availability"]');
|
|
@@ -1522,10 +1554,8 @@ export class JATSExporter {
|
|
|
1522
1554
|
return name;
|
|
1523
1555
|
};
|
|
1524
1556
|
}
|
|
1525
|
-
buildKeywords(articleMeta
|
|
1526
|
-
const keywords =
|
|
1527
|
-
.map((id) => this.modelMap.get(id))
|
|
1528
|
-
.filter((model) => model && model.name);
|
|
1557
|
+
buildKeywords(articleMeta) {
|
|
1558
|
+
const keywords = [...this.modelMap.values()].filter((model) => model.objectType === ObjectTypes.Keyword);
|
|
1529
1559
|
const keywordGroups = new Map();
|
|
1530
1560
|
keywords.forEach((keyword) => {
|
|
1531
1561
|
const containedGroup = keyword.containedGroup || '';
|
|
@@ -1559,6 +1589,7 @@ export class JATSExporter {
|
|
|
1559
1589
|
kwd.textContent = keyword.name;
|
|
1560
1590
|
kwdGroup.appendChild(kwd);
|
|
1561
1591
|
}
|
|
1592
|
+
articleMeta.appendChild(kwdGroup);
|
|
1562
1593
|
}
|
|
1563
1594
|
}
|
|
1564
1595
|
}
|
package/dist/es/schema/index.js
CHANGED
|
@@ -42,6 +42,7 @@ 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';
|
|
45
46
|
import { keywordsSection } from './nodes/keywords_section';
|
|
46
47
|
import { link } from './nodes/link';
|
|
47
48
|
import { bulletList, listItem, orderedList } from './nodes/list';
|
|
@@ -156,6 +157,7 @@ export const schema = new Schema({
|
|
|
156
157
|
keyword,
|
|
157
158
|
keywords_element: keywordsElement,
|
|
158
159
|
keywords_section: keywordsSection,
|
|
160
|
+
keywords_group: keywordsGroup,
|
|
159
161
|
link,
|
|
160
162
|
list_item: listItem,
|
|
161
163
|
listing,
|
|
@@ -15,11 +15,12 @@
|
|
|
15
15
|
*/
|
|
16
16
|
export const keywordsElement = {
|
|
17
17
|
atom: true,
|
|
18
|
-
content: '
|
|
18
|
+
content: 'keywords_group*',
|
|
19
19
|
attrs: {
|
|
20
20
|
id: { default: '' },
|
|
21
21
|
contents: { default: '' },
|
|
22
22
|
paragraphStyle: { default: '' },
|
|
23
|
+
type: { default: '' },
|
|
23
24
|
dataTracked: { default: null },
|
|
24
25
|
},
|
|
25
26
|
group: 'block element',
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
export const keywordsGroup = {
|
|
17
|
+
content: 'keyword*',
|
|
18
|
+
attrs: {
|
|
19
|
+
id: { default: '' },
|
|
20
|
+
type: { default: '' },
|
|
21
|
+
dataTracked: { default: null },
|
|
22
|
+
},
|
|
23
|
+
group: 'block',
|
|
24
|
+
selectable: false,
|
|
25
|
+
parseDOM: [
|
|
26
|
+
{
|
|
27
|
+
tag: 'div.keywords',
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
toDOM: (node) => {
|
|
31
|
+
const keywordsGroupNode = node;
|
|
32
|
+
return [
|
|
33
|
+
'div',
|
|
34
|
+
{
|
|
35
|
+
id: keywordsGroupNode.attrs.id,
|
|
36
|
+
class: 'keywords',
|
|
37
|
+
spellcheck: 'false',
|
|
38
|
+
contenteditable: false,
|
|
39
|
+
},
|
|
40
|
+
0,
|
|
41
|
+
];
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
export const isKeywordsGroupNode = (node) => node.type === node.type.schema.nodes.keywords_group;
|