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:
parent
8accf0f18a
commit
6bc7cd574f
120
src/buildHTML.js
120
src/buildHTML.js
|
@ -168,16 +168,17 @@ var makeNullDelimiter = function(options) {
|
|||
* 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.
|
||||
*/
|
||||
var groupTypes = {
|
||||
mathord: function(group, options, prev) {
|
||||
var groupTypes = {};
|
||||
|
||||
groupTypes.mathord = function(group, options, prev) {
|
||||
return buildCommon.makeOrd(group, options, "mathord");
|
||||
},
|
||||
};
|
||||
|
||||
textord: function(group, options, prev) {
|
||||
groupTypes.textord = function(group, options, prev) {
|
||||
return buildCommon.makeOrd(group, options, "textord");
|
||||
},
|
||||
};
|
||||
|
||||
bin: function(group, options, prev) {
|
||||
groupTypes.bin = function(group, options, prev) {
|
||||
var className = "mbin";
|
||||
// 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
|
||||
|
@ -198,46 +199,46 @@ var groupTypes = {
|
|||
|
||||
return buildCommon.mathsym(
|
||||
group.value, group.mode, options.getColor(), [className]);
|
||||
},
|
||||
};
|
||||
|
||||
rel: function(group, options, prev) {
|
||||
groupTypes.rel = function(group, options, prev) {
|
||||
return buildCommon.mathsym(
|
||||
group.value, group.mode, options.getColor(), ["mrel"]);
|
||||
},
|
||||
};
|
||||
|
||||
open: function(group, options, prev) {
|
||||
groupTypes.open = function(group, options, prev) {
|
||||
return buildCommon.mathsym(
|
||||
group.value, group.mode, options.getColor(), ["mopen"]);
|
||||
},
|
||||
};
|
||||
|
||||
close: function(group, options, prev) {
|
||||
groupTypes.close = function(group, options, prev) {
|
||||
return buildCommon.mathsym(
|
||||
group.value, group.mode, options.getColor(), ["mclose"]);
|
||||
},
|
||||
};
|
||||
|
||||
inner: function(group, options, prev) {
|
||||
groupTypes.inner = function(group, options, prev) {
|
||||
return buildCommon.mathsym(
|
||||
group.value, group.mode, options.getColor(), ["minner"]);
|
||||
},
|
||||
};
|
||||
|
||||
punct: function(group, options, prev) {
|
||||
groupTypes.punct = function(group, options, prev) {
|
||||
return buildCommon.mathsym(
|
||||
group.value, group.mode, options.getColor(), ["mpunct"]);
|
||||
},
|
||||
};
|
||||
|
||||
ordgroup: function(group, options, prev) {
|
||||
groupTypes.ordgroup = function(group, options, prev) {
|
||||
return makeSpan(
|
||||
["mord", options.style.cls()],
|
||||
buildExpression(group.value, options.reset())
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
text: function(group, options, prev) {
|
||||
groupTypes.text = function(group, options, prev) {
|
||||
return makeSpan(["text", "mord", options.style.cls()],
|
||||
buildExpression(group.value.body, options.reset()));
|
||||
},
|
||||
};
|
||||
|
||||
color: function(group, options, prev) {
|
||||
groupTypes.color = function(group, options, prev) {
|
||||
var elements = buildExpression(
|
||||
group.value.value,
|
||||
options.withColor(group.value.color),
|
||||
|
@ -249,9 +250,9 @@ var groupTypes = {
|
|||
// elements will be able to directly interact with their neighbors. For
|
||||
// example, `\color{red}{2 +} 3` has the same spacing as `2 + 3`
|
||||
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
|
||||
// 445-446, rules 18(a-f).
|
||||
|
||||
|
@ -370,9 +371,9 @@ var groupTypes = {
|
|||
|
||||
return makeSpan([getTypeOfGroup(group.value.base)],
|
||||
[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).
|
||||
// Figure out what style this fraction should be in based on the
|
||||
// function used
|
||||
|
@ -503,9 +504,9 @@ var groupTypes = {
|
|||
["mord", options.style.reset(), fstyle.cls()],
|
||||
[leftDelim, makeSpan(["mfrac"], [frac]), rightDelim],
|
||||
options.getColor());
|
||||
},
|
||||
};
|
||||
|
||||
array: function(group, options, prev) {
|
||||
groupTypes.array = function(group, options, prev) {
|
||||
var r, c;
|
||||
var nr = group.value.body.length;
|
||||
var nc = 0;
|
||||
|
@ -664,9 +665,9 @@ var groupTypes = {
|
|||
}
|
||||
body = makeSpan(["mtable"], cols);
|
||||
return makeSpan(["mord"], [body], options.getColor());
|
||||
},
|
||||
};
|
||||
|
||||
spacing: function(group, options, prev) {
|
||||
groupTypes.spacing = function(group, options, prev) {
|
||||
if (group.value === "\\ " || group.value === "\\space" ||
|
||||
group.value === " " || group.value === "~") {
|
||||
// Spaces are generated by adding an actual space. Each of these
|
||||
|
@ -683,25 +684,25 @@ var groupTypes = {
|
|||
["mord", "mspace",
|
||||
buildCommon.spacingFunctions[group.value].className]);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
llap: function(group, options, prev) {
|
||||
groupTypes.llap = function(group, options, prev) {
|
||||
var inner = makeSpan(
|
||||
["inner"], [buildGroup(group.value.body, options.reset())]);
|
||||
var fix = makeSpan(["fix"], []);
|
||||
return makeSpan(
|
||||
["llap", options.style.cls()], [inner, fix]);
|
||||
},
|
||||
};
|
||||
|
||||
rlap: function(group, options, prev) {
|
||||
groupTypes.rlap = function(group, options, prev) {
|
||||
var inner = makeSpan(
|
||||
["inner"], [buildGroup(group.value.body, options.reset())]);
|
||||
var fix = makeSpan(["fix"], []);
|
||||
return makeSpan(
|
||||
["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).
|
||||
var supGroup;
|
||||
var subGroup;
|
||||
|
@ -858,9 +859,9 @@ var groupTypes = {
|
|||
|
||||
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
|
||||
// good, but the offsets for the T, E, and X were taken from the
|
||||
// definition of \TeX in TeX (see TeXbook pg. 356)
|
||||
|
@ -885,9 +886,9 @@ var groupTypes = {
|
|||
|
||||
return makeSpan(
|
||||
["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.
|
||||
|
||||
// Build the inner group in the cramped style.
|
||||
|
@ -912,9 +913,9 @@ var groupTypes = {
|
|||
], "firstBaseline", null, options);
|
||||
|
||||
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.
|
||||
|
||||
// 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]);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
sizing: function(group, options, prev) {
|
||||
groupTypes.sizing = function(group, options, prev) {
|
||||
// Handle sizing operators like \Huge. Real TeX doesn't actually allow
|
||||
// these functions inside of math expressions, so we do some special
|
||||
// handling.
|
||||
|
@ -1030,9 +1031,9 @@ var groupTypes = {
|
|||
span.maxFontSize = fontSize * options.style.sizeMultiplier;
|
||||
|
||||
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.
|
||||
|
||||
// Figure out what style we're changing to.
|
||||
|
@ -1050,14 +1051,14 @@ var groupTypes = {
|
|||
group.value.value, options.withStyle(newStyle), prev);
|
||||
|
||||
return makeSpan([options.style.reset(), newStyle.cls()], inner);
|
||||
},
|
||||
};
|
||||
|
||||
font: function(group, options, prev) {
|
||||
groupTypes.font = function(group, options, prev) {
|
||||
var font = group.value.font;
|
||||
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;
|
||||
|
||||
if (delim === ".") {
|
||||
|
@ -1071,9 +1072,9 @@ var groupTypes = {
|
|||
[groupToType[group.value.delimType]],
|
||||
[delimiter.sizedDelim(
|
||||
delim, group.value.size, options, group.mode)]);
|
||||
},
|
||||
};
|
||||
|
||||
leftright: function(group, options, prev) {
|
||||
groupTypes.leftright = function(group, options, prev) {
|
||||
// Build the inner expression
|
||||
var inner = buildExpression(group.value.body, options.reset());
|
||||
|
||||
|
@ -1120,9 +1121,9 @@ var groupTypes = {
|
|||
|
||||
return makeSpan(
|
||||
["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
|
||||
var rule = makeSpan(["mord", "rule"], [], options.getColor());
|
||||
|
||||
|
@ -1162,9 +1163,9 @@ var groupTypes = {
|
|||
rule.depth = -shift;
|
||||
|
||||
return rule;
|
||||
},
|
||||
};
|
||||
|
||||
accent: function(group, options, prev) {
|
||||
groupTypes.accent = function(group, options, prev) {
|
||||
// Accents are handled in the TeXbook pg. 443, rule 12.
|
||||
var base = group.value.base;
|
||||
|
||||
|
@ -1268,9 +1269,9 @@ var groupTypes = {
|
|||
} else {
|
||||
return accentWrap;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
phantom: function(group, options, prev) {
|
||||
groupTypes.phantom = function(group, options, prev) {
|
||||
var elements = buildExpression(
|
||||
group.value.value,
|
||||
options.withPhantom(),
|
||||
|
@ -1280,8 +1281,7 @@ var groupTypes = {
|
|||
// \phantom isn't supposed to affect the elements it contains.
|
||||
// See "color" for more details.
|
||||
return new buildCommon.makeFragment(elements);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* buildGroup is the function that takes a group and calls the correct groupType
|
||||
|
|
|
@ -61,8 +61,9 @@ var getVariant = function(group, options) {
|
|||
* 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.
|
||||
*/
|
||||
var groupTypes = {
|
||||
mathord: function(group, options) {
|
||||
var groupTypes = {};
|
||||
|
||||
groupTypes.mathord = function(group, options) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mi",
|
||||
[makeText(group.value, group.mode)]);
|
||||
|
@ -72,9 +73,9 @@ var groupTypes = {
|
|||
node.setAttribute("mathvariant", variant);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
textord: function(group, options) {
|
||||
groupTypes.textord = function(group, options) {
|
||||
var text = makeText(group.value, group.mode);
|
||||
|
||||
var variant = getVariant(group, options) || "normal";
|
||||
|
@ -93,69 +94,69 @@ var groupTypes = {
|
|||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
bin: function(group) {
|
||||
groupTypes.bin = function(group) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mo", [makeText(group.value, group.mode)]);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
rel: function(group) {
|
||||
groupTypes.rel = function(group) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mo", [makeText(group.value, group.mode)]);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
open: function(group) {
|
||||
groupTypes.open = function(group) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mo", [makeText(group.value, group.mode)]);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
close: function(group) {
|
||||
groupTypes.close = function(group) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mo", [makeText(group.value, group.mode)]);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
inner: function(group) {
|
||||
groupTypes.inner = function(group) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mo", [makeText(group.value, group.mode)]);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
punct: function(group) {
|
||||
groupTypes.punct = function(group) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mo", [makeText(group.value, group.mode)]);
|
||||
|
||||
node.setAttribute("separator", "true");
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
ordgroup: function(group, options) {
|
||||
groupTypes.ordgroup = function(group, options) {
|
||||
var inner = buildExpression(group.value, options);
|
||||
|
||||
var node = new mathMLTree.MathNode("mrow", inner);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
text: function(group, options) {
|
||||
groupTypes.text = function(group, options) {
|
||||
var inner = buildExpression(group.value.body, options);
|
||||
|
||||
var node = new mathMLTree.MathNode("mtext", inner);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
color: function(group, options) {
|
||||
groupTypes.color = function(group, options) {
|
||||
var inner = buildExpression(group.value.value, options);
|
||||
|
||||
var node = new mathMLTree.MathNode("mstyle", inner);
|
||||
|
@ -163,9 +164,9 @@ var groupTypes = {
|
|||
node.setAttribute("mathcolor", group.value.color);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
supsub: function(group, options) {
|
||||
groupTypes.supsub = function(group, options) {
|
||||
var children = [buildGroup(group.value.base, options)];
|
||||
|
||||
if (group.value.sub) {
|
||||
|
@ -188,9 +189,9 @@ var groupTypes = {
|
|||
var node = new mathMLTree.MathNode(nodeType, children);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
genfrac: function(group, options) {
|
||||
groupTypes.genfrac = function(group, options) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mfrac",
|
||||
[buildGroup(group.value.numer, options),
|
||||
|
@ -229,9 +230,9 @@ var groupTypes = {
|
|||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
array: function(group, options) {
|
||||
groupTypes.array = function(group, options) {
|
||||
return new mathMLTree.MathNode(
|
||||
"mtable", group.value.body.map(function(row) {
|
||||
return new mathMLTree.MathNode(
|
||||
|
@ -240,9 +241,9 @@ var groupTypes = {
|
|||
"mtd", [buildGroup(cell, options)]);
|
||||
}));
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
sqrt: function(group, options) {
|
||||
groupTypes.sqrt = function(group, options) {
|
||||
var node;
|
||||
if (group.value.index) {
|
||||
node = new mathMLTree.MathNode(
|
||||
|
@ -256,9 +257,9 @@ var groupTypes = {
|
|||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
leftright: function(group, options) {
|
||||
groupTypes.leftright = function(group, options) {
|
||||
var inner = buildExpression(group.value.body, options);
|
||||
|
||||
if (group.value.left !== ".") {
|
||||
|
@ -282,9 +283,9 @@ var groupTypes = {
|
|||
var outerNode = new mathMLTree.MathNode("mrow", inner);
|
||||
|
||||
return outerNode;
|
||||
},
|
||||
};
|
||||
|
||||
accent: function(group, options) {
|
||||
groupTypes.accent = function(group, options) {
|
||||
var accentNode = new mathMLTree.MathNode(
|
||||
"mo", [makeText(group.value.accent, group.mode)]);
|
||||
|
||||
|
@ -296,9 +297,9 @@ var groupTypes = {
|
|||
node.setAttribute("accent", "true");
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
spacing: function(group) {
|
||||
groupTypes.spacing = function(group) {
|
||||
var node;
|
||||
|
||||
if (group.value === "\\ " || group.value === "\\space" ||
|
||||
|
@ -313,9 +314,9 @@ var groupTypes = {
|
|||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
op: function(group) {
|
||||
groupTypes.op = function(group) {
|
||||
var node;
|
||||
|
||||
// TODO(emily): handle big operators using the `largeop` attribute
|
||||
|
@ -334,21 +335,21 @@ var groupTypes = {
|
|||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
katex: function(group) {
|
||||
groupTypes.katex = function(group) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mtext", [new mathMLTree.TextNode("KaTeX")]);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
font: function(group, options) {
|
||||
groupTypes.font = function(group, options) {
|
||||
var font = group.value.font;
|
||||
return buildGroup(group.value.body, options.withFont(font));
|
||||
},
|
||||
};
|
||||
|
||||
delimsizing: function(group) {
|
||||
groupTypes.delimsizing = function(group) {
|
||||
var children = [];
|
||||
|
||||
if (group.value.value !== ".") {
|
||||
|
@ -369,9 +370,9 @@ var groupTypes = {
|
|||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
styling: function(group, options) {
|
||||
groupTypes.styling = function(group, options) {
|
||||
var inner = buildExpression(group.value.value, options);
|
||||
|
||||
var node = new mathMLTree.MathNode("mstyle", inner);
|
||||
|
@ -389,9 +390,9 @@ var groupTypes = {
|
|||
node.setAttribute("displaystyle", attr[1]);
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
sizing: function(group, options) {
|
||||
groupTypes.sizing = function(group, options) {
|
||||
var inner = buildExpression(group.value.value, options);
|
||||
|
||||
var node = new mathMLTree.MathNode("mstyle", inner);
|
||||
|
@ -405,9 +406,9 @@ var groupTypes = {
|
|||
"mathsize", buildCommon.sizingMultiplier[group.value.size] + "em");
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
overline: function(group, options) {
|
||||
groupTypes.overline = function(group, options) {
|
||||
var operator = new mathMLTree.MathNode(
|
||||
"mo", [new mathMLTree.TextNode("\u203e")]);
|
||||
operator.setAttribute("stretchy", "true");
|
||||
|
@ -419,17 +420,17 @@ var groupTypes = {
|
|||
node.setAttribute("accent", "true");
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
rule: function(group) {
|
||||
groupTypes.rule = function(group) {
|
||||
// TODO(emily): Figure out if there's an actual way to draw black boxes
|
||||
// in MathML.
|
||||
var node = new mathMLTree.MathNode("mrow");
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
llap: function(group, options) {
|
||||
groupTypes.llap = function(group, options) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mpadded", [buildGroup(group.value.body, options)]);
|
||||
|
||||
|
@ -437,22 +438,21 @@ var groupTypes = {
|
|||
node.setAttribute("width", "0px");
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
rlap: function(group, options) {
|
||||
groupTypes.rlap = function(group, options) {
|
||||
var node = new mathMLTree.MathNode(
|
||||
"mpadded", [buildGroup(group.value.body, options)]);
|
||||
|
||||
node.setAttribute("width", "0px");
|
||||
|
||||
return node;
|
||||
},
|
||||
};
|
||||
|
||||
phantom: function(group, options, prev) {
|
||||
groupTypes.phantom = function(group, options, prev) {
|
||||
var inner = buildExpression(group.value.value, options);
|
||||
return new mathMLTree.MathNode("mphantom", inner);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes a list of nodes, builds them, and returns a list of the generated
|
||||
|
|
Loading…
Reference in New Issue
Block a user