wed
Version:
Wed is a schema-aware editor for XML documents.
136 lines • 4.58 kB
JavaScript
/**
* Facilities for interpreting the patterns passed in dochtml in
* metadata files.
*
* @author Louis-Dominique Dubeau
* @license MPL 2.0
* @copyright Mangalam Research Center for Buddhist Languages
*/
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* A literal value in a pattern.
*/
class Literal {
/**
* @param value The value to which this literal resolves to.
*/
constructor(value) {
this.value = value;
}
execute() {
return this.value;
}
}
/**
* A concatenation operation.
*/
class Concat {
/**
* @param values The patterns to concatenate.
*/
constructor(values) {
this.values = values;
}
execute(context) {
return this.values.map((value) => value.execute(context)).join("");
}
}
/**
* An interpolation like ``${foo}``.
*/
class Interpolation {
/**
* @param name The name to interpolate.
*/
constructor(name) {
this.name = name;
}
execute(context) {
return context.resolveName(this.name);
}
}
/**
* A substitution operation, like in ``${foo:s("a","b")}``.
*/
class Substitution {
constructor(pattern, substitution, child) {
this.pattern = pattern;
this.substitution = substitution;
this.child = child;
}
execute(context) {
const value = this.child.execute(context);
return value.replace(this.pattern, this.substitution);
}
}
/**
* Compile a string pattern to a [[DocPattern]] object.
*
* @param pattern The pattern to compile.
*
* @returns The compiled pattern.
*/
function compile(pattern) {
const parts = pattern.split(/(\$\{|\})/);
const patterns = [];
let interpolating = false;
for (const part of parts) {
// tslint:disable-next-line:no-invalid-template-strings
if (part === "${") {
if (interpolating) {
throw new Error("nested interpolations are invalid");
}
interpolating = true;
}
else if (part === "}") {
if (!interpolating) {
throw new Error("errant interpolation closure");
}
interpolating = false;
}
else if (interpolating) {
const [name, transform] = part.split(":", 1);
if (transform === undefined) {
patterns.push(new Interpolation(name));
}
else {
if (transform[0] === "s") {
const paramList = transform.slice(1);
if (paramList[0] !== "(" || paramList[paramList.length - 1] !== ")") {
throw new Error("transform parameters must be in parentheses");
}
// We slice to drop the parentheses.
let params = paramList.slice(1, -1).split(",").map((x) => x.trim());
if (params.length !== 2) {
throw new Error("an s transform takes 2 parameters");
}
for (const param of params) {
if (param[0] !== "\"" || param[param.length - 1] !== "\"") {
throw new Error(`parameter must be a string wrapped in double \
quotes: ${param}`);
}
}
// Drop the wrapping quotes.
params = params.map((x) => x.slice(1, -1));
patterns.push(new Substitution(params[0], params[1], new Interpolation(name)));
}
else {
throw new Error(`unknown transform ${transform}`);
}
}
}
else {
patterns.push(new Literal(part));
}
}
if (interpolating) {
throw new Error("an interpolation was not closed");
}
return new Concat(patterns);
}
exports.compile = compile;
});
// LocalWords: dochtml MPL unresolvable param
//# sourceMappingURL=doc-pattern.js.map