@manuscripts/transform 1.5.2-LEAN-3034 → 1.5.2-LEAN-3032
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 +19 -7
- package/dist/cjs/jats/jats-exporter.js +12 -37
- package/dist/cjs/lib/utils.js +10 -1
- package/dist/cjs/schema/index.js +7 -3
- package/dist/cjs/schema/nodes/affiliations_section.js +1 -1
- package/dist/cjs/schema/nodes/contributors_section.js +1 -1
- package/dist/cjs/schema/nodes/core_section.js +27 -0
- package/dist/cjs/schema/nodes/keywords_section.js +1 -1
- package/dist/cjs/schema/nodes/manuscript.js +1 -1
- package/dist/cjs/transformer/decode.js +67 -19
- package/dist/cjs/transformer/encode.js +12 -25
- package/dist/cjs/transformer/node-names.js +1 -1
- package/dist/cjs/transformer/node-title.js +1 -1
- package/dist/cjs/transformer/node-types.js +6 -3
- package/dist/cjs/transformer/section-category.js +35 -8
- package/dist/es/jats/importer/jats-body-dom-parser.js +19 -7
- package/dist/es/jats/jats-exporter.js +13 -38
- package/dist/es/lib/utils.js +8 -0
- package/dist/es/schema/index.js +7 -3
- package/dist/es/schema/nodes/affiliations_section.js +1 -1
- package/dist/es/schema/nodes/contributors_section.js +1 -1
- package/dist/es/schema/nodes/core_section.js +24 -0
- package/dist/es/schema/nodes/keywords_section.js +1 -1
- package/dist/es/schema/nodes/manuscript.js +1 -1
- package/dist/es/transformer/decode.js +68 -20
- package/dist/es/transformer/encode.js +12 -25
- package/dist/es/transformer/node-names.js +1 -1
- package/dist/es/transformer/node-title.js +1 -1
- package/dist/es/transformer/node-types.js +6 -3
- package/dist/es/transformer/section-category.js +33 -7
- package/dist/types/jats/jats-exporter.d.ts +1 -8
- package/dist/types/lib/utils.d.ts +1 -0
- package/dist/types/{lib/citationProvider.d.ts → schema/nodes/core_section.d.ts} +8 -14
- package/dist/types/schema/types.d.ts +1 -1
- package/dist/types/transformer/decode.d.ts +3 -0
- package/dist/types/transformer/section-category.d.ts +1 -0
- package/package.json +2 -3
- package/dist/cjs/lib/citationProvider.js +0 -50
- package/dist/cjs/lib/defaultLocale.js +0 -3
- package/dist/es/lib/citationProvider.js +0 -43
- package/dist/es/lib/defaultLocale.js +0 -1
- package/dist/types/lib/defaultLocale.d.ts +0 -2
|
@@ -501,7 +501,7 @@ const nodes = [
|
|
|
501
501
|
},
|
|
502
502
|
{
|
|
503
503
|
tag: 'sec[sec-type="affiliations"]',
|
|
504
|
-
node: '
|
|
504
|
+
node: 'affiliations',
|
|
505
505
|
getAttrs: (node) => {
|
|
506
506
|
const element = node;
|
|
507
507
|
return {
|
|
@@ -513,7 +513,7 @@ const nodes = [
|
|
|
513
513
|
{
|
|
514
514
|
tag: 'aff',
|
|
515
515
|
node: 'affiliation',
|
|
516
|
-
context: '
|
|
516
|
+
context: 'affiliations/',
|
|
517
517
|
getAttrs: (node) => {
|
|
518
518
|
const element = node;
|
|
519
519
|
const aff = {
|
|
@@ -560,7 +560,7 @@ const nodes = [
|
|
|
560
560
|
},
|
|
561
561
|
{
|
|
562
562
|
tag: 'sec[sec-type="contributors"]',
|
|
563
|
-
node: '
|
|
563
|
+
node: 'contributors',
|
|
564
564
|
getAttrs: (node) => {
|
|
565
565
|
const element = node;
|
|
566
566
|
return {
|
|
@@ -572,7 +572,7 @@ const nodes = [
|
|
|
572
572
|
{
|
|
573
573
|
tag: 'contrib',
|
|
574
574
|
node: 'contributor',
|
|
575
|
-
context: '
|
|
575
|
+
context: 'contributors/',
|
|
576
576
|
getAttrs: (node) => {
|
|
577
577
|
const element = node;
|
|
578
578
|
const contrib = {
|
|
@@ -627,7 +627,7 @@ const nodes = [
|
|
|
627
627
|
},
|
|
628
628
|
{
|
|
629
629
|
tag: 'sec[sec-type="keywords"]',
|
|
630
|
-
node: '
|
|
630
|
+
node: 'keywords',
|
|
631
631
|
getAttrs: (node) => {
|
|
632
632
|
const element = node;
|
|
633
633
|
return {
|
|
@@ -638,9 +638,21 @@ const nodes = [
|
|
|
638
638
|
},
|
|
639
639
|
{
|
|
640
640
|
tag: 'kwd-group-list',
|
|
641
|
-
context: '
|
|
641
|
+
context: 'keywords/',
|
|
642
642
|
node: 'keywords_element',
|
|
643
643
|
},
|
|
644
|
+
{
|
|
645
|
+
tag: 'sec[sec-type="abstracts"]',
|
|
646
|
+
node: 'abstracts',
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
tag: 'sec[sec-type="body"]',
|
|
650
|
+
node: 'body',
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
tag: 'sec[sec-type="backmatter"]',
|
|
654
|
+
node: 'backmatter',
|
|
655
|
+
},
|
|
644
656
|
{
|
|
645
657
|
tag: 'sec',
|
|
646
658
|
node: 'section',
|
|
@@ -720,7 +732,7 @@ const nodes = [
|
|
|
720
732
|
{
|
|
721
733
|
tag: 'title',
|
|
722
734
|
node: 'section_title',
|
|
723
|
-
context: 'section/|footnotes_section/|bibliography_section/|
|
|
735
|
+
context: 'section/|footnotes_section/|bibliography_section/|keywords/',
|
|
724
736
|
},
|
|
725
737
|
{
|
|
726
738
|
tag: 'title',
|
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { ObjectTypes, } from '@manuscripts/json-schema';
|
|
17
17
|
import debug from 'debug';
|
|
18
|
-
import { DOMParser, DOMSerializer
|
|
18
|
+
import { DOMParser, DOMSerializer } from 'prosemirror-model';
|
|
19
19
|
import serializeToXML from 'w3c-xmlserializer';
|
|
20
|
-
import { CitationProvider } from '../lib/citationProvider';
|
|
21
20
|
import { nodeFromHTML, textFromHTML } from '../lib/html';
|
|
22
21
|
import { normalizeStyleName } from '../lib/styled-content';
|
|
23
22
|
import { iterateChildren } from '../lib/utils';
|
|
@@ -112,16 +111,9 @@ const sortContributors = (a, b) => Number(a.priority) - Number(b.priority);
|
|
|
112
111
|
export class JATSExporter {
|
|
113
112
|
constructor() {
|
|
114
113
|
this.serializeToJATS = async (fragment, modelMap, manuscriptID, options = {}) => {
|
|
115
|
-
const { version = '1.2', doi, id, frontMatterOnly = false, links, idGenerator, mediaPathGenerator,
|
|
114
|
+
const { version = '1.2', doi, id, frontMatterOnly = false, links, idGenerator, mediaPathGenerator, } = options;
|
|
116
115
|
this.modelMap = modelMap;
|
|
117
116
|
this.models = Array.from(this.modelMap.values());
|
|
118
|
-
if (citationStyle) {
|
|
119
|
-
this.citeProcEngine = CitationProvider.getEngine({
|
|
120
|
-
bibliographyItemsMap: this.getBibliographyItemsMap(),
|
|
121
|
-
citationStyle: citationStyle,
|
|
122
|
-
locale: locale,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
117
|
this.createSerializer();
|
|
126
118
|
const versionIds = selectVersionIds(version);
|
|
127
119
|
this.document = document.implementation.createDocument(null, 'article', document.implementation.createDocumentType('article', versionIds.publicId, versionIds.systemId));
|
|
@@ -431,9 +423,11 @@ export class JATSExporter {
|
|
|
431
423
|
}
|
|
432
424
|
};
|
|
433
425
|
this.buildBody = (fragment) => {
|
|
434
|
-
const content = this.serializeFragment(fragment);
|
|
435
426
|
const body = this.document.createElement('body');
|
|
436
|
-
|
|
427
|
+
fragment.forEach((cFragment) => {
|
|
428
|
+
const serializedNode = this.serializeNode(cFragment);
|
|
429
|
+
body.append(...serializedNode.childNodes);
|
|
430
|
+
});
|
|
437
431
|
this.fixBody(body, fragment);
|
|
438
432
|
return body;
|
|
439
433
|
};
|
|
@@ -599,8 +593,8 @@ export class JATSExporter {
|
|
|
599
593
|
this.createSerializer = () => {
|
|
600
594
|
const getModel = (id) => id ? this.modelMap.get(id) : undefined;
|
|
601
595
|
const nodes = {
|
|
602
|
-
|
|
603
|
-
|
|
596
|
+
affiliations: () => '',
|
|
597
|
+
contributors: () => '',
|
|
604
598
|
table_element_footer: () => ['table-wrap-foot', 0],
|
|
605
599
|
contributor: () => '',
|
|
606
600
|
affiliation: () => '',
|
|
@@ -610,6 +604,9 @@ export class JATSExporter {
|
|
|
610
604
|
bibliography_item: () => '',
|
|
611
605
|
comment_list: () => '',
|
|
612
606
|
keywords_group: () => '',
|
|
607
|
+
body: () => ['body', 0],
|
|
608
|
+
abstracts: () => ['abstract', 0],
|
|
609
|
+
backmatter: () => ['backmatter', 0],
|
|
613
610
|
bibliography_section: (node) => [
|
|
614
611
|
'ref-list',
|
|
615
612
|
{ id: normalizeID(node.attrs.id) },
|
|
@@ -644,10 +641,7 @@ export class JATSExporter {
|
|
|
644
641
|
const xref = this.document.createElement('xref');
|
|
645
642
|
xref.setAttribute('ref-type', 'bibr');
|
|
646
643
|
xref.setAttribute('rid', rids.map((item) => normalizeID(item.bibliographyItem)).join(' '));
|
|
647
|
-
if (
|
|
648
|
-
xref.textContent = this.generateCitationContent(node);
|
|
649
|
-
}
|
|
650
|
-
else if (node.attrs.contents) {
|
|
644
|
+
if (node.attrs.contents) {
|
|
651
645
|
const text = textFromHTML(node.attrs.contents);
|
|
652
646
|
if (text !== null && text.length) {
|
|
653
647
|
xref.textContent = text;
|
|
@@ -791,7 +785,7 @@ export class JATSExporter {
|
|
|
791
785
|
},
|
|
792
786
|
keyword: () => '',
|
|
793
787
|
keywords_element: () => '',
|
|
794
|
-
|
|
788
|
+
keywords: () => '',
|
|
795
789
|
link: (node) => {
|
|
796
790
|
const text = node.textContent;
|
|
797
791
|
if (!text) {
|
|
@@ -1577,25 +1571,6 @@ export class JATSExporter {
|
|
|
1577
1571
|
return name;
|
|
1578
1572
|
};
|
|
1579
1573
|
}
|
|
1580
|
-
getBibliographyItemsMap() {
|
|
1581
|
-
const map = new Map();
|
|
1582
|
-
this.modelMap.forEach((model) => {
|
|
1583
|
-
if (model.objectType === ObjectTypes.BibliographyItem) {
|
|
1584
|
-
map.set(model._id, model);
|
|
1585
|
-
}
|
|
1586
|
-
});
|
|
1587
|
-
return map;
|
|
1588
|
-
}
|
|
1589
|
-
generateCitationContent(node) {
|
|
1590
|
-
var _a;
|
|
1591
|
-
const citationItems = (_a = node.attrs.embeddedCitationItems) === null || _a === void 0 ? void 0 : _a.map(({ bibliographyItem }) => ({
|
|
1592
|
-
id: bibliographyItem,
|
|
1593
|
-
}));
|
|
1594
|
-
return this.citeProcEngine.previewCitationCluster({
|
|
1595
|
-
citationID: node.attrs.rid,
|
|
1596
|
-
citationItems: citationItems,
|
|
1597
|
-
}, [], [], 'text');
|
|
1598
|
-
}
|
|
1599
1574
|
buildKeywords(articleMeta) {
|
|
1600
1575
|
const keywords = [...this.modelMap.values()].filter((model) => model.objectType === ObjectTypes.Keyword);
|
|
1601
1576
|
const keywordGroups = new Map();
|
package/dist/es/lib/utils.js
CHANGED
|
@@ -84,3 +84,11 @@ export const getTrimmedTextContent = (node, querySelector) => {
|
|
|
84
84
|
}
|
|
85
85
|
return (_b = (_a = node.querySelector(querySelector)) === null || _a === void 0 ? void 0 : _a.textContent) === null || _b === void 0 ? void 0 : _b.trim();
|
|
86
86
|
};
|
|
87
|
+
export const groupBy = (list, getKey) => list.reduce((previous, currentItem) => {
|
|
88
|
+
const group = getKey(currentItem);
|
|
89
|
+
if (!previous[group]) {
|
|
90
|
+
previous[group] = [];
|
|
91
|
+
}
|
|
92
|
+
previous[group].push(currentItem);
|
|
93
|
+
return previous;
|
|
94
|
+
}, {});
|
package/dist/es/schema/index.js
CHANGED
|
@@ -29,6 +29,7 @@ import { comment } from './nodes/comment';
|
|
|
29
29
|
import { commentList } from './nodes/comment_list';
|
|
30
30
|
import { contributor } from './nodes/contributor';
|
|
31
31
|
import { contributorsSection } from './nodes/contributors_section';
|
|
32
|
+
import { coreSection } from './nodes/core_section';
|
|
32
33
|
import { crossReference } from './nodes/cross_reference';
|
|
33
34
|
import { doc } from './nodes/doc';
|
|
34
35
|
import { equation } from './nodes/equation';
|
|
@@ -151,6 +152,9 @@ export const schema = new Schema({
|
|
|
151
152
|
caption,
|
|
152
153
|
caption_title: captionTitle,
|
|
153
154
|
citation,
|
|
155
|
+
abstracts: coreSection,
|
|
156
|
+
body: coreSection,
|
|
157
|
+
backmatter: coreSection,
|
|
154
158
|
cross_reference: crossReference,
|
|
155
159
|
doc,
|
|
156
160
|
equation,
|
|
@@ -168,7 +172,7 @@ export const schema = new Schema({
|
|
|
168
172
|
inline_footnote: inlineFootnote,
|
|
169
173
|
keyword,
|
|
170
174
|
keywords_element: keywordsElement,
|
|
171
|
-
|
|
175
|
+
keywords: keywordsSection,
|
|
172
176
|
keywords_group: keywordsGroup,
|
|
173
177
|
link,
|
|
174
178
|
list_item: listItem,
|
|
@@ -199,7 +203,7 @@ export const schema = new Schema({
|
|
|
199
203
|
meta_section: metaSection,
|
|
200
204
|
contributor: contributor,
|
|
201
205
|
table_element_footer: tableElementFooter,
|
|
202
|
-
|
|
203
|
-
|
|
206
|
+
affiliations: affiliationsSection,
|
|
207
|
+
contributors: contributorsSection,
|
|
204
208
|
},
|
|
205
209
|
});
|
|
@@ -8,4 +8,4 @@ export const affiliationsSection = {
|
|
|
8
8
|
selectable: false,
|
|
9
9
|
toDOM: () => ['section', 0],
|
|
10
10
|
};
|
|
11
|
-
export const isAffiliationsSectionNode = (node) => node.type === node.type.schema.nodes.
|
|
11
|
+
export const isAffiliationsSectionNode = (node) => node.type === node.type.schema.nodes.affiliations;
|
|
@@ -8,4 +8,4 @@ export const contributorsSection = {
|
|
|
8
8
|
selectable: false,
|
|
9
9
|
toDOM: () => ['section', 0],
|
|
10
10
|
};
|
|
11
|
-
export const isContributorsSectionNode = (node) => node.type === node.type.schema.nodes.
|
|
11
|
+
export const isContributorsSectionNode = (node) => node.type === node.type.schema.nodes.contributors;
|
|
@@ -0,0 +1,24 @@
|
|
|
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 coreSection = {
|
|
17
|
+
content: '(section | sections)*',
|
|
18
|
+
atom: true,
|
|
19
|
+
attrs: {
|
|
20
|
+
id: { default: '' },
|
|
21
|
+
},
|
|
22
|
+
group: 'block sections',
|
|
23
|
+
toDOM: () => ['section', 0],
|
|
24
|
+
};
|
|
@@ -28,11 +28,12 @@ import { ObjectTypes, } from '@manuscripts/json-schema';
|
|
|
28
28
|
import debug from 'debug';
|
|
29
29
|
import { DOMParser } from 'prosemirror-model';
|
|
30
30
|
import { MissingElement } from '../errors';
|
|
31
|
+
import { groupBy } from '../lib/utils';
|
|
31
32
|
import { schema, } from '../schema';
|
|
32
33
|
import { insertHighlightMarkers } from './highlight-markers';
|
|
33
34
|
import { generateNodeID } from './id';
|
|
34
35
|
import { ExtraObjectTypes, hasObjectType, isCommentAnnotation, isManuscript, } from './object-types';
|
|
35
|
-
import { chooseSectionLableName, chooseSectionNodeType, chooseSecType, guessSectionCategory, } from './section-category';
|
|
36
|
+
import { chooseCoreSectionBySection, chooseSectionLableName, chooseSectionNodeType, chooseSecType, guessSectionCategory, } from './section-category';
|
|
36
37
|
import { timestamp } from './timestamp';
|
|
37
38
|
const warn = debug('manuscripts-transform');
|
|
38
39
|
const parser = DOMParser.fromSchema(schema);
|
|
@@ -53,6 +54,7 @@ export const sortSectionsByPriority = (a, b) => a.priority === b.priority ? 0 :
|
|
|
53
54
|
const getSections = (modelMap) => getModelsByType(modelMap, ObjectTypes.Section).sort(sortSectionsByPriority);
|
|
54
55
|
const getAffiliations = (modelMap) => getModelsByType(modelMap, ObjectTypes.Affiliation);
|
|
55
56
|
const getContributors = (modelMap) => getModelsByType(modelMap, ObjectTypes.Contributor);
|
|
57
|
+
const getKeywordElements = (modelMap) => getModelsByType(modelMap, ObjectTypes.KeywordsElement);
|
|
56
58
|
export const isManuscriptNode = (model) => model !== null;
|
|
57
59
|
const isParagraphElement = hasObjectType(ObjectTypes.ParagraphElement);
|
|
58
60
|
const isFootnote = hasObjectType(ObjectTypes.Footnote);
|
|
@@ -76,10 +78,13 @@ export class Decoder {
|
|
|
76
78
|
]);
|
|
77
79
|
}
|
|
78
80
|
handleMissingRootSectionNodes(rootSectionNodes) {
|
|
79
|
-
if (!rootSectionNodes.find((node) => node.type.name === '
|
|
81
|
+
if (!rootSectionNodes.find((node) => node.type.name === 'keywords')) {
|
|
82
|
+
this.createKeywordsSectionNode(rootSectionNodes);
|
|
83
|
+
}
|
|
84
|
+
if (!rootSectionNodes.find((node) => node.type.name === 'affiliations')) {
|
|
80
85
|
this.createAffiliationSectionNode(rootSectionNodes);
|
|
81
86
|
}
|
|
82
|
-
if (!rootSectionNodes.find((node) => node.type.name === '
|
|
87
|
+
if (!rootSectionNodes.find((node) => node.type.name === 'contributors')) {
|
|
83
88
|
this.createContributorSectionNode(rootSectionNodes);
|
|
84
89
|
}
|
|
85
90
|
}
|
|
@@ -87,37 +92,79 @@ export class Decoder {
|
|
|
87
92
|
const affiliationNodes = getAffiliations(this.modelMap)
|
|
88
93
|
.map((affiliation) => this.decode(affiliation))
|
|
89
94
|
.filter(Boolean);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
rootSectionNodes.unshift(node);
|
|
95
|
-
}
|
|
95
|
+
const node = schema.nodes.affiliations.createAndFill({
|
|
96
|
+
id: generateNodeID(schema.nodes.section),
|
|
97
|
+
}, affiliationNodes);
|
|
98
|
+
rootSectionNodes.unshift(node);
|
|
96
99
|
}
|
|
97
100
|
createContributorSectionNode(rootSectionNodes) {
|
|
98
101
|
const contributorNodes = getContributors(this.modelMap)
|
|
99
102
|
.map((contributor) => this.decode(contributor))
|
|
100
103
|
.filter(Boolean);
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
const node = schema.nodes.contributors.createAndFill({
|
|
105
|
+
id: generateNodeID(schema.nodes.section),
|
|
106
|
+
}, contributorNodes);
|
|
107
|
+
rootSectionNodes.unshift(node);
|
|
108
|
+
}
|
|
109
|
+
createKeywordsSectionNode(rootSectionNodes) {
|
|
110
|
+
const keywordElementNodes = getKeywordElements(this.modelMap)
|
|
111
|
+
.map((keywordEl) => this.decode(keywordEl))
|
|
112
|
+
.filter(Boolean);
|
|
113
|
+
if (keywordElementNodes) {
|
|
114
|
+
const node = schema.nodes.keywords.createAndFill({
|
|
103
115
|
id: generateNodeID(schema.nodes.section),
|
|
104
|
-
},
|
|
116
|
+
}, [
|
|
117
|
+
schema.nodes.section_title.create({}, schema.text('Keywords')),
|
|
118
|
+
...keywordElementNodes,
|
|
119
|
+
]);
|
|
105
120
|
rootSectionNodes.unshift(node);
|
|
106
121
|
}
|
|
107
122
|
}
|
|
108
123
|
createRootSectionNodes() {
|
|
109
|
-
let rootSections = getSections(this.modelMap)
|
|
124
|
+
let rootSections = getSections(this.modelMap)
|
|
125
|
+
.filter((section) => !section.path || section.path.length <= 1)
|
|
126
|
+
.filter((section) => section.category !== 'MPSectionCategory:contributors' &&
|
|
127
|
+
section.category !== 'MPSectionCategory:affiliations' &&
|
|
128
|
+
section.category !== 'MPSectionCategory:keywords');
|
|
110
129
|
rootSections = this.addGeneratedLabels(rootSections);
|
|
111
|
-
const
|
|
130
|
+
const sectionGroups = groupBy(rootSections, (sec) => {
|
|
131
|
+
var _a;
|
|
132
|
+
return chooseCoreSectionBySection((_a = sec.category) !== null && _a !== void 0 ? _a : '');
|
|
133
|
+
});
|
|
134
|
+
this.ensureCoreSectionsExist(sectionGroups);
|
|
135
|
+
const absSectionNode = sectionGroups['MPSectionCategory:abstracts']
|
|
112
136
|
.map(this.decode)
|
|
113
137
|
.filter(isManuscriptNode);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
138
|
+
const bodySectionNodes = sectionGroups['MPSectionCategory:body']
|
|
139
|
+
.map(this.decode)
|
|
140
|
+
.filter(isManuscriptNode);
|
|
141
|
+
const backmatterSectionNodes = sectionGroups['MPSectionCategory:backmatter']
|
|
142
|
+
.map(this.decode)
|
|
143
|
+
.filter(isManuscriptNode);
|
|
144
|
+
const abstractCoreSectionNodes = this.createAndFill(schema.nodes.abstracts, absSectionNode);
|
|
145
|
+
const bodyCoreSectionNodes = this.createAndFill(schema.nodes.body, bodySectionNodes);
|
|
146
|
+
const backmatterCoreSectionNodes = this.createAndFill(schema.nodes.backmatter, backmatterSectionNodes);
|
|
147
|
+
return [
|
|
148
|
+
abstractCoreSectionNodes,
|
|
149
|
+
bodyCoreSectionNodes,
|
|
150
|
+
backmatterCoreSectionNodes,
|
|
151
|
+
];
|
|
152
|
+
}
|
|
153
|
+
ensureCoreSectionsExist(coreSections) {
|
|
154
|
+
if (!coreSections['MPSectionCategory:abstracts']) {
|
|
155
|
+
coreSections['MPSectionCategory:abstracts'] = [];
|
|
119
156
|
}
|
|
120
|
-
|
|
157
|
+
if (!coreSections['MPSectionCategory:body']) {
|
|
158
|
+
coreSections['MPSectionCategory:body'] = [];
|
|
159
|
+
}
|
|
160
|
+
if (!coreSections['MPSectionCategory:backmatter']) {
|
|
161
|
+
coreSections['MPSectionCategory:backmatter'] = [];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
createAndFill(nodeType, content) {
|
|
165
|
+
return nodeType.createAndFill({
|
|
166
|
+
id: generateNodeID(nodeType),
|
|
167
|
+
}, content);
|
|
121
168
|
}
|
|
122
169
|
createCommentsNode(model) {
|
|
123
170
|
const comments = [];
|
|
@@ -622,6 +669,7 @@ export class Decoder {
|
|
|
622
669
|
this.getModel = (id) => this.modelMap.get(id);
|
|
623
670
|
this.createArticleNode = (manuscriptID) => {
|
|
624
671
|
const rootSectionNodes = this.createRootSectionNodes();
|
|
672
|
+
this.handleMissingRootSectionNodes(rootSectionNodes);
|
|
625
673
|
const metaSectionNode = this.createMetaSectionNode();
|
|
626
674
|
const contents = [...rootSectionNodes, metaSectionNode];
|
|
627
675
|
return schema.nodes.manuscript.create({
|
|
@@ -417,31 +417,6 @@ const encoders = {
|
|
|
417
417
|
keywords_group: (node) => ({
|
|
418
418
|
type: node.attrs.type,
|
|
419
419
|
}),
|
|
420
|
-
keywords_section: (node, parent, path, priority) => ({
|
|
421
|
-
category: buildSectionCategory(node),
|
|
422
|
-
priority: priority.value++,
|
|
423
|
-
title: inlineContentsOfNodeType(node, node.type.schema.nodes.section_title),
|
|
424
|
-
path: path.concat([node.attrs.id]),
|
|
425
|
-
elementIDs: childElements(node)
|
|
426
|
-
.map((childNode) => childNode.attrs.id)
|
|
427
|
-
.filter((id) => id),
|
|
428
|
-
}),
|
|
429
|
-
affiliations_section: (node, parent, path, priority) => ({
|
|
430
|
-
category: buildSectionCategory(node),
|
|
431
|
-
priority: priority.value++,
|
|
432
|
-
path: path.concat([node.attrs.id]),
|
|
433
|
-
elementIDs: childElements(node)
|
|
434
|
-
.map((childNode) => childNode.attrs.id)
|
|
435
|
-
.filter((id) => id),
|
|
436
|
-
}),
|
|
437
|
-
contributors_section: (node, parent, path, priority) => ({
|
|
438
|
-
category: buildSectionCategory(node),
|
|
439
|
-
priority: priority.value++,
|
|
440
|
-
path: path.concat([node.attrs.id]),
|
|
441
|
-
elementIDs: childElements(node)
|
|
442
|
-
.map((childNode) => childNode.attrs.id)
|
|
443
|
-
.filter((id) => id),
|
|
444
|
-
}),
|
|
445
420
|
missing_figure: (node) => ({
|
|
446
421
|
position: node.attrs.position || undefined,
|
|
447
422
|
}),
|
|
@@ -561,6 +536,14 @@ export const modelFromNode = (node, parent, path, priority) => {
|
|
|
561
536
|
}
|
|
562
537
|
return { model, commentAnnotationsMap };
|
|
563
538
|
};
|
|
539
|
+
function isCoreSection(child) {
|
|
540
|
+
return (child.type === schema.nodes.abstracts ||
|
|
541
|
+
child.type === schema.nodes.body ||
|
|
542
|
+
child.type === schema.nodes.backmatter ||
|
|
543
|
+
child.type === schema.nodes.affiliations ||
|
|
544
|
+
child.type === schema.nodes.contributors ||
|
|
545
|
+
child.type === schema.nodes.keywords);
|
|
546
|
+
}
|
|
564
547
|
export const encode = (node) => {
|
|
565
548
|
const models = new Map();
|
|
566
549
|
const priority = {
|
|
@@ -568,6 +551,10 @@ export const encode = (node) => {
|
|
|
568
551
|
};
|
|
569
552
|
const placeholders = ['placeholder', 'placeholder_element'];
|
|
570
553
|
const addModel = (path, parent) => (child) => {
|
|
554
|
+
if (isCoreSection(child)) {
|
|
555
|
+
child.forEach(addModel([], child));
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
571
558
|
if (!child.attrs.id) {
|
|
572
559
|
return;
|
|
573
560
|
}
|
|
@@ -35,6 +35,6 @@ export const nodeNames = new Map([
|
|
|
35
35
|
[schema.nodes.table_element, 'Table'],
|
|
36
36
|
[schema.nodes.blockquote_element, 'Block Quote'],
|
|
37
37
|
[schema.nodes.pullquote_element, 'Pull Quote'],
|
|
38
|
-
[schema.nodes.
|
|
38
|
+
[schema.nodes.keywords, 'Section'],
|
|
39
39
|
[schema.nodes.toc_section, 'Section'],
|
|
40
40
|
]);
|
|
@@ -45,7 +45,7 @@ export const nodeTitle = (node) => {
|
|
|
45
45
|
case nodes.section:
|
|
46
46
|
case nodes.bibliography_section:
|
|
47
47
|
case nodes.footnotes_section:
|
|
48
|
-
case nodes.
|
|
48
|
+
case nodes.keywords:
|
|
49
49
|
case nodes.toc_section:
|
|
50
50
|
case nodes.graphical_abstract_section:
|
|
51
51
|
return snippetOfNodeType(node, nodes.section_title);
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
import { ObjectTypes } from '@manuscripts/json-schema';
|
|
17
17
|
import { GROUP_ELEMENT, GROUP_EXECUTABLE, GROUP_SECTION, hasGroup, schema, } from '../schema';
|
|
18
18
|
export const nodeTypesMap = new Map([
|
|
19
|
+
[schema.nodes.abstracts, ObjectTypes.Section],
|
|
20
|
+
[schema.nodes.body, ObjectTypes.Section],
|
|
21
|
+
[schema.nodes.backmatter, ObjectTypes.Section],
|
|
19
22
|
[schema.nodes.comment, ObjectTypes.CommentAnnotation],
|
|
20
23
|
[schema.nodes.bibliography_item, ObjectTypes.BibliographyItem],
|
|
21
24
|
[schema.nodes.bibliography_element, ObjectTypes.BibliographyElement],
|
|
@@ -37,7 +40,7 @@ export const nodeTypesMap = new Map([
|
|
|
37
40
|
[schema.nodes.inline_equation, ObjectTypes.InlineMathFragment],
|
|
38
41
|
[schema.nodes.keyword, ObjectTypes.Keyword],
|
|
39
42
|
[schema.nodes.keywords_element, ObjectTypes.KeywordsElement],
|
|
40
|
-
[schema.nodes.
|
|
43
|
+
[schema.nodes.keywords, ObjectTypes.Section],
|
|
41
44
|
[schema.nodes.keywords_group, ObjectTypes.KeywordGroup],
|
|
42
45
|
[schema.nodes.listing, ObjectTypes.Listing],
|
|
43
46
|
[schema.nodes.listing_element, ObjectTypes.ListingElement],
|
|
@@ -54,8 +57,8 @@ export const nodeTypesMap = new Map([
|
|
|
54
57
|
[schema.nodes.affiliation, ObjectTypes.Affiliation],
|
|
55
58
|
[schema.nodes.contributor, ObjectTypes.Contributor],
|
|
56
59
|
[schema.nodes.table_element_footer, ObjectTypes.TableElementFooter],
|
|
57
|
-
[schema.nodes.
|
|
58
|
-
[schema.nodes.
|
|
60
|
+
[schema.nodes.contributors, ObjectTypes.Section],
|
|
61
|
+
[schema.nodes.affiliations, ObjectTypes.Section],
|
|
59
62
|
]);
|
|
60
63
|
export const isExecutableNodeType = (type) => hasGroup(type, GROUP_EXECUTABLE);
|
|
61
64
|
export const isElementNodeType = (type) => hasGroup(type, GROUP_ELEMENT);
|
|
@@ -19,7 +19,7 @@ import { schema } from '../schema';
|
|
|
19
19
|
const sectionNodeTypes = [
|
|
20
20
|
schema.nodes.bibliography_section,
|
|
21
21
|
schema.nodes.footnotes_section,
|
|
22
|
-
schema.nodes.
|
|
22
|
+
schema.nodes.keywords,
|
|
23
23
|
schema.nodes.section,
|
|
24
24
|
schema.nodes.toc_section,
|
|
25
25
|
];
|
|
@@ -40,11 +40,11 @@ export const chooseSectionNodeType = (category) => {
|
|
|
40
40
|
case 'MPSectionCategory:endnotes':
|
|
41
41
|
return schema.nodes.footnotes_section;
|
|
42
42
|
case 'MPSectionCategory:keywords':
|
|
43
|
-
return schema.nodes.
|
|
43
|
+
return schema.nodes.keywords;
|
|
44
44
|
case 'MPSectionCategory:affiliations':
|
|
45
|
-
return schema.nodes.
|
|
45
|
+
return schema.nodes.affiliations;
|
|
46
46
|
case 'MPSectionCategory:contributors':
|
|
47
|
-
return schema.nodes.
|
|
47
|
+
return schema.nodes.contributors;
|
|
48
48
|
case 'MPSectionCategory:toc':
|
|
49
49
|
return schema.nodes.toc_section;
|
|
50
50
|
default:
|
|
@@ -82,15 +82,15 @@ export const buildSectionCategory = (node) => {
|
|
|
82
82
|
return 'MPSectionCategory:bibliography';
|
|
83
83
|
case schema.nodes.footnotes_section:
|
|
84
84
|
return 'MPSectionCategory:endnotes';
|
|
85
|
-
case schema.nodes.
|
|
85
|
+
case schema.nodes.keywords:
|
|
86
86
|
return 'MPSectionCategory:keywords';
|
|
87
87
|
case schema.nodes.toc_section:
|
|
88
88
|
return 'MPSectionCategory:toc';
|
|
89
89
|
case schema.nodes.graphical_abstract_section:
|
|
90
90
|
return 'MPSectionCategory:abstract-graphical';
|
|
91
|
-
case schema.nodes.
|
|
91
|
+
case schema.nodes.affiliations:
|
|
92
92
|
return 'MPSectionCategory:affiliations';
|
|
93
|
-
case schema.nodes.
|
|
93
|
+
case schema.nodes.contributors:
|
|
94
94
|
return 'MPSectionCategory:contributors';
|
|
95
95
|
default:
|
|
96
96
|
return node.attrs.category || undefined;
|
|
@@ -117,6 +117,32 @@ export const chooseSecType = (sectionCategory) => {
|
|
|
117
117
|
return suffix;
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
|
+
export const chooseCoreSectionBySection = (section) => {
|
|
121
|
+
switch (section) {
|
|
122
|
+
case 'MPSectionCategory:abstract':
|
|
123
|
+
case 'MPSectionCategory:abstract-teaser':
|
|
124
|
+
case 'MPSectionCategory:abstract-graphical':
|
|
125
|
+
return 'MPSectionCategory:abstracts';
|
|
126
|
+
case 'MPSectionCategory:acknowledgement':
|
|
127
|
+
case 'MPSectionCategory:availability':
|
|
128
|
+
case 'MPSectionCategory:conclusions':
|
|
129
|
+
case 'MPSectionCategory:bibliography':
|
|
130
|
+
case 'MPSectionCategory:discussion':
|
|
131
|
+
case 'MPSectionCategory:endnotes':
|
|
132
|
+
case 'MPSectionCategory:appendices':
|
|
133
|
+
case 'MPSectionCategory:competing-interests':
|
|
134
|
+
case 'MPSectionCategory:con':
|
|
135
|
+
case 'MPSectionCategory:deceased':
|
|
136
|
+
case 'MPSectionCategory:ethics-statement':
|
|
137
|
+
case 'MPSectionCategory:financial-disclosure':
|
|
138
|
+
case 'MPSectionCategory:supplementary-material':
|
|
139
|
+
case 'MPSectionCategory:supported-by':
|
|
140
|
+
case 'MPSectionCategory:abbreviations':
|
|
141
|
+
case 'MPSectionCategory:results':
|
|
142
|
+
return 'MPSectionCategory:backmatter';
|
|
143
|
+
}
|
|
144
|
+
return 'MPSectionCategory:body';
|
|
145
|
+
};
|
|
120
146
|
export const chooseSectionCategoryByType = (secType) => {
|
|
121
147
|
switch (secType) {
|
|
122
148
|
case 'abstract':
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {
|
|
17
|
-
import CiteProc from 'citeproc';
|
|
16
|
+
import { Model } from '@manuscripts/json-schema';
|
|
18
17
|
import { DOMSerializer } from 'prosemirror-model';
|
|
19
18
|
import { ManuscriptFragment, ManuscriptNode } from '../schema';
|
|
20
19
|
import { Target } from '../transformer/labels';
|
|
@@ -37,19 +36,13 @@ export interface JATSExporterOptions {
|
|
|
37
36
|
citationType?: 'element' | 'mixed';
|
|
38
37
|
idGenerator?: IDGenerator;
|
|
39
38
|
mediaPathGenerator?: MediaPathGenerator;
|
|
40
|
-
citationStyle?: string;
|
|
41
|
-
locale?: string;
|
|
42
39
|
}
|
|
43
40
|
export declare class JATSExporter {
|
|
44
41
|
protected document: Document;
|
|
45
|
-
protected citeProcEngine: CiteProc.Engine;
|
|
46
42
|
protected modelMap: Map<string, Model>;
|
|
47
|
-
protected bibliographyItemsMap: Map<string, BibliographyItem>;
|
|
48
43
|
protected models: Model[];
|
|
49
44
|
protected serializer: DOMSerializer;
|
|
50
45
|
protected labelTargets?: Map<string, Target>;
|
|
51
|
-
private getBibliographyItemsMap;
|
|
52
|
-
private generateCitationContent;
|
|
53
46
|
serializeToJATS: (fragment: ManuscriptFragment, modelMap: Map<string, Model>, manuscriptID: string, options?: JATSExporterOptions) => Promise<string>;
|
|
54
47
|
private nodeFromJATS;
|
|
55
48
|
protected rewriteCrossReferenceTypes: () => void;
|
|
@@ -27,3 +27,4 @@ export declare const findParentNodeClosestToPos: ($pos: ResolvedPos, predicate:
|
|
|
27
27
|
node: ProsemirrorNode;
|
|
28
28
|
} | undefined;
|
|
29
29
|
export declare const getTrimmedTextContent: (node: Element | Document, querySelector: string) => string | null | undefined;
|
|
30
|
+
export declare const groupBy: <T, K extends string | number | symbol>(list: T[], getKey: (item: T) => K) => Record<K, T[]>;
|