@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
@@ -30,28 +30,15 @@ const uuidRegex = /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[
30
30
  const replaceUUIDWithTest = (input) => input.replace(uuidRegex, 'test');
31
31
  const updateContributorNodeIDs = (node) => {
32
32
  if ((0, schema_1.isContributorNode)(node)) {
33
- node.attrs.footnote = node.attrs.footnote.map((fn) => {
34
- return { ...fn, noteID: replaceUUIDWithTest(fn.noteID) };
35
- });
36
- node.attrs.corresp = node.attrs.corresp.map((corresp) => {
37
- return { ...corresp, correspID: replaceUUIDWithTest(corresp.correspID) };
38
- });
39
- node.attrs.affiliations = node.attrs.affiliations.map((aff) => replaceUUIDWithTest(aff));
40
- if (node.attrs.bibliographicName._id) {
41
- node.attrs.bibliographicName._id = replaceUUIDWithTest(node.attrs.bibliographicName._id);
42
- }
33
+ node.attrs.footnoteIDs = node.attrs.footnoteIDs?.map((id) => replaceUUIDWithTest(id));
34
+ node.attrs.correspIDs = node.attrs.correspIDs?.map((id) => replaceUUIDWithTest(id));
35
+ node.attrs.affiliationIDs = node.attrs.affiliationIDs?.map((id) => replaceUUIDWithTest(id));
43
36
  }
44
37
  };
45
38
  const updateCommentNodeIDs = (node) => {
46
39
  if ((0, schema_1.isCommentNode)(node)) {
47
40
  node.attrs.target = replaceUUIDWithTest(node.attrs.target);
48
- node.attrs.contributions = node.attrs.contributions?.map((contribution) => {
49
- return {
50
- ...contribution,
51
- _id: replaceUUIDWithTest(contribution._id),
52
- timestamp: 1234,
53
- };
54
- });
41
+ node.attrs.timestamp = 1234;
55
42
  }
56
43
  };
57
44
  const updateNodeRID = (node) => {
@@ -138,7 +138,7 @@ class JATSExporter {
138
138
  this.document = document.implementation.createDocument(null, 'article', document.implementation.createDocumentType('article', versionIds.publicId, versionIds.systemId));
139
139
  const article = this.document.documentElement;
140
140
  article.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', xml_1.XLINK_NAMESPACE);
141
- const front = this.buildFront(options.journal);
141
+ const front = this.buildFront();
142
142
  article.appendChild(front);
143
143
  article.setAttribute('article-type', manuscriptNode.attrs.articleType || 'other');
144
144
  article.setAttributeNS(xml_1.XML_NAMESPACE, 'lang', manuscriptNode.attrs.primaryLanguageCode || 'en');
@@ -247,60 +247,10 @@ class JATSExporter {
247
247
  }
248
248
  }
249
249
  };
250
- this.buildFront = (journal) => {
250
+ this.buildFront = () => {
251
251
  const front = this.createElement('front');
252
- const journalMeta = this.createElement('journal-meta');
253
- front.appendChild(journalMeta);
254
252
  const articleMeta = this.createElement('article-meta');
255
253
  front.appendChild(articleMeta);
256
- if (journal) {
257
- if (journal.journalIdentifiers) {
258
- for (const item of journal.journalIdentifiers) {
259
- const element = this.createElement('journal-id');
260
- if (item.journalIDType) {
261
- element.setAttribute('journal-id-type', item.journalIDType);
262
- }
263
- element.textContent = item.journalID;
264
- journalMeta.appendChild(element);
265
- }
266
- }
267
- if (journal.title || journal.abbreviatedTitles) {
268
- const parentElement = this.createElement('journal-title-group');
269
- journalMeta.appendChild(parentElement);
270
- if (journal.title) {
271
- const element = this.createElement('journal-title');
272
- element.textContent = journal.title;
273
- parentElement.appendChild(element);
274
- }
275
- if (journal.abbreviatedTitles) {
276
- for (const item of journal.abbreviatedTitles) {
277
- const element = this.createElement('abbrev-journal-title');
278
- if (item.abbrevType) {
279
- element.setAttribute('abbrev-type', item.abbrevType);
280
- }
281
- element.textContent = item.abbreviatedTitle;
282
- parentElement.appendChild(element);
283
- }
284
- }
285
- }
286
- if (journal.ISSNs) {
287
- for (const item of journal.ISSNs) {
288
- const element = this.createElement('issn');
289
- if (item.publicationType) {
290
- element.setAttribute('pub-type', item.publicationType);
291
- }
292
- element.textContent = item.ISSN;
293
- journalMeta.appendChild(element);
294
- }
295
- }
296
- if (journal.publisherName) {
297
- const publisher = this.createElement('publisher');
298
- const publisherName = this.createElement('publisher-name');
299
- publisherName.textContent = journal.publisherName;
300
- publisher.appendChild(publisherName);
301
- journalMeta.appendChild(publisher);
302
- }
303
- }
304
254
  if (this.manuscriptNode.attrs.doi) {
305
255
  const articleID = this.createElement('article-id');
306
256
  articleID.setAttribute('pub-id-type', 'doi');
@@ -385,18 +335,15 @@ class JATSExporter {
385
335
  counts.append(...countingElements);
386
336
  articleMeta.append(counts);
387
337
  }
388
- if (!journalMeta.hasChildNodes()) {
389
- journalMeta.remove();
390
- }
391
- const selfUriAttachments = this.getChildrenOfType(schema_1.schema.nodes.attachment);
392
- selfUriAttachments.forEach((attachment) => {
393
- const selfUriElement = this.createElement('self-uri');
394
- selfUriElement.setAttribute('content-type', attachment.attrs.type);
395
- selfUriElement.setAttributeNS(xml_1.XLINK_NAMESPACE, 'href', attachment.attrs.href);
338
+ const attachments = this.getChildrenOfType(schema_1.schema.nodes.attachment);
339
+ attachments.forEach((attachment) => {
340
+ const $selfUri = this.createElement('self-uri');
341
+ $selfUri.setAttribute('content-type', attachment.attrs.type);
342
+ $selfUri.setAttributeNS(xml_1.XLINK_NAMESPACE, 'href', attachment.attrs.href);
396
343
  const insertBeforeElements = articleMeta.querySelector('related-article, related-object, abstract, trans-abstract, kwd-group, funding-group, support-group, conference, counts, custom-meta-group');
397
344
  insertBeforeElements
398
- ? articleMeta.insertBefore(selfUriElement, insertBeforeElements)
399
- : articleMeta.appendChild(selfUriElement);
345
+ ? articleMeta.insertBefore($selfUri, insertBeforeElements)
346
+ : articleMeta.appendChild($selfUri);
400
347
  });
401
348
  return front;
402
349
  };
@@ -1007,219 +954,219 @@ class JATSExporter {
1007
954
  this.serializeNode = (node) => this.serializer.serializeNode(node, {
1008
955
  document: this.document,
1009
956
  });
1010
- this.validateContributor = (contributor) => {
1011
- if (!contributor.attrs.bibliographicName) {
1012
- throw new Error(`${contributor.attrs.id} has no bibliographicName`);
1013
- }
1014
- const { family, given } = contributor.attrs.bibliographicName;
1015
- if (!family && !given) {
1016
- throw new Error(`${contributor.attrs.id} has neither family nor given name`);
1017
- }
1018
- };
1019
957
  this.buildContributors = (articleMeta) => {
1020
958
  const contributors = this.getChildrenOfType(schema_1.schema.nodes.contributor).sort(sortContributors);
1021
- const affiliationLabels = new Map();
1022
- const creatAffiliationLabel = (rid) => {
1023
- let label = affiliationLabels.get(rid);
959
+ if (!contributors.length) {
960
+ return;
961
+ }
962
+ const labels = new Map();
963
+ const createLabel = (id) => {
964
+ let label = labels.get(id);
1024
965
  if (!label) {
1025
- label = String(affiliationLabels.size + 1);
1026
- affiliationLabels.set(rid, label);
966
+ label = labels.size + 1;
967
+ labels.set(id, label);
1027
968
  }
1028
969
  const sup = this.createElement('sup');
1029
970
  sup.textContent = String(label);
1030
971
  return sup;
1031
972
  };
1032
- const createFootNotesLabels = (content) => {
1033
- const sup = this.createElement('sup');
1034
- sup.textContent = String(content);
1035
- return sup;
1036
- };
1037
- if (contributors.length) {
1038
- const contribGroup = this.createElement('contrib-group');
1039
- contribGroup.setAttribute('content-type', 'authors');
1040
- articleMeta.appendChild(contribGroup);
1041
- contributors.forEach((contributor) => {
1042
- try {
1043
- this.validateContributor(contributor);
1044
- }
1045
- catch (error) {
1046
- return;
1047
- }
1048
- const contrib = this.createElement('contrib');
1049
- contrib.setAttribute('contrib-type', 'author');
1050
- contrib.setAttribute('id', normalizeID(contributor.attrs.id));
1051
- if (contributor.attrs.isCorresponding) {
1052
- contrib.setAttribute('corresp', 'yes');
1053
- }
1054
- if (contributor.attrs.role) {
1055
- this.appendElement(contrib, 'role', contributor.attrs.role);
1056
- }
1057
- if (contributor.attrs.ORCIDIdentifier) {
1058
- this.appendElement(contrib, 'contrib-id', contributor.attrs.ORCIDIdentifier, { 'contrib-id-type': 'orcid' });
1059
- }
1060
- const name = this.buildContributorName(contributor);
1061
- contrib.appendChild(name);
1062
- if (contributor.attrs.email) {
1063
- this.appendElement(contrib, 'email', contributor.attrs.email);
1064
- }
1065
- if (contributor.attrs.affiliations) {
1066
- contributor.attrs.affiliations.forEach((rid) => {
1067
- const xref = this.appendElement(contrib, 'xref', '', {
1068
- 'ref-type': 'aff',
1069
- rid: normalizeID(rid),
1070
- });
1071
- xref.appendChild(creatAffiliationLabel(rid));
1072
- contrib.appendChild(xref);
1073
- });
1074
- }
1075
- if (contributor.attrs.footnote) {
1076
- contributor.attrs.footnote.map((note) => {
1077
- const xref = this.appendElement(contrib, 'xref', '', {
1078
- 'ref-type': 'fn',
1079
- rid: normalizeID(note.noteID),
1080
- });
1081
- xref.appendChild(createFootNotesLabels(note.noteLabel));
1082
- contrib.appendChild(xref);
1083
- });
1084
- }
1085
- if (contributor.attrs.corresp) {
1086
- contributor.attrs.corresp.map((corresp) => {
1087
- const xref = this.appendElement(contrib, 'xref', '', {
1088
- 'ref-type': 'corresp',
1089
- rid: normalizeID(corresp.correspID),
1090
- });
1091
- xref.appendChild(createFootNotesLabels(corresp.correspLabel));
1092
- contrib.appendChild(xref);
1093
- });
1094
- }
1095
- if (contributor.attrs.creditRoles) {
1096
- contributor.attrs.creditRoles.forEach((cr) => {
1097
- const role = this.createElement('role');
1098
- const creditUrl = credit_roles_1.CreditRoleUrls.get(cr.vocabTerm);
1099
- if (creditUrl) {
1100
- role.setAttribute('vocab-identifier', 'http://credit.niso.org/');
1101
- role.setAttribute('vocab', 'CRediT');
1102
- role.setAttribute('vocab-term', cr.vocabTerm);
1103
- role.setAttribute('vocab-term-identifier', creditUrl);
1104
- role.textContent = cr.vocabTerm;
1105
- }
1106
- contrib.appendChild(role);
1107
- });
1108
- }
1109
- contribGroup.appendChild(contrib);
1110
- });
1111
- const affiliationRIDs = [];
1112
- for (const contributor of contributors) {
1113
- if (contributor.attrs.affiliations) {
1114
- affiliationRIDs.push(...contributor.attrs.affiliations);
1115
- }
973
+ const $contribGroup = this.createElement('contrib-group');
974
+ $contribGroup.setAttribute('content-type', 'authors');
975
+ articleMeta.appendChild($contribGroup);
976
+ contributors.forEach((contributor) => {
977
+ const $contrib = this.createElement('contrib');
978
+ $contrib.setAttribute('contrib-type', 'author');
979
+ $contrib.setAttribute('id', normalizeID(contributor.attrs.id));
980
+ if (contributor.attrs.isCorresponding) {
981
+ $contrib.setAttribute('corresp', 'yes');
1116
982
  }
1117
- const affiliationIDs = contributors.flatMap((n) => n.attrs.affiliations);
1118
- const sortAffiliations = (a, b) => affiliationIDs.indexOf(a.attrs.id) - affiliationIDs.indexOf(b.attrs.id);
1119
- this.getChildrenOfType(schema_1.schema.nodes.affiliation)
1120
- .filter((a) => affiliationIDs.includes(a.attrs.id))
1121
- .sort(sortAffiliations)
1122
- .forEach((affiliation) => {
1123
- const $aff = this.createElement('aff', '', {
1124
- id: normalizeID(affiliation.attrs.id),
983
+ if (contributor.attrs.role) {
984
+ this.appendElement($contrib, 'role', contributor.attrs.role);
985
+ }
986
+ if (contributor.attrs.ORCID) {
987
+ this.appendElement($contrib, 'contrib-id', contributor.attrs.ORCID, {
988
+ 'contrib-id-type': 'orcid',
1125
989
  });
1126
- const label = affiliationLabels.get(affiliation.attrs.id);
1127
- if (label) {
1128
- this.appendElement($aff, 'label', String(label));
1129
- }
1130
- const affiliationParts = [
1131
- {
1132
- value: affiliation.attrs.department,
1133
- tag: 'institution',
1134
- 'content-type': 'dept',
1135
- },
1136
- { value: affiliation.attrs.institution, tag: 'institution' },
1137
- { value: affiliation.attrs.addressLine1, tag: 'addr-line' },
1138
- { value: affiliation.attrs.addressLine2, tag: 'addr-line' },
1139
- { value: affiliation.attrs.addressLine3, tag: 'addr-line' },
1140
- { value: affiliation.attrs.city, tag: 'city' },
1141
- { value: affiliation.attrs.county, tag: 'state' },
1142
- { value: affiliation.attrs.country, tag: 'country' },
1143
- { value: affiliation.attrs.postCode, tag: 'postal-code' },
1144
- ].filter((obj) => obj.value);
1145
- affiliationParts.forEach((location, index) => {
1146
- if (index) {
1147
- const punctuation = this.document.createTextNode(', ');
1148
- $aff.appendChild(punctuation);
1149
- }
1150
- const { tag, value, ...rest } = location;
1151
- this.appendElement($aff, tag, value, rest);
990
+ }
991
+ const $name = this.buildContributorName(contributor);
992
+ $contrib.appendChild($name);
993
+ if (contributor.attrs.email) {
994
+ this.appendElement($contrib, 'email', contributor.attrs.email);
995
+ }
996
+ contributor.attrs.affiliationIDs?.forEach((rid) => {
997
+ const $xref = this.appendElement($contrib, 'xref', '', {
998
+ 'ref-type': 'aff',
999
+ rid: normalizeID(rid),
1152
1000
  });
1153
- const { href, text } = affiliation.attrs.email ?? {};
1154
- if (href) {
1155
- const email = this.appendElement($aff, 'email', text ?? href);
1156
- email.setAttributeNS(xml_1.XLINK_NAMESPACE, 'href', href);
1001
+ $xref.appendChild(createLabel(rid));
1002
+ });
1003
+ contributor.attrs.footnoteIDs?.forEach((rid) => {
1004
+ const $xref = this.appendElement($contrib, 'xref', '', {
1005
+ 'ref-type': 'fn',
1006
+ rid: normalizeID(rid),
1007
+ });
1008
+ $xref.appendChild(createLabel(rid));
1009
+ });
1010
+ contributor.attrs.correspIDs?.forEach((rid) => {
1011
+ const $xref = this.appendElement($contrib, 'xref', '', {
1012
+ 'ref-type': 'corresp',
1013
+ rid: normalizeID(rid),
1014
+ });
1015
+ $xref.appendChild(createLabel(rid));
1016
+ });
1017
+ contributor.attrs.creditRoles?.forEach((credit) => {
1018
+ const url = credit_roles_1.CreditRoleUrls.get(credit.vocabTerm);
1019
+ if (!url) {
1020
+ return;
1157
1021
  }
1158
- contribGroup.appendChild($aff);
1022
+ this.appendElement($contrib, 'role', credit.vocabTerm, {
1023
+ 'vocab-identifier': 'http://credit.niso.org/',
1024
+ 'vocab': 'CRediT',
1025
+ 'vocab-term': credit.vocabTerm,
1026
+ 'vocab-term-identifier': url,
1027
+ });
1159
1028
  });
1160
- const authorNotesEl = this.createAuthorNotesElement();
1161
- if (authorNotesEl.childNodes.length > 0) {
1162
- articleMeta.insertBefore(authorNotesEl, contribGroup.nextSibling);
1029
+ $contribGroup.appendChild($contrib);
1030
+ });
1031
+ const affiliationIDs = contributors.flatMap((n) => n.attrs.affiliationIDs);
1032
+ const sortAffiliations = (a, b) => affiliationIDs.indexOf(a.attrs.id) - affiliationIDs.indexOf(b.attrs.id);
1033
+ this.getChildrenOfType(schema_1.schema.nodes.affiliation)
1034
+ .filter((a) => affiliationIDs.includes(a.attrs.id))
1035
+ .sort(sortAffiliations)
1036
+ .forEach((affiliation) => {
1037
+ const $content = [];
1038
+ if (affiliation.attrs.department) {
1039
+ const $institution = this.createElement('institution', affiliation.attrs.department, {
1040
+ 'content-type': 'dept',
1041
+ });
1042
+ $content.push($institution);
1043
+ }
1044
+ if (affiliation.attrs.institution) {
1045
+ const $institution = this.createElement('institution', affiliation.attrs.institution);
1046
+ $content.push($institution);
1047
+ }
1048
+ if (affiliation.attrs.addressLine1) {
1049
+ const $addrLine = this.createElement('addr-line', affiliation.attrs.addressLine1);
1050
+ $content.push($addrLine);
1051
+ }
1052
+ if (affiliation.attrs.addressLine2) {
1053
+ const $addrLine = this.createElement('addr-line', affiliation.attrs.addressLine2);
1054
+ $content.push($addrLine);
1055
+ }
1056
+ if (affiliation.attrs.addressLine3) {
1057
+ const $addrLine = this.createElement('addr-line', affiliation.attrs.addressLine3);
1058
+ $content.push($addrLine);
1059
+ }
1060
+ if (affiliation.attrs.city) {
1061
+ const $city = this.createElement('city', affiliation.attrs.city);
1062
+ $content.push($city);
1063
+ }
1064
+ if (affiliation.attrs.county) {
1065
+ const $state = this.createElement('state', affiliation.attrs.county);
1066
+ $content.push($state);
1067
+ }
1068
+ if (affiliation.attrs.country) {
1069
+ const $country = this.createElement('country', affiliation.attrs.country);
1070
+ $content.push($country);
1071
+ }
1072
+ if (affiliation.attrs.postCode) {
1073
+ const $postalCode = this.createElement('postal-code', affiliation.attrs.postCode);
1074
+ $content.push($postalCode);
1075
+ }
1076
+ const $aff = this.createElement('aff');
1077
+ $aff.setAttribute('id', normalizeID(affiliation.attrs.id));
1078
+ $contribGroup.appendChild($aff);
1079
+ const label = labels.get(affiliation.attrs.id);
1080
+ if (label) {
1081
+ this.appendElement($aff, 'label', String(label));
1163
1082
  }
1083
+ $content.forEach((node, i) => {
1084
+ if (i > 0) {
1085
+ $aff.appendChild(this.document.createTextNode(', '));
1086
+ }
1087
+ $aff.appendChild(node);
1088
+ });
1089
+ });
1090
+ const $authorNotes = this.createAuthorNotesElement(contributors);
1091
+ if ($authorNotes) {
1092
+ articleMeta.insertBefore($authorNotes, $contribGroup.nextSibling);
1164
1093
  }
1165
1094
  };
1166
1095
  this.buildContributorName = (contributor) => {
1167
- const { given, family } = contributor.attrs.bibliographicName;
1096
+ const { given, family } = contributor.attrs;
1168
1097
  if (Boolean(given) !== Boolean(family)) {
1169
1098
  return this.createElement('string-name', given || family);
1170
1099
  }
1171
1100
  const name = this.createElement('name');
1172
- if (contributor.attrs.bibliographicName.family) {
1173
- this.appendElement(name, 'surname', contributor.attrs.bibliographicName.family);
1101
+ if (contributor.attrs.family) {
1102
+ this.appendElement(name, 'surname', contributor.attrs.family);
1174
1103
  }
1175
- if (contributor.attrs.bibliographicName.given) {
1176
- this.appendElement(name, 'given-names', contributor.attrs.bibliographicName.given);
1104
+ if (contributor.attrs.given) {
1105
+ this.appendElement(name, 'given-names', contributor.attrs.given);
1177
1106
  }
1178
1107
  if (contributor.attrs.prefix) {
1179
1108
  this.appendElement(name, 'prefix', contributor.attrs.prefix);
1180
1109
  }
1181
1110
  return name;
1182
1111
  };
1183
- this.createAuthorNotesElement = () => {
1184
- const authorNotesEl = this.createElement('author-notes');
1185
- const authorNotesNode = this.getFirstChildOfType(schema_1.schema.nodes.author_notes);
1186
- if (authorNotesNode) {
1187
- this.appendModelsToAuthorNotes(authorNotesEl, authorNotesNode);
1112
+ this.createAuthorNotesElement = (contributors) => {
1113
+ const authorNotes = this.getFirstChildOfType(schema_1.schema.nodes.author_notes);
1114
+ if (!authorNotes || !authorNotes.childCount) {
1115
+ return;
1188
1116
  }
1189
- return authorNotesEl;
1117
+ const $authorNotes = this.createElement('author-notes');
1118
+ const used = contributors.flatMap((c) => c.attrs.correspIDs);
1119
+ authorNotes.descendants((node) => {
1120
+ switch (node.type) {
1121
+ case schema_1.schema.nodes.paragraph: {
1122
+ const $p = this.writeParagraph(node);
1123
+ $authorNotes.append($p);
1124
+ break;
1125
+ }
1126
+ case schema_1.schema.nodes.footnote: {
1127
+ const $fn = this.writeFootnote(node);
1128
+ $authorNotes.append($fn);
1129
+ break;
1130
+ }
1131
+ case schema_1.schema.nodes.corresp: {
1132
+ if (used.includes(node.attrs.id)) {
1133
+ const $corresp = this.writeCorresp(node);
1134
+ $authorNotes.append($corresp);
1135
+ }
1136
+ break;
1137
+ }
1138
+ }
1139
+ return false;
1140
+ });
1141
+ return $authorNotes;
1190
1142
  };
1191
- this.appendCorrespondingToElement = (corresponding, element) => {
1192
- const correspondingEl = this.createElement('corresp');
1193
- correspondingEl.setAttribute('id', normalizeID(corresponding.attrs.id));
1194
- if (corresponding.attrs.label) {
1195
- const labelEl = this.createElement('label');
1196
- labelEl.textContent = corresponding.attrs.label;
1197
- correspondingEl.appendChild(labelEl);
1198
- }
1199
- correspondingEl.append(corresponding.textContent);
1200
- element.appendChild(correspondingEl);
1143
+ this.writeCorresp = (corresp) => {
1144
+ const $corresp = this.createElement('corresp');
1145
+ $corresp.setAttribute('id', normalizeID(corresp.attrs.id));
1146
+ if (corresp.attrs.label) {
1147
+ this.appendElement($corresp, 'label', corresp.attrs.label);
1148
+ }
1149
+ $corresp.append(corresp.textContent);
1150
+ return $corresp;
1201
1151
  };
1202
- this.appendParagraphToElement = (paragraph, element) => {
1203
- const parsedDoc = new DOMParser().parseFromString(paragraph.textContent, 'text/html');
1204
- if (parsedDoc.body.innerHTML.length) {
1205
- const paragraphEl = this.createElement('p');
1206
- paragraphEl.innerHTML = parsedDoc.body.innerHTML;
1207
- paragraphEl.setAttribute('id', normalizeID(paragraph.attrs.id));
1208
- element.appendChild(paragraphEl);
1209
- }
1152
+ this.writeParagraph = (paragraph) => {
1153
+ const dom = new DOMParser().parseFromString(paragraph.textContent, 'text/html');
1154
+ const $p = this.createElement('p');
1155
+ $p.setAttribute('id', normalizeID(paragraph.attrs.id));
1156
+ if (dom.body.innerHTML.length) {
1157
+ $p.innerHTML = dom.body.innerHTML;
1158
+ }
1159
+ return $p;
1210
1160
  };
1211
- this.appendFootnoteToElement = (footnote, element) => {
1212
- const footnoteEl = this.createElement('fn');
1213
- footnoteEl.setAttribute('id', normalizeID(footnote.attrs.id));
1214
- if (!footnote.textContent.includes('<p>')) {
1215
- const p = this.createElement('p');
1216
- p.innerHTML = footnote.textContent;
1217
- footnoteEl.appendChild(p);
1218
- }
1219
- else {
1220
- footnoteEl.innerHTML = footnote.textContent;
1221
- }
1222
- element.appendChild(footnoteEl);
1161
+ this.writeFootnote = (footnote) => {
1162
+ const $fn = this.createElement('fn');
1163
+ $fn.setAttribute('id', normalizeID(footnote.attrs.id));
1164
+ let content = footnote.textContent;
1165
+ if (!content.includes('<p>')) {
1166
+ content = `<p>${content}</p>`;
1167
+ }
1168
+ $fn.innerHTML = content;
1169
+ return $fn;
1223
1170
  };
1224
1171
  this.fixBody = (body) => {
1225
1172
  this.manuscriptNode.descendants((node) => {
@@ -1479,34 +1426,6 @@ class JATSExporter {
1479
1426
  return mathml;
1480
1427
  }
1481
1428
  }
1482
- appendModelsToAuthorNotes(authorNotesEl, authorNotesNode) {
1483
- const contributorsNodes = this.getChildrenOfType(schema_1.schema.nodes.contributor);
1484
- const usedCorrespondings = this.getUsedCorrespondings(contributorsNodes);
1485
- authorNotesNode.descendants((node) => {
1486
- switch (node.type) {
1487
- case schema_1.schema.nodes.paragraph:
1488
- this.appendParagraphToElement(node, authorNotesEl);
1489
- break;
1490
- case schema_1.schema.nodes.footnote:
1491
- this.appendFootnoteToElement(node, authorNotesEl);
1492
- break;
1493
- case schema_1.schema.nodes.corresp:
1494
- if (usedCorrespondings.includes(node)) {
1495
- this.appendCorrespondingToElement(node, authorNotesEl);
1496
- }
1497
- break;
1498
- }
1499
- return false;
1500
- });
1501
- }
1502
- getUsedCorrespondings(contributors) {
1503
- return contributors
1504
- .flatMap((c) => c.attrs.corresp ?? [])
1505
- .map((corresp) => {
1506
- return (0, prosemirror_utils_1.findChildrenByAttr)(this.manuscriptNode, (attr) => attr.id === corresp.correspID)[0]?.node;
1507
- })
1508
- .filter((corresp) => !!corresp);
1509
- }
1510
1429
  buildKeywords(articleMeta) {
1511
1430
  const keywordGroups = this.getChildrenOfType(schema_1.schema.nodes.keyword_group);
1512
1431
  keywordGroups.forEach((group) => {