@manuscripts/transform 1.5.5 → 1.5.7-LEAN-3030
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 +23 -18
- package/dist/cjs/jats/importer/jats-body-transformations.js +3 -3
- package/dist/cjs/jats/jats-exporter.js +11 -6
- package/dist/cjs/lib/utils.js +10 -1
- package/dist/cjs/schema/index.js +15 -11
- package/dist/cjs/schema/nodes/{affiliations_section.js → affiliations.js} +9 -8
- package/dist/cjs/schema/nodes/{contributors_section.js → contributors.js} +8 -7
- package/dist/cjs/schema/nodes/core_section.js +27 -0
- package/dist/cjs/schema/nodes/graphical_abstract_section.js +1 -0
- package/dist/cjs/schema/nodes/keyword.js +0 -1
- package/dist/cjs/schema/nodes/{keywords_group.js → keyword_group.js} +6 -6
- package/dist/cjs/schema/nodes/{keywords_section.js → keywords.js} +7 -7
- package/dist/cjs/schema/nodes/keywords_element.js +1 -1
- package/dist/cjs/schema/nodes/manuscript.js +1 -1
- package/dist/cjs/transformer/decode.js +110 -113
- package/dist/cjs/transformer/encode.js +24 -28
- 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 +7 -4
- package/dist/cjs/transformer/section-category.js +35 -8
- package/dist/es/jats/importer/jats-body-dom-parser.js +23 -18
- package/dist/es/jats/importer/jats-body-transformations.js +3 -3
- package/dist/es/jats/jats-exporter.js +11 -6
- package/dist/es/lib/utils.js +8 -0
- package/dist/es/schema/index.js +15 -11
- package/dist/es/schema/nodes/{affiliations_section.js → affiliations.js} +7 -6
- package/dist/es/schema/nodes/{contributors_section.js → contributors.js} +6 -5
- package/dist/es/schema/nodes/core_section.js +24 -0
- package/dist/es/schema/nodes/graphical_abstract_section.js +1 -0
- package/dist/es/schema/nodes/keyword.js +0 -1
- package/dist/es/schema/nodes/{keywords_group.js → keyword_group.js} +4 -4
- package/dist/es/schema/nodes/{keywords_section.js → keywords.js} +5 -5
- package/dist/es/schema/nodes/keywords_element.js +1 -1
- package/dist/es/schema/nodes/manuscript.js +1 -1
- package/dist/es/transformer/decode.js +111 -114
- package/dist/es/transformer/encode.js +24 -28
- 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 +7 -4
- package/dist/es/transformer/section-category.js +33 -7
- package/dist/types/lib/utils.d.ts +1 -0
- package/dist/types/schema/index.d.ts +3 -3
- package/dist/types/schema/nodes/affiliations.d.ts +11 -0
- package/dist/types/schema/nodes/contributors.d.ts +12 -0
- package/dist/types/schema/nodes/core_section.d.ts +17 -0
- package/dist/types/schema/nodes/keyword.d.ts +0 -1
- package/dist/types/schema/nodes/{keywords_group.d.ts → keyword_group.d.ts} +3 -3
- package/dist/types/schema/nodes/{keywords_section.d.ts → keywords.d.ts} +3 -3
- package/dist/types/schema/types.d.ts +1 -1
- package/dist/types/transformer/decode.d.ts +6 -6
- package/dist/types/transformer/encode.d.ts +1 -1
- package/dist/types/transformer/section-category.d.ts +1 -0
- package/package.json +1 -1
- package/dist/types/schema/nodes/affiliations_section.d.ts +0 -11
- package/dist/types/schema/nodes/contributors_section.d.ts +0 -12
|
@@ -424,9 +424,11 @@ export class JATSExporter {
|
|
|
424
424
|
}
|
|
425
425
|
};
|
|
426
426
|
this.buildBody = (fragment) => {
|
|
427
|
-
const content = this.serializeFragment(fragment);
|
|
428
427
|
const body = this.document.createElement('body');
|
|
429
|
-
|
|
428
|
+
fragment.forEach((cFragment) => {
|
|
429
|
+
const serializedNode = this.serializeNode(cFragment);
|
|
430
|
+
body.append(...serializedNode.childNodes);
|
|
431
|
+
});
|
|
430
432
|
this.fixBody(body, fragment);
|
|
431
433
|
return body;
|
|
432
434
|
};
|
|
@@ -593,8 +595,8 @@ export class JATSExporter {
|
|
|
593
595
|
const getModel = (id) => id ? this.modelMap.get(id) : undefined;
|
|
594
596
|
const nodes = {
|
|
595
597
|
title: () => '',
|
|
596
|
-
|
|
597
|
-
|
|
598
|
+
affiliations: () => '',
|
|
599
|
+
contributors: () => '',
|
|
598
600
|
table_element_footer: () => ['table-wrap-foot', 0],
|
|
599
601
|
contributor: () => '',
|
|
600
602
|
affiliation: () => '',
|
|
@@ -603,7 +605,10 @@ export class JATSExporter {
|
|
|
603
605
|
bibliography_element: () => '',
|
|
604
606
|
bibliography_item: () => '',
|
|
605
607
|
comment_list: () => '',
|
|
606
|
-
|
|
608
|
+
keyword_group: () => '',
|
|
609
|
+
body: () => ['body', 0],
|
|
610
|
+
abstracts: () => ['abstract', 0],
|
|
611
|
+
backmatter: () => ['backmatter', 0],
|
|
607
612
|
bibliography_section: (node) => [
|
|
608
613
|
'ref-list',
|
|
609
614
|
{ id: normalizeID(node.attrs.id) },
|
|
@@ -782,7 +787,7 @@ export class JATSExporter {
|
|
|
782
787
|
},
|
|
783
788
|
keyword: () => '',
|
|
784
789
|
keywords_element: () => '',
|
|
785
|
-
|
|
790
|
+
keywords: () => '',
|
|
786
791
|
link: (node) => {
|
|
787
792
|
const text = node.textContent;
|
|
788
793
|
if (!text) {
|
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
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import { Schema } from 'prosemirror-model';
|
|
17
17
|
import { bold, code, italic, smallcaps, strikethrough, styled, subscript, superscript, tracked_delete, tracked_insert, underline, } from './marks';
|
|
18
18
|
import { affiliation } from './nodes/affiliation';
|
|
19
|
-
import {
|
|
19
|
+
import { affiliations } from './nodes/affiliations';
|
|
20
20
|
import { attribution } from './nodes/attribution';
|
|
21
21
|
import { bibliographyElement } from './nodes/bibliography_element';
|
|
22
22
|
import { bibliographyItem } from './nodes/bibliography_item';
|
|
@@ -28,7 +28,8 @@ import { citation } from './nodes/citation';
|
|
|
28
28
|
import { comment } from './nodes/comment';
|
|
29
29
|
import { commentList } from './nodes/comment_list';
|
|
30
30
|
import { contributor } from './nodes/contributor';
|
|
31
|
-
import {
|
|
31
|
+
import { contributors } from './nodes/contributors';
|
|
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';
|
|
@@ -45,9 +46,9 @@ import { highlightMarker } from './nodes/highlight_marker';
|
|
|
45
46
|
import { inlineEquation } from './nodes/inline_equation';
|
|
46
47
|
import { inlineFootnote } from './nodes/inline_footnote';
|
|
47
48
|
import { keyword } from './nodes/keyword';
|
|
49
|
+
import { keywordGroup } from './nodes/keyword_group';
|
|
50
|
+
import { keywords } from './nodes/keywords';
|
|
48
51
|
import { keywordsElement } from './nodes/keywords_element';
|
|
49
|
-
import { keywordsGroup } from './nodes/keywords_group';
|
|
50
|
-
import { keywordsSection } from './nodes/keywords_section';
|
|
51
52
|
import { link } from './nodes/link';
|
|
52
53
|
import { bulletList, listItem, orderedList } from './nodes/list';
|
|
53
54
|
import { listing } from './nodes/listing';
|
|
@@ -100,7 +101,7 @@ export * from './nodes/inline_equation';
|
|
|
100
101
|
export * from './nodes/inline_footnote';
|
|
101
102
|
export * from './nodes/keyword';
|
|
102
103
|
export * from './nodes/keywords_element';
|
|
103
|
-
export * from './nodes/
|
|
104
|
+
export * from './nodes/keywords';
|
|
104
105
|
export * from './nodes/link';
|
|
105
106
|
export * from './nodes/list';
|
|
106
107
|
export * from './nodes/listing';
|
|
@@ -125,8 +126,8 @@ export * from './nodes/meta_section';
|
|
|
125
126
|
export * from './nodes/contributor';
|
|
126
127
|
export * from './nodes/table_element_footer';
|
|
127
128
|
export * from './nodes/title';
|
|
128
|
-
export * from './nodes/
|
|
129
|
-
export * from './nodes/
|
|
129
|
+
export * from './nodes/affiliations';
|
|
130
|
+
export * from './nodes/contributors';
|
|
130
131
|
export const schema = new Schema({
|
|
131
132
|
marks: {
|
|
132
133
|
bold,
|
|
@@ -153,6 +154,9 @@ export const schema = new Schema({
|
|
|
153
154
|
caption,
|
|
154
155
|
caption_title: captionTitle,
|
|
155
156
|
citation,
|
|
157
|
+
abstracts: coreSection,
|
|
158
|
+
body: coreSection,
|
|
159
|
+
backmatter: coreSection,
|
|
156
160
|
cross_reference: crossReference,
|
|
157
161
|
doc,
|
|
158
162
|
equation,
|
|
@@ -170,8 +174,8 @@ export const schema = new Schema({
|
|
|
170
174
|
inline_footnote: inlineFootnote,
|
|
171
175
|
keyword,
|
|
172
176
|
keywords_element: keywordsElement,
|
|
173
|
-
|
|
174
|
-
|
|
177
|
+
keywords: keywords,
|
|
178
|
+
keyword_group: keywordGroup,
|
|
175
179
|
link,
|
|
176
180
|
list_item: listItem,
|
|
177
181
|
listing,
|
|
@@ -202,7 +206,7 @@ export const schema = new Schema({
|
|
|
202
206
|
contributor: contributor,
|
|
203
207
|
table_element_footer: tableElementFooter,
|
|
204
208
|
title: title,
|
|
205
|
-
|
|
206
|
-
|
|
209
|
+
affiliations: affiliations,
|
|
210
|
+
contributors: contributors,
|
|
207
211
|
},
|
|
208
212
|
});
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { schema } from '../index';
|
|
2
|
+
export const affiliations = {
|
|
2
3
|
content: 'section_title? affiliation*',
|
|
3
4
|
attrs: {
|
|
4
5
|
id: { default: 'META_SECTION_AFFILLIATIONS' },
|
|
5
6
|
dataTracked: { default: null },
|
|
6
7
|
},
|
|
7
|
-
group: 'block
|
|
8
|
+
group: 'block',
|
|
8
9
|
selectable: false,
|
|
9
10
|
parseDOM: [
|
|
10
11
|
{
|
|
@@ -18,15 +19,15 @@ export const affiliationsSection = {
|
|
|
18
19
|
},
|
|
19
20
|
],
|
|
20
21
|
toDOM: (node) => {
|
|
21
|
-
const
|
|
22
|
+
const affiliations = node;
|
|
22
23
|
return [
|
|
23
24
|
'section',
|
|
24
25
|
{
|
|
25
26
|
class: 'affiliations',
|
|
26
|
-
id:
|
|
27
|
+
id: affiliations.attrs.id,
|
|
27
28
|
},
|
|
28
|
-
0
|
|
29
|
+
0,
|
|
29
30
|
];
|
|
30
31
|
},
|
|
31
32
|
};
|
|
32
|
-
export const
|
|
33
|
+
export const isAffiliationsNode = (node) => node.type === schema.nodes.affiliations;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import { schema } from '../index';
|
|
2
|
+
export const contributors = {
|
|
2
3
|
content: 'section_title? contributor*',
|
|
3
4
|
attrs: {
|
|
4
5
|
id: { default: 'META_SECTION_CONTRIBUTORS' },
|
|
5
6
|
dataTracked: { default: null },
|
|
6
7
|
contents: { default: '' },
|
|
7
8
|
},
|
|
8
|
-
group: 'block
|
|
9
|
+
group: 'block',
|
|
9
10
|
selectable: false,
|
|
10
11
|
parseDOM: [
|
|
11
12
|
{
|
|
@@ -18,15 +19,15 @@ export const contributorsSection = {
|
|
|
18
19
|
},
|
|
19
20
|
],
|
|
20
21
|
toDOM: (node) => {
|
|
21
|
-
const
|
|
22
|
+
const contributors = node;
|
|
22
23
|
return [
|
|
23
24
|
'section',
|
|
24
25
|
{
|
|
25
26
|
class: 'contributors',
|
|
26
|
-
id:
|
|
27
|
+
id: contributors.attrs.id,
|
|
27
28
|
},
|
|
28
29
|
0,
|
|
29
30
|
];
|
|
30
31
|
},
|
|
31
32
|
};
|
|
32
|
-
export const
|
|
33
|
+
export const isContributorsNode = (node) => 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: 'sections*',
|
|
18
|
+
atom: true,
|
|
19
|
+
attrs: {
|
|
20
|
+
id: { default: '' },
|
|
21
|
+
},
|
|
22
|
+
group: 'block',
|
|
23
|
+
toDOM: () => ['section', 0],
|
|
24
|
+
};
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
export const
|
|
16
|
+
export const keywordGroup = {
|
|
17
17
|
content: 'keyword*',
|
|
18
18
|
attrs: {
|
|
19
19
|
id: { default: '' },
|
|
@@ -28,11 +28,11 @@ export const keywordsGroup = {
|
|
|
28
28
|
},
|
|
29
29
|
],
|
|
30
30
|
toDOM: (node) => {
|
|
31
|
-
const
|
|
31
|
+
const keywordGroupNode = node;
|
|
32
32
|
return [
|
|
33
33
|
'div',
|
|
34
34
|
{
|
|
35
|
-
id:
|
|
35
|
+
id: keywordGroupNode.attrs.id,
|
|
36
36
|
class: 'keywords',
|
|
37
37
|
spellcheck: 'false',
|
|
38
38
|
contenteditable: false,
|
|
@@ -41,4 +41,4 @@ export const keywordsGroup = {
|
|
|
41
41
|
];
|
|
42
42
|
},
|
|
43
43
|
};
|
|
44
|
-
export const
|
|
44
|
+
export const isKeywordGroupNode = (node) => node.type === node.type.schema.nodes.keywords_group;
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
export const
|
|
16
|
+
export const keywords = {
|
|
17
17
|
content: 'section_title (keywords_element | placeholder_element)',
|
|
18
18
|
attrs: {
|
|
19
19
|
id: { default: '' },
|
|
20
20
|
dataTracked: { default: null },
|
|
21
21
|
},
|
|
22
|
-
group: 'block
|
|
22
|
+
group: 'block',
|
|
23
23
|
selectable: false,
|
|
24
24
|
parseDOM: [
|
|
25
25
|
{
|
|
@@ -27,11 +27,11 @@ export const keywordsSection = {
|
|
|
27
27
|
},
|
|
28
28
|
],
|
|
29
29
|
toDOM: (node) => {
|
|
30
|
-
const
|
|
30
|
+
const keywords = node;
|
|
31
31
|
return [
|
|
32
32
|
'div',
|
|
33
33
|
{
|
|
34
|
-
id:
|
|
34
|
+
id: keywords.attrs.id,
|
|
35
35
|
class: 'keywords',
|
|
36
36
|
spellcheck: 'false',
|
|
37
37
|
contenteditable: false,
|
|
@@ -40,4 +40,4 @@ export const keywordsSection = {
|
|
|
40
40
|
];
|
|
41
41
|
},
|
|
42
42
|
};
|
|
43
|
-
export const
|
|
43
|
+
export const isKeywordsNode = (node) => node.type === node.type.schema.nodes.keywords;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
export const manuscript = {
|
|
17
|
-
content: 'title
|
|
17
|
+
content: 'title? contributors? affiliations? keywords? abstracts body backmatter meta_section',
|
|
18
18
|
attrs: {
|
|
19
19
|
id: { default: '' },
|
|
20
20
|
},
|
|
@@ -28,12 +28,13 @@ 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 { buildTitles } from './builders';
|
|
33
34
|
import { insertHighlightMarkers } from './highlight-markers';
|
|
34
35
|
import { generateNodeID } from './id';
|
|
35
36
|
import { ExtraObjectTypes, hasObjectType, isCommentAnnotation, isManuscript, } from './object-types';
|
|
36
|
-
import { chooseSectionLableName, chooseSectionNodeType, chooseSecType, guessSectionCategory, } from './section-category';
|
|
37
|
+
import { chooseCoreSectionBySection, chooseSectionLableName, chooseSectionNodeType, chooseSecType, guessSectionCategory, } from './section-category';
|
|
37
38
|
import { timestamp } from './timestamp';
|
|
38
39
|
const warn = debug('manuscripts-transform');
|
|
39
40
|
const parser = DOMParser.fromSchema(schema);
|
|
@@ -54,17 +55,41 @@ export const sortSectionsByPriority = (a, b) => a.priority === b.priority ? 0 :
|
|
|
54
55
|
const getSections = (modelMap) => getModelsByType(modelMap, ObjectTypes.Section).sort(sortSectionsByPriority);
|
|
55
56
|
const getAffiliations = (modelMap) => getModelsByType(modelMap, ObjectTypes.Affiliation);
|
|
56
57
|
const getContributors = (modelMap) => getModelsByType(modelMap, ObjectTypes.Contributor);
|
|
58
|
+
const getKeywordElements = (modelMap) => getModelsByType(modelMap, ObjectTypes.KeywordsElement);
|
|
59
|
+
const getKeywordGroups = (modelMap) => getModelsByType(modelMap, ObjectTypes.KeywordGroup);
|
|
60
|
+
const getKeywords = (modelMap) => getModelsByType(modelMap, ObjectTypes.Keyword);
|
|
61
|
+
const getTitles = (modelMap) => getModelsByType(modelMap, ObjectTypes.Titles)[0];
|
|
57
62
|
export const isManuscriptNode = (model) => model !== null;
|
|
58
|
-
const isParagraphElement = hasObjectType(ObjectTypes.ParagraphElement);
|
|
59
63
|
const isFootnote = hasObjectType(ObjectTypes.Footnote);
|
|
60
|
-
const isKeyword = hasObjectType(ObjectTypes.Keyword);
|
|
61
|
-
const isKeywordsSection = (model) => model.category === 'MPSectionCategory:keywords';
|
|
62
|
-
const isAffiliationsSection = (model) => model.category === 'MPSectionCategory:affiliations';
|
|
63
|
-
const isContributorsSection = (model) => model.category === 'MPSectionCategory:contributors';
|
|
64
64
|
const hasParentSection = (id) => (section) => section.path &&
|
|
65
65
|
section.path.length > 1 &&
|
|
66
66
|
section.path[section.path.length - 2] === id;
|
|
67
67
|
export class Decoder {
|
|
68
|
+
createTitleNode() {
|
|
69
|
+
const titles = getTitles(this.modelMap) || buildTitles();
|
|
70
|
+
return this.decode(titles);
|
|
71
|
+
}
|
|
72
|
+
createAffiliationsNode() {
|
|
73
|
+
const affiliations = getAffiliations(this.modelMap)
|
|
74
|
+
.map((a) => this.decode(a))
|
|
75
|
+
.filter(Boolean);
|
|
76
|
+
return schema.nodes.affiliations.createAndFill({}, affiliations);
|
|
77
|
+
}
|
|
78
|
+
createContributorsNode() {
|
|
79
|
+
const contributors = getContributors(this.modelMap)
|
|
80
|
+
.map((c) => this.decode(c))
|
|
81
|
+
.filter(Boolean);
|
|
82
|
+
return schema.nodes.contributors.createAndFill({}, contributors);
|
|
83
|
+
}
|
|
84
|
+
createKeywordsNode() {
|
|
85
|
+
const elements = getKeywordElements(this.modelMap)
|
|
86
|
+
.map((e) => this.decode(e))
|
|
87
|
+
.filter(Boolean);
|
|
88
|
+
return schema.nodes.keywords.createAndFill({}, [
|
|
89
|
+
schema.nodes.section_title.create({}, schema.text('Keywords')),
|
|
90
|
+
...elements,
|
|
91
|
+
]);
|
|
92
|
+
}
|
|
68
93
|
createMetaSectionNode() {
|
|
69
94
|
const commentListNode = this.createCommentListNode();
|
|
70
95
|
return schema.nodes.meta_section.createAndFill({}, [
|
|
@@ -76,54 +101,51 @@ export class Decoder {
|
|
|
76
101
|
...this.comments.values(),
|
|
77
102
|
]);
|
|
78
103
|
}
|
|
79
|
-
handleMissingRootSectionNodes(rootSectionNodes) {
|
|
80
|
-
if (!rootSectionNodes.find((node) => node.type.name === 'affiliations_section')) {
|
|
81
|
-
this.createAffiliationSectionNode(rootSectionNodes);
|
|
82
|
-
}
|
|
83
|
-
if (!rootSectionNodes.find((node) => node.type.name === 'contributors_section')) {
|
|
84
|
-
this.createContributorSectionNode(rootSectionNodes);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
createAffiliationSectionNode(rootSectionNodes) {
|
|
88
|
-
const affiliationNodes = getAffiliations(this.modelMap)
|
|
89
|
-
.map((affiliation) => this.decode(affiliation))
|
|
90
|
-
.filter(Boolean);
|
|
91
|
-
if (affiliationNodes.length) {
|
|
92
|
-
const node = schema.nodes.affiliations_section.createAndFill({
|
|
93
|
-
id: generateNodeID(schema.nodes.section),
|
|
94
|
-
}, affiliationNodes);
|
|
95
|
-
rootSectionNodes.unshift(node);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
createContributorSectionNode(rootSectionNodes) {
|
|
99
|
-
const contributorNodes = getContributors(this.modelMap)
|
|
100
|
-
.map((contributor) => this.decode(contributor))
|
|
101
|
-
.filter(Boolean);
|
|
102
|
-
if (contributorNodes.length) {
|
|
103
|
-
const node = schema.nodes.contributors_section.createAndFill({
|
|
104
|
-
id: generateNodeID(schema.nodes.section),
|
|
105
|
-
}, contributorNodes);
|
|
106
|
-
rootSectionNodes.unshift(node);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
createTitleNode() {
|
|
110
|
-
const titles = getModelsByType(this.modelMap, ObjectTypes.Titles)[0] ||
|
|
111
|
-
buildTitles();
|
|
112
|
-
return this.decode(titles);
|
|
113
|
-
}
|
|
114
104
|
createRootSectionNodes() {
|
|
115
|
-
let rootSections = getSections(this.modelMap)
|
|
105
|
+
let rootSections = getSections(this.modelMap)
|
|
106
|
+
.filter((section) => !section.path || section.path.length <= 1)
|
|
107
|
+
.filter((section) => section.category !== 'MPSectionCategory:contributors' &&
|
|
108
|
+
section.category !== 'MPSectionCategory:affiliations' &&
|
|
109
|
+
section.category !== 'MPSectionCategory:keywords');
|
|
116
110
|
rootSections = this.addGeneratedLabels(rootSections);
|
|
117
|
-
const
|
|
111
|
+
const sectionGroups = groupBy(rootSections, (sec) => {
|
|
112
|
+
var _a;
|
|
113
|
+
return chooseCoreSectionBySection((_a = sec.category) !== null && _a !== void 0 ? _a : '');
|
|
114
|
+
});
|
|
115
|
+
this.ensureCoreSectionsExist(sectionGroups);
|
|
116
|
+
const absSectionNode = sectionGroups['MPSectionCategory:abstracts']
|
|
117
|
+
.map(this.decode)
|
|
118
|
+
.filter(isManuscriptNode);
|
|
119
|
+
const bodySectionNodes = sectionGroups['MPSectionCategory:body']
|
|
120
|
+
.map(this.decode)
|
|
121
|
+
.filter(isManuscriptNode);
|
|
122
|
+
const backmatterSectionNodes = sectionGroups['MPSectionCategory:backmatter']
|
|
118
123
|
.map(this.decode)
|
|
119
124
|
.filter(isManuscriptNode);
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
const abstractCoreSectionNodes = this.createAndFill(schema.nodes.abstracts, absSectionNode);
|
|
126
|
+
const bodyCoreSectionNodes = this.createAndFill(schema.nodes.body, bodySectionNodes);
|
|
127
|
+
const backmatterCoreSectionNodes = this.createAndFill(schema.nodes.backmatter, backmatterSectionNodes);
|
|
128
|
+
return {
|
|
129
|
+
abstracts: abstractCoreSectionNodes,
|
|
130
|
+
body: bodyCoreSectionNodes,
|
|
131
|
+
backmatter: backmatterCoreSectionNodes,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
ensureCoreSectionsExist(coreSections) {
|
|
135
|
+
if (!coreSections['MPSectionCategory:abstracts']) {
|
|
136
|
+
coreSections['MPSectionCategory:abstracts'] = [];
|
|
137
|
+
}
|
|
138
|
+
if (!coreSections['MPSectionCategory:body']) {
|
|
139
|
+
coreSections['MPSectionCategory:body'] = [];
|
|
125
140
|
}
|
|
126
|
-
|
|
141
|
+
if (!coreSections['MPSectionCategory:backmatter']) {
|
|
142
|
+
coreSections['MPSectionCategory:backmatter'] = [];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
createAndFill(nodeType, content) {
|
|
146
|
+
return nodeType.createAndFill({
|
|
147
|
+
id: generateNodeID(nodeType),
|
|
148
|
+
}, content);
|
|
127
149
|
}
|
|
128
150
|
createCommentsNode(model) {
|
|
129
151
|
const comments = [];
|
|
@@ -329,19 +351,34 @@ export class Decoder {
|
|
|
329
351
|
},
|
|
330
352
|
[ObjectTypes.KeywordsElement]: (data) => {
|
|
331
353
|
const model = data;
|
|
332
|
-
const keywordGroups = this.
|
|
354
|
+
const keywordGroups = getKeywordGroups(this.modelMap).map((k) => this.decode(k));
|
|
333
355
|
return schema.nodes.keywords_element.create({
|
|
334
356
|
id: model._id,
|
|
335
357
|
paragraphStyle: model.paragraphStyle,
|
|
336
358
|
}, keywordGroups);
|
|
337
359
|
},
|
|
360
|
+
[ObjectTypes.KeywordGroup]: (data) => {
|
|
361
|
+
const keywordGroup = data;
|
|
362
|
+
const keywords = getKeywords(this.modelMap)
|
|
363
|
+
.filter((k) => k.containedGroup === keywordGroup._id)
|
|
364
|
+
.map((k) => this.decode(k));
|
|
365
|
+
const comments = this.createCommentsNode(keywordGroup);
|
|
366
|
+
comments.forEach((c) => this.comments.set(c.attrs.id, c));
|
|
367
|
+
return schema.nodes.keyword_group.create({
|
|
368
|
+
id: keywordGroup._id,
|
|
369
|
+
type: keywordGroup.type,
|
|
370
|
+
comments: comments.map((c) => c.attrs.id),
|
|
371
|
+
}, keywords);
|
|
372
|
+
},
|
|
338
373
|
[ObjectTypes.Keyword]: (data) => {
|
|
339
|
-
const
|
|
374
|
+
const keyword = data;
|
|
375
|
+
const comments = this.createCommentsNode(keyword);
|
|
376
|
+
comments.forEach((c) => this.comments.set(c.attrs.id, c));
|
|
340
377
|
return schema.nodes.keyword.create({
|
|
341
|
-
id:
|
|
342
|
-
contents:
|
|
343
|
-
comments:
|
|
344
|
-
}, schema.text(
|
|
378
|
+
id: keyword._id,
|
|
379
|
+
contents: keyword.name,
|
|
380
|
+
comments: comments.map((c) => c.attrs.id),
|
|
381
|
+
}, schema.text(keyword.name));
|
|
345
382
|
},
|
|
346
383
|
[ObjectTypes.ListElement]: (data) => {
|
|
347
384
|
const model = data;
|
|
@@ -463,9 +500,6 @@ export class Decoder {
|
|
|
463
500
|
for (const id of model.elementIDs) {
|
|
464
501
|
const element = this.getModel(id);
|
|
465
502
|
if (element) {
|
|
466
|
-
if (isKeywordsSection(model) && isParagraphElement(element)) {
|
|
467
|
-
continue;
|
|
468
|
-
}
|
|
469
503
|
elements.push(element);
|
|
470
504
|
}
|
|
471
505
|
else if (this.allowMissingElements) {
|
|
@@ -506,17 +540,11 @@ export class Decoder {
|
|
|
506
540
|
const sectionNodeType = chooseSectionNodeType(sectionCategory);
|
|
507
541
|
const commentNodes = this.createCommentsNode(model);
|
|
508
542
|
commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
content = (sectionLabelNode
|
|
515
|
-
? [sectionLabelNode, sectionTitleNode]
|
|
516
|
-
: [sectionTitleNode])
|
|
517
|
-
.concat(elementNodes)
|
|
518
|
-
.concat(nestedSections);
|
|
519
|
-
}
|
|
543
|
+
const content = (sectionLabelNode
|
|
544
|
+
? [sectionLabelNode, sectionTitleNode]
|
|
545
|
+
: [sectionTitleNode])
|
|
546
|
+
.concat(elementNodes)
|
|
547
|
+
.concat(nestedSections);
|
|
520
548
|
const sectionNode = sectionNodeType.createAndFill({
|
|
521
549
|
id: model._id,
|
|
522
550
|
category: sectionCategory,
|
|
@@ -635,13 +663,21 @@ export class Decoder {
|
|
|
635
663
|
};
|
|
636
664
|
this.getModel = (id) => this.modelMap.get(id);
|
|
637
665
|
this.createArticleNode = (manuscriptID) => {
|
|
638
|
-
const
|
|
639
|
-
const
|
|
640
|
-
const
|
|
666
|
+
const title = this.createTitleNode();
|
|
667
|
+
const contributors = this.createContributorsNode();
|
|
668
|
+
const affiliations = this.createAffiliationsNode();
|
|
669
|
+
const keywords = this.createKeywordsNode();
|
|
670
|
+
const { abstracts, body, backmatter } = this.createRootSectionNodes();
|
|
671
|
+
const meta = this.createMetaSectionNode();
|
|
641
672
|
const contents = [
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
673
|
+
title,
|
|
674
|
+
contributors,
|
|
675
|
+
affiliations,
|
|
676
|
+
keywords,
|
|
677
|
+
abstracts,
|
|
678
|
+
body,
|
|
679
|
+
backmatter,
|
|
680
|
+
meta,
|
|
645
681
|
];
|
|
646
682
|
return schema.nodes.manuscript.create({
|
|
647
683
|
id: manuscriptID || this.getManuscriptID(),
|
|
@@ -683,23 +719,6 @@ export class Decoder {
|
|
|
683
719
|
}
|
|
684
720
|
return parser.parse(template.content.firstElementChild, options);
|
|
685
721
|
};
|
|
686
|
-
this.getKeywords = (id) => {
|
|
687
|
-
const keywordsOfKind = [];
|
|
688
|
-
const keywordsByGroup = [...this.modelMap.values()].filter((m) => m.objectType === ObjectTypes.Keyword &&
|
|
689
|
-
m.containedGroup === id);
|
|
690
|
-
for (const model of keywordsByGroup) {
|
|
691
|
-
if (isKeyword(model)) {
|
|
692
|
-
const keyword = this.parseContents(model.name || '', 'div', this.getComments(model), {
|
|
693
|
-
topNode: schema.nodes.keyword.create({
|
|
694
|
-
id: model._id,
|
|
695
|
-
contents: model.name,
|
|
696
|
-
}),
|
|
697
|
-
});
|
|
698
|
-
keywordsOfKind.push(keyword);
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
return keywordsOfKind;
|
|
702
|
-
};
|
|
703
722
|
this.getManuscriptID = () => {
|
|
704
723
|
for (const item of this.modelMap.values()) {
|
|
705
724
|
if (isManuscript(item)) {
|
|
@@ -784,26 +803,4 @@ export class Decoder {
|
|
|
784
803
|
}
|
|
785
804
|
return listing;
|
|
786
805
|
}
|
|
787
|
-
getKeywordGroups() {
|
|
788
|
-
const kwdGroupNodes = [];
|
|
789
|
-
const kwdGroupsModels = [
|
|
790
|
-
...this.modelMap.values(),
|
|
791
|
-
].filter((model) => model.objectType === ObjectTypes.KeywordGroup);
|
|
792
|
-
if (kwdGroupsModels.length > 0) {
|
|
793
|
-
for (const kwdGroupModel of kwdGroupsModels) {
|
|
794
|
-
const keywords = this.getKeywords(kwdGroupModel._id);
|
|
795
|
-
const commentNodes = this.createCommentsNode(kwdGroupModel);
|
|
796
|
-
commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
|
|
797
|
-
const contents = [];
|
|
798
|
-
contents.push(...keywords);
|
|
799
|
-
const kwdGroupNode = schema.nodes.keywords_group.create({
|
|
800
|
-
id: kwdGroupModel._id,
|
|
801
|
-
type: kwdGroupModel.type,
|
|
802
|
-
comments: commentNodes.map((c) => c.attrs.id),
|
|
803
|
-
}, contents);
|
|
804
|
-
kwdGroupNodes.push(kwdGroupNode);
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
return kwdGroupNodes;
|
|
808
|
-
}
|
|
809
806
|
}
|