commit d7d13675586c1fa6dfc34c24020a61e603950948
parent 0fc77e2f4018adf23e0d9c1aabf05edcc984e4d3
Author: Kevin Barabash <kevinb7@gmail.com>
Date: Mon, 14 Sep 2015 22:51:04 -0600
Merge pull request #347 from gagern/splitEnvironments
Split up environments list into calls to defineEnvironment
Diffstat:
| M | src/environments.js | | | 248 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
1 file changed, 124 insertions(+), 124 deletions(-)
diff --git a/src/environments.js b/src/environments.js
@@ -38,141 +38,141 @@ 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:
- * - 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.
+ * 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) {
- var parser = this;
- colalign = colalign.value.map ? colalign.value : [colalign];
- var cols = colalign.map(function(node) {
- var ca = node.value;
- if ("lcr".indexOf(ca) !== -1) {
- return {
- type: "align",
- align: ca
- };
- } else if (ca === "|") {
- return {
- type: "separator",
- separator: "|"
- };
- }
- throw new ParseError(
- "Unknown column alignment: " + node.value,
- parser.lexer, positions[1]);
- });
- var res = {
- type: "array",
- cols: cols,
- hskipBeforeAndAfter: true // \@preamble in lttab.dtx
+// Arrays are part of LaTeX, defined in lttab.dtx so its documentation
+// is part of the source2e.pdf file of LaTeX2e source documentation.
+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) {
+ var ca = node.value;
+ if ("lcr".indexOf(ca) !== -1) {
+ return {
+ type: "align",
+ align: ca
};
- 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: [
- "matrix",
- "pmatrix",
- "bmatrix",
- "Bmatrix",
- "vmatrix",
- "Vmatrix"
- ],
- handler: function(pos, mode, envName) {
- var delimiters = {
- "matrix": null,
- "pmatrix": ["(", ")"],
- "bmatrix": ["[", "]"],
- "Bmatrix": ["\\{", "\\}"],
- "vmatrix": ["|", "|"],
- "Vmatrix": ["\\Vert", "\\Vert"]
- }[envName];
- var res = {
- type: "array",
- hskipBeforeAndAfter: false // \hskip -\arraycolsep in amsmath
+ } else if (ca === "|") {
+ return {
+ type: "separator",
+ separator: "|"
};
- res = parseArray(this, pos, mode, res);
- if (delimiters) {
- res.result = new ParseNode("leftright", {
- body: [res.result],
- left: delimiters[0],
- right: delimiters[1]
- }, mode);
- }
- return res;
}
- },
+ throw new ParseError(
+ "Unknown column alignment: " + node.value,
+ parser.lexer, positions[1]);
+ });
+ var res = {
+ type: "array",
+ cols: cols,
+ hskipBeforeAndAfter: true // \@preamble in lttab.dtx
+ };
+ res = parseArray(parser, pos, mode, res);
+ 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) {
- var res = {
- type: "array",
- arraystretch: 1.2,
- cols: [{
- type: "align",
- align: "l",
- pregap: 0,
- postgap: fontMetrics.metrics.quad
- }, {
- type: "align",
- align: "l",
- pregap: 0,
- postgap: 0
- }]
- };
- res = parseArray(this, pos, mode, res);
- res.result = new ParseNode("leftright", {
- body: [res.result],
- left: "\\{",
- right: "."
- }, mode);
- return res;
- }
+// The matrix environments of amsmath builds on the array environment
+// of LaTeX, which is discussed above.
+defineEnvironment([
+ "matrix",
+ "pmatrix",
+ "bmatrix",
+ "Bmatrix",
+ "vmatrix",
+ "Vmatrix"
+], {
+}, function(pos, mode, envName) {
+ var delimiters = {
+ "matrix": null,
+ "pmatrix": ["(", ")"],
+ "bmatrix": ["[", "]"],
+ "Bmatrix": ["\\{", "\\}"],
+ "vmatrix": ["|", "|"],
+ "Vmatrix": ["\\Vert", "\\Vert"]
+ }[envName];
+ var res = {
+ type: "array",
+ hskipBeforeAndAfter: false // \hskip -\arraycolsep in amsmath
+ };
+ res = parseArray(this, pos, mode, res);
+ if (delimiters) {
+ res.result = new ParseNode("leftright", {
+ body: [res.result],
+ left: delimiters[0],
+ right: delimiters[1]
+ }, 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;
-})();
+// A cases environment (in amsmath.sty) is almost equivalent to
+// \def\arraystretch{1.2}%
+// \left\{\begin{array}{@{}l@{\quad}l@{}} … \end{array}\right.
+defineEnvironment("cases", {
+}, function(pos, mode, envName) {
+ var res = {
+ type: "array",
+ arraystretch: 1.2,
+ cols: [{
+ type: "align",
+ align: "l",
+ pregap: 0,
+ postgap: fontMetrics.metrics.quad
+ }, {
+ type: "align",
+ align: "l",
+ pregap: 0,
+ postgap: 0
+ }]
+ };
+ res = parseArray(this, pos, mode, res);
+ res.result = new ParseNode("leftright", {
+ body: [res.result],
+ left: "\\{",
+ right: "."
+ }, mode);
+ return res;
+});