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