Flatten a bunch of non-pervasive ParseNode types (part 2) (#1552)

* Flatten "operatorname" ParseNode.

* Flatten "overline" ParseNode.

* Flatten "raisebox" ParseNode.

* Flatten "rule" ParseNode.

* Flatten "sizing" ParseNode.

* Flatten "smash" ParseNode.

* Flatten "sqrt" ParseNode.

* Flatten "underline" ParseNode.

* Flatten "enclose" ParseNode.

* Flatten "environment" ParseNode.

* Flatten "genfrac" ParseNode.

* Flatten "htmlmathml" ParseNode.

* Flatten "infix" ParseNode.

* Flatten "kern" ParseNode.

* Flatten "lap" ParseNode.

* Flatten "color" ParseNode.
This commit is contained in:
Ashish Myles
2018-08-06 01:59:44 -04:00
committed by ylemkimon
parent 1506dc1d88
commit 5b6ffd7b9d
21 changed files with 412 additions and 553 deletions

View File

@@ -223,10 +223,10 @@ export default class Parser {
if (overIndex !== -1) {
throw new ParseError(
"only one infix operator per group",
node.value.token);
node.token);
}
overIndex = i;
funcName = node.value.replaceWith;
funcName = node.replaceWith;
}
}
@@ -327,12 +327,9 @@ export default class Parser {
const colorNode = {
type: "color",
value: {
type: "color",
color: this.settings.errorColor,
value: [textNode],
},
mode: this.mode,
color: this.settings.errorColor,
body: [textNode],
};
this.consume();
@@ -460,10 +457,10 @@ export default class Parser {
const begin =
assertNodeType(this.parseGivenFunction(start), "environment");
const envName = begin.value.name;
const envName = begin.name;
if (!environments.hasOwnProperty(envName)) {
throw new ParseError(
"No such environment: " + envName, begin.value.nameGroup);
"No such environment: " + envName, begin.nameGroup);
}
// Build the environment object. Arguments and other information will
// be made available to the begin and end methods using properties.
@@ -483,10 +480,9 @@ export default class Parser {
throw new ParseError("failed to parse function after \\end");
}
end = assertNodeType(end, "environment");
if (end.value.name !== envName) {
if (end.name !== envName) {
throw new ParseError(
"Mismatch: \\begin{" + envName + "} matched " +
"by \\end{" + end.value.name + "}",
`Mismatch: \\begin{${envName}} matched by \\end{${end.name}}`,
endNameToken);
}
return result;

View File

@@ -169,7 +169,7 @@ export const buildExpression = function(
if (!node) {
// No match.
} else if (node.type === "sizing") {
glueOptions = options.havingSize(node.value.size);
glueOptions = options.havingSize(node.size);
} else if (node.type === "styling") {
glueOptions = options.havingStyle(
styleMap[node.value.style]);

View File

@@ -9,8 +9,8 @@ import * as mml from "../buildMathML";
const htmlBuilder = (group, options) => {
const elements = html.buildExpression(
group.value.value,
options.withColor(group.value.color),
group.body,
options.withColor(group.color),
false
);
@@ -22,11 +22,11 @@ const htmlBuilder = (group, options) => {
};
const mathmlBuilder = (group, options) => {
const inner = mml.buildExpression(group.value.value, options);
const inner = mml.buildExpression(group.body, options);
const node = new mathMLTree.MathNode("mstyle", inner);
node.setAttribute("mathcolor", group.value.color);
node.setAttribute("mathcolor", group.color);
return node;
};
@@ -46,11 +46,8 @@ defineFunction({
return {
type: "color",
mode: parser.mode,
value: {
type: "color",
color: color.value,
value: ordargument(body),
},
color: color.value,
body: ordargument(body),
};
},
htmlBuilder,
@@ -85,11 +82,8 @@ defineFunction({
return {
type: "color",
mode: parser.mode,
value: {
type: "color",
color: "katex-" + funcName.slice(1),
value: ordargument(body),
},
color: "katex-" + funcName.slice(1),
body: ordargument(body),
};
},
htmlBuilder,
@@ -114,11 +108,8 @@ defineFunction({
return {
type: "color",
mode: parser.mode,
value: {
type: "color",
color: color.value,
value: body,
},
color: color.value,
body,
};
},
htmlBuilder,

View File

@@ -12,9 +12,9 @@ import * as mml from "../buildMathML";
const htmlBuilder = (group, options) => {
// \cancel, \bcancel, \xcancel, \sout, \fbox, \colorbox, \fcolorbox
const inner = html.buildGroup(group.value.body, options);
const inner = html.buildGroup(group.body, options);
const label = group.value.label.substr(1);
const label = group.label.substr(1);
const scale = options.sizeMultiplier;
let img;
let imgShift = 0;
@@ -24,7 +24,7 @@ const htmlBuilder = (group, options) => {
// We don't know the width of a group, so as a proxy, we test if
// the subject is a single character. This captures most of the
// subjects that should get the "tall" treatment.
const isSingleChar = utils.isCharacterBox(group.value.body);
const isSingleChar = utils.isCharacterBox(group.body);
if (label === "sout") {
img = buildCommon.makeSpan(["stretchy", "sout"]);
@@ -54,16 +54,16 @@ const htmlBuilder = (group, options) => {
img = stretchy.encloseSpan(inner, label, vertPad, options);
imgShift = inner.depth + vertPad;
if (group.value.backgroundColor) {
img.style.backgroundColor = group.value.backgroundColor.value;
if (group.value.borderColor) {
img.style.borderColor = group.value.borderColor.value;
if (group.backgroundColor) {
img.style.backgroundColor = group.backgroundColor.value;
if (group.borderColor) {
img.style.borderColor = group.borderColor.value;
}
}
}
let vlist;
if (group.value.backgroundColor) {
if (group.backgroundColor) {
vlist = buildCommon.makeVList({
positionType: "individualShift",
children: [
@@ -109,8 +109,8 @@ const htmlBuilder = (group, options) => {
const mathmlBuilder = (group, options) => {
const node = new mathMLTree.MathNode(
"menclose", [mml.buildGroup(group.value.body, options)]);
switch (group.value.label) {
"menclose", [mml.buildGroup(group.body, options)]);
switch (group.label) {
case "\\cancel":
node.setAttribute("notation", "updiagonalstrike");
break;
@@ -131,8 +131,8 @@ const mathmlBuilder = (group, options) => {
node.setAttribute("notation", "updiagonalstrike downdiagonalstrike");
break;
}
if (group.value.backgroundColor) {
node.setAttribute("mathbackground", group.value.backgroundColor.value);
if (group.backgroundColor) {
node.setAttribute("mathbackground", group.backgroundColor.value);
}
return node;
};
@@ -152,12 +152,9 @@ defineFunction({
return {
type: "enclose",
mode: parser.mode,
value: {
type: "enclose",
label: funcName,
backgroundColor: color,
body: body,
},
label: funcName,
backgroundColor: color,
body,
};
},
htmlBuilder,
@@ -180,13 +177,10 @@ defineFunction({
return {
type: "enclose",
mode: parser.mode,
value: {
type: "enclose",
label: funcName,
backgroundColor: backgroundColor,
borderColor: borderColor,
body: body,
},
label: funcName,
backgroundColor: backgroundColor,
borderColor: borderColor,
body,
};
},
htmlBuilder,
@@ -205,11 +199,8 @@ defineFunction({
return {
type: "enclose",
mode: parser.mode,
value: {
type: "enclose",
label: "\\fbox",
body: args[0],
},
label: "\\fbox",
body: args[0],
};
},
});
@@ -225,11 +216,8 @@ defineFunction({
return {
type: "enclose",
mode: parser.mode,
value: {
type: "enclose",
label: funcName,
body: body,
},
label: funcName,
body,
};
},
htmlBuilder,

View File

@@ -24,11 +24,8 @@ defineFunction({
return {
type: "environment",
mode: parser.mode,
value: {
type: "environment",
name: name,
nameGroup: nameGroup,
},
name,
nameGroup,
};
},
});

View File

@@ -15,15 +15,15 @@ const htmlBuilder = (group, options) => {
// Figure out what style this fraction should be in based on the
// function used
let style = options.style;
if (group.value.size === "display") {
if (group.size === "display") {
style = Style.DISPLAY;
} else if (group.value.size === "text" &&
} else if (group.size === "text" &&
style.size === Style.DISPLAY.size) {
// We're in a \tfrac but incoming style is displaystyle, so:
style = Style.TEXT;
} else if (group.value.size === "script") {
} else if (group.size === "script") {
style = Style.SCRIPT;
} else if (group.value.size === "scriptscript") {
} else if (group.size === "scriptscript") {
style = Style.SCRIPTSCRIPT;
}
@@ -32,9 +32,9 @@ const htmlBuilder = (group, options) => {
let newOptions;
newOptions = options.havingStyle(nstyle);
const numerm = html.buildGroup(group.value.numer, newOptions, options);
const numerm = html.buildGroup(group.numer, newOptions, options);
if (group.value.continued) {
if (group.continued) {
// \cfrac inserts a \strut into the numerator.
// Get \strut dimensions from TeXbook page 353.
const hStrut = 8.5 / options.fontMetrics().ptPerEm;
@@ -44,14 +44,14 @@ const htmlBuilder = (group, options) => {
}
newOptions = options.havingStyle(dstyle);
const denomm = html.buildGroup(group.value.denom, newOptions, options);
const denomm = html.buildGroup(group.denom, newOptions, options);
let rule;
let ruleWidth;
let ruleSpacing;
if (group.value.hasBarLine) {
if (group.value.barSize) {
ruleWidth = calculateSize(group.value.barSize, options);
if (group.hasBarLine) {
if (group.barSize) {
ruleWidth = calculateSize(group.barSize, options);
rule = buildCommon.makeLineSpan("frac-line", options, ruleWidth);
} else {
rule = buildCommon.makeLineSpan("frac-line", options);
@@ -150,21 +150,21 @@ const htmlBuilder = (group, options) => {
let leftDelim;
let rightDelim;
if (group.value.leftDelim == null) {
if (group.leftDelim == null) {
leftDelim = html.makeNullDelimiter(options, ["mopen"]);
} else {
leftDelim = delimiter.customSizedDelim(
group.value.leftDelim, delimSize, true,
group.leftDelim, delimSize, true,
options.havingStyle(style), group.mode, ["mopen"]);
}
if (group.value.continued) {
if (group.continued) {
rightDelim = buildCommon.makeSpan([]); // zero width for \cfrac
} else if (group.value.rightDelim == null) {
} else if (group.rightDelim == null) {
rightDelim = html.makeNullDelimiter(options, ["mclose"]);
} else {
rightDelim = delimiter.customSizedDelim(
group.value.rightDelim, delimSize, true,
group.rightDelim, delimSize, true,
options.havingStyle(style), group.mode, ["mclose"]);
}
@@ -178,23 +178,23 @@ const mathmlBuilder = (group, options) => {
const node = new mathMLTree.MathNode(
"mfrac",
[
mml.buildGroup(group.value.numer, options),
mml.buildGroup(group.value.denom, options),
mml.buildGroup(group.numer, options),
mml.buildGroup(group.denom, options),
]);
if (!group.value.hasBarLine) {
if (!group.hasBarLine) {
node.setAttribute("linethickness", "0px");
} else if (group.value.barSize) {
const ruleWidth = calculateSize(group.value.barSize, options);
} else if (group.barSize) {
const ruleWidth = calculateSize(group.barSize, options);
node.setAttribute("linethickness", ruleWidth + "em");
}
if (group.value.leftDelim != null || group.value.rightDelim != null) {
if (group.leftDelim != null || group.rightDelim != null) {
const withDelims = [];
if (group.value.leftDelim != null) {
if (group.leftDelim != null) {
const leftOp = new mathMLTree.MathNode(
"mo", [new mathMLTree.TextNode(group.value.leftDelim)]);
"mo", [new mathMLTree.TextNode(group.leftDelim)]);
leftOp.setAttribute("fence", "true");
@@ -203,9 +203,9 @@ const mathmlBuilder = (group, options) => {
withDelims.push(node);
if (group.value.rightDelim != null) {
if (group.rightDelim != null) {
const rightOp = new mathMLTree.MathNode(
"mo", [new mathMLTree.TextNode(group.value.rightDelim)]);
"mo", [new mathMLTree.TextNode(group.rightDelim)]);
rightOp.setAttribute("fence", "true");
@@ -284,17 +284,14 @@ defineFunction({
return {
type: "genfrac",
mode: parser.mode,
value: {
type: "genfrac",
continued: funcName === "\\cfrac",
numer: numer,
denom: denom,
hasBarLine: hasBarLine,
leftDelim: leftDelim,
rightDelim: rightDelim,
size: size,
barSize: null,
},
continued: funcName === "\\cfrac",
numer,
denom,
hasBarLine,
leftDelim,
rightDelim,
size,
barSize: null,
};
},
@@ -335,11 +332,8 @@ defineFunction({
return {
type: "infix",
mode: parser.mode,
value: {
type: "infix",
replaceWith: replaceWith,
token: token,
},
replaceWith,
token,
};
},
});
@@ -413,17 +407,14 @@ defineFunction({
return {
type: "genfrac",
mode: parser.mode,
value: {
type: "genfrac",
numer: numer,
denom: denom,
continued: false,
hasBarLine: hasBarLine,
barSize: barSize,
leftDelim: leftDelim,
rightDelim: rightDelim,
size: size,
},
numer,
denom,
continued: false,
hasBarLine,
barSize,
leftDelim,
rightDelim,
size,
};
},
@@ -445,12 +436,9 @@ defineFunction({
return {
type: "infix",
mode: parser.mode,
value: {
type: "infix",
replaceWith: "\\\\abovefrac",
sizeNode: sizeNode,
token: token,
},
replaceWith: "\\\\abovefrac",
sizeNode,
token,
};
},
});
@@ -465,7 +453,7 @@ defineFunction({
handler: ({parser, funcName}, args) => {
const numer = args[0];
const infixNode = assertNodeType(args[1], "infix");
const sizeNode = assertNodeType(infixNode.value.sizeNode, "size");
const sizeNode = assertNodeType(infixNode.sizeNode, "size");
const denom = args[2];
const barSize = sizeNode.value.value;
@@ -473,17 +461,14 @@ defineFunction({
return {
type: "genfrac",
mode: parser.mode,
value: {
type: "genfrac",
numer: numer,
denom: denom,
continued: false,
hasBarLine: hasBarLine,
barSize: barSize,
leftDelim: null,
rightDelim: null,
size: "auto",
},
numer,
denom,
continued: false,
hasBarLine,
barSize,
leftDelim: null,
rightDelim: null,
size: "auto",
};
},

View File

@@ -16,22 +16,19 @@ defineFunction({
return {
type: "htmlmathml",
mode: parser.mode,
value: {
type: "htmlmathml",
html: ordargument(args[0]),
mathml: ordargument(args[1]),
},
html: ordargument(args[0]),
mathml: ordargument(args[1]),
};
},
htmlBuilder: (group, options) => {
const elements = html.buildExpression(
group.value.html,
group.html,
options,
false
);
return new buildCommon.makeFragment(elements);
},
mathmlBuilder: (group, options) => {
return mml.buildExpressionRow(group.value.mathml, options);
return mml.buildExpressionRow(group.mathml, options);
},
});

View File

@@ -42,17 +42,14 @@ defineFunction({
return {
type: "kern",
mode: parser.mode,
value: {
type: "kern",
dimension: size.value.value,
},
dimension: size.value.value,
};
},
htmlBuilder: (group, options) => {
return buildCommon.makeGlue(group.value.dimension, options);
return buildCommon.makeGlue(group.dimension, options);
},
mathmlBuilder: (group, options) => {
const dimension = calculateSize(group.value.dimension, options);
const dimension = calculateSize(group.dimension, options);
return new mathMLTree.SpaceNode(dimension);
},
});

View File

@@ -19,29 +19,26 @@ defineFunction({
return {
type: "lap",
mode: parser.mode,
value: {
type: "lap",
alignment: funcName.slice(5),
body: body,
},
alignment: funcName.slice(5),
body,
};
},
htmlBuilder: (group, options) => {
// mathllap, mathrlap, mathclap
let inner;
if (group.value.alignment === "clap") {
if (group.alignment === "clap") {
// ref: https://www.math.lsu.edu/~aperlis/publications/mathclap/
inner = buildCommon.makeSpan(
[], [html.buildGroup(group.value.body, options)]);
[], [html.buildGroup(group.body, options)]);
// wrap, since CSS will center a .clap > .inner > span
inner = buildCommon.makeSpan(["inner"], [inner], options);
} else {
inner = buildCommon.makeSpan(
["inner"], [html.buildGroup(group.value.body, options)]);
["inner"], [html.buildGroup(group.body, options)]);
}
const fix = buildCommon.makeSpan(["fix"], []);
let node = buildCommon.makeSpan(
[group.value.alignment], [inner, fix], options);
[group.alignment], [inner, fix], options);
// At this point, we have correctly set horizontal alignment of the
// two items involved in the lap.
@@ -64,10 +61,10 @@ defineFunction({
mathmlBuilder: (group, options) => {
// mathllap, mathrlap, mathclap
const node = new mathMLTree.MathNode(
"mpadded", [mml.buildGroup(group.value.body, options)]);
"mpadded", [mml.buildGroup(group.body, options)]);
if (group.value.alignment !== "rlap") {
const offset = (group.value.alignment === "llap" ? "-1" : "-0.5");
if (group.alignment !== "rlap") {
const offset = (group.alignment === "llap" ? "-1" : "-0.5");
node.setAttribute("lspace", offset + "width");
}
node.setAttribute("width", "0px");

View File

@@ -20,16 +20,13 @@ defineFunction({
return {
type: "operatorname",
mode: parser.mode,
value: {
type: "operatorname",
value: ordargument(body),
},
body: ordargument(body),
};
},
htmlBuilder: (group, options) => {
if (group.value.value.length > 0) {
const groupValue = group.value.value.map(child => {
if (group.body.length > 0) {
const body = group.body.map(child => {
// $FlowFixMe: Check if the node has a string `value` property.
const childValue = child.value;
if (typeof childValue === "string") {
@@ -45,7 +42,7 @@ defineFunction({
// Consolidate function names into symbol characters.
const expression = html.buildExpression(
groupValue, options.withFont("mathrm"), true);
body, options.withFont("mathrm"), true);
for (let i = 0; i < expression.length; i++) {
const child = expression[i];
@@ -65,7 +62,7 @@ defineFunction({
mathmlBuilder: (group, options) => {
// The steps taken here are similar to the html version.
let expression = mml.buildExpression(
group.value.value, options.withFont("mathrm"));
group.body, options.withFont("mathrm"));
// Is expression a string or has it something like a fraction?
let isAllString = true; // default

View File

@@ -17,17 +17,14 @@ defineFunction({
return {
type: "overline",
mode: parser.mode,
value: {
type: "overline",
body: body,
},
body,
};
},
htmlBuilder(group, options) {
// Overlines are handled in the TeXbook pg 443, Rule 9.
// Build the inner group in the cramped style.
const innerGroup = html.buildGroup(group.value.body,
const innerGroup = html.buildGroup(group.body,
options.havingCrampedStyle());
// Create the line above the body
@@ -53,7 +50,7 @@ defineFunction({
const node = new mathMLTree.MathNode(
"mover",
[mml.buildGroup(group.value.body, options), operator]);
[mml.buildGroup(group.body, options), operator]);
node.setAttribute("accent", "true");
return node;

View File

@@ -23,12 +23,8 @@ defineFunction({
return {
type: "raisebox",
mode: parser.mode,
value: {
type: "raisebox",
dy: amount,
body: body,
value: ordargument(body),
},
dy: amount,
body,
};
},
htmlBuilder(group, options) {
@@ -37,21 +33,18 @@ defineFunction({
mode: group.mode,
value: {
type: "text",
body: group.value.value,
body: ordargument(group.body),
font: "mathrm", // simulate \textrm
},
};
const sizedText = {
type: "sizing",
mode: group.mode,
value: {
type: "sizing",
value: [text],
size: 6, // simulate \normalsize
},
body: [text],
size: 6, // simulate \normalsize
};
const body = sizing.htmlBuilder(sizedText, options);
const dy = calculateSize(group.value.dy.value.value, options);
const dy = calculateSize(group.dy.value.value, options);
return buildCommon.makeVList({
positionType: "shift",
positionData: -dy,
@@ -60,9 +53,8 @@ defineFunction({
},
mathmlBuilder(group, options) {
const node = new mathMLTree.MathNode(
"mpadded", [mml.buildGroup(group.value.body, options)]);
const dy =
group.value.dy.value.value.number + group.value.dy.value.value.unit;
"mpadded", [mml.buildGroup(group.body, options)]);
const dy = group.dy.value.value.number + group.dy.value.value.unit;
node.setAttribute("voffset", dy);
return node;
},

View File

@@ -20,12 +20,9 @@ defineFunction({
return {
type: "rule",
mode: parser.mode,
value: {
type: "rule",
shift: shift && assertNodeType(shift, "size").value.value,
width: width.value.value,
height: height.value.value,
},
shift: shift && assertNodeType(shift, "size").value.value,
width: width.value.value,
height: height.value.value,
};
},
htmlBuilder(group, options) {
@@ -34,12 +31,12 @@ defineFunction({
// Calculate the shift, width, and height of the rule, and account for units
let shift = 0;
if (group.value.shift) {
shift = calculateSize(group.value.shift, options);
if (group.shift) {
shift = calculateSize(group.shift, options);
}
const width = calculateSize(group.value.width, options);
const height = calculateSize(group.value.height, options);
const width = calculateSize(group.width, options);
const height = calculateSize(group.height, options);
// Style the rule to the right size
rule.style.borderRightWidth = width + "em";

View File

@@ -8,9 +8,15 @@ import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import type Options from "../Options";
import type {AnyParseNode} from "../parseNode";
import type {HtmlBuilder} from "../defineFunction";
import type {documentFragment as HtmlDocumentFragment} from "../domTree";
export function sizingGroup(value: *, options: Options, baseOptions: Options) {
export function sizingGroup(
value: AnyParseNode[],
options: Options,
baseOptions: Options,
): HtmlDocumentFragment {
const inner = html.buildExpression(value, options, false);
const multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier;
@@ -44,8 +50,8 @@ export const htmlBuilder: HtmlBuilder<"sizing"> = (group, options) => {
// Handle sizing operators like \Huge. Real TeX doesn't actually allow
// these functions inside of math expressions, so we do some special
// handling.
const newOptions = options.havingSize(group.value.size);
return sizingGroup(group.value.value, newOptions, options);
const newOptions = options.havingSize(group.size);
return sizingGroup(group.body, newOptions, options);
};
defineFunction({
@@ -62,18 +68,15 @@ defineFunction({
return {
type: "sizing",
mode: parser.mode,
value: {
type: "sizing",
// Figure out what size to use based on the list of functions above
size: utils.indexOf(sizeFuncs, funcName) + 1,
value: body,
},
// Figure out what size to use based on the list of functions above
size: utils.indexOf(sizeFuncs, funcName) + 1,
body,
};
},
htmlBuilder,
mathmlBuilder: (group, options) => {
const newOptions = options.havingSize(group.value.size);
const inner = mml.buildExpression(group.value.value, newOptions);
const newOptions = options.havingSize(group.size);
const inner = mml.buildExpression(group.body, newOptions);
const node = new mathMLTree.MathNode("mstyle", inner);

View File

@@ -48,23 +48,20 @@ defineFunction({
return {
type: "smash",
mode: parser.mode,
value: {
type: "smash",
body: body,
smashHeight: smashHeight,
smashDepth: smashDepth,
},
body,
smashHeight,
smashDepth,
};
},
htmlBuilder: (group, options) => {
const node = buildCommon.makeSpan(
["mord"], [html.buildGroup(group.value.body, options)]);
["mord"], [html.buildGroup(group.body, options)]);
if (!group.value.smashHeight && !group.value.smashDepth) {
if (!group.smashHeight && !group.smashDepth) {
return node;
}
if (group.value.smashHeight) {
if (group.smashHeight) {
node.height = 0;
// In order to influence makeVList, we have to reset the children.
if (node.children) {
@@ -74,7 +71,7 @@ defineFunction({
}
}
if (group.value.smashDepth) {
if (group.smashDepth) {
node.depth = 0;
if (node.children) {
for (let i = 0; i < node.children.length; i++) {
@@ -95,13 +92,13 @@ defineFunction({
},
mathmlBuilder: (group, options) => {
const node = new mathMLTree.MathNode(
"mpadded", [mml.buildGroup(group.value.body, options)]);
"mpadded", [mml.buildGroup(group.body, options)]);
if (group.value.smashHeight) {
if (group.smashHeight) {
node.setAttribute("height", "0px");
}
if (group.value.smashDepth) {
if (group.smashDepth) {
node.setAttribute("depth", "0px");
}

View File

@@ -22,11 +22,8 @@ defineFunction({
return {
type: "sqrt",
mode: parser.mode,
value: {
type: "sqrt",
body: body,
index: index,
},
body,
index,
};
},
htmlBuilder(group, options) {
@@ -34,7 +31,7 @@ defineFunction({
// First, we do the same steps as in overline to build the inner group
// and line
let inner = html.buildGroup(group.value.body, options.havingCrampedStyle());
let inner = html.buildGroup(group.body, options.havingCrampedStyle());
if (inner.height === 0) {
// Render a small surd.
inner.height = options.fontMetrics().xHeight;
@@ -89,14 +86,14 @@ defineFunction({
],
}, options);
if (!group.value.index) {
if (!group.index) {
return buildCommon.makeSpan(["mord", "sqrt"], [body], options);
} else {
// Handle the optional root index
// The index is always in scriptscript style
const newOptions = options.havingStyle(Style.SCRIPTSCRIPT);
const rootm = html.buildGroup(group.value.index, newOptions, options);
const rootm = html.buildGroup(group.index, newOptions, options);
// The amount the index is shifted by. This is taken from the TeX
// source, in the definition of `\r@@t`.
@@ -117,7 +114,7 @@ defineFunction({
}
},
mathmlBuilder(group, options) {
const {body, index} = group.value;
const {body, index} = group;
return index ?
new mathMLTree.MathNode(
"mroot", [

View File

@@ -14,20 +14,16 @@ defineFunction({
allowedInText: true,
},
handler({parser}, args) {
const body = args[0];
return {
type: "underline",
mode: parser.mode,
value: {
type: "underline",
body: body,
},
body: args[0],
};
},
htmlBuilder(group, options) {
// Underlines are handled in the TeXbook pg 443, Rule 10.
// Build the inner group.
const innerGroup = html.buildGroup(group.value.body, options);
const innerGroup = html.buildGroup(group.body, options);
// Create the line to go below the body
const line = buildCommon.makeLineSpan("underline-line", options);
@@ -53,7 +49,7 @@ defineFunction({
const node = new mathMLTree.MathNode(
"munder",
[mml.buildGroup(group.value.body, options), operator]);
[mml.buildGroup(group.body, options), operator]);
node.setAttribute("accentunder", "true");
return node;

View File

@@ -34,11 +34,8 @@ type ParseNodeTypes = {
type: "color",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "color",
color: string,
value: AnyParseNode[],
|},
color: string,
body: AnyParseNode[],
|},
"color-token": {|
type: "color-token",
@@ -216,23 +213,17 @@ type ParseNodeTypes = {
type: "enclose",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "enclose",
label: string,
backgroundColor?: ParseNode<"color-token">,
borderColor?: ParseNode<"color-token">,
body: AnyParseNode,
|},
label: string,
backgroundColor?: ParseNode<"color-token">,
borderColor?: ParseNode<"color-token">,
body: AnyParseNode,
|},
"environment": {|
type: "environment",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "environment",
name: string,
nameGroup: AnyParseNode,
|},
name: string,
nameGroup: AnyParseNode,
|},
"font": {|
type: "font",
@@ -245,17 +236,14 @@ type ParseNodeTypes = {
type: "genfrac",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "genfrac",
continued: boolean,
numer: AnyParseNode,
denom: AnyParseNode,
hasBarLine: boolean,
leftDelim: ?string,
rightDelim: ?string,
size: StyleStr | "auto",
barSize: Measurement | null,
|},
continued: boolean,
numer: AnyParseNode,
denom: AnyParseNode,
hasBarLine: boolean,
leftDelim: ?string,
rightDelim: ?string,
size: StyleStr | "auto",
barSize: Measurement | null,
|},
"horizBrace": {|
type: "horizBrace",
@@ -276,41 +264,29 @@ type ParseNodeTypes = {
type: "htmlmathml",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "htmlmathml",
html: AnyParseNode[],
mathml: AnyParseNode[],
|},
html: AnyParseNode[],
mathml: AnyParseNode[],
|},
"infix": {|
type: "infix",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "infix",
replaceWith: string,
sizeNode?: ParseNode<"size">,
token: ?Token,
|},
replaceWith: string,
sizeNode?: ParseNode<"size">,
token: ?Token,
|},
"kern": {|
type: "kern",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "kern",
dimension: Measurement,
|},
dimension: Measurement,
|},
"lap": {|
type: "lap",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "lap",
alignment: string,
body: AnyParseNode,
|},
alignment: string,
body: AnyParseNode,
|},
"leftright": {|
type: "leftright",
@@ -352,19 +328,13 @@ type ParseNodeTypes = {
type: "operatorname",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "operatorname",
value: AnyParseNode[],
|},
body: AnyParseNode[],
|},
"overline": {|
type: "overline",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "overline",
body: AnyParseNode,
|},
body: AnyParseNode,
|},
"phantom": {|
type: "phantom",
@@ -388,63 +358,44 @@ type ParseNodeTypes = {
type: "raisebox",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "raisebox",
dy: ParseNode<"size">,
body: AnyParseNode,
value: AnyParseNode[],
|},
dy: ParseNode<"size">,
body: AnyParseNode,
|},
"rule": {|
type: "rule",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "rule",
shift: ?Measurement,
width: Measurement,
height: Measurement,
|},
shift: ?Measurement,
width: Measurement,
height: Measurement,
|},
"sizing": {|
type: "sizing",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "sizing",
size: number,
value: AnyParseNode[],
|},
size: number,
body: AnyParseNode[],
|},
"smash": {|
type: "smash",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "smash",
body: AnyParseNode,
smashHeight: boolean,
smashDepth: boolean,
|},
body: AnyParseNode,
smashHeight: boolean,
smashDepth: boolean,
|},
"sqrt": {|
type: "sqrt",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "sqrt",
body: AnyParseNode,
index: ?AnyParseNode,
|},
body: AnyParseNode,
index: ?AnyParseNode,
|},
"underline": {|
type: "underline",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "underline",
body: AnyParseNode,
|},
body: AnyParseNode,
|},
"xArrow": {|
type: "xArrow",

View File

@@ -104,8 +104,8 @@ const getBaseElem = function(group: AnyParseNode): AnyParseNode {
return group;
}
} else if (group.type === "color") {
if (group.value.value.length === 1) {
return getBaseElem(group.value.value[0]);
if (group.body.length === 1) {
return getBaseElem(group.body[0]);
} else {
return group;
}

View File

@@ -643,42 +643,39 @@ exports[`An implicit group parser within optional groups should work style comma
[
{
"type": "sqrt",
"mode": "math",
"value": {
"type": "sqrt",
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "mathord",
"mode": "math",
"value": "x"
}
]
},
"index": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "mathord",
"mode": "math",
"value": "x"
}
]
},
"index": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "styling",
"mode": "math",
"value": {
"type": "styling",
"mode": "math",
"value": {
"type": "styling",
"style": "text",
"value": [
{
"type": "textord",
"mode": "math",
"value": "3"
}
]
}
"style": "text",
"value": [
{
"type": "textord",
"mode": "math",
"value": "3"
}
]
}
]
}
}
}
]
},
"mode": "math"
}
]
`;
@@ -687,42 +684,36 @@ exports[`An implicit group parser within optional groups should work with \\colo
[
{
"type": "sqrt",
"mode": "math",
"value": {
"type": "sqrt",
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "mathord",
"mode": "math",
"value": "x"
}
]
},
"index": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "color",
"mode": "math",
"value": {
"type": "color",
"color": "red",
"value": [
{
"type": "textord",
"mode": "math",
"value": "3"
}
]
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "mathord",
"mode": "math",
"value": "x"
}
]
},
"index": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "color",
"body": [
{
"type": "textord",
"mode": "math",
"value": "3"
}
}
]
}
}
],
"color": "red",
"mode": "math"
}
]
},
"mode": "math"
}
]
`;
@@ -731,43 +722,40 @@ exports[`An implicit group parser within optional groups should work with old fo
[
{
"type": "sqrt",
"mode": "math",
"value": {
"type": "sqrt",
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "mathord",
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "mathord",
"mode": "math",
"value": "x"
}
]
},
"index": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "font",
"body": {
"type": "ordgroup",
"mode": "math",
"value": "x"
}
]
},
"index": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "font",
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "textord",
"mode": "math",
"value": "3"
}
]
},
"font": "mathtt",
"mode": "math"
}
]
}
}
"value": [
{
"type": "textord",
"mode": "math",
"value": "3"
}
]
},
"font": "mathtt",
"mode": "math"
}
]
},
"mode": "math"
}
]
`;
@@ -776,42 +764,36 @@ exports[`An implicit group parser within optional groups should work with sizing
[
{
"type": "sqrt",
"mode": "math",
"value": {
"type": "sqrt",
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "mathord",
"mode": "math",
"value": "x"
}
]
},
"index": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "sizing",
"mode": "math",
"value": {
"type": "sizing",
"size": 5,
"value": [
{
"type": "textord",
"mode": "math",
"value": "3"
}
]
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "mathord",
"mode": "math",
"value": "x"
}
]
},
"index": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "sizing",
"body": [
{
"type": "textord",
"mode": "math",
"value": "3"
}
}
]
}
}
],
"mode": "math",
"size": 5
}
]
},
"mode": "math"
}
]
`;

View File

@@ -92,7 +92,7 @@ describe("A rel parser", function() {
for (let i = 0; i < parse.length; i++) {
let group = parse[i];
if (group.type === "htmlmathml") {
group = group.value.html[0];
group = group.html[0];
}
if (group.type === "mclass") {
expect(group.mclass).toEqual("mrel");
@@ -342,7 +342,8 @@ describe("An implicit group parser", function() {
const sizing = parse[0];
expect(sizing.type).toEqual("sizing");
expect(sizing.value).toBeTruthy();
expect(sizing.body).toBeTruthy();
expect(sizing.size).toBeDefined();
});
it("should apply only after the function", function() {
@@ -353,7 +354,7 @@ describe("An implicit group parser", function() {
const sizing = parse[1];
expect(sizing.type).toEqual("sizing");
expect(sizing.value.value).toHaveLength(3);
expect(sizing.body).toHaveLength(3);
});
it("should stop at the ends of groups", function() {
@@ -363,7 +364,7 @@ describe("An implicit group parser", function() {
const sizing = group.value[1];
expect(sizing.type).toEqual("sizing");
expect(sizing.value.value).toHaveLength(1);
expect(sizing.body).toHaveLength(1);
});
describe("within optional groups", () => {
@@ -441,8 +442,8 @@ describe("A frac parser", function() {
const parse = getParsed(expression)[0];
expect(parse.type).toEqual("genfrac");
expect(parse.value.numer).toBeDefined();
expect(parse.value.denom).toBeDefined();
expect(parse.numer).toBeDefined();
expect(parse.denom).toBeDefined();
});
it("should also parse cfrac, dfrac, tfrac, and genfrac", function() {
@@ -457,28 +458,28 @@ describe("A frac parser", function() {
const dfracParse = getParsed(dfracExpression)[0];
expect(dfracParse.type).toEqual("genfrac");
expect(dfracParse.value.numer).toBeDefined();
expect(dfracParse.value.denom).toBeDefined();
expect(dfracParse.numer).toBeDefined();
expect(dfracParse.denom).toBeDefined();
const tfracParse = getParsed(tfracExpression)[0];
expect(tfracParse.type).toEqual("genfrac");
expect(tfracParse.value.numer).toBeDefined();
expect(tfracParse.value.denom).toBeDefined();
expect(tfracParse.numer).toBeDefined();
expect(tfracParse.denom).toBeDefined();
const cfracParse = getParsed(cfracExpression)[0];
expect(cfracParse.type).toEqual("genfrac");
expect(cfracParse.value.numer).toBeDefined();
expect(cfracParse.value.denom).toBeDefined();
expect(cfracParse.numer).toBeDefined();
expect(cfracParse.denom).toBeDefined();
const genfracParse = getParsed(genfrac1)[0];
expect(genfracParse.type).toEqual("genfrac");
expect(genfracParse.value.numer).toBeDefined();
expect(genfracParse.value.denom).toBeDefined();
expect(genfracParse.value.leftDelim).toBeDefined();
expect(genfracParse.value.rightDelim).toBeDefined();
expect(genfracParse.numer).toBeDefined();
expect(genfracParse.denom).toBeDefined();
expect(genfracParse.leftDelim).toBeDefined();
expect(genfracParse.rightDelim).toBeDefined();
});
it("should fail, given math as a line thickness to genfrac", function() {
@@ -495,9 +496,9 @@ describe("A frac parser", function() {
const parse = getParsed`x \atop y`[0];
expect(parse.type).toEqual("genfrac");
expect(parse.value.numer).toBeDefined();
expect(parse.value.denom).toBeDefined();
expect(parse.value.hasBarLine).toEqual(false);
expect(parse.numer).toBeDefined();
expect(parse.denom).toBeDefined();
expect(parse.hasBarLine).toEqual(false);
});
});
@@ -520,43 +521,43 @@ describe("An over/brace/brack parser", function() {
parse = getParsed(simpleOver)[0];
expect(parse.type).toEqual("genfrac");
expect(parse.value.numer).toBeDefined();
expect(parse.value.denom).toBeDefined();
expect(parse.numer).toBeDefined();
expect(parse.denom).toBeDefined();
parse = getParsed(complexOver)[0];
expect(parse.type).toEqual("genfrac");
expect(parse.value.numer).toBeDefined();
expect(parse.value.denom).toBeDefined();
expect(parse.numer).toBeDefined();
expect(parse.denom).toBeDefined();
const parseBraceFrac = getParsed(braceFrac)[0];
expect(parseBraceFrac.type).toEqual("genfrac");
expect(parseBraceFrac.value.numer).toBeDefined();
expect(parseBraceFrac.value.denom).toBeDefined();
expect(parseBraceFrac.value.leftDelim).toBeDefined();
expect(parseBraceFrac.value.rightDelim).toBeDefined();
expect(parseBraceFrac.numer).toBeDefined();
expect(parseBraceFrac.denom).toBeDefined();
expect(parseBraceFrac.leftDelim).toBeDefined();
expect(parseBraceFrac.rightDelim).toBeDefined();
const parseBrackFrac = getParsed(brackFrac)[0];
expect(parseBrackFrac.type).toEqual("genfrac");
expect(parseBrackFrac.value.numer).toBeDefined();
expect(parseBrackFrac.value.denom).toBeDefined();
expect(parseBrackFrac.value.leftDelim).toBeDefined();
expect(parseBrackFrac.value.rightDelim).toBeDefined();
expect(parseBrackFrac.numer).toBeDefined();
expect(parseBrackFrac.denom).toBeDefined();
expect(parseBrackFrac.leftDelim).toBeDefined();
expect(parseBrackFrac.rightDelim).toBeDefined();
});
it("should create a numerator from the atoms before \\over", function() {
const parse = getParsed(complexOver)[0];
const numer = parse.value.numer;
const numer = parse.numer;
expect(numer.value).toHaveLength(4);
});
it("should create a demonimator from the atoms after \\over", function() {
const parse = getParsed(complexOver)[0];
const denom = parse.value.numer;
const denom = parse.numer;
expect(denom.value).toHaveLength(4);
});
@@ -564,24 +565,24 @@ describe("An over/brace/brack parser", function() {
const emptyNumerator = r`\over x`;
const parse = getParsed(emptyNumerator)[0];
expect(parse.type).toEqual("genfrac");
expect(parse.value.numer).toBeDefined();
expect(parse.value.denom).toBeDefined();
expect(parse.numer).toBeDefined();
expect(parse.denom).toBeDefined();
});
it("should handle empty denominators", function() {
const emptyDenominator = r`1 \over`;
const parse = getParsed(emptyDenominator)[0];
expect(parse.type).toEqual("genfrac");
expect(parse.value.numer).toBeDefined();
expect(parse.value.denom).toBeDefined();
expect(parse.numer).toBeDefined();
expect(parse.denom).toBeDefined();
});
it("should handle \\displaystyle correctly", function() {
const displaystyleExpression = r`\displaystyle 1 \over 2`;
const parse = getParsed(displaystyleExpression)[0];
expect(parse.type).toEqual("genfrac");
expect(parse.value.numer.value[0].type).toEqual("styling");
expect(parse.value.denom).toBeDefined();
expect(parse.numer.value[0].type).toEqual("styling");
expect(parse.denom).toBeDefined();
});
it("should handle \\textstyle correctly", function() {
@@ -593,11 +594,11 @@ describe("An over/brace/brack parser", function() {
const nestedOverExpression = r`{1 \over 2} \over 3`;
const parse = getParsed(nestedOverExpression)[0];
expect(parse.type).toEqual("genfrac");
expect(parse.value.numer.value[0].type).toEqual("genfrac");
expect(parse.value.numer.value[0].value.numer.value[0].value).toEqual("1");
expect(parse.value.numer.value[0].value.denom.value[0].value).toEqual("2");
expect(parse.value.denom).toBeDefined();
expect(parse.value.denom.value[0].value).toEqual("3");
expect(parse.numer.value[0].type).toEqual("genfrac");
expect(parse.numer.value[0].numer.value[0].value).toEqual("1");
expect(parse.numer.value[0].denom.value[0].value).toEqual("2");
expect(parse.denom).toBeDefined();
expect(parse.denom.value[0].value).toEqual("3");
});
it("should fail with multiple overs in the same group", function() {
@@ -641,7 +642,8 @@ describe("A sizing parser", function() {
const parse = getParsed(sizeExpression)[0];
expect(parse.type).toEqual("sizing");
expect(parse.value).toBeDefined();
expect(parse.size).toBeDefined();
expect(parse.body).toBeDefined();
});
});
@@ -778,8 +780,8 @@ describe("A color parser", function() {
const parse = getParsed(colorExpression)[0];
expect(parse.type).toEqual("color");
expect(parse.value.color).toBeDefined();
expect(parse.value.value).toBeDefined();
expect(parse.color).toBeDefined();
expect(parse.body).toBeDefined();
});
it("should parse a custom color", function() {
@@ -791,8 +793,8 @@ describe("A color parser", function() {
const parse1 = getParsed(customColorExpression1)[0];
const parse2 = getParsed(customColorExpression2)[0];
expect(parse1.value.color).toEqual("#fA6");
expect(parse2.value.color).toEqual("#fA6fA6");
expect(parse1.color).toEqual("#fA6");
expect(parse2.color).toEqual("#fA6fA6");
});
it("should not parse a bad custom color", function() {
@@ -984,25 +986,25 @@ describe("A rule parser", function() {
const emParse = getParsed(emRule)[0];
const exParse = getParsed(exRule)[0];
expect(emParse.value.width.unit).toEqual("em");
expect(emParse.value.height.unit).toEqual("em");
expect(emParse.width.unit).toEqual("em");
expect(emParse.height.unit).toEqual("em");
expect(exParse.value.width.unit).toEqual("ex");
expect(exParse.value.height.unit).toEqual("em");
expect(exParse.width.unit).toEqual("ex");
expect(exParse.height.unit).toEqual("em");
});
it("should parse the number correctly", function() {
const hardNumberParse = getParsed(hardNumberRule)[0];
expect(hardNumberParse.value.width.number).toBeCloseTo(1.24);
expect(hardNumberParse.value.height.number).toBeCloseTo(2.45);
expect(hardNumberParse.width.number).toBeCloseTo(1.24);
expect(hardNumberParse.height.number).toBeCloseTo(2.45);
});
it("should parse negative sizes", function() {
const parse = getParsed`\rule{-1em}{- 0.2em}`[0];
expect(parse.value.width.number).toBeCloseTo(-1);
expect(parse.value.height.number).toBeCloseTo(-0.2);
expect(parse.width.number).toBeCloseTo(-1);
expect(parse.height.number).toBeCloseTo(-0.2);
});
});
@@ -1020,10 +1022,10 @@ describe("A kern parser", function() {
const muParse = getParsed(muKern)[0];
const abParse = getParsed(abKern)[1];
expect(emParse.value.dimension.unit).toEqual("em");
expect(exParse.value.dimension.unit).toEqual("ex");
expect(muParse.value.dimension.unit).toEqual("mu");
expect(abParse.value.dimension.unit).toEqual("em");
expect(emParse.dimension.unit).toEqual("em");
expect(exParse.dimension.unit).toEqual("ex");
expect(muParse.dimension.unit).toEqual("mu");
expect(abParse.dimension.unit).toEqual("em");
});
it("should not parse invalid units", function() {
@@ -1033,12 +1035,12 @@ describe("A kern parser", function() {
it("should parse negative sizes", function() {
const parse = getParsed`\kern{-1em}`[0];
expect(parse.value.dimension.number).toBeCloseTo(-1);
expect(parse.dimension.number).toBeCloseTo(-1);
});
it("should parse positive sizes", function() {
const parse = getParsed`\kern{+1em}`[0];
expect(parse.value.dimension.number).toBeCloseTo(1);
expect(parse.dimension.number).toBeCloseTo(1);
});
});
@@ -1060,12 +1062,12 @@ describe("A non-braced kern parser", function() {
const abParse2 = getParsed(abKern2)[1];
const abParse3 = getParsed(abKern3)[1];
expect(emParse.value.dimension.unit).toEqual("em");
expect(exParse.value.dimension.unit).toEqual("ex");
expect(muParse.value.dimension.unit).toEqual("mu");
expect(abParse1.value.dimension.unit).toEqual("mu");
expect(abParse2.value.dimension.unit).toEqual("mu");
expect(abParse3.value.dimension.unit).toEqual("mu");
expect(emParse.dimension.unit).toEqual("em");
expect(exParse.dimension.unit).toEqual("ex");
expect(muParse.dimension.unit).toEqual("mu");
expect(abParse1.dimension.unit).toEqual("mu");
expect(abParse2.dimension.unit).toEqual("mu");
expect(abParse3.dimension.unit).toEqual("mu");
});
it("should parse elements on either side of a kern", function() {
@@ -1091,12 +1093,12 @@ describe("A non-braced kern parser", function() {
it("should parse negative sizes", function() {
const parse = getParsed`\kern-1em`[0];
expect(parse.value.dimension.number).toBeCloseTo(-1);
expect(parse.dimension.number).toBeCloseTo(-1);
});
it("should parse positive sizes", function() {
const parse = getParsed`\kern+1em`[0];
expect(parse.value.dimension.number).toBeCloseTo(1);
expect(parse.dimension.number).toBeCloseTo(1);
});
it("should handle whitespace", function() {
@@ -1105,7 +1107,7 @@ describe("A non-braced kern parser", function() {
expect(abParse).toHaveLength(3);
expect(abParse[0].value).toEqual("a");
expect(abParse[1].value.dimension.unit).toEqual("mu");
expect(abParse[1].dimension.unit).toEqual("mu");
expect(abParse[2].value).toEqual("b");
});
});
@@ -1511,9 +1513,9 @@ describe("A font parser", function() {
it("should work with \\textcolor", function() {
const colorMathbbParse = getParsed`\textcolor{blue}{\mathbb R}`[0];
expect(colorMathbbParse.value.type).toEqual("color");
expect(colorMathbbParse.value.color).toEqual("blue");
const body = colorMathbbParse.value.value;
expect(colorMathbbParse.type).toEqual("color");
expect(colorMathbbParse.color).toEqual("blue");
const body = colorMathbbParse.body;
expect(body).toHaveLength(1);
expect(body[0].type).toEqual("font");
expect(body[0].font).toEqual("mathbb");
@@ -2589,7 +2591,7 @@ describe("A parser that does not throw on unsupported commands", function() {
it("should produce color nodes with a color value given by errorColor", function() {
const parsedInput = getParsed(r`\error`, noThrowSettings);
expect(parsedInput[0].type).toBe("color");
expect(parsedInput[0].value.color).toBe(errorColor);
expect(parsedInput[0].color).toBe(errorColor);
});
it("should build katex-error span for other type of KaTeX error", function() {