Spaces:
Sleeping
Sleeping
| 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 | null | undefined)[], | |
| ) => 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 environment 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 extends 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: Record<string, EnvSpec<any>> = {}; | |
| type EnvDefSpec<NODETYPE extends 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 extends 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; | |
| } | |
| } | |