UNPKG

2.24 kBJavaScriptView Raw
1// @flow
2import defineFunction from "../defineFunction";
3import ParseError from "../ParseError";
4import {assertNodeType} from "../parseNode";
5import environments from "../environments";
6
7// Environment delimiters. HTML/MathML rendering is defined in the corresponding
8// defineEnvironment definitions.
9// $FlowFixMe, "environment" handler returns an environment ParseNode
10defineFunction({
11 type: "environment",
12 names: ["\\begin", "\\end"],
13 props: {
14 numArgs: 1,
15 argTypes: ["text"],
16 },
17 handler({parser, funcName}, args) {
18 const nameGroup = args[0];
19 if (nameGroup.type !== "ordgroup") {
20 throw new ParseError("Invalid environment name", nameGroup);
21 }
22 let envName = "";
23 for (let i = 0; i < nameGroup.body.length; ++i) {
24 envName += assertNodeType(nameGroup.body[i], "textord").text;
25 }
26
27 if (funcName === "\\begin") {
28 // begin...end is similar to left...right
29 if (!environments.hasOwnProperty(envName)) {
30 throw new ParseError(
31 "No such environment: " + envName, nameGroup);
32 }
33 // Build the environment object. Arguments and other information will
34 // be made available to the begin and end methods using properties.
35 const env = environments[envName];
36 const {args, optArgs} =
37 parser.parseArguments("\\begin{" + envName + "}", env);
38 const context = {
39 mode: parser.mode,
40 envName,
41 parser,
42 };
43 const result = env.handler(context, args, optArgs);
44 parser.expect("\\end", false);
45 const endNameToken = parser.nextToken;
46 const end = assertNodeType(parser.parseFunction(), "environment");
47 if (end.name !== envName) {
48 throw new ParseError(
49 `Mismatch: \\begin{${envName}} matched by \\end{${end.name}}`,
50 endNameToken);
51 }
52 return result;
53 }
54
55 return {
56 type: "environment",
57 mode: parser.mode,
58 name: envName,
59 nameGroup,
60 };
61 },
62});