@manuscripts/transform 4.3.53 → 4.4.1

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 (196) hide show
  1. package/dist/cjs/jats/__tests__/jats-roundtrip.test.js +3 -3
  2. package/dist/cjs/jats/exporter/jats-exporter.js +3 -0
  3. package/dist/cjs/jats/importer/jats-dom-parser.js +41 -1
  4. package/dist/cjs/schema/index.js +9 -0
  5. package/dist/cjs/schema/nodes/headshot_element.js +38 -0
  6. package/dist/cjs/schema/nodes/headshot_grid.js +37 -0
  7. package/dist/cjs/schema/nodes/headshot_image.js +51 -0
  8. package/dist/cjs/transformer/node-names.js +2 -0
  9. package/dist/cjs/transformer/node-title.js +6 -0
  10. package/dist/cjs/version.js +1 -1
  11. package/dist/es/jats/__tests__/jats-roundtrip.test.js +3 -3
  12. package/dist/es/jats/exporter/jats-exporter.js +3 -0
  13. package/dist/es/jats/importer/jats-dom-parser.js +41 -1
  14. package/dist/es/schema/index.js +9 -0
  15. package/dist/es/schema/nodes/headshot_element.js +34 -0
  16. package/dist/es/schema/nodes/headshot_grid.js +33 -0
  17. package/dist/es/schema/nodes/headshot_image.js +48 -0
  18. package/dist/es/transformer/node-names.js +2 -0
  19. package/dist/es/transformer/node-title.js +6 -0
  20. package/dist/es/version.js +1 -1
  21. package/dist/types/jats/__tests__/utils.d.ts +1 -1
  22. package/dist/types/schema/index.d.ts +3 -0
  23. package/dist/types/schema/nodes/headshot_element.d.ts +25 -0
  24. package/dist/types/schema/nodes/headshot_grid.d.ts +24 -0
  25. package/dist/types/schema/nodes/headshot_image.d.ts +26 -0
  26. package/dist/types/schema/types.d.ts +1 -1
  27. package/dist/types/version.d.ts +1 -1
  28. package/package.json +22 -21
  29. package/src/errors.ts +28 -0
  30. package/src/getVersion.ts +21 -0
  31. package/src/index.ts +28 -0
  32. package/src/jats/__tests__/__fixtures__/debug-example.xml +136 -0
  33. package/src/jats/__tests__/__fixtures__/jats-abstract-no-body.xml +163 -0
  34. package/src/jats/__tests__/__fixtures__/jats-citations.xml +472 -0
  35. package/src/jats/__tests__/__fixtures__/jats-comments.xml +46 -0
  36. package/src/jats/__tests__/__fixtures__/jats-document.xml +134 -0
  37. package/src/jats/__tests__/__fixtures__/jats-example-doc.xml +1235 -0
  38. package/src/jats/__tests__/__fixtures__/jats-example-front-only.xml +26 -0
  39. package/src/jats/__tests__/__fixtures__/jats-example-full.xml +209 -0
  40. package/src/jats/__tests__/__fixtures__/jats-example-no-back.xml +156 -0
  41. package/src/jats/__tests__/__fixtures__/jats-example-no-body.xml +91 -0
  42. package/src/jats/__tests__/__fixtures__/jats-example.xml +221 -0
  43. package/src/jats/__tests__/__fixtures__/jats-fn-group.xml +60 -0
  44. package/src/jats/__tests__/__fixtures__/jats-import-no-refs.xml +1077 -0
  45. package/src/jats/__tests__/__fixtures__/jats-import.xml +1578 -0
  46. package/src/jats/__tests__/__fixtures__/jats-roundtrip.xml +133 -0
  47. package/src/jats/__tests__/__fixtures__/jats-tables-example.xml +2043 -0
  48. package/src/jats/__tests__/__fixtures__/math-fragment.xml +12 -0
  49. package/src/jats/__tests__/__snapshots__/citeproc.test.ts.snap +57 -0
  50. package/src/jats/__tests__/__snapshots__/create-article-node.test.ts.snap +65 -0
  51. package/src/jats/__tests__/__snapshots__/jats-exporter.test.ts.snap +7 -0
  52. package/src/jats/__tests__/__snapshots__/jats-importer.test.ts.snap +59796 -0
  53. package/src/jats/__tests__/__snapshots__/jats-roundtrip.test.ts.snap +18 -0
  54. package/src/jats/__tests__/citations.ts +25 -0
  55. package/src/jats/__tests__/citeproc.test.ts +195 -0
  56. package/src/jats/__tests__/create-article-node.test.ts +29 -0
  57. package/src/jats/__tests__/data/section-categories.ts +212 -0
  58. package/src/jats/__tests__/files.ts +24 -0
  59. package/src/jats/__tests__/jats-exporter.test.ts +223 -0
  60. package/src/jats/__tests__/jats-importer.test.ts +567 -0
  61. package/src/jats/__tests__/jats-roundtrip.test.ts +66 -0
  62. package/src/jats/__tests__/utils.ts +90 -0
  63. package/src/jats/exporter/citeproc.ts +265 -0
  64. package/src/jats/exporter/jats-exporter.ts +2093 -0
  65. package/src/jats/exporter/jats-versions.ts +50 -0
  66. package/src/jats/exporter/labels.ts +101 -0
  67. package/src/jats/importer/create-article-node.ts +52 -0
  68. package/src/jats/importer/jats-comments.ts +111 -0
  69. package/src/jats/importer/jats-dom-parser.ts +1306 -0
  70. package/src/jats/importer/jats-parser-utils.ts +234 -0
  71. package/src/jats/importer/jats-transformations.ts +591 -0
  72. package/src/jats/importer/parse-jats-article.ts +106 -0
  73. package/src/jats/index.ts +21 -0
  74. package/src/jats/types.ts +16 -0
  75. package/src/lib/__tests__/footnotes.test.ts +36 -0
  76. package/src/lib/citeproc.ts +30 -0
  77. package/src/lib/credit-roles.ts +91 -0
  78. package/src/lib/deafults.ts +17 -0
  79. package/src/lib/footnotes.ts +85 -0
  80. package/src/lib/html.ts +56 -0
  81. package/src/lib/section-categories.ts +27 -0
  82. package/src/lib/utils.ts +145 -0
  83. package/src/lib/xml.ts +28 -0
  84. package/src/schema/__tests__/docs.ts +1911 -0
  85. package/src/schema/__tests__/groups.test.ts +61 -0
  86. package/src/schema/__tests__/migration.test.ts +23 -0
  87. package/src/schema/groups.ts +36 -0
  88. package/src/schema/index.ts +295 -0
  89. package/src/schema/marks.ts +254 -0
  90. package/src/schema/migration/migrate.ts +77 -0
  91. package/src/schema/migration/migration-script.ts +26 -0
  92. package/src/schema/migration/migration-scripts/1.2.5.ts +44 -0
  93. package/src/schema/migration/migration-scripts/2.3.22.ts +52 -0
  94. package/src/schema/migration/migration-scripts/3.0.12.ts +33 -0
  95. package/src/schema/migration/migration-scripts/3.0.21.ts +50 -0
  96. package/src/schema/migration/migration-scripts/3.0.30.ts +65 -0
  97. package/src/schema/migration/migration-scripts/3.0.31.ts +40 -0
  98. package/src/schema/migration/migration-scripts/3.0.41.ts +37 -0
  99. package/src/schema/migration/migration-scripts/3.0.55.ts +42 -0
  100. package/src/schema/migration/migration-scripts/3.0.56.ts +114 -0
  101. package/src/schema/migration/migration-scripts/4.2.13.ts +37 -0
  102. package/src/schema/migration/migration-scripts/4.2.15.ts +48 -0
  103. package/src/schema/migration/migration-scripts/4.3.23.ts +55 -0
  104. package/src/schema/migration/migration-scripts/4.3.34.ts +132 -0
  105. package/src/schema/migration/migration-scripts/4.3.35.ts +41 -0
  106. package/src/schema/migration/migration-scripts/index.ts +49 -0
  107. package/src/schema/nodes/abstracts.ts +29 -0
  108. package/src/schema/nodes/affiliation.ts +88 -0
  109. package/src/schema/nodes/affiliations.ts +30 -0
  110. package/src/schema/nodes/alt_text.ts +36 -0
  111. package/src/schema/nodes/alt_title.ts +40 -0
  112. package/src/schema/nodes/alt_titles_section.ts +58 -0
  113. package/src/schema/nodes/attachment.ts +46 -0
  114. package/src/schema/nodes/attachments.ts +45 -0
  115. package/src/schema/nodes/attribution.ts +38 -0
  116. package/src/schema/nodes/author_notes.ts +44 -0
  117. package/src/schema/nodes/award.ts +52 -0
  118. package/src/schema/nodes/awards.ts +45 -0
  119. package/src/schema/nodes/backmatter.ts +31 -0
  120. package/src/schema/nodes/bibliography_element.ts +58 -0
  121. package/src/schema/nodes/bibliography_item.ts +108 -0
  122. package/src/schema/nodes/bibliography_section.ts +60 -0
  123. package/src/schema/nodes/blockquote_element.ts +79 -0
  124. package/src/schema/nodes/body.ts +29 -0
  125. package/src/schema/nodes/box_element.ts +67 -0
  126. package/src/schema/nodes/caption.ts +67 -0
  127. package/src/schema/nodes/caption_title.ts +67 -0
  128. package/src/schema/nodes/citation.ts +70 -0
  129. package/src/schema/nodes/comment.ts +50 -0
  130. package/src/schema/nodes/comments.ts +28 -0
  131. package/src/schema/nodes/contributor.ts +87 -0
  132. package/src/schema/nodes/contributors.ts +40 -0
  133. package/src/schema/nodes/core_section.ts +27 -0
  134. package/src/schema/nodes/corresp.ts +49 -0
  135. package/src/schema/nodes/cross_reference.ts +64 -0
  136. package/src/schema/nodes/doc.ts +21 -0
  137. package/src/schema/nodes/embed.ts +55 -0
  138. package/src/schema/nodes/equation.ts +65 -0
  139. package/src/schema/nodes/equation_element.ts +61 -0
  140. package/src/schema/nodes/figure.ts +65 -0
  141. package/src/schema/nodes/figure_element.ts +73 -0
  142. package/src/schema/nodes/footnote.ts +95 -0
  143. package/src/schema/nodes/footnotes_element.ts +69 -0
  144. package/src/schema/nodes/footnotes_section.ts +61 -0
  145. package/src/schema/nodes/general_table_footnote.ts +42 -0
  146. package/src/schema/nodes/graphical_abstract_section.ts +62 -0
  147. package/src/schema/nodes/hard_break.ts +36 -0
  148. package/src/schema/nodes/headshot_element.ts +48 -0
  149. package/src/schema/nodes/headshot_grid.ts +46 -0
  150. package/src/schema/nodes/headshot_image.ts +65 -0
  151. package/src/schema/nodes/hero_image.ts +46 -0
  152. package/src/schema/nodes/highlight_marker.ts +68 -0
  153. package/src/schema/nodes/image_element.ts +49 -0
  154. package/src/schema/nodes/inline_equation.ts +68 -0
  155. package/src/schema/nodes/inline_footnote.ts +66 -0
  156. package/src/schema/nodes/keyword.ts +61 -0
  157. package/src/schema/nodes/keyword_group.ts +63 -0
  158. package/src/schema/nodes/keywords.ts +59 -0
  159. package/src/schema/nodes/keywords_element.ts +64 -0
  160. package/src/schema/nodes/link.ts +79 -0
  161. package/src/schema/nodes/list.ts +134 -0
  162. package/src/schema/nodes/listing.ts +91 -0
  163. package/src/schema/nodes/listing_element.ts +61 -0
  164. package/src/schema/nodes/long_desc.ts +36 -0
  165. package/src/schema/nodes/manuscript.ts +86 -0
  166. package/src/schema/nodes/missing_figure.ts +59 -0
  167. package/src/schema/nodes/paragraph.ts +77 -0
  168. package/src/schema/nodes/placeholder.ts +62 -0
  169. package/src/schema/nodes/placeholder_element.ts +60 -0
  170. package/src/schema/nodes/pullquote_element.ts +81 -0
  171. package/src/schema/nodes/quote_image.ts +64 -0
  172. package/src/schema/nodes/section.ts +69 -0
  173. package/src/schema/nodes/section_label.ts +39 -0
  174. package/src/schema/nodes/section_title.ts +58 -0
  175. package/src/schema/nodes/subtitle.ts +40 -0
  176. package/src/schema/nodes/subtitles.ts +51 -0
  177. package/src/schema/nodes/supplement.ts +77 -0
  178. package/src/schema/nodes/supplements.ts +60 -0
  179. package/src/schema/nodes/table.ts +144 -0
  180. package/src/schema/nodes/table_col.ts +76 -0
  181. package/src/schema/nodes/table_element.ts +67 -0
  182. package/src/schema/nodes/table_element_footer.ts +42 -0
  183. package/src/schema/nodes/text.ts +31 -0
  184. package/src/schema/nodes/title.ts +43 -0
  185. package/src/schema/nodes/trans_abstract.ts +58 -0
  186. package/src/schema/nodes/trans_graphical_abstract.ts +67 -0
  187. package/src/schema/types.ts +243 -0
  188. package/src/tests.ts +33 -0
  189. package/src/transformer/id.ts +23 -0
  190. package/src/transformer/index.ts +21 -0
  191. package/src/transformer/node-names.ts +75 -0
  192. package/src/transformer/node-title.ts +116 -0
  193. package/src/transformer/node-types.ts +39 -0
  194. package/src/transformer/node-validator.ts +82 -0
  195. package/src/types.ts +25 -0
  196. package/src/version.ts +1 -0
