mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-06 19:58:40 +00:00
Port environments.js to @flow. (#862)
* Port environment.js to @flow. * Updated per comments.
This commit is contained in:
committed by
Kevin Barabash
parent
b4a00824d3
commit
1c344ed6ee
@@ -1,18 +1,96 @@
|
||||
/* eslint no-constant-condition:0 */
|
||||
// @flow
|
||||
import ParseNode from "./ParseNode";
|
||||
import ParseError from "./ParseError";
|
||||
|
||||
import type Parser from "./Parser";
|
||||
import type {ArgType, Mode, StyleStr} from "./types";
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* - positions: the positions associated with these arguments from args.
|
||||
*/
|
||||
type EnvContext = {
|
||||
mode: Mode,
|
||||
envName: string,
|
||||
parser: Parser,
|
||||
positions: number[],
|
||||
};
|
||||
|
||||
/**
|
||||
* List of ParseNodes followed by an array of positions.
|
||||
* Returned by `Parser`'s `parseArguments`.
|
||||
*/
|
||||
type ParseResult = (ParseNode | number[])[] | ParseNode;
|
||||
|
||||
/**
|
||||
* The handler function receives two arguments
|
||||
* - context: information and references provided by the parser
|
||||
* - args: an array of arguments passed to \begin{name}
|
||||
*/
|
||||
type EnvHandler = (context: EnvContext, args: ParseNode[]) => ParseResult;
|
||||
|
||||
/**
|
||||
* - 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,
|
||||
argTypes?: ArgType[],
|
||||
allowedInText?: boolean,
|
||||
numOptionalArgs?: number,
|
||||
};
|
||||
|
||||
type EnvData = {
|
||||
numArgs: number,
|
||||
argTypes?: ArgType[],
|
||||
greediness: number,
|
||||
allowedInText: boolean,
|
||||
numOptionalArgs: number,
|
||||
handler: EnvHandler,
|
||||
};
|
||||
const environments: {[string]: EnvData} = {};
|
||||
export default environments;
|
||||
|
||||
// Data stored in the ParseNode associated with the environment.
|
||||
type AlignSpec = { type: "separator", separator: string } | {
|
||||
type: "align",
|
||||
align: string,
|
||||
pregap?: number,
|
||||
postgap?: number,
|
||||
};
|
||||
type ArrayEnvNodeData = {
|
||||
type: "array",
|
||||
hskipBeforeAndAfter?: boolean,
|
||||
arraystretch?: number,
|
||||
addJot?: boolean,
|
||||
cols?: AlignSpec[],
|
||||
// These fields are always set, but not on struct construction
|
||||
// initialization.
|
||||
body?: ParseNode[][], // List of rows in the (2D) array.
|
||||
rowGaps?: number[],
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the body of the environment, with rows delimited by \\ and
|
||||
* columns delimited by &, and create a nested list in row-major order
|
||||
* with one group per cell. If given an optional argument style
|
||||
* ("text", "display", etc.), then each cell is cast into that style.
|
||||
*/
|
||||
function parseArray(parser, result, style) {
|
||||
function parseArray(
|
||||
parser: Parser,
|
||||
result: ArrayEnvNodeData,
|
||||
style: StyleStr,
|
||||
) {
|
||||
let row = [];
|
||||
const body = [row];
|
||||
const rowGaps = [];
|
||||
while (true) {
|
||||
for (;;) {
|
||||
let cell = parser.parseExpression(false, null);
|
||||
cell = new ParseNode("ordgroup", cell, parser.mode);
|
||||
if (style) {
|
||||
@@ -42,36 +120,17 @@ function parseArray(parser, result, style) {
|
||||
return new ParseNode(result.type, result, parser.mode);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* An environment definition is very similar to a function definition:
|
||||
* it is declared with a name or a list of names, a set of properties
|
||||
* and a handler containing the actual implementation.
|
||||
*
|
||||
* The properties include:
|
||||
* - numArgs: The number of arguments after the \begin{name} function.
|
||||
* - argTypes: (optional) Just like for a function
|
||||
* - allowedInText: (optional) Whether or not the environment is allowed inside
|
||||
* text mode (default false) (not enforced yet)
|
||||
* - numOptionalArgs: (optional) Just like for a function
|
||||
* A bare number instead of that object indicates the numArgs value.
|
||||
*
|
||||
* The handler function will receive two arguments
|
||||
* - context: information and references provided by the parser
|
||||
* - args: an array of arguments passed to \begin{name}
|
||||
* The context contains the following properties:
|
||||
* - envName: the name of the environment, one of the listed names.
|
||||
* - parser: the parser object
|
||||
* - lexer: the lexer object
|
||||
* - positions: the positions associated with these arguments from args.
|
||||
* The handler must return a ParseResult.
|
||||
* it is declared with a list of names, a set of properties and a handler
|
||||
* containing the actual implementation.
|
||||
*/
|
||||
function defineEnvironment(names, props, handler) {
|
||||
if (typeof names === "string") {
|
||||
names = [names];
|
||||
}
|
||||
if (typeof props === "number") {
|
||||
props = { numArgs: props };
|
||||
}
|
||||
function defineEnvironment(
|
||||
names: string[],
|
||||
props: EnvProps,
|
||||
handler: EnvHandler,
|
||||
) {
|
||||
// Set default values of environments
|
||||
const data = {
|
||||
numArgs: props.numArgs || 0,
|
||||
@@ -82,7 +141,7 @@ function defineEnvironment(names, props, handler) {
|
||||
handler: handler,
|
||||
};
|
||||
for (let i = 0; i < names.length; ++i) {
|
||||
module.exports[names[i]] = data;
|
||||
environments[names[i]] = data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +266,7 @@ defineEnvironment([
|
||||
// except it operates within math mode.
|
||||
// Note that we assume \nomallineskiplimit to be zero,
|
||||
// so that \strut@ is the same as \strut.
|
||||
defineEnvironment("aligned", {
|
||||
defineEnvironment(["aligned"], {
|
||||
}, function(context) {
|
||||
let res = {
|
||||
type: "array",
|
||||
@@ -252,7 +311,7 @@ defineEnvironment("aligned", {
|
||||
// A gathered environment is like an array environment with one centered
|
||||
// column, but where rows are considered lines so get \jot line spacing
|
||||
// and contents are set in \displaystyle.
|
||||
defineEnvironment("gathered", {
|
||||
defineEnvironment(["gathered"], {
|
||||
}, function(context) {
|
||||
let res = {
|
||||
type: "array",
|
||||
|
@@ -16,3 +16,6 @@ export type Mode = "math" | "text";
|
||||
// first argument is special and the second
|
||||
// argument is parsed normally)
|
||||
export type ArgType = "color" | "size" | "original";
|
||||
|
||||
// LaTeX display style.
|
||||
export type StyleStr = "text" | "display";
|
||||
|
Reference in New Issue
Block a user