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
JavaScript
;
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