@@ -0,0 +1,90 @@
1
+ /*!
2
+ * © 2024 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
+
17
+ import { Node, NodeType } from 'prosemirror-model'
18
+ import { findChildrenByType } from 'prosemirror-utils'
19
+
20
+ import { isCommentNode, isContributorNode, ManuscriptNode } from '../../schema'
21
+ import { parseJATSArticle } from '../importer/parse-jats-article'
22
+ import { sectionCategories } from './data/section-categories'
23
+ import { readAndParseFixture } from './files'
24
+
25
+ export const createNodeFromJATS = async (fileName: string) => {
26
+ const jats = await readAndParseFixture(fileName)
27
+ return parseJATSArticle(jats, sectionCategories)
28
+ }
29
+
30
+ const uuidRegex =
31
+ /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/g
32
+ const replaceUUIDWithTest = (input: string) => input.replace(uuidRegex, 'test')
33
+
34
+ const updateContributorNodeIDs = (node: ManuscriptNode) => {
35
+ if (isContributorNode(node)) {
36
+ node.attrs.footnoteIDs = node.attrs.footnoteIDs?.map((id) =>
37
+ replaceUUIDWithTest(id)
38
+ )
39
+ node.attrs.correspIDs = node.attrs.correspIDs?.map((id) =>
40
+ replaceUUIDWithTest(id)
41
+ )
42
+ node.attrs.affiliationIDs = node.attrs.affiliationIDs?.map((id) =>
43
+ replaceUUIDWithTest(id)
44
+ )
45
+ }
46
+ }
47
+
48
+ const updateCommentNodeIDs = (node: ManuscriptNode) => {
49
+ if (isCommentNode(node)) {
50
+ node.attrs.target = replaceUUIDWithTest(node.attrs.target)
51
+ node.attrs.timestamp = 1234
52
+ }
53
+ }
54
+
55
+ const updateNodeRID = (node: ManuscriptNode) => {
56
+ if (node.attrs.rid) {
57
+ //@ts-ignore
58
+ node.attrs.rid = replaceUUIDWithTest(node.attrs.rid)
59
+ }
60
+ }
61
+ const updateNodeRIDs = (node: ManuscriptNode) => {
62
+ if (node.attrs.rids) {
63
+ //@ts-ignore
64
+ node.attrs.rids = node.attrs.rids.map((rid) => replaceUUIDWithTest(rid))
65
+ }
66
+ }
67
+
68
+ export const changeIDs = (node: ManuscriptNode) => {
69
+ updateNodeID(node)
70
+ node.descendants((child) => {
71
+ updateNodeID(child)
72
+ updateNodeRID(child)
73
+ updateNodeRIDs(child)
74
+ updateContributorNodeIDs(child)
75
+ updateCommentNodeIDs(child)
76
+ })
77
+ }
78
+
79
+ export const findNodesByType = (node: Node, type: NodeType, descend = true) => {
80
+ return findChildrenByType(node, type, descend).map((n) => n.node)
81
+ }
82
+ export const findNodeByType = (node: Node, type: NodeType, descend = true) =>
83
+ findNodesByType(node, type, descend)[0]
84
+
85
+ export const updateNodeID = (node: ManuscriptNode) => {
86
+ if (node.attrs.id) {
87
+ //@ts-ignore
88
+ node.attrs.id = replaceUUIDWithTest(node.attrs.id)
89
+ }
90
+ }
@@ -0,0 +1,265 @@
1
+ /*!
2
+ * © 2025 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
+ //@ts-nocheck
17
+
18
+ import Citeproc from 'citeproc'
19
+
20
+ import { BibliographyItemAttrs } from '../../schema'
21
+
22
+ const normalizeID = (id: string) => id.replace(/:/g, '_')
23
+ const labelOnly = /^<label>.+<\/label>$/
24
+
25
+ /**
26
+ * This is a hacky way to add JATS support to citeproc-js
27
+ */
28
+ export const initJats = () => {
29
+ // make sure initialization happens once
30
+ if (Citeproc.Output.Formats.jats) {
31
+ return
32
+ }
33
+ // This defines a new citeproc "format". There is no real documentation
34
+ // for this, so the html format was copied and modified.
35
+ Citeproc.Output.Formats.jats = {
36
+ ...Citeproc.Output.Formats.html,
37
+ text_escape: function (text) {
38
+ return text ?? ''
39
+ },
40
+ bibstart: '<ref-list>',
41
+ bibend: '</ref-list>',
42
+ '@font-style/italic': '<italic>%%STRING%%</italic>',
43
+ '@font-style/oblique': '<italic>%%STRING%%</italic>',
44
+ '@font-style/normal': false,
45
+ '@font-variant/small-caps': '<smallcaps>%%STRING%%</smallcaps>',
46
+ '@font-variant/normal': false,
47
+ '@font-weight/bold': '<bold>%%STRING%%</bold>',
48
+ '@font-weight/normal': false,
49
+ '@font-weight/light': false,
50
+ '@text-decoration/none': false,
51
+ '@text-decoration/underline': '<underline>%%STRING%%</underline>',
52
+ '@vertical-align/sup': '<sup>%%STRING%%</sup>',
53
+ '@vertical-align/sub': '<sub>%%STRING%%</sub>',
54
+ '@vertical-align/baseline': false,
55
+ // this is the entry point for rendering bibliography items. The "str" arg
56
+ // will be the formatted bibliography item.
57
+ '@bibliography/entry': function (state, str) {
58
+ // the id of the bibliography item
59
+ const id = this.system_id
60
+ // get the bibliography item from the internal citeproc registry
61
+ const item: BibliographyItemAttrs = state.registry.registry[id].ref
62
+ const type = getPublicationType(item)
63
+ str = str.trim()
64
+ if (labelOnly.test(str)) {
65
+ // If only a <label> is present in str, use the "literal" value of the
66
+ // item. This is usually the case for "unstructured" references, where
67
+ // no individual metadata is tagged. Since str includes the label, it's
68
+ // placed before the <mixed-citation> tag.
69
+ return `<ref id="${normalizeID(
70
+ id
71
+ )}">${str}<mixed-citation specific-use="unstructured-citation">${
72
+ item.literal
73
+ }</mixed-citation></ref>`
74
+ } else if (str.includes('mixed-citation')) {
75
+ // For citation styles that include a label (e.g. AMA), citeproc-js will
76
+ // invoke both @display/left-margin and @display/right-inline, meaning
77
+ // that str will include a <mixed-citation> tag. In that case, only the
78
+ // <ref> tag needs to be added.
79
+ return `<ref id="${normalizeID(id)}">${str.replace(
80
+ '%%TYPE%%',
81
+ type
82
+ )}</ref>`
83
+ } else {
84
+ // For citation styles that do not include a label (e.g. Chicago Author),
85
+ // citeproc-js will invoke neither @display/left-margin nor
86
+ // @display/right-inline, meaning that str will not include a
87
+ // <mixed-citation> tag. In that case, both <ref> and <mixed-citation>
88
+ // need to be added.
89
+ return `<ref id="${normalizeID(
90
+ id
91
+ )}"><mixed-citation publication-type="${type}">${str}</mixed-citation></ref>`
92
+ }
93
+ },
94
+ '@display/block': false,
95
+ '@display/left-margin': function (state, str) {
96
+ return `<label>${str}</label>`
97
+ },
98
+ '@display/right-inline': function (state, str) {
99
+ // this function doesn't have access to the metadat, so it's not possible
100
+ // to determine the publication type here. Instead, a placeholder is used
101
+ // and replaced in the @bibliography/entry function.
102
+ return `<mixed-citation publication-type="%%TYPE%%">${str}</mixed-citation>`
103
+ },
104
+ '@display/indent': false,
105
+ '@URL/true': false,
106
+ '@DOI/true': false,
107
+ }
108
+
109
+ // This overrides how a person name is rendered and wraps it in
110
+ // a <string-name> tag.
111
+ const name = Citeproc.NameOutput.prototype._renderOnePersonalName
112
+ Citeproc.NameOutput.prototype._renderOnePersonalName = function (...args) {
113
+ const area = this.state.tmp.area
114
+ const blob = name.call(this, ...args)
115
+ if (blob && area === 'bibliography') {
116
+ blob.strings.prefix = '<string-name>'
117
+ blob.strings.suffix = '</string-name>'
118
+ }
119
+ return blob
120
+ }
121
+
122
+ // This overrides how the given name of a person is rendered
123
+ // and wraps it in a <given-names> tag.
124
+ const given = Citeproc.NameOutput.prototype._givenName
125
+ Citeproc.NameOutput.prototype._givenName = function (...args) {
126
+ const area = this.state.tmp.area
127
+ const info = given.call(this, ...args)
128
+ if (info.blob && area === 'bibliography') {
129
+ info.blob.strings.prefix = '<given-names>'
130
+ info.blob.strings.suffix = '</given-names>'
131
+ }
132
+ return info
133
+ }
134
+
135
+ // This overrides how the family name of a person is rendered
136
+ // and wraps it in a <surname> tag.
137
+ const family = Citeproc.NameOutput.prototype._familyName
138
+ Citeproc.NameOutput.prototype._familyName = function (...args) {
139
+ const area = this.state.tmp.area
140
+ const blob = family.call(this, ...args)
141
+ if (blob && area === 'bibliography') {
142
+ blob.strings.prefix = '<surname>'
143
+ blob.strings.suffix = '</surname>'
144
+ }
145
+ return blob
146
+ }
147
+ }
148
+
149
+ const namesWrapper = (type: string) => (str: string) =>
150
+ `<person-group person-group-type="${type}">${str}</person-group>`
151
+
152
+ // Even though the CSL data model specifies a date type, citeproc-js processes
153
+ // date fields and replaces their value with an object with the structure:
154
+ // {
155
+ // year: number
156
+ // month: number
157
+ // day: number
158
+ // }
159
+ // see CSL.Engine.prototype.dateParseArray for more details.
160
+ const formatDate = (date) => {
161
+ let output = date.year
162
+ if (date.month) {
163
+ output += '-' + String(date.month).padStart(2, '0')
164
+ if (date.day) {
165
+ output += '-' + String(date.day).padStart(2, '0')
166
+ }
167
+ }
168
+ return output
169
+ }
170
+
171
+ const getPublicationType = (item: BibliographyItemAttrs) => {
172
+ switch (item.type) {
173
+ case 'article-journal':
174
+ return 'journal'
175
+ case 'webpage':
176
+ return 'page'
177
+ case 'dataset':
178
+ return 'data'
179
+ default:
180
+ return item.type
181
+ }
182
+ }
183
+
184
+ const wrappers = {
185
+ // this is a name field, so other processing is required. See the "initJats"
186
+ // function for more info.
187
+ author: namesWrapper('author'),
188
+ // Unlike other date fields, where a formatted date string is wrapped in
189
+ // a tag with the "iso-8601-date" attribute, the "issued" date components
190
+ // are individually wrapped in year/month/day tags. For the time being,
191
+ // only the year component is processed.
192
+ issued: (str: string, item: BibliographyItemAttrs) =>
193
+ str.replace(item.issued.year, `<year>${item.issued.year}</year>`),
194
+ 'container-title': (str: string) => `<source>${str}</source>`,
195
+ volume: (str: string) => `<volume>${str}</volume>`,
196
+ issue: (str: string) => `<issue>${str}</issue>`,
197
+ supplement: (str: string) => `<supplement>${str}</supplement>`,
198
+ page: (str: string) => {
199
+ const parts = str.split(/([-–])/)
200
+ if (parts.length === 3) {
201
+ const fpage = parts[0].trim()
202
+ const separator = parts[1].trim()
203
+ const lpage = parts[2].trim()
204
+ return `<fpage>${fpage}</fpage>${separator}<lpage>${lpage}</lpage>`
205
+ }
206
+ return `<fpage>${str.trim()}</fpage>`
207
+ },
208
+ title: (str: string, item: BibliographyItemAttrs) => {
209
+ const type = item.type
210
+ switch (type) {
211
+ case 'dataset':
212
+ return `<data-title>${str}</data-title>`
213
+ case 'article-journal':
214
+ case 'preprint':
215
+ return `<article-title>${str}</article-title>`
216
+ default:
217
+ return `<part-title>${str}</part-title>`
218
+ }
219
+ },
220
+ std: (str: string) => `<pub-id pub-id-type="std-designation">${str}</pub-id>`,
221
+ 'collection-title': (str: string) => `<series>${str}</series>`,
222
+ edition: (str: string) => `<edition>${str}</edition>`,
223
+ publisher: (str: string) => `<publisher-name>${str}</publisher-name>`,
224
+ 'publisher-place': (str: string) => `<publisher-loc>${str}</publisher-loc>`,
225
+ event: (str: string) => `<conf-name>${str}</conf-name>`,
226
+ 'event-place': (str: string) => `<conf-loc>${str}</conf-loc>`,
227
+ 'number-of-pages': (str: string) => `<size units="pages">${str}</size>`,
228
+ institution: (str: string) => `<institution>${str}</institution>`,
229
+ locator: (str: string) => `<elocation-id>${str}</elocation-id>`,
230
+ // this is a name field, so other processing is required. See the "initJats"
231
+ // function for more info.
232
+ editor: namesWrapper('editor'),
233
+ accessed: (str: string, item: BibliographyItemAttrs) =>
234
+ `<date-in-citation content-type="access-date" iso-8601-date="${formatDate(
235
+ item.accessed
236
+ )}">${str}</date-in-citation>`,
237
+ 'event-date': (str: string, item: BibliographyItemAttrs) =>
238
+ `<conf-date iso-8601-date="${formatDate(
239
+ item['event-date']
240
+ )}">${str}</conf-date>`,
241
+ DOI: (str: string) => `<pub-id pub-id-type="doi">${str}</pub-id>`,
242
+ URL: (str: string) =>
243
+ `<ext-link ext-link-type="uri" xlink:href="${str}">${str}</ext-link>`,
244
+ }
245
+
246
+ /**
247
+ * A function that formats the CSL variables into JATS. This is a simple operation
248
+ * in most cases: the passed string is wrapped with the appropriate tag
249
+ * as is. However, some variables require special handling.
250
+ */
251
+ export const jatsVariableWrapper: Citeproc.VariableWrapper = (
252
+ params,
253
+ pre,
254
+ str,
255
+ post
256
+ ) => {
257
+ if (str && params.context === 'bibliography') {
258
+ const name = params.variableNames[0]
259
+ const fn = wrappers[name]
260
+ if (fn) {
261
+ str = fn(str, params.itemData)
262
+ }
263
+ }
264
+ return `${pre}${str ?? ''}${post}`
265
+ }