1 | // @flow
|
2 | import {_htmlGroupBuilders, _mathmlGroupBuilders} from "./defineFunction";
|
3 |
|
4 | import type Parser from "./Parser";
|
5 | import type {AnyParseNode} from "./parseNode";
|
6 | import type {ArgType, Mode} from "./types";
|
7 | import type {NodeType} from "./parseNode";
|
8 | import type {HtmlBuilder, MathMLBuilder} from "./defineFunction";
|
9 |
|
10 | /**
|
11 | * The context contains the following properties:
|
12 | * - mode: current parsing mode.
|
13 | * - envName: the name of the environment, one of the listed names.
|
14 | * - parser: the parser object.
|
15 | */
|
16 | type EnvContext = {|
|
17 | mode: Mode,
|
18 | envName: string,
|
19 | parser: Parser,
|
20 | |};
|
21 |
|
22 | /**
|
23 | * - context: information and references provided by the parser
|
24 | * - args: an array of arguments passed to \begin{name}
|
25 | * - optArgs: an array of optional arguments passed to \begin{name}
|
26 | */
|
27 | type EnvHandler = (
|
28 | context: EnvContext,
|
29 | args: AnyParseNode[],
|
30 | optArgs: (?AnyParseNode)[],
|
31 | ) => AnyParseNode;
|
32 |
|
33 | /**
|
34 | * - numArgs: (default 0) The number of arguments after the \begin{name} function.
|
35 | * - argTypes: (optional) Just like for a function
|
36 | * - allowedInText: (default false) Whether or not the environment is allowed
|
37 | * inside text mode (not enforced yet).
|
38 | * - numOptionalArgs: (default 0) Just like for a function
|
39 | */
|
40 | type EnvProps = {
|
41 | numArgs: number,
|
42 | };
|
43 |
|
44 | /**
|
45 | * Final enviornment spec for use at parse time.
|
46 | * This is almost identical to `EnvDefSpec`, except it
|
47 | * 1. includes the function handler
|
48 | * 2. requires all arguments except argType
|
49 | * It is generated by `defineEnvironment()` below.
|
50 | */
|
51 | export type EnvSpec<NODETYPE: NodeType> = {|
|
52 | type: NODETYPE, // Need to use the type to avoid error. See NOTES below.
|
53 | numArgs: number,
|
54 | argTypes?: ArgType[],
|
55 | greediness: number,
|
56 | allowedInText: boolean,
|
57 | numOptionalArgs: number,
|
58 | handler: EnvHandler,
|
59 | |};
|
60 |
|
61 | /**
|
62 | * All registered environments.
|
63 | * `environments.js` exports this same dictionary again and makes it public.
|
64 | * `Parser.js` requires this dictionary via `environments.js`.
|
65 | */
|
66 | export const _environments: {[string]: EnvSpec<*>} = {};
|
67 |
|
68 | type EnvDefSpec<NODETYPE: NodeType> = {|
|
69 | // Unique string to differentiate parse nodes.
|
70 | type: NODETYPE,
|
71 |
|
72 | // List of functions which use the give handler, htmlBuilder,
|
73 | // and mathmlBuilder.
|
74 | names: Array<string>,
|
75 |
|
76 | // Properties that control how the environments are parsed.
|
77 | props: EnvProps,
|
78 |
|
79 | handler: EnvHandler,
|
80 |
|
81 | // This function returns an object representing the DOM structure to be
|
82 | // created when rendering the defined LaTeX function.
|
83 | htmlBuilder: HtmlBuilder<NODETYPE>,
|
84 |
|
85 | // This function returns an object representing the MathML structure to be
|
86 | // created when rendering the defined LaTeX function.
|
87 | mathmlBuilder: MathMLBuilder<NODETYPE>,
|
88 | |};
|
89 |
|
90 | export default function defineEnvironment<NODETYPE: NodeType>({
|
91 | type,
|
92 | names,
|
93 | props,
|
94 | handler,
|
95 | htmlBuilder,
|
96 | mathmlBuilder,
|
97 | }: EnvDefSpec<NODETYPE>) {
|
98 | // Set default values of environments.
|
99 | const data = {
|
100 | type,
|
101 | numArgs: props.numArgs || 0,
|
102 | greediness: 1,
|
103 | allowedInText: false,
|
104 | numOptionalArgs: 0,
|
105 | handler,
|
106 | };
|
107 | for (let i = 0; i < names.length; ++i) {
|
108 | // TODO: The value type of _environments should be a type union of all
|
109 | // possible `EnvSpec<>` possibilities instead of `EnvSpec<*>`, which is
|
110 | // an existential type.
|
111 | // $FlowFixMe
|
112 | _environments[names[i]] = data;
|
113 | }
|
114 | if (htmlBuilder) {
|
115 | _htmlGroupBuilders[type] = htmlBuilder;
|
116 | }
|
117 | if (mathmlBuilder) {
|
118 | _mathmlGroupBuilders[type] = mathmlBuilder;
|
119 | }
|
120 | }
|