jats-xml 0.0.15 → 0.0.16
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/dist/cjs/cli/validate.js +11 -4
- package/dist/cjs/validate/dtd.js +168 -18
- package/dist/cjs/version.js +1 -1
- package/dist/esm/cli/validate.js +11 -4
- package/dist/esm/validate/dtd.js +166 -17
- package/dist/esm/version.js +1 -1
- package/dist/jats.js +140 -22
- package/dist/types/cli/validate.d.ts.map +1 -1
- package/dist/types/validate/dtd.d.ts +19 -2
- package/dist/types/validate/dtd.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/cjs/cli/validate.js
CHANGED
|
@@ -7,11 +7,18 @@ const session_1 = require("../session");
|
|
|
7
7
|
const validate_1 = require("../validate");
|
|
8
8
|
function makeValidateCLI(program) {
|
|
9
9
|
const command = new commander_1.Command('validate')
|
|
10
|
-
.description(
|
|
10
|
+
.description(`
|
|
11
|
+
Validate JATS file against DTD schema.
|
|
12
|
+
|
|
13
|
+
The JATS DTD schema file is fetched from nih.gov ftp server if not available locally.
|
|
14
|
+
This will attempt to infer the specific JATS DTD version, library, etc from the file header,
|
|
15
|
+
but options are available to override the inferred values.
|
|
16
|
+
`)
|
|
11
17
|
.argument('<file>', 'JATS file to validate')
|
|
12
|
-
.addOption(new commander_1.Option('--
|
|
13
|
-
.addOption(new commander_1.Option('--
|
|
14
|
-
.addOption(new commander_1.Option('--
|
|
18
|
+
.addOption(new commander_1.Option('--library <value>', 'JATS library - archiving, publishing, or authoring (default: archiving, if value cannot be inferred from file)'))
|
|
19
|
+
.addOption(new commander_1.Option('--jats <version>', 'JATS version, must be 1.1 or later (default: 1.3, if value cannot be inferred from file)'))
|
|
20
|
+
.addOption(new commander_1.Option('--mathml <version>', 'MathML version, 2 or 3 (default: 3, if value cannot be inferred from file)'))
|
|
21
|
+
.addOption(new commander_1.Option('--oasis', 'Use OASIS table model (default: false, if value cannot be inferred from file)'))
|
|
15
22
|
.addOption(new commander_1.Option('--directory <value>', 'Directory to save DTD file'))
|
|
16
23
|
.action((0, myst_cli_utils_1.clirun)(validate_1.validateJatsAgainstDtdWrapper, { program, getSession: session_1.getSession }));
|
|
17
24
|
return command;
|
package/dist/cjs/validate/dtd.js
CHANGED
|
@@ -35,7 +35,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.validateJatsAgainstDtdWrapper = exports.validateJatsAgainstDtd = void 0;
|
|
38
|
+
exports.validateJatsAgainstDtdWrapper = exports.validateJatsAgainstDtd = exports.inferOptions = void 0;
|
|
39
39
|
const fs_1 = __importStar(require("fs"));
|
|
40
40
|
const path_1 = __importDefault(require("path"));
|
|
41
41
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
@@ -43,15 +43,54 @@ const unzipper_1 = __importDefault(require("unzipper"));
|
|
|
43
43
|
const which_1 = require("which");
|
|
44
44
|
const myst_cli_utils_1 = require("myst-cli-utils");
|
|
45
45
|
const chalk_1 = __importDefault(require("chalk"));
|
|
46
|
-
const JATS_VERSIONS = [
|
|
46
|
+
const JATS_VERSIONS = [
|
|
47
|
+
'1.1',
|
|
48
|
+
'1.1d1',
|
|
49
|
+
'1.1d2',
|
|
50
|
+
'1.1d3',
|
|
51
|
+
'1.2',
|
|
52
|
+
'1.2d1',
|
|
53
|
+
'1.2d2',
|
|
54
|
+
'1.3',
|
|
55
|
+
'1.3d1',
|
|
56
|
+
'1.3d2',
|
|
57
|
+
];
|
|
47
58
|
const DEFAULT_JATS_VERSION = '1.3';
|
|
48
59
|
const MATHML_VERSIONS = ['2', '3'];
|
|
49
60
|
const DEFAULT_MATHML_VERSION = '3';
|
|
50
|
-
|
|
51
|
-
|
|
61
|
+
const JATS_LIBRARIES = ['authoring', 'publishing', 'archiving'];
|
|
62
|
+
const DEFAULT_JATS_LIBRARY = 'archiving';
|
|
63
|
+
/**
|
|
64
|
+
* Return static/ directory adjacent to the code
|
|
65
|
+
*
|
|
66
|
+
* This provides a standard location to cache DTD files, minimizing re-downloading.
|
|
67
|
+
*/
|
|
68
|
+
function defaultDirectory() {
|
|
69
|
+
return path_1.default.join(__dirname, 'static');
|
|
70
|
+
}
|
|
71
|
+
function warnOnOptionsMismatch(session, opts, inferredOpts) {
|
|
72
|
+
if (opts.jats && inferredOpts.jats && opts.jats !== inferredOpts.jats) {
|
|
73
|
+
session.log.warn(`Using JATS version ${opts.jats}; does not match version inferred from file ${inferredOpts.jats}`);
|
|
74
|
+
}
|
|
75
|
+
if (opts.library && inferredOpts.library && opts.library !== inferredOpts.library) {
|
|
76
|
+
session.log.warn(`Using JATS library ${opts.library}; does not match library inferred from file ${inferredOpts.library}`);
|
|
77
|
+
}
|
|
78
|
+
if (opts.mathml && inferredOpts.mathml && opts.mathml !== inferredOpts.mathml) {
|
|
79
|
+
session.log.warn(`Using MathML version ${opts.mathml}; does not match version inferred from file ${inferredOpts.mathml}`);
|
|
80
|
+
}
|
|
81
|
+
if (opts.oasis && !inferredOpts.oasis) {
|
|
82
|
+
session.log.warn('Using OASIS table model; does not match non-OASIS inferred from file');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Validate input value as JATS options and fill in defaults
|
|
87
|
+
*/
|
|
88
|
+
function validateOptions(session, opts, inferredOpts) {
|
|
89
|
+
var _a, _b, _c, _d, _e;
|
|
90
|
+
warnOnOptionsMismatch(session, opts, inferredOpts);
|
|
52
91
|
let jats;
|
|
53
92
|
if (!opts.jats) {
|
|
54
|
-
jats = DEFAULT_JATS_VERSION;
|
|
93
|
+
jats = (_a = inferredOpts.jats) !== null && _a !== void 0 ? _a : DEFAULT_JATS_VERSION;
|
|
55
94
|
}
|
|
56
95
|
else if (!JATS_VERSIONS.includes(opts.jats)) {
|
|
57
96
|
throw new Error(`Invalid JATS version "${opts.jats}" - must be one of [${JATS_VERSIONS.join(', ')}]`);
|
|
@@ -61,7 +100,7 @@ function validateOptions(opts) {
|
|
|
61
100
|
}
|
|
62
101
|
let mathml;
|
|
63
102
|
if (!opts.mathml) {
|
|
64
|
-
mathml = DEFAULT_MATHML_VERSION;
|
|
103
|
+
mathml = (_b = inferredOpts.mathml) !== null && _b !== void 0 ? _b : DEFAULT_MATHML_VERSION;
|
|
65
104
|
}
|
|
66
105
|
else if (!MATHML_VERSIONS.includes(opts.mathml)) {
|
|
67
106
|
throw new Error(`Invalid MathML version "${opts.mathml}" - must be one of [${MATHML_VERSIONS.join(', ')}]`);
|
|
@@ -69,41 +108,128 @@ function validateOptions(opts) {
|
|
|
69
108
|
else {
|
|
70
109
|
mathml = opts.mathml;
|
|
71
110
|
}
|
|
111
|
+
let library;
|
|
112
|
+
if (!opts.library) {
|
|
113
|
+
library = (_c = inferredOpts.library) !== null && _c !== void 0 ? _c : DEFAULT_JATS_LIBRARY;
|
|
114
|
+
}
|
|
115
|
+
else if (typeof opts.library !== 'string' ||
|
|
116
|
+
!JATS_LIBRARIES.includes(opts.library.toLowerCase())) {
|
|
117
|
+
throw new Error(`Invalid JATS library "${opts.library}" - must be one of [${JATS_LIBRARIES.join(', ')}]`);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
library = opts.library.toLowerCase();
|
|
121
|
+
}
|
|
122
|
+
const oasis = (_d = inferredOpts.oasis) !== null && _d !== void 0 ? _d : !!opts.oasis;
|
|
123
|
+
if (library === 'authoring' && oasis) {
|
|
124
|
+
throw new Error('JATS article authoring library cannot use OASIS table model');
|
|
125
|
+
}
|
|
72
126
|
const out = {
|
|
127
|
+
library,
|
|
73
128
|
jats,
|
|
74
129
|
mathml,
|
|
75
|
-
oasis
|
|
76
|
-
directory: (
|
|
130
|
+
oasis,
|
|
131
|
+
directory: (_e = opts.directory) !== null && _e !== void 0 ? _e : defaultDirectory(),
|
|
77
132
|
};
|
|
78
133
|
return out;
|
|
79
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* DTD folder name
|
|
137
|
+
*/
|
|
80
138
|
function dtdFolder(opts) {
|
|
81
139
|
const version = opts.jats.replace('.', '-');
|
|
82
140
|
const oasis = opts.oasis ? '-OASIS' : '';
|
|
83
141
|
const mathml = `MathML${opts.mathml}`;
|
|
84
|
-
|
|
142
|
+
const library = opts.library.charAt(0).toUpperCase() + opts.library.slice(1);
|
|
143
|
+
return `JATS-${library}-${version}${oasis}-${mathml}-DTD`;
|
|
85
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* DTD zip file name on FTP server
|
|
147
|
+
*/
|
|
86
148
|
function dtdZipFile(opts) {
|
|
87
149
|
return `${dtdFolder(opts)}.zip`;
|
|
88
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Local location of DTD zip file
|
|
153
|
+
*/
|
|
89
154
|
function localDtdZipFile(opts) {
|
|
90
155
|
return path_1.default.join(opts.directory, dtdZipFile(opts));
|
|
91
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Extracted DTD file name
|
|
159
|
+
*/
|
|
92
160
|
function dtdFile(opts) {
|
|
93
|
-
const version = opts.jats.startsWith('1.
|
|
94
|
-
|
|
161
|
+
const version = opts.jats.startsWith('1.3') ? opts.jats.replace('.', '-') : '1';
|
|
162
|
+
let article;
|
|
163
|
+
if (opts.library === 'archiving') {
|
|
164
|
+
article = opts.oasis ? 'archive-oasis-article' : 'archivearticle';
|
|
165
|
+
}
|
|
166
|
+
else if (opts.library === 'publishing') {
|
|
167
|
+
article = opts.oasis ? 'journalpublishing-oasis-article' : 'journalpublishing';
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
article = 'articleauthoring';
|
|
171
|
+
}
|
|
95
172
|
const mathml = opts.mathml === '3' ? '-mathml3' : '';
|
|
96
173
|
return `JATS-${article}${version}${mathml}.dtd`;
|
|
97
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Local location of extracted DTD file
|
|
177
|
+
*/
|
|
98
178
|
function localDtdFile(opts) {
|
|
99
179
|
return path_1.default.join(opts.directory, dtdFolder(opts), dtdFile(opts));
|
|
100
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* NIH FTP server and path for downloading JATS DTD files
|
|
183
|
+
*
|
|
184
|
+
* This is accessed by node-fetch over https.
|
|
185
|
+
*/
|
|
101
186
|
function ftpUrl(opts) {
|
|
102
|
-
|
|
187
|
+
const library = opts.library === 'authoring' ? 'articleauthoring' : opts.library;
|
|
188
|
+
return `https://ftp.ncbi.nih.gov/pub/jats/${library}/${opts.jats}/${dtdZipFile(opts)}`;
|
|
103
189
|
}
|
|
104
|
-
|
|
105
|
-
|
|
190
|
+
/**
|
|
191
|
+
* Create a DTS-filename-options lookup for implicitly setting options based on JATS header content
|
|
192
|
+
*/
|
|
193
|
+
function buildDtdFileLookup() {
|
|
194
|
+
const lookup = {};
|
|
195
|
+
JATS_VERSIONS.filter((jats) => jats === '1.2' || jats.startsWith('1.3')).forEach((jats) => {
|
|
196
|
+
MATHML_VERSIONS.forEach((mathml) => {
|
|
197
|
+
JATS_LIBRARIES.forEach((library) => {
|
|
198
|
+
(library === 'authoring' ? [false] : [true, false]).forEach((oasis) => {
|
|
199
|
+
const opts = { jats, mathml, library, oasis };
|
|
200
|
+
lookup[dtdFile(opts)] = opts;
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
return lookup;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Infer DTD options from file content
|
|
209
|
+
*
|
|
210
|
+
* This looks at DTD file name in DOCTYPE as well as dtd-version in article element
|
|
211
|
+
*/
|
|
212
|
+
function inferOptions(file) {
|
|
213
|
+
var _a, _b;
|
|
214
|
+
const data = fs_1.default.readFileSync(file).toString();
|
|
215
|
+
const doctype = (_a = data.match(/<!DOCTYPE [\s\S]+?">/g)) === null || _a === void 0 ? void 0 : _a[0];
|
|
216
|
+
const lookup = buildDtdFileLookup();
|
|
217
|
+
let opts = {};
|
|
218
|
+
Object.entries(lookup).forEach(([key, value]) => {
|
|
219
|
+
if (doctype === null || doctype === void 0 ? void 0 : doctype.includes(key))
|
|
220
|
+
opts = Object.assign({}, value);
|
|
221
|
+
});
|
|
222
|
+
const article = (_b = data.match(/<article [\s\S]+?>/g)) === null || _b === void 0 ? void 0 : _b[0];
|
|
223
|
+
JATS_VERSIONS.forEach((jats) => {
|
|
224
|
+
if (article === null || article === void 0 ? void 0 : article.includes(`dtd-version="${jats}"`))
|
|
225
|
+
opts.jats = jats;
|
|
226
|
+
});
|
|
227
|
+
return opts;
|
|
106
228
|
}
|
|
229
|
+
exports.inferOptions = inferOptions;
|
|
230
|
+
/**
|
|
231
|
+
* Download DTD zip file from NIH FTP server
|
|
232
|
+
*/
|
|
107
233
|
function dtdDownload(session, opts) {
|
|
108
234
|
return __awaiter(this, void 0, void 0, function* () {
|
|
109
235
|
if (!fs_1.default.existsSync(opts.directory)) {
|
|
@@ -115,6 +241,9 @@ function dtdDownload(session, opts) {
|
|
|
115
241
|
(0, myst_cli_utils_1.writeFileToFolder)(localDtdZipFile(opts), yield resp.buffer());
|
|
116
242
|
});
|
|
117
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Download DTD zip file from NIH FTP server if it does not yet exist
|
|
246
|
+
*/
|
|
118
247
|
function ensureDtdZipExists(session, opts) {
|
|
119
248
|
return __awaiter(this, void 0, void 0, function* () {
|
|
120
249
|
if (!fs_1.default.existsSync(path_1.default.join(opts.directory, dtdZipFile(opts)))) {
|
|
@@ -122,32 +251,48 @@ function ensureDtdZipExists(session, opts) {
|
|
|
122
251
|
}
|
|
123
252
|
});
|
|
124
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Download and extract DTD file if it does not yet exist
|
|
256
|
+
*/
|
|
125
257
|
function ensureDtdExists(session, opts) {
|
|
126
258
|
return __awaiter(this, void 0, void 0, function* () {
|
|
127
259
|
if (!fs_1.default.existsSync(localDtdFile(opts))) {
|
|
128
260
|
yield ensureDtdZipExists(session, opts);
|
|
129
261
|
const zipFile = localDtdZipFile(opts);
|
|
130
|
-
session.log.info(`🤐 Unzipping template
|
|
262
|
+
session.log.info(`🤐 Unzipping template: ${zipFile}`);
|
|
131
263
|
yield (0, fs_1.createReadStream)(zipFile)
|
|
132
264
|
.pipe(unzipper_1.default.Extract({ path: opts.directory }))
|
|
133
265
|
.promise();
|
|
134
266
|
}
|
|
135
|
-
session.log.debug(`Validating against ${localDtdFile(opts)}`);
|
|
136
267
|
});
|
|
137
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Test if xmllint is available as a cli command
|
|
271
|
+
*/
|
|
138
272
|
function isXmllintAvailable() {
|
|
139
273
|
return (0, which_1.sync)('xmllint', { nothrow: true });
|
|
140
274
|
}
|
|
275
|
+
/**
|
|
276
|
+
* Check if JATS file is valid based on JATS version/library/etc.
|
|
277
|
+
*
|
|
278
|
+
* Returns true if valid and false if invalid.
|
|
279
|
+
*/
|
|
141
280
|
function validateJatsAgainstDtd(session, file, opts) {
|
|
142
281
|
return __awaiter(this, void 0, void 0, function* () {
|
|
143
282
|
if (!isXmllintAvailable()) {
|
|
144
283
|
session.log.error(`JATS validation against DTD requires xmllint\n\n${chalk_1.default.dim('To install:\n mac: brew install xmlstarlet\n debian: apt install libxml2-utils')}`);
|
|
145
284
|
return;
|
|
146
285
|
}
|
|
147
|
-
const
|
|
286
|
+
const inferredOpts = inferOptions(file);
|
|
287
|
+
const validatedOpts = validateOptions(session, opts !== null && opts !== void 0 ? opts : {}, inferredOpts);
|
|
148
288
|
yield ensureDtdExists(session, validatedOpts);
|
|
289
|
+
session.log.debug(`Validating against: ${localDtdFile(validatedOpts)}`);
|
|
290
|
+
session.log.info(`🧐 Validating against: ${dtdFolder(validatedOpts)}`);
|
|
149
291
|
try {
|
|
150
|
-
|
|
292
|
+
// First drop DOCTYPE with DTD in it - we have already fetched the DTD
|
|
293
|
+
const dropDtdCommand = `xmllint --dropdtd`;
|
|
294
|
+
const validateCommand = `xmllint --noout --dtdvalid ${localDtdFile(validatedOpts)}`;
|
|
295
|
+
yield (0, myst_cli_utils_1.makeExecutable)(`${dropDtdCommand} ${file} | ${validateCommand} -`, session.log)();
|
|
151
296
|
}
|
|
152
297
|
catch (_a) {
|
|
153
298
|
return false;
|
|
@@ -156,6 +301,11 @@ function validateJatsAgainstDtd(session, file, opts) {
|
|
|
156
301
|
});
|
|
157
302
|
}
|
|
158
303
|
exports.validateJatsAgainstDtd = validateJatsAgainstDtd;
|
|
304
|
+
/**
|
|
305
|
+
* Check if JATS file is valid based on JATS version/library/etc.
|
|
306
|
+
*
|
|
307
|
+
* Logs confirmation message if valid and throws an error if invalid.
|
|
308
|
+
*/
|
|
159
309
|
function validateJatsAgainstDtdWrapper(session, file, opts) {
|
|
160
310
|
return __awaiter(this, void 0, void 0, function* () {
|
|
161
311
|
const success = yield validateJatsAgainstDtd(session, file, opts);
|
package/dist/cjs/version.js
CHANGED
package/dist/esm/cli/validate.js
CHANGED
|
@@ -4,11 +4,18 @@ import { getSession } from '../session';
|
|
|
4
4
|
import { validateJatsAgainstDtdWrapper } from '../validate';
|
|
5
5
|
function makeValidateCLI(program) {
|
|
6
6
|
const command = new Command('validate')
|
|
7
|
-
.description(
|
|
7
|
+
.description(`
|
|
8
|
+
Validate JATS file against DTD schema.
|
|
9
|
+
|
|
10
|
+
The JATS DTD schema file is fetched from nih.gov ftp server if not available locally.
|
|
11
|
+
This will attempt to infer the specific JATS DTD version, library, etc from the file header,
|
|
12
|
+
but options are available to override the inferred values.
|
|
13
|
+
`)
|
|
8
14
|
.argument('<file>', 'JATS file to validate')
|
|
9
|
-
.addOption(new Option('--
|
|
10
|
-
.addOption(new Option('--
|
|
11
|
-
.addOption(new Option('--
|
|
15
|
+
.addOption(new Option('--library <value>', 'JATS library - archiving, publishing, or authoring (default: archiving, if value cannot be inferred from file)'))
|
|
16
|
+
.addOption(new Option('--jats <version>', 'JATS version, must be 1.1 or later (default: 1.3, if value cannot be inferred from file)'))
|
|
17
|
+
.addOption(new Option('--mathml <version>', 'MathML version, 2 or 3 (default: 3, if value cannot be inferred from file)'))
|
|
18
|
+
.addOption(new Option('--oasis', 'Use OASIS table model (default: false, if value cannot be inferred from file)'))
|
|
12
19
|
.addOption(new Option('--directory <value>', 'Directory to save DTD file'))
|
|
13
20
|
.action(clirun(validateJatsAgainstDtdWrapper, { program, getSession }));
|
|
14
21
|
return command;
|
package/dist/esm/validate/dtd.js
CHANGED
|
@@ -14,15 +14,54 @@ import unzipper from 'unzipper';
|
|
|
14
14
|
import { sync as which } from 'which';
|
|
15
15
|
import { makeExecutable, writeFileToFolder } from 'myst-cli-utils';
|
|
16
16
|
import chalk from 'chalk';
|
|
17
|
-
const JATS_VERSIONS = [
|
|
17
|
+
const JATS_VERSIONS = [
|
|
18
|
+
'1.1',
|
|
19
|
+
'1.1d1',
|
|
20
|
+
'1.1d2',
|
|
21
|
+
'1.1d3',
|
|
22
|
+
'1.2',
|
|
23
|
+
'1.2d1',
|
|
24
|
+
'1.2d2',
|
|
25
|
+
'1.3',
|
|
26
|
+
'1.3d1',
|
|
27
|
+
'1.3d2',
|
|
28
|
+
];
|
|
18
29
|
const DEFAULT_JATS_VERSION = '1.3';
|
|
19
30
|
const MATHML_VERSIONS = ['2', '3'];
|
|
20
31
|
const DEFAULT_MATHML_VERSION = '3';
|
|
21
|
-
|
|
22
|
-
|
|
32
|
+
const JATS_LIBRARIES = ['authoring', 'publishing', 'archiving'];
|
|
33
|
+
const DEFAULT_JATS_LIBRARY = 'archiving';
|
|
34
|
+
/**
|
|
35
|
+
* Return static/ directory adjacent to the code
|
|
36
|
+
*
|
|
37
|
+
* This provides a standard location to cache DTD files, minimizing re-downloading.
|
|
38
|
+
*/
|
|
39
|
+
function defaultDirectory() {
|
|
40
|
+
return path.join(__dirname, 'static');
|
|
41
|
+
}
|
|
42
|
+
function warnOnOptionsMismatch(session, opts, inferredOpts) {
|
|
43
|
+
if (opts.jats && inferredOpts.jats && opts.jats !== inferredOpts.jats) {
|
|
44
|
+
session.log.warn(`Using JATS version ${opts.jats}; does not match version inferred from file ${inferredOpts.jats}`);
|
|
45
|
+
}
|
|
46
|
+
if (opts.library && inferredOpts.library && opts.library !== inferredOpts.library) {
|
|
47
|
+
session.log.warn(`Using JATS library ${opts.library}; does not match library inferred from file ${inferredOpts.library}`);
|
|
48
|
+
}
|
|
49
|
+
if (opts.mathml && inferredOpts.mathml && opts.mathml !== inferredOpts.mathml) {
|
|
50
|
+
session.log.warn(`Using MathML version ${opts.mathml}; does not match version inferred from file ${inferredOpts.mathml}`);
|
|
51
|
+
}
|
|
52
|
+
if (opts.oasis && !inferredOpts.oasis) {
|
|
53
|
+
session.log.warn('Using OASIS table model; does not match non-OASIS inferred from file');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Validate input value as JATS options and fill in defaults
|
|
58
|
+
*/
|
|
59
|
+
function validateOptions(session, opts, inferredOpts) {
|
|
60
|
+
var _a, _b, _c, _d, _e;
|
|
61
|
+
warnOnOptionsMismatch(session, opts, inferredOpts);
|
|
23
62
|
let jats;
|
|
24
63
|
if (!opts.jats) {
|
|
25
|
-
jats = DEFAULT_JATS_VERSION;
|
|
64
|
+
jats = (_a = inferredOpts.jats) !== null && _a !== void 0 ? _a : DEFAULT_JATS_VERSION;
|
|
26
65
|
}
|
|
27
66
|
else if (!JATS_VERSIONS.includes(opts.jats)) {
|
|
28
67
|
throw new Error(`Invalid JATS version "${opts.jats}" - must be one of [${JATS_VERSIONS.join(', ')}]`);
|
|
@@ -32,7 +71,7 @@ function validateOptions(opts) {
|
|
|
32
71
|
}
|
|
33
72
|
let mathml;
|
|
34
73
|
if (!opts.mathml) {
|
|
35
|
-
mathml = DEFAULT_MATHML_VERSION;
|
|
74
|
+
mathml = (_b = inferredOpts.mathml) !== null && _b !== void 0 ? _b : DEFAULT_MATHML_VERSION;
|
|
36
75
|
}
|
|
37
76
|
else if (!MATHML_VERSIONS.includes(opts.mathml)) {
|
|
38
77
|
throw new Error(`Invalid MathML version "${opts.mathml}" - must be one of [${MATHML_VERSIONS.join(', ')}]`);
|
|
@@ -40,41 +79,127 @@ function validateOptions(opts) {
|
|
|
40
79
|
else {
|
|
41
80
|
mathml = opts.mathml;
|
|
42
81
|
}
|
|
82
|
+
let library;
|
|
83
|
+
if (!opts.library) {
|
|
84
|
+
library = (_c = inferredOpts.library) !== null && _c !== void 0 ? _c : DEFAULT_JATS_LIBRARY;
|
|
85
|
+
}
|
|
86
|
+
else if (typeof opts.library !== 'string' ||
|
|
87
|
+
!JATS_LIBRARIES.includes(opts.library.toLowerCase())) {
|
|
88
|
+
throw new Error(`Invalid JATS library "${opts.library}" - must be one of [${JATS_LIBRARIES.join(', ')}]`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
library = opts.library.toLowerCase();
|
|
92
|
+
}
|
|
93
|
+
const oasis = (_d = inferredOpts.oasis) !== null && _d !== void 0 ? _d : !!opts.oasis;
|
|
94
|
+
if (library === 'authoring' && oasis) {
|
|
95
|
+
throw new Error('JATS article authoring library cannot use OASIS table model');
|
|
96
|
+
}
|
|
43
97
|
const out = {
|
|
98
|
+
library,
|
|
44
99
|
jats,
|
|
45
100
|
mathml,
|
|
46
|
-
oasis
|
|
47
|
-
directory: (
|
|
101
|
+
oasis,
|
|
102
|
+
directory: (_e = opts.directory) !== null && _e !== void 0 ? _e : defaultDirectory(),
|
|
48
103
|
};
|
|
49
104
|
return out;
|
|
50
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* DTD folder name
|
|
108
|
+
*/
|
|
51
109
|
function dtdFolder(opts) {
|
|
52
110
|
const version = opts.jats.replace('.', '-');
|
|
53
111
|
const oasis = opts.oasis ? '-OASIS' : '';
|
|
54
112
|
const mathml = `MathML${opts.mathml}`;
|
|
55
|
-
|
|
113
|
+
const library = opts.library.charAt(0).toUpperCase() + opts.library.slice(1);
|
|
114
|
+
return `JATS-${library}-${version}${oasis}-${mathml}-DTD`;
|
|
56
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* DTD zip file name on FTP server
|
|
118
|
+
*/
|
|
57
119
|
function dtdZipFile(opts) {
|
|
58
120
|
return `${dtdFolder(opts)}.zip`;
|
|
59
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Local location of DTD zip file
|
|
124
|
+
*/
|
|
60
125
|
function localDtdZipFile(opts) {
|
|
61
126
|
return path.join(opts.directory, dtdZipFile(opts));
|
|
62
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Extracted DTD file name
|
|
130
|
+
*/
|
|
63
131
|
function dtdFile(opts) {
|
|
64
|
-
const version = opts.jats.startsWith('1.
|
|
65
|
-
|
|
132
|
+
const version = opts.jats.startsWith('1.3') ? opts.jats.replace('.', '-') : '1';
|
|
133
|
+
let article;
|
|
134
|
+
if (opts.library === 'archiving') {
|
|
135
|
+
article = opts.oasis ? 'archive-oasis-article' : 'archivearticle';
|
|
136
|
+
}
|
|
137
|
+
else if (opts.library === 'publishing') {
|
|
138
|
+
article = opts.oasis ? 'journalpublishing-oasis-article' : 'journalpublishing';
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
article = 'articleauthoring';
|
|
142
|
+
}
|
|
66
143
|
const mathml = opts.mathml === '3' ? '-mathml3' : '';
|
|
67
144
|
return `JATS-${article}${version}${mathml}.dtd`;
|
|
68
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Local location of extracted DTD file
|
|
148
|
+
*/
|
|
69
149
|
function localDtdFile(opts) {
|
|
70
150
|
return path.join(opts.directory, dtdFolder(opts), dtdFile(opts));
|
|
71
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* NIH FTP server and path for downloading JATS DTD files
|
|
154
|
+
*
|
|
155
|
+
* This is accessed by node-fetch over https.
|
|
156
|
+
*/
|
|
72
157
|
function ftpUrl(opts) {
|
|
73
|
-
|
|
158
|
+
const library = opts.library === 'authoring' ? 'articleauthoring' : opts.library;
|
|
159
|
+
return `https://ftp.ncbi.nih.gov/pub/jats/${library}/${opts.jats}/${dtdZipFile(opts)}`;
|
|
74
160
|
}
|
|
75
|
-
|
|
76
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Create a DTS-filename-options lookup for implicitly setting options based on JATS header content
|
|
163
|
+
*/
|
|
164
|
+
function buildDtdFileLookup() {
|
|
165
|
+
const lookup = {};
|
|
166
|
+
JATS_VERSIONS.filter((jats) => jats === '1.2' || jats.startsWith('1.3')).forEach((jats) => {
|
|
167
|
+
MATHML_VERSIONS.forEach((mathml) => {
|
|
168
|
+
JATS_LIBRARIES.forEach((library) => {
|
|
169
|
+
(library === 'authoring' ? [false] : [true, false]).forEach((oasis) => {
|
|
170
|
+
const opts = { jats, mathml, library, oasis };
|
|
171
|
+
lookup[dtdFile(opts)] = opts;
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
return lookup;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Infer DTD options from file content
|
|
180
|
+
*
|
|
181
|
+
* This looks at DTD file name in DOCTYPE as well as dtd-version in article element
|
|
182
|
+
*/
|
|
183
|
+
export function inferOptions(file) {
|
|
184
|
+
var _a, _b;
|
|
185
|
+
const data = fs.readFileSync(file).toString();
|
|
186
|
+
const doctype = (_a = data.match(/<!DOCTYPE [\s\S]+?">/g)) === null || _a === void 0 ? void 0 : _a[0];
|
|
187
|
+
const lookup = buildDtdFileLookup();
|
|
188
|
+
let opts = {};
|
|
189
|
+
Object.entries(lookup).forEach(([key, value]) => {
|
|
190
|
+
if (doctype === null || doctype === void 0 ? void 0 : doctype.includes(key))
|
|
191
|
+
opts = Object.assign({}, value);
|
|
192
|
+
});
|
|
193
|
+
const article = (_b = data.match(/<article [\s\S]+?>/g)) === null || _b === void 0 ? void 0 : _b[0];
|
|
194
|
+
JATS_VERSIONS.forEach((jats) => {
|
|
195
|
+
if (article === null || article === void 0 ? void 0 : article.includes(`dtd-version="${jats}"`))
|
|
196
|
+
opts.jats = jats;
|
|
197
|
+
});
|
|
198
|
+
return opts;
|
|
77
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Download DTD zip file from NIH FTP server
|
|
202
|
+
*/
|
|
78
203
|
function dtdDownload(session, opts) {
|
|
79
204
|
return __awaiter(this, void 0, void 0, function* () {
|
|
80
205
|
if (!fs.existsSync(opts.directory)) {
|
|
@@ -86,6 +211,9 @@ function dtdDownload(session, opts) {
|
|
|
86
211
|
writeFileToFolder(localDtdZipFile(opts), yield resp.buffer());
|
|
87
212
|
});
|
|
88
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Download DTD zip file from NIH FTP server if it does not yet exist
|
|
216
|
+
*/
|
|
89
217
|
function ensureDtdZipExists(session, opts) {
|
|
90
218
|
return __awaiter(this, void 0, void 0, function* () {
|
|
91
219
|
if (!fs.existsSync(path.join(opts.directory, dtdZipFile(opts)))) {
|
|
@@ -93,32 +221,48 @@ function ensureDtdZipExists(session, opts) {
|
|
|
93
221
|
}
|
|
94
222
|
});
|
|
95
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Download and extract DTD file if it does not yet exist
|
|
226
|
+
*/
|
|
96
227
|
function ensureDtdExists(session, opts) {
|
|
97
228
|
return __awaiter(this, void 0, void 0, function* () {
|
|
98
229
|
if (!fs.existsSync(localDtdFile(opts))) {
|
|
99
230
|
yield ensureDtdZipExists(session, opts);
|
|
100
231
|
const zipFile = localDtdZipFile(opts);
|
|
101
|
-
session.log.info(`🤐 Unzipping template
|
|
232
|
+
session.log.info(`🤐 Unzipping template: ${zipFile}`);
|
|
102
233
|
yield createReadStream(zipFile)
|
|
103
234
|
.pipe(unzipper.Extract({ path: opts.directory }))
|
|
104
235
|
.promise();
|
|
105
236
|
}
|
|
106
|
-
session.log.debug(`Validating against ${localDtdFile(opts)}`);
|
|
107
237
|
});
|
|
108
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Test if xmllint is available as a cli command
|
|
241
|
+
*/
|
|
109
242
|
function isXmllintAvailable() {
|
|
110
243
|
return which('xmllint', { nothrow: true });
|
|
111
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* Check if JATS file is valid based on JATS version/library/etc.
|
|
247
|
+
*
|
|
248
|
+
* Returns true if valid and false if invalid.
|
|
249
|
+
*/
|
|
112
250
|
export function validateJatsAgainstDtd(session, file, opts) {
|
|
113
251
|
return __awaiter(this, void 0, void 0, function* () {
|
|
114
252
|
if (!isXmllintAvailable()) {
|
|
115
253
|
session.log.error(`JATS validation against DTD requires xmllint\n\n${chalk.dim('To install:\n mac: brew install xmlstarlet\n debian: apt install libxml2-utils')}`);
|
|
116
254
|
return;
|
|
117
255
|
}
|
|
118
|
-
const
|
|
256
|
+
const inferredOpts = inferOptions(file);
|
|
257
|
+
const validatedOpts = validateOptions(session, opts !== null && opts !== void 0 ? opts : {}, inferredOpts);
|
|
119
258
|
yield ensureDtdExists(session, validatedOpts);
|
|
259
|
+
session.log.debug(`Validating against: ${localDtdFile(validatedOpts)}`);
|
|
260
|
+
session.log.info(`🧐 Validating against: ${dtdFolder(validatedOpts)}`);
|
|
120
261
|
try {
|
|
121
|
-
|
|
262
|
+
// First drop DOCTYPE with DTD in it - we have already fetched the DTD
|
|
263
|
+
const dropDtdCommand = `xmllint --dropdtd`;
|
|
264
|
+
const validateCommand = `xmllint --noout --dtdvalid ${localDtdFile(validatedOpts)}`;
|
|
265
|
+
yield makeExecutable(`${dropDtdCommand} ${file} | ${validateCommand} -`, session.log)();
|
|
122
266
|
}
|
|
123
267
|
catch (_a) {
|
|
124
268
|
return false;
|
|
@@ -126,6 +270,11 @@ export function validateJatsAgainstDtd(session, file, opts) {
|
|
|
126
270
|
return true;
|
|
127
271
|
});
|
|
128
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Check if JATS file is valid based on JATS version/library/etc.
|
|
275
|
+
*
|
|
276
|
+
* Logs confirmation message if valid and throws an error if invalid.
|
|
277
|
+
*/
|
|
129
278
|
export function validateJatsAgainstDtdWrapper(session, file, opts) {
|
|
130
279
|
return __awaiter(this, void 0, void 0, function* () {
|
|
131
280
|
const success = yield validateJatsAgainstDtd(session, file, opts);
|
package/dist/esm/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const version = '0.0.
|
|
1
|
+
const version = '0.0.16';
|
|
2
2
|
export default version;
|
package/dist/jats.js
CHANGED
|
@@ -26375,7 +26375,7 @@ var require_which = __commonJS({
|
|
|
26375
26375
|
var import_commander3 = __toESM(require_commander());
|
|
26376
26376
|
|
|
26377
26377
|
// src/version.ts
|
|
26378
|
-
var version = "0.0.
|
|
26378
|
+
var version = "0.0.16";
|
|
26379
26379
|
var version_default = version;
|
|
26380
26380
|
|
|
26381
26381
|
// src/cli/parse.ts
|
|
@@ -27238,15 +27238,52 @@ var import_node_fetch3 = __toESM(require_lib4());
|
|
|
27238
27238
|
var import_unzipper = __toESM(require_unzip2());
|
|
27239
27239
|
var import_which = __toESM(require_which());
|
|
27240
27240
|
var import_chalk3 = __toESM(require_source());
|
|
27241
|
-
var JATS_VERSIONS = [
|
|
27241
|
+
var JATS_VERSIONS = [
|
|
27242
|
+
"1.1",
|
|
27243
|
+
"1.1d1",
|
|
27244
|
+
"1.1d2",
|
|
27245
|
+
"1.1d3",
|
|
27246
|
+
"1.2",
|
|
27247
|
+
"1.2d1",
|
|
27248
|
+
"1.2d2",
|
|
27249
|
+
"1.3",
|
|
27250
|
+
"1.3d1",
|
|
27251
|
+
"1.3d2"
|
|
27252
|
+
];
|
|
27242
27253
|
var DEFAULT_JATS_VERSION = "1.3";
|
|
27243
27254
|
var MATHML_VERSIONS = ["2", "3"];
|
|
27244
27255
|
var DEFAULT_MATHML_VERSION = "3";
|
|
27245
|
-
|
|
27246
|
-
|
|
27256
|
+
var JATS_LIBRARIES = ["authoring", "publishing", "archiving"];
|
|
27257
|
+
var DEFAULT_JATS_LIBRARY = "archiving";
|
|
27258
|
+
function defaultDirectory() {
|
|
27259
|
+
return import_path4.default.join(__dirname, "static");
|
|
27260
|
+
}
|
|
27261
|
+
function warnOnOptionsMismatch(session, opts, inferredOpts) {
|
|
27262
|
+
if (opts.jats && inferredOpts.jats && opts.jats !== inferredOpts.jats) {
|
|
27263
|
+
session.log.warn(
|
|
27264
|
+
`Using JATS version ${opts.jats}; does not match version inferred from file ${inferredOpts.jats}`
|
|
27265
|
+
);
|
|
27266
|
+
}
|
|
27267
|
+
if (opts.library && inferredOpts.library && opts.library !== inferredOpts.library) {
|
|
27268
|
+
session.log.warn(
|
|
27269
|
+
`Using JATS library ${opts.library}; does not match library inferred from file ${inferredOpts.library}`
|
|
27270
|
+
);
|
|
27271
|
+
}
|
|
27272
|
+
if (opts.mathml && inferredOpts.mathml && opts.mathml !== inferredOpts.mathml) {
|
|
27273
|
+
session.log.warn(
|
|
27274
|
+
`Using MathML version ${opts.mathml}; does not match version inferred from file ${inferredOpts.mathml}`
|
|
27275
|
+
);
|
|
27276
|
+
}
|
|
27277
|
+
if (opts.oasis && !inferredOpts.oasis) {
|
|
27278
|
+
session.log.warn("Using OASIS table model; does not match non-OASIS inferred from file");
|
|
27279
|
+
}
|
|
27280
|
+
}
|
|
27281
|
+
function validateOptions(session, opts, inferredOpts) {
|
|
27282
|
+
var _a, _b, _c, _d, _e;
|
|
27283
|
+
warnOnOptionsMismatch(session, opts, inferredOpts);
|
|
27247
27284
|
let jats;
|
|
27248
27285
|
if (!opts.jats) {
|
|
27249
|
-
jats = DEFAULT_JATS_VERSION;
|
|
27286
|
+
jats = (_a = inferredOpts.jats) != null ? _a : DEFAULT_JATS_VERSION;
|
|
27250
27287
|
} else if (!JATS_VERSIONS.includes(opts.jats)) {
|
|
27251
27288
|
throw new Error(
|
|
27252
27289
|
`Invalid JATS version "${opts.jats}" - must be one of [${JATS_VERSIONS.join(", ")}]`
|
|
@@ -27256,7 +27293,7 @@ function validateOptions(opts) {
|
|
|
27256
27293
|
}
|
|
27257
27294
|
let mathml;
|
|
27258
27295
|
if (!opts.mathml) {
|
|
27259
|
-
mathml = DEFAULT_MATHML_VERSION;
|
|
27296
|
+
mathml = (_b = inferredOpts.mathml) != null ? _b : DEFAULT_MATHML_VERSION;
|
|
27260
27297
|
} else if (!MATHML_VERSIONS.includes(opts.mathml)) {
|
|
27261
27298
|
throw new Error(
|
|
27262
27299
|
`Invalid MathML version "${opts.mathml}" - must be one of [${MATHML_VERSIONS.join(", ")}]`
|
|
@@ -27264,11 +27301,26 @@ function validateOptions(opts) {
|
|
|
27264
27301
|
} else {
|
|
27265
27302
|
mathml = opts.mathml;
|
|
27266
27303
|
}
|
|
27304
|
+
let library;
|
|
27305
|
+
if (!opts.library) {
|
|
27306
|
+
library = (_c = inferredOpts.library) != null ? _c : DEFAULT_JATS_LIBRARY;
|
|
27307
|
+
} else if (typeof opts.library !== "string" || !JATS_LIBRARIES.includes(opts.library.toLowerCase())) {
|
|
27308
|
+
throw new Error(
|
|
27309
|
+
`Invalid JATS library "${opts.library}" - must be one of [${JATS_LIBRARIES.join(", ")}]`
|
|
27310
|
+
);
|
|
27311
|
+
} else {
|
|
27312
|
+
library = opts.library.toLowerCase();
|
|
27313
|
+
}
|
|
27314
|
+
const oasis = (_d = inferredOpts.oasis) != null ? _d : !!opts.oasis;
|
|
27315
|
+
if (library === "authoring" && oasis) {
|
|
27316
|
+
throw new Error("JATS article authoring library cannot use OASIS table model");
|
|
27317
|
+
}
|
|
27267
27318
|
const out = {
|
|
27319
|
+
library,
|
|
27268
27320
|
jats,
|
|
27269
27321
|
mathml,
|
|
27270
|
-
oasis
|
|
27271
|
-
directory: (
|
|
27322
|
+
oasis,
|
|
27323
|
+
directory: (_e = opts.directory) != null ? _e : defaultDirectory()
|
|
27272
27324
|
};
|
|
27273
27325
|
return out;
|
|
27274
27326
|
}
|
|
@@ -27276,7 +27328,8 @@ function dtdFolder(opts) {
|
|
|
27276
27328
|
const version2 = opts.jats.replace(".", "-");
|
|
27277
27329
|
const oasis = opts.oasis ? "-OASIS" : "";
|
|
27278
27330
|
const mathml = `MathML${opts.mathml}`;
|
|
27279
|
-
|
|
27331
|
+
const library = opts.library.charAt(0).toUpperCase() + opts.library.slice(1);
|
|
27332
|
+
return `JATS-${library}-${version2}${oasis}-${mathml}-DTD`;
|
|
27280
27333
|
}
|
|
27281
27334
|
function dtdZipFile(opts) {
|
|
27282
27335
|
return `${dtdFolder(opts)}.zip`;
|
|
@@ -27285,8 +27338,15 @@ function localDtdZipFile(opts) {
|
|
|
27285
27338
|
return import_path4.default.join(opts.directory, dtdZipFile(opts));
|
|
27286
27339
|
}
|
|
27287
27340
|
function dtdFile(opts) {
|
|
27288
|
-
const version2 = opts.jats.startsWith("1.
|
|
27289
|
-
|
|
27341
|
+
const version2 = opts.jats.startsWith("1.3") ? opts.jats.replace(".", "-") : "1";
|
|
27342
|
+
let article;
|
|
27343
|
+
if (opts.library === "archiving") {
|
|
27344
|
+
article = opts.oasis ? "archive-oasis-article" : "archivearticle";
|
|
27345
|
+
} else if (opts.library === "publishing") {
|
|
27346
|
+
article = opts.oasis ? "journalpublishing-oasis-article" : "journalpublishing";
|
|
27347
|
+
} else {
|
|
27348
|
+
article = "articleauthoring";
|
|
27349
|
+
}
|
|
27290
27350
|
const mathml = opts.mathml === "3" ? "-mathml3" : "";
|
|
27291
27351
|
return `JATS-${article}${version2}${mathml}.dtd`;
|
|
27292
27352
|
}
|
|
@@ -27294,10 +27354,39 @@ function localDtdFile(opts) {
|
|
|
27294
27354
|
return import_path4.default.join(opts.directory, dtdFolder(opts), dtdFile(opts));
|
|
27295
27355
|
}
|
|
27296
27356
|
function ftpUrl(opts) {
|
|
27297
|
-
|
|
27357
|
+
const library = opts.library === "authoring" ? "articleauthoring" : opts.library;
|
|
27358
|
+
return `https://ftp.ncbi.nih.gov/pub/jats/${library}/${opts.jats}/${dtdZipFile(opts)}`;
|
|
27298
27359
|
}
|
|
27299
|
-
function
|
|
27300
|
-
|
|
27360
|
+
function buildDtdFileLookup() {
|
|
27361
|
+
const lookup = {};
|
|
27362
|
+
JATS_VERSIONS.filter((jats) => jats === "1.2" || jats.startsWith("1.3")).forEach((jats) => {
|
|
27363
|
+
MATHML_VERSIONS.forEach((mathml) => {
|
|
27364
|
+
JATS_LIBRARIES.forEach((library) => {
|
|
27365
|
+
(library === "authoring" ? [false] : [true, false]).forEach((oasis) => {
|
|
27366
|
+
const opts = { jats, mathml, library, oasis };
|
|
27367
|
+
lookup[dtdFile(opts)] = opts;
|
|
27368
|
+
});
|
|
27369
|
+
});
|
|
27370
|
+
});
|
|
27371
|
+
});
|
|
27372
|
+
return lookup;
|
|
27373
|
+
}
|
|
27374
|
+
function inferOptions(file) {
|
|
27375
|
+
var _a, _b;
|
|
27376
|
+
const data = import_fs3.default.readFileSync(file).toString();
|
|
27377
|
+
const doctype = (_a = data.match(/<!DOCTYPE [\s\S]+?">/g)) == null ? void 0 : _a[0];
|
|
27378
|
+
const lookup = buildDtdFileLookup();
|
|
27379
|
+
let opts = {};
|
|
27380
|
+
Object.entries(lookup).forEach(([key, value]) => {
|
|
27381
|
+
if (doctype == null ? void 0 : doctype.includes(key))
|
|
27382
|
+
opts = __spreadValues({}, value);
|
|
27383
|
+
});
|
|
27384
|
+
const article = (_b = data.match(/<article [\s\S]+?>/g)) == null ? void 0 : _b[0];
|
|
27385
|
+
JATS_VERSIONS.forEach((jats) => {
|
|
27386
|
+
if (article == null ? void 0 : article.includes(`dtd-version="${jats}"`))
|
|
27387
|
+
opts.jats = jats;
|
|
27388
|
+
});
|
|
27389
|
+
return opts;
|
|
27301
27390
|
}
|
|
27302
27391
|
function dtdDownload(session, opts) {
|
|
27303
27392
|
return __async(this, null, function* () {
|
|
@@ -27322,10 +27411,9 @@ function ensureDtdExists(session, opts) {
|
|
|
27322
27411
|
if (!import_fs3.default.existsSync(localDtdFile(opts))) {
|
|
27323
27412
|
yield ensureDtdZipExists(session, opts);
|
|
27324
27413
|
const zipFile = localDtdZipFile(opts);
|
|
27325
|
-
session.log.info(`\u{1F910} Unzipping template
|
|
27414
|
+
session.log.info(`\u{1F910} Unzipping template: ${zipFile}`);
|
|
27326
27415
|
yield (0, import_fs3.createReadStream)(zipFile).pipe(import_unzipper.default.Extract({ path: opts.directory })).promise();
|
|
27327
27416
|
}
|
|
27328
|
-
session.log.debug(`Validating against ${localDtdFile(opts)}`);
|
|
27329
27417
|
});
|
|
27330
27418
|
}
|
|
27331
27419
|
function isXmllintAvailable() {
|
|
@@ -27343,13 +27431,15 @@ ${import_chalk3.default.dim(
|
|
|
27343
27431
|
);
|
|
27344
27432
|
return;
|
|
27345
27433
|
}
|
|
27346
|
-
const
|
|
27434
|
+
const inferredOpts = inferOptions(file);
|
|
27435
|
+
const validatedOpts = validateOptions(session, opts != null ? opts : {}, inferredOpts);
|
|
27347
27436
|
yield ensureDtdExists(session, validatedOpts);
|
|
27437
|
+
session.log.debug(`Validating against: ${localDtdFile(validatedOpts)}`);
|
|
27438
|
+
session.log.info(`\u{1F9D0} Validating against: ${dtdFolder(validatedOpts)}`);
|
|
27348
27439
|
try {
|
|
27349
|
-
|
|
27350
|
-
|
|
27351
|
-
|
|
27352
|
-
)();
|
|
27440
|
+
const dropDtdCommand = `xmllint --dropdtd`;
|
|
27441
|
+
const validateCommand = `xmllint --noout --dtdvalid ${localDtdFile(validatedOpts)}`;
|
|
27442
|
+
yield makeExecutable(`${dropDtdCommand} ${file} | ${validateCommand} -`, session.log)();
|
|
27353
27443
|
} catch (e) {
|
|
27354
27444
|
return false;
|
|
27355
27445
|
}
|
|
@@ -27369,7 +27459,35 @@ function validateJatsAgainstDtdWrapper(session, file, opts) {
|
|
|
27369
27459
|
|
|
27370
27460
|
// src/cli/validate.ts
|
|
27371
27461
|
function makeValidateCLI(program2) {
|
|
27372
|
-
const command = new import_commander2.Command("validate").description(
|
|
27462
|
+
const command = new import_commander2.Command("validate").description(
|
|
27463
|
+
`
|
|
27464
|
+
Validate JATS file against DTD schema.
|
|
27465
|
+
|
|
27466
|
+
The JATS DTD schema file is fetched from nih.gov ftp server if not available locally.
|
|
27467
|
+
This will attempt to infer the specific JATS DTD version, library, etc from the file header,
|
|
27468
|
+
but options are available to override the inferred values.
|
|
27469
|
+
`
|
|
27470
|
+
).argument("<file>", "JATS file to validate").addOption(
|
|
27471
|
+
new import_commander2.Option(
|
|
27472
|
+
"--library <value>",
|
|
27473
|
+
"JATS library - archiving, publishing, or authoring (default: archiving, if value cannot be inferred from file)"
|
|
27474
|
+
)
|
|
27475
|
+
).addOption(
|
|
27476
|
+
new import_commander2.Option(
|
|
27477
|
+
"--jats <version>",
|
|
27478
|
+
"JATS version, must be 1.1 or later (default: 1.3, if value cannot be inferred from file)"
|
|
27479
|
+
)
|
|
27480
|
+
).addOption(
|
|
27481
|
+
new import_commander2.Option(
|
|
27482
|
+
"--mathml <version>",
|
|
27483
|
+
"MathML version, 2 or 3 (default: 3, if value cannot be inferred from file)"
|
|
27484
|
+
)
|
|
27485
|
+
).addOption(
|
|
27486
|
+
new import_commander2.Option(
|
|
27487
|
+
"--oasis",
|
|
27488
|
+
"Use OASIS table model (default: false, if value cannot be inferred from file)"
|
|
27489
|
+
)
|
|
27490
|
+
).addOption(new import_commander2.Option("--directory <value>", "Directory to save DTD file")).action(clirun(validateJatsAgainstDtdWrapper, { program: program2, getSession }));
|
|
27373
27491
|
return command;
|
|
27374
27492
|
}
|
|
27375
27493
|
function addValidateCLI(program2) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AA8C5C,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,QAE9C"}
|
|
@@ -3,9 +3,26 @@ type Options = {
|
|
|
3
3
|
jats: string;
|
|
4
4
|
mathml: '2' | '3';
|
|
5
5
|
oasis: boolean;
|
|
6
|
+
library: string;
|
|
6
7
|
directory: string;
|
|
7
8
|
};
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Infer DTD options from file content
|
|
11
|
+
*
|
|
12
|
+
* This looks at DTD file name in DOCTYPE as well as dtd-version in article element
|
|
13
|
+
*/
|
|
14
|
+
export declare function inferOptions(file: string): Partial<Options>;
|
|
15
|
+
/**
|
|
16
|
+
* Check if JATS file is valid based on JATS version/library/etc.
|
|
17
|
+
*
|
|
18
|
+
* Returns true if valid and false if invalid.
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateJatsAgainstDtd(session: ISession, file: string, opts?: Partial<Options>): Promise<boolean | undefined>;
|
|
21
|
+
/**
|
|
22
|
+
* Check if JATS file is valid based on JATS version/library/etc.
|
|
23
|
+
*
|
|
24
|
+
* Logs confirmation message if valid and throws an error if invalid.
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateJatsAgainstDtdWrapper(session: ISession, file: string, opts?: Partial<Options>): Promise<void>;
|
|
10
27
|
export {};
|
|
11
28
|
//# sourceMappingURL=dtd.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dtd.d.ts","sourceRoot":"","sources":["../../../src/validate/dtd.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"dtd.d.ts","sourceRoot":"","sources":["../../../src/validate/dtd.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAwBzC,KAAK,OAAO,GAAG;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAgKF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,oBAaxC;AA6CD;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,gCAwBxB;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,iBAQxB"}
|
package/dist/types/version.d.ts
CHANGED
package/package.json
CHANGED