diff --git a/src/environments.js b/src/environments.js index ff294ca7a..c589d752b 100644 --- a/src/environments.js +++ b/src/environments.js @@ -38,32 +38,54 @@ function parseArray(parser, pos, mode, result) { } /* - * An environment definition is very similar to a function definition. - * Each element of the following array may contain - * - names: The names associated with a function. This can be used to - * share one implementation between several similar environments. + * An environment definition is very similar to a function definition: + * it is declared with a name or a list of names, a set of properties + * and a handler containing the actual implementation. + * + * The properties include: * - numArgs: The number of arguments after the \begin{name} function. * - argTypes: (optional) Just like for a function * - allowedInText: (optional) Whether or not the environment is allowed inside * text mode (default false) (not enforced yet) * - numOptionalArgs: (optional) Just like for a function - * - handler: The function that is called to handle this environment. - * It will receive the following arguments: + * A bare number instead of that object indicates the numArgs value. + * + * The handler function will receive the following arguments: * - pos: the current position of the parser. * - mode: the current parsing mode. * - envName: the name of the environment, one of the listed names. * - [args]: the arguments passed to \begin. * - positions: the positions associated with these arguments. + * The handler is called with `this` referring to the parser. + * It must return a ParseResult. */ -var environmentDefinitions = [ +function defineEnvironment(names, props, handler) { + if (typeof names === "string") { + names = [names]; + } + if (typeof props === "number") { + props = { numArgs: props }; + } + // Set default values of environments + var data = { + numArgs: props.numArgs || 0, + argTypes: props.argTypes, + greediness: 1, + allowedInText: !!props.allowedInText, + numOptionalArgs: props.numOptionalArgs || 0, + handler: handler + }; + for (var i = 0; i < names.length; ++i) { + module.exports[names[i]] = data; + } +} // Arrays are part of LaTeX, defined in lttab.dtx so its documentation // is part of the source2e.pdf file of LaTeX2e source documentation. - { - names: ["array"], - numArgs: 1, - handler: function(pos, mode, envName, colalign, positions) { + defineEnvironment("array", { + numArgs: 1 + }, function(pos, mode, envName, colalign, positions) { var parser = this; colalign = colalign.value.map ? colalign.value : [colalign]; var cols = colalign.map(function(node) { @@ -90,21 +112,19 @@ var environmentDefinitions = [ }; res = parseArray(parser, pos, mode, res); return res; - } - }, + }); // The matrix environments of amsmath builds on the array environment // of LaTeX, which is discussed above. - { - names: [ + defineEnvironment([ "matrix", "pmatrix", "bmatrix", "Bmatrix", "vmatrix", "Vmatrix" - ], - handler: function(pos, mode, envName) { + ], { + }, function(pos, mode, envName) { var delimiters = { "matrix": null, "pmatrix": ["(", ")"], @@ -126,15 +146,13 @@ var environmentDefinitions = [ }, mode); } return res; - } - }, + }); // A cases environment (in amsmath.sty) is almost equivalent to // \def\arraystretch{1.2}% // \left\{\begin{array}{@{}l@{\quad}l@{}} … \end{array}\right. - { - names: ["cases"], - handler: function(pos, mode, envName) { + defineEnvironment("cases", { + }, function(pos, mode, envName) { var res = { type: "array", arraystretch: 1.2, @@ -157,22 +175,4 @@ var environmentDefinitions = [ right: "." }, mode); return res; - } - } -]; - -module.exports = (function() { - // nested function so we don't leak i and j into the module scope - var exports = {}; - for (var i = 0; i < environmentDefinitions.length; ++i) { - var def = environmentDefinitions[i]; - def.greediness = 1; - def.allowedInText = !!def.allowedInText; - def.numArgs = def.numArgs || 0; - def.numOptionalArgs = def.numOptionalArgs || 0; - for (var j = 0; j < def.names.length; ++j) { - exports[def.names[j]] = def; - } - } - return exports; -})(); + });