* Parses an "expression", which is a list of atoms. * * `breakOnInfix`: Should the parsing stop when we hit infix nodes? This * happens when functions have higher precedence than infix * nodes in implicit parses. * * `breakOnTokenText`: T
(
breakOnInfix: boolean,
breakOnTokenText?: BreakToken,
)
| 187 | * expression. |
| 188 | */ |
| 189 | parseExpression( |
| 190 | breakOnInfix: boolean, |
| 191 | breakOnTokenText?: BreakToken, |
| 192 | ): AnyParseNode[] { |
| 193 | const body = []; |
| 194 | // Keep adding atoms to the body until we can't parse any more atoms (either |
| 195 | // we reached the end, a }, or a \right) |
| 196 | while (true) { |
| 197 | // Ignore spaces in math mode |
| 198 | if (this.mode === "math") { |
| 199 | this.consumeSpaces(); |
| 200 | } |
| 201 | const lex = this.fetch(); |
| 202 | if (Parser.endOfExpression.has(lex.text)) { |
| 203 | break; |
| 204 | } |
| 205 | if (breakOnTokenText && lex.text === breakOnTokenText) { |
| 206 | break; |
| 207 | } |
| 208 | if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) { |
| 209 | break; |
| 210 | } |
| 211 | const atom = this.parseAtom(breakOnTokenText); |
| 212 | if (!atom) { |
| 213 | break; |
| 214 | } else if (atom.type === "internal") { |
| 215 | // Internal nodes do not appear in parse tree |
| 216 | continue; |
| 217 | } |
| 218 | body.push(atom); |
| 219 | } |
| 220 | if (this.mode === "text") { |
| 221 | this.formLigatures(body); |
| 222 | } |
| 223 | return this.handleInfixNodes(body); |
| 224 | } |
| 225 | |
| 226 | /** |
| 227 | * Rewrites infix operators such as \over with corresponding commands such |
no test coverage detected