jats-xml 0.0.16 → 0.1.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.
- package/README.md +22 -0
- package/dist/cjs/cli/index.js +2 -0
- package/dist/cjs/cli/jats-test.js +125 -0
- package/dist/cjs/cli/parse.js +14 -13
- package/dist/cjs/jats.js +25 -25
- package/dist/cjs/utils.js +11 -6
- package/dist/cjs/version.js +1 -1
- package/dist/esm/cli/index.js +2 -0
- package/dist/esm/cli/jats-test.js +117 -0
- package/dist/esm/cli/parse.js +2 -2
- package/dist/esm/jats.js +1 -1
- package/dist/esm/utils.js +9 -4
- package/dist/esm/version.js +1 -1
- package/dist/jats.js +4323 -1090
- package/dist/types/cli/jats-test.d.ts +9 -0
- package/dist/types/cli/jats-test.d.ts.map +1 -0
- package/dist/types/cli/parse.d.ts +3 -0
- package/dist/types/cli/parse.d.ts.map +1 -1
- package/dist/types/jats.d.ts +1 -1
- package/dist/types/jats.d.ts.map +1 -1
- package/dist/types/{types/session.d.ts → types.d.ts} +1 -1
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +6 -8
- package/LICENSE +0 -21
- package/dist/cjs/types/elementTags.js +0 -1301
- package/dist/cjs/types/index.js +0 -20
- package/dist/cjs/types/refType.js +0 -57
- package/dist/cjs/types/session.js +0 -2
- package/dist/esm/types/elementTags.js +0 -1298
- package/dist/esm/types/index.js +0 -4
- package/dist/esm/types/refType.js +0 -54
- package/dist/esm/types/session.js +0 -1
- package/dist/types/types/elementTags.d.ts +0 -1298
- package/dist/types/types/elementTags.d.ts.map +0 -1
- package/dist/types/types/elements.d.ts +0 -93
- package/dist/types/types/elements.d.ts.map +0 -1
- package/dist/types/types/index.d.ts +0 -5
- package/dist/types/types/index.d.ts.map +0 -1
- package/dist/types/types/refType.d.ts +0 -54
- package/dist/types/types/refType.d.ts.map +0 -1
- package/dist/types/types/session.d.ts.map +0 -1
- /package/dist/cjs/{types/elements.js → types.js} +0 -0
- /package/dist/esm/{types/elements.js → types.js} +0 -0
package/README.md
CHANGED
|
@@ -53,6 +53,28 @@ This will provide a summary, including a list of what the JATS file contains.
|
|
|
53
53
|
jats validate article.jats --jats 1.2 --mathmml 2
|
|
54
54
|
```
|
|
55
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
|
+
|
|
56
78
|
## Working in Typescript
|
|
57
79
|
|
|
58
80
|
All tags are accessible as types/enums. There is also documentation from each node-type
|
package/dist/cjs/cli/index.js
CHANGED
|
@@ -8,9 +8,11 @@ const commander_1 = __importDefault(require("commander"));
|
|
|
8
8
|
const version_1 = __importDefault(require("../version"));
|
|
9
9
|
const parse_1 = require("./parse");
|
|
10
10
|
const validate_1 = require("./validate");
|
|
11
|
+
const jats_test_1 = require("./jats-test");
|
|
11
12
|
const program = new commander_1.default.Command();
|
|
12
13
|
(0, parse_1.addDownloadCLI)(program);
|
|
13
14
|
(0, validate_1.addValidateCLI)(program);
|
|
15
|
+
(0, jats_test_1.addTestCLI)(program);
|
|
14
16
|
program.version(`v${version_1.default}`, '-v, --version', 'Print the current version of jats-xml');
|
|
15
17
|
program.option('-d, --debug', 'Log out any errors to the console.');
|
|
16
18
|
program.parse(process.argv);
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.addTestCLI = exports.testJatsFile = void 0;
|
|
16
|
+
const commander_1 = require("commander");
|
|
17
|
+
const myst_cli_utils_1 = require("myst-cli-utils");
|
|
18
|
+
const session_1 = require("../session");
|
|
19
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
20
|
+
const fs_1 = __importDefault(require("fs"));
|
|
21
|
+
const parse_1 = require("./parse");
|
|
22
|
+
const unist_util_select_1 = require("unist-util-select");
|
|
23
|
+
const unist_util_is_1 = require("unist-util-is");
|
|
24
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
25
|
+
const INDENT = ' ';
|
|
26
|
+
function printNodes(expected, received) {
|
|
27
|
+
return chalk_1.default.reset(`\n${INDENT}${chalk_1.default.greenBright('Expected node containing')}:\n${INDENT} ${js_yaml_1.default
|
|
28
|
+
.dump(expected)
|
|
29
|
+
.replace(/\n/g, `\n${INDENT} `)}\n${INDENT}${chalk_1.default.redBright('Received node')}:\n${INDENT} ${js_yaml_1.default.dump(received).replace(/\n/g, `\n${INDENT} `)}`);
|
|
30
|
+
}
|
|
31
|
+
function testJatsFile(session, file, opts) {
|
|
32
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
const toc = (0, myst_cli_utils_1.tic)();
|
|
34
|
+
const jats = yield (0, parse_1.parseJats)(session, file);
|
|
35
|
+
const tests = js_yaml_1.default.load(fs_1.default.readFileSync(opts.cases).toString());
|
|
36
|
+
const results = tests.cases.map((testCase, index) => {
|
|
37
|
+
if (!testCase.title) {
|
|
38
|
+
return [`Test Case ${index}`, null, 'Test must include a title'];
|
|
39
|
+
}
|
|
40
|
+
if (testCase.equals === undefined) {
|
|
41
|
+
return [testCase.title, null, 'Test must have an equals statement'];
|
|
42
|
+
}
|
|
43
|
+
if (testCase.select) {
|
|
44
|
+
const node = (0, unist_util_select_1.select)(testCase.select, jats.tree);
|
|
45
|
+
const pass = (0, unist_util_is_1.is)(node, testCase.equals);
|
|
46
|
+
if (testCase.equals == null && node) {
|
|
47
|
+
return [testCase.title, false, 'Expected no node to be present'];
|
|
48
|
+
}
|
|
49
|
+
if (!node && testCase.equals == null)
|
|
50
|
+
return [testCase.title, true];
|
|
51
|
+
if (!node)
|
|
52
|
+
return [testCase.title, false];
|
|
53
|
+
let failed = false;
|
|
54
|
+
const messages = [];
|
|
55
|
+
if (!pass) {
|
|
56
|
+
failed = failed || true;
|
|
57
|
+
messages.push(`Failed to validate node\n${printNodes(testCase.equals, node)}`);
|
|
58
|
+
}
|
|
59
|
+
return [testCase.title, !failed, messages.join('\n')];
|
|
60
|
+
}
|
|
61
|
+
else if (testCase.selectAll) {
|
|
62
|
+
const testNodes = (0, unist_util_select_1.selectAll)(testCase.selectAll, jats.tree);
|
|
63
|
+
if (!testNodes && testCase.equals == null)
|
|
64
|
+
return [testCase.title, true];
|
|
65
|
+
if (!testNodes)
|
|
66
|
+
return [testCase.title, false, 'Node not found'];
|
|
67
|
+
let equals = testCase.equals;
|
|
68
|
+
if (!Array.isArray(testCase.equals)) {
|
|
69
|
+
equals = Array(testNodes.length).fill(testCase.equals);
|
|
70
|
+
}
|
|
71
|
+
let failed = false;
|
|
72
|
+
const messages = [];
|
|
73
|
+
if (equals.length !== testNodes.length) {
|
|
74
|
+
failed = failed || true;
|
|
75
|
+
messages.push(`Expected ${equals.length} nodes, got ${testNodes.length}\n${printNodes(equals, testNodes)}`);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
equals.forEach((node, ii) => {
|
|
79
|
+
const pass = (0, unist_util_is_1.is)(testNodes[ii], node);
|
|
80
|
+
if (!pass) {
|
|
81
|
+
failed = failed || true;
|
|
82
|
+
messages.push(`Failed to validate node ${ii}\n${printNodes(node, testNodes[ii])}`);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return [testCase.title, !failed, messages.join('\n')];
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
return [testCase.title, false, 'Test must have either `select` or `selectAll`'];
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
results.forEach((result) => {
|
|
93
|
+
const [title, pass, message] = result;
|
|
94
|
+
if (pass === null)
|
|
95
|
+
session.log.info(`${chalk_1.default.redBright.bold(`ERROR`)} - ${title}\n ${chalk_1.default.blueBright(message)}`);
|
|
96
|
+
else if (pass)
|
|
97
|
+
session.log.info(`${chalk_1.default.green(`PASS`)} - ${title}`);
|
|
98
|
+
else
|
|
99
|
+
session.log.info(`${chalk_1.default.red(`FAIL`)} - ${title}\n\n${INDENT}${chalk_1.default.blueBright(message)}\n`);
|
|
100
|
+
}, true);
|
|
101
|
+
const passed = results.reduce((num, [, pass]) => num + (pass ? 1 : 0), 0);
|
|
102
|
+
const failed = results.length - passed;
|
|
103
|
+
if (failed > 0 && passed === 0) {
|
|
104
|
+
throw new Error(toc(`${chalk_1.default.red(`Failed ${failed} tests in %s`)} 👎`));
|
|
105
|
+
}
|
|
106
|
+
if (failed > 0) {
|
|
107
|
+
throw new Error(toc(`${chalk_1.default.green(`Passed ${passed}/${results.length} tests in %s`)}\n${chalk_1.default.red(`Failed ${failed} tests`)} 👎`));
|
|
108
|
+
}
|
|
109
|
+
session.log.info(chalk_1.default.green(toc(`Passed ${passed} tests in %s 🚀`)));
|
|
110
|
+
return true;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
exports.testJatsFile = testJatsFile;
|
|
114
|
+
function makeTestCLI(program) {
|
|
115
|
+
const command = new commander_1.Command('test')
|
|
116
|
+
.description('Test JATS file against a list of cases')
|
|
117
|
+
.argument('<file>', 'JATS file to test')
|
|
118
|
+
.addOption(new commander_1.Option('--cases <value>', 'The YAML file of unit tests to test against'))
|
|
119
|
+
.action((0, myst_cli_utils_1.clirun)(testJatsFile, { program, getSession: session_1.getSession }));
|
|
120
|
+
return command;
|
|
121
|
+
}
|
|
122
|
+
function addTestCLI(program) {
|
|
123
|
+
program.addCommand(makeTestCLI(program));
|
|
124
|
+
}
|
|
125
|
+
exports.addTestCLI = addTestCLI;
|
package/dist/cjs/cli/parse.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.addDownloadCLI = void 0;
|
|
15
|
+
exports.addDownloadCLI = exports.parseJats = void 0;
|
|
16
16
|
const commander_1 = require("commander");
|
|
17
17
|
const fs_1 = __importDefault(require("fs"));
|
|
18
18
|
const path_1 = require("path");
|
|
@@ -21,7 +21,7 @@ const doi_utils_1 = __importDefault(require("doi-utils"));
|
|
|
21
21
|
const chalk_1 = __importDefault(require("chalk"));
|
|
22
22
|
const fair_principles_1 = require("fair-principles");
|
|
23
23
|
const session_1 = require("../session");
|
|
24
|
-
const
|
|
24
|
+
const jats_tags_1 = require("jats-tags");
|
|
25
25
|
const jats_1 = require("../jats");
|
|
26
26
|
const myst_common_1 = require("myst-common");
|
|
27
27
|
const unist_util_select_1 = require("unist-util-select");
|
|
@@ -77,6 +77,7 @@ function parseJats(session, file, opts = { resolvers: resolvers_1.DEFAULT_RESOLV
|
|
|
77
77
|
return jats;
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
|
+
exports.parseJats = parseJats;
|
|
80
81
|
function formatLongString(data, offset = 0, length = 88 - offset) {
|
|
81
82
|
const out = [data.slice(0, length)];
|
|
82
83
|
let left = data.slice(length);
|
|
@@ -121,7 +122,7 @@ function jatsSummaryCLI(session, file) {
|
|
|
121
122
|
Title: (_a = (0, myst_common_1.toText)(jats.articleTitle)) === null || _a === void 0 ? void 0 : _a.replace(/\n/g, ' '),
|
|
122
123
|
Date: (0, utils_1.formatDate)((0, utils_1.toDate)(jats.publicationDate)),
|
|
123
124
|
Authors: jats.articleAuthors
|
|
124
|
-
.map((a) => `${(0, myst_common_1.toText)((0, unist_util_select_1.select)(
|
|
125
|
+
.map((a) => `${(0, myst_common_1.toText)((0, unist_util_select_1.select)(jats_tags_1.Tags.givenNames, a))} ${(0, myst_common_1.toText)((0, unist_util_select_1.select)(jats_tags_1.Tags.surname, a))}`)
|
|
125
126
|
.join(', '),
|
|
126
127
|
Abstract: (_b = (0, myst_common_1.toText)(jats.abstract)) === null || _b === void 0 ? void 0 : _b.replace(/\n/g, ' '),
|
|
127
128
|
Keywords: jats.keywords.map((k) => (0, myst_common_1.toText)(k)).join(', '),
|
|
@@ -130,32 +131,32 @@ function jatsSummaryCLI(session, file) {
|
|
|
130
131
|
if (jats.body) {
|
|
131
132
|
summary.Figures = {
|
|
132
133
|
label: chalk_1.default.blue.bold,
|
|
133
|
-
value: String((0, unist_util_select_1.selectAll)(
|
|
134
|
+
value: String((0, unist_util_select_1.selectAll)(jats_tags_1.Tags.fig, jats.body).length),
|
|
134
135
|
};
|
|
135
136
|
summary.Equations = {
|
|
136
137
|
label: chalk_1.default.blue.bold,
|
|
137
|
-
value: String((0, unist_util_select_1.selectAll)(
|
|
138
|
+
value: String((0, unist_util_select_1.selectAll)(jats_tags_1.Tags.dispFormula, jats.body).length),
|
|
138
139
|
};
|
|
139
140
|
summary.Tables = {
|
|
140
141
|
label: chalk_1.default.blue.bold,
|
|
141
|
-
value: String((0, unist_util_select_1.selectAll)(
|
|
142
|
+
value: String((0, unist_util_select_1.selectAll)(jats_tags_1.Tags.table, jats.body).length),
|
|
142
143
|
};
|
|
143
144
|
summary.Code = {
|
|
144
145
|
label: chalk_1.default.blue.bold,
|
|
145
|
-
value: String((0, unist_util_select_1.selectAll)(
|
|
146
|
+
value: String((0, unist_util_select_1.selectAll)(jats_tags_1.Tags.code, jats.body).length),
|
|
146
147
|
};
|
|
147
148
|
summary.Sections = {
|
|
148
149
|
label: chalk_1.default.blue.bold,
|
|
149
|
-
value: String((0, unist_util_select_1.selectAll)(
|
|
150
|
+
value: String((0, unist_util_select_1.selectAll)(jats_tags_1.Tags.sec, jats.body).length),
|
|
150
151
|
};
|
|
151
152
|
summary.Paragraphs = {
|
|
152
153
|
label: chalk_1.default.blue.bold,
|
|
153
|
-
value: String((0, unist_util_select_1.selectAll)(
|
|
154
|
+
value: String((0, unist_util_select_1.selectAll)(jats_tags_1.Tags.p, jats.body).length),
|
|
154
155
|
};
|
|
155
156
|
summary.Citations = { label: chalk_1.default.blue.bold, value: String(jats.references.length) };
|
|
156
157
|
summary['Cross-References'] = {
|
|
157
158
|
label: chalk_1.default.blue.bold,
|
|
158
|
-
value: String((0, unist_util_select_1.selectAll)(
|
|
159
|
+
value: String((0, unist_util_select_1.selectAll)(jats_tags_1.Tags.xref, jats.body).length),
|
|
159
160
|
};
|
|
160
161
|
summary['Sub Articles'] = { label: chalk_1.default.blue.bold, value: String(jats.subArticles.length) };
|
|
161
162
|
}
|
|
@@ -171,9 +172,9 @@ function jatsReferencesCLI(session, file) {
|
|
|
171
172
|
const sorted = jats.references
|
|
172
173
|
.map((ref) => {
|
|
173
174
|
const doiString = (0, utils_1.findArticleId)(ref, 'doi');
|
|
174
|
-
const title = (0, myst_common_1.toText)((0, unist_util_select_1.select)(
|
|
175
|
-
const year = (0, myst_common_1.toText)((0, unist_util_select_1.select)(
|
|
176
|
-
const surnames = (0, unist_util_select_1.selectAll)(
|
|
175
|
+
const title = (0, myst_common_1.toText)((0, unist_util_select_1.select)(jats_tags_1.Tags.articleTitle, ref));
|
|
176
|
+
const year = (0, myst_common_1.toText)((0, unist_util_select_1.select)(jats_tags_1.Tags.year, ref));
|
|
177
|
+
const surnames = (0, unist_util_select_1.selectAll)(jats_tags_1.Tags.surname, ref);
|
|
177
178
|
const short = surnames.length > 2
|
|
178
179
|
? (0, myst_common_1.toText)(surnames[0]) + ' et al.'
|
|
179
180
|
: surnames.length === 2
|
package/dist/cjs/jats.js
CHANGED
|
@@ -9,7 +9,7 @@ const xml_js_1 = require("xml-js");
|
|
|
9
9
|
const doi_utils_1 = __importDefault(require("doi-utils"));
|
|
10
10
|
const utils_1 = require("./utils");
|
|
11
11
|
const unist_util_select_1 = require("unist-util-select");
|
|
12
|
-
const
|
|
12
|
+
const jats_tags_1 = require("jats-tags");
|
|
13
13
|
const myst_cli_utils_1 = require("myst-cli-utils");
|
|
14
14
|
function select(selector, node) {
|
|
15
15
|
var _a;
|
|
@@ -44,8 +44,8 @@ class Jats {
|
|
|
44
44
|
const subtitle = this.articleSubtitle;
|
|
45
45
|
const date = this.publicationDate;
|
|
46
46
|
const authors = this.articleAuthors;
|
|
47
|
-
const firstSubject = select(
|
|
48
|
-
const journalTitle = select(
|
|
47
|
+
const firstSubject = select(jats_tags_1.Tags.subject, (_a = this.articleCategories) !== null && _a !== void 0 ? _a : this.front);
|
|
48
|
+
const journalTitle = select(jats_tags_1.Tags.journalTitle, this.front);
|
|
49
49
|
return {
|
|
50
50
|
title: title ? (0, myst_common_1.toText)(title) : undefined,
|
|
51
51
|
subtitle: subtitle ? (0, myst_common_1.toText)(subtitle) : undefined,
|
|
@@ -58,10 +58,10 @@ class Jats {
|
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
60
|
get front() {
|
|
61
|
-
return select(
|
|
61
|
+
return select(jats_tags_1.Tags.front, this.tree);
|
|
62
62
|
}
|
|
63
63
|
get premissions() {
|
|
64
|
-
return select(
|
|
64
|
+
return select(jats_tags_1.Tags.permissions, this.front);
|
|
65
65
|
}
|
|
66
66
|
get doi() {
|
|
67
67
|
var _a;
|
|
@@ -75,65 +75,65 @@ class Jats {
|
|
|
75
75
|
return (0, utils_1.findArticleId)(this.front, 'pmid');
|
|
76
76
|
}
|
|
77
77
|
get publicationDates() {
|
|
78
|
-
return (0, unist_util_select_1.selectAll)(
|
|
78
|
+
return (0, unist_util_select_1.selectAll)(jats_tags_1.Tags.pubDate, this.front);
|
|
79
79
|
}
|
|
80
80
|
get publicationDate() {
|
|
81
|
-
return this.publicationDates.find((d) => !!select(
|
|
81
|
+
return this.publicationDates.find((d) => !!select(jats_tags_1.Tags.day, d));
|
|
82
82
|
}
|
|
83
83
|
get license() {
|
|
84
|
-
return select(
|
|
84
|
+
return select(jats_tags_1.Tags.license, this.premissions);
|
|
85
85
|
}
|
|
86
86
|
get keywordGroup() {
|
|
87
|
-
return select(
|
|
87
|
+
return select(jats_tags_1.Tags.kwdGroup, this.front);
|
|
88
88
|
}
|
|
89
89
|
/** The first keywords */
|
|
90
90
|
get keywords() {
|
|
91
|
-
return (0, unist_util_select_1.selectAll)(
|
|
91
|
+
return (0, unist_util_select_1.selectAll)(jats_tags_1.Tags.kwd, this.keywordGroup);
|
|
92
92
|
}
|
|
93
93
|
get keywordGroups() {
|
|
94
|
-
return (0, unist_util_select_1.selectAll)(
|
|
94
|
+
return (0, unist_util_select_1.selectAll)(jats_tags_1.Tags.kwdGroup, this.front);
|
|
95
95
|
}
|
|
96
96
|
get articleCategories() {
|
|
97
|
-
return select(
|
|
97
|
+
return select(jats_tags_1.Tags.articleCategories, this.front);
|
|
98
98
|
}
|
|
99
99
|
get titleGroup() {
|
|
100
|
-
return select(
|
|
100
|
+
return select(jats_tags_1.Tags.titleGroup, this.front);
|
|
101
101
|
}
|
|
102
102
|
get articleTitle() {
|
|
103
|
-
return select(
|
|
103
|
+
return select(jats_tags_1.Tags.articleTitle, this.titleGroup);
|
|
104
104
|
}
|
|
105
105
|
get articleSubtitle() {
|
|
106
|
-
return select(
|
|
106
|
+
return select(jats_tags_1.Tags.subtitle, this.titleGroup);
|
|
107
107
|
}
|
|
108
108
|
get abstract() {
|
|
109
|
-
return select(
|
|
109
|
+
return select(jats_tags_1.Tags.abstract, this.front);
|
|
110
110
|
}
|
|
111
111
|
get abstracts() {
|
|
112
|
-
return (0, unist_util_select_1.selectAll)(
|
|
112
|
+
return (0, unist_util_select_1.selectAll)(jats_tags_1.Tags.abstract, this.front);
|
|
113
113
|
}
|
|
114
114
|
get contribGroup() {
|
|
115
|
-
return select(
|
|
115
|
+
return select(jats_tags_1.Tags.contribGroup, this.front);
|
|
116
116
|
}
|
|
117
117
|
get contribGroups() {
|
|
118
|
-
return (0, unist_util_select_1.selectAll)(
|
|
118
|
+
return (0, unist_util_select_1.selectAll)(jats_tags_1.Tags.contribGroup, this.front);
|
|
119
119
|
}
|
|
120
120
|
get articleAuthors() {
|
|
121
|
-
return (0, unist_util_select_1.selectAll)(
|
|
121
|
+
return (0, unist_util_select_1.selectAll)(jats_tags_1.Tags.contrib, this.contribGroup);
|
|
122
122
|
}
|
|
123
123
|
get body() {
|
|
124
|
-
return select(
|
|
124
|
+
return select(jats_tags_1.Tags.body, this.tree);
|
|
125
125
|
}
|
|
126
126
|
get back() {
|
|
127
|
-
return select(
|
|
127
|
+
return select(jats_tags_1.Tags.back, this.tree);
|
|
128
128
|
}
|
|
129
129
|
get subArticles() {
|
|
130
|
-
return (0, unist_util_select_1.selectAll)(
|
|
130
|
+
return (0, unist_util_select_1.selectAll)(jats_tags_1.Tags.subArticle, this.tree);
|
|
131
131
|
}
|
|
132
132
|
get refList() {
|
|
133
|
-
return select(
|
|
133
|
+
return select(jats_tags_1.Tags.refList, this.back);
|
|
134
134
|
}
|
|
135
135
|
get references() {
|
|
136
|
-
return (0, unist_util_select_1.selectAll)(
|
|
136
|
+
return (0, unist_util_select_1.selectAll)(jats_tags_1.Tags.ref, this.refList);
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
exports.Jats = Jats;
|
package/dist/cjs/utils.js
CHANGED
|
@@ -7,24 +7,29 @@ exports.authorAndAffiliation = exports.findArticleId = exports.formatDate = expo
|
|
|
7
7
|
const myst_common_1 = require("myst-common");
|
|
8
8
|
const doi_utils_1 = __importDefault(require("doi-utils"));
|
|
9
9
|
const unist_util_select_1 = require("unist-util-select");
|
|
10
|
-
const
|
|
10
|
+
const jats_tags_1 = require("jats-tags");
|
|
11
11
|
function convertToUnist(node) {
|
|
12
12
|
switch (node.type) {
|
|
13
13
|
case 'element': {
|
|
14
14
|
const { name, attributes, elements } = node;
|
|
15
15
|
const children = elements === null || elements === void 0 ? void 0 : elements.map(convertToUnist).filter((n) => !!n);
|
|
16
16
|
const next = Object.assign({ type: name !== null && name !== void 0 ? name : 'unknown' }, attributes);
|
|
17
|
-
if (
|
|
17
|
+
if (name === 'code') {
|
|
18
|
+
next.value = elements === null || elements === void 0 ? void 0 : elements[0].text;
|
|
19
|
+
}
|
|
20
|
+
else if (children)
|
|
18
21
|
next.children = children;
|
|
19
22
|
return next;
|
|
20
23
|
}
|
|
21
24
|
case 'text': {
|
|
22
25
|
const { attributes, text } = node;
|
|
23
|
-
return Object.assign(Object.assign({ type: 'text' }, attributes), { value: String(text)
|
|
26
|
+
return Object.assign(Object.assign({ type: 'text' }, attributes), { value: String(text)
|
|
27
|
+
.replace(/\n(\s+)$/, '')
|
|
28
|
+
.replace('\n', ' ') });
|
|
24
29
|
}
|
|
25
30
|
case 'cdata': {
|
|
26
31
|
const { attributes, cdata } = node;
|
|
27
|
-
return Object.assign(Object.assign({ type: 'cdata' }, attributes), { cdata });
|
|
32
|
+
return Object.assign(Object.assign({ type: 'cdata' }, attributes), { cdata: String(cdata).trim() });
|
|
28
33
|
}
|
|
29
34
|
case 'comment': {
|
|
30
35
|
const { comment } = node;
|
|
@@ -100,13 +105,13 @@ function findArticleId(node, pubIdType = 'doi') {
|
|
|
100
105
|
const id = (0, unist_util_select_1.select)(`[pub-id-type=${pubIdType}]`, node);
|
|
101
106
|
if (id && (0, myst_common_1.toText)(id))
|
|
102
107
|
return (0, myst_common_1.toText)(id);
|
|
103
|
-
const doiTag = (0, unist_util_select_1.selectAll)(`${
|
|
108
|
+
const doiTag = (0, unist_util_select_1.selectAll)(`${jats_tags_1.Tags.articleId},${jats_tags_1.Tags.pubId}`, node).find((t) => doi_utils_1.default.validate((0, myst_common_1.toText)(t)));
|
|
104
109
|
return (0, myst_common_1.toText)(doiTag) || undefined;
|
|
105
110
|
}
|
|
106
111
|
exports.findArticleId = findArticleId;
|
|
107
112
|
function authorAndAffiliation(node, article) {
|
|
108
113
|
const author = {
|
|
109
|
-
name: `${(0, myst_common_1.toText)((0, unist_util_select_1.select)(
|
|
114
|
+
name: `${(0, myst_common_1.toText)((0, unist_util_select_1.select)(jats_tags_1.Tags.givenNames, node))} ${(0, myst_common_1.toText)((0, unist_util_select_1.select)(jats_tags_1.Tags.surname, node))}`,
|
|
110
115
|
};
|
|
111
116
|
const orcid = (0, unist_util_select_1.select)('[contrib-id-type=orcid]', node);
|
|
112
117
|
if (orcid) {
|
package/dist/cjs/version.js
CHANGED
package/dist/esm/cli/index.js
CHANGED
|
@@ -3,9 +3,11 @@ import commander from 'commander';
|
|
|
3
3
|
import version from '../version';
|
|
4
4
|
import { addDownloadCLI } from './parse';
|
|
5
5
|
import { addValidateCLI } from './validate';
|
|
6
|
+
import { addTestCLI } from './jats-test';
|
|
6
7
|
const program = new commander.Command();
|
|
7
8
|
addDownloadCLI(program);
|
|
8
9
|
addValidateCLI(program);
|
|
10
|
+
addTestCLI(program);
|
|
9
11
|
program.version(`v${version}`, '-v, --version', 'Print the current version of jats-xml');
|
|
10
12
|
program.option('-d, --debug', 'Log out any errors to the console.');
|
|
11
13
|
program.parse(process.argv);
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Command, Option } from 'commander';
|
|
11
|
+
import { clirun, tic } from 'myst-cli-utils';
|
|
12
|
+
import { getSession } from '../session';
|
|
13
|
+
import yaml from 'js-yaml';
|
|
14
|
+
import fs from 'fs';
|
|
15
|
+
import { parseJats } from './parse';
|
|
16
|
+
import { select, selectAll } from 'unist-util-select';
|
|
17
|
+
import { is } from 'unist-util-is';
|
|
18
|
+
import chalk from 'chalk';
|
|
19
|
+
const INDENT = ' ';
|
|
20
|
+
function printNodes(expected, received) {
|
|
21
|
+
return chalk.reset(`\n${INDENT}${chalk.greenBright('Expected node containing')}:\n${INDENT} ${yaml
|
|
22
|
+
.dump(expected)
|
|
23
|
+
.replace(/\n/g, `\n${INDENT} `)}\n${INDENT}${chalk.redBright('Received node')}:\n${INDENT} ${yaml.dump(received).replace(/\n/g, `\n${INDENT} `)}`);
|
|
24
|
+
}
|
|
25
|
+
export function testJatsFile(session, file, opts) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
const toc = tic();
|
|
28
|
+
const jats = yield parseJats(session, file);
|
|
29
|
+
const tests = yaml.load(fs.readFileSync(opts.cases).toString());
|
|
30
|
+
const results = tests.cases.map((testCase, index) => {
|
|
31
|
+
if (!testCase.title) {
|
|
32
|
+
return [`Test Case ${index}`, null, 'Test must include a title'];
|
|
33
|
+
}
|
|
34
|
+
if (testCase.equals === undefined) {
|
|
35
|
+
return [testCase.title, null, 'Test must have an equals statement'];
|
|
36
|
+
}
|
|
37
|
+
if (testCase.select) {
|
|
38
|
+
const node = select(testCase.select, jats.tree);
|
|
39
|
+
const pass = is(node, testCase.equals);
|
|
40
|
+
if (testCase.equals == null && node) {
|
|
41
|
+
return [testCase.title, false, 'Expected no node to be present'];
|
|
42
|
+
}
|
|
43
|
+
if (!node && testCase.equals == null)
|
|
44
|
+
return [testCase.title, true];
|
|
45
|
+
if (!node)
|
|
46
|
+
return [testCase.title, false];
|
|
47
|
+
let failed = false;
|
|
48
|
+
const messages = [];
|
|
49
|
+
if (!pass) {
|
|
50
|
+
failed = failed || true;
|
|
51
|
+
messages.push(`Failed to validate node\n${printNodes(testCase.equals, node)}`);
|
|
52
|
+
}
|
|
53
|
+
return [testCase.title, !failed, messages.join('\n')];
|
|
54
|
+
}
|
|
55
|
+
else if (testCase.selectAll) {
|
|
56
|
+
const testNodes = selectAll(testCase.selectAll, jats.tree);
|
|
57
|
+
if (!testNodes && testCase.equals == null)
|
|
58
|
+
return [testCase.title, true];
|
|
59
|
+
if (!testNodes)
|
|
60
|
+
return [testCase.title, false, 'Node not found'];
|
|
61
|
+
let equals = testCase.equals;
|
|
62
|
+
if (!Array.isArray(testCase.equals)) {
|
|
63
|
+
equals = Array(testNodes.length).fill(testCase.equals);
|
|
64
|
+
}
|
|
65
|
+
let failed = false;
|
|
66
|
+
const messages = [];
|
|
67
|
+
if (equals.length !== testNodes.length) {
|
|
68
|
+
failed = failed || true;
|
|
69
|
+
messages.push(`Expected ${equals.length} nodes, got ${testNodes.length}\n${printNodes(equals, testNodes)}`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
equals.forEach((node, ii) => {
|
|
73
|
+
const pass = is(testNodes[ii], node);
|
|
74
|
+
if (!pass) {
|
|
75
|
+
failed = failed || true;
|
|
76
|
+
messages.push(`Failed to validate node ${ii}\n${printNodes(node, testNodes[ii])}`);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return [testCase.title, !failed, messages.join('\n')];
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return [testCase.title, false, 'Test must have either `select` or `selectAll`'];
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
results.forEach((result) => {
|
|
87
|
+
const [title, pass, message] = result;
|
|
88
|
+
if (pass === null)
|
|
89
|
+
session.log.info(`${chalk.redBright.bold(`ERROR`)} - ${title}\n ${chalk.blueBright(message)}`);
|
|
90
|
+
else if (pass)
|
|
91
|
+
session.log.info(`${chalk.green(`PASS`)} - ${title}`);
|
|
92
|
+
else
|
|
93
|
+
session.log.info(`${chalk.red(`FAIL`)} - ${title}\n\n${INDENT}${chalk.blueBright(message)}\n`);
|
|
94
|
+
}, true);
|
|
95
|
+
const passed = results.reduce((num, [, pass]) => num + (pass ? 1 : 0), 0);
|
|
96
|
+
const failed = results.length - passed;
|
|
97
|
+
if (failed > 0 && passed === 0) {
|
|
98
|
+
throw new Error(toc(`${chalk.red(`Failed ${failed} tests in %s`)} 👎`));
|
|
99
|
+
}
|
|
100
|
+
if (failed > 0) {
|
|
101
|
+
throw new Error(toc(`${chalk.green(`Passed ${passed}/${results.length} tests in %s`)}\n${chalk.red(`Failed ${failed} tests`)} 👎`));
|
|
102
|
+
}
|
|
103
|
+
session.log.info(chalk.green(toc(`Passed ${passed} tests in %s 🚀`)));
|
|
104
|
+
return true;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function makeTestCLI(program) {
|
|
108
|
+
const command = new Command('test')
|
|
109
|
+
.description('Test JATS file against a list of cases')
|
|
110
|
+
.argument('<file>', 'JATS file to test')
|
|
111
|
+
.addOption(new Option('--cases <value>', 'The YAML file of unit tests to test against'))
|
|
112
|
+
.action(clirun(testJatsFile, { program, getSession }));
|
|
113
|
+
return command;
|
|
114
|
+
}
|
|
115
|
+
export function addTestCLI(program) {
|
|
116
|
+
program.addCommand(makeTestCLI(program));
|
|
117
|
+
}
|
package/dist/esm/cli/parse.js
CHANGED
|
@@ -15,7 +15,7 @@ import doi from 'doi-utils';
|
|
|
15
15
|
import chalk from 'chalk';
|
|
16
16
|
import { formatPrinciples, highlightFAIR } from 'fair-principles';
|
|
17
17
|
import { getSession } from '../session';
|
|
18
|
-
import { Tags } from '
|
|
18
|
+
import { Tags } from 'jats-tags';
|
|
19
19
|
import { Jats } from '../jats';
|
|
20
20
|
import { toText } from 'myst-common';
|
|
21
21
|
import { select, selectAll } from 'unist-util-select';
|
|
@@ -53,7 +53,7 @@ function logAboutJatsFailing(session, jatsUrls) {
|
|
|
53
53
|
session.log.debug(formatPrinciples('A*', { chalk }));
|
|
54
54
|
session.log.info(`\n${chalk.blue('The link may work in a browser.')}\n`);
|
|
55
55
|
}
|
|
56
|
-
function parseJats(session, file, opts = { resolvers: DEFAULT_RESOLVERS }) {
|
|
56
|
+
export function parseJats(session, file, opts = { resolvers: DEFAULT_RESOLVERS }) {
|
|
57
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58
58
|
const toc = tic();
|
|
59
59
|
if (fs.existsSync(file)) {
|
package/dist/esm/jats.js
CHANGED
|
@@ -3,7 +3,7 @@ import { xml2js } from 'xml-js';
|
|
|
3
3
|
import doi from 'doi-utils';
|
|
4
4
|
import { authorAndAffiliation, convertToUnist, findArticleId, toDate } from './utils';
|
|
5
5
|
import { select as unistSelect, selectAll } from 'unist-util-select';
|
|
6
|
-
import { Tags } from '
|
|
6
|
+
import { Tags } from 'jats-tags';
|
|
7
7
|
import { tic } from 'myst-cli-utils';
|
|
8
8
|
function select(selector, node) {
|
|
9
9
|
var _a;
|
package/dist/esm/utils.js
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
import { toText } from 'myst-common';
|
|
2
2
|
import doi from 'doi-utils';
|
|
3
3
|
import { select, selectAll } from 'unist-util-select';
|
|
4
|
-
import { Tags } from '
|
|
4
|
+
import { Tags } from 'jats-tags';
|
|
5
5
|
export function convertToUnist(node) {
|
|
6
6
|
switch (node.type) {
|
|
7
7
|
case 'element': {
|
|
8
8
|
const { name, attributes, elements } = node;
|
|
9
9
|
const children = elements === null || elements === void 0 ? void 0 : elements.map(convertToUnist).filter((n) => !!n);
|
|
10
10
|
const next = Object.assign({ type: name !== null && name !== void 0 ? name : 'unknown' }, attributes);
|
|
11
|
-
if (
|
|
11
|
+
if (name === 'code') {
|
|
12
|
+
next.value = elements === null || elements === void 0 ? void 0 : elements[0].text;
|
|
13
|
+
}
|
|
14
|
+
else if (children)
|
|
12
15
|
next.children = children;
|
|
13
16
|
return next;
|
|
14
17
|
}
|
|
15
18
|
case 'text': {
|
|
16
19
|
const { attributes, text } = node;
|
|
17
|
-
return Object.assign(Object.assign({ type: 'text' }, attributes), { value: String(text)
|
|
20
|
+
return Object.assign(Object.assign({ type: 'text' }, attributes), { value: String(text)
|
|
21
|
+
.replace(/\n(\s+)$/, '')
|
|
22
|
+
.replace('\n', ' ') });
|
|
18
23
|
}
|
|
19
24
|
case 'cdata': {
|
|
20
25
|
const { attributes, cdata } = node;
|
|
21
|
-
return Object.assign(Object.assign({ type: 'cdata' }, attributes), { cdata });
|
|
26
|
+
return Object.assign(Object.assign({ type: 'cdata' }, attributes), { cdata: String(cdata).trim() });
|
|
22
27
|
}
|
|
23
28
|
case 'comment': {
|
|
24
29
|
const { comment } = node;
|
package/dist/esm/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const version = '0.0
|
|
1
|
+
const version = '0.1.0';
|
|
2
2
|
export default version;
|