@manuscripts/transform 1.4.6 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/jats/importer/jats-body-dom-parser.js +126 -0
- package/dist/cjs/jats/importer/jats-body-transformations.js +59 -0
- package/dist/cjs/jats/importer/jats-front-parser.js +7 -7
- package/dist/cjs/jats/importer/jats-parser-utils.js +4 -0
- package/dist/cjs/jats/importer/parse-jats-article.js +7 -5
- package/dist/cjs/jats/jats-exporter.js +2 -2
- package/dist/cjs/lib/core-section-categories.js +2 -2
- package/dist/cjs/schema/index.js +6 -6
- package/dist/cjs/schema/nodes/affiliation.js +3 -0
- package/dist/cjs/schema/nodes/affiliations_section.js +15 -0
- package/dist/cjs/schema/nodes/contributor.js +8 -1
- package/dist/cjs/schema/nodes/contributors_section.js +15 -0
- package/dist/cjs/schema/nodes/meta_section.js +1 -1
- package/dist/cjs/transformer/decode.js +51 -23
- package/dist/cjs/transformer/encode.js +20 -0
- package/dist/cjs/transformer/node-types.js +2 -0
- package/dist/cjs/transformer/section-category.js +12 -0
- package/dist/es/jats/importer/jats-body-dom-parser.js +126 -0
- package/dist/es/jats/importer/jats-body-transformations.js +59 -0
- package/dist/es/jats/importer/jats-front-parser.js +1 -1
- package/dist/es/jats/importer/jats-parser-utils.js +4 -0
- package/dist/es/jats/importer/parse-jats-article.js +7 -5
- package/dist/es/jats/jats-exporter.js +2 -2
- package/dist/es/lib/core-section-categories.js +2 -2
- package/dist/es/schema/index.js +6 -6
- package/dist/es/schema/nodes/affiliation.js +3 -0
- package/dist/es/schema/nodes/affiliations_section.js +11 -0
- package/dist/es/schema/nodes/contributor.js +6 -0
- package/dist/es/schema/nodes/contributors_section.js +11 -0
- package/dist/es/schema/nodes/meta_section.js +1 -1
- package/dist/es/transformer/decode.js +51 -23
- package/dist/es/transformer/encode.js +20 -0
- package/dist/es/transformer/node-types.js +2 -0
- package/dist/es/transformer/section-category.js +12 -0
- package/dist/types/jats/importer/jats-body-transformations.d.ts +4 -1
- package/dist/types/jats/importer/jats-front-parser.d.ts +5 -5
- package/dist/types/jats/importer/parse-jats-article.d.ts +5 -2
- package/dist/types/schema/index.d.ts +2 -2
- package/dist/types/schema/nodes/affiliation.d.ts +1 -0
- package/dist/types/schema/nodes/affiliations_section.d.ts +11 -0
- package/dist/types/schema/nodes/contributor.d.ts +2 -0
- package/dist/types/schema/nodes/contributors_section.d.ts +11 -0
- package/dist/types/schema/types.d.ts +1 -1
- package/dist/types/transformer/decode.d.ts +3 -2
- package/dist/types/transformer/section-category.d.ts +2 -2
- package/package.json +2 -2
- package/dist/cjs/schema/nodes/affiliation_list.js +0 -10
- package/dist/cjs/schema/nodes/contributor_list.js +0 -10
- package/dist/es/schema/nodes/affiliation_list.js +0 -7
- package/dist/es/schema/nodes/contributor_list.js +0 -7
- package/dist/types/schema/nodes/affiliation_list.d.ts +0 -10
- package/dist/types/schema/nodes/contributor_list.d.ts +0 -10
|
@@ -57,6 +57,8 @@ exports.nodeTypesMap = new Map([
|
|
|
57
57
|
[schema_1.schema.nodes.affiliation, json_schema_1.ObjectTypes.Affiliation],
|
|
58
58
|
[schema_1.schema.nodes.contributor, json_schema_1.ObjectTypes.Contributor],
|
|
59
59
|
[schema_1.schema.nodes.table_element_footer, json_schema_1.ObjectTypes.TableElementFooter],
|
|
60
|
+
[schema_1.schema.nodes.contributors_section, json_schema_1.ObjectTypes.Section],
|
|
61
|
+
[schema_1.schema.nodes.affiliations_section, json_schema_1.ObjectTypes.Section],
|
|
60
62
|
]);
|
|
61
63
|
const isExecutableNodeType = (type) => (0, schema_1.hasGroup)(type, schema_1.GROUP_EXECUTABLE);
|
|
62
64
|
exports.isExecutableNodeType = isExecutableNodeType;
|
|
@@ -46,6 +46,10 @@ const chooseSectionNodeType = (category) => {
|
|
|
46
46
|
return schema_1.schema.nodes.footnotes_section;
|
|
47
47
|
case 'MPSectionCategory:keywords':
|
|
48
48
|
return schema_1.schema.nodes.keywords_section;
|
|
49
|
+
case 'MPSectionCategory:affiliations':
|
|
50
|
+
return schema_1.schema.nodes.affiliations_section;
|
|
51
|
+
case 'MPSectionCategory:contributors':
|
|
52
|
+
return schema_1.schema.nodes.contributors_section;
|
|
49
53
|
case 'MPSectionCategory:toc':
|
|
50
54
|
return schema_1.schema.nodes.toc_section;
|
|
51
55
|
default:
|
|
@@ -92,6 +96,10 @@ const buildSectionCategory = (node) => {
|
|
|
92
96
|
return 'MPSectionCategory:toc';
|
|
93
97
|
case schema_1.schema.nodes.graphical_abstract_section:
|
|
94
98
|
return 'MPSectionCategory:abstract-graphical';
|
|
99
|
+
case schema_1.schema.nodes.affiliations_section:
|
|
100
|
+
return 'MPSectionCategory:affiliations';
|
|
101
|
+
case schema_1.schema.nodes.contributors_section:
|
|
102
|
+
return 'MPSectionCategory:contributors';
|
|
95
103
|
default:
|
|
96
104
|
return node.attrs.category || undefined;
|
|
97
105
|
}
|
|
@@ -185,6 +193,10 @@ const chooseSectionCategoryByType = (secType) => {
|
|
|
185
193
|
return 'MPSectionCategory:backmatter';
|
|
186
194
|
case 'abstracts':
|
|
187
195
|
return 'MPSectionCategory:abstracts';
|
|
196
|
+
case 'affiliations':
|
|
197
|
+
return 'MPSectionCategory:affiliations';
|
|
198
|
+
case 'contributors':
|
|
199
|
+
return 'MPSectionCategory:contributors';
|
|
188
200
|
default:
|
|
189
201
|
return undefined;
|
|
190
202
|
}
|
|
@@ -499,6 +499,132 @@ const nodes = [
|
|
|
499
499
|
};
|
|
500
500
|
},
|
|
501
501
|
},
|
|
502
|
+
{
|
|
503
|
+
tag: 'sec[sec-type="affiliations"]',
|
|
504
|
+
node: 'affiliations_section',
|
|
505
|
+
getAttrs: (node) => {
|
|
506
|
+
const element = node;
|
|
507
|
+
return {
|
|
508
|
+
id: element.getAttribute('id'),
|
|
509
|
+
category: 'MPSectionCategory:affiliations',
|
|
510
|
+
};
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
tag: 'aff',
|
|
515
|
+
node: 'affiliation',
|
|
516
|
+
context: 'affiliations_section/',
|
|
517
|
+
getAttrs: (node) => {
|
|
518
|
+
const element = node;
|
|
519
|
+
const aff = {
|
|
520
|
+
id: element.getAttribute('id'),
|
|
521
|
+
};
|
|
522
|
+
const institution = element.getAttribute('institution');
|
|
523
|
+
if (institution) {
|
|
524
|
+
aff.institution = institution;
|
|
525
|
+
}
|
|
526
|
+
const email = element.getAttribute('email');
|
|
527
|
+
if (email) {
|
|
528
|
+
aff.bibliographicName = JSON.parse(email);
|
|
529
|
+
}
|
|
530
|
+
const department = element.getAttribute('department');
|
|
531
|
+
if (department) {
|
|
532
|
+
aff.department = department;
|
|
533
|
+
}
|
|
534
|
+
const addressLine1 = element.getAttribute('addressLine1');
|
|
535
|
+
if (addressLine1) {
|
|
536
|
+
aff.addressLine1 = addressLine1;
|
|
537
|
+
}
|
|
538
|
+
const addressLine2 = element.getAttribute('addressLine2');
|
|
539
|
+
if (addressLine2) {
|
|
540
|
+
aff.addressLine2 = addressLine2;
|
|
541
|
+
}
|
|
542
|
+
const addressLine3 = element.getAttribute('addressLine3');
|
|
543
|
+
if (addressLine3) {
|
|
544
|
+
aff.addressLine3 = addressLine3;
|
|
545
|
+
}
|
|
546
|
+
const postCode = element.getAttribute('postCode');
|
|
547
|
+
if (postCode) {
|
|
548
|
+
aff.postCode = postCode;
|
|
549
|
+
}
|
|
550
|
+
const country = element.getAttribute('country');
|
|
551
|
+
if (country) {
|
|
552
|
+
aff.country = country;
|
|
553
|
+
}
|
|
554
|
+
const priority = element.getAttribute('priority');
|
|
555
|
+
if (priority) {
|
|
556
|
+
aff.priority = parseInt(priority);
|
|
557
|
+
}
|
|
558
|
+
return aff;
|
|
559
|
+
},
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
tag: 'sec[sec-type="contributors"]',
|
|
563
|
+
node: 'contributors_section',
|
|
564
|
+
getAttrs: (node) => {
|
|
565
|
+
const element = node;
|
|
566
|
+
return {
|
|
567
|
+
id: element.getAttribute('id'),
|
|
568
|
+
category: 'MPSectionCategory:contributors',
|
|
569
|
+
};
|
|
570
|
+
},
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
tag: 'contrib',
|
|
574
|
+
node: 'contributor',
|
|
575
|
+
context: 'contributors_section/',
|
|
576
|
+
getAttrs: (node) => {
|
|
577
|
+
const element = node;
|
|
578
|
+
const contrib = {
|
|
579
|
+
id: element.getAttribute('id'),
|
|
580
|
+
};
|
|
581
|
+
const role = element.getAttribute('role');
|
|
582
|
+
if (role) {
|
|
583
|
+
contrib.role = role;
|
|
584
|
+
}
|
|
585
|
+
const affiliations = element.getAttribute('affiliations');
|
|
586
|
+
if (affiliations) {
|
|
587
|
+
contrib.affiliations = JSON.parse(affiliations);
|
|
588
|
+
}
|
|
589
|
+
const footnote = element.getAttribute('footnote');
|
|
590
|
+
if (footnote) {
|
|
591
|
+
contrib.footnote = JSON.parse(footnote);
|
|
592
|
+
}
|
|
593
|
+
const corresp = element.getAttribute('corresp');
|
|
594
|
+
if (corresp) {
|
|
595
|
+
contrib.corresp = JSON.parse(corresp);
|
|
596
|
+
}
|
|
597
|
+
const bibliographicName = element.getAttribute('bibliographicName');
|
|
598
|
+
if (bibliographicName) {
|
|
599
|
+
contrib.bibliographicName = JSON.parse(bibliographicName);
|
|
600
|
+
}
|
|
601
|
+
const userID = element.getAttribute('userID');
|
|
602
|
+
if (userID) {
|
|
603
|
+
contrib.userID = userID;
|
|
604
|
+
}
|
|
605
|
+
const priority = element.getAttribute('priority');
|
|
606
|
+
if (priority) {
|
|
607
|
+
contrib.priority = parseInt(priority);
|
|
608
|
+
}
|
|
609
|
+
const invitationID = element.getAttribute('invitationID');
|
|
610
|
+
if (invitationID) {
|
|
611
|
+
contrib.invitationID = invitationID;
|
|
612
|
+
}
|
|
613
|
+
const objectType = element.getAttribute('objectType');
|
|
614
|
+
if (objectType) {
|
|
615
|
+
contrib.objectType = objectType;
|
|
616
|
+
}
|
|
617
|
+
const isCorresponding = element.getAttribute('isCorresponding');
|
|
618
|
+
if (isCorresponding) {
|
|
619
|
+
contrib.isCorresponding = JSON.parse(isCorresponding);
|
|
620
|
+
}
|
|
621
|
+
const ORCIDIdentifier = element.getAttribute('ORCIDIdentifier');
|
|
622
|
+
if (ORCIDIdentifier) {
|
|
623
|
+
contrib.ORCIDIdentifier = ORCIDIdentifier;
|
|
624
|
+
}
|
|
625
|
+
return contrib;
|
|
626
|
+
},
|
|
627
|
+
},
|
|
502
628
|
{
|
|
503
629
|
tag: 'sec[sec-type="keywords"]',
|
|
504
630
|
node: 'keywords_section',
|
|
@@ -281,6 +281,65 @@ export const jatsBodyTransformations = {
|
|
|
281
281
|
}
|
|
282
282
|
}
|
|
283
283
|
},
|
|
284
|
+
moveAffiliationsToBody(doc, affiliations, body, createElement) {
|
|
285
|
+
if (affiliations === null || affiliations === void 0 ? void 0 : affiliations.length) {
|
|
286
|
+
const section = createElement('sec');
|
|
287
|
+
section.setAttribute('sec-type', 'affiliations');
|
|
288
|
+
affiliations.forEach((affiliation) => {
|
|
289
|
+
const item = doc.createElement('aff');
|
|
290
|
+
item.setAttribute('id', affiliation._id);
|
|
291
|
+
affiliation.institution &&
|
|
292
|
+
item.setAttribute('institution', affiliation.institution);
|
|
293
|
+
affiliation.email &&
|
|
294
|
+
item.setAttribute('email', JSON.stringify(affiliation.email));
|
|
295
|
+
affiliation.department &&
|
|
296
|
+
item.setAttribute('department', affiliation.department);
|
|
297
|
+
affiliation.addressLine1 &&
|
|
298
|
+
item.setAttribute('addressLine1', affiliation.addressLine1);
|
|
299
|
+
affiliation.addressLine2 &&
|
|
300
|
+
item.setAttribute('addressLine2', affiliation.addressLine2);
|
|
301
|
+
affiliation.addressLine3 &&
|
|
302
|
+
item.setAttribute('addressLine3', affiliation.addressLine3);
|
|
303
|
+
affiliation.postCode &&
|
|
304
|
+
item.setAttribute('postCode', affiliation.postCode);
|
|
305
|
+
affiliation.country && item.setAttribute('country', affiliation.country);
|
|
306
|
+
(affiliation.priority === 0 || affiliation.priority) &&
|
|
307
|
+
item.setAttribute('priority', affiliation.priority.toString());
|
|
308
|
+
section.appendChild(item);
|
|
309
|
+
});
|
|
310
|
+
body.prepend(section);
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
moveAuthorsToBody(doc, authors, body, createElement) {
|
|
314
|
+
if (authors === null || authors === void 0 ? void 0 : authors.length) {
|
|
315
|
+
const section = createElement('sec');
|
|
316
|
+
section.setAttribute('sec-type', 'contributors');
|
|
317
|
+
authors.forEach((author) => {
|
|
318
|
+
const item = doc.createElement('contrib');
|
|
319
|
+
item.setAttribute('id', author._id);
|
|
320
|
+
author.role && item.setAttribute('role', author.role);
|
|
321
|
+
author.affiliations &&
|
|
322
|
+
item.setAttribute('affiliations', JSON.stringify(author.affiliations));
|
|
323
|
+
author.footnote &&
|
|
324
|
+
item.setAttribute('footnote', JSON.stringify(author.footnote));
|
|
325
|
+
author.corresp &&
|
|
326
|
+
item.setAttribute('corresp', JSON.stringify(author.corresp));
|
|
327
|
+
author.bibliographicName &&
|
|
328
|
+
item.setAttribute('bibliographicName', JSON.stringify(author.bibliographicName));
|
|
329
|
+
author.userID && item.setAttribute('userID', author.userID);
|
|
330
|
+
author.invitationID &&
|
|
331
|
+
item.setAttribute('invitationID', author.invitationID);
|
|
332
|
+
author.isCorresponding &&
|
|
333
|
+
item.setAttribute('isCorresponding', JSON.stringify(author.isCorresponding));
|
|
334
|
+
author.ORCIDIdentifier &&
|
|
335
|
+
item.setAttribute('ORCIDIdentifier', author.ORCIDIdentifier);
|
|
336
|
+
(author.priority === 0 || author.priority) &&
|
|
337
|
+
item.setAttribute('priority', author.priority.toString());
|
|
338
|
+
section.appendChild(item);
|
|
339
|
+
});
|
|
340
|
+
body.prepend(section);
|
|
341
|
+
}
|
|
342
|
+
},
|
|
284
343
|
moveFloatsGroupToBody(doc, body, createElement) {
|
|
285
344
|
const floatsGroup = doc.querySelector('floats-group');
|
|
286
345
|
if (floatsGroup) {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import debug from 'debug';
|
|
17
17
|
import { getTrimmedTextContent } from '../../lib/utils';
|
|
18
|
-
import { buildAffiliation, buildBibliographicName, buildContributor, buildCorresp, buildFootnote, buildSupplementaryMaterial, } from '../../transformer
|
|
18
|
+
import { buildAffiliation, buildBibliographicName, buildContributor, buildCorresp, buildFootnote, buildSupplementaryMaterial, } from '../../transformer';
|
|
19
19
|
import { parseJournalMeta } from './jats-journal-meta-parser';
|
|
20
20
|
const warn = debug('manuscripts-transform');
|
|
21
21
|
const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { ObjectTypes, } from '@manuscripts/json-schema';
|
|
17
17
|
import { generateID, hasObjectType, nodeTypesMap } from '../../transformer';
|
|
18
18
|
const isAuxiliaryObjectReference = hasObjectType(ObjectTypes.AuxiliaryObjectReference);
|
|
19
|
+
const excludedObjectTypes = [ObjectTypes.Contributor, ObjectTypes.Affiliation];
|
|
19
20
|
export function flatten(arrays) {
|
|
20
21
|
return [].concat(...arrays);
|
|
21
22
|
}
|
|
@@ -44,6 +45,9 @@ const addMissingID = (node, replacements, warnings) => {
|
|
|
44
45
|
warnings.push(`Unknown object type for node type ${node.type.name}`);
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
48
|
+
if (excludedObjectTypes.includes(objectType)) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
47
51
|
const previousID = node.attrs.id;
|
|
48
52
|
const nextID = generateID(objectType);
|
|
49
53
|
if (previousID) {
|
|
@@ -71,13 +71,13 @@ export const parseJATSFront = async (front) => {
|
|
|
71
71
|
return {
|
|
72
72
|
models: generateModelIDs([
|
|
73
73
|
manuscript,
|
|
74
|
-
...affiliations,
|
|
75
|
-
...authors,
|
|
76
74
|
...footnotes,
|
|
77
75
|
...correspondingList,
|
|
78
76
|
journal,
|
|
79
77
|
...supplements,
|
|
80
78
|
]),
|
|
79
|
+
authors: [...authors],
|
|
80
|
+
affiliations: [...affiliations],
|
|
81
81
|
};
|
|
82
82
|
};
|
|
83
83
|
export const parseJATSReferences = (back, body, createElement) => {
|
|
@@ -101,7 +101,7 @@ export const parseJATSReferences = (back, body, createElement) => {
|
|
|
101
101
|
referenceIdsMap,
|
|
102
102
|
};
|
|
103
103
|
};
|
|
104
|
-
export const parseJATSBody = (document, body, bibliographyItems, refModels, referenceIdsMap, footnotesOrder) => {
|
|
104
|
+
export const parseJATSBody = (document, body, bibliographyItems, authors, affiliations, refModels, referenceIdsMap, footnotesOrder) => {
|
|
105
105
|
const createElement = createElementFn(document);
|
|
106
106
|
const orderedFootnotesIDs = createOrderedFootnotesIDs(document);
|
|
107
107
|
jatsBodyTransformations.moveFloatsGroupToBody(document, body, createElement);
|
|
@@ -111,6 +111,8 @@ export const parseJATSBody = (document, body, bibliographyItems, refModels, refe
|
|
|
111
111
|
jatsBodyTransformations.moveTableFooterToEnd(body);
|
|
112
112
|
jatsBodyTransformations.moveBlockNodesFromParagraph(document, body, createElement);
|
|
113
113
|
jatsBodyTransformations.moveKeywordsToBody(document, body, createElement);
|
|
114
|
+
jatsBodyTransformations.moveAffiliationsToBody(document, affiliations, body, createElement);
|
|
115
|
+
jatsBodyTransformations.moveAuthorsToBody(document, authors, body, createElement);
|
|
114
116
|
const node = jatsBodyDOMParser.parse(body);
|
|
115
117
|
if (!node.firstChild) {
|
|
116
118
|
throw new Error('No content was parsed from the JATS article body');
|
|
@@ -162,14 +164,14 @@ export const parseJATSArticle = async (doc) => {
|
|
|
162
164
|
}
|
|
163
165
|
const authorQueriesMap = markProcessingInstructions(doc);
|
|
164
166
|
const createElement = createElementFn(document);
|
|
165
|
-
const { models: frontModels } = await parseJATSFront(front);
|
|
167
|
+
const { models: frontModels, authors, affiliations, } = await parseJATSFront(front);
|
|
166
168
|
const { references, crossReferences, referenceQueriesMap, referenceIdsMap } = parseJATSReferences(back, body, createElement);
|
|
167
169
|
transformTables(doc.querySelectorAll('table-wrap > table'), createElement);
|
|
168
170
|
const footnotesOrder = createEmptyFootnotesOrder();
|
|
169
171
|
let elementsOrder = [];
|
|
170
172
|
const bodyModels = [];
|
|
171
173
|
if (body) {
|
|
172
|
-
const bodyDoc = parseJATSBody(doc, body, references, crossReferences, referenceIdsMap, footnotesOrder);
|
|
174
|
+
const bodyDoc = parseJATSBody(doc, body, references, authors, affiliations, crossReferences, referenceIdsMap, footnotesOrder);
|
|
173
175
|
bodyModels.push(...encode(bodyDoc).values());
|
|
174
176
|
elementsOrder = getElementsOrder(bodyDoc);
|
|
175
177
|
}
|
|
@@ -591,10 +591,10 @@ export class JATSExporter {
|
|
|
591
591
|
this.createSerializer = () => {
|
|
592
592
|
const getModel = (id) => id ? this.modelMap.get(id) : undefined;
|
|
593
593
|
const nodes = {
|
|
594
|
+
affiliations_section: () => '',
|
|
595
|
+
contributors_section: () => '',
|
|
594
596
|
table_element_footer: () => ['table-wrap-foot', 0],
|
|
595
|
-
contributor_list: () => '',
|
|
596
597
|
contributor: () => '',
|
|
597
|
-
affiliation_list: () => '',
|
|
598
598
|
affiliation: () => '',
|
|
599
599
|
meta_section: () => '',
|
|
600
600
|
attribution: () => ['attrib', 0],
|
|
@@ -13,7 +13,7 @@ export const coreSectionCategories = [
|
|
|
13
13
|
desc: 'Backmatter section for grouping',
|
|
14
14
|
objectType: 'MPSectionCategory',
|
|
15
15
|
titles: [],
|
|
16
|
-
priority:
|
|
16
|
+
priority: 180,
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
_id: 'MPSectionCategory:body',
|
|
@@ -21,6 +21,6 @@ export const coreSectionCategories = [
|
|
|
21
21
|
desc: 'Body section for grouping',
|
|
22
22
|
objectType: 'MPSectionCategory',
|
|
23
23
|
titles: [],
|
|
24
|
-
priority:
|
|
24
|
+
priority: 200,
|
|
25
25
|
},
|
|
26
26
|
];
|
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 { affiliationsSection } from './nodes/affiliations_section';
|
|
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,7 @@ 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 { contributorsSection } from './nodes/contributors_section';
|
|
32
32
|
import { crossReference } from './nodes/cross_reference';
|
|
33
33
|
import { doc } from './nodes/doc';
|
|
34
34
|
import { equation } from './nodes/equation';
|
|
@@ -120,11 +120,11 @@ export * from './nodes/text';
|
|
|
120
120
|
export * from './nodes/toc_element';
|
|
121
121
|
export * from './nodes/toc_section';
|
|
122
122
|
export * from './nodes/affiliation';
|
|
123
|
-
export * from './nodes/affiliation_list';
|
|
124
123
|
export * from './nodes/meta_section';
|
|
125
|
-
export * from './nodes/contributor_list';
|
|
126
124
|
export * from './nodes/contributor';
|
|
127
125
|
export * from './nodes/table_element_footer';
|
|
126
|
+
export * from './nodes/affiliations_section';
|
|
127
|
+
export * from './nodes/contributors_section';
|
|
128
128
|
export const schema = new Schema({
|
|
129
129
|
marks: {
|
|
130
130
|
bold,
|
|
@@ -197,9 +197,9 @@ export const schema = new Schema({
|
|
|
197
197
|
toc_section: tocSection,
|
|
198
198
|
affiliation,
|
|
199
199
|
meta_section: metaSection,
|
|
200
|
-
affiliation_list: affiliationList,
|
|
201
|
-
contributor_list: contributorList,
|
|
202
200
|
contributor: contributor,
|
|
203
201
|
table_element_footer: tableElementFooter,
|
|
202
|
+
affiliations_section: affiliationsSection,
|
|
203
|
+
contributors_section: contributorsSection,
|
|
204
204
|
},
|
|
205
205
|
});
|
|
@@ -8,6 +8,7 @@ export const affiliation = {
|
|
|
8
8
|
addressLine3: { default: '' },
|
|
9
9
|
postCode: { default: '' },
|
|
10
10
|
country: { default: '' },
|
|
11
|
+
priority: { default: undefined },
|
|
11
12
|
email: {
|
|
12
13
|
default: {
|
|
13
14
|
href: undefined,
|
|
@@ -15,5 +16,7 @@ export const affiliation = {
|
|
|
15
16
|
},
|
|
16
17
|
},
|
|
17
18
|
},
|
|
19
|
+
group: 'block element',
|
|
20
|
+
toDOM: () => ['span'],
|
|
18
21
|
};
|
|
19
22
|
export const isAffiliationNode = (node) => node.type === node.type.schema.nodes.affiliation;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const affiliationsSection = {
|
|
2
|
+
content: 'section_title? affiliation*',
|
|
3
|
+
attrs: {
|
|
4
|
+
id: { default: '' },
|
|
5
|
+
dataTracked: { default: null },
|
|
6
|
+
},
|
|
7
|
+
group: 'block sections',
|
|
8
|
+
selectable: false,
|
|
9
|
+
toDOM: () => ['section', 0],
|
|
10
|
+
};
|
|
11
|
+
export const isAffiliationsSectionNode = (node) => node.type === node.type.schema.nodes.affiliations_section;
|
|
@@ -3,10 +3,16 @@ export const contributor = {
|
|
|
3
3
|
id: { default: '' },
|
|
4
4
|
role: { default: '' },
|
|
5
5
|
affiliations: { default: [] },
|
|
6
|
+
footnote: { default: undefined },
|
|
7
|
+
corresp: { default: undefined },
|
|
6
8
|
bibliographicName: { default: {} },
|
|
7
9
|
userID: { default: undefined },
|
|
8
10
|
invitationID: { default: undefined },
|
|
9
11
|
isCorresponding: { default: undefined },
|
|
10
12
|
ORCIDIdentifier: { default: undefined },
|
|
13
|
+
priority: { default: undefined },
|
|
11
14
|
},
|
|
15
|
+
group: 'block element',
|
|
16
|
+
toDOM: () => ['span'],
|
|
12
17
|
};
|
|
18
|
+
export const isContributorNode = (node) => node.type === node.type.schema.nodes.contributor;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const contributorsSection = {
|
|
2
|
+
content: 'section_title? contributor*',
|
|
3
|
+
attrs: {
|
|
4
|
+
id: { default: '' },
|
|
5
|
+
dataTracked: { default: null },
|
|
6
|
+
},
|
|
7
|
+
group: 'block sections',
|
|
8
|
+
selectable: false,
|
|
9
|
+
toDOM: () => ['section', 0],
|
|
10
|
+
};
|
|
11
|
+
export const isContributorsSectionNode = (node) => node.type === node.type.schema.nodes.contributors_section;
|
|
@@ -57,29 +57,16 @@ export const isManuscriptNode = (model) => model !== null;
|
|
|
57
57
|
const isParagraphElement = hasObjectType(ObjectTypes.ParagraphElement);
|
|
58
58
|
const isFootnote = hasObjectType(ObjectTypes.Footnote);
|
|
59
59
|
const isKeyword = hasObjectType(ObjectTypes.Keyword);
|
|
60
|
+
const isKeywordsSection = (model) => model.category === 'MPSectionCategory:keywords';
|
|
61
|
+
const isAffiliationsSection = (model) => model.category === 'MPSectionCategory:affiliations';
|
|
62
|
+
const isContributorsSection = (model) => model.category === 'MPSectionCategory:contributors';
|
|
60
63
|
const hasParentSection = (id) => (section) => section.path &&
|
|
61
64
|
section.path.length > 1 &&
|
|
62
65
|
section.path[section.path.length - 2] === id;
|
|
63
66
|
export class Decoder {
|
|
64
|
-
createAffiliationListNode() {
|
|
65
|
-
const affiliationNodes = getAffiliations(this.modelMap)
|
|
66
|
-
.map((affiliation) => this.decode(affiliation))
|
|
67
|
-
.filter(Boolean);
|
|
68
|
-
return schema.nodes.affiliation_list.createAndFill({}, affiliationNodes);
|
|
69
|
-
}
|
|
70
|
-
createContributorListNode() {
|
|
71
|
-
const contributorNodes = getContributors(this.modelMap)
|
|
72
|
-
.map((contributor) => this.decode(contributor))
|
|
73
|
-
.filter(Boolean);
|
|
74
|
-
return schema.nodes.contributor_list.createAndFill({}, contributorNodes);
|
|
75
|
-
}
|
|
76
67
|
createMetaSectionNode() {
|
|
77
|
-
const affiliationListNode = this.createAffiliationListNode();
|
|
78
|
-
const contributorListNode = this.createContributorListNode();
|
|
79
68
|
const commentListNode = this.createCommentListNode();
|
|
80
69
|
return schema.nodes.meta_section.createAndFill({}, [
|
|
81
|
-
affiliationListNode,
|
|
82
|
-
contributorListNode,
|
|
83
70
|
commentListNode,
|
|
84
71
|
]);
|
|
85
72
|
}
|
|
@@ -88,12 +75,43 @@ export class Decoder {
|
|
|
88
75
|
...this.comments.values(),
|
|
89
76
|
]);
|
|
90
77
|
}
|
|
78
|
+
handleMissingRootSectionNodes(rootSectionNodes) {
|
|
79
|
+
if (!rootSectionNodes.find((node) => node.type.name === 'affiliations_section')) {
|
|
80
|
+
this.createAffiliationSectionNode(rootSectionNodes);
|
|
81
|
+
}
|
|
82
|
+
if (!rootSectionNodes.find((node) => node.type.name === 'contributors_section')) {
|
|
83
|
+
this.createContributorSectionNode(rootSectionNodes);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
createAffiliationSectionNode(rootSectionNodes) {
|
|
87
|
+
const affiliationNodes = getAffiliations(this.modelMap)
|
|
88
|
+
.map((affiliation) => this.decode(affiliation))
|
|
89
|
+
.filter(Boolean);
|
|
90
|
+
if (affiliationNodes.length) {
|
|
91
|
+
const node = schema.nodes.affiliations_section.createAndFill({
|
|
92
|
+
id: generateNodeID(schema.nodes.section),
|
|
93
|
+
}, affiliationNodes);
|
|
94
|
+
rootSectionNodes.unshift(node);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
createContributorSectionNode(rootSectionNodes) {
|
|
98
|
+
const contributorNodes = getContributors(this.modelMap)
|
|
99
|
+
.map((contributor) => this.decode(contributor))
|
|
100
|
+
.filter(Boolean);
|
|
101
|
+
if (contributorNodes.length) {
|
|
102
|
+
const node = schema.nodes.contributors_section.createAndFill({
|
|
103
|
+
id: generateNodeID(schema.nodes.section),
|
|
104
|
+
}, contributorNodes);
|
|
105
|
+
rootSectionNodes.unshift(node);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
91
108
|
createRootSectionNodes() {
|
|
92
109
|
let rootSections = getSections(this.modelMap).filter((section) => !section.path || section.path.length <= 1);
|
|
93
110
|
rootSections = this.addGeneratedLabels(rootSections);
|
|
94
111
|
const rootSectionNodes = rootSections
|
|
95
112
|
.map(this.decode)
|
|
96
113
|
.filter(isManuscriptNode);
|
|
114
|
+
this.handleMissingRootSectionNodes(rootSectionNodes);
|
|
97
115
|
if (!rootSectionNodes.length) {
|
|
98
116
|
rootSectionNodes.push(schema.nodes.section.createAndFill({
|
|
99
117
|
id: generateNodeID(schema.nodes.section),
|
|
@@ -426,13 +444,12 @@ export class Decoder {
|
|
|
426
444
|
},
|
|
427
445
|
[ObjectTypes.Section]: (data) => {
|
|
428
446
|
const model = data;
|
|
429
|
-
const isKeywordsSection = model.category === 'MPSectionCategory:keywords';
|
|
430
447
|
const elements = [];
|
|
431
448
|
if (model.elementIDs) {
|
|
432
449
|
for (const id of model.elementIDs) {
|
|
433
450
|
const element = this.getModel(id);
|
|
434
451
|
if (element) {
|
|
435
|
-
if (isKeywordsSection && isParagraphElement(element)) {
|
|
452
|
+
if (isKeywordsSection(model) && isParagraphElement(element)) {
|
|
436
453
|
continue;
|
|
437
454
|
}
|
|
438
455
|
elements.push(element);
|
|
@@ -475,11 +492,17 @@ export class Decoder {
|
|
|
475
492
|
const sectionNodeType = chooseSectionNodeType(sectionCategory);
|
|
476
493
|
const commentNodes = this.createCommentsNode(model);
|
|
477
494
|
commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
495
|
+
let content;
|
|
496
|
+
if (isAffiliationsSection(model) || isContributorsSection(model)) {
|
|
497
|
+
content = elementNodes.concat(nestedSections);
|
|
498
|
+
}
|
|
499
|
+
else {
|
|
500
|
+
content = (sectionLabelNode
|
|
501
|
+
? [sectionLabelNode, sectionTitleNode]
|
|
502
|
+
: [sectionTitleNode])
|
|
503
|
+
.concat(elementNodes)
|
|
504
|
+
.concat(nestedSections);
|
|
505
|
+
}
|
|
483
506
|
const sectionNode = sectionNodeType.createAndFill({
|
|
484
507
|
id: model._id,
|
|
485
508
|
category: sectionCategory,
|
|
@@ -568,6 +591,8 @@ export class Decoder {
|
|
|
568
591
|
postCode: model.postCode,
|
|
569
592
|
country: model.country,
|
|
570
593
|
email: model.email,
|
|
594
|
+
department: model.department,
|
|
595
|
+
priority: model.priority,
|
|
571
596
|
});
|
|
572
597
|
},
|
|
573
598
|
[ObjectTypes.Contributor]: (data) => {
|
|
@@ -581,6 +606,9 @@ export class Decoder {
|
|
|
581
606
|
invitationID: model.invitationID,
|
|
582
607
|
isCorresponding: model.isCorresponding,
|
|
583
608
|
ORCIDIdentifier: model.ORCIDIdentifier,
|
|
609
|
+
footnote: model.footnote,
|
|
610
|
+
corresp: model.corresp,
|
|
611
|
+
priority: model.priority,
|
|
584
612
|
});
|
|
585
613
|
},
|
|
586
614
|
};
|
|
@@ -426,6 +426,22 @@ const encoders = {
|
|
|
426
426
|
.map((childNode) => childNode.attrs.id)
|
|
427
427
|
.filter((id) => id),
|
|
428
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
|
+
}),
|
|
429
445
|
missing_figure: (node) => ({
|
|
430
446
|
position: node.attrs.position || undefined,
|
|
431
447
|
}),
|
|
@@ -506,6 +522,7 @@ const encoders = {
|
|
|
506
522
|
postCode: node.attrs.postCode,
|
|
507
523
|
country: node.attrs.country,
|
|
508
524
|
email: node.attrs.email,
|
|
525
|
+
priority: node.attrs.priority,
|
|
509
526
|
}),
|
|
510
527
|
contributor: (node) => ({
|
|
511
528
|
role: node.attrs.role,
|
|
@@ -515,6 +532,9 @@ const encoders = {
|
|
|
515
532
|
invitationID: node.attrs.invitationID,
|
|
516
533
|
isCorresponding: node.attrs.isCorresponding,
|
|
517
534
|
ORCIDIdentifier: node.attrs.ORCIDIdentifier,
|
|
535
|
+
footnote: node.attrs.footnote,
|
|
536
|
+
corresp: node.attrs.corresp,
|
|
537
|
+
priority: node.attrs.priority,
|
|
518
538
|
}),
|
|
519
539
|
};
|
|
520
540
|
const modelData = (node, parent, path, priority) => {
|
|
@@ -54,6 +54,8 @@ export const nodeTypesMap = new Map([
|
|
|
54
54
|
[schema.nodes.affiliation, ObjectTypes.Affiliation],
|
|
55
55
|
[schema.nodes.contributor, ObjectTypes.Contributor],
|
|
56
56
|
[schema.nodes.table_element_footer, ObjectTypes.TableElementFooter],
|
|
57
|
+
[schema.nodes.contributors_section, ObjectTypes.Section],
|
|
58
|
+
[schema.nodes.affiliations_section, ObjectTypes.Section],
|
|
57
59
|
]);
|
|
58
60
|
export const isExecutableNodeType = (type) => hasGroup(type, GROUP_EXECUTABLE);
|
|
59
61
|
export const isElementNodeType = (type) => hasGroup(type, GROUP_ELEMENT);
|