jats-xml 1.0.8 → 1.0.10
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 +1 -62
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/jats.d.ts +3 -2
- package/dist/jats.d.ts.map +1 -1
- package/dist/jats.js +82 -16
- package/dist/order.d.ts +1 -0
- package/dist/order.d.ts.map +1 -1
- package/dist/order.js +36 -0
- package/dist/session.d.ts +2 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +3 -0
- package/dist/utils.d.ts +4 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +97 -32
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +11 -23
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -13
- package/dist/cli/jats-test.d.ts +0 -9
- package/dist/cli/jats-test.d.ts.map +0 -1
- package/dist/cli/jats-test.js +0 -106
- package/dist/cli/parse.d.ts +0 -7
- package/dist/cli/parse.d.ts.map +0 -1
- package/dist/cli/parse.js +0 -200
- package/dist/cli/validate.d.ts +0 -3
- package/dist/cli/validate.d.ts.map +0 -1
- package/dist/cli/validate.js +0 -25
- package/dist/jats.cjs +0 -20496
package/README.md
CHANGED
|
@@ -6,15 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
Types and utilities for working with JATS XML documents in Node and Typescript.
|
|
8
8
|
|
|
9
|
-
Read and write JATS XML from node or see summries from the command line.
|
|
10
|
-
|
|
11
|
-
To use from the command line, use the `-g` to create a global install, which will provide a `jats` CLI:
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
npm install -g jats-xml
|
|
15
|
-
jats -v
|
|
16
|
-
```
|
|
17
|
-
|
|
18
9
|
## What is JATS?
|
|
19
10
|
|
|
20
11
|
JATS is a NISO standard for Journal Article Tags Schema, which is a way to define the XML structure of a scientific article semantically. This includes the `front`-matter (authors, funding, title, abstract, etc.), the `body` of the article (sections, figures, equations, tables, etc.), and `back`-matter (references, footnotes, etc.). The JATS can also contain `sub-articles`.
|
|
@@ -23,58 +14,6 @@ The standard documents are hosted by the NIH <https://jats.nlm.nih.gov/>. There
|
|
|
23
14
|
|
|
24
15
|
Note that most publishers do **not** provide the XML as a first class output - they should, it is an important part of open-science to have the content programatically accessible and interoperable. It is only [FAIR](https://www.go-fair.org/fair-principles/) 😉.
|
|
25
16
|
|
|
26
|
-
## From the command line
|
|
27
|
-
|
|
28
|
-
Commands available:
|
|
29
|
-
|
|
30
|
-
`download`: attempt to find the JATS file and download it locally.
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
jats download https://elifesciences.org/articles/81952 article.jats
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Note, currently this just downloads the XML, **not** the associated files.
|
|
37
|
-
|
|
38
|
-
`summary`: summarize the contents of the JATS, given a URL, DOI, or local file
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
jats summary https://elifesciences.org/articles/81952
|
|
42
|
-
jats summary 10.1371/journal.pclm.0000068
|
|
43
|
-
jats summary /local/article.jats
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
This will provide a summary, including a list of what the JATS file contains.
|
|
47
|
-
|
|
48
|
-

|
|
49
|
-
|
|
50
|
-
`validate`: validate local file against JATS Archive DTD schema. By default, this uses JATS 1.3.
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
jats validate article.jats --jats 1.2 --mathmml 2
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
`test`: test a JATS file against a list of unit tests in YAML
|
|
57
|
-
|
|
58
|
-
The test cases are useful for known exports and expecting specific pieces of information in the XML.
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
jats test article.jats --cases tests.yml
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
```yaml
|
|
65
|
-
cases:
|
|
66
|
-
- title: Correct publisher ID (publisher-id)
|
|
67
|
-
select: 'front > journal-meta > journal-id[journal-id-type="publisher-id"] > *'
|
|
68
|
-
equals:
|
|
69
|
-
type: text
|
|
70
|
-
value: plos
|
|
71
|
-
- title: Every orcid is authenticated
|
|
72
|
-
selectAll: 'front > article-meta > contrib-group > contrib > contrib-id'
|
|
73
|
-
equals:
|
|
74
|
-
contrib-id-type: orcid
|
|
75
|
-
authenticated: 'true'
|
|
76
|
-
```
|
|
77
|
-
|
|
78
17
|
## Working in Typescript
|
|
79
18
|
|
|
80
19
|
All tags are accessible as types/enums. There is also documentation from each node-type
|
|
@@ -116,6 +55,6 @@ As of v1.0.0 this package is [ESM only](https://gist.github.com/sindresorhus/a39
|
|
|
116
55
|
<p style="text-align: center; color: #aaa; padding-top: 50px">
|
|
117
56
|
Made with love by
|
|
118
57
|
<a href="https://curvenote.com" target="_blank" style="color: #aaa">
|
|
119
|
-
<img src="https://curvenote.
|
|
58
|
+
<img src="https://cdn.curvenote.com/brand/logo-blue-icon.png" style="height: 1em" /> Curvenote
|
|
120
59
|
</a>
|
|
121
60
|
</p>
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/jats.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { GenericParent } from 'myst-common';
|
|
2
2
|
import type { Element, DeclarationAttributes } from 'xml-js';
|
|
3
|
-
import type
|
|
4
|
-
import type { Front, Body, Back, SubArticle, RefList, Reference, TitleGroup, ArticleTitle, Subtitle, Permissions, PubDate, License, Abstract, ContribGroup, Contrib, KeywordGroup, Keyword, ArticleCategories, ArticleMeta } from 'jats-tags';
|
|
3
|
+
import { type PageFrontmatter } from 'myst-frontmatter';
|
|
4
|
+
import type { Front, Body, Back, SubArticle, RefList, Reference, TitleGroup, ArticleTitle, Subtitle, Permissions, PubDate, License, Abstract, ContribGroup, Contrib, Affiliation, KeywordGroup, Keyword, ArticleCategories, ArticleMeta } from 'jats-tags';
|
|
5
5
|
import type { Logger } from 'myst-cli-utils';
|
|
6
6
|
import { type SerializationOptions } from 'jats-utils';
|
|
7
7
|
type Options = {
|
|
@@ -43,6 +43,7 @@ export declare class Jats {
|
|
|
43
43
|
get contribGroup(): ContribGroup | undefined;
|
|
44
44
|
get contribGroups(): ContribGroup[];
|
|
45
45
|
get articleAuthors(): Contrib[];
|
|
46
|
+
get articleAffiliations(): Affiliation[];
|
|
46
47
|
get body(): Body | undefined;
|
|
47
48
|
get back(): Back | undefined;
|
|
48
49
|
get subArticles(): SubArticle[];
|
package/dist/jats.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jats.d.ts","sourceRoot":"","sources":["../src/jats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,aAAa,CAAC;AAI9D,OAAO,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"jats.d.ts","sourceRoot":"","sources":["../src/jats.ts"],"names":[],"mappings":"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"}
|
package/dist/jats.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { toText } from 'myst-common';
|
|
2
2
|
import { xml2js } from 'xml-js';
|
|
3
3
|
import { doi } from 'doi-utils';
|
|
4
|
+
import { validatePageFrontmatter } from 'myst-frontmatter';
|
|
4
5
|
import { select as unistSelect, selectAll } from 'unist-util-select';
|
|
5
6
|
import { Tags } from 'jats-tags';
|
|
6
|
-
import {
|
|
7
|
+
import { findArticleId, processAffiliation, processContributor } from './utils.js';
|
|
7
8
|
import { tic } from 'myst-cli-utils';
|
|
8
|
-
import { articleMetaOrder } from './order.js';
|
|
9
|
+
import { articleMetaOrder, tableWrapOrder } from './order.js';
|
|
9
10
|
import { serializeJatsXml, convertToUnist, convertToXml, toDate, } from 'jats-utils';
|
|
10
11
|
function select(selector, node) {
|
|
11
12
|
var _a;
|
|
@@ -14,7 +15,7 @@ function select(selector, node) {
|
|
|
14
15
|
const DEFAULT_DOCTYPE = 'article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD with MathML3 v1.3 20210610//EN" "http://jats.nlm.nih.gov/publishing/1.3/JATS-archivearticle1-3-mathml3.dtd"';
|
|
15
16
|
export class Jats {
|
|
16
17
|
constructor(data, opts) {
|
|
17
|
-
var _a;
|
|
18
|
+
var _a, _b;
|
|
18
19
|
const toc = tic();
|
|
19
20
|
this.log = opts === null || opts === void 0 ? void 0 : opts.log;
|
|
20
21
|
if (opts === null || opts === void 0 ? void 0 : opts.source)
|
|
@@ -27,34 +28,85 @@ export class Jats {
|
|
|
27
28
|
}
|
|
28
29
|
const { declaration, elements } = this.raw;
|
|
29
30
|
this.declaration = declaration === null || declaration === void 0 ? void 0 : declaration.attributes;
|
|
31
|
+
if ((elements === null || elements === void 0 ? void 0 : elements.length) && elements[0].type !== 'doctype') {
|
|
32
|
+
(_a = this.log) === null || _a === void 0 ? void 0 : _a.warn('JATS is missing DOCTYPE declaration');
|
|
33
|
+
elements.unshift({ type: 'doctype' });
|
|
34
|
+
}
|
|
30
35
|
if (!((elements === null || elements === void 0 ? void 0 : elements.length) === 2 && elements[0].type === 'doctype' && hasSingleArticle(elements[1]))) {
|
|
31
|
-
throw new Error('
|
|
36
|
+
throw new Error('JATS must be structured as <!DOCTYPE><article>...</article>');
|
|
32
37
|
}
|
|
33
38
|
this.doctype = elements[0].doctype;
|
|
34
39
|
const converted = convertToUnist(elements[1]);
|
|
35
40
|
this.tree = select('article', converted);
|
|
36
|
-
(
|
|
41
|
+
(_b = this.log) === null || _b === void 0 ? void 0 : _b.debug(toc('Parsed and converted JATS to unist tree in %s'));
|
|
37
42
|
}
|
|
38
43
|
get frontmatter() {
|
|
39
|
-
var _a, _b, _c, _d;
|
|
44
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
40
45
|
const title = this.articleTitle;
|
|
41
46
|
const subtitle = this.articleSubtitle;
|
|
42
47
|
const short_title = this.articleAltTitle;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
let date;
|
|
49
|
+
if (this.publicationDate) {
|
|
50
|
+
const pubDate = toDate(this.publicationDate);
|
|
51
|
+
if (pubDate) {
|
|
52
|
+
const year = pubDate.getFullYear();
|
|
53
|
+
const month = (pubDate.getMonth() + 1).toString().padStart(2, '0');
|
|
54
|
+
const day = pubDate.getDate().toString().padStart(2, '0');
|
|
55
|
+
date = `${year}-${month}-${day}`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const authors = (_a = this.articleAuthors) === null || _a === void 0 ? void 0 : _a.map((auth) => {
|
|
59
|
+
return processContributor(auth);
|
|
60
|
+
});
|
|
61
|
+
const affiliations = (_b = this.articleAffiliations) === null || _b === void 0 ? void 0 : _b.map((aff) => {
|
|
62
|
+
return processAffiliation(aff);
|
|
63
|
+
});
|
|
64
|
+
const keywords = (_d = (_c = this.keywords) === null || _c === void 0 ? void 0 : _c.map((k) => toText(k))) !== null && _d !== void 0 ? _d : [];
|
|
65
|
+
const firstSubject = select(Tags.subject, (_e = this.articleCategories) !== null && _e !== void 0 ? _e : this.front);
|
|
46
66
|
const journalTitle = select(Tags.journalTitle, this.front);
|
|
47
|
-
|
|
67
|
+
const license = this.license;
|
|
68
|
+
let licenseString = null;
|
|
69
|
+
if (license === null || license === void 0 ? void 0 : license['xlink:href']) {
|
|
70
|
+
licenseString = license['xlink:href'];
|
|
71
|
+
}
|
|
72
|
+
else if (select('[type=ali:license_ref]', license)) {
|
|
73
|
+
licenseString = toText(select('[type=ali:license_ref]', license));
|
|
74
|
+
}
|
|
75
|
+
else if (selectAll('ext-link', license).length === 1) {
|
|
76
|
+
// this should only happen if there is only one ext-link
|
|
77
|
+
licenseString = (_f = select('ext-link', license)['xlink:href']) !== null && _f !== void 0 ? _f : null;
|
|
78
|
+
}
|
|
79
|
+
else if (license) {
|
|
80
|
+
licenseString = toText(license);
|
|
81
|
+
}
|
|
82
|
+
let openAccess;
|
|
83
|
+
const licenseType = (_g = license === null || license === void 0 ? void 0 : license['license-type']) === null || _g === void 0 ? void 0 : _g.toLowerCase();
|
|
84
|
+
if (licenseType && ['openaccess', 'open-access'].includes(licenseType)) {
|
|
85
|
+
openAccess = true;
|
|
86
|
+
}
|
|
87
|
+
else if (licenseString === null || licenseString === void 0 ? void 0 : licenseString.match(/^\s*Open Access\s*This/)) {
|
|
88
|
+
licenseString = licenseString.replace(/^\s*Open Access\s*/, '');
|
|
89
|
+
openAccess = true;
|
|
90
|
+
}
|
|
91
|
+
else if (licenseString === null || licenseString === void 0 ? void 0 : licenseString.toLowerCase().startsWith('this is an open access article')) {
|
|
92
|
+
openAccess = true;
|
|
93
|
+
}
|
|
94
|
+
const frontmatter = validatePageFrontmatter({
|
|
48
95
|
title: title ? toText(title) : undefined,
|
|
49
96
|
subtitle: subtitle ? toText(subtitle) : undefined,
|
|
50
97
|
short_title: short_title ? toText(short_title) : undefined,
|
|
51
|
-
doi: (
|
|
52
|
-
date
|
|
53
|
-
authors: authors
|
|
54
|
-
|
|
98
|
+
doi: (_h = this.doi) !== null && _h !== void 0 ? _h : undefined,
|
|
99
|
+
date,
|
|
100
|
+
authors: authors.length ? authors : undefined,
|
|
101
|
+
// editors,
|
|
102
|
+
affiliations: affiliations.length ? affiliations : undefined,
|
|
103
|
+
keywords: keywords.length ? keywords : undefined,
|
|
55
104
|
venue: journalTitle ? { title: toText(journalTitle) } : undefined,
|
|
56
105
|
subject: firstSubject ? toText(firstSubject) : undefined,
|
|
57
|
-
|
|
106
|
+
license: licenseString !== null && licenseString !== void 0 ? licenseString : undefined,
|
|
107
|
+
open_access: openAccess,
|
|
108
|
+
}, { property: 'frontmatter', messages: {} });
|
|
109
|
+
return frontmatter;
|
|
58
110
|
}
|
|
59
111
|
get front() {
|
|
60
112
|
return select(Tags.front, this.tree);
|
|
@@ -123,7 +175,18 @@ export class Jats {
|
|
|
123
175
|
return selectAll(Tags.contribGroup, this.front);
|
|
124
176
|
}
|
|
125
177
|
get articleAuthors() {
|
|
126
|
-
|
|
178
|
+
const contribs = selectAll(Tags.contrib, {
|
|
179
|
+
type: 'contribGroups',
|
|
180
|
+
children: this.contribGroups,
|
|
181
|
+
});
|
|
182
|
+
const authors = contribs.filter((contrib) => {
|
|
183
|
+
const contribType = contrib['contrib-type'];
|
|
184
|
+
return !contribType || contribType === 'author';
|
|
185
|
+
});
|
|
186
|
+
return authors;
|
|
187
|
+
}
|
|
188
|
+
get articleAffiliations() {
|
|
189
|
+
return selectAll(`${Tags.aff}[id]`, this.front);
|
|
127
190
|
}
|
|
128
191
|
get body() {
|
|
129
192
|
return select(Tags.body, this.tree);
|
|
@@ -146,6 +209,9 @@ export class Jats {
|
|
|
146
209
|
this.articleMeta.children = (_a = this.articleMeta) === null || _a === void 0 ? void 0 : _a.children.sort((a, b) => articleMetaOrder.findIndex((x) => x === a.type) -
|
|
147
210
|
articleMetaOrder.findIndex((x) => x === b.type));
|
|
148
211
|
}
|
|
212
|
+
selectAll('table-wrap', this.tree).forEach((tw) => {
|
|
213
|
+
tw.children = tw.children.sort((a, b) => { var _a, _b; return ((_a = tableWrapOrder[a.type]) !== null && _a !== void 0 ? _a : -1) - ((_b = tableWrapOrder[b.type]) !== null && _b !== void 0 ? _b : -1); });
|
|
214
|
+
});
|
|
149
215
|
}
|
|
150
216
|
serialize(opts) {
|
|
151
217
|
var _a;
|
package/dist/order.d.ts
CHANGED
package/dist/order.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"order.d.ts","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,UAgD5B,CAAC"}
|
|
1
|
+
{"version":3,"file":"order.d.ts","sourceRoot":"","sources":["../src/order.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,UAgD5B,CAAC;AAaF,eAAO,MAAM,cAAc,wBA0BzB,CAAC"}
|
package/dist/order.js
CHANGED
|
@@ -47,3 +47,39 @@ export const articleMetaOrder = [
|
|
|
47
47
|
'counts',
|
|
48
48
|
'custom-meta-group',
|
|
49
49
|
];
|
|
50
|
+
function order(tags) {
|
|
51
|
+
return Object.fromEntries(tags
|
|
52
|
+
.map((tag, i) => {
|
|
53
|
+
if (typeof tag === 'string')
|
|
54
|
+
return [[tag, i]];
|
|
55
|
+
return tag.map((t) => [t, i]);
|
|
56
|
+
})
|
|
57
|
+
.flat());
|
|
58
|
+
}
|
|
59
|
+
export const tableWrapOrder = order([
|
|
60
|
+
'object-id',
|
|
61
|
+
'label',
|
|
62
|
+
'caption',
|
|
63
|
+
'abstract',
|
|
64
|
+
'kwd-group',
|
|
65
|
+
'subj-group',
|
|
66
|
+
['alt-text', 'long-desc', 'email', 'ext-link', 'uri'],
|
|
67
|
+
[
|
|
68
|
+
'disp-quote',
|
|
69
|
+
'speech',
|
|
70
|
+
'statement',
|
|
71
|
+
'verse-group',
|
|
72
|
+
'def-list',
|
|
73
|
+
'list',
|
|
74
|
+
'alternatives',
|
|
75
|
+
'chem-struct-wrap',
|
|
76
|
+
'code',
|
|
77
|
+
'disp-formula',
|
|
78
|
+
'graphic',
|
|
79
|
+
'media',
|
|
80
|
+
'preformat',
|
|
81
|
+
'table',
|
|
82
|
+
'xref',
|
|
83
|
+
],
|
|
84
|
+
['table-wrap-foot', 'attrib', 'permissions'],
|
|
85
|
+
]);
|
package/dist/session.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Response } from 'node-fetch';
|
|
1
2
|
import type { Logger } from 'myst-cli-utils';
|
|
2
3
|
import type { ISession } from './types.js';
|
|
3
4
|
export declare class Session implements ISession {
|
|
@@ -5,6 +6,7 @@ export declare class Session implements ISession {
|
|
|
5
6
|
constructor(opts?: {
|
|
6
7
|
logger?: Logger;
|
|
7
8
|
});
|
|
9
|
+
fetch(): Promise<Response>;
|
|
8
10
|
}
|
|
9
11
|
export declare function getSession(logger: Logger): Session;
|
|
10
12
|
//# sourceMappingURL=session.d.ts.map
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAc3C,qBAAa,OAAQ,YAAW,QAAQ;IACtC,GAAG,EAAE,MAAM,CAAC;gBACA,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAGtC,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC;CAG3B;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,WAExC"}
|
package/dist/session.js
CHANGED
|
@@ -17,6 +17,9 @@ export class Session {
|
|
|
17
17
|
var _a;
|
|
18
18
|
this.log = xmllintLogWrapper((_a = opts === null || opts === void 0 ? void 0 : opts.logger) !== null && _a !== void 0 ? _a : chalkLogger(LogLevel.debug));
|
|
19
19
|
}
|
|
20
|
+
fetch() {
|
|
21
|
+
throw new Error('fetch not implemented on session');
|
|
22
|
+
}
|
|
20
23
|
}
|
|
21
24
|
export function getSession(logger) {
|
|
22
25
|
return new Session({ logger });
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { GenericParent } from 'myst-common';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Affiliation, Contrib } from 'jats-tags';
|
|
3
|
+
import type { Affiliation as AffiliationFM, Contributor as ContributorFM } from 'myst-frontmatter';
|
|
3
4
|
export type PubIdTypes = 'doi' | 'pmc' | 'pmid' | 'publisher-id' | string;
|
|
4
5
|
export declare function findArticleId(node: GenericParent | undefined, pubIdType?: PubIdTypes): string | undefined;
|
|
5
|
-
export declare function
|
|
6
|
+
export declare function processContributor(contrib: Contrib): ContributorFM;
|
|
7
|
+
export declare function processAffiliation(aff: Affiliation): AffiliationFM;
|
|
6
8
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,aAAa,CAAC;AAK9D,OAAO,KAAK,EAAE,WAAW,EAAa,OAAO,EAAmB,MAAM,WAAW,CAAC;AAElF,OAAO,KAAK,EAAE,WAAW,IAAI,aAAa,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGnG,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,cAAc,GAAG,MAAM,CAAC;AAE1E,wBAAgB,aAAa,CAC3B,IAAI,EAAE,aAAa,GAAG,SAAS,EAC/B,SAAS,GAAE,UAAkB,GAC5B,MAAM,GAAG,SAAS,CAQpB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAmBlE;AAmBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG,aAAa,CAqElE"}
|
package/dist/utils.js
CHANGED
|
@@ -2,6 +2,7 @@ import { toText } from 'myst-common';
|
|
|
2
2
|
import { doi } from 'doi-utils';
|
|
3
3
|
import { select, selectAll } from 'unist-util-select';
|
|
4
4
|
import { Tags } from 'jats-tags';
|
|
5
|
+
import { remove } from 'unist-util-remove';
|
|
5
6
|
export function findArticleId(node, pubIdType = 'doi') {
|
|
6
7
|
if (!node)
|
|
7
8
|
return undefined;
|
|
@@ -11,43 +12,107 @@ export function findArticleId(node, pubIdType = 'doi') {
|
|
|
11
12
|
const doiTag = selectAll(`${Tags.articleId},${Tags.pubId}`, node).find((t) => doi.validate(toText(t)));
|
|
12
13
|
return toText(doiTag) || undefined;
|
|
13
14
|
}
|
|
14
|
-
export function
|
|
15
|
+
export function processContributor(contrib) {
|
|
15
16
|
const author = {
|
|
16
|
-
name: `${toText(select(Tags.givenNames,
|
|
17
|
+
name: `${toText(select(Tags.givenNames, contrib))} ${toText(select(Tags.surname, contrib))}`,
|
|
17
18
|
};
|
|
18
|
-
const orcid = select('[contrib-id-type=orcid]',
|
|
19
|
+
const orcid = select('[contrib-id-type=orcid]', contrib);
|
|
19
20
|
if (orcid) {
|
|
20
21
|
author.orcid = toText(orcid).replace(/(https?:\/\/)?orcid\.org\//, '');
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* ```xml
|
|
27
|
-
* <aff id="aff2">
|
|
28
|
-
* <label>2</label>
|
|
29
|
-
* <institution-wrap>
|
|
30
|
-
* <institution-id institution-id-type="ror">https://ror.org/00t9vx427</institution-id>
|
|
31
|
-
* <institution>Department of Biochemistry, University of Texas Southwestern Medical Center</institution>
|
|
32
|
-
* </institution-wrap>
|
|
33
|
-
* <addr-line>
|
|
34
|
-
* <named-content content-type="city">Dallas</named-content>
|
|
35
|
-
* </addr-line>
|
|
36
|
-
* <country>United States</country>
|
|
37
|
-
* </aff>
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
const affiliationRefs = selectAll('xref[ref-type=aff]', node);
|
|
41
|
-
const affiliations = affiliationRefs.map((xref) => select(`[id=${xref.rid}]`, article));
|
|
42
|
-
const affiliationText = affiliations
|
|
43
|
-
.map((aff) => {
|
|
44
|
-
// TODO: handle rors!
|
|
45
|
-
const ror = select(`[institution-id-type=ror]`, aff);
|
|
46
|
-
return toText(select('institution', aff));
|
|
47
|
-
})
|
|
48
|
-
.filter((t) => !!t);
|
|
49
|
-
if (affiliationText.length > 0) {
|
|
50
|
-
author.affiliations = affiliationText;
|
|
23
|
+
const affiliationRefs = selectAll('xref[ref-type=aff]', contrib);
|
|
24
|
+
const affiliationIds = affiliationRefs.map((xref) => xref.rid);
|
|
25
|
+
if (affiliationIds.length > 0) {
|
|
26
|
+
author.affiliations = affiliationIds;
|
|
51
27
|
}
|
|
28
|
+
const uri = select('uri', contrib);
|
|
29
|
+
if (uri === null || uri === void 0 ? void 0 : uri['xlink:href']) {
|
|
30
|
+
author.url = uri['xlink:href'];
|
|
31
|
+
}
|
|
32
|
+
// If there are no aff xrefs AND contrib is in a contrib group with affs AND those affs do not have IDs, add them as affiliations...
|
|
52
33
|
return author;
|
|
53
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Perform standard toText, trim, remove trailing comma and semicolon
|
|
37
|
+
*
|
|
38
|
+
* Additionally, this returns undefined instead of empty string if node is undefined
|
|
39
|
+
*/
|
|
40
|
+
function toTextAndTrim(content) {
|
|
41
|
+
const text = toText(content);
|
|
42
|
+
if (!text)
|
|
43
|
+
return undefined;
|
|
44
|
+
return text.replace(/^[\s;,]+/, '').replace(/[\s;,]+$/, '');
|
|
45
|
+
}
|
|
46
|
+
function markForDeletion(nodes) {
|
|
47
|
+
nodes.forEach((node) => {
|
|
48
|
+
if (node)
|
|
49
|
+
node.type = '__delete__';
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export function processAffiliation(aff) {
|
|
53
|
+
var _a, _b;
|
|
54
|
+
const id = aff.id;
|
|
55
|
+
let ror;
|
|
56
|
+
let isni;
|
|
57
|
+
const rorNode = select(`institution-id[institution-id-type=ror]`, aff);
|
|
58
|
+
if (rorNode) {
|
|
59
|
+
ror = toTextAndTrim(rorNode);
|
|
60
|
+
}
|
|
61
|
+
const isniNode = select(`institution-id[institution-id-type=ISNI]`, aff);
|
|
62
|
+
if (isniNode) {
|
|
63
|
+
isni = toTextAndTrim(isniNode);
|
|
64
|
+
}
|
|
65
|
+
markForDeletion(selectAll('institution-id', aff));
|
|
66
|
+
remove(aff, '__delete__');
|
|
67
|
+
const institutions = selectAll('institution', aff);
|
|
68
|
+
const textAddress = selectAll('addr-line > text', aff);
|
|
69
|
+
const namedContent = selectAll('named-content', aff);
|
|
70
|
+
const departmentNode = (_a = institutions.find((inst) => inst['content-type'] === 'dept')) !== null && _a !== void 0 ? _a : namedContent.find((content) => content['content-type'] === 'organisation-division');
|
|
71
|
+
const addressNode = namedContent.find((content) => content['content-type'] === 'street');
|
|
72
|
+
const cityNode = namedContent.find((content) => content['content-type'] === 'city');
|
|
73
|
+
const stateNode = namedContent.find((content) => content['content-type'] === 'country-part');
|
|
74
|
+
const postalCodeNode = namedContent.find((content) => content['content-type'] === 'post-code');
|
|
75
|
+
const countryNode = (_b = select('country', aff)) !== null && _b !== void 0 ? _b : namedContent.find((content) => content['content-type'] === 'country');
|
|
76
|
+
markForDeletion([
|
|
77
|
+
...textAddress,
|
|
78
|
+
...namedContent,
|
|
79
|
+
departmentNode,
|
|
80
|
+
addressNode,
|
|
81
|
+
cityNode,
|
|
82
|
+
stateNode,
|
|
83
|
+
postalCodeNode,
|
|
84
|
+
countryNode,
|
|
85
|
+
]);
|
|
86
|
+
remove(aff, '__delete__');
|
|
87
|
+
const affChildren = aff.children.filter((child) => child.type !== 'label');
|
|
88
|
+
let institution;
|
|
89
|
+
if (affChildren.filter((child) => ['text', 'institution-wrap', 'institution'].includes(child.type))
|
|
90
|
+
.length === affChildren.length) {
|
|
91
|
+
institution = toTextAndTrim(affChildren);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
institution = toTextAndTrim(institutions.find((inst) => inst['content-type'] !== 'dept'));
|
|
95
|
+
}
|
|
96
|
+
const addressLines = textAddress
|
|
97
|
+
.map((line) => toTextAndTrim(line))
|
|
98
|
+
.filter((line) => !!line);
|
|
99
|
+
let department = departmentNode
|
|
100
|
+
? toTextAndTrim(departmentNode)
|
|
101
|
+
: addressLines.find((line) => line.toLowerCase().includes('department'));
|
|
102
|
+
let address = addressNode
|
|
103
|
+
? toTextAndTrim(addressNode)
|
|
104
|
+
: addressLines.find((line) => !line.toLowerCase().includes('department'));
|
|
105
|
+
if (address && !institution) {
|
|
106
|
+
institution = address;
|
|
107
|
+
address = undefined;
|
|
108
|
+
}
|
|
109
|
+
if (department && !institution) {
|
|
110
|
+
institution = department;
|
|
111
|
+
department = undefined;
|
|
112
|
+
}
|
|
113
|
+
const city = toTextAndTrim(cityNode);
|
|
114
|
+
const state = toTextAndTrim(stateNode);
|
|
115
|
+
const postal_code = toTextAndTrim(postalCodeNode);
|
|
116
|
+
const country = toTextAndTrim(countryNode);
|
|
117
|
+
return { id, ror, isni, department, institution, address, city, state, postal_code, country };
|
|
118
|
+
}
|
package/dist/version.d.ts
CHANGED
package/dist/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,OAAO,WAAW,CAAC;AACzB,eAAe,OAAO,CAAC"}
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const version = '1.0.
|
|
1
|
+
const version = '1.0.10';
|
|
2
2
|
export default version;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jats-xml",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Types and utilities for working with JATS in Typescript",
|
|
5
5
|
"author": "Rowan Cockett <rowan@curvenote.com>",
|
|
6
6
|
"homepage": "https://github.com/curvenote/jats",
|
|
@@ -24,53 +24,41 @@
|
|
|
24
24
|
"type": "git",
|
|
25
25
|
"url": "git+https://github.com/curvenote/jats.git"
|
|
26
26
|
},
|
|
27
|
-
"bin": {
|
|
28
|
-
"jats": "./dist/jats.cjs"
|
|
29
|
-
},
|
|
30
27
|
"scripts": {
|
|
31
28
|
"copy:version": "echo \"const version = '\"$npm_package_version\"';\nexport default version;\" > src/version.ts",
|
|
32
29
|
"clean": "rm -rf dist",
|
|
33
|
-
"unlink": "npm uninstall -g jats-xml;",
|
|
34
|
-
"link": "npm run unlink; npm link;",
|
|
35
|
-
"dev": "npm run copy:version && npm run link && esbuild src/cli/index.ts --bundle --outfile=dist/jats.cjs --platform=node --watch",
|
|
36
30
|
"test": "npm run copy:version && vitest run",
|
|
37
31
|
"test:watch": "npm run copy:version && vitest watch",
|
|
38
32
|
"lint": "eslint \"src/**/*.ts*\" -c ./.eslintrc.cjs",
|
|
39
33
|
"lint:format": "prettier --check \"src/**/*.{ts,tsx,md}\"",
|
|
40
34
|
"build:esm": "tsc",
|
|
41
|
-
"build
|
|
42
|
-
"build": "npm-run-all -l clean copy:version -p build:esm build:cli"
|
|
35
|
+
"build": "npm-run-all -l clean copy:version -p build:esm"
|
|
43
36
|
},
|
|
44
37
|
"bugs": {
|
|
45
38
|
"url": "https://github.com/curvenote/jats/issues"
|
|
46
39
|
},
|
|
47
40
|
"dependencies": {
|
|
48
41
|
"adm-zip": "^0.5.10",
|
|
49
|
-
"doi-utils": "^2.0.
|
|
50
|
-
"
|
|
51
|
-
"jats-
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
42
|
+
"doi-utils": "^2.0.3",
|
|
43
|
+
"jats-tags": "^1.0.10",
|
|
44
|
+
"jats-utils": "^1.0.10",
|
|
45
|
+
"myst-cli-utils": "^2.0.11",
|
|
46
|
+
"myst-common": "^1.7.5",
|
|
47
|
+
"myst-frontmatter": "^1.7.5",
|
|
55
48
|
"node-fetch": "^3.3.1",
|
|
56
|
-
"unist-util-is": "^5.2.1",
|
|
57
|
-
"unist-util-remove": "^3.1.0",
|
|
58
49
|
"unist-util-select": "^4.0.0",
|
|
50
|
+
"unist-util-remove": "4.0.0",
|
|
59
51
|
"which": "^3.0.1",
|
|
60
52
|
"xml-js": "^1.6.11"
|
|
61
53
|
},
|
|
62
54
|
"peerDependencies": {
|
|
63
|
-
"chalk": "^5.2.0"
|
|
64
|
-
"commander": "^10.0.1"
|
|
55
|
+
"chalk": "^5.2.0"
|
|
65
56
|
},
|
|
66
57
|
"devDependencies": {
|
|
67
58
|
"@types/adm-zip": "^0.5.0",
|
|
68
59
|
"@types/js-yaml": "^4.0.5",
|
|
69
60
|
"@types/which": "^3.0.0",
|
|
70
61
|
"chalk": "^5.2.0",
|
|
71
|
-
"
|
|
72
|
-
"myst-cli-utils": "^2.0.0",
|
|
73
|
-
"myst-common": "^1.0.0",
|
|
74
|
-
"myst-frontmatter": "^1.0.0"
|
|
62
|
+
"js-yaml": "^4.1.0"
|
|
75
63
|
}
|
|
76
64
|
}
|
package/dist/cli/index.d.ts
DELETED
package/dist/cli/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
package/dist/cli/index.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { Command } from 'commander';
|
|
3
|
-
import version from '../version.js';
|
|
4
|
-
import { addDownloadCLI } from './parse.js';
|
|
5
|
-
import { addValidateCLI } from './validate.js';
|
|
6
|
-
import { addTestCLI } from './jats-test.js';
|
|
7
|
-
const program = new Command();
|
|
8
|
-
addDownloadCLI(program);
|
|
9
|
-
addValidateCLI(program);
|
|
10
|
-
addTestCLI(program);
|
|
11
|
-
program.version(`v${version}`, '-v, --version', 'Print the current version of jats-xml');
|
|
12
|
-
program.option('-d, --debug', 'Log out any errors to the console.');
|
|
13
|
-
program.parse(process.argv);
|