@manuscripts/transform 4.5.6 → 4.5.8

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.
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import { parseXml } from 'libxmljs2'
18
+ import serializeToXML from 'w3c-xmlserializer'
18
19
 
19
20
  import { JATSExporter } from '../exporter/jats-exporter'
20
21
  import { parseJATSArticle } from '../importer/parse-jats-article'
@@ -36,9 +37,10 @@ const roundtrip = async (filename: string) => {
36
37
  const node = parseJATSArticle(doc, sectionCategories)
37
38
 
38
39
  const exporter = new JATSExporter()
39
- return await exporter.serializeToJATS(node, {
40
+ const document = await exporter.export(node, {
40
41
  csl: DEFAULT_CSL_OPTIONS,
41
42
  })
43
+ return serializeToXML(document)
42
44
  }
43
45
 
44
46
  describe('JATS roundtrip', () => {
@@ -17,7 +17,6 @@
17
17
  import * as Citeproc from 'citeproc'
18
18
  import { DOMOutputSpec, DOMSerializer, type NodeType } from 'prosemirror-model'
19
19
  import { findChildrenByAttr, findChildrenByType } from 'prosemirror-utils'
20
- import serializeToXML from 'w3c-xmlserializer'
21
20
 
22
21
  import { buildCiteprocCitation } from '../../lib/citeproc'
23
22
  import { CreditRoleUrls } from '../../lib/credit-roles'
@@ -33,6 +32,7 @@ import {
33
32
  AffiliationNode,
34
33
  AuthorNotesNode,
35
34
  AwardNode,
35
+ ExtLink,
36
36
  CitationNode,
37
37
  ContributorNode,
38
38
  CorrespNode,
@@ -162,10 +162,10 @@ export class JATSExporter {
162
162
  return (nodes ?? []).filter((n): n is T => isNodeOfType<T>(n, type))
163
163
  }
164
164
 
165
- public serializeToJATS = async (
165
+ public export = async (
166
166
  manuscriptNode: ActualManuscriptNode,
167
167
  options: ExportOptions
168
- ): Promise<string> => {
168
+ ): Promise<Document> => {
169
169
  this.manuscriptNode = manuscriptNode
170
170
  this.populateNodesMap()
171
171
  this.initCiteprocEngine(options)
@@ -222,7 +222,7 @@ export class JATSExporter {
222
222
  $article.appendChild($floatsGroup)
223
223
  }
224
224
  await this.rewriteIDs()
225
- return serializeToXML(this.document)
225
+ return this.document
226
226
  }
227
227
 
228
228
  private appendChildNodeOfType = (
@@ -615,9 +615,9 @@ export class JATSExporter {
615
615
  const [, bibliography] = this.engine.makeBibliography()
616
616
  const parser = new DOMParser()
617
617
  bibliography.forEach((item) => {
618
- const fragment = `<template xmlns:xlink="${XLINK_NAMESPACE}">${sanitizeXmlString(
618
+ const fragment = `<wrapper xmlns:xlink="${XLINK_NAMESPACE}">${sanitizeXmlString(
619
619
  item
620
- )}</template>`
620
+ )}</wrapper>`
621
621
  const $ref = parser
622
622
  .parseFromString(fragment, 'text/xml')
623
623
  .querySelector('ref')
@@ -691,7 +691,7 @@ export class JATSExporter {
691
691
  attachments: () => '',
692
692
  image_element: (node) => createImage(node),
693
693
  embed: (node) => {
694
- const { id, href, mimetype, mimeSubtype } = node.attrs
694
+ const { id, href, mimetype, mimeSubtype, extLinks } = node.attrs
695
695
  if (!href) {
696
696
  return ''
697
697
  }
@@ -709,6 +709,22 @@ export class JATSExporter {
709
709
  this.appendChildNodeOfType($media, node, schema.nodes.alt_text)
710
710
  this.appendChildNodeOfType($media, node, schema.nodes.long_desc)
711
711
  this.appendCaption($media, node)
712
+ if (extLinks && extLinks.length > 0) {
713
+ extLinks.forEach((extLink: ExtLink) => {
714
+ if (extLink.href) {
715
+ const extLinkElement = this.createElement('ext-link')
716
+ extLinkElement.setAttribute('ext-link-type', extLink.type)
717
+ extLinkElement.setAttributeNS(XLINK_NAMESPACE, 'href', extLink.href)
718
+ if (extLink.lang) {
719
+ extLinkElement.setAttributeNS(XML_NAMESPACE, 'lang', extLink.lang)
720
+ }
721
+ if (extLink.label) {
722
+ extLinkElement.textContent = extLink.label
723
+ }
724
+ $media.appendChild(extLinkElement)
725
+ }
726
+ })
727
+ }
712
728
  return $media
713
729
  },
714
730
  awards: () => ['funding-group', 0],
@@ -730,6 +730,11 @@ export class JATSDOMParser {
730
730
  context: 'pullquote_element/',
731
731
  getAttrs: this.getFigAttrs,
732
732
  },
733
+ {
734
+ tag: 'ext-link',
735
+ context: 'embed/',
736
+ ignore: true, // ext-links within media are handled via extLinks attribute
737
+ },
733
738
  {
734
739
  tag: 'ext-link',
735
740
  node: 'link',
@@ -758,11 +763,22 @@ export class JATSDOMParser {
758
763
  node: 'embed',
759
764
  getAttrs: (node) => {
760
765
  const element = node as HTMLElement
766
+ const extLinkElements = element.querySelectorAll('ext-link')
767
+ const extLinks = Array.from(extLinkElements)
768
+ .map((extLinkElement) => ({
769
+ type: extLinkElement.getAttribute('ext-link-type') || '',
770
+ href: extLinkElement.getAttributeNS(XLINK_NAMESPACE, 'href') || '',
771
+ lang: extLinkElement.getAttributeNS(XML_NAMESPACE, 'lang') || '',
772
+ label: getTrimmedTextContent(extLinkElement) || undefined,
773
+ }))
774
+ .filter((extLink) => extLink.href) // Filter out entries without href
775
+
761
776
  return {
762
777
  id: element.getAttribute('id'),
763
778
  href: element.getAttributeNS(XLINK_NAMESPACE, 'href'),
764
779
  mimetype: element.getAttribute('mimetype'),
765
780
  mimeSubtype: element.getAttribute('mime-subtype'),
781
+ extLinks: extLinks.length > 0 ? extLinks : undefined,
766
782
  }
767
783
  },
768
784
  },
@@ -18,11 +18,19 @@ import { NodeSpec } from 'prosemirror-model'
18
18
 
19
19
  import { ManuscriptNode } from '../types'
20
20
 
21
+ export interface ExtLink {
22
+ type: string
23
+ href: string
24
+ lang: string
25
+ label?: string
26
+ }
27
+
21
28
  export interface EmbedAttrs {
22
29
  id: string
23
30
  href: string
24
31
  mimetype: string
25
32
  mimeSubtype: string
33
+ extLinks?: ExtLink[]
26
34
  }
27
35
 
28
36
  export interface EmbedNode extends ManuscriptNode {
@@ -38,6 +46,7 @@ export const embed: NodeSpec = {
38
46
  mimetype: { default: undefined },
39
47
  mimeSubtype: { default: undefined },
40
48
  longDesc: { default: '' },
49
+ extLinks: { default: [] },
41
50
  },
42
51
  group: 'block element',
43
52
  toDOM: (node) => {
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = "4.5.6";
1
+ export const VERSION = "4.5.8";