UNPKG

salve-annos

Version:

A fork with support for documentation of Salve, a Javascript library which implements a validator able to validate an XML document on the basis of a subset of RelaxNG.

221 lines 9.46 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.XSLSimplifier = void 0; /** * A simplifier implemented as a series of XSL transformations. It launches * external processes to perform the transformation. * * @author Louis-Dominique Dubeau * @license MPL 2.0 * @copyright Mangalam Research Center for Buddhist Languages */ const child_process_1 = require("child_process"); const fs = __importStar(require("fs")); const path = __importStar(require("path")); const parser_1 = require("../parser"); const schema_simplification_1 = require("../schema-simplification"); const base_1 = require("./base"); const common_1 = require("./common"); /** * A simplifier implemented as a series of XSL transformations. It launches * external processes to perform the transformation. * * This simiplifier does not produce a manifest, and it does not validate. */ class XSLSimplifier extends base_1.BaseSimplifier { constructor(options) { super(options); if (options.timing) { options.verbose = true; } } processDatatypes(tree) { const processor = new common_1.DatatypeProcessor(); processor.walk(tree); return processor.warnings; } get steps() { if (this._steps !== undefined) { return this._steps; } // Grab the xsl files that form the simplification process, and store these // paths in ``steps``. const libPath = path.resolve(__dirname, path.join("..", "..", "rng-simplification")); const stepRe = /^rng-simplification_step(\d*?).xsl$/; const stepFiles = fs.readdirSync(libPath).filter(file => file.match(stepRe)); // The filter step above ensures the regexp match. // tslint:disable-next-line:no-non-null-assertion stepFiles.sort((a, b) => parseInt(a.match(stepRe)[1]) - // tslint:disable-next-line:no-non-null-assertion parseInt(b.match(stepRe)[1])); return this._steps = stepFiles.map(file => { const ret = { name: file, path: path.join(libPath, file), repeatNo: 0, saxon: false, }; if (file === "rng-simplification_step1.xsl") { ret.saxon = true; // We want to check whether we need to run the step again to include // more files. ret.repeatWhen = parser_1.dependsOnExternalFile; } return ret; }); } simplify(schemaURL) { return __awaiter(this, void 0, void 0, function* () { let schemaPath = schemaURL.toString(); if (schemaURL.protocol === "file:") { schemaPath = schemaPath.replace(/^file:\/\//, ""); } else { throw new Error("URLs must use the file: protocol"); } let startTime; if (this.options.verbose) { // tslint:disable-next-line:no-console console.log("Simplifying..."); if (this.options.timing) { startTime = Date.now(); } } const originalInputDir = `${path.dirname(path.resolve(schemaPath))}/`; const schemaText = fs.readFileSync(schemaPath).toString(); const result = yield this.executeStep(originalInputDir, 0, schemaText); const simplified = (0, parser_1.parseSimplifiedSchema)(schemaPath, result); const warnings = (this.options.simplifyTo >= 18) ? this.processDatatypes(simplified) : []; this.stepTiming(); if (this.options.timing) { // tslint:disable-next-line:no-non-null-assertion no-console console.log(`Simplification delta: ${Date.now() - startTime}`); } return { simplified, warnings, manifest: [], schemaText }; }); } stepTiming() { if (this.lastStepStart !== undefined) { // tslint:disable-next-line:no-console console.log(`${Date.now() - this.lastStepStart}ms`); } } /** * @param originalInputDir The URL to the directory that contained the * original file to simplify. * * @param stepNo The index in ``steps`` of the step we are running. * * @param input The data to process. */ executeStep(originalInputDir, stepNo, input) { return __awaiter(this, void 0, void 0, function* () { const steps = this.steps; if (stepNo >= steps.length || stepNo >= this.options.simplifyTo) { return input; } const step = steps[stepNo]; if (this.options.verbose) { this.stepTiming(); // tslint:disable-next-line:no-console console.log(`Simplification step ${stepNo + 1}, repetition ${step.repeatNo}...`); if (this.options.timing) { this.lastStepStart = Date.now(); } } let child; const output = yield new Promise((resolve, reject) => { // Only step 1 requires XSLT 2. Remember that steps are 0-based here. if (step.saxon) { child = (0, child_process_1.spawn)("java", ["-jar", "/usr/share/java/Saxon-HE.jar", `-xsl:${step.path}`, "-s:-", `originalDir=file://${originalInputDir}`], { stdio: ["pipe", "pipe", "inherit"] }); } else { child = (0, child_process_1.spawn)("xsltproc", ["--stringparam", "originalDir", originalInputDir, step.path, "-"], { stdio: ["pipe", "pipe", "inherit"], cwd: originalInputDir, }); } child.stdin.end(input); let outputBuf = ""; child.stdout.on("data", data => { outputBuf += data.toString(); }); child.on("exit", status => { if (status !== 0) { reject(new Error(`child terminated with status: ${status}`)); } resolve(outputBuf); }); }); if (this.options.keepTemp) { // tslint:disable-next-line:no-non-null-assertion const tempDir = this.options.ensureTempDir(); const outBase = `out${String((stepNo + 1)) + (step.repeatWhen !== undefined ? `.${step.repeatNo + 1}` : "")}.rng`; const outPath = path.join(tempDir, outBase); fs.writeFileSync(outPath, output); } if (step.repeatWhen !== undefined) { if (step.repeatWhen(output)) { step.repeatNo++; return this.executeStep(originalInputDir, stepNo, output); } } return this.executeStep(originalInputDir, stepNo + 1, output); }); } } exports.XSLSimplifier = XSLSimplifier; XSLSimplifier.validates = false; XSLSimplifier.createsManifest = false; (0, schema_simplification_1.registerSimplifier)("xsl", XSLSimplifier); //# sourceMappingURL=xsl.js.map