From b738e3f4d71613eb6758611d1501e92e086fea96 Mon Sep 17 00:00:00 2001 From: Ashish Myles Date: Wed, 30 May 2018 22:49:44 -0400 Subject: [PATCH] Separate parsing of \left and \right for improved type safety. (#1386) --- src/ParseNode.js | 5 +-- src/functions/delimsizing.js | 67 ++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/ParseNode.js b/src/ParseNode.js index 6e47f14a..40a33a7c 100644 --- a/src/ParseNode.js +++ b/src/ParseNode.js @@ -203,8 +203,9 @@ export type ParseNodeTypes = { alignment: string, body: ParseNode<*>, |}, - "leftright": LeftRightDelimType | {| - type: "leftright", + "leftright": LeftRightDelimType, + "leftright-right": {| + type: "leftright-right", value: string, |}, "mathchoice": {| diff --git a/src/functions/delimsizing.js b/src/functions/delimsizing.js index 7b7f3388..2483da7e 100644 --- a/src/functions/delimsizing.js +++ b/src/functions/delimsizing.js @@ -5,6 +5,7 @@ import delimiter from "../delimiter"; import mathMLTree from "../mathMLTree"; import ParseError from "../ParseError"; import utils from "../utils"; +import {assertNodeType} from "../ParseNode"; import * as html from "../buildHTML"; import * as mml from "../buildMathML"; @@ -132,45 +133,51 @@ function leftRightGroupValue(group: ParseNode<"leftright">): LeftRightDelimType } +defineFunction({ + type: "leftright-right", + names: ["\\right"], + props: { + numArgs: 1, + }, + handler: (context, args) => { + // \left case below triggers parsing of \right in + // `const right = parser.parseFunction();` + // uses this return value. + return { + type: "leftright-right", + value: checkDelimiter(args[0], context).value, + }; + }, +}); + + defineFunction({ type: "leftright", - names: [ - "\\left", "\\right", - ], + names: ["\\left"], props: { numArgs: 1, }, handler: (context, args) => { const delim = checkDelimiter(args[0], context); - if (context.funcName === "\\left") { - const parser = context.parser; - // Parse out the implicit body - ++parser.leftrightDepth; - // parseExpression stops before '\\right' - const body = parser.parseExpression(false); - --parser.leftrightDepth; - // Check the next token - parser.expect("\\right", false); - const right = parser.parseFunction(); - if (!right) { - throw new ParseError('failed to parse function after \\right'); - } - return { - type: "leftright", - body: body, - left: delim.value, - right: right.value.value, - }; - } else { - // This is a little weird. We return this object which gets turned - // into a ParseNode which gets returned by - // `const right = parser.parseFunction();` up above. - return { - type: "leftright", - value: delim.value, - }; + const parser = context.parser; + // Parse out the implicit body + ++parser.leftrightDepth; + // parseExpression stops before '\\right' + const body = parser.parseExpression(false); + --parser.leftrightDepth; + // Check the next token + parser.expect("\\right", false); + const right = parser.parseFunction(); + if (!right) { + throw new ParseError('failed to parse function after \\right'); } + return { + type: "leftright", + body: body, + left: delim.value, + right: assertNodeType(right, "leftright-right").value.value, + }; }, htmlBuilder: (group, options) => { const groupValue = leftRightGroupValue(group);