@manuscripts/transform 4.5.7 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/cjs/jats/__tests__/jats-exporter.test.js +50 -20
  2. package/dist/cjs/jats/__tests__/jats-importer.test.js +26 -0
  3. package/dist/cjs/jats/__tests__/jats-roundtrip.test.js +6 -1
  4. package/dist/cjs/jats/exporter/JATSExporterBase.js +118 -0
  5. package/dist/cjs/jats/exporter/jats-exporter.js +227 -349
  6. package/dist/cjs/jats/exporter/lib.js +62 -0
  7. package/dist/cjs/jats/importer/jats-dom-parser.js +11 -3
  8. package/dist/cjs/schema/index.js +4 -1
  9. package/dist/cjs/schema/migration/migration-scripts/4.5.9.js +30 -0
  10. package/dist/cjs/schema/migration/migration-scripts/index.js +3 -1
  11. package/dist/cjs/schema/nodes/bibliography_element.js +0 -1
  12. package/dist/cjs/schema/nodes/bio.js +24 -0
  13. package/dist/cjs/schema/nodes/contributor.js +1 -2
  14. package/dist/cjs/schema/nodes/keywords_element.js +0 -1
  15. package/dist/cjs/types.js +1 -1
  16. package/dist/cjs/version.js +1 -1
  17. package/dist/es/jats/__tests__/jats-exporter.test.js +47 -20
  18. package/dist/es/jats/__tests__/jats-importer.test.js +26 -0
  19. package/dist/es/jats/__tests__/jats-roundtrip.test.js +3 -1
  20. package/dist/es/jats/exporter/JATSExporterBase.js +114 -0
  21. package/dist/es/jats/exporter/jats-exporter.js +201 -319
  22. package/dist/es/jats/exporter/lib.js +55 -0
  23. package/dist/es/jats/importer/jats-dom-parser.js +11 -3
  24. package/dist/es/schema/index.js +4 -1
  25. package/dist/es/schema/migration/migration-scripts/4.5.9.js +28 -0
  26. package/dist/es/schema/migration/migration-scripts/index.js +3 -1
  27. package/dist/es/schema/nodes/bibliography_element.js +0 -1
  28. package/dist/es/schema/nodes/bio.js +20 -0
  29. package/dist/es/schema/nodes/contributor.js +1 -2
  30. package/dist/es/schema/nodes/keywords_element.js +0 -1
  31. package/dist/es/types.js +1 -1
  32. package/dist/es/version.js +1 -1
  33. package/dist/types/jats/exporter/JATSExporterBase.d.ts +35 -0
  34. package/dist/types/jats/exporter/jats-exporter.d.ts +23 -19
  35. package/dist/types/jats/exporter/lib.d.ts +23 -0
  36. package/dist/types/schema/index.d.ts +2 -1
  37. package/dist/types/schema/migration/migration-scripts/4.5.9.d.ts +8 -0
  38. package/dist/types/schema/migration/migration-scripts/index.d.ts +3 -2
  39. package/dist/types/schema/nodes/bio.d.ts +10 -0
  40. package/dist/types/schema/types.d.ts +1 -1
  41. package/dist/types/types.d.ts +1 -1
  42. package/dist/types/version.d.ts +1 -1
  43. package/package.json +4 -4
  44. package/src/jats/__tests__/__fixtures__/jats-import.xml +7 -0
  45. package/src/jats/__tests__/__snapshots__/jats-importer.test.ts.snap +272 -151
  46. package/src/jats/__tests__/__snapshots__/jats-roundtrip.test.ts.snap +2 -2
  47. package/src/jats/__tests__/jats-exporter.test.ts +60 -20
  48. package/src/jats/__tests__/jats-importer.test.ts +37 -0
  49. package/src/jats/__tests__/jats-roundtrip.test.ts +3 -1
  50. package/src/jats/exporter/JATSExporterBase.ts +164 -0
  51. package/src/jats/exporter/jats-exporter.ts +217 -386
  52. package/src/jats/exporter/lib.ts +69 -0
  53. package/src/jats/importer/jats-dom-parser.ts +15 -5
  54. package/src/schema/index.ts +4 -1
  55. package/src/schema/migration/migration-scripts/4.5.9.ts +62 -0
  56. package/src/schema/migration/migration-scripts/index.ts +3 -1
  57. package/src/schema/nodes/bibliography_element.ts +0 -1
  58. package/src/schema/nodes/bio.ts +48 -0
  59. package/src/schema/nodes/contributor.ts +1 -2
  60. package/src/schema/nodes/keywords_element.ts +0 -1
  61. package/src/schema/types.ts +1 -0
  62. package/src/types.ts +1 -1
  63. package/src/version.ts +1 -1
