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.

95 lines 3.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.step14 = step14; /** * Simplification step 14. * @author Louis-Dominique Dubeau * @license MPL 2.0 * @copyright 2013, 2014 Mangalam Research Center for Buddhist Languages */ const parser_1 = require("../parser"); const schema_validation_1 = require("../schema-validation"); const util_1 = require("./util"); function makeName(el) { let ret = el.local; if (ret === "def") { ret += `@name="${(0, util_1.getName)(el)}"`; } return ret; } function combine(els) { if (els.length < 2) { // There's nothing to actually *combine*. if (els.length > 0) { // Delete the useless combine attribute that may be present. els[0].removeAttribute("combine"); } return; } let undefinedCombine = false; let combineAs; for (const el of els) { const combineAttr = el.getAttribute("combine"); if (combineAttr === undefined) { if (undefinedCombine) { throw new schema_validation_1.SchemaValidationError(`more than one ${makeName(el)} without @combine`); } undefinedCombine = true; } else { if (combineAs === undefined) { combineAs = combineAttr; } else if (combineAs !== combineAttr) { throw new schema_validation_1.SchemaValidationError(`inconsistent values on ${makeName(el)}/@combine`); } } } if (combineAs === undefined) { throw new Error("no combination value found"); } let wrapper = parser_1.Element.makeElement(combineAs, []); const [first, second, ...rest] = els; wrapper.grabChildren(first); wrapper.grabChildren(second); second.parent.removeChild(second); for (const el of rest) { const newWrapper = parser_1.Element.makeElement(combineAs, [wrapper]); newWrapper.grabChildren(el); el.parent.removeChild(el); wrapper = newWrapper; } first.appendChild(wrapper); first.removeAttribute("combine"); } /** * Implements step 14 of the XSL pipeline. Namely, in each grammar: * * - ``start`` elements are combined. * * - ``define`` elements with the same name are combined. * * The scope of the transformation performed for a grammar include all ``start`` * and ``define`` elements, *excluding* those that may be in a descendant * ``grammar`` element. * * @param el The tree to process. It is modified in-place. * * @returns The new root of the tree. */ function step14(el) { const grammars = (0, util_1.findDescendantsByLocalName)(el, "grammar"); if (el.local === "grammar") { grammars.unshift(el); } for (const grammar of grammars) { combine((0, util_1.findChildrenByLocalName)(grammar, "start")); const defs = (0, util_1.findChildrenByLocalName)(grammar, "define"); const grouped = (0, util_1.groupBy)(defs, util_1.getName); for (const group of grouped.values()) { combine(group); } } return el; } //# sourceMappingURL=step14.js.map