@manuscripts/transform 1.4.6 → 1.5.0-LEAN-2852-9

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.
Files changed (63) hide show
  1. package/dist/cjs/jats/importer/jats-body-dom-parser.js +126 -0
  2. package/dist/cjs/jats/importer/jats-body-transformations.js +59 -0
  3. package/dist/cjs/jats/importer/jats-front-parser.js +7 -7
  4. package/dist/cjs/jats/importer/jats-parser-utils.js +4 -0
  5. package/dist/cjs/jats/importer/parse-jats-article.js +18 -7
  6. package/dist/cjs/jats/jats-exporter.js +10 -8
  7. package/dist/cjs/lib/core-section-categories.js +2 -2
  8. package/dist/cjs/schema/index.js +9 -6
  9. package/dist/cjs/schema/nodes/affiliation.js +3 -0
  10. package/dist/cjs/schema/nodes/affiliations_section.js +15 -0
  11. package/dist/cjs/schema/nodes/contributor.js +8 -1
  12. package/dist/cjs/schema/nodes/contributors_section.js +15 -0
  13. package/dist/cjs/schema/nodes/meta_section.js +1 -1
  14. package/dist/cjs/schema/nodes/titles.js +32 -0
  15. package/dist/cjs/transformer/builders.js +1 -2
  16. package/dist/cjs/transformer/decode.js +74 -23
  17. package/dist/cjs/transformer/encode.js +26 -0
  18. package/dist/cjs/transformer/html.js +6 -5
  19. package/dist/cjs/transformer/node-types.js +3 -0
  20. package/dist/cjs/transformer/project-bundle.js +22 -1
  21. package/dist/cjs/transformer/section-category.js +12 -0
  22. package/dist/es/jats/importer/jats-body-dom-parser.js +126 -0
  23. package/dist/es/jats/importer/jats-body-transformations.js +59 -0
  24. package/dist/es/jats/importer/jats-front-parser.js +1 -1
  25. package/dist/es/jats/importer/jats-parser-utils.js +4 -0
  26. package/dist/es/jats/importer/parse-jats-article.js +18 -7
  27. package/dist/es/jats/jats-exporter.js +11 -9
  28. package/dist/es/lib/core-section-categories.js +2 -2
  29. package/dist/es/schema/index.js +9 -6
  30. package/dist/es/schema/nodes/affiliation.js +3 -0
  31. package/dist/es/schema/nodes/affiliations_section.js +11 -0
  32. package/dist/es/schema/nodes/contributor.js +6 -0
  33. package/dist/es/schema/nodes/contributors_section.js +11 -0
  34. package/dist/es/schema/nodes/meta_section.js +1 -1
  35. package/dist/es/schema/nodes/titles.js +29 -0
  36. package/dist/es/transformer/builders.js +1 -2
  37. package/dist/es/transformer/decode.js +74 -23
  38. package/dist/es/transformer/encode.js +26 -0
  39. package/dist/es/transformer/html.js +7 -6
  40. package/dist/es/transformer/node-types.js +3 -0
  41. package/dist/es/transformer/project-bundle.js +20 -0
  42. package/dist/es/transformer/section-category.js +12 -0
  43. package/dist/types/jats/importer/jats-body-transformations.d.ts +4 -1
  44. package/dist/types/jats/importer/jats-front-parser.d.ts +5 -5
  45. package/dist/types/jats/importer/parse-jats-article.d.ts +5 -2
  46. package/dist/types/schema/index.d.ts +3 -2
  47. package/dist/types/schema/nodes/affiliation.d.ts +1 -0
  48. package/dist/types/schema/nodes/affiliations_section.d.ts +11 -0
  49. package/dist/types/schema/nodes/contributor.d.ts +2 -0
  50. package/dist/types/schema/nodes/contributors_section.d.ts +11 -0
  51. package/dist/types/schema/nodes/titles.d.ts +28 -0
  52. package/dist/types/schema/types.d.ts +1 -1
  53. package/dist/types/transformer/builders.d.ts +1 -1
  54. package/dist/types/transformer/decode.d.ts +4 -2
  55. package/dist/types/transformer/project-bundle.d.ts +2 -1
  56. package/dist/types/transformer/section-category.d.ts +2 -2
  57. package/package.json +3 -3
  58. package/dist/cjs/schema/nodes/affiliation_list.js +0 -10
  59. package/dist/cjs/schema/nodes/contributor_list.js +0 -10
  60. package/dist/es/schema/nodes/affiliation_list.js +0 -7
  61. package/dist/es/schema/nodes/contributor_list.js +0 -7
  62. package/dist/types/schema/nodes/affiliation_list.d.ts +0 -10
  63. package/dist/types/schema/nodes/contributor_list.d.ts +0 -10