@@ -0,0 +1,69 @@
1
+ /*!
2
+ * © 2026 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 { ManuscriptNodeType, schema } from '../../schema'
18
+ import { IDGenerator } from '../types'
19
+
20
+ export const normalizeID = (id: string) => id.replace(/:/g, '_')
21
+
22
+ export const createCounter = () => {
23
+ const counts = new Map<string, number>()
24
+
25
+ return {
26
+ increment: (field: string) => {
27
+ const value = counts.get(field)
28
+ const newValue = value === undefined ? 1 : value + 1
29
+ counts.set(field, newValue)
30
+ return newValue
31
+ },
32
+ }
33
+ }
34
+
35
+ export const createDefaultIDGenerator = (): IDGenerator => {
36
+ const counter = createCounter()
37
+
38
+ return async (element: Element) => {
39
+ const value = String(counter.increment(element.nodeName))
40
+
41
+ return `${element.localName}-${value}`
42
+ }
43
+ }
44
+
45
+ export const chooseRefType = (type: ManuscriptNodeType): string | undefined => {
46
+ switch (type) {
47
+ case schema.nodes.figure:
48
+ case schema.nodes.figure_element:
49
+ return 'fig'
50
+
51
+ case schema.nodes.footnote:
52
+ return 'fn'
53
+
54
+ case schema.nodes.table:
55
+ case schema.nodes.table_element:
56
+ return 'table'
57
+
58
+ case schema.nodes.section:
59
+ case schema.nodes.abstract:
60
+ return 'sec'
61
+
62
+ case schema.nodes.equation:
63
+ case schema.nodes.equation_element:
64
+ return 'disp-formula'
65
+
66
+ case schema.nodes.supplement:
67
+ return 'supplementary-material'
68
+ }
69
+ }
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * © 2020 Atypon Systems LLC
2
+ * © 2026 Atypon Systems LLC
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -525,7 +525,7 @@ export class JATSDOMParser {
525
525
  const affiliationIDs: string[] = []
526
526
  const correspIDs: string[] = []
527
527
 
528
- const xrefs = element.querySelectorAll('xref')
528
+ const xrefs = element.querySelectorAll(':scope > xref')
529
529
  for (const xref of xrefs) {
530
530
  const rid = xref.getAttribute('rid')
531
531
  const type = xref.getAttribute('ref-type')
@@ -572,10 +572,20 @@ export class JATSDOMParser {
572
572
  email: getTrimmedTextContent(element, 'email') || '',
573
573
  }
574
574
  },
575
- getContent: () => {
576
- return Fragment.from(this.schema.text('_'))
575
+ getContent: (node) => {
576
+ const bio = (node as HTMLElement).querySelector('bio')
577
+ if (!bio) {
578
+ return Fragment.empty
579
+ }
580
+ return Fragment.from(
581
+ this.parse(bio, { topNode: this.schema.nodes.bio.create() })
582
+ )
577
583
  },
578
584
  },
585
+ {
586
+ tag: 'bio',
587
+ node: 'bio',
588
+ },
579
589
  {
580
590
  tag: 'affiliations',
581
591
  node: 'affiliations',
@@ -772,7 +782,7 @@ export class JATSDOMParser {
772
782
  label: getTrimmedTextContent(extLinkElement) || undefined,
773
783
  }))
774
784
  .filter((extLink) => extLink.href) // Filter out entries without href
775
-
785
+
776
786
  return {
777
787
  id: element.getAttribute('id'),
778
788
  href: element.getAttributeNS(XLINK_NAMESPACE, 'href'),
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * © 2019 Atypon Systems LLC
2
+ * © 2026 Atypon Systems LLC
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -47,6 +47,7 @@ import { backmatter } from './nodes/backmatter'
47
47
  import { bibliographyElement } from './nodes/bibliography_element'
48
48
  import { bibliographyItem } from './nodes/bibliography_item'
49
49
  import { bibliographySection } from './nodes/bibliography_section'
50
+ import { bio } from './nodes/bio'
50
51
  import { blockquoteElement } from './nodes/blockquote_element'
51
52
  import { body } from './nodes/body'
52
53
  import { box_element } from './nodes/box_element'
@@ -128,6 +129,7 @@ export * from './nodes/awards'
128
129
  export * from './nodes/bibliography_element'
129
130
  export * from './nodes/bibliography_item'
130
131
  export * from './nodes/bibliography_section'
132
+ export * from './nodes/bio'
131
133
  export * from './nodes/blockquote_element'
132
134
  export * from './nodes/box_element'
133
135
  export * from './nodes/caption'
@@ -213,6 +215,7 @@ export const schema = new Schema<Nodes, Marks>({
213
215
  bibliography_element: bibliographyElement,
214
216
  bibliography_section: bibliographySection,
215
217
  blockquote_element: blockquoteElement,
218
+ bio: bio,
216
219
  list: list,
217
220
  caption,
218
221
  caption_title: captionTitle,
@@ -0,0 +1,62 @@
1
+ /*!
2
+ * © 2026 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 { JSONProsemirrorNode } from '../../../types'
17
+ import { MigrationScript } from '../migration-script'
18
+
19
+ /**
20
+ * Nodes that still carried the `contents` attribute inherited from the
21
+ * json-schema era. The attribute was never read for these types and has been
22
+ * removed from their specs.
23
+ */
24
+ const LEGACY_CONTENTS_NODES = new Set([
25
+ 'contributor',
26
+ 'bibliography_element',
27
+ 'keywords_element',
28
+ ])
29
+
30
+ /**
31
+ * - contributor content changed from `inline*` (holding a '_' placeholder text
32
+ * node written by the JATS importer) to `bio?`. Any non-bio content is dropped.
33
+ * - the dead `contents` attribute is removed from the nodes listed above - this won't
34
+ * invalidate the doc actually so it's added only for hygiene
35
+ */
36
+ class Migration459 implements MigrationScript {
37
+ fromVersion = '4.5.8'
38
+ toVersion = '4.5.9'
39
+
40
+ migrateNode(node: JSONProsemirrorNode): JSONProsemirrorNode {
41
+ if (
42
+ LEGACY_CONTENTS_NODES.has(node.type) &&
43
+ node.attrs &&
44
+ 'contents' in node.attrs
45
+ ) {
46
+ const attrs = { ...node.attrs }
47
+ delete attrs.contents
48
+ node = { ...node, attrs }
49
+ }
50
+
51
+ if (node.type === 'contributor') {
52
+ const bio = node.content?.filter((child) => child.type === 'bio')
53
+ const migrated = { ...node }
54
+ delete migrated.content
55
+ return bio?.length ? { ...migrated, content: bio } : migrated
56
+ }
57
+
58
+ return node
59
+ }
60
+ }
61
+
62
+ export default Migration459
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * © 2024 Atypon Systems LLC
2
+ * © 2026 Atypon Systems LLC
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@ import Migration4335 from './4.3.35'
31
31
  import Migration442 from './4.4.2'
