@manuscripts/transform 4.4.0 → 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 (38) hide show
  1. package/dist/cjs/jats/exporter/jats-exporter.js +3 -0
  2. package/dist/cjs/jats/importer/jats-dom-parser.js +41 -1
  3. package/dist/cjs/schema/index.js +9 -0
  4. package/dist/cjs/schema/nodes/headshot_element.js +38 -0
  5. package/dist/cjs/schema/nodes/headshot_grid.js +37 -0
  6. package/dist/cjs/schema/nodes/headshot_image.js +51 -0
  7. package/dist/cjs/transformer/node-names.js +2 -0
  8. package/dist/cjs/transformer/node-title.js +6 -0
  9. package/dist/cjs/version.js +1 -1
  10. package/dist/es/jats/exporter/jats-exporter.js +3 -0
  11. package/dist/es/jats/importer/jats-dom-parser.js +41 -1
  12. package/dist/es/schema/index.js +9 -0
  13. package/dist/es/schema/nodes/headshot_element.js +34 -0
  14. package/dist/es/schema/nodes/headshot_grid.js +33 -0
  15. package/dist/es/schema/nodes/headshot_image.js +48 -0
  16. package/dist/es/transformer/node-names.js +2 -0
  17. package/dist/es/transformer/node-title.js +6 -0
  18. package/dist/es/version.js +1 -1
  19. package/dist/types/schema/index.d.ts +3 -0
  20. package/dist/types/schema/nodes/headshot_element.d.ts +25 -0
  21. package/dist/types/schema/nodes/headshot_grid.d.ts +24 -0
  22. package/dist/types/schema/nodes/headshot_image.d.ts +26 -0
  23. package/dist/types/schema/types.d.ts +1 -1
  24. package/dist/types/version.d.ts +1 -1
  25. package/package.json +1 -1
  26. package/src/jats/__tests__/__fixtures__/jats-import.xml +17 -0
  27. package/src/jats/__tests__/__snapshots__/jats-importer.test.ts.snap +191 -0
  28. package/src/jats/__tests__/__snapshots__/jats-roundtrip.test.ts.snap +1 -1
  29. package/src/jats/exporter/jats-exporter.ts +3 -0
  30. package/src/jats/importer/jats-dom-parser.ts +47 -1
  31. package/src/schema/index.ts +10 -1
  32. package/src/schema/nodes/headshot_element.ts +48 -0
  33. package/src/schema/nodes/headshot_grid.ts +46 -0
  34. package/src/schema/nodes/headshot_image.ts +65 -0
  35. package/src/schema/types.ts +3 -0
  36. package/src/transformer/node-names.ts +2 -0
  37. package/src/transformer/node-title.ts +5 -0
  38. package/src/version.ts +1 -1
