@manuscripts/transform 4.3.21 → 4.3.23

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 (69) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/jats/__tests__/jats-exporter.test.js +11 -45
  3. package/dist/cjs/jats/__tests__/jats-importer.test.js +54 -76
  4. package/dist/cjs/jats/__tests__/jats-roundtrip.test.js +1 -2
  5. package/dist/cjs/jats/__tests__/utils.js +4 -17
  6. package/dist/cjs/jats/exporter/jats-exporter.js +190 -271
  7. package/dist/cjs/jats/importer/jats-dom-parser.js +16 -42
  8. package/dist/cjs/jats/importer/jats-parser-utils.js +5 -29
  9. package/dist/cjs/jats/importer/parse-jats-article.js +1 -6
  10. package/dist/cjs/schema/__tests__/docs.js +1830 -0
  11. package/dist/cjs/schema/__tests__/migration.test.js +3 -37
  12. package/dist/cjs/schema/migration/migration-scripts/4.3.12.js +39 -0
  13. package/dist/cjs/schema/migration/migration-scripts/index.js +2 -0
  14. package/dist/cjs/schema/nodes/blockquote_element.js +0 -2
  15. package/dist/cjs/schema/nodes/comment.js +2 -1
  16. package/dist/cjs/schema/nodes/contributor.js +11 -11
  17. package/dist/cjs/schema/nodes/equation.js +1 -3
  18. package/dist/cjs/schema/nodes/list.js +0 -2
  19. package/dist/cjs/schema/nodes/listing.js +1 -3
  20. package/dist/cjs/schema/nodes/paragraph.js +0 -2
  21. package/dist/cjs/schema/nodes/pullquote_element.js +0 -2
  22. package/dist/cjs/transformer/id.js +2 -14
  23. package/dist/cjs/transformer/node-names.js +6 -1
  24. package/dist/cjs/transformer/node-types.js +1 -47
  25. package/dist/cjs/version.js +1 -1
  26. package/dist/es/jats/__tests__/jats-exporter.test.js +11 -45
  27. package/dist/es/jats/__tests__/jats-importer.test.js +54 -76
  28. package/dist/es/jats/__tests__/jats-roundtrip.test.js +1 -2
  29. package/dist/es/jats/__tests__/utils.js +4 -17
  30. package/dist/es/jats/exporter/jats-exporter.js +190 -271
  31. package/dist/es/jats/importer/jats-dom-parser.js +16 -42
  32. package/dist/es/jats/importer/jats-parser-utils.js +6 -30
  33. package/dist/es/jats/importer/parse-jats-article.js +1 -6
  34. package/dist/es/schema/__tests__/docs.js +1827 -0
  35. package/dist/es/schema/__tests__/migration.test.js +3 -4
  36. package/dist/es/schema/migration/migration-scripts/4.3.12.js +37 -0
  37. package/dist/es/schema/migration/migration-scripts/index.js +2 -0
  38. package/dist/es/schema/nodes/blockquote_element.js +0 -2
  39. package/dist/es/schema/nodes/comment.js +2 -1
  40. package/dist/es/schema/nodes/contributor.js +11 -11
  41. package/dist/es/schema/nodes/equation.js +1 -3
  42. package/dist/es/schema/nodes/list.js +0 -2
  43. package/dist/es/schema/nodes/listing.js +1 -3
  44. package/dist/es/schema/nodes/paragraph.js +0 -2
  45. package/dist/es/schema/nodes/pullquote_element.js +0 -2
  46. package/dist/es/transformer/id.js +2 -14
  47. package/dist/es/transformer/node-names.js +4 -0
  48. package/dist/es/transformer/node-types.js +1 -47
  49. package/dist/es/version.js +1 -1
  50. package/dist/types/jats/__tests__/utils.d.ts +1 -11
  51. package/dist/types/jats/exporter/jats-exporter.d.ts +5 -10
  52. package/dist/types/jats/importer/jats-dom-parser.d.ts +0 -15
  53. package/dist/types/jats/importer/parse-jats-article.d.ts +1 -11
  54. package/dist/types/schema/__tests__/docs.d.ts +2 -0
  55. package/dist/types/schema/migration/migration-scripts/4.3.12.d.ts +8 -0
  56. package/dist/types/schema/migration/migration-scripts/index.d.ts +2 -1
  57. package/dist/types/schema/nodes/comment.d.ts +2 -2
  58. package/dist/types/schema/nodes/contributor.d.ts +11 -21
  59. package/dist/types/schema/types.d.ts +22 -0
  60. package/dist/types/transformer/node-names.d.ts +1 -0
  61. package/dist/types/transformer/node-types.d.ts +0 -2
  62. package/dist/types/version.d.ts +1 -1
  63. package/package.json +2 -2
  64. package/dist/cjs/jats/importer/jats-journal-meta-parser.js +0 -103
  65. package/dist/cjs/lib/styled-content.js +0 -28
  66. package/dist/es/jats/importer/jats-journal-meta-parser.js +0 -95
  67. package/dist/es/lib/styled-content.js +0 -23
  68. package/dist/types/jats/importer/jats-journal-meta-parser.d.ts +0 -46
  69. package/dist/types/lib/styled-content.d.ts +0 -22