32
32
  import Migration447 from './4.4.7'
33
33
  import Migration453 from './4.5.3'
34
+ import Migration459 from './4.5.9'
34
35
 
35
36
  const migrations = [
36
37
  new Migration125(),
@@ -50,6 +51,7 @@ const migrations = [
50
51
  new Migration442(),
51
52
  new Migration447(),
52
53
  new Migration453(),
54
+ new Migration459(),
53
55
  ]
54
56
 
55
57
  export default migrations
@@ -30,7 +30,6 @@ export const bibliographyElement: NodeSpec = {
30
30
  content: 'bibliography_item*',
31
31
  attrs: {
32
32
  id: { default: '' },
33
- contents: { default: '' },
34
33
  dataTracked: { default: null },
35
34
  },
36
35
  selectable: false,
@@ -0,0 +1,48 @@
1
+ /*!
2
+ * © 2023 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 { NodeSpec } from 'prosemirror-model'
17
+
18
+ import { ManuscriptNode } from '../types'
19
+
20
+ export interface BioAttrs {
21
+ id: string
22
+ }
23
+
24
+ export interface BioNode extends ManuscriptNode {
25
+ attrs: BioAttrs
26
+ }
27
+
28
+ export const bio: NodeSpec = {
29
+ content: 'image_element? paragraph',
30
+ attrs: {
31
+ id: { default: '' },
32
+ dataTracked: { default: null },
33
+ },
34
+ group: 'block',
35
+ toDOM: (node) => {
36
+ const bioNode = node as BioNode
37
+ return [
38
+ 'div',
39
+ {
40
+ class: 'bio',
41
+ id: bioNode.attrs.id,
42
+ },
43
+ 0,
44
+ ]
45
+ },
46
+ }
47
+ export const isBioNode = (node: ManuscriptNode): node is BioNode =>
48
+ node.type === node.type.schema.nodes.bio
@@ -47,7 +47,7 @@ export interface ContributorNode extends ManuscriptNode {
47
47
  }
48
48
 
49
49
  export const contributor: NodeSpec = {
50
- content: 'inline*',
50
+ content: 'bio?',
51
51
  atom: true,
52
52
  attrs: {
53
53
  id: { default: '' },
@@ -68,7 +68,6 @@ export const contributor: NodeSpec = {
68
68
  priority: { default: undefined },
69
69
  creditRoles: { default: [] },
70
70
  dataTracked: { default: null },
71
- contents: { default: '' },
72
71
  },
73
72
  group: 'block',
74
73
  toDOM: (node) => {
@@ -32,7 +32,6 @@ export const keywordsElement: NodeSpec = {
32
32
  content: 'keyword_group*',
33
33
  attrs: {
34
34
  id: { default: '' },
35
- contents: { default: '' },
36
35
  dataTracked: { default: null },
37
36
  },
38
37
  group: 'block element',
@@ -54,6 +54,7 @@ export type Nodes =
54
54
  | 'bibliography_element'
55
55
  | 'bibliography_section'
56
56
  | 'blockquote_element'
57
+ | 'bio'
57
58
  | 'quote_image'
58
59
  | 'list'
59
60
  | 'caption'
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * © 2019 Atypon Systems LLC
2
+ * © 2026 Atypon Systems LLC
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = "4.5.7";
1
+ export const VERSION = "4.6.0";