update function handlers to return a ParseNode (#1393)

* update function handlers to return a ParseNode

* remove FlowFixMes
This commit is contained in:
Kevin Barabash
2018-06-02 13:05:15 -04:00
committed by Ashish Myles
parent 3e0ad9fd48
commit 9d2722f879
31 changed files with 209 additions and 208 deletions

View File

@@ -9,7 +9,7 @@ import {validUnit} from "./units";
import {supportedCodepoint} from "./unicodeScripts";
import unicodeAccents from "./unicodeAccents";
import unicodeSymbols from "./unicodeSymbols";
import ParseNode from "./ParseNode";
import ParseNode, {assertNodeType} from "./ParseNode";
import ParseError from "./ParseError";
import {combiningDiacriticalMarksEndRegex} from "./Lexer.js";
import Settings from "./Settings";
@@ -244,8 +244,8 @@ export default class Parser {
denomNode = new ParseNode("ordgroup", denomBody, this.mode);
}
const value = this.callFunction(funcName, [numerNode, denomNode], []);
return [new ParseNode(value.type, value, this.mode)];
const node = this.callFunction(funcName, [numerNode, denomNode], []);
return [node];
} else {
return body;
}
@@ -442,7 +442,9 @@ export default class Parser {
if (func === "\\begin") {
// begin...end is similar to left...right
const begin = this.parseGivenFunction(start);
const begin =
assertNodeType(this.parseGivenFunction(start), "environment");
const envName = begin.value.name;
if (!environments.hasOwnProperty(envName)) {
throw new ParseError(
@@ -461,7 +463,7 @@ export default class Parser {
const result = env.handler(context, args, optArgs);
this.expect("\\end", false);
const endNameToken = this.nextToken;
const end = this.parseFunction();
const end = assertNodeType(this.parseFunction(), "environment");
if (!end) {
throw new ParseError("failed to parse function after \\end");
} else if (end.value.name !== envName) {
@@ -521,9 +523,8 @@ export default class Parser {
}
const {args, optArgs} = this.parseArguments(func, funcData);
const token = baseGroup.token;
const result = this.callFunction(
return this.callFunction(
func, args, optArgs, token, breakOnTokenText);
return new ParseNode(result.type, result, this.mode);
} else {
return baseGroup.result;
}
@@ -538,7 +539,7 @@ export default class Parser {
optArgs: (?ParseNode<*>)[],
token?: Token,
breakOnTokenText?: BreakToken,
): * {
): ParseNode<*> {
const context: FunctionContext = {
funcName: name,
parser: this,

View File

@@ -3,7 +3,7 @@ import {checkNodeType} from "./ParseNode";
import domTree from "./domTree";
import type Parser from "./Parser";
import type ParseNode, {NodeType, NodeValue} from "./ParseNode";
import type ParseNode, {NodeType} from "./ParseNode";
import type Options from "./Options";
import type {ArgType, BreakToken, Mode} from "./types";
import type {HtmlDomNode} from "./domTree";
@@ -22,7 +22,7 @@ export type FunctionHandler<NODETYPE: NodeType> = (
context: FunctionContext,
args: ParseNode<*>[],
optArgs: (?ParseNode<*>)[],
) => NodeValue<NODETYPE>;
) => ParseNode<NODETYPE>;
export type HtmlBuilder<NODETYPE> = (ParseNode<NODETYPE>, Options) => HtmlDomNode;
export type MathMLBuilder<NODETYPE> = (

View File

@@ -4,12 +4,11 @@ import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import utils from "../utils";
import stretchy from "../stretchy";
import {assertNodeType, checkNodeType} from "../ParseNode";
import ParseNode, {assertNodeType, checkNodeType} from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import type ParseNode from "../ParseNode";
import type {HtmlBuilderSupSub, MathMLBuilder} from "../defineFunction";
// NOTE: Unlike most `htmlBuilder`s, this one handles not only "accent", but
@@ -225,13 +224,13 @@ defineFunction({
context.funcName === "\\widehat" ||
context.funcName === "\\widetilde";
return {
return new ParseNode("accent", {
type: "accent",
label: context.funcName,
isStretchy: isStretchy,
isShifty: isShifty,
base: base,
};
}, context.parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -252,13 +251,13 @@ defineFunction({
handler: (context, args) => {
const base = args[0];
return {
return new ParseNode("accent", {
type: "accent",
label: context.funcName,
isStretchy: false,
isShifty: true,
base: base,
};
}, context.parser.mode);
},
htmlBuilder,
mathmlBuilder,

View File

@@ -4,12 +4,11 @@ import defineFunction from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import stretchy from "../stretchy";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import type ParseNode from "../ParseNode";
defineFunction({
type: "accentUnder",
names: [
@@ -19,13 +18,13 @@ defineFunction({
props: {
numArgs: 1,
},
handler: (context, args) => {
handler: ({parser, funcName}, args) => {
const base = args[0];
return {
return new ParseNode("accentUnder", {
type: "accentUnder",
label: context.funcName,
label: funcName,
base: base,
};
}, parser.mode);
},
htmlBuilder: (group: ParseNode<"accentUnder">, options) => {
// Treat under accents much like underlines.

View File

@@ -3,12 +3,11 @@ import defineFunction from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import stretchy from "../stretchy";
import ParseNode from "../ParseNode.js";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import type ParseNode from "../ParseNode.js";
// Stretchy arrows with an optional argument
defineFunction({
type: "xArrow",
@@ -27,13 +26,13 @@ defineFunction({
numArgs: 1,
numOptionalArgs: 1,
},
handler(context, args, optArgs) {
return {
handler({parser, funcName}, args, optArgs) {
return new ParseNode("xArrow", {
type: "xArrow", // x for extensible
label: context.funcName,
label: funcName,
body: args[0],
below: optArgs[0],
};
}, parser.mode);
},
// Flow is unable to correctly infer the type of `group`, even though it's
// unamibiguously determined from the passed-in `type` above.

View File

@@ -3,7 +3,7 @@ import defineFunction, {ordargument} from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import ParseError from "../ParseError";
import {assertNodeType} from "../ParseNode";
import ParseNode, {assertNodeType} from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -41,14 +41,14 @@ defineFunction({
greediness: 3,
argTypes: ["color", "original"],
},
handler(context, args) {
handler({parser}, args) {
const color = assertNodeType(args[0], "color-token");
const body = args[1];
return {
return new ParseNode("color", {
type: "color",
color: color.value,
value: ordargument(body),
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -77,13 +77,13 @@ defineFunction({
allowedInText: true,
greediness: 3,
},
handler(context, args) {
handler({parser, funcName}, args) {
const body = args[0];
return {
return new ParseNode("color", {
type: "color",
color: "katex-" + context.funcName.slice(1),
color: "katex-" + funcName.slice(1),
value: ordargument(body),
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -98,9 +98,7 @@ defineFunction({
greediness: 3,
argTypes: ["color"],
},
handler(context, args) {
const {parser, breakOnTokenText} = context;
handler({parser, breakOnTokenText}, args) {
const color = args[0];
if (!color) {
throw new ParseError("\\color not followed by color");
@@ -109,11 +107,11 @@ defineFunction({
// If we see a styling function, parse out the implicit body
const body = parser.parseExpression(true, breakOnTokenText);
return {
return new ParseNode("color", {
type: "color",
color: color.value,
value: body,
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,

View File

@@ -6,7 +6,7 @@ import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import {calculateSize} from "../units";
import ParseError from "../ParseError";
import {assertNodeType} from "../ParseNode";
import ParseNode, {assertNodeType} from "../ParseNode";
// \\ is a macro mapping to either \cr or \newline. Because they have the
// same signature, we implement them as one megafunction, with newRow
@@ -23,13 +23,13 @@ defineFunction({
allowedInText: true,
},
handler: (context, args, optArgs) => {
handler: ({parser, funcName}, args, optArgs) => {
const size = optArgs[0];
const newRow = (context.funcName === "\\cr");
const newRow = (funcName === "\\cr");
let newLine = false;
if (!newRow) {
if (context.parser.settings.displayMode &&
context.parser.settings.useStrictBehavior(
if (parser.settings.displayMode &&
parser.settings.useStrictBehavior(
"newLineInDisplayMode", "In LaTeX, \\\\ or \\newline " +
"does nothing in display mode")) {
newLine = false;
@@ -37,12 +37,12 @@ defineFunction({
newLine = true;
}
}
return {
return new ParseNode("cr", {
type: "cr",
newLine,
newRow,
size: size && assertNodeType(size, "size"),
};
}, parser.mode);
},
// The following builders are called only at the top level,

View File

@@ -5,12 +5,11 @@ import delimiter from "../delimiter";
import mathMLTree from "../mathMLTree";
import ParseError from "../ParseError";
import utils from "../utils";
import {assertNodeType} from "../ParseNode";
import ParseNode, {assertNodeType} from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import type ParseNode from "../ParseNode";
import type {LeftRightDelimType} from "../ParseNode";
import type {FunctionContext} from "../defineFunction";
@@ -79,12 +78,12 @@ defineFunction({
handler: (context, args) => {
const delim = checkDelimiter(args[0], context);
return {
return new ParseNode("delimsizing", {
type: "delimsizing",
size: delimiterSizes[context.funcName].size,
mclass: delimiterSizes[context.funcName].mclass,
value: delim.value,
};
}, context.parser.mode);
},
htmlBuilder: (group, options) => {
const delim = group.value.value;
@@ -143,10 +142,10 @@ defineFunction({
// \left case below triggers parsing of \right in
// `const right = parser.parseFunction();`
// uses this return value.
return {
return new ParseNode("leftright-right", {
type: "leftright-right",
value: checkDelimiter(args[0], context).value,
};
}, context.parser.mode);
},
});
@@ -172,12 +171,12 @@ defineFunction({
if (!right) {
throw new ParseError('failed to parse function after \\right');
}
return {
return new ParseNode("leftright", {
type: "leftright",
body: body,
left: delim.value,
right: assertNodeType(right, "leftright-right").value.value,
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
const groupValue = leftRightGroupValue(group);
@@ -284,10 +283,10 @@ defineFunction({
throw new ParseError("\\middle without preceding \\left", delim);
}
return {
return new ParseNode("middle", {
type: "middle",
value: delim.value,
};
}, context.parser.mode);
},
htmlBuilder: (group, options) => {
let middleDelim;

View File

@@ -4,7 +4,7 @@ import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import utils from "../utils";
import stretchy from "../stretchy";
import {assertNodeType} from "../ParseNode";
import ParseNode, {assertNodeType} from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -127,15 +127,15 @@ defineFunction({
greediness: 3,
argTypes: ["color", "text"],
},
handler(context, args, optArgs) {
handler({parser, funcName}, args, optArgs) {
const color = assertNodeType(args[0], "color-token");
const body = args[1];
return {
return new ParseNode("enclose", {
type: "enclose",
label: context.funcName,
label: funcName,
backgroundColor: color,
body: body,
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -150,17 +150,17 @@ defineFunction({
greediness: 3,
argTypes: ["color", "color", "text"],
},
handler(context, args, optArgs) {
handler({parser, funcName}, args, optArgs) {
const borderColor = assertNodeType(args[0], "color-token");
const backgroundColor = assertNodeType(args[1], "color-token");
const body = args[2];
return {
return new ParseNode("enclose", {
type: "enclose",
label: context.funcName,
label: funcName,
backgroundColor: backgroundColor,
borderColor: borderColor,
body: body,
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -172,13 +172,13 @@ defineFunction({
props: {
numArgs: 1,
},
handler(context, args, optArgs) {
handler({parser, funcName}, args, optArgs) {
const body = args[0];
return {
return new ParseNode("enclose", {
type: "enclose",
label: context.funcName,
label: funcName,
body: body,
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,

View File

@@ -1,6 +1,7 @@
// @flow
import defineFunction from "../defineFunction";
import ParseError from "../ParseError";
import ParseNode from "../ParseNode";
// Environment delimiters. HTML/MathML rendering is defined in the corresponding
// defineEnvironment definitions.
@@ -11,7 +12,7 @@ defineFunction({
numArgs: 1,
argTypes: ["text"],
},
handler(context, args) {
handler({parser}, args) {
const nameGroup = args[0];
if (nameGroup.type !== "ordgroup") {
throw new ParseError("Invalid environment name", nameGroup);
@@ -20,10 +21,10 @@ defineFunction({
for (let i = 0; i < nameGroup.value.length; ++i) {
name += nameGroup.value[i].value;
}
return {
return new ParseNode("environment", {
type: "environment",
name: name,
nameGroup: nameGroup,
};
}, parser.mode);
},
});

View File

@@ -44,17 +44,17 @@ defineFunction({
numArgs: 1,
greediness: 2,
},
handler: (context, args) => {
handler: ({parser, funcName}, args) => {
const body = args[0];
let func = context.funcName;
let func = funcName;
if (func in fontAliases) {
func = fontAliases[func];
}
return {
return new ParseNode("font", {
type: "font",
font: func.slice(1),
body: body,
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -76,18 +76,17 @@ defineFunction({
numArgs: 0,
allowedInText: true,
},
handler: (context, args) => {
const {parser, funcName, breakOnTokenText} = context;
handler: ({parser, funcName, breakOnTokenText}, args) => {
const {mode} = parser;
parser.consumeSpaces();
const body = parser.parseExpression(true, breakOnTokenText);
const style = oldFontFuncsMap[funcName];
return {
return new ParseNode("font", {
type: "font",
font: style,
body: new ParseNode("ordgroup", body, parser.mode),
};
}, mode);
},
htmlBuilder,
mathmlBuilder,

View File

@@ -4,6 +4,7 @@ import buildCommon from "../buildCommon";
import delimiter from "../delimiter";
import mathMLTree from "../mathMLTree";
import Style from "../Style";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -19,7 +20,7 @@ defineFunction({
numArgs: 2,
greediness: 2,
},
handler: (context, args) => {
handler: ({parser, funcName}, args) => {
const numer = args[0];
const denom = args[1];
let hasBarLine;
@@ -27,7 +28,7 @@ defineFunction({
let rightDelim = null;
let size = "auto";
switch (context.funcName) {
switch (funcName) {
case "\\dfrac":
case "\\frac":
case "\\tfrac":
@@ -47,7 +48,7 @@ defineFunction({
throw new Error("Unrecognized genfrac command");
}
switch (context.funcName) {
switch (funcName) {
case "\\dfrac":
case "\\dbinom":
size = "display";
@@ -58,7 +59,7 @@ defineFunction({
break;
}
return {
return new ParseNode("genfrac", {
type: "genfrac",
numer: numer,
denom: denom,
@@ -66,7 +67,7 @@ defineFunction({
leftDelim: leftDelim,
rightDelim: rightDelim,
size: size,
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
// Fractions are handled in the TeXbook on pages 444-445, rules 15(a-e).
@@ -261,9 +262,9 @@ defineFunction({
numArgs: 0,
infix: true,
},
handler(context) {
handler({parser, funcName, token}) {
let replaceWith;
switch (context.funcName) {
switch (funcName) {
case "\\over":
replaceWith = "\\frac";
break;
@@ -276,11 +277,11 @@ defineFunction({
default:
throw new Error("Unrecognized infix genfrac command");
}
return {
return new ParseNode("infix", {
type: "infix",
replaceWith: replaceWith,
token: context.token,
};
token: token,
}, parser.mode);
},
});

View File

@@ -4,12 +4,11 @@ import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import stretchy from "../stretchy";
import Style from "../Style";
import {assertNodeType, checkNodeType} from "../ParseNode";
import ParseNode, {assertNodeType, checkNodeType} from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import type ParseNode from "../ParseNode";
import type {HtmlBuilderSupSub, MathMLBuilder} from "../defineFunction";
// NOTE: Unlike most `htmlBuilder`s, this one handles not only "horizBrace", but
@@ -126,13 +125,13 @@ defineFunction({
props: {
numArgs: 1,
},
handler(context, args) {
return {
handler({parser, funcName}, args) {
return new ParseNode("horizBrace", {
type: "horizBrace",
label: context.funcName,
isOver: /^\\over/.test(context.funcName),
label: funcName,
isOver: /^\\over/.test(funcName),
base: args[0],
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,

View File

@@ -1,7 +1,7 @@
// @flow
import defineFunction, {ordargument} from "../defineFunction";
import buildCommon from "../buildCommon";
import {assertNodeType} from "../ParseNode";
import ParseNode, {assertNodeType} from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -13,14 +13,14 @@ defineFunction({
numArgs: 2,
argTypes: ["url", "original"],
},
handler: (context, args) => {
handler: ({parser}, args) => {
const body = args[1];
const href = assertNodeType(args[0], "url").value.value;
return {
return new ParseNode("href", {
type: "href",
href: href,
body: ordargument(body),
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
const elements = html.buildExpression(

View File

@@ -5,7 +5,7 @@ import defineFunction from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import {calculateSize} from "../units";
import {assertNodeType} from "../ParseNode";
import ParseNode, {assertNodeType} from "../ParseNode";
// TODO: \hskip and \mskip should support plus and minus in lengths
@@ -17,32 +17,32 @@ defineFunction({
argTypes: ["size"],
allowedInText: true,
},
handler: (context, args) => {
handler: ({parser, funcName}, args) => {
const size = assertNodeType(args[0], "size");
if (context.parser.settings.strict) {
const mathFunction = (context.funcName[1] === 'm'); // \mkern, \mskip
if (parser.settings.strict) {
const mathFunction = (funcName[1] === 'm'); // \mkern, \mskip
const muUnit = (size.value.value.unit === 'mu');
if (mathFunction) {
if (!muUnit) {
context.parser.settings.reportNonstrict("mathVsTextUnits",
`LaTeX's ${context.funcName} supports only mu units, ` +
parser.settings.reportNonstrict("mathVsTextUnits",
`LaTeX's ${funcName} supports only mu units, ` +
`not ${size.value.value.unit} units`);
}
if (context.parser.mode !== "math") {
context.parser.settings.reportNonstrict("mathVsTextUnits",
`LaTeX's ${context.funcName} works only in math mode`);
if (parser.mode !== "math") {
parser.settings.reportNonstrict("mathVsTextUnits",
`LaTeX's ${funcName} works only in math mode`);
}
} else { // !mathFunction
if (muUnit) {
context.parser.settings.reportNonstrict("mathVsTextUnits",
`LaTeX's ${context.funcName} doesn't support mu units`);
parser.settings.reportNonstrict("mathVsTextUnits",
`LaTeX's ${funcName} doesn't support mu units`);
}
}
}
return {
return new ParseNode("kern", {
type: "kern",
dimension: size.value.value,
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
return buildCommon.makeGlue(group.value.dimension, options);

View File

@@ -3,6 +3,7 @@
import defineFunction from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -14,13 +15,13 @@ defineFunction({
numArgs: 1,
allowedInText: true,
},
handler: (context, args) => {
handler: ({parser, funcName}, args) => {
const body = args[0];
return {
return new ParseNode("lap", {
type: "lap",
alignment: context.funcName.slice(5),
alignment: funcName.slice(5),
body: body,
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
// mathllap, mathrlap, mathclap

View File

@@ -1,6 +1,7 @@
// @flow
import defineFunction from "../defineFunction";
import ParseError from "../ParseError";
import ParseNode from "../ParseNode";
// Switching from text mode back to math mode
defineFunction({
@@ -12,8 +13,7 @@ defineFunction({
allowedInMath: false,
consumeMode: "math",
},
handler(context, args) {
const {funcName, parser} = context;
handler({funcName, parser}, args) {
const outerMode = parser.mode;
parser.switchMode("math");
const close = (funcName === "\\(" ? "\\)" : "$");
@@ -23,11 +23,11 @@ defineFunction({
parser.expect(close, false);
parser.switchMode(outerMode);
parser.consume();
return {
return new ParseNode("styling", {
type: "styling",
style: "text",
value: body,
};
}, parser.mode);
},
});

View File

@@ -2,6 +2,8 @@
import defineFunction, {ordargument} from "../defineFunction";
import buildCommon from "../buildCommon";
import Style from "../Style";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -26,14 +28,14 @@ defineFunction({
props: {
numArgs: 4,
},
handler: (context, args) => {
return {
handler: ({parser}, args) => {
return new ParseNode("mathchoice", {
type: "mathchoice",
display: ordargument(args[0]),
text: ordargument(args[1]),
script: ordargument(args[2]),
scriptscript: ordargument(args[3]),
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
const body = chooseMathStyle(group, options);

View File

@@ -29,13 +29,13 @@ defineFunction({
props: {
numArgs: 1,
},
handler(context, args) {
handler({parser, funcName}, args) {
const body = args[0];
return {
return new ParseNode("mclass", {
type: "mclass",
mclass: "m" + context.funcName.substr(5),
mclass: "m" + funcName.substr(5),
value: ordargument(body),
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -48,12 +48,12 @@ defineFunction({
props: {
numArgs: 2,
},
handler(context, args) {
handler({parser, funcName}, args) {
const baseArg = args[1];
const shiftedArg = args[0];
let mclass = "mrel"; // default. May change below.
if (context.funcName !== "\\stackrel") {
if (funcName !== "\\stackrel") {
// LaTeX applies \binrel spacing to \overset and \underset. \binrel
// spacing varies with (bin|rel|ord) of the atom in the argument.
// We'll do the same.
@@ -78,22 +78,22 @@ defineFunction({
limits: true,
alwaysHandleSupSub: true,
symbol: false,
suppressBaseShift: context.funcName !== "\\stackrel",
suppressBaseShift: funcName !== "\\stackrel",
value: ordargument(baseArg),
}, baseArg.mode);
const supsub = new ParseNode("supsub", {
type: "supsub",
base: baseOp,
sup: context.funcName === "\\underset" ? null : shiftedArg,
sub: context.funcName === "\\underset" ? shiftedArg : null,
sup: funcName === "\\underset" ? null : shiftedArg,
sub: funcName === "\\underset" ? shiftedArg : null,
}, shiftedArg.mode);
return {
return new ParseNode("mclass", {
type: "mclass",
mclass: mclass,
value: [supsub],
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,

View File

@@ -6,12 +6,11 @@ import domTree from "../domTree";
import mathMLTree from "../mathMLTree";
import utils from "../utils";
import Style from "../Style";
import {assertNodeType, checkNodeType} from "../ParseNode";
import ParseNode, {assertNodeType, checkNodeType} from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import type ParseNode from "../ParseNode";
import type {HtmlBuilderSupSub, MathMLBuilder} from "../defineFunction";
// NOTE: Unlike most `htmlBuilder`s, this one handles not only "op", but also
@@ -263,17 +262,17 @@ defineFunction({
props: {
numArgs: 0,
},
handler: (context, args) => {
let fName = context.funcName;
handler: ({parser, funcName}, args) => {
let fName = funcName;
if (fName.length === 1) {
fName = singleCharBigOps[fName];
}
return {
return new ParseNode("op", {
type: "op",
limits: true,
symbol: true,
body: fName,
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -287,14 +286,14 @@ defineFunction({
props: {
numArgs: 1,
},
handler: (context, args) => {
handler: ({parser}, args) => {
const body = args[0];
return {
return new ParseNode("op", {
type: "op",
limits: false,
symbol: false,
value: ordargument(body),
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -317,14 +316,14 @@ defineFunction({
props: {
numArgs: 1,
},
handler: (context, args) => {
handler: ({parser}, args) => {
const body = args[0];
return {
return new ParseNode("op", {
type: "op",
limits: false,
symbol: false,
value: ordargument(body),
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -343,13 +342,13 @@ defineFunction({
props: {
numArgs: 0,
},
handler(context) {
return {
handler({parser, funcName}) {
return new ParseNode("op", {
type: "op",
limits: false,
symbol: false,
body: context.funcName,
};
body: funcName,
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -364,13 +363,13 @@ defineFunction({
props: {
numArgs: 0,
},
handler(context) {
return {
handler({parser, funcName}) {
return new ParseNode("op", {
type: "op",
limits: true,
symbol: false,
body: context.funcName,
};
body: funcName,
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,
@@ -386,17 +385,17 @@ defineFunction({
props: {
numArgs: 0,
},
handler(context) {
let fName = context.funcName;
handler({parser, funcName}) {
let fName = funcName;
if (fName.length === 1) {
fName = singleCharIntegrals[fName];
}
return {
return new ParseNode("op", {
type: "op",
limits: false,
symbol: true,
body: fName,
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder,

View File

@@ -16,12 +16,12 @@ defineFunction({
props: {
numArgs: 1,
},
handler: (context, args) => {
handler: ({parser}, args) => {
const body = args[0];
return {
return new ParseNode("operatorname", {
type: "operatorname",
value: ordargument(body),
};
}, parser.mode);
},
htmlBuilder: (group, options) => {

View File

@@ -2,6 +2,7 @@
import defineFunction from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -12,12 +13,12 @@ defineFunction({
props: {
numArgs: 1,
},
handler(context, args) {
handler({parser}, args) {
const body = args[0];
return {
return new ParseNode("overline", {
type: "overline",
body: body,
};
}, parser.mode);
},
htmlBuilder(group, options) {
// Overlines are handled in the TeXbook pg 443, Rule 9.

View File

@@ -2,6 +2,7 @@
import defineFunction, {ordargument} from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -12,12 +13,12 @@ defineFunction({
props: {
numArgs: 1,
},
handler: (context, args) => {
handler: ({parser}, args) => {
const body = args[0];
return {
return new ParseNode("phantom", {
type: "phantom",
value: ordargument(body),
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
const elements = html.buildExpression(
@@ -42,13 +43,13 @@ defineFunction({
props: {
numArgs: 1,
},
handler: (context, args) => {
handler: ({parser}, args) => {
const body = args[0];
return {
return new ParseNode("hphantom", {
type: "hphantom",
value: ordargument(body),
body: body,
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
let node = buildCommon.makeSpan(
@@ -84,13 +85,13 @@ defineFunction({
props: {
numArgs: 1,
},
handler: (context, args) => {
handler: ({parser}, args) => {
const body = args[0];
return {
return new ParseNode("vphantom", {
type: "vphantom",
value: ordargument(body),
body: body,
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
const inner = buildCommon.makeSpan(

View File

@@ -17,15 +17,15 @@ defineFunction({
argTypes: ["size", "text"],
allowedInText: true,
},
handler(context, args) {
handler({parser}, args) {
const amount = assertNodeType(args[0], "size");
const body = args[1];
return {
return new ParseNode("raisebox", {
type: "raisebox",
dy: amount,
body: body,
value: ordargument(body),
};
}, parser.mode);
},
htmlBuilder(group, options) {
const text = new ParseNode("text", {

View File

@@ -2,7 +2,7 @@
import buildCommon from "../buildCommon";
import defineFunction from "../defineFunction";
import mathMLTree from "../mathMLTree";
import {assertNodeType} from "../ParseNode";
import ParseNode, {assertNodeType} from "../ParseNode";
import {calculateSize} from "../units";
defineFunction({
@@ -13,16 +13,16 @@ defineFunction({
numOptionalArgs: 1,
argTypes: ["size", "size", "size"],
},
handler(context, args, optArgs) {
handler({parser}, args, optArgs) {
const shift = optArgs[0];
const width = assertNodeType(args[0], "size");
const height = assertNodeType(args[1], "size");
return {
return new ParseNode("rule", {
type: "rule",
shift: shift && shift.value,
width: width.value.value,
height: height.value.value,
};
}, parser.mode);
},
htmlBuilder(group, options) {
// Make an empty span for the rule

View File

@@ -3,6 +3,7 @@ import buildCommon from "../buildCommon";
import defineFunction from "../defineFunction";
import mathMLTree from "../mathMLTree";
import utils from "../utils";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -55,18 +56,16 @@ defineFunction({
numArgs: 0,
allowedInText: true,
},
handler: (context, args) => {
const {breakOnTokenText, funcName, parser} = context;
handler: ({breakOnTokenText, funcName, parser}, args) => {
parser.consumeSpaces();
const body = parser.parseExpression(false, breakOnTokenText);
return {
return new ParseNode("sizing", {
type: "sizing",
// Figure out what size to use based on the list of functions above
size: utils.indexOf(sizeFuncs, funcName) + 1,
value: body,
};
}, parser.mode);
},
htmlBuilder,
mathmlBuilder: (group, options) => {

View File

@@ -3,6 +3,7 @@
import defineFunction from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -15,7 +16,7 @@ defineFunction({
numOptionalArgs: 1,
allowedInText: true,
},
handler: (context, args, optArgs) => {
handler: ({parser}, args, optArgs) => {
let smashHeight = false;
let smashDepth = false;
const tbArg = optArgs[0];
@@ -42,12 +43,12 @@ defineFunction({
}
const body = args[0];
return {
return new ParseNode("smash", {
type: "smash",
body: body,
smashHeight: smashHeight,
smashDepth: smashDepth,
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
const node = buildCommon.makeSpan(

View File

@@ -5,6 +5,7 @@ import domTree from "../domTree";
import mathMLTree from "../mathMLTree";
import delimiter from "../delimiter";
import Style from "../Style";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -16,14 +17,14 @@ defineFunction({
numArgs: 1,
numOptionalArgs: 1,
},
handler(context, args, optArgs) {
handler({parser}, args, optArgs) {
const index = optArgs[0];
const body = args[0];
return {
return new ParseNode("sqrt", {
type: "sqrt",
body: body,
index: index,
};
}, parser.mode);
},
htmlBuilder(group, options) {
// Square roots are handled in the TeXbook pg. 443, Rule 11.

View File

@@ -3,6 +3,7 @@ import defineFunction from "../defineFunction";
import mathMLTree from "../mathMLTree";
import Style from "../Style";
import {sizingGroup} from "./sizing";
import ParseNode from "../ParseNode";
import * as mml from "../buildMathML";
@@ -23,9 +24,7 @@ defineFunction({
numArgs: 0,
allowedInText: true,
},
handler: (context, args) => {
const {breakOnTokenText, funcName, parser} = context;
handler: ({breakOnTokenText, funcName, parser}, args) => {
// parse out the implicit body
parser.consumeSpaces();
const body = parser.parseExpression(true, breakOnTokenText);
@@ -34,13 +33,13 @@ defineFunction({
// here and in buildHTML and de-dupe the enumeration of all the styles).
// $FlowFixMe: The names above exactly match the styles.
const style: StyleStr = funcName.slice(1, funcName.length - 5);
return {
return new ParseNode("styling", {
type: "styling",
// Figure out what style to use by pulling out the style from
// the function name
style,
value: body,
};
}, parser.mode);
},
htmlBuilder: (group, options) => {
// Style changes are handled in the TeXbook on pg. 442, Rule 3.

View File

@@ -1,6 +1,7 @@
// @flow
import defineFunction, {ordargument} from "../defineFunction";
import buildCommon from "../buildCommon";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -36,13 +37,13 @@ defineFunction({
allowedInText: true,
consumeMode: "text",
},
handler(context, args) {
handler({parser, funcName}, args) {
const body = args[0];
return {
return new ParseNode("text", {
type: "text",
body: ordargument(body),
font: context.funcName,
};
font: funcName,
}, parser.mode);
},
htmlBuilder(group, options) {
const font = group.value.font;

View File

@@ -2,6 +2,7 @@
import defineFunction from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import ParseNode from "../ParseNode";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -13,12 +14,12 @@ defineFunction({
numArgs: 1,
allowedInText: true,
},
handler(context, args) {
handler({parser}, args) {
const body = args[0];
return {
return new ParseNode("underline", {
type: "underline",
body: body,
};
}, parser.mode);
},
htmlBuilder(group, options) {
// Underlines are handled in the TeXbook pg 443, Rule 10.