Split up groupType map in buildHTML and buildMathML code

Having long object literals containing the code is problematic.
It makes it difficult to add auxiliary functions or data close to the
function inside the map where it is needed.
Building the map in several steps, repeating the map name at each step,
avoids that problem since it makes the definitions independent from one
another, so anything can go between them.

This commit deliberately avoided reindenting existing code to match the new
surroundings.  That way it is easier to see where actual changes happen,
even when not performing a whitespace-ignoring diff.
This commit is contained in:
Martin von Gagern 2015-09-10 11:34:34 +02:00
parent 8accf0f18a
commit 6bc7cd574f
2 changed files with 120 additions and 120 deletions

View File

@ -168,16 +168,17 @@ var makeNullDelimiter = function(options) {
* This is a map of group types to the function used to handle that type. * This is a map of group types to the function used to handle that type.
* Simpler types come at the beginning, while complicated types come afterwards. * Simpler types come at the beginning, while complicated types come afterwards.
*/ */
var groupTypes = { var groupTypes = {};
mathord: function(group, options, prev) {
groupTypes.mathord = function(group, options, prev) {
return buildCommon.makeOrd(group, options, "mathord"); return buildCommon.makeOrd(group, options, "mathord");
}, };
textord: function(group, options, prev) { groupTypes.textord = function(group, options, prev) {
return buildCommon.makeOrd(group, options, "textord"); return buildCommon.makeOrd(group, options, "textord");
}, };
bin: function(group, options, prev) { groupTypes.bin = function(group, options, prev) {
var className = "mbin"; var className = "mbin";
// Pull out the most recent element. Do some special handling to find // Pull out the most recent element. Do some special handling to find
// things at the end of a \color group. Note that we don't use the same // things at the end of a \color group. Note that we don't use the same
@ -198,46 +199,46 @@ var groupTypes = {
return buildCommon.mathsym( return buildCommon.mathsym(
group.value, group.mode, options.getColor(), [className]); group.value, group.mode, options.getColor(), [className]);
}, };
rel: function(group, options, prev) { groupTypes.rel = function(group, options, prev) {
return buildCommon.mathsym( return buildCommon.mathsym(
group.value, group.mode, options.getColor(), ["mrel"]); group.value, group.mode, options.getColor(), ["mrel"]);
}, };
open: function(group, options, prev) { groupTypes.open = function(group, options, prev) {
return buildCommon.mathsym( return buildCommon.mathsym(
group.value, group.mode, options.getColor(), ["mopen"]); group.value, group.mode, options.getColor(), ["mopen"]);
}, };
close: function(group, options, prev) { groupTypes.close = function(group, options, prev) {
return buildCommon.mathsym( return buildCommon.mathsym(
group.value, group.mode, options.getColor(), ["mclose"]); group.value, group.mode, options.getColor(), ["mclose"]);
}, };
inner: function(group, options, prev) { groupTypes.inner = function(group, options, prev) {
return buildCommon.mathsym( return buildCommon.mathsym(
group.value, group.mode, options.getColor(), ["minner"]); group.value, group.mode, options.getColor(), ["minner"]);
}, };
punct: function(group, options, prev) { groupTypes.punct = function(group, options, prev) {
return buildCommon.mathsym( return buildCommon.mathsym(
group.value, group.mode, options.getColor(), ["mpunct"]); group.value, group.mode, options.getColor(), ["mpunct"]);
}, };
ordgroup: function(group, options, prev) { groupTypes.ordgroup = function(group, options, prev) {
return makeSpan( return makeSpan(
["mord", options.style.cls()], ["mord", options.style.cls()],
buildExpression(group.value, options.reset()) buildExpression(group.value, options.reset())
); );
}, };
text: function(group, options, prev) { groupTypes.text = function(group, options, prev) {
return makeSpan(["text", "mord", options.style.cls()], return makeSpan(["text", "mord", options.style.cls()],
buildExpression(group.value.body, options.reset())); buildExpression(group.value.body, options.reset()));
}, };
color: function(group, options, prev) { groupTypes.color = function(group, options, prev) {
var elements = buildExpression( var elements = buildExpression(
group.value.value, group.value.value,
options.withColor(group.value.color), options.withColor(group.value.color),
@ -249,9 +250,9 @@ var groupTypes = {
// elements will be able to directly interact with their neighbors. For // elements will be able to directly interact with their neighbors. For
// example, `\color{red}{2 +} 3` has the same spacing as `2 + 3` // example, `\color{red}{2 +} 3` has the same spacing as `2 + 3`
return new buildCommon.makeFragment(elements); return new buildCommon.makeFragment(elements);
}, };
supsub: function(group, options, prev) { groupTypes.supsub = function(group, options, prev) {
// Superscript and subscripts are handled in the TeXbook on page // Superscript and subscripts are handled in the TeXbook on page
// 445-446, rules 18(a-f). // 445-446, rules 18(a-f).
@ -370,9 +371,9 @@ var groupTypes = {
return makeSpan([getTypeOfGroup(group.value.base)], return makeSpan([getTypeOfGroup(group.value.base)],
[base, supsub]); [base, supsub]);
}, };
genfrac: function(group, options, prev) { groupTypes.genfrac = function(group, options, prev) {
// Fractions are handled in the TeXbook on pages 444-445, rules 15(a-e). // Fractions are handled in the TeXbook on pages 444-445, rules 15(a-e).
// Figure out what style this fraction should be in based on the // Figure out what style this fraction should be in based on the
// function used // function used
@ -503,9 +504,9 @@ var groupTypes = {
["mord", options.style.reset(), fstyle.cls()], ["mord", options.style.reset(), fstyle.cls()],
[leftDelim, makeSpan(["mfrac"], [frac]), rightDelim], [leftDelim, makeSpan(["mfrac"], [frac]), rightDelim],
options.getColor()); options.getColor());
}, };
array: function(group, options, prev) { groupTypes.array = function(group, options, prev) {
var r, c; var r, c;
var nr = group.value.body.length; var nr = group.value.body.length;
var nc = 0; var nc = 0;
@ -664,9 +665,9 @@ var groupTypes = {
} }
body = makeSpan(["mtable"], cols); body = makeSpan(["mtable"], cols);
return makeSpan(["mord"], [body], options.getColor()); return makeSpan(["mord"], [body], options.getColor());
}, };
spacing: function(group, options, prev) { groupTypes.spacing = function(group, options, prev) {
if (group.value === "\\ " || group.value === "\\space" || if (group.value === "\\ " || group.value === "\\space" ||
group.value === " " || group.value === "~") { group.value === " " || group.value === "~") {
// Spaces are generated by adding an actual space. Each of these // Spaces are generated by adding an actual space. Each of these
@ -683,25 +684,25 @@ var groupTypes = {
["mord", "mspace", ["mord", "mspace",
buildCommon.spacingFunctions[group.value].className]); buildCommon.spacingFunctions[group.value].className]);
} }
}, };
llap: function(group, options, prev) { groupTypes.llap = function(group, options, prev) {
var inner = makeSpan( var inner = makeSpan(
["inner"], [buildGroup(group.value.body, options.reset())]); ["inner"], [buildGroup(group.value.body, options.reset())]);
var fix = makeSpan(["fix"], []); var fix = makeSpan(["fix"], []);
return makeSpan( return makeSpan(
["llap", options.style.cls()], [inner, fix]); ["llap", options.style.cls()], [inner, fix]);
}, };
rlap: function(group, options, prev) { groupTypes.rlap = function(group, options, prev) {
var inner = makeSpan( var inner = makeSpan(
["inner"], [buildGroup(group.value.body, options.reset())]); ["inner"], [buildGroup(group.value.body, options.reset())]);
var fix = makeSpan(["fix"], []); var fix = makeSpan(["fix"], []);
return makeSpan( return makeSpan(
["rlap", options.style.cls()], [inner, fix]); ["rlap", options.style.cls()], [inner, fix]);
}, };
op: function(group, options, prev) { groupTypes.op = function(group, options, prev) {
// Operators are handled in the TeXbook pg. 443-444, rule 13(a). // Operators are handled in the TeXbook pg. 443-444, rule 13(a).
var supGroup; var supGroup;
var subGroup; var subGroup;
@ -858,9 +859,9 @@ var groupTypes = {
return base; return base;
} }
}, };
katex: function(group, options, prev) { groupTypes.katex = function(group, options, prev) {
// The KaTeX logo. The offsets for the K and a were chosen to look // The KaTeX logo. The offsets for the K and a were chosen to look
// good, but the offsets for the T, E, and X were taken from the // good, but the offsets for the T, E, and X were taken from the
// definition of \TeX in TeX (see TeXbook pg. 356) // definition of \TeX in TeX (see TeXbook pg. 356)
@ -885,9 +886,9 @@ var groupTypes = {
return makeSpan( return makeSpan(
["katex-logo", "mord"], [k, a, t, e, x], options.getColor()); ["katex-logo", "mord"], [k, a, t, e, x], options.getColor());
}, };
overline: function(group, options, prev) { groupTypes.overline = function(group, options, prev) {
// Overlines are handled in the TeXbook pg 443, Rule 9. // Overlines are handled in the TeXbook pg 443, Rule 9.
// Build the inner group in the cramped style. // Build the inner group in the cramped style.
@ -912,9 +913,9 @@ var groupTypes = {
], "firstBaseline", null, options); ], "firstBaseline", null, options);
return makeSpan(["overline", "mord"], [vlist], options.getColor()); return makeSpan(["overline", "mord"], [vlist], options.getColor());
}, };
sqrt: function(group, options, prev) { groupTypes.sqrt = function(group, options, prev) {
// Square roots are handled in the TeXbook pg. 443, Rule 11. // Square roots are handled in the TeXbook pg. 443, Rule 11.
// First, we do the same steps as in overline to build the inner group // First, we do the same steps as in overline to build the inner group
@ -1011,9 +1012,9 @@ var groupTypes = {
return makeSpan(["sqrt", "mord"], [rootVListWrap, delim, body]); return makeSpan(["sqrt", "mord"], [rootVListWrap, delim, body]);
} }
}, };
sizing: function(group, options, prev) { groupTypes.sizing = function(group, options, prev) {
// Handle sizing operators like \Huge. Real TeX doesn't actually allow // Handle sizing operators like \Huge. Real TeX doesn't actually allow
// these functions inside of math expressions, so we do some special // these functions inside of math expressions, so we do some special
// handling. // handling.
@ -1030,9 +1031,9 @@ var groupTypes = {
span.maxFontSize = fontSize * options.style.sizeMultiplier; span.maxFontSize = fontSize * options.style.sizeMultiplier;
return span; return span;
}, };
styling: function(group, options, prev) { groupTypes.styling = function(group, options, prev) {
// Style changes are handled in the TeXbook on pg. 442, Rule 3. // Style changes are handled in the TeXbook on pg. 442, Rule 3.
// Figure out what style we're changing to. // Figure out what style we're changing to.
@ -1050,14 +1051,14 @@ var groupTypes = {
group.value.value, options.withStyle(newStyle), prev); group.value.value, options.withStyle(newStyle), prev);
return makeSpan([options.style.reset(), newStyle.cls()], inner); return makeSpan([options.style.reset(), newStyle.cls()], inner);
}, };
font: function(group, options, prev) { groupTypes.font = function(group, options, prev) {
var font = group.value.font; var font = group.value.font;
return buildGroup(group.value.body, options.withFont(font), prev); return buildGroup(group.value.body, options.withFont(font), prev);
}, };
delimsizing: function(group, options, prev) { groupTypes.delimsizing = function(group, options, prev) {
var delim = group.value.value; var delim = group.value.value;
if (delim === ".") { if (delim === ".") {
@ -1071,9 +1072,9 @@ var groupTypes = {
[groupToType[group.value.delimType]], [groupToType[group.value.delimType]],
[delimiter.sizedDelim( [delimiter.sizedDelim(
delim, group.value.size, options, group.mode)]); delim, group.value.size, options, group.mode)]);
}, };
leftright: function(group, options, prev) { groupTypes.leftright = function(group, options, prev) {
// Build the inner expression // Build the inner expression
var inner = buildExpression(group.value.body, options.reset()); var inner = buildExpression(group.value.body, options.reset());
@ -1120,9 +1121,9 @@ var groupTypes = {
return makeSpan( return makeSpan(
["minner", options.style.cls()], inner, options.getColor()); ["minner", options.style.cls()], inner, options.getColor());
}, };
rule: function(group, options, prev) { groupTypes.rule = function(group, options, prev) {
// Make an empty span for the rule // Make an empty span for the rule
var rule = makeSpan(["mord", "rule"], [], options.getColor()); var rule = makeSpan(["mord", "rule"], [], options.getColor());
@ -1162,9 +1163,9 @@ var groupTypes = {
rule.depth = -shift; rule.depth = -shift;
return rule; return rule;
}, };
accent: function(group, options, prev) { groupTypes.accent = function(group, options, prev) {
// Accents are handled in the TeXbook pg. 443, rule 12. // Accents are handled in the TeXbook pg. 443, rule 12.
var base = group.value.base; var base = group.value.base;
@ -1268,9 +1269,9 @@ var groupTypes = {
} else { } else {
return accentWrap; return accentWrap;
} }
}, };
phantom: function(group, options, prev) { groupTypes.phantom = function(group, options, prev) {
var elements = buildExpression( var elements = buildExpression(
group.value.value, group.value.value,
options.withPhantom(), options.withPhantom(),
@ -1280,8 +1281,7 @@ var groupTypes = {
// \phantom isn't supposed to affect the elements it contains. // \phantom isn't supposed to affect the elements it contains.
// See "color" for more details. // See "color" for more details.
return new buildCommon.makeFragment(elements); return new buildCommon.makeFragment(elements);
} };
};
/** /**
* buildGroup is the function that takes a group and calls the correct groupType * buildGroup is the function that takes a group and calls the correct groupType

View File

@ -61,8 +61,9 @@ var getVariant = function(group, options) {
* Functions for handling the different types of groups found in the parse * Functions for handling the different types of groups found in the parse
* tree. Each function should take a parse group and return a MathML node. * tree. Each function should take a parse group and return a MathML node.
*/ */
var groupTypes = { var groupTypes = {};
mathord: function(group, options) {
groupTypes.mathord = function(group, options) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mi", "mi",
[makeText(group.value, group.mode)]); [makeText(group.value, group.mode)]);
@ -72,9 +73,9 @@ var groupTypes = {
node.setAttribute("mathvariant", variant); node.setAttribute("mathvariant", variant);
} }
return node; return node;
}, };
textord: function(group, options) { groupTypes.textord = function(group, options) {
var text = makeText(group.value, group.mode); var text = makeText(group.value, group.mode);
var variant = getVariant(group, options) || "normal"; var variant = getVariant(group, options) || "normal";
@ -93,69 +94,69 @@ var groupTypes = {
} }
return node; return node;
}, };
bin: function(group) { groupTypes.bin = function(group) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]); "mo", [makeText(group.value, group.mode)]);
return node; return node;
}, };
rel: function(group) { groupTypes.rel = function(group) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]); "mo", [makeText(group.value, group.mode)]);
return node; return node;
}, };
open: function(group) { groupTypes.open = function(group) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]); "mo", [makeText(group.value, group.mode)]);
return node; return node;
}, };
close: function(group) { groupTypes.close = function(group) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]); "mo", [makeText(group.value, group.mode)]);
return node; return node;
}, };
inner: function(group) { groupTypes.inner = function(group) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]); "mo", [makeText(group.value, group.mode)]);
return node; return node;
}, };
punct: function(group) { groupTypes.punct = function(group) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]); "mo", [makeText(group.value, group.mode)]);
node.setAttribute("separator", "true"); node.setAttribute("separator", "true");
return node; return node;
}, };
ordgroup: function(group, options) { groupTypes.ordgroup = function(group, options) {
var inner = buildExpression(group.value, options); var inner = buildExpression(group.value, options);
var node = new mathMLTree.MathNode("mrow", inner); var node = new mathMLTree.MathNode("mrow", inner);
return node; return node;
}, };
text: function(group, options) { groupTypes.text = function(group, options) {
var inner = buildExpression(group.value.body, options); var inner = buildExpression(group.value.body, options);
var node = new mathMLTree.MathNode("mtext", inner); var node = new mathMLTree.MathNode("mtext", inner);
return node; return node;
}, };
color: function(group, options) { groupTypes.color = function(group, options) {
var inner = buildExpression(group.value.value, options); var inner = buildExpression(group.value.value, options);
var node = new mathMLTree.MathNode("mstyle", inner); var node = new mathMLTree.MathNode("mstyle", inner);
@ -163,9 +164,9 @@ var groupTypes = {
node.setAttribute("mathcolor", group.value.color); node.setAttribute("mathcolor", group.value.color);
return node; return node;
}, };
supsub: function(group, options) { groupTypes.supsub = function(group, options) {
var children = [buildGroup(group.value.base, options)]; var children = [buildGroup(group.value.base, options)];
if (group.value.sub) { if (group.value.sub) {
@ -188,9 +189,9 @@ var groupTypes = {
var node = new mathMLTree.MathNode(nodeType, children); var node = new mathMLTree.MathNode(nodeType, children);
return node; return node;
}, };
genfrac: function(group, options) { groupTypes.genfrac = function(group, options) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mfrac", "mfrac",
[buildGroup(group.value.numer, options), [buildGroup(group.value.numer, options),
@ -229,9 +230,9 @@ var groupTypes = {
} }
return node; return node;
}, };
array: function(group, options) { groupTypes.array = function(group, options) {
return new mathMLTree.MathNode( return new mathMLTree.MathNode(
"mtable", group.value.body.map(function(row) { "mtable", group.value.body.map(function(row) {
return new mathMLTree.MathNode( return new mathMLTree.MathNode(
@ -240,9 +241,9 @@ var groupTypes = {
"mtd", [buildGroup(cell, options)]); "mtd", [buildGroup(cell, options)]);
})); }));
})); }));
}, };
sqrt: function(group, options) { groupTypes.sqrt = function(group, options) {
var node; var node;
if (group.value.index) { if (group.value.index) {
node = new mathMLTree.MathNode( node = new mathMLTree.MathNode(
@ -256,9 +257,9 @@ var groupTypes = {
} }
return node; return node;
}, };
leftright: function(group, options) { groupTypes.leftright = function(group, options) {
var inner = buildExpression(group.value.body, options); var inner = buildExpression(group.value.body, options);
if (group.value.left !== ".") { if (group.value.left !== ".") {
@ -282,9 +283,9 @@ var groupTypes = {
var outerNode = new mathMLTree.MathNode("mrow", inner); var outerNode = new mathMLTree.MathNode("mrow", inner);
return outerNode; return outerNode;
}, };
accent: function(group, options) { groupTypes.accent = function(group, options) {
var accentNode = new mathMLTree.MathNode( var accentNode = new mathMLTree.MathNode(
"mo", [makeText(group.value.accent, group.mode)]); "mo", [makeText(group.value.accent, group.mode)]);
@ -296,9 +297,9 @@ var groupTypes = {
node.setAttribute("accent", "true"); node.setAttribute("accent", "true");
return node; return node;
}, };
spacing: function(group) { groupTypes.spacing = function(group) {
var node; var node;
if (group.value === "\\ " || group.value === "\\space" || if (group.value === "\\ " || group.value === "\\space" ||
@ -313,9 +314,9 @@ var groupTypes = {
} }
return node; return node;
}, };
op: function(group) { groupTypes.op = function(group) {
var node; var node;
// TODO(emily): handle big operators using the `largeop` attribute // TODO(emily): handle big operators using the `largeop` attribute
@ -334,21 +335,21 @@ var groupTypes = {
} }
return node; return node;
}, };
katex: function(group) { groupTypes.katex = function(group) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mtext", [new mathMLTree.TextNode("KaTeX")]); "mtext", [new mathMLTree.TextNode("KaTeX")]);
return node; return node;
}, };
font: function(group, options) { groupTypes.font = function(group, options) {
var font = group.value.font; var font = group.value.font;
return buildGroup(group.value.body, options.withFont(font)); return buildGroup(group.value.body, options.withFont(font));
}, };
delimsizing: function(group) { groupTypes.delimsizing = function(group) {
var children = []; var children = [];
if (group.value.value !== ".") { if (group.value.value !== ".") {
@ -369,9 +370,9 @@ var groupTypes = {
} }
return node; return node;
}, };
styling: function(group, options) { groupTypes.styling = function(group, options) {
var inner = buildExpression(group.value.value, options); var inner = buildExpression(group.value.value, options);
var node = new mathMLTree.MathNode("mstyle", inner); var node = new mathMLTree.MathNode("mstyle", inner);
@ -389,9 +390,9 @@ var groupTypes = {
node.setAttribute("displaystyle", attr[1]); node.setAttribute("displaystyle", attr[1]);
return node; return node;
}, };
sizing: function(group, options) { groupTypes.sizing = function(group, options) {
var inner = buildExpression(group.value.value, options); var inner = buildExpression(group.value.value, options);
var node = new mathMLTree.MathNode("mstyle", inner); var node = new mathMLTree.MathNode("mstyle", inner);
@ -405,9 +406,9 @@ var groupTypes = {
"mathsize", buildCommon.sizingMultiplier[group.value.size] + "em"); "mathsize", buildCommon.sizingMultiplier[group.value.size] + "em");
return node; return node;
}, };
overline: function(group, options) { groupTypes.overline = function(group, options) {
var operator = new mathMLTree.MathNode( var operator = new mathMLTree.MathNode(
"mo", [new mathMLTree.TextNode("\u203e")]); "mo", [new mathMLTree.TextNode("\u203e")]);
operator.setAttribute("stretchy", "true"); operator.setAttribute("stretchy", "true");
@ -419,17 +420,17 @@ var groupTypes = {
node.setAttribute("accent", "true"); node.setAttribute("accent", "true");
return node; return node;
}, };
rule: function(group) { groupTypes.rule = function(group) {
// TODO(emily): Figure out if there's an actual way to draw black boxes // TODO(emily): Figure out if there's an actual way to draw black boxes
// in MathML. // in MathML.
var node = new mathMLTree.MathNode("mrow"); var node = new mathMLTree.MathNode("mrow");
return node; return node;
}, };
llap: function(group, options) { groupTypes.llap = function(group, options) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mpadded", [buildGroup(group.value.body, options)]); "mpadded", [buildGroup(group.value.body, options)]);
@ -437,22 +438,21 @@ var groupTypes = {
node.setAttribute("width", "0px"); node.setAttribute("width", "0px");
return node; return node;
}, };
rlap: function(group, options) { groupTypes.rlap = function(group, options) {
var node = new mathMLTree.MathNode( var node = new mathMLTree.MathNode(
"mpadded", [buildGroup(group.value.body, options)]); "mpadded", [buildGroup(group.value.body, options)]);
node.setAttribute("width", "0px"); node.setAttribute("width", "0px");
return node; return node;
}, };
phantom: function(group, options, prev) { groupTypes.phantom = function(group, options, prev) {
var inner = buildExpression(group.value.value, options); var inner = buildExpression(group.value.value, options);
return new mathMLTree.MathNode("mphantom", inner); return new mathMLTree.MathNode("mphantom", inner);
} };
};
/** /**
* Takes a list of nodes, builds them, and returns a list of the generated * Takes a list of nodes, builds them, and returns a list of the generated