@@ -658,7 +658,7 @@ export class JATSDOMParser {
658
658
  {
659
659
  tag: 'caption',
660
660
  node: 'caption',
661
- context: 'listing_element/|embed/|supplement/',
661
+ context: 'listing_element/|embed/|supplement/|headshot_element/',
662
662
  getContent: (node) => {
663
663
  const element = node as HTMLElement
664
664
  const title = element.querySelector('title')
@@ -788,6 +788,48 @@ export class JATSDOMParser {
788
788
  }
789
789
  },
790
790
  },
791
+ {
792
+ tag: 'graphic',
793
+ node: 'headshot_image',
794
+ context: 'headshot_element/',
795
+ getAttrs: this.getFigAttrs,
796
+ },
797
+ {
798
+ tag: 'graphic',
799
+ node: 'headshot_element',
800
+ context: 'headshot_grid/',
801
+ getContent: (node) => {
802
+ const element = node as HTMLElement
803
+
804
+ const innerGraphic = element.cloneNode(false) as HTMLElement
805
+
806
+ // build wrapper: [graphic(shallow), caption, alt-text, long-desc]
807
+ const wrapper = element.ownerDocument!.createElement('div')
808
+ wrapper.appendChild(innerGraphic)
809
+
810
+ const caption = element.querySelector('caption')
811
+ if (caption) wrapper.appendChild(caption)
812
+
813
+ const altText = element.querySelector('alt-text')
814
+ if (altText) {
815
+ if (altText.childNodes.length === 0) {
816
+ // fill empty alt-text with `caption > title` content
817
+ const title = caption?.querySelector(':scope > title')
818
+ if (title) {
819
+ altText.append(...Array.from(title.childNodes).map(n => n.cloneNode(true)))
820
+ }
821
+ }
822
+ wrapper.appendChild(altText)
823
+ }
824
+
825
+ const longDesc = element.querySelector('long-desc')
826
+ if (longDesc) wrapper.appendChild(longDesc)
827
+
828
+ return this.parse(wrapper, {
829
+ topNode: this.schema.nodes.headshot_element.create(),
830
+ }).content
831
+ }
832
+ },
791
833
  {
792
834
  tag: 'graphic[specific-use=MISSING]',
793
835
  node: 'missing_figure',
@@ -920,6 +962,10 @@ export class JATSDOMParser {
920
962
  tag: 'list-item',
921
963
  node: 'list_item',
922
964
  },
965
+ {
966
+ tag: 'p[content-type="headshots"]',
967
+ node: 'headshot_grid',
968
+ },
923
969
  {
924
970
  tag: 'p',
925
971
  node: 'paragraph',
@@ -71,6 +71,9 @@ import { generalTableFootnote } from './nodes/general_table_footnote'
71
71
  import { graphicalAbstractSection } from './nodes/graphical_abstract_section'
72
72
  import { hardBreak } from './nodes/hard_break'
73
73
  import { heroImage } from './nodes/hero_image'
74
+ import { headshotGrid } from './nodes/headshot_grid'
75
+ import { headshotElement } from './nodes/headshot_element'
76
+ import { headshotImage } from './nodes/headshot_image'
74
77
  import { highlightMarker } from './nodes/highlight_marker'
75
78
  import { imageElement } from './nodes/image_element'
76
79
  import { inlineEquation } from './nodes/inline_equation'
@@ -147,6 +150,9 @@ export * from './nodes/general_table_footnote'
147
150
  export * from './nodes/graphical_abstract_section'
148
151
  export * from './nodes/hard_break'
149
152
  export * from './nodes/hero_image'
153
+ export * from './nodes/headshot_grid'
154
+ export * from './nodes/headshot_element'
155
+ export * from './nodes/headshot_image'
150
156
  export * from './nodes/highlight_marker'
151
157
  export * from './nodes/image_element'
152
158
  export * from './nodes/inline_equation'
@@ -277,10 +283,13 @@ export const schema = new Schema<Nodes, Marks>({
277
283
  long_desc: longDesc,
278
284
  quote_image: quoteImage,
279
285
  hero_image: heroImage,
286
+ headshot_grid: headshotGrid,
287
+ headshot_element: headshotElement,
288
+ headshot_image: headshotImage,
280
289
  trans_abstract: transAbstract,
281
290
  trans_graphical_abstract: transGraphicalAbstract,
282
291
  subtitle: subtitle,
283
292
  subtitles: subtitles,
284
293
  },
285
294
  })
286
- /**/
295
+
@@ -0,0 +1,48 @@
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 { NodeSpec } from 'prosemirror-model'
18
+
19
+ import { ManuscriptNode } from '../types'
20
+
21
+ export interface HeadshotElementNode extends ManuscriptNode {
22
+ attrs: {
23
+ id: string
24
+ type: string
25
+ }
26
+ }
27
+
28
+ export const headshotElement: NodeSpec = {
29
+ content: 'headshot_image caption_title caption alt_text long_desc',
30
+ attrs: {
31
+ id: { default: '' },
32
+ type: { default: '' },
33
+ dataTracked: { default: null },
34
+ },
35
+ group: 'block',
36
+ toDOM: (node) => {
37
+ return [
38
+ 'div',
39
+ {
40
+ class: 'headshot_element',
41
+ id: node.attrs.id,
42
+ },
43
+ ]
44
+ },
45
+ }
46
+
47
+ export const isHeadshotElementNode = (node: ManuscriptNode): node is HeadshotElementNode =>
48
+ node.type === node.type.schema.nodes.headshot_element
@@ -0,0 +1,46 @@
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 { NodeSpec } from 'prosemirror-model'
18
+
19
+ import { ManuscriptNode } from '../types'
20
+
21
+ export interface HeadshotGridNode extends ManuscriptNode {
22
+ attrs: {
23
+ id: string
24
+ }
25
+ }
26
+
27
+ export const headshotGrid: NodeSpec = {
28
+ content: 'headshot_element*',
29
+ attrs: {
30
+ id: { default: '' },
31
+ dataTracked: { default: null },
32
+ },
33
+ group: 'block element',
34
+ toDOM: (node) => {
35
+ return [
36
+ 'div',
37
+ {
38
+ class: 'headshot_grid',
39
+ id: node.attrs.id,
40
+ },
41
+ ]
42
+ },
43
+ }
44
+
45
+ export const isHeadshotGridNode = (node: ManuscriptNode): node is HeadshotGridNode =>
46
+ node.type === node.type.schema.nodes.headshot_grid
@@ -0,0 +1,65 @@
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 { NodeSpec } from 'prosemirror-model'
18
+
19
+ import { ManuscriptNode } from '../types'
20
+
21
+ export interface HeadshotImageAttrs {
22
+ id: string
23
+ src: string
24
+ type: string
25
+ }
26
+
27
+ export interface HeadshotImageNode extends ManuscriptNode {
28
+ attrs: HeadshotImageAttrs
29
+ }
30
+
31
+ export const headshotImage: NodeSpec = {
32
+ attrs: {
33
+ id: { default: '' },
34
+ src: { default: '' },
35
+ type: { default: '' },
36
+ dataTracked: { default: null },
37
+ },
38
+ selectable: false,
39
+ group: 'block',
40
+ parseDOM: [
41
+ {
42
+ tag: 'figure',
43
+ context: 'headshot_element/',
44
+ getAttrs: (dom) => {
45
+ const element = dom as HTMLElement
46
+
47
+ return {
48
+ id: element.getAttribute('id'),
49
+ src: element.getAttribute('src'),
50
+ }
51
+ },
52
+ },
53
+ ],
54
+ toDOM: (node) => {
55
+ const imageNode = node as HeadshotImageNode
56
+
57
+ return [
58
+ 'figure',
59
+ {
60
+ class: 'headshot-figure',
61
+ id: imageNode.attrs.id,
62
+ },
63
+ ]
64
+ },
65
+ }
@@ -128,6 +128,9 @@ export type Nodes =
128
128
  | 'alt_titles'
129
129
  | 'long_desc'
130
130
  | 'hero_image'
131
+ | 'headshot_grid'
132
+ | 'headshot_element'
133
+ | 'headshot_image'
131
134
  | 'trans_abstract'
132
135
  | 'trans_graphical_abstract'
133
136
  | 'subtitle'
@@ -32,6 +32,8 @@ export const nodeNames: Map<ManuscriptNodeType, string> = new Map([
32
32
  [schema.nodes.figure_element, 'Figure'],
33
33
  [schema.nodes.image_element, 'Image'],
34
34
  [schema.nodes.hero_image, 'Hero Image'],
35
+ [schema.nodes.headshot_grid, 'Headshot Panel'],
36
+ [schema.nodes.headshot_element, 'Headshot'],
35
37
  [schema.nodes.table_element, 'Table'],
36
38
  [schema.nodes.table_cell, 'Table Cell'],
37
39
  [schema.nodes.table_col, 'Table Column'],
@@ -29,6 +29,10 @@ const textSnippet = (node: ManuscriptNode, max = 100) => {
29
29
  text += child.text
30
30
  } else if (isHighlightMarkerNode(node)) {
31
31
  text += ''
32
+ } else if (node.type === schema.nodes.headshot_element) {
33
+ if (child.type === schema.nodes.caption_title) {
34
+ text += child.textContent
35
+ }
32
36
  } else {
33
37
  text += ' '
34
38
  }
@@ -82,6 +86,7 @@ export const nodeTitle = (node: ManuscriptNode) => {
82
86
  case nodes.multi_graphic_figure_element:
83
87
  case nodes.image_element:
84
88
  case nodes.hero_image:
89
+ case nodes.headshot_grid:
85
90
  case nodes.box_element:
86
91
  case nodes.supplements:
87
92
  case nodes.attachments:
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = "4.4.0";
1
+ export const VERSION = "4.4.1";