@manuscripts/transform 4.3.22 → 4.3.24
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/README.md +2 -2
- package/dist/cjs/jats/__tests__/jats-exporter.test.js +11 -45
- package/dist/cjs/jats/__tests__/jats-importer.test.js +54 -76
- package/dist/cjs/jats/__tests__/jats-roundtrip.test.js +1 -2
- package/dist/cjs/jats/__tests__/utils.js +4 -17
- package/dist/cjs/jats/exporter/jats-exporter.js +190 -279
- package/dist/cjs/jats/importer/jats-dom-parser.js +16 -42
- package/dist/cjs/jats/importer/jats-parser-utils.js +5 -29
- package/dist/cjs/jats/importer/jats-transformations.js +10 -0
- package/dist/cjs/jats/importer/parse-jats-article.js +1 -6
- package/dist/cjs/schema/__tests__/docs.js +1830 -0
- package/dist/cjs/schema/__tests__/migration.test.js +3 -37
- package/dist/cjs/schema/migration/migration-scripts/4.3.12.js +39 -0
- package/dist/cjs/schema/migration/migration-scripts/index.js +2 -0
- package/dist/cjs/schema/nodes/blockquote_element.js +0 -2
- package/dist/cjs/schema/nodes/comment.js +2 -1
- package/dist/cjs/schema/nodes/contributor.js +11 -11
- package/dist/cjs/schema/nodes/equation.js +1 -3
- package/dist/cjs/schema/nodes/list.js +0 -2
- package/dist/cjs/schema/nodes/listing.js +1 -3
- package/dist/cjs/schema/nodes/paragraph.js +0 -2
- package/dist/cjs/schema/nodes/pullquote_element.js +0 -2
- package/dist/cjs/transformer/id.js +2 -14
- package/dist/cjs/transformer/node-names.js +6 -1
- package/dist/cjs/transformer/node-types.js +1 -47
- package/dist/cjs/version.js +1 -1
- package/dist/es/jats/__tests__/jats-exporter.test.js +11 -45
- package/dist/es/jats/__tests__/jats-importer.test.js +54 -76
- package/dist/es/jats/__tests__/jats-roundtrip.test.js +1 -2
- package/dist/es/jats/__tests__/utils.js +4 -17
- package/dist/es/jats/exporter/jats-exporter.js +190 -279
- package/dist/es/jats/importer/jats-dom-parser.js +16 -42
- package/dist/es/jats/importer/jats-parser-utils.js +6 -30
- package/dist/es/jats/importer/jats-transformations.js +10 -0
- package/dist/es/jats/importer/parse-jats-article.js +1 -6
- package/dist/es/schema/__tests__/docs.js +1827 -0
- package/dist/es/schema/__tests__/migration.test.js +3 -4
- package/dist/es/schema/migration/migration-scripts/4.3.12.js +37 -0
- package/dist/es/schema/migration/migration-scripts/index.js +2 -0
- package/dist/es/schema/nodes/blockquote_element.js +0 -2
- package/dist/es/schema/nodes/comment.js +2 -1
- package/dist/es/schema/nodes/contributor.js +11 -11
- package/dist/es/schema/nodes/equation.js +1 -3
- package/dist/es/schema/nodes/list.js +0 -2
- package/dist/es/schema/nodes/listing.js +1 -3
- package/dist/es/schema/nodes/paragraph.js +0 -2
- package/dist/es/schema/nodes/pullquote_element.js +0 -2
- package/dist/es/transformer/id.js +2 -14
- package/dist/es/transformer/node-names.js +4 -0
- package/dist/es/transformer/node-types.js +1 -47
- package/dist/es/version.js +1 -1
- package/dist/types/jats/__tests__/utils.d.ts +1 -11
- package/dist/types/jats/exporter/jats-exporter.d.ts +5 -10
- package/dist/types/jats/importer/jats-dom-parser.d.ts +0 -15
- package/dist/types/jats/importer/parse-jats-article.d.ts +1 -11
- package/dist/types/schema/__tests__/docs.d.ts +2 -0
- package/dist/types/schema/migration/migration-scripts/4.3.12.d.ts +8 -0
- package/dist/types/schema/migration/migration-scripts/index.d.ts +2 -1
- package/dist/types/schema/nodes/comment.d.ts +2 -2
- package/dist/types/schema/nodes/contributor.d.ts +11 -21
- package/dist/types/schema/types.d.ts +22 -0
- package/dist/types/transformer/node-names.d.ts +1 -0
- package/dist/types/transformer/node-types.d.ts +0 -2
- package/dist/types/version.d.ts +1 -1
- package/package.json +2 -2
- package/dist/cjs/jats/importer/jats-journal-meta-parser.js +0 -103
- package/dist/cjs/lib/styled-content.js +0 -28
- package/dist/es/jats/importer/jats-journal-meta-parser.js +0 -95
- package/dist/es/lib/styled-content.js +0 -23
- package/dist/types/jats/importer/jats-journal-meta-parser.d.ts +0 -46
- 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(
|
|
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 = (
|
|
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
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
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(
|
|
359
|
-
: articleMeta.appendChild(
|
|
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
|
-
|
|
982
|
-
|
|
983
|
-
|
|
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 =
|
|
986
|
-
|
|
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
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
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');
|
|
942
|
+
}
|
|
943
|
+
if (contributor.attrs.role) {
|
|
944
|
+
this.appendElement($contrib, 'role', contributor.attrs.role);
|
|
1076
945
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
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),
|
|
946
|
+
if (contributor.attrs.ORCID) {
|
|
947
|
+
this.appendElement($contrib, 'contrib-id', contributor.attrs.ORCID, {
|
|
948
|
+
'contrib-id-type': 'orcid',
|
|
1085
949
|
});
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
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),
|
|
960
|
+
});
|
|
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),
|
|
1112
967
|
});
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
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);
|
|
1123
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));
|
|
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
|
|
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.
|
|
1133
|
-
this.appendElement(name, 'surname', contributor.attrs.
|
|
1061
|
+
if (contributor.attrs.family) {
|
|
1062
|
+
this.appendElement(name, 'surname', contributor.attrs.family);
|
|
1134
1063
|
}
|
|
1135
|
-
if (contributor.attrs.
|
|
1136
|
-
this.appendElement(name, 'given-names', contributor.attrs.
|
|
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
|
|
1145
|
-
|
|
1146
|
-
|
|
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
|
-
|
|
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.
|
|
1152
|
-
const
|
|
1153
|
-
|
|
1154
|
-
if (
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
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.
|
|
1163
|
-
const
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
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.
|
|
1172
|
-
const
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
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) => {
|
|
@@ -1237,7 +1184,6 @@ export class JATSExporter {
|
|
|
1237
1184
|
}
|
|
1238
1185
|
const tbodyRows = Array.from(tbody.childNodes);
|
|
1239
1186
|
const thead = this.createElement('thead');
|
|
1240
|
-
const tfoot = this.createElement('tfoot');
|
|
1241
1187
|
tbodyRows.forEach((row, i) => {
|
|
1242
1188
|
const isRow = row instanceof Element && row.tagName.toLowerCase() === 'tr';
|
|
1243
1189
|
if (isRow) {
|
|
@@ -1250,18 +1196,11 @@ export class JATSExporter {
|
|
|
1250
1196
|
}
|
|
1251
1197
|
thead.appendChild(row);
|
|
1252
1198
|
}
|
|
1253
|
-
else if (i === tbodyRows.length - 1) {
|
|
1254
|
-
tbody?.removeChild(row);
|
|
1255
|
-
tfoot.appendChild(row);
|
|
1256
|
-
}
|
|
1257
1199
|
}
|
|
1258
1200
|
});
|
|
1259
1201
|
if (thead.hasChildNodes()) {
|
|
1260
1202
|
table.insertBefore(thead, tbody);
|
|
1261
1203
|
}
|
|
1262
|
-
if (tfoot.hasChildNodes()) {
|
|
1263
|
-
table.insertBefore(tfoot, tbody);
|
|
1264
|
-
}
|
|
1265
1204
|
};
|
|
1266
1205
|
this.unwrapBody = (body) => {
|
|
1267
1206
|
const container = body.querySelector(':scope > sec[sec-type="body"]');
|
|
@@ -1439,34 +1378,6 @@ export class JATSExporter {
|
|
|
1439
1378
|
return mathml;
|
|
1440
1379
|
}
|
|
1441
1380
|
}
|
|
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
1381
|
buildKeywords(articleMeta) {
|
|
1471
1382
|
const keywordGroups = this.getChildrenOfType(schema.nodes.keyword_group);
|
|
1472
1383
|
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
|
-
|
|
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
|
|
382
|
-
const
|
|
383
|
-
const
|
|
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
|
-
|
|
394
|
-
noteID: rid,
|
|
395
|
-
noteLabel: getTrimmedTextContent(xref) || '',
|
|
396
|
-
});
|
|
378
|
+
footnoteIDs.push(rid);
|
|
397
379
|
break;
|
|
398
380
|
case 'corresp':
|
|
399
|
-
|
|
400
|
-
correspID: rid,
|
|
401
|
-
correspLabel: getTrimmedTextContent(xref) || '',
|
|
402
|
-
});
|
|
381
|
+
correspIDs.push(rid);
|
|
403
382
|
break;
|
|
404
383
|
case 'aff':
|
|
405
|
-
|
|
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
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
isCorresponding: element.getAttribute('corresp')
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
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: () => {
|