@@ -98,7 +98,7 @@ export class JATSExporter {
98
98
  this.document = document.implementation.createDocument(null, 'article', document.implementation.createDocumentType('article', versionIds.publicId, versionIds.systemId));
99
99
  const article = this.document.documentElement;
100
100
  article.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', XLINK_NAMESPACE);
101
- const front = this.buildFront(options.journal);
101
+ const front = this.buildFront();
102
102
  article.appendChild(front);
103
103
  article.setAttribute('article-type', manuscriptNode.attrs.articleType || 'other');
104
104
  article.setAttributeNS(XML_NAMESPACE, 'lang', manuscriptNode.attrs.primaryLanguageCode || 'en');
@@ -207,60 +207,10 @@ export class JATSExporter {
207
207
  }
208
208
  }
209
209
  };
210
- this.buildFront = (journal) => {
210
+ this.buildFront = () => {
211
211
  const front = this.createElement('front');
212
- const journalMeta = this.createElement('journal-meta');
213
- front.appendChild(journalMeta);
214
212
  const articleMeta = this.createElement('article-meta');
215
213
  front.appendChild(articleMeta);
216
- if (journal) {
217
- if (journal.journalIdentifiers) {
218
- for (const item of journal.journalIdentifiers) {
219
- const element = this.createElement('journal-id');
220
- if (item.journalIDType) {
221
- element.setAttribute('journal-id-type', item.journalIDType);
222
- }
223
- element.textContent = item.journalID;
224
- journalMeta.appendChild(element);
225
- }
226
- }
227
- if (journal.title || journal.abbreviatedTitles) {
228
- const parentElement = this.createElement('journal-title-group');
229
- journalMeta.appendChild(parentElement);
230
- if (journal.title) {
231
- const element = this.createElement('journal-title');
232
- element.textContent = journal.title;
233
- parentElement.appendChild(element);
234
- }
235
- if (journal.abbreviatedTitles) {
236
- for (const item of journal.abbreviatedTitles) {
237
- const element = this.createElement('abbrev-journal-title');
238
- if (item.abbrevType) {
239
- element.setAttribute('abbrev-type', item.abbrevType);
240
- }
241
- element.textContent = item.abbreviatedTitle;
242
- parentElement.appendChild(element);
243
- }
244
- }
245
- }
246
- if (journal.ISSNs) {
247
- for (const item of journal.ISSNs) {
248
- const element = this.createElement('issn');
249
- if (item.publicationType) {
250
- element.setAttribute('pub-type', item.publicationType);
251
- }
252
- element.textContent = item.ISSN;
253
- journalMeta.appendChild(element);
254
- }
255
- }
256
- if (journal.publisherName) {
257
- const publisher = this.createElement('publisher');
258
- const publisherName = this.createElement('publisher-name');
259
- publisherName.textContent = journal.publisherName;
260
- publisher.appendChild(publisherName);
261
- journalMeta.appendChild(publisher);
262
- }
263
- }
264
214
  if (this.manuscriptNode.attrs.doi) {
265
215
  const articleID = this.createElement('article-id');
266
216
  articleID.setAttribute('pub-id-type', 'doi');
@@ -345,18 +295,15 @@ export class JATSExporter {
345
295
  counts.append(...countingElements);
346
296
  articleMeta.append(counts);
347
297
  }
348
- if (!journalMeta.hasChildNodes()) {
349
- journalMeta.remove();
350
- }
351
- const selfUriAttachments = this.getChildrenOfType(schema.nodes.attachment);
352
- selfUriAttachments.forEach((attachment) => {
353
- const selfUriElement = this.createElement('self-uri');
354
- selfUriElement.setAttribute('content-type', attachment.attrs.type);
355
- selfUriElement.setAttributeNS(XLINK_NAMESPACE, 'href', attachment.attrs.href);
298
+ const attachments = this.getChildrenOfType(schema.nodes.attachment);
299
+ attachments.forEach((attachment) => {
300
+ const $selfUri = this.createElement('self-uri');
301
+ $selfUri.setAttribute('content-type', attachment.attrs.type);
302
+ $selfUri.setAttributeNS(XLINK_NAMESPACE, 'href', attachment.attrs.href);
356
303
  const insertBeforeElements = articleMeta.querySelector('related-article, related-object, abstract, trans-abstract, kwd-group, funding-group, support-group, conference, counts, custom-meta-group');
357
304
  insertBeforeElements
358
- ? articleMeta.insertBefore(selfUriElement, insertBeforeElements)
359
- : articleMeta.appendChild(selfUriElement);
305
+ ? articleMeta.insertBefore($selfUri, insertBeforeElements)
306
+ : articleMeta.appendChild($selfUri);
360
307
  });
361
308
  return front;
362
309
  };
@@ -967,219 +914,219 @@ export class JATSExporter {
967
914
  this.serializeNode = (node) => this.serializer.serializeNode(node, {
968
915
  document: this.document,
969
916
  });
970
- this.validateContributor = (contributor) => {
971
- if (!contributor.attrs.bibliographicName) {
972
- throw new Error(`${contributor.attrs.id} has no bibliographicName`);
973
- }
974
- const { family, given } = contributor.attrs.bibliographicName;
975
- if (!family && !given) {
976
- throw new Error(`${contributor.attrs.id} has neither family nor given name`);
977
- }
978
- };
979
917
  this.buildContributors = (articleMeta) => {
980
918
  const contributors = this.getChildrenOfType(schema.nodes.contributor).sort(sortContributors);
981
- const affiliationLabels = new Map();
982
- const creatAffiliationLabel = (rid) => {
983
- let label = affiliationLabels.get(rid);
919
+ if (!contributors.length) {
920
+ return;
921
+ }
922
+ const labels = new Map();
923
+ const createLabel = (id) => {
924
+ let label = labels.get(id);
984
925
  if (!label) {
985
- label = String(affiliationLabels.size + 1);
986
- affiliationLabels.set(rid, label);
926
+ label = labels.size + 1;
927
+ labels.set(id, label);
987
928
  }
988
929
  const sup = this.createElement('sup');
989
930
  sup.textContent = String(label);
990
931
  return sup;
991
932
  };
992
- const createFootNotesLabels = (content) => {
993
- const sup = this.createElement('sup');
994
- sup.textContent = String(content);
995
- return sup;
996
- };
997
- if (contributors.length) {
998
- const contribGroup = this.createElement('contrib-group');
999
- contribGroup.setAttribute('content-type', 'authors');
1000
- articleMeta.appendChild(contribGroup);
1001
- contributors.forEach((contributor) => {
1002
- try {
1003
- this.validateContributor(contributor);
1004
- }
1005
- catch (error) {
1006
- return;
1007
- }
1008
- const contrib = this.createElement('contrib');
1009
- contrib.setAttribute('contrib-type', 'author');
1010
- contrib.setAttribute('id', normalizeID(contributor.attrs.id));
1011
- if (contributor.attrs.isCorresponding) {
1012
- contrib.setAttribute('corresp', 'yes');
1013
- }
1014
- if (contributor.attrs.role) {
1015
- this.appendElement(contrib, 'role', contributor.attrs.role);
1016
- }
1017
- if (contributor.attrs.ORCIDIdentifier) {
1018
- this.appendElement(contrib, 'contrib-id', contributor.attrs.ORCIDIdentifier, { 'contrib-id-type': 'orcid' });
1019
- }
1020
- const name = this.buildContributorName(contributor);
1021
- contrib.appendChild(name);
1022
- if (contributor.attrs.email) {
1023
- this.appendElement(contrib, 'email', contributor.attrs.email);
1024
- }
1025
- if (contributor.attrs.affiliations) {
1026
- contributor.attrs.affiliations.forEach((rid) => {
1027
- const xref = this.appendElement(contrib, 'xref', '', {
1028
- 'ref-type': 'aff',
1029
- rid: normalizeID(rid),
1030
- });
1031
- xref.appendChild(creatAffiliationLabel(rid));
1032
- contrib.appendChild(xref);
1033
- });
1034
- }
1035
- if (contributor.attrs.footnote) {
1036
- contributor.attrs.footnote.map((note) => {
1037
- const xref = this.appendElement(contrib, 'xref', '', {
1038
- 'ref-type': 'fn',
1039
- rid: normalizeID(note.noteID),
1040
- });
1041
- xref.appendChild(createFootNotesLabels(note.noteLabel));
1042
- contrib.appendChild(xref);
1043
- });
1044
- }
1045
- if (contributor.attrs.corresp) {
1046
- contributor.attrs.corresp.map((corresp) => {
1047
- const xref = this.appendElement(contrib, 'xref', '', {
1048
- 'ref-type': 'corresp',
1049
- rid: normalizeID(corresp.correspID),
1050
- });
1051
- xref.appendChild(createFootNotesLabels(corresp.correspLabel));
1052
- contrib.appendChild(xref);
1053
- });
1054
- }
1055
- if (contributor.attrs.creditRoles) {
1056
- contributor.attrs.creditRoles.forEach((cr) => {
1057
- const role = this.createElement('role');
1058
- const creditUrl = CreditRoleUrls.get(cr.vocabTerm);
1059
- if (creditUrl) {
1060
- role.setAttribute('vocab-identifier', 'http://credit.niso.org/');
1061
- role.setAttribute('vocab', 'CRediT');
1062
- role.setAttribute('vocab-term', cr.vocabTerm);
1063
- role.setAttribute('vocab-term-identifier', creditUrl);
1064
- role.textContent = cr.vocabTerm;
1065
- }
1066
- contrib.appendChild(role);
1067
- });
1068
- }
1069
- contribGroup.appendChild(contrib);
1070
- });
1071
- const affiliationRIDs = [];
1072
- for (const contributor of contributors) {
1073
- if (contributor.attrs.affiliations) {
1074
- affiliationRIDs.push(...contributor.attrs.affiliations);
1075
- }
933
+ const $contribGroup = this.createElement('contrib-group');
934
+ $contribGroup.setAttribute('content-type', 'authors');
935
+ articleMeta.appendChild($contribGroup);
936
+ contributors.forEach((contributor) => {
937
+ const $contrib = this.createElement('contrib');
938
+ $contrib.setAttribute('contrib-type', 'author');
939
+ $contrib.setAttribute('id', normalizeID(contributor.attrs.id));
940
+ if (contributor.attrs.isCorresponding) {
941
+ $contrib.setAttribute('corresp', 'yes');
1076
942
  }
1077
- const affiliationIDs = contributors.flatMap((n) => n.attrs.affiliations);
1078
- const sortAffiliations = (a, b) => affiliationIDs.indexOf(a.attrs.id) - affiliationIDs.indexOf(b.attrs.id);
1079
- this.getChildrenOfType(schema.nodes.affiliation)
1080
- .filter((a) => affiliationIDs.includes(a.attrs.id))
1081
- .sort(sortAffiliations)
1082
- .forEach((affiliation) => {
1083
- const $aff = this.createElement('aff', '', {
1084
- id: normalizeID(affiliation.attrs.id),
943
+ if (contributor.attrs.role) {
944
+ this.appendElement($contrib, 'role', contributor.attrs.role);
945
+ }
946
+ if (contributor.attrs.ORCID) {
947
+ this.appendElement($contrib, 'contrib-id', contributor.attrs.ORCID, {
948
+ 'contrib-id-type': 'orcid',
1085
949
  });
1086
- const label = affiliationLabels.get(affiliation.attrs.id);
1087
- if (label) {
1088
- this.appendElement($aff, 'label', String(label));
1089
- }
1090
- const affiliationParts = [
1091
- {
1092
- value: affiliation.attrs.department,
1093
- tag: 'institution',
1094
- 'content-type': 'dept',
1095
- },
1096
- { value: affiliation.attrs.institution, tag: 'institution' },
1097
- { value: affiliation.attrs.addressLine1, tag: 'addr-line' },
1098
- { value: affiliation.attrs.addressLine2, tag: 'addr-line' },
1099
- { value: affiliation.attrs.addressLine3, tag: 'addr-line' },
1100
- { value: affiliation.attrs.city, tag: 'city' },
1101
- { value: affiliation.attrs.county, tag: 'state' },
1102
- { value: affiliation.attrs.country, tag: 'country' },
1103
- { value: affiliation.attrs.postCode, tag: 'postal-code' },
1104
- ].filter((obj) => obj.value);
1105
- affiliationParts.forEach((location, index) => {
1106
- if (index) {
1107
- const punctuation = this.document.createTextNode(', ');
1108
- $aff.appendChild(punctuation);
1109
- }
1110
- const { tag, value, ...rest } = location;
1111
- this.appendElement($aff, tag, value, rest);
950
+ }
951
+ const $name = this.buildContributorName(contributor);
952
+ $contrib.appendChild($name);
953
+ if (contributor.attrs.email) {
954
+ this.appendElement($contrib, 'email', contributor.attrs.email);
955
+ }
956
+ contributor.attrs.affiliationIDs?.forEach((rid) => {
957
+ const $xref = this.appendElement($contrib, 'xref', '', {
958
+ 'ref-type': 'aff',
959
+ rid: normalizeID(rid),
1112
960
  });
1113
- const { href, text } = affiliation.attrs.email ?? {};
1114
- if (href) {
1115
- const email = this.appendElement($aff, 'email', text ?? href);
1116
- email.setAttributeNS(XLINK_NAMESPACE, 'href', href);
961
+ $xref.appendChild(createLabel(rid));
962
+ });
963
+ contributor.attrs.footnoteIDs?.forEach((rid) => {
964
+ const $xref = this.appendElement($contrib, 'xref', '', {
965
+ 'ref-type': 'fn',
966
+ rid: normalizeID(rid),
967
+ });
968
+ $xref.appendChild(createLabel(rid));
969
+ });
970
+ contributor.attrs.correspIDs?.forEach((rid) => {
971
+ const $xref = this.appendElement($contrib, 'xref', '', {
972
+ 'ref-type': 'corresp',
973
+ rid: normalizeID(rid),
974
+ });
975
+ $xref.appendChild(createLabel(rid));
976
+ });
977
+ contributor.attrs.creditRoles?.forEach((credit) => {
978
+ const url = CreditRoleUrls.get(credit.vocabTerm);
979
+ if (!url) {
980
+ return;
1117
981
  }
1118
- contribGroup.appendChild($aff);
982
+ this.appendElement($contrib, 'role', credit.vocabTerm, {
983
+ 'vocab-identifier': 'http://credit.niso.org/',
984
+ 'vocab': 'CRediT',
985
+ 'vocab-term': credit.vocabTerm,
986
+ 'vocab-term-identifier': url,
987
+ });
1119
988
  });
1120
- const authorNotesEl = this.createAuthorNotesElement();
1121
- if (authorNotesEl.childNodes.length > 0) {
1122
- articleMeta.insertBefore(authorNotesEl, contribGroup.nextSibling);
989
+ $contribGroup.appendChild($contrib);
990
+ });
991
+ const affiliationIDs = contributors.flatMap((n) => n.attrs.affiliationIDs);
992
+ const sortAffiliations = (a, b) => affiliationIDs.indexOf(a.attrs.id) - affiliationIDs.indexOf(b.attrs.id);
993
+ this.getChildrenOfType(schema.nodes.affiliation)
994
+ .filter((a) => affiliationIDs.includes(a.attrs.id))
995
+ .sort(sortAffiliations)
996
+ .forEach((affiliation) => {
997
+ const $content = [];
998
+ if (affiliation.attrs.department) {
999
+ const $institution = this.createElement('institution', affiliation.attrs.department, {
1000
+ 'content-type': 'dept',
1001
+ });
1002
+ $content.push($institution);
1003
+ }
1004
+ if (affiliation.attrs.institution) {
1005
+ const $institution = this.createElement('institution', affiliation.attrs.institution);
1006
+ $content.push($institution);
1007
+ }
1008
+ if (affiliation.attrs.addressLine1) {
1009
+ const $addrLine = this.createElement('addr-line', affiliation.attrs.addressLine1);
1010
+ $content.push($addrLine);
1011
+ }
1012
+ if (affiliation.attrs.addressLine2) {
1013
+ const $addrLine = this.createElement('addr-line', affiliation.attrs.addressLine2);
1014
+ $content.push($addrLine);
1015
+ }
1016
+ if (affiliation.attrs.addressLine3) {
1017
+ const $addrLine = this.createElement('addr-line', affiliation.attrs.addressLine3);
1018
+ $content.push($addrLine);
1019
+ }
1020
+ if (affiliation.attrs.city) {
1021
+ const $city = this.createElement('city', affiliation.attrs.city);
1022
+ $content.push($city);
1023
+ }
1024
+ if (affiliation.attrs.county) {
1025
+ const $state = this.createElement('state', affiliation.attrs.county);
1026
+ $content.push($state);
1027
+ }
1028
+ if (affiliation.attrs.country) {
1029
+ const $country = this.createElement('country', affiliation.attrs.country);
1030
+ $content.push($country);
1031
+ }
1032
+ if (affiliation.attrs.postCode) {
1033
+ const $postalCode = this.createElement('postal-code', affiliation.attrs.postCode);
1034
+ $content.push($postalCode);
1035
+ }
1036
+ const $aff = this.createElement('aff');
1037
+ $aff.setAttribute('id', normalizeID(affiliation.attrs.id));
1038
+ $contribGroup.appendChild($aff);
1039
+ const label = labels.get(affiliation.attrs.id);
1040
+ if (label) {
1041
+ this.appendElement($aff, 'label', String(label));
1123
1042
  }
1043
+ $content.forEach((node, i) => {
1044
+ if (i > 0) {
1045
+ $aff.appendChild(this.document.createTextNode(', '));
1046
+ }
1047
+ $aff.appendChild(node);
1048
+ });
1049
+ });
1050
+ const $authorNotes = this.createAuthorNotesElement(contributors);
1051
+ if ($authorNotes) {
1052
+ articleMeta.insertBefore($authorNotes, $contribGroup.nextSibling);
1124
1053
  }
1125
1054
  };
1126
1055
  this.buildContributorName = (contributor) => {
1127
- const { given, family } = contributor.attrs.bibliographicName;
1056
+ const { given, family } = contributor.attrs;
1128
1057
  if (Boolean(given) !== Boolean(family)) {
1129
1058
  return this.createElement('string-name', given || family);
1130
1059
  }
1131
1060
  const name = this.createElement('name');
1132
- if (contributor.attrs.bibliographicName.family) {
1133
- this.appendElement(name, 'surname', contributor.attrs.bibliographicName.family);
1061
+ if (contributor.attrs.family) {
1062
+ this.appendElement(name, 'surname', contributor.attrs.family);
1134
1063
  }
1135
- if (contributor.attrs.bibliographicName.given) {
1136
- this.appendElement(name, 'given-names', contributor.attrs.bibliographicName.given);
1064
+ if (contributor.attrs.given) {
1065
+ this.appendElement(name, 'given-names', contributor.attrs.given);
1137
1066
  }
1138
1067
  if (contributor.attrs.prefix) {
1139
1068
  this.appendElement(name, 'prefix', contributor.attrs.prefix);
1140
1069
  }
1141
1070
  return name;
1142
1071
  };
1143
- this.createAuthorNotesElement = () => {
1144
- const authorNotesEl = this.createElement('author-notes');
1145
- const authorNotesNode = this.getFirstChildOfType(schema.nodes.author_notes);
1146
- if (authorNotesNode) {
1147
- this.appendModelsToAuthorNotes(authorNotesEl, authorNotesNode);
1072
+ this.createAuthorNotesElement = (contributors) => {
1073
+ const authorNotes = this.getFirstChildOfType(schema.nodes.author_notes);
1074
+ if (!authorNotes || !authorNotes.childCount) {
1075
+ return;
1148
1076
  }
1149
- return authorNotesEl;
1077
+ const $authorNotes = this.createElement('author-notes');
1078
+ const used = contributors.flatMap((c) => c.attrs.correspIDs);
1079
+ authorNotes.descendants((node) => {
1080
+ switch (node.type) {
1081
+ case schema.nodes.paragraph: {
1082
+ const $p = this.writeParagraph(node);
1083
+ $authorNotes.append($p);
1084
+ break;
1085
+ }
1086
+ case schema.nodes.footnote: {
1087
+ const $fn = this.writeFootnote(node);
1088
+ $authorNotes.append($fn);
1089
+ break;
1090
+ }
1091
+ case schema.nodes.corresp: {
1092
+ if (used.includes(node.attrs.id)) {
1093
+ const $corresp = this.writeCorresp(node);
1094
+ $authorNotes.append($corresp);
1095
+ }
1096
+ break;
1097
+ }
1098
+ }
1099
+ return false;
1100
+ });
1101
+ return $authorNotes;
1150
1102
  };
1151
- this.appendCorrespondingToElement = (corresponding, element) => {
1152
- const correspondingEl = this.createElement('corresp');
1153
- correspondingEl.setAttribute('id', normalizeID(corresponding.attrs.id));
1154
- if (corresponding.attrs.label) {
1155
- const labelEl = this.createElement('label');
1156
- labelEl.textContent = corresponding.attrs.label;
1157
- correspondingEl.appendChild(labelEl);
1158
- }
1159
- correspondingEl.append(corresponding.textContent);
1160
- element.appendChild(correspondingEl);
1103
+ this.writeCorresp = (corresp) => {
1104
+ const $corresp = this.createElement('corresp');
1105
+ $corresp.setAttribute('id', normalizeID(corresp.attrs.id));
1106
+ if (corresp.attrs.label) {
1107
+ this.appendElement($corresp, 'label', corresp.attrs.label);
1108
+ }
1109
+ $corresp.append(corresp.textContent);
1110
+ return $corresp;
1161
1111
  };
1162
- this.appendParagraphToElement = (paragraph, element) => {
1163
- const parsedDoc = new DOMParser().parseFromString(paragraph.textContent, 'text/html');
1164
- if (parsedDoc.body.innerHTML.length) {
1165
- const paragraphEl = this.createElement('p');
1166
- paragraphEl.innerHTML = parsedDoc.body.innerHTML;
1167
- paragraphEl.setAttribute('id', normalizeID(paragraph.attrs.id));
1168
- element.appendChild(paragraphEl);
1169
- }
1112
+ this.writeParagraph = (paragraph) => {
1113
+ const dom = new DOMParser().parseFromString(paragraph.textContent, 'text/html');
1114
+ const $p = this.createElement('p');
1115
+ $p.setAttribute('id', normalizeID(paragraph.attrs.id));
1116
+ if (dom.body.innerHTML.length) {
1117
+ $p.innerHTML = dom.body.innerHTML;
1118
+ }
1119
+ return $p;
1170
1120
  };
1171
- this.appendFootnoteToElement = (footnote, element) => {
1172
- const footnoteEl = this.createElement('fn');
1173
- footnoteEl.setAttribute('id', normalizeID(footnote.attrs.id));
1174
- if (!footnote.textContent.includes('<p>')) {
1175
- const p = this.createElement('p');
1176
- p.innerHTML = footnote.textContent;
1177
- footnoteEl.appendChild(p);
1178
- }
1179
- else {
1180
- footnoteEl.innerHTML = footnote.textContent;
1181
- }
1182
- element.appendChild(footnoteEl);
1121
+ this.writeFootnote = (footnote) => {
1122
+ const $fn = this.createElement('fn');
1123
+ $fn.setAttribute('id', normalizeID(footnote.attrs.id));
1124
+ let content = footnote.textContent;
1125
+ if (!content.includes('<p>')) {
1126
+ content = `<p>${content}</p>`;
1127
+ }
1128
+ $fn.innerHTML = content;
1129
+ return $fn;
1183
1130
  };
1184
1131
  this.fixBody = (body) => {
1185
1132
  this.manuscriptNode.descendants((node) => {
@@ -1439,34 +1386,6 @@ export class JATSExporter {
1439
1386
  return mathml;
1440
1387
  }
1441
1388
  }
1442
- appendModelsToAuthorNotes(authorNotesEl, authorNotesNode) {
1443
- const contributorsNodes = this.getChildrenOfType(schema.nodes.contributor);
1444
- const usedCorrespondings = this.getUsedCorrespondings(contributorsNodes);
1445
- authorNotesNode.descendants((node) => {
1446
- switch (node.type) {
1447
- case schema.nodes.paragraph:
1448
- this.appendParagraphToElement(node, authorNotesEl);
1449
- break;
1450
- case schema.nodes.footnote:
1451
- this.appendFootnoteToElement(node, authorNotesEl);
1452
- break;
1453
- case schema.nodes.corresp:
1454
- if (usedCorrespondings.includes(node)) {
1455
- this.appendCorrespondingToElement(node, authorNotesEl);
1456
- }
1457
- break;
1458
- }
1459
- return false;
1460
- });
1461
- }
1462
- getUsedCorrespondings(contributors) {
1463
- return contributors
1464
- .flatMap((c) => c.attrs.corresp ?? [])
1465
- .map((corresp) => {
1466
- return findChildrenByAttr(this.manuscriptNode, (attr) => attr.id === corresp.correspID)[0]?.node;
1467
- })
1468
- .filter((corresp) => !!corresp);
1469
- }
1470
1389
  buildKeywords(articleMeta) {
1471
1390
  const keywordGroups = this.getChildrenOfType(schema.nodes.keyword_group);
1472
1391
  keywordGroups.forEach((group) => {
@@ -1,19 +1,3 @@
1
- /*!
2
- * © 2020 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
- import { buildContribution, ObjectTypes } from '@manuscripts/json-schema';
17
1
  import { DOMParser, Fragment } from 'prosemirror-model';
18
2
  import { dateToTimestamp, getCreditRole, getHTMLContent, getTrimmedTextContent, } from '../../lib/utils';
19
3
  import { XLINK_NAMESPACE, XML_NAMESPACE } from '../../lib/xml';
@@ -304,7 +288,8 @@ export class JATSDOMParser {
304
288
  id: element.getAttribute('id'),
305
289
  target: element.getAttribute('target-id'),
306
290
  contents: getTrimmedTextContent(element),
307
- contributions: [buildContribution(DEFAULT_PROFILE_ID)],
291
+ userID: DEFAULT_PROFILE_ID,
292
+ timestamp: Date.now(),
308
293
  };
309
294
  },
310
295
  },
@@ -378,9 +363,9 @@ export class JATSDOMParser {
378
363
  node: 'contributor',
379
364
  getAttrs: (node) => {
380
365
  const element = node;
381
- const footnote = [];
382
- const affiliations = [];
383
- const corresp = [];
366
+ const footnoteIDs = [];
367
+ const affiliationIDs = [];
368
+ const correspIDs = [];
384
369
  const xrefs = element.querySelectorAll('xref');
385
370
  for (const xref of xrefs) {
386
371
  const rid = xref.getAttribute('rid');
@@ -390,41 +375,30 @@ export class JATSDOMParser {
390
375
  }
391
376
  switch (type) {
392
377
  case 'fn':
393
- footnote.push({
394
- noteID: rid,
395
- noteLabel: getTrimmedTextContent(xref) || '',
396
- });
378
+ footnoteIDs.push(rid);
397
379
  break;
398
380
  case 'corresp':
399
- corresp.push({
400
- correspID: rid,
401
- correspLabel: getTrimmedTextContent(xref) || '',
402
- });
381
+ correspIDs.push(rid);
403
382
  break;
404
383
  case 'aff':
405
- affiliations.push(rid);
384
+ affiliationIDs.push(rid);
406
385
  break;
407
386
  }
408
387
  }
409
388
  return {
410
389
  id: element.getAttribute('id') || undefined,
411
390
  role: getTrimmedTextContent(element, 'role'),
412
- affiliations,
413
- corresp,
414
- footnote,
415
- isCorresponding: element.getAttribute('corresp')
416
- ? element.getAttribute('corresp') === 'yes'
417
- : undefined,
418
- bibliographicName: {
419
- given: getTrimmedTextContent(element, 'given-names'),
420
- family: this.getSurname(element),
421
- ObjectType: ObjectTypes.BibliographicName,
422
- },
423
- ORCIDIdentifier: getTrimmedTextContent(element, 'contrib-id[contrib-id-type="orcid"]'),
391
+ affiliationIDs,
392
+ correspIDs,
393
+ footnoteIDs,
394
+ isCorresponding: element.getAttribute('corresp') === 'yes',
395
+ given: getTrimmedTextContent(element, 'given-names'),
396
+ family: this.getSurname(element),
397
+ prefix: getTrimmedTextContent(element, 'prefix'),
398
+ ORCID: getTrimmedTextContent(element, 'contrib-id[contrib-id-type="orcid"]'),
424
399
  creditRoles: getCreditRole(element),
425
400
  priority: this.parsePriority(element.getAttribute('priority')),
426
401
  email: getTrimmedTextContent(element, 'email') || '',
427
- prefix: getTrimmedTextContent(element, 'prefix'),
428
402
  };
429
403
  },
430
404
  getContent: () => {