@@ -67,29 +67,16 @@ exports.isManuscriptNode = isManuscriptNode;
67
67
  const isParagraphElement = (0, object_types_1.hasObjectType)(json_schema_1.ObjectTypes.ParagraphElement);
68
68
  const isFootnote = (0, object_types_1.hasObjectType)(json_schema_1.ObjectTypes.Footnote);
69
69
  const isKeyword = (0, object_types_1.hasObjectType)(json_schema_1.ObjectTypes.Keyword);
70
+ const isKeywordsSection = (model) => model.category === 'MPSectionCategory:keywords';
71
+ const isAffiliationsSection = (model) => model.category === 'MPSectionCategory:affiliations';
72
+ const isContributorsSection = (model) => model.category === 'MPSectionCategory:contributors';
70
73
  const hasParentSection = (id) => (section) => section.path &&
71
74
  section.path.length > 1 &&
72
75
  section.path[section.path.length - 2] === id;
73
76
  class Decoder {
74
- createAffiliationListNode() {
75
- const affiliationNodes = getAffiliations(this.modelMap)
76
- .map((affiliation) => this.decode(affiliation))
77
- .filter(Boolean);
78
- return schema_1.schema.nodes.affiliation_list.createAndFill({}, affiliationNodes);
79
- }
80
- createContributorListNode() {
81
- const contributorNodes = getContributors(this.modelMap)
82
- .map((contributor) => this.decode(contributor))
83
- .filter(Boolean);
84
- return schema_1.schema.nodes.contributor_list.createAndFill({}, contributorNodes);
85
- }
86
77
  createMetaSectionNode() {
87
- const affiliationListNode = this.createAffiliationListNode();
88
- const contributorListNode = this.createContributorListNode();
89
78
  const commentListNode = this.createCommentListNode();
90
79
  return schema_1.schema.nodes.meta_section.createAndFill({}, [
91
- affiliationListNode,
92
- contributorListNode,
93
80
  commentListNode,
94
81
  ]);
95
82
  }
@@ -98,12 +85,53 @@ class Decoder {
98
85
  ...this.comments.values(),
99
86
  ]);
100
87
  }
