Flatten a bunch of non-pervasive ParseNode types (part 1) (#1551)

* Flatten "url" ParseNode.

* Flatten "href" ParseNode.

* Flatten "verb" ParseNode.

* Flatten "tag" ParseNode.

* Flatten "cr" ParseNode.

* Flatten "delimsizing" ParseNode.

* Flatten "middle" ParseNode.

* Flatten "leftright" ParseNode.

* Flatten "leftright-right" ParseNode.

* Flatten "mathchoice" ParseNode.

* Remove unused ParseNode type "mod".

* Flatten "mclass" ParseNode.

* Flatten "font" ParseNode.

* Flatten "phantom" ParseNode.

* Flatten "hphantom" ParseNode.

* Flatten "vphantom" ParseNode.
This commit is contained in:
Ashish Myles
2018-08-05 22:49:43 -04:00
committed by ylemkimon
parent b2d38104cd
commit 1506dc1d88
17 changed files with 212 additions and 357 deletions

View File

@@ -942,10 +942,7 @@ export default class Parser {
const urlArg = {
type: "url",
mode: this.mode,
value: {
type: "url",
value: url,
},
url,
};
this.consume();
if (funcName === "\\href") { // two arguments
@@ -983,11 +980,8 @@ export default class Parser {
return newArgument({
type: "verb",
mode: "text",
value: {
type: "verb",
body: arg,
star: star,
},
body: arg,
star,
}, nucleus);
}
// At this point, we should have a symbol, possibly with accents.

View File

@@ -613,8 +613,8 @@ const makeVList = function(params: VListParam, options: Options): DomSpan {
// Converts verb group into body string, dealing with \verb* form
const makeVerb = function(group: ParseNode<"verb">, options: Options): string {
let text = group.value.body;
if (group.value.star) {
let text = group.body;
if (group.star) {
text = text.replace(/ /g, '\u2423'); // Open Box
} else {
text = text.replace(/ /g, '\xA0'); // No-Break Space

View File

@@ -309,8 +309,8 @@ export default function buildHTML(tree: AnyParseNode[], options: Options): DomSp
// Strip off outer tag wrapper for processing below.
let tag = null;
if (tree.length === 1 && tree[0].type === "tag") {
tag = tree[0].value.tag;
tree = tree[0].value.body;
tag = tree[0].tag;
tree = tree[0].body;
}
// Build the expression contained in the tree

View File

@@ -139,7 +139,7 @@ function parseArray(
if (!cr) {
throw new ParseError(`Failed to parse function after ${next}`);
}
rowGaps.push(assertNodeType(cr, "cr").value.size);
rowGaps.push(assertNodeType(cr, "cr").size);
// check for \hline(s) following the row separator
hLinesBeforeRow.push(getHLines(parser));
@@ -563,12 +563,9 @@ defineEnvironment({
return delimiters ? {
type: "leftright",
mode: context.mode,
value: {
type: "leftright",
body: [res],
left: delimiters[0],
right: delimiters[1],
},
body: [res],
left: delimiters[0],
right: delimiters[1],
} : res;
},
htmlBuilder,
@@ -614,12 +611,9 @@ defineEnvironment({
return {
type: "leftright",
mode: context.mode,
value: {
type: "leftright",
body: [res],
left: "\\{",
right: ".",
},
body: [res],
left: "\\{",
right: ".",
};
},
htmlBuilder,

View File

@@ -40,12 +40,9 @@ defineFunction({
return {
type: "cr",
mode: parser.mode,
value: {
type: "cr",
newLine,
newRow,
size: size && assertNodeType(size, "size"),
},
newLine,
newRow,
size: size && assertNodeType(size, "size"),
};
},
@@ -53,16 +50,16 @@ defineFunction({
// not within tabular/array environments.
htmlBuilder: (group, options) => {
if (group.value.newRow) {
if (group.newRow) {
throw new ParseError(
"\\cr valid only within a tabular/array environment");
}
const span = buildCommon.makeSpan(["mspace"], [], options);
if (group.value.newLine) {
if (group.newLine) {
span.classes.push("newline");
if (group.value.size) {
if (group.size) {
span.style.marginTop =
calculateSize(group.value.size.value.value, options) + "em";
calculateSize(group.size.value.value, options) + "em";
}
}
return span;
@@ -70,11 +67,11 @@ defineFunction({
mathmlBuilder: (group, options) => {
const node = new mathMLTree.MathNode("mspace");
if (group.value.newLine) {
if (group.newLine) {
node.setAttribute("linebreak", "newline");
if (group.value.size) {
if (group.size) {
node.setAttribute("height",
calculateSize(group.value.size.value.value, options) + "em");
calculateSize(group.size.value.value, options) + "em");
}
}
return node;

View File

@@ -12,7 +12,6 @@ import * as mml from "../buildMathML";
import type Options from "../Options";
import type {AnyParseNode, ParseNode, SymbolParseNode} from "../parseNode";
import type {LeftRightDelimType} from "../parseNode";
import type {FunctionContext} from "../defineFunction";
// Extra data needed for the delimiter handler down below
@@ -52,7 +51,7 @@ const delimiters = [
".",
];
type IsMiddle = {value: string, options: Options};
type IsMiddle = {delim: string, options: Options};
// Delimiter functions
function checkDelimiter(
@@ -87,39 +86,33 @@ defineFunction({
return {
type: "delimsizing",
mode: context.parser.mode,
value: {
type: "delimsizing",
size: delimiterSizes[context.funcName].size,
mclass: delimiterSizes[context.funcName].mclass,
value: delim.value,
},
size: delimiterSizes[context.funcName].size,
mclass: delimiterSizes[context.funcName].mclass,
delim: delim.value,
};
},
htmlBuilder: (group, options) => {
const delim = group.value.value;
if (delim === ".") {
if (group.delim === ".") {
// Empty delimiters still count as elements, even though they don't
// show anything.
return buildCommon.makeSpan([group.value.mclass]);
return buildCommon.makeSpan([group.mclass]);
}
// Use delimiter.sizedDelim to generate the delimiter.
return delimiter.sizedDelim(
delim, group.value.size, options, group.mode,
[group.value.mclass]);
group.delim, group.size, options, group.mode, [group.mclass]);
},
mathmlBuilder: (group) => {
const children = [];
if (group.value.value !== ".") {
children.push(mml.makeText(group.value.value, group.mode));
if (group.delim !== ".") {
children.push(mml.makeText(group.delim, group.mode));
}
const node = new mathMLTree.MathNode("mo", children);
if (group.value.mclass === "mopen" ||
group.value.mclass === "mclose") {
if (group.mclass === "mopen" ||
group.mclass === "mclose") {
// Only some of the delimsizing functions act as fences, and they
// return "mopen" or "mclose" mclass.
node.setAttribute("fence", "true");
@@ -134,11 +127,10 @@ defineFunction({
});
function leftRightGroupValue(group: ParseNode<"leftright">): LeftRightDelimType {
if (!group.value.body) {
function assertParsed(group: ParseNode<"leftright">) {
if (!group.body) {
throw new Error("Bug: The leftright ParseNode wasn't fully parsed.");
}
return group.value;
}
@@ -155,10 +147,7 @@ defineFunction({
return {
type: "leftright-right",
mode: context.parser.mode,
value: {
type: "leftright-right",
value: checkDelimiter(args[0], context).value,
},
delim: checkDelimiter(args[0], context).value,
};
},
});
@@ -188,18 +177,15 @@ defineFunction({
return {
type: "leftright",
mode: parser.mode,
value: {
type: "leftright",
body: body,
left: delim.value,
right: assertNodeType(right, "leftright-right").value.value,
},
body,
left: delim.value,
right: assertNodeType(right, "leftright-right").delim,
};
},
htmlBuilder: (group, options) => {
const groupValue = leftRightGroupValue(group);
assertParsed(group);
// Build the inner expression
const inner = html.buildExpression(groupValue.body, options, true,
const inner = html.buildExpression(group.body, options, true,
[null, "mclose"]);
let innerHeight = 0;
@@ -226,14 +212,14 @@ defineFunction({
innerDepth *= options.sizeMultiplier;
let leftDelim;
if (groupValue.left === ".") {
if (group.left === ".") {
// Empty delimiters in \left and \right make null delimiter spaces.
leftDelim = html.makeNullDelimiter(options, ["mopen"]);
} else {
// Otherwise, use leftRightDelim to generate the correct sized
// delimiter.
leftDelim = delimiter.leftRightDelim(
groupValue.left, innerHeight, innerDepth, options,
group.left, innerHeight, innerDepth, options,
group.mode, ["mopen"]);
}
// Add it to the beginning of the expression
@@ -250,7 +236,7 @@ defineFunction({
if (isMiddle) {
// Apply the options that were active when \middle was called
inner[i] = delimiter.leftRightDelim(
isMiddle.value, innerHeight, innerDepth,
isMiddle.delim, innerHeight, innerDepth,
isMiddle.options, group.mode, []);
}
}
@@ -258,11 +244,11 @@ defineFunction({
let rightDelim;
// Same for the right delimiter
if (groupValue.right === ".") {
if (group.right === ".") {
rightDelim = html.makeNullDelimiter(options, ["mclose"]);
} else {
rightDelim = delimiter.leftRightDelim(
groupValue.right, innerHeight, innerDepth, options,
group.right, innerHeight, innerDepth, options,
group.mode, ["mclose"]);
}
// Add it to the end of the expression.
@@ -271,21 +257,21 @@ defineFunction({
return buildCommon.makeSpan(["minner"], inner, options);
},
mathmlBuilder: (group, options) => {
const groupValue = leftRightGroupValue(group);
const inner = mml.buildExpression(groupValue.body, options);
assertParsed(group);
const inner = mml.buildExpression(group.body, options);
if (groupValue.left !== ".") {
if (group.left !== ".") {
const leftNode = new mathMLTree.MathNode(
"mo", [mml.makeText(groupValue.left, group.mode)]);
"mo", [mml.makeText(group.left, group.mode)]);
leftNode.setAttribute("fence", "true");
inner.unshift(leftNode);
}
if (groupValue.right !== ".") {
if (group.right !== ".") {
const rightNode = new mathMLTree.MathNode(
"mo", [mml.makeText(groupValue.right, group.mode)]);
"mo", [mml.makeText(group.right, group.mode)]);
rightNode.setAttribute("fence", "true");
@@ -311,22 +297,19 @@ defineFunction({
return {
type: "middle",
mode: context.parser.mode,
value: {
type: "middle",
value: delim.value,
},
delim: delim.value,
};
},
htmlBuilder: (group, options) => {
let middleDelim;
if (group.value.value === ".") {
if (group.delim === ".") {
middleDelim = html.makeNullDelimiter(options, []);
} else {
middleDelim = delimiter.sizedDelim(
group.value.value, 1, options,
group.delim, 1, options,
group.mode, []);
const isMiddle: IsMiddle = {value: group.value.value, options};
const isMiddle: IsMiddle = {delim: group.delim, options};
// Property `isMiddle` not defined on `span`. It is only used in
// this file above.
// TODO: Fix this violation of the `span` type and possibly rename
@@ -338,7 +321,7 @@ defineFunction({
},
mathmlBuilder: (group, options) => {
const middleNode = new mathMLTree.MathNode(
"mo", [mml.makeText(group.value.value, group.mode)]);
"mo", [mml.makeText(group.delim, group.mode)]);
middleNode.setAttribute("fence", "true");
return middleNode;
},

View File

@@ -7,17 +7,18 @@ import defineFunction from "../defineFunction";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import type {ParseNode} from "../parseNode";
const htmlBuilder = (group, options) => {
const font = group.value.font;
const htmlBuilder = (group: ParseNode<"font">, options) => {
const font = group.font;
const newOptions = options.withFont(font);
return html.buildGroup(group.value.body, newOptions);
return html.buildGroup(group.body, newOptions);
};
const mathmlBuilder = (group, options) => {
const font = group.value.font;
const mathmlBuilder = (group: ParseNode<"font">, options) => {
const font = group.font;
const newOptions = options.withFont(font);
return mml.buildGroup(group.value.body, newOptions);
return mml.buildGroup(group.body, newOptions);
};
const fontAliases = {
@@ -53,11 +54,8 @@ defineFunction({
return {
type: "font",
mode: parser.mode,
value: {
type: "font",
font: func.slice(1),
body,
},
font: func.slice(1),
body,
};
},
htmlBuilder,
@@ -78,21 +76,15 @@ defineFunction({
return {
type: "mclass",
mode: parser.mode,
value: {
type: "mclass",
mclass: binrelClass(body),
value: [
{
type: "font",
mode: parser.mode,
value: {
type: "font",
font: "boldsymbol",
body,
},
},
],
},
mclass: binrelClass(body),
body: [
{
type: "font",
mode: parser.mode,
font: "boldsymbol",
body,
},
],
};
},
});
@@ -114,14 +106,11 @@ defineFunction({
return {
type: "font",
mode: mode,
value: {
type: "font",
font: style,
body: {
type: "ordgroup",
mode: parser.mode,
value: body,
},
font: style,
body: {
type: "ordgroup",
mode: parser.mode,
value: body,
},
};
},

View File

@@ -18,31 +18,21 @@ defineFunction({
},
handler: ({parser}, args) => {
const body = args[1];
const href = assertNodeType(args[0], "url").value.value;
const href = assertNodeType(args[0], "url").url;
return {
type: "href",
mode: parser.mode,
value: {
type: "href",
href: href,
body: ordargument(body),
},
href,
body: ordargument(body),
};
},
htmlBuilder: (group, options) => {
const elements = html.buildExpression(
group.value.body,
options,
false
);
const href = group.value.href;
return new buildCommon.makeAnchor(href, [], elements, options);
const elements = html.buildExpression(group.body, options, false);
return new buildCommon.makeAnchor(group.href, [], elements, options);
},
mathmlBuilder: (group, options) => {
const math = mml.buildExpressionRow(group.value.body, options);
assertType(math, MathNode).setAttribute("href", group.value.href);
const math = mml.buildExpressionRow(group.body, options);
assertType(math, MathNode).setAttribute("href", group.href);
return math;
},
});
@@ -56,7 +46,7 @@ defineFunction({
allowedInText: true,
},
handler: ({parser}, args) => {
const href = assertNodeType(args[0], "url").value.value;
const href = assertNodeType(args[0], "url").url;
const chars = [];
for (let i = 0; i < href.length; i++) {
let c = href[i];
@@ -81,11 +71,8 @@ defineFunction({
return {
type: "href",
mode: parser.mode,
value: {
type: "href",
href: href,
body: ordargument(body),
},
href,
body: ordargument(body),
};
},
});

View File

@@ -6,19 +6,16 @@ import Style from "../Style";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
const chooseMathStyle = (group, options) => {
const style = options.style;
if (style.size === Style.DISPLAY.size) {
return group.value.display;
} else if (style.size === Style.TEXT.size) {
return group.value.text;
} else if (style.size === Style.SCRIPT.size) {
return group.value.script;
} else if (style.size === Style.SCRIPTSCRIPT.size) {
return group.value.scriptscript;
}
return group.value.text;
import type {ParseNode} from "../parseNode";
const chooseMathStyle = (group: ParseNode<"mathchoice">, options) => {
switch (options.style.size) {
case Style.DISPLAY.size: return group.display;
case Style.TEXT.size: return group.text;
case Style.SCRIPT.size: return group.script;
case Style.SCRIPTSCRIPT.size: return group.scriptscript;
default: return group.text;
}
};
defineFunction({
@@ -31,13 +28,10 @@ defineFunction({
return {
type: "mathchoice",
mode: parser.mode,
value: {
type: "mathchoice",
display: ordargument(args[0]),
text: ordargument(args[1]),
script: ordargument(args[2]),
scriptscript: ordargument(args[3]),
},
display: ordargument(args[0]),
text: ordargument(args[1]),
script: ordargument(args[2]),
scriptscript: ordargument(args[3]),
};
},
htmlBuilder: (group, options) => {

View File

@@ -7,15 +7,17 @@ import type {AnyParseNode} from "../parseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import type {ParseNode} from "../parseNode";
const makeSpan = buildCommon.makeSpan;
function htmlBuilder(group, options) {
const elements = html.buildExpression(group.value.value, options, true);
return makeSpan([group.value.mclass], elements, options);
function htmlBuilder(group: ParseNode<"mclass">, options) {
const elements = html.buildExpression(group.body, options, true);
return makeSpan([group.mclass], elements, options);
}
function mathmlBuilder(group, options) {
const inner = mml.buildExpression(group.value.value, options);
function mathmlBuilder(group: ParseNode<"mclass">, options) {
const inner = mml.buildExpression(group.body, options);
return mathMLTree.newDocumentFragment(inner);
}
@@ -34,11 +36,8 @@ defineFunction({
return {
type: "mclass",
mode: parser.mode,
value: {
type: "mclass",
mclass: "m" + funcName.substr(5),
value: ordargument(body),
},
mclass: "m" + funcName.substr(5),
body: ordargument(body),
};
},
htmlBuilder,
@@ -70,11 +69,8 @@ defineFunction({
return {
type: "mclass",
mode: parser.mode,
value: {
type: "mclass",
mclass: binrelClass(args[0]),
value: [args[1]],
},
mclass: binrelClass(args[0]),
body: [args[1]],
};
},
});
@@ -119,11 +115,8 @@ defineFunction({
return {
type: "mclass",
mode: parser.mode,
value: {
type: "mclass",
mclass: mclass,
value: [supsub],
},
mclass,
body: [supsub],
};
},
htmlBuilder,

View File

@@ -18,15 +18,12 @@ defineFunction({
return {
type: "phantom",
mode: parser.mode,
value: {
type: "phantom",
value: ordargument(body),
},
body: ordargument(body),
};
},
htmlBuilder: (group, options) => {
const elements = html.buildExpression(
group.value.value,
group.body,
options.withPhantom(),
false
);
@@ -36,7 +33,7 @@ defineFunction({
return new buildCommon.makeFragment(elements);
},
mathmlBuilder: (group, options) => {
const inner = mml.buildExpression(group.value.value, options);
const inner = mml.buildExpression(group.body, options);
return new mathMLTree.MathNode("mphantom", inner);
},
});
@@ -53,16 +50,12 @@ defineFunction({
return {
type: "hphantom",
mode: parser.mode,
value: {
type: "hphantom",
value: ordargument(body),
body: body,
},
body,
};
},
htmlBuilder: (group, options) => {
let node = buildCommon.makeSpan(
[], [html.buildGroup(group.value.body, options.withPhantom())]);
[], [html.buildGroup(group.body, options.withPhantom())]);
node.height = 0;
node.depth = 0;
if (node.children) {
@@ -81,7 +74,7 @@ defineFunction({
return node;
},
mathmlBuilder: (group, options) => {
const inner = mml.buildExpression(group.value.value, options);
const inner = mml.buildExpression(ordargument(group.body), options);
const node = new mathMLTree.MathNode("mphantom", inner);
node.setAttribute("height", "0px");
return node;
@@ -100,23 +93,19 @@ defineFunction({
return {
type: "vphantom",
mode: parser.mode,
value: {
type: "vphantom",
value: ordargument(body),
body: body,
},
body,
};
},
htmlBuilder: (group, options) => {
const inner = buildCommon.makeSpan(
["inner"],
[html.buildGroup(group.value.body, options.withPhantom())]);
[html.buildGroup(group.body, options.withPhantom())]);
const fix = buildCommon.makeSpan(["fix"], []);
return buildCommon.makeSpan(
["mord", "rlap"], [inner, fix], options);
},
mathmlBuilder: (group, options) => {
const inner = mml.buildExpression(group.value.value, options);
const inner = mml.buildExpression(ordargument(group.body), options);
const node = new mathMLTree.MathNode("mphantom", inner);
node.setAttribute("width", "0px");
return node;

View File

@@ -10,10 +10,10 @@ defineFunctionBuilders({
const table = new mathMLTree.MathNode("mtable", [
new mathMLTree.MathNode("mlabeledtr", [
new mathMLTree.MathNode("mtd", [
mml.buildExpressionRow(group.value.tag, options),
mml.buildExpressionRow(group.tag, options),
]),
new mathMLTree.MathNode("mtd", [
mml.buildExpressionRow(group.value.body, options),
mml.buildExpressionRow(group.body, options),
]),
]),
]);

View File

@@ -10,13 +10,6 @@ import type {Measurement} from "./units";
export type NodeType = $Keys<ParseNodeTypes>;
export type ParseNode<TYPE: NodeType> = $ElementType<ParseNodeTypes, TYPE>;
export type LeftRightDelimType = {|
type: "leftright",
body: AnyParseNode[],
left: string,
right: string,
|};
// ParseNode's corresponding to Symbol `Group`s in symbols.js.
export type SymbolParseNode =
ParseNode<"atom"> |
@@ -116,11 +109,8 @@ type ParseNodeTypes = {
type: "tag",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "tag",
body: AnyParseNode[],
tag: AnyParseNode[],
|},
body: AnyParseNode[],
tag: AnyParseNode[],
|},
"text": {|
type: "text",
@@ -136,20 +126,14 @@ type ParseNodeTypes = {
type: "url",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "url",
value: string,
|},
url: string,
|},
"verb": {|
type: "verb",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "verb",
body: string,
star: boolean,
|},
body: string,
star: boolean,
|},
// From symbol groups, constructed in Parser.js via `symbols` lookup.
// (Some of these have "-token" suffix to distinguish them from existing
@@ -216,23 +200,17 @@ type ParseNodeTypes = {
type: "cr",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "cr",
newRow: boolean,
newLine: boolean,
size: ?ParseNode<"size">,
|},
newRow: boolean,
newLine: boolean,
size: ?ParseNode<"size">,
|},
"delimsizing": {|
type: "delimsizing",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "delimsizing",
size: 1 | 2 | 3 | 4,
mclass: "mopen" | "mclose" | "mrel" | "mord",
value: string,
|},
size: 1 | 2 | 3 | 4,
mclass: "mopen" | "mclose" | "mrel" | "mord",
delim: string,
|},
"enclose": {|
type: "enclose",
@@ -260,11 +238,8 @@ type ParseNodeTypes = {
type: "font",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "font",
font: string,
body: AnyParseNode,
|},
font: string,
body: AnyParseNode,
|},
"genfrac": {|
type: "genfrac",
@@ -294,11 +269,8 @@ type ParseNodeTypes = {
type: "href",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "href",
href: string,
body: AnyParseNode[],
|},
href: string,
body: AnyParseNode[],
|},
"htmlmathml": {|
type: "htmlmathml",
@@ -344,57 +316,37 @@ type ParseNodeTypes = {
type: "leftright",
mode: Mode,
loc?: ?SourceLocation,
value: LeftRightDelimType,
body: AnyParseNode[],
left: string,
right: string,
|},
"leftright-right": {|
type: "leftright-right",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "leftright-right",
value: string,
|},
delim: string,
|},
"mathchoice": {|
type: "mathchoice",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "mathchoice",
display: AnyParseNode[],
text: AnyParseNode[],
script: AnyParseNode[],
scriptscript: AnyParseNode[],
|},
display: AnyParseNode[],
text: AnyParseNode[],
script: AnyParseNode[],
scriptscript: AnyParseNode[],
|},
"middle": {|
type: "middle",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "middle",
value: string,
|},
delim: string,
|},
"mclass": {|
type: "mclass",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "mclass",
mclass: string,
value: AnyParseNode[],
|},
|},
"mod": {|
type: "mod",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "mod",
modType: string,
value: ?AnyParseNode[],
|},
mclass: string,
body: AnyParseNode[],
|},
"operatorname": {|
type: "operatorname",
@@ -418,30 +370,19 @@ type ParseNodeTypes = {
type: "phantom",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "phantom",
value: AnyParseNode[],
|},
body: AnyParseNode[],
|},
"hphantom": {|
type: "hphantom",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "hphantom",
body: AnyParseNode,
value: AnyParseNode[],
|},
body: AnyParseNode,
|},
"vphantom": {|
type: "vphantom",
mode: Mode,
loc?: ?SourceLocation,
value: {|
type: "vphantom",
body: AnyParseNode,
value: AnyParseNode[],
|},
body: AnyParseNode,
|},
"raisebox": {|
type: "raisebox",

View File

@@ -32,11 +32,8 @@ const parseTree = function(toParse: string, settings: Settings): AnyParseNode[]
tree = [{
type: "tag",
mode: "text",
value: {
type: "tag",
body: tree,
tag: parser.parse(),
},
body: tree,
tag: parser.parse(),
}];
}

View File

@@ -110,7 +110,7 @@ const getBaseElem = function(group: AnyParseNode): AnyParseNode {
return group;
}
} else if (group.type === "font") {
return getBaseElem(group.value.body);
return getBaseElem(group.body);
} else {
return group;
}

View File

@@ -751,22 +751,19 @@ exports[`An implicit group parser within optional groups should work with old fo
"value": [
{
"type": "font",
"mode": "math",
"value": {
"type": "font",
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "textord",
"mode": "math",
"value": "3"
}
]
},
"font": "mathtt"
}
"body": {
"type": "ordgroup",
"mode": "math",
"value": [
{
"type": "textord",
"mode": "math",
"value": "3"
}
]
},
"font": "mathtt",
"mode": "math"
}
]
}

View File

@@ -95,7 +95,7 @@ describe("A rel parser", function() {
group = group.value.html[0];
}
if (group.type === "mclass") {
expect(group.value.mclass).toEqual("mrel");
expect(group.mclass).toEqual("mrel");
} else {
expect(group.type).toEqual("atom");
expect(group.family).toEqual("rel");
@@ -895,16 +895,16 @@ describe("A delimiter sizing parser", function() {
const leftParse = getParsed(normalDelim)[0];
const rightParse = getParsed(bigDelim)[0];
expect(leftParse.value.mclass).toEqual("mopen");
expect(rightParse.value.mclass).toEqual("mclose");
expect(leftParse.mclass).toEqual("mopen");
expect(rightParse.mclass).toEqual("mclose");
});
it("should parse the correct size delimiter", function() {
const smallParse = getParsed(normalDelim)[0];
const bigParse = getParsed(bigDelim)[0];
expect(smallParse.value.size).toEqual(1);
expect(bigParse.value.size).toEqual(4);
expect(smallParse.size).toEqual(1);
expect(bigParse.size).toEqual(4);
});
});
@@ -1122,8 +1122,8 @@ describe("A left/right parser", function() {
const parse = getParsed(normalLeftRight)[0];
expect(parse.type).toEqual("leftright");
expect(parse.value.left).toEqual("(");
expect(parse.value.right).toEqual(")");
expect(parse.left).toEqual("(");
expect(parse.right).toEqual(")");
});
it("should error when it is mismatched", function() {
@@ -1476,37 +1476,37 @@ describe("A font parser", function() {
it("should produce the correct fonts", function() {
const mathbbParse = getParsed`\mathbb x`[0];
expect(mathbbParse.value.font).toEqual("mathbb");
expect(mathbbParse.value.type).toEqual("font");
expect(mathbbParse.font).toEqual("mathbb");
expect(mathbbParse.type).toEqual("font");
const mathrmParse = getParsed`\mathrm x`[0];
expect(mathrmParse.value.font).toEqual("mathrm");
expect(mathrmParse.value.type).toEqual("font");
expect(mathrmParse.font).toEqual("mathrm");
expect(mathrmParse.type).toEqual("font");
const mathitParse = getParsed`\mathit x`[0];
expect(mathitParse.value.font).toEqual("mathit");
expect(mathitParse.value.type).toEqual("font");
expect(mathitParse.font).toEqual("mathit");
expect(mathitParse.type).toEqual("font");
const mathcalParse = getParsed`\mathcal C`[0];
expect(mathcalParse.value.font).toEqual("mathcal");
expect(mathcalParse.value.type).toEqual("font");
expect(mathcalParse.font).toEqual("mathcal");
expect(mathcalParse.type).toEqual("font");
const mathfrakParse = getParsed`\mathfrak C`[0];
expect(mathfrakParse.value.font).toEqual("mathfrak");
expect(mathfrakParse.value.type).toEqual("font");
expect(mathfrakParse.font).toEqual("mathfrak");
expect(mathfrakParse.type).toEqual("font");
});
it("should parse nested font commands", function() {
const nestedParse = getParsed`\mathbb{R \neq \mathrm{R}}`[0];
expect(nestedParse.value.font).toEqual("mathbb");
expect(nestedParse.value.type).toEqual("font");
expect(nestedParse.font).toEqual("mathbb");
expect(nestedParse.type).toEqual("font");
const bbBody = nestedParse.value.body.value;
const bbBody = nestedParse.body.value;
expect(bbBody).toHaveLength(3);
expect(bbBody[0].type).toEqual("mathord");
expect(bbBody[2].type).toEqual("font");
expect(bbBody[2].value.font).toEqual("mathrm");
expect(bbBody[2].value.type).toEqual("font");
expect(bbBody[2].font).toEqual("mathrm");
expect(bbBody[2].type).toEqual("font");
});
it("should work with \\textcolor", function() {
@@ -1515,8 +1515,8 @@ describe("A font parser", function() {
expect(colorMathbbParse.value.color).toEqual("blue");
const body = colorMathbbParse.value.value;
expect(body).toHaveLength(1);
expect(body[0].value.type).toEqual("font");
expect(body[0].value.font).toEqual("mathbb");
expect(body[0].type).toEqual("font");
expect(body[0].font).toEqual("mathbb");
});
it("should not parse a series of font commands", function() {
@@ -1525,13 +1525,13 @@ describe("A font parser", function() {
it("should nest fonts correctly", function() {
const bf = getParsed`\mathbf{a\mathrm{b}c}`[0];
expect(bf.value.type).toEqual("font");
expect(bf.value.font).toEqual("mathbf");
expect(bf.value.body.value).toHaveLength(3);
expect(bf.value.body.value[0].value).toEqual("a");
expect(bf.value.body.value[1].value.type).toEqual("font");
expect(bf.value.body.value[1].value.font).toEqual("mathrm");
expect(bf.value.body.value[2].value).toEqual("c");
expect(bf.type).toEqual("font");
expect(bf.font).toEqual("mathbf");
expect(bf.body.value).toHaveLength(3);
expect(bf.body.value[0].value).toEqual("a");
expect(bf.body.value[1].type).toEqual("font");
expect(bf.body.value[1].font).toEqual("mathrm");
expect(bf.body.value[2].value).toEqual("c");
});
it("should have the correct greediness", function() {
@@ -2292,7 +2292,7 @@ describe("A phantom parser", function() {
const parse = getParsed`\phantom{x}`[0];
expect(parse.type).toEqual("phantom");
expect(parse.value.value).toBeDefined();
expect(parse.body).toBeDefined();
});
});
@@ -2499,17 +2499,17 @@ describe("href and url commands", function() {
it("should allow letters [#$%&~_^] without escaping", function() {
const url = "http://example.org/~bar/#top?foo=$foo&bar=ba^r_boo%20baz";
const parsed1 = getParsed(`\\href{${url}}{\\alpha}`)[0];
expect(parsed1.value.href).toBe(url);
expect(parsed1.href).toBe(url);
const parsed2 = getParsed(`\\url{${url}}`)[0];
expect(parsed2.value.href).toBe(url);
expect(parsed2.href).toBe(url);
});
it("should allow balanced braces in url", function() {
const url = "http://example.org/{too}";
const parsed1 = getParsed(`\\href{${url}}{\\alpha}`)[0];
expect(parsed1.value.href).toBe(url);
expect(parsed1.href).toBe(url);
const parsed2 = getParsed(`\\url{${url}}`)[0];
expect(parsed2.value.href).toBe(url);
expect(parsed2.href).toBe(url);
});
it("should not allow unbalanced brace(s) in url", function() {
@@ -2523,9 +2523,9 @@ describe("href and url commands", function() {
const url = "http://example.org/~bar/#top?foo=$}foo{&bar=bar^r_boo%20baz";
const input = url.replace(/([#$%&~_^{}])/g, '\\$1');
const parsed1 = getParsed(`\\href{${input}}{\\alpha}`)[0];
expect(parsed1.value.href).toBe(url);
expect(parsed1.href).toBe(url);
const parsed2 = getParsed(`\\url{${input}}`)[0];
expect(parsed2.value.href).toBe(url);
expect(parsed2.href).toBe(url);
});
it("should be marked up correctly", function() {