katex 0.16.47 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -10
- package/cli.js +6 -9
- package/contrib/auto-render/index.html +1 -1
- package/contrib/copy-tex/README.md +3 -3
- package/contrib/copy-tex/index.html +1 -1
- package/contrib/mathtex-script-type/README.md +5 -5
- package/contrib/mhchem/README.md +1 -1
- package/contrib/render-a11y-string/render-a11y-string.ts +1 -1
- package/dist/README.md +5 -10
- package/dist/contrib/render-a11y-string.js +15 -40
- package/dist/contrib/render-a11y-string.min.js +1 -1
- package/dist/contrib/render-a11y-string.mjs +13 -33
- package/dist/katex-swap.css +159 -164
- package/dist/katex-swap.min.css +1 -1
- package/dist/katex.css +159 -164
- package/dist/katex.js +509 -849
- package/dist/katex.min.css +1 -1
- package/dist/katex.min.js +1 -1
- package/dist/katex.mjs +498 -831
- package/katex.ts +1 -1
- package/package.json +12 -16
- package/src/MacroExpander.ts +11 -8
- package/src/Namespace.ts +17 -21
- package/src/Options.ts +2 -2
- package/src/ParseError.ts +1 -1
- package/src/Parser.ts +44 -50
- package/src/Settings.ts +1 -1
- package/src/SourceLocation.ts +2 -2
- package/src/atoms.ts +22 -22
- package/src/buildCommon.ts +8 -8
- package/src/buildHTML.ts +12 -13
- package/src/buildMathML.ts +4 -4
- package/src/buildTree.ts +1 -1
- package/src/defineEnvironment.ts +1 -2
- package/src/defineFunction.ts +104 -112
- package/src/environments/array.ts +11 -15
- package/src/environments/cd.ts +8 -8
- package/src/fontMetrics.ts +2 -4
- package/src/functions/accent.ts +12 -15
- package/src/functions/accentunder.ts +4 -4
- package/src/functions/arrow.ts +5 -5
- package/src/functions/char.ts +3 -4
- package/src/functions/color.ts +10 -13
- package/src/functions/cr.ts +4 -6
- package/src/functions/def.ts +15 -19
- package/src/functions/delimsizing.ts +23 -23
- package/src/functions/enclose.ts +23 -34
- package/src/functions/environment.ts +5 -6
- package/src/functions/font.ts +15 -27
- package/src/functions/genfrac.ts +19 -23
- package/src/functions/hbox.ts +6 -6
- package/src/functions/horizBrace.ts +4 -4
- package/src/functions/href.ts +10 -11
- package/src/functions/html.ts +8 -8
- package/src/functions/htmlmathml.ts +5 -5
- package/src/functions/includegraphics.ts +7 -7
- package/src/functions/kern.ts +6 -6
- package/src/functions/lap.ts +11 -11
- package/src/functions/math.ts +8 -10
- package/src/functions/mathchoice.ts +5 -5
- package/src/functions/mclass.ts +16 -28
- package/src/functions/op.ts +16 -30
- package/src/functions/operatorname.ts +4 -4
- package/src/functions/overline.ts +4 -4
- package/src/functions/phantom.ts +10 -10
- package/src/functions/pmb.ts +5 -5
- package/src/functions/raisebox.ts +5 -5
- package/src/functions/relax.ts +4 -5
- package/src/functions/rule.ts +8 -8
- package/src/functions/sizing.ts +7 -7
- package/src/functions/smash.ts +6 -6
- package/src/functions/sqrt.ts +5 -5
- package/src/functions/styling.ts +5 -5
- package/src/functions/supsub.ts +1 -1
- package/src/functions/symbolsOrd.ts +3 -3
- package/src/functions/symbolsSpacing.ts +21 -22
- package/src/functions/text.ts +7 -7
- package/src/functions/underline.ts +5 -5
- package/src/functions/utils/assembleSupSub.ts +1 -1
- package/src/functions/vcenter.ts +5 -5
- package/src/functions/verb.ts +5 -5
- package/src/macros.ts +3 -3
- package/src/mathMLTree.ts +6 -10
- package/src/parseNode.ts +6 -480
- package/src/parseTree.ts +1 -6
- package/src/spacingData.ts +2 -1
- package/src/stretchy.ts +3 -3
- package/src/styles/katex.scss +31 -37
- package/src/types/index.ts +12 -0
- package/src/types/nodes.ts +456 -0
- package/src/units.ts +1 -2
- package/src/utils.ts +1 -1
- package/src/wide-character.ts +2 -2
package/src/buildHTML.ts
CHANGED
|
@@ -8,15 +8,16 @@
|
|
|
8
8
|
import ParseError from "./ParseError";
|
|
9
9
|
import Style from "./Style";
|
|
10
10
|
import {makeGlue, makeSpan, tryCombineChars} from "./buildCommon";
|
|
11
|
-
import {
|
|
11
|
+
import type {DomSpan, HtmlDomNode} from "./domTree";
|
|
12
|
+
import {Anchor, Span} from "./domTree";
|
|
12
13
|
import {makeEm} from "./units";
|
|
13
14
|
import {spacings, tightSpacings} from "./spacingData";
|
|
14
15
|
import {_htmlGroupBuilders as groupBuilders} from "./defineFunction";
|
|
15
16
|
import {DocumentFragment} from "./tree";
|
|
16
17
|
|
|
17
18
|
import type Options from "./Options";
|
|
18
|
-
import type {AnyParseNode} from "./
|
|
19
|
-
import type {
|
|
19
|
+
import type {AnyParseNode} from "./types/nodes";
|
|
20
|
+
import type {Side} from "./types";
|
|
20
21
|
|
|
21
22
|
// Binary atoms (first class `mbin`) change into ordinary atoms (`mord`)
|
|
22
23
|
// depending on their surroundings. See TeXbook pg. 442-446, Rules 5 and 6,
|
|
@@ -35,8 +36,6 @@ const styleMap = {
|
|
|
35
36
|
"scriptscript": Style.SCRIPTSCRIPT,
|
|
36
37
|
};
|
|
37
38
|
|
|
38
|
-
type Side = "left" | "right";
|
|
39
|
-
|
|
40
39
|
const DomEnum = {
|
|
41
40
|
mord: "mord",
|
|
42
41
|
mop: "mop",
|
|
@@ -183,7 +182,7 @@ const traverseNonSpaceNodes = function(
|
|
|
183
182
|
|
|
184
183
|
if (nonspace) {
|
|
185
184
|
prev.node = node;
|
|
186
|
-
} else if (isRoot && node.hasClass("newline")) {
|
|
185
|
+
} else if (isRoot && node.hasClass("katex-newline")) {
|
|
187
186
|
prev.node = makeSpan(["leftmost"]); // treat like beginning of line
|
|
188
187
|
}
|
|
189
188
|
prev.insertAfter = (index => n => {
|
|
@@ -293,18 +292,18 @@ export const buildGroup = function(
|
|
|
293
292
|
|
|
294
293
|
/**
|
|
295
294
|
* Combine an array of HTML DOM nodes (e.g., the output of `buildExpression`)
|
|
296
|
-
* into an unbreakable HTML node of class .base, with proper struts to
|
|
295
|
+
* into an unbreakable HTML node of class .katex-base, with proper struts to
|
|
297
296
|
* guarantee correct vertical extent. `buildHTML` calls this repeatedly to
|
|
298
297
|
* make up the entire expression as a sequence of unbreakable units.
|
|
299
298
|
*/
|
|
300
299
|
function buildHTMLUnbreakable(children: HtmlDomNode[], options: Options) {
|
|
301
300
|
// Compute height and depth of this chunk.
|
|
302
|
-
const body = makeSpan(["base"], children, options);
|
|
301
|
+
const body = makeSpan(["katex-base"], children, options);
|
|
303
302
|
|
|
304
303
|
// Add strut, which ensures that the top of the HTML element falls at
|
|
305
304
|
// the height of the expression, and the bottom of the HTML element
|
|
306
305
|
// falls at the depth of the expression.
|
|
307
|
-
const strut = makeSpan(["strut"]);
|
|
306
|
+
const strut = makeSpan(["katex-strut"]);
|
|
308
307
|
strut.style.height = makeEm(body.height + body.depth);
|
|
309
308
|
if (body.depth) {
|
|
310
309
|
strut.style.verticalAlign = makeEm(-body.depth);
|
|
@@ -330,7 +329,7 @@ export default function buildHTML(tree: AnyParseNode[], options: Options): DomSp
|
|
|
330
329
|
const expression = buildExpression(tree, options, "root");
|
|
331
330
|
|
|
332
331
|
let eqnNum;
|
|
333
|
-
if (expression.length === 2 && expression[1].hasClass("tag")) {
|
|
332
|
+
if (expression.length === 2 && expression[1].hasClass("katex-tag")) {
|
|
334
333
|
// An environment with automatic equation numbers, e.g. {gather}.
|
|
335
334
|
eqnNum = expression.pop();
|
|
336
335
|
}
|
|
@@ -355,7 +354,7 @@ export default function buildHTML(tree: AnyParseNode[], options: Options): DomSp
|
|
|
355
354
|
let nobreak = false;
|
|
356
355
|
while (i < expression.length - 1 &&
|
|
357
356
|
expression[i + 1].hasClass("mspace") &&
|
|
358
|
-
!expression[i + 1].hasClass("newline")) {
|
|
357
|
+
!expression[i + 1].hasClass("katex-newline")) {
|
|
359
358
|
i++;
|
|
360
359
|
parts.push(expression[i]);
|
|
361
360
|
if (expression[i].hasClass("nobreak")) {
|
|
@@ -367,7 +366,7 @@ export default function buildHTML(tree: AnyParseNode[], options: Options): DomSp
|
|
|
367
366
|
children.push(buildHTMLUnbreakable(parts, options));
|
|
368
367
|
parts = [];
|
|
369
368
|
}
|
|
370
|
-
} else if (expression[i].hasClass("newline")) {
|
|
369
|
+
} else if (expression[i].hasClass("katex-newline")) {
|
|
371
370
|
// Write the line except the newline
|
|
372
371
|
parts.pop();
|
|
373
372
|
if (parts.length > 0) {
|
|
@@ -389,7 +388,7 @@ export default function buildHTML(tree: AnyParseNode[], options: Options): DomSp
|
|
|
389
388
|
buildExpression(tag, options, true),
|
|
390
389
|
options,
|
|
391
390
|
);
|
|
392
|
-
tagChild.classes = ["tag"];
|
|
391
|
+
tagChild.classes = ["katex-tag"];
|
|
393
392
|
children.push(tagChild);
|
|
394
393
|
} else if (eqnNum) {
|
|
395
394
|
children.push(eqnNum);
|
package/src/buildMathML.ts
CHANGED
|
@@ -12,11 +12,11 @@ import {_mathmlGroupBuilders as groupBuilders} from "./defineFunction";
|
|
|
12
12
|
import {MathNode, TextNode} from "./mathMLTree";
|
|
13
13
|
|
|
14
14
|
import type Options from "./Options";
|
|
15
|
-
import type {AnyParseNode, SymbolParseNode} from "./parseNode";
|
|
16
15
|
import type {DomSpan, HtmlDomNode} from "./domTree";
|
|
17
16
|
import type {MathDomNode} from "./mathMLTree";
|
|
18
17
|
import type {Mode} from "./types";
|
|
19
18
|
import type {FontVariant, MathFont} from "./types/fonts";
|
|
19
|
+
import type {AnyParseNode, SymbolParseNode} from "./types/nodes";
|
|
20
20
|
|
|
21
21
|
const noVariantSymbols = new Set(["\\imath", "\\jmath"]);
|
|
22
22
|
const rowLikeTypes = new Set(["mrow", "mtable"]);
|
|
@@ -32,9 +32,9 @@ export const makeText = function(
|
|
|
32
32
|
): TextNode {
|
|
33
33
|
if (symbols[mode][text] && symbols[mode][text].replace &&
|
|
34
34
|
text.charCodeAt(0) !== 0xD835 &&
|
|
35
|
-
!(
|
|
36
|
-
(
|
|
37
|
-
|
|
35
|
+
!(Object.prototype.hasOwnProperty.call(ligatures, text) &&
|
|
36
|
+
(options?.fontFamily?.slice(4, 6) === "tt" ||
|
|
37
|
+
options?.font?.slice(4, 6) === "tt"))) {
|
|
38
38
|
text = symbols[mode][text].replace!;
|
|
39
39
|
}
|
|
40
40
|
|
package/src/buildTree.ts
CHANGED
|
@@ -5,7 +5,7 @@ import Options from "./Options";
|
|
|
5
5
|
import Settings from "./Settings";
|
|
6
6
|
import Style from "./Style";
|
|
7
7
|
|
|
8
|
-
import type {AnyParseNode} from "./
|
|
8
|
+
import type {AnyParseNode} from "./types/nodes";
|
|
9
9
|
import type {DomSpan} from "./domTree";
|
|
10
10
|
|
|
11
11
|
const optionsFromSettings = function(settings: Settings) {
|
package/src/defineEnvironment.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {_htmlGroupBuilders, _mathmlGroupBuilders} from "./defineFunction";
|
|
2
2
|
|
|
3
3
|
import type Parser from "./Parser";
|
|
4
|
-
import type {AnyParseNode} from "./
|
|
4
|
+
import type {AnyParseNode, NodeType} from "./types/nodes";
|
|
5
5
|
import type {ArgType, Mode} from "./types";
|
|
6
|
-
import type {NodeType} from "./parseNode";
|
|
7
6
|
import type {HtmlBuilder, MathMLBuilder} from "./defineFunction";
|
|
8
7
|
|
|
9
8
|
/**
|
package/src/defineFunction.ts
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import type Parser from "./Parser";
|
|
2
|
-
import type {ParseNode, AnyParseNode, NodeType, UnsupportedCmdParseNode}
|
|
3
|
-
from "./parseNode";
|
|
4
2
|
import type Options from "./Options";
|
|
5
3
|
import type {ArgType, BreakToken} from "./types";
|
|
4
|
+
import type {AnyParseNode, NodeType, ParseNode, UnsupportedCmdParseNode} from "./types/nodes";
|
|
6
5
|
import type {HtmlDomNode} from "./domTree";
|
|
7
6
|
import type {Token} from "./Token";
|
|
8
7
|
import type {MathDomNode} from "./mathMLTree";
|
|
9
8
|
|
|
10
9
|
/** Context provided to function handlers for error messages. */
|
|
11
|
-
export type FunctionContext = {
|
|
12
|
-
funcName:
|
|
10
|
+
export type FunctionContext<FUNCNAME extends string = string> = {
|
|
11
|
+
funcName: FUNCNAME;
|
|
13
12
|
parser: Parser;
|
|
14
13
|
token?: Token;
|
|
15
14
|
breakOnTokenText?: BreakToken;
|
|
16
15
|
};
|
|
17
16
|
|
|
18
|
-
export type FunctionHandler<
|
|
19
|
-
|
|
17
|
+
export type FunctionHandler<
|
|
18
|
+
NODETYPE extends NodeType,
|
|
19
|
+
FUNCNAME extends string = string,
|
|
20
|
+
> = (
|
|
21
|
+
context: FunctionContext<FUNCNAME>,
|
|
20
22
|
args: AnyParseNode[],
|
|
21
|
-
optArgs: (AnyParseNode | null
|
|
23
|
+
optArgs: (AnyParseNode | null)[],
|
|
22
24
|
) => UnsupportedCmdParseNode | ParseNode<NODETYPE>;
|
|
23
25
|
// Note: reverse the order of the return type union will cause a flow error.
|
|
24
26
|
// See https://github.com/facebook/flow/issues/3663.
|
|
@@ -34,104 +36,109 @@ export type MathMLBuilder<NODETYPE extends NodeType> =
|
|
|
34
36
|
export type HtmlBuilderSupSub<NODETYPE extends NodeType> =
|
|
35
37
|
(group: ParseNode<"supsub"> | ParseNode<NODETYPE>, options: Options) => HtmlDomNode;
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Parser-facing function spec. Optional properties should use the defaults
|
|
41
|
+
* documented below.
|
|
42
|
+
*/
|
|
43
|
+
export type FunctionSpec<
|
|
44
|
+
NODETYPE extends NodeType,
|
|
45
|
+
FUNCNAME extends string = string,
|
|
46
|
+
> = {
|
|
47
|
+
/**
|
|
48
|
+
* Unique string to differentiate parse nodes.
|
|
49
|
+
* Also determines the type of the value returned by `handler`.
|
|
50
|
+
*/
|
|
51
|
+
type: NODETYPE;
|
|
52
|
+
|
|
53
|
+
/** The number of arguments the function takes. */
|
|
39
54
|
numArgs: number;
|
|
40
55
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
/**
|
|
57
|
+
* An array corresponding to each argument of the function, giving the
|
|
58
|
+
* type of argument that should be parsed. Its length should be equal
|
|
59
|
+
* to `numOptionalArgs + numArgs`, and types for optional arguments
|
|
60
|
+
* should appear before types for mandatory arguments.
|
|
61
|
+
*/
|
|
45
62
|
argTypes?: ArgType[];
|
|
46
63
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Whether it expands to a single token or a braced group of tokens.
|
|
66
|
+
* If it's grouped, it can be used as an argument to primitive commands,
|
|
67
|
+
* such as \sqrt (without the optional argument) and super/subscript.
|
|
68
|
+
* (default false)
|
|
69
|
+
*/
|
|
50
70
|
allowedInArgument?: boolean;
|
|
51
71
|
|
|
52
|
-
|
|
53
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Whether or not the function is allowed inside text mode
|
|
74
|
+
* (default false)
|
|
75
|
+
*/
|
|
54
76
|
allowedInText?: boolean;
|
|
55
77
|
|
|
56
|
-
|
|
57
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Whether or not the function is allowed inside math mode
|
|
80
|
+
* (default true)
|
|
81
|
+
*/
|
|
58
82
|
allowedInMath?: boolean;
|
|
59
83
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
84
|
+
/**
|
|
85
|
+
* The number of optional arguments the function should parse. If the
|
|
86
|
+
* optional arguments aren't found, `null` will be passed to the handler in
|
|
87
|
+
* their place.
|
|
88
|
+
* (default 0)
|
|
89
|
+
*/
|
|
64
90
|
numOptionalArgs?: number;
|
|
65
91
|
|
|
66
|
-
|
|
92
|
+
/** Must be true if the function is an infix operator. */
|
|
67
93
|
infix?: boolean;
|
|
68
94
|
|
|
69
|
-
|
|
95
|
+
/** Whether or not the function is a TeX primitive. */
|
|
70
96
|
primitive?: boolean;
|
|
71
|
-
};
|
|
72
97
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
names: Array<string>;
|
|
81
|
-
|
|
82
|
-
// Properties that control how the functions are parsed.
|
|
83
|
-
props: FunctionPropSpec;
|
|
84
|
-
|
|
85
|
-
// The handler is called to handle these functions and their arguments and
|
|
86
|
-
// returns a `ParseNode`.
|
|
87
|
-
handler: FunctionHandler<NODETYPE> | null | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* The handler is called to handle these functions and their arguments and
|
|
100
|
+
* returns a `ParseNode`. It must be specified unless it's handled directly
|
|
101
|
+
* in the parser.
|
|
102
|
+
*/
|
|
103
|
+
handler: FunctionHandler<NODETYPE, FUNCNAME> | null | undefined;
|
|
104
|
+
};
|
|
88
105
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Builder fields consumed during registration. These are stored separately in
|
|
108
|
+
* `_htmlGroupBuilders` and `_mathmlGroupBuilders`, and are not used by Parser.
|
|
109
|
+
*/
|
|
110
|
+
export type FunctionBuilders<NODETYPE extends NodeType> = {
|
|
111
|
+
/**
|
|
112
|
+
* This function returns an object representing the DOM structure to be
|
|
113
|
+
* created when rendering the defined LaTeX function.
|
|
114
|
+
* This should not modify the `ParseNode`.
|
|
115
|
+
*/
|
|
92
116
|
htmlBuilder?: HtmlBuilder<NODETYPE>;
|
|
93
117
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
118
|
+
/**
|
|
119
|
+
* This function returns an object representing the MathML structure to be
|
|
120
|
+
* created when rendering the defined LaTeX function.
|
|
121
|
+
* This should not modify the `ParseNode`.
|
|
122
|
+
*/
|
|
97
123
|
mathmlBuilder?: MathMLBuilder<NODETYPE>;
|
|
98
124
|
};
|
|
99
125
|
|
|
100
126
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* 2. requires all arguments except argTypes.
|
|
105
|
-
* It is generated by `defineFunction()` below.
|
|
127
|
+
* Full registration spec passed to `defineFunction`. It combines the
|
|
128
|
+
* parser-facing fields with optional builder fields and the names being
|
|
129
|
+
* registered.
|
|
106
130
|
*/
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
// FLOW TYPE NOTES: Doing either one of the following two
|
|
119
|
-
//
|
|
120
|
-
// - removing the NODETYPE type parameter in FunctionSpec above;
|
|
121
|
-
// - using ?FunctionHandler<NODETYPE> below;
|
|
122
|
-
//
|
|
123
|
-
// results in a confusing flow typing error:
|
|
124
|
-
// "string literal `styling`. This type is incompatible with..."
|
|
125
|
-
// pointing to the definition of `defineFunction` and finishing with
|
|
126
|
-
// "some incompatible instantiation of `NODETYPE`"
|
|
127
|
-
//
|
|
128
|
-
// Having FunctionSpec<NODETYPE> above and FunctionHandler<*> below seems to
|
|
129
|
-
// circumvent this error. This is not harmful for catching errors since
|
|
130
|
-
// _functions is typed FunctionSpec<*> (it stores all TeX function specs).
|
|
131
|
-
|
|
132
|
-
// Must be specified unless it's handled directly in the parser.
|
|
133
|
-
handler: FunctionHandler<NodeType> | null | undefined;
|
|
134
|
-
};
|
|
131
|
+
type FunctionDefSpec<
|
|
132
|
+
NODETYPE extends NodeType,
|
|
133
|
+
NAMES extends readonly string[],
|
|
134
|
+
> =
|
|
135
|
+
FunctionSpec<NODETYPE, NAMES[number]> & FunctionBuilders<NODETYPE> & {
|
|
136
|
+
/**
|
|
137
|
+
* The first argument to defineFunction is a single name or a list of names.
|
|
138
|
+
* All functions named in such a list will share a single implementation.
|
|
139
|
+
*/
|
|
140
|
+
names: NAMES;
|
|
141
|
+
};
|
|
135
142
|
|
|
136
143
|
/**
|
|
137
144
|
* All registered functions.
|
|
@@ -159,30 +166,17 @@ export const _htmlGroupBuilders: Record<string, HtmlBuilder<any>> = {};
|
|
|
159
166
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
160
167
|
export const _mathmlGroupBuilders: Record<string, MathMLBuilder<any>> = {};
|
|
161
168
|
|
|
162
|
-
export default function defineFunction<
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
mathmlBuilder
|
|
169
|
-
}: FunctionDefSpec<NODETYPE>) {
|
|
170
|
-
// Set default values of functions
|
|
171
|
-
const data = {
|
|
172
|
-
type,
|
|
173
|
-
numArgs: props.numArgs,
|
|
174
|
-
argTypes: props.argTypes,
|
|
175
|
-
allowedInArgument: !!props.allowedInArgument,
|
|
176
|
-
allowedInText: !!props.allowedInText,
|
|
177
|
-
allowedInMath: (props.allowedInMath === undefined)
|
|
178
|
-
? true
|
|
179
|
-
: props.allowedInMath,
|
|
180
|
-
numOptionalArgs: props.numOptionalArgs || 0,
|
|
181
|
-
infix: !!props.infix,
|
|
182
|
-
primitive: !!props.primitive,
|
|
183
|
-
handler,
|
|
184
|
-
};
|
|
169
|
+
export default function defineFunction<
|
|
170
|
+
NODETYPE extends NodeType,
|
|
171
|
+
const NAMES extends readonly string[],
|
|
172
|
+
>(
|
|
173
|
+
data: FunctionDefSpec<NODETYPE, NAMES>,
|
|
174
|
+
) {
|
|
175
|
+
const {type, names, htmlBuilder, mathmlBuilder} = data;
|
|
185
176
|
for (let i = 0; i < names.length; ++i) {
|
|
177
|
+
// To avoid destructuring and rebuilding an object,
|
|
178
|
+
// we store the entire FunctionDefSpec object,
|
|
179
|
+
// even though Parser only needs the FunctionSpec fields.
|
|
186
180
|
_functions[names[i]] = data;
|
|
187
181
|
}
|
|
188
182
|
if (type) {
|
|
@@ -207,14 +201,12 @@ export function defineFunctionBuilders<NODETYPE extends NodeType>({
|
|
|
207
201
|
htmlBuilder?: HtmlBuilder<NODETYPE>;
|
|
208
202
|
mathmlBuilder: MathMLBuilder<NODETYPE>;
|
|
209
203
|
}) {
|
|
210
|
-
|
|
211
|
-
type
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
mathmlBuilder,
|
|
217
|
-
});
|
|
204
|
+
if (htmlBuilder) {
|
|
205
|
+
_htmlGroupBuilders[type] = htmlBuilder;
|
|
206
|
+
}
|
|
207
|
+
if (mathmlBuilder) {
|
|
208
|
+
_mathmlGroupBuilders[type] = mathmlBuilder;
|
|
209
|
+
}
|
|
218
210
|
}
|
|
219
211
|
|
|
220
212
|
export const normalizeArgument = function(arg: AnyParseNode): AnyParseNode {
|
|
@@ -15,8 +15,8 @@ import * as html from "../buildHTML";
|
|
|
15
15
|
import * as mml from "../buildMathML";
|
|
16
16
|
|
|
17
17
|
import type Parser from "../Parser";
|
|
18
|
-
import type {ParseNode, AnyParseNode} from "../parseNode";
|
|
19
18
|
import type {StyleStr, Mode} from "../types";
|
|
19
|
+
import type {AnyParseNode, ParseNode} from "../types/nodes";
|
|
20
20
|
import type {HtmlBuilder, MathMLBuilder} from "../defineFunction";
|
|
21
21
|
import type {HtmlDomNode} from "../domTree";
|
|
22
22
|
|
|
@@ -520,8 +520,8 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
520
520
|
|
|
521
521
|
// Add \hline(s), if any.
|
|
522
522
|
if (hlines.length > 0) {
|
|
523
|
-
const line = makeLineSpan("hline", options, ruleThickness);
|
|
524
|
-
const dashes = makeLineSpan("hdashline", options, ruleThickness);
|
|
523
|
+
const line = makeLineSpan("katex-hline", options, ruleThickness);
|
|
524
|
+
const dashes = makeLineSpan("katex-hdashline", options, ruleThickness);
|
|
525
525
|
const vListElems = [{type: "elem" as const, elem: tableBody, shift: 0}];
|
|
526
526
|
while (hlines.length > 0) {
|
|
527
527
|
const hline = hlines.pop()!;
|
|
@@ -546,7 +546,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
546
546
|
positionType: "individualShift",
|
|
547
547
|
children: tagSpans,
|
|
548
548
|
}, options);
|
|
549
|
-
const tagCol = makeSpan(["tag"], [eqnNumCol], options);
|
|
549
|
+
const tagCol = makeSpan(["katex-tag"], [eqnNumCol], options);
|
|
550
550
|
return makeFragment([tableBody, tagCol]);
|
|
551
551
|
}
|
|
552
552
|
};
|
|
@@ -703,7 +703,6 @@ const alignedHandler = function(context: EnvContextLike, args: AnyParseNode[]) {
|
|
|
703
703
|
validateAmsEnvironmentContext(context);
|
|
704
704
|
}
|
|
705
705
|
const cols: AlignSpec[] = [];
|
|
706
|
-
const separationType: ColSeparationType = context.envName.includes("at") ? "alignat" : "align";
|
|
707
706
|
const isSplit = context.envName === "split";
|
|
708
707
|
const res = parseArray(context.parser,
|
|
709
708
|
{
|
|
@@ -711,7 +710,7 @@ const alignedHandler = function(context: EnvContextLike, args: AnyParseNode[]) {
|
|
|
711
710
|
addJot: true,
|
|
712
711
|
autoTag: isSplit ? undefined : getAutoTag(context.envName),
|
|
713
712
|
emptySingleRow: true,
|
|
714
|
-
colSeparationType:
|
|
713
|
+
colSeparationType: context.envName.includes("at") ? "alignat" : "align",
|
|
715
714
|
maxNumCols: isSplit ? 2 : undefined,
|
|
716
715
|
leqno: context.parser.settings.leqno,
|
|
717
716
|
},
|
|
@@ -893,8 +892,7 @@ defineEnvironment({
|
|
|
893
892
|
payload.cols = [{type: "align", align: colAlign}];
|
|
894
893
|
}
|
|
895
894
|
}
|
|
896
|
-
const res
|
|
897
|
-
parseArray(context.parser, payload, dCellStyle(context.envName));
|
|
895
|
+
const res = parseArray(context.parser, payload, dCellStyle(context.envName));
|
|
898
896
|
// Populate cols with the correct number of column alignment specs.
|
|
899
897
|
const numCols = Math.max(0, ...res.body.map(row => row.length));
|
|
900
898
|
res.cols = new Array(numCols).fill(
|
|
@@ -1006,8 +1004,7 @@ defineEnvironment({
|
|
|
1006
1004
|
postgap: 0,
|
|
1007
1005
|
}],
|
|
1008
1006
|
};
|
|
1009
|
-
const res
|
|
1010
|
-
parseArray(context.parser, payload, dCellStyle(context.envName));
|
|
1007
|
+
const res = parseArray(context.parser, payload, dCellStyle(context.envName));
|
|
1011
1008
|
return {
|
|
1012
1009
|
type: "leftright",
|
|
1013
1010
|
mode: context.mode,
|
|
@@ -1124,11 +1121,10 @@ defineMacro("\\notag", "\\nonumber");
|
|
|
1124
1121
|
defineFunction({
|
|
1125
1122
|
type: "text", // Doesn't matter what this is.
|
|
1126
1123
|
names: ["\\hline", "\\hdashline"],
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
},
|
|
1124
|
+
numArgs: 0,
|
|
1125
|
+
allowedInText: true,
|
|
1126
|
+
allowedInMath: true,
|
|
1127
|
+
|
|
1132
1128
|
handler(context, args) {
|
|
1133
1129
|
throw new ParseError(
|
|
1134
1130
|
`${context.funcName} valid only within array environment`);
|
package/src/environments/cd.ts
CHANGED
|
@@ -8,7 +8,8 @@ import ParseError from "../ParseError";
|
|
|
8
8
|
import {makeEm} from "../units";
|
|
9
9
|
|
|
10
10
|
import type Parser from "../Parser";
|
|
11
|
-
import type {
|
|
11
|
+
import type {AnyParseNode, ParseNode} from "../types/nodes";
|
|
12
|
+
import type {Slice4} from "../types";
|
|
12
13
|
|
|
13
14
|
const cdArrowFunctionName: Record<string, string> = {
|
|
14
15
|
">": "\\\\cdrightarrow",
|
|
@@ -247,17 +248,16 @@ export function parseCD(parser: Parser): ParseNode<"array"> {
|
|
|
247
248
|
defineFunction({
|
|
248
249
|
type: "cdlabel",
|
|
249
250
|
names: ["\\\\cdleft", "\\\\cdright"],
|
|
250
|
-
|
|
251
|
-
numArgs: 1,
|
|
252
|
-
},
|
|
251
|
+
numArgs: 1,
|
|
253
252
|
handler({parser, funcName}, args) {
|
|
254
253
|
return {
|
|
255
254
|
type: "cdlabel",
|
|
256
255
|
mode: parser.mode,
|
|
257
|
-
side: funcName.slice(4)
|
|
256
|
+
side: funcName.slice(4) as Slice4<typeof funcName>,
|
|
258
257
|
label: args[0],
|
|
259
258
|
};
|
|
260
259
|
},
|
|
260
|
+
|
|
261
261
|
htmlBuilder(group, options) {
|
|
262
262
|
const newOptions = options.havingStyle(options.style.sup());
|
|
263
263
|
const label = wrapFragment(
|
|
@@ -291,9 +291,8 @@ defineFunction({
|
|
|
291
291
|
defineFunction({
|
|
292
292
|
type: "cdlabelparent",
|
|
293
293
|
names: ["\\\\cdparent"],
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
},
|
|
294
|
+
numArgs: 1,
|
|
295
|
+
|
|
297
296
|
handler({parser}, args) {
|
|
298
297
|
return {
|
|
299
298
|
type: "cdlabelparent",
|
|
@@ -301,6 +300,7 @@ defineFunction({
|
|
|
301
300
|
fragment: args[0],
|
|
302
301
|
};
|
|
303
302
|
},
|
|
303
|
+
|
|
304
304
|
htmlBuilder(group, options) {
|
|
305
305
|
// Wrap the vertical arrow and its labels.
|
|
306
306
|
// The parent gets position: relative. The child gets position: absolute.
|
package/src/fontMetrics.ts
CHANGED
|
@@ -257,10 +257,8 @@ export function getGlobalMetrics(size: number): FontMetrics {
|
|
|
257
257
|
const metrics: FontMetrics = fontMetricsBySizeIndex[sizeIndex] = {
|
|
258
258
|
cssEmPerMu: sigmasAndXis.quad[sizeIndex] / 18,
|
|
259
259
|
};
|
|
260
|
-
for (const key
|
|
261
|
-
|
|
262
|
-
metrics[key] = sigmasAndXis[key][sizeIndex];
|
|
263
|
-
}
|
|
260
|
+
for (const key of Object.keys(sigmasAndXis)) {
|
|
261
|
+
metrics[key] = sigmasAndXis[key][sizeIndex];
|
|
264
262
|
}
|
|
265
263
|
}
|
|
266
264
|
return fontMetricsBySizeIndex[sizeIndex]!;
|
package/src/functions/accent.ts
CHANGED
|
@@ -10,9 +10,9 @@ import {makeEm} from "../units";
|
|
|
10
10
|
import * as html from "../buildHTML";
|
|
11
11
|
import * as mml from "../buildMathML";
|
|
12
12
|
|
|
13
|
-
import type {ParseNode, AnyParseNode} from "../parseNode";
|
|
14
13
|
import type {HtmlBuilderSupSub, MathMLBuilder} from "../defineFunction";
|
|
15
14
|
import type {HtmlDomNode} from "../domTree";
|
|
15
|
+
import type {AnyParseNode, ParseNode} from "../types/nodes";
|
|
16
16
|
|
|
17
17
|
const getBaseSymbol = (group: HtmlDomNode): SymbolNode | undefined => {
|
|
18
18
|
if (group instanceof SymbolNode) {
|
|
@@ -100,7 +100,7 @@ export const htmlBuilder: HtmlBuilderSupSub<"accent"> = (grp, options) => {
|
|
|
100
100
|
width = svgData.vec[1];
|
|
101
101
|
} else {
|
|
102
102
|
accent = makeOrd({type: "textord", mode: group.mode, text: group.label},
|
|
103
|
-
options
|
|
103
|
+
options);
|
|
104
104
|
accent = assertSymbolDomNode(accent);
|
|
105
105
|
// Remove the italic correction of the accent, because it only serves to
|
|
106
106
|
// shift the accent over to a place we don't want.
|
|
@@ -125,7 +125,7 @@ export const htmlBuilder: HtmlBuilderSupSub<"accent"> = (grp, options) => {
|
|
|
125
125
|
// Shift the accent over by the skew.
|
|
126
126
|
let left = skew;
|
|
127
127
|
|
|
128
|
-
// CSS defines `.katex .accent .accent-body:not(.accent-full) { width: 0 }`
|
|
128
|
+
// CSS defines `.katex .katex-accent .accent-body:not(.accent-full) { width: 0 }`
|
|
129
129
|
// so that the accent doesn't contribute to the bounding box.
|
|
130
130
|
// We need to shift the character by its width (effectively half
|
|
131
131
|
// its width) to compensate.
|
|
@@ -173,7 +173,7 @@ export const htmlBuilder: HtmlBuilderSupSub<"accent"> = (grp, options) => {
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
const accentWrap =
|
|
176
|
-
makeSpan(["mord", "accent"], [accentBody], options);
|
|
176
|
+
makeSpan(["mord", "katex-accent"], [accentBody], options);
|
|
177
177
|
|
|
178
178
|
if (supSubGroup) {
|
|
179
179
|
// Here, we replace the "base" child of the supsub with our newly
|
|
@@ -223,9 +223,8 @@ defineFunction({
|
|
|
223
223
|
"\\Overrightarrow", "\\overleftrightarrow", "\\overgroup",
|
|
224
224
|
"\\overlinesegment", "\\overleftharpoon", "\\overrightharpoon",
|
|
225
225
|
],
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
},
|
|
226
|
+
numArgs: 1,
|
|
227
|
+
|
|
229
228
|
handler: (context, args) => {
|
|
230
229
|
const base = normalizeArgument(args[0]);
|
|
231
230
|
|
|
@@ -244,6 +243,7 @@ defineFunction({
|
|
|
244
243
|
base: base,
|
|
245
244
|
};
|
|
246
245
|
},
|
|
246
|
+
|
|
247
247
|
htmlBuilder,
|
|
248
248
|
mathmlBuilder,
|
|
249
249
|
});
|
|
@@ -255,12 +255,11 @@ defineFunction({
|
|
|
255
255
|
"\\'", "\\`", "\\^", "\\~", "\\=", "\\u", "\\.", '\\"',
|
|
256
256
|
"\\c", "\\r", "\\H", "\\v", "\\textcircled",
|
|
257
257
|
],
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
},
|
|
258
|
+
numArgs: 1,
|
|
259
|
+
allowedInText: true,
|
|
260
|
+
allowedInMath: true, // unless in strict mode
|
|
261
|
+
argTypes: ["primitive"],
|
|
262
|
+
|
|
264
263
|
handler: (context, args) => {
|
|
265
264
|
const base = args[0];
|
|
266
265
|
let mode = context.parser.mode;
|
|
@@ -280,6 +279,4 @@ defineFunction({
|
|
|
280
279
|
base: base,
|
|
281
280
|
};
|
|
282
281
|
},
|
|
283
|
-
htmlBuilder,
|
|
284
|
-
mathmlBuilder,
|
|
285
282
|
});
|