88
+ handleMissingRootSectionNodes(rootSectionNodes) {
89
+ if (!rootSectionNodes.find((node) => node.type.name === 'affiliations_section')) {
90
+ this.createAffiliationSectionNode(rootSectionNodes);
91
+ }
92
+ if (!rootSectionNodes.find((node) => node.type.name === 'contributors_section')) {
93
+ this.createContributorSectionNode(rootSectionNodes);
94
+ }
95
+ }
96
+ createAffiliationSectionNode(rootSectionNodes) {
97
+ const affiliationNodes = getAffiliations(this.modelMap)
98
+ .map((affiliation) => this.decode(affiliation))
99
+ .filter(Boolean);
100
+ if (affiliationNodes.length) {
101
+ const node = schema_1.schema.nodes.affiliations_section.createAndFill({
102
+ id: (0, id_1.generateNodeID)(schema_1.schema.nodes.section),
103
+ }, affiliationNodes);
104
+ rootSectionNodes.unshift(node);
105
+ }
106
+ }
107
+ createContributorSectionNode(rootSectionNodes) {
108
+ const contributorNodes = getContributors(this.modelMap)
109
+ .map((contributor) => this.decode(contributor))
110
+ .filter(Boolean);
111
+ if (contributorNodes.length) {
112
+ const node = schema_1.schema.nodes.contributors_section.createAndFill({
113
+ id: (0, id_1.generateNodeID)(schema_1.schema.nodes.section),
114
+ }, contributorNodes);
115
+ rootSectionNodes.unshift(node);
116
+ }
117
+ }
118
+ createTitlesNode() {
119
+ const titlesModel = (0, exports.getModelsByType)(this.modelMap, json_schema_1.ObjectTypes.Titles)[0];
120
+ if (titlesModel) {
121
+ const titlesNode = this.decode(titlesModel);
122
+ return titlesNode;
123
+ }
124
+ else {
125
+ return null;
126
+ }
127
+ }
101
128
  createRootSectionNodes() {
102
129
  let rootSections = getSections(this.modelMap).filter((section) => !section.path || section.path.length <= 1);
103
130
  rootSections = this.addGeneratedLabels(rootSections);
104
131
  const rootSectionNodes = rootSections
105
132
  .map(this.decode)
106
133
  .filter(exports.isManuscriptNode);
134
+ this.handleMissingRootSectionNodes(rootSectionNodes);
107
135
  if (!rootSectionNodes.length) {
108
136
  rootSectionNodes.push(schema_1.schema.nodes.section.createAndFill({
109
137
  id: (0, id_1.generateNodeID)(schema_1.schema.nodes.section),
@@ -129,6 +157,15 @@ class Decoder {
129
157
  constructor(modelMap, allowMissingElements = false) {
130
158
  this.comments = new Map();
131
159
  this.creators = {
160
+ [json_schema_1.ObjectTypes.Titles]: (data) => {
161
+ const model = data;
162
+ return schema_1.schema.nodes.titles.create({
163
+ id: model._id,
164
+ title: model.title,
165
+ subtitle: model.subtitle,
166
+ runningTitle: model.runningTitle,
167
+ });
168
+ },
132
169
  [json_schema_1.ObjectTypes.BibliographyElement]: (data) => {
133
170
  var _a;
134
171
  const model = data;
@@ -436,13 +473,12 @@ class Decoder {
436
473
  },
437
474
  [json_schema_1.ObjectTypes.Section]: (data) => {
438
475
  const model = data;
439
- const isKeywordsSection = model.category === 'MPSectionCategory:keywords';
440
476
  const elements = [];
441
477
  if (model.elementIDs) {
442
478
  for (const id of model.elementIDs) {
443
479
  const element = this.getModel(id);
444
480
  if (element) {
445
- if (isKeywordsSection && isParagraphElement(element)) {
481
+ if (isKeywordsSection(model) && isParagraphElement(element)) {
446
482
  continue;
447
483
  }
448
484
  elements.push(element);
@@ -485,11 +521,17 @@ class Decoder {
485
521
  const sectionNodeType = (0, section_category_1.chooseSectionNodeType)(sectionCategory);
486
522
  const commentNodes = this.createCommentsNode(model);
487
523
  commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
488
- const content = (sectionLabelNode
489
- ? [sectionLabelNode, sectionTitleNode]
490
- : [sectionTitleNode])
491
- .concat(elementNodes)
492
- .concat(nestedSections);
524
+ let content;
525
+ if (isAffiliationsSection(model) || isContributorsSection(model)) {
526
+ content = elementNodes.concat(nestedSections);
527
+ }
528
+ else {
529
+ content = (sectionLabelNode
530
+ ? [sectionLabelNode, sectionTitleNode]
531
+ : [sectionTitleNode])
532
+ .concat(elementNodes)
533
+ .concat(nestedSections);
534
+ }
493
535
  const sectionNode = sectionNodeType.createAndFill({
494
536
  id: model._id,
495
537
  category: sectionCategory,
@@ -578,6 +620,8 @@ class Decoder {
578
620
  postCode: model.postCode,
579
621
  country: model.country,
580
622
  email: model.email,
623
+ department: model.department,
624
+ priority: model.priority,
581
625
  });
582
626
  },
583
627
  [json_schema_1.ObjectTypes.Contributor]: (data) => {
@@ -591,6 +635,9 @@ class Decoder {
591
635
  invitationID: model.invitationID,
592
636
  isCorresponding: model.isCorresponding,
593
637
  ORCIDIdentifier: model.ORCIDIdentifier,
638
+ footnote: model.footnote,
639
+ corresp: model.corresp,
640
+ priority: model.priority,
594
641
  });
595
642
  },
596
643
  };
@@ -603,9 +650,13 @@ class Decoder {
603
650
  };
604
651
  this.getModel = (id) => this.modelMap.get(id);
605
652
  this.createArticleNode = (manuscriptID) => {
653
+ const titlesNode = this.createTitlesNode();
606
654
  const rootSectionNodes = this.createRootSectionNodes();
607
655
  const metaSectionNode = this.createMetaSectionNode();
608
656
  const contents = [...rootSectionNodes, metaSectionNode];
657
+ if (titlesNode) {
658
+ contents.push(titlesNode);
659
+ }
609
660
  return schema_1.schema.nodes.manuscript.create({
610
661
  id: manuscriptID || this.getManuscriptID(),
611
662
  }, contents);
@@ -263,6 +263,12 @@ function figureElementEncoder(node) {
263
263
  };
264
264
  }
265
265
  const encoders = {
266
+ titles: (node) => ({
267
+ title: node.attrs.title,
268
+ subtitle: node.attrs.subtitle,
269
+ runningTitle: node.attrs.runningTitle,
270
+ _id: node.attrs._id,
271
+ }),
266
272
  bibliography_element: (node) => ({
267
273
  elementType: 'div',
268
274
  contents: '',
@@ -434,6 +440,22 @@ const encoders = {
434
440
  .map((childNode) => childNode.attrs.id)
435
441
  .filter((id) => id),
436
442
  }),
443
+ affiliations_section: (node, parent, path, priority) => ({
444
+ category: (0, section_category_1.buildSectionCategory)(node),
445
+ priority: priority.value++,
446
+ path: path.concat([node.attrs.id]),
447
+ elementIDs: childElements(node)
448
+ .map((childNode) => childNode.attrs.id)
449
+ .filter((id) => id),
450
+ }),
451
+ contributors_section: (node, parent, path, priority) => ({
452
+ category: (0, section_category_1.buildSectionCategory)(node),
453
+ priority: priority.value++,
454
+ path: path.concat([node.attrs.id]),
455
+ elementIDs: childElements(node)
456
+ .map((childNode) => childNode.attrs.id)
457
+ .filter((id) => id),
458
+ }),
437
459
  missing_figure: (node) => ({
438
460
  position: node.attrs.position || undefined,
439
461
  }),
@@ -514,6 +536,7 @@ const encoders = {
514
536
  postCode: node.attrs.postCode,
515
537
  country: node.attrs.country,
516
538
  email: node.attrs.email,
539
+ priority: node.attrs.priority,
517
540
  }),
518
541
  contributor: (node) => ({
519
542
  role: node.attrs.role,
@@ -523,6 +546,9 @@ const encoders = {
523
546
  invitationID: node.attrs.invitationID,
524
547
  isCorresponding: node.attrs.isCorresponding,
525
548
  ORCIDIdentifier: node.attrs.ORCIDIdentifier,
549
+ footnote: node.attrs.footnote,
550
+ corresp: node.attrs.corresp,
551
+ priority: node.attrs.priority,
526
552
  }),
527
553
  };
528
554
  const modelData = (node, parent, path, priority) => {
@@ -152,6 +152,7 @@ class HTMLTransformer {
152
152
  this.buildFront = () => {
153
153
  const manuscript = (0, project_bundle_1.findManuscript)(this.modelMap);
154
154
  const journal = (0, project_bundle_1.findJournal)(this.modelMap);
155
+ const titles = (0, project_bundle_1.findTitles)(this.modelMap);
155
156
  if (!manuscript) {
156
157
  throw new Error('Manuscript not found in project modelMap');
157
158
  }
@@ -170,14 +171,14 @@ class HTMLTransformer {
170
171
  }
171
172
  const articleMeta = this.document.createElement('div');
172
173
  front.appendChild(articleMeta);
173
- const articleTitle = this.document.createElement('h1');
174
- if (manuscript.title) {
175
- articleTitle.innerHTML = manuscript.title;
174
+ const title = this.document.createElement('h1');
175
+ if (titles.title) {
176
+ title.innerHTML = titles.title;
176
177
  }
177
178
  if (journal === null || journal === void 0 ? void 0 : journal.title) {
178
- articleTitle.setAttribute('data-journal', journal.title);
179
+ title.setAttribute('data-journal', journal.title);
179
180
  }
180
- articleMeta.appendChild(articleTitle);
181
+ articleMeta.appendChild(title);
181
182
  if (manuscript.DOI) {
182
183
  const articleID = this.document.createElement('article-id');
183
184
  articleID.setAttribute('pub-id-type', 'doi');
@@ -57,6 +57,9 @@ 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.titles, json_schema_1.ObjectTypes.Titles],
61
+ [schema_1.schema.nodes.contributors_section, json_schema_1.ObjectTypes.Section],
62
+ [schema_1.schema.nodes.affiliations_section, json_schema_1.ObjectTypes.Section],
60
63
  ]);
61
64
  const isExecutableNodeType = (type) => (0, schema_1.hasGroup)(type, schema_1.GROUP_EXECUTABLE);
62
65
  exports.isExecutableNodeType = isExecutableNodeType;
@@ -15,7 +15,7 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.findManuscriptById = exports.findManuscriptModelByType = exports.findJournal = exports.findManuscript = exports.parseProjectBundle = void 0;
18
+ exports.findTitles = exports.findManuscriptById = exports.findManuscriptModelByType = exports.findJournal = exports.findManuscript = exports.parseProjectBundle = void 0;
19
19
  const json_schema_1 = require("@manuscripts/json-schema");
20
20
  const decode_1 = require("./decode");
21
21
  const object_types_1 = require("./object-types");
@@ -71,3 +71,24 @@ const findManuscriptById = (modelMap, manuscriptID) => {
71
71
  throw new Error(`There is no manuscript found for the following _id (${manuscriptID})`);
72
72
  };
73
73
  exports.findManuscriptById = findManuscriptById;
74
+ const isTitle = (0, object_types_1.hasObjectType)(json_schema_1.ObjectTypes.Titles);
75
+ const findTitles = (modelMap) => {
76
+ for (const model of modelMap.values()) {
77
+ if (isTitle(model)) {
78
+ return model;
79
+ }
80
+ }
81
+ const defaultTitle = {
82
+ _id: 'MPTitles:8EB79C14-9F61-483A-902F-A0B8EF5973C1',
83
+ createdAt: 1538472121.690101,
84
+ updatedAt: 1538472121.690101,
85
+ objectType: 'MPTitles',
86
+ title: 'main title',
87
+ subtitle: 'subtitle',
88
+ runningTitle: 'running title',
89
+ manuscriptID: 'MPManuscript:E3830344-E77B-42BA-BD77-3E95489712A0',
90
+ containerID: 'MPProject:1',
91
+ };
92
+ return defaultTitle;
93
+ };
94
+ exports.findTitles = findTitles;
@@ -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/builders';
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) {
@@ -13,6 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { ObjectTypes, } from '@manuscripts/json-schema';
16
17
  import { DOMParser } from 'prosemirror-model';
17
18
  import { InvalidInput } from '../../errors';
18
19
  import { nodeFromHTML } from '../../lib/html';
@@ -48,9 +49,16 @@ export const parseJATSFront = async (front) => {
48
49
  const title = (_a = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > article-title')) === null || _a === void 0 ? void 0 : _a.innerHTML;
49
50
  const subtitle = (_b = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > subtitle')) === null || _b === void 0 ? void 0 : _b.innerHTML;
50
51
  const runningTitle = (_c = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > alt-title[alt-title-type="right-running"]')) === null || _c === void 0 ? void 0 : _c.innerHTML;
51
- const manuscriptMeta = Object.assign({ title: title ? inlineContentsFromJATSTitle(title) : undefined, subtitle: subtitle ? inlineContentsFromJATSTitle(subtitle) : undefined, runningTitle: runningTitle
52
+ const manuscriptMeta = Object.assign({}, jatsFrontParser.parseCounts(articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('counts')));
53
+ const titles = {
54
+ objectType: ObjectTypes.Titles,
55
+ _id: generateID(ObjectTypes.Titles),
56
+ title: title ? inlineContentsFromJATSTitle(title) : undefined,
57
+ subtitle: subtitle ? inlineContentsFromJATSTitle(subtitle) : undefined,
58
+ runningTitle: runningTitle
52
59
  ? inlineContentsFromJATSTitle(runningTitle)
53
- : undefined }, jatsFrontParser.parseCounts(articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('counts')));
60
+ : undefined,
61
+ };
54
62
  const { affiliations, affiliationIDs } = jatsFrontParser.parseAffiliationNodes([
55
63
  ...front.querySelectorAll('article-meta > contrib-group > aff'),
56
64
  ]);
@@ -70,14 +78,15 @@ export const parseJATSFront = async (front) => {
70
78
  const manuscript = Object.assign(Object.assign(Object.assign({}, buildManuscript()), manuscriptMeta), history);
71
79
  return {
72
80
  models: generateModelIDs([
81
+ titles,
73
82
  manuscript,
74
- ...affiliations,
75
- ...authors,
76
83
  ...footnotes,
77
84
  ...correspondingList,
78
85
  journal,
79
86
  ...supplements,
80
87
  ]),
88
+ authors: [...authors],
89
+ affiliations: [...affiliations],
81
90
  };
82
91
  };
83
92
  export const parseJATSReferences = (back, body, createElement) => {
@@ -101,7 +110,7 @@ export const parseJATSReferences = (back, body, createElement) => {
101
110
  referenceIdsMap,
102
111
  };
103
112
  };
104
- export const parseJATSBody = (document, body, bibliographyItems, refModels, referenceIdsMap, footnotesOrder) => {
113
+ export const parseJATSBody = (document, body, bibliographyItems, authors, affiliations, refModels, referenceIdsMap, footnotesOrder) => {
105
114
  const createElement = createElementFn(document);
106
115
  const orderedFootnotesIDs = createOrderedFootnotesIDs(document);
107
116
  jatsBodyTransformations.moveFloatsGroupToBody(document, body, createElement);
@@ -111,6 +120,8 @@ export const parseJATSBody = (document, body, bibliographyItems, refModels, refe
111
120
  jatsBodyTransformations.moveTableFooterToEnd(body);
112
121
  jatsBodyTransformations.moveBlockNodesFromParagraph(document, body, createElement);
113
122
  jatsBodyTransformations.moveKeywordsToBody(document, body, createElement);
123
+ jatsBodyTransformations.moveAffiliationsToBody(document, affiliations, body, createElement);
124
+ jatsBodyTransformations.moveAuthorsToBody(document, authors, body, createElement);
114
125
  const node = jatsBodyDOMParser.parse(body);
115
126
  if (!node.firstChild) {
116
127
  throw new Error('No content was parsed from the JATS article body');
@@ -162,14 +173,14 @@ export const parseJATSArticle = async (doc) => {
162
173
  }
163
174
  const authorQueriesMap = markProcessingInstructions(doc);
164
175
  const createElement = createElementFn(document);
165
- const { models: frontModels } = await parseJATSFront(front);
176
+ const { models: frontModels, authors, affiliations, } = await parseJATSFront(front);
166
177
  const { references, crossReferences, referenceQueriesMap, referenceIdsMap } = parseJATSReferences(back, body, createElement);
167
178
  transformTables(doc.querySelectorAll('table-wrap > table'), createElement);
168
179
  const footnotesOrder = createEmptyFootnotesOrder();
169
180
  let elementsOrder = [];
170
181
  const bodyModels = [];
171
182
  if (body) {
172
- const bodyDoc = parseJATSBody(doc, body, references, crossReferences, referenceIdsMap, footnotesOrder);
183
+ const bodyDoc = parseJATSBody(doc, body, references, authors, affiliations, crossReferences, referenceIdsMap, footnotesOrder);
173
184
  bodyModels.push(...encode(bodyDoc).values());
174
185
  elementsOrder = getElementsOrder(bodyDoc);
175
186
  }