1 |
|
2 | import defineFunction from "../defineFunction";
|
3 | import ParseError from "../ParseError";
|
4 | import {assertNodeType} from "../parseNode";
|
5 | import environments from "../environments";
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | defineFunction({
|
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 |
|
29 | if (!environments.hasOwnProperty(envName)) {
|
30 | throw new ParseError(
|
31 | "No such environment: " + envName, nameGroup);
|
32 | }
|
33 |
|
34 |
|
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 | });
|