katex 0.16.32 → 0.16.34
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 +3 -3
- package/contrib/auto-render/{auto-render.js → auto-render.ts} +41 -19
- package/contrib/auto-render/{splitAtDelimiters.js → splitAtDelimiters.ts} +18 -4
- package/contrib/auto-render/test/{auto-render-spec.js → auto-render-spec.ts} +10 -2
- package/contrib/copy-tex/README.md +2 -2
- package/contrib/copy-tex/{copy-tex.js → copy-tex.ts} +4 -6
- package/contrib/copy-tex/{katex2tex.js → katex2tex.ts} +2 -3
- package/contrib/mathtex-script-type/README.md +5 -5
- package/contrib/mhchem/README.md +1 -1
- package/contrib/render-a11y-string/{render-a11y-string.js → render-a11y-string.ts} +18 -33
- package/contrib/render-a11y-string/test/{render-a11y-string-spec.js → render-a11y-string-spec.ts} +0 -1
- package/dist/README.md +3 -3
- package/dist/contrib/auto-render.js +24 -57
- package/dist/contrib/auto-render.min.js +1 -1
- package/dist/contrib/auto-render.mjs +16586 -210
- package/dist/contrib/copy-tex.js +23 -37
- package/dist/contrib/copy-tex.min.js +1 -1
- package/dist/contrib/copy-tex.mjs +77 -95
- package/dist/contrib/mathtex-script-type.js +0 -3
- package/dist/contrib/mathtex-script-type.mjs +16427 -4
- package/dist/contrib/mhchem.js +55 -303
- package/dist/contrib/mhchem.mjs +12884 -723
- package/dist/contrib/render-a11y-string.js +13 -108
- package/dist/contrib/render-a11y-string.min.js +1 -1
- package/dist/contrib/render-a11y-string.mjs +17020 -760
- package/dist/katex-swap.css +2 -1
- package/dist/katex-swap.min.css +1 -1
- package/dist/katex.css +2 -1
- package/dist/katex.js +4547 -5680
- package/dist/katex.min.css +1 -1
- package/dist/katex.min.js +1 -1
- package/dist/katex.mjs +11854 -13828
- package/{katex.js → katex.ts} +8 -5
- package/package.json +34 -31
- package/src/{Lexer.js → Lexer.ts} +1 -2
- package/src/{MacroExpander.js → MacroExpander.ts} +11 -15
- package/src/{Namespace.js → Namespace.ts} +4 -6
- package/src/{Options.js → Options.ts} +7 -12
- package/src/{ParseError.js → ParseError.ts} +16 -26
- package/src/{Parser.js → Parser.ts} +68 -56
- package/src/{Settings.js → Settings.ts} +70 -70
- package/src/{SourceLocation.js → SourceLocation.ts} +6 -7
- package/src/{Style.js → Style.ts} +4 -5
- package/src/{Token.js → Token.ts} +8 -6
- package/src/{buildCommon.js → buildCommon.ts} +62 -55
- package/src/{buildHTML.js → buildHTML.ts} +29 -25
- package/src/{buildMathML.js → buildMathML.ts} +15 -13
- package/src/{buildTree.js → buildTree.ts} +1 -2
- package/src/{defineEnvironment.js → defineEnvironment.ts} +26 -27
- package/src/{defineFunction.js → defineFunction.ts} +54 -56
- package/src/{defineMacro.js → defineMacro.ts} +12 -13
- package/src/{delimiter.js → delimiter.ts} +19 -17
- package/src/{domTree.js → domTree.ts} +94 -103
- package/src/environments/{array.js → array.ts} +109 -99
- package/src/environments/{cd.js → cd.ts} +9 -11
- package/src/{environments.js → environments.ts} +0 -1
- package/src/{fontMetrics.js → fontMetrics.ts} +10 -12
- package/src/fontMetricsData.d.ts +3 -0
- package/src/functions/{accent.js → accent.ts} +1 -2
- package/src/functions/{accentunder.js → accentunder.ts} +0 -1
- package/src/functions/{arrow.js → arrow.ts} +4 -6
- package/src/functions/{char.js → char.ts} +0 -1
- package/src/functions/{color.js → color.ts} +5 -6
- package/src/functions/{cr.js → cr.ts} +0 -1
- package/src/functions/{def.js → def.ts} +9 -7
- package/src/functions/{delimsizing.js → delimsizing.ts} +11 -9
- package/src/functions/{enclose.js → enclose.ts} +3 -4
- package/src/functions/{environment.js → environment.ts} +2 -3
- package/src/functions/{font.js → font.ts} +4 -4
- package/src/functions/{genfrac.js → genfrac.ts} +14 -15
- package/src/functions/{hbox.js → hbox.ts} +0 -1
- package/src/functions/{horizBrace.js → horizBrace.ts} +4 -5
- package/src/functions/{href.js → href.ts} +4 -4
- package/src/functions/{html.js → html.ts} +3 -3
- package/src/functions/{htmlmathml.js → htmlmathml.ts} +0 -1
- package/src/functions/{includegraphics.js → includegraphics.ts} +0 -1
- package/src/functions/{kern.js → kern.ts} +0 -1
- package/src/functions/{lap.js → lap.ts} +0 -1
- package/src/functions/{math.js → math.ts} +0 -1
- package/src/functions/{mathchoice.js → mathchoice.ts} +2 -2
- package/src/functions/{mclass.js → mclass.ts} +5 -6
- package/src/functions/{op.js → op.ts} +9 -11
- package/src/functions/{operatorname.js → operatorname.ts} +4 -7
- package/src/functions/{ordgroup.js → ordgroup.ts} +0 -2
- package/src/functions/{overline.js → overline.ts} +0 -1
- package/src/functions/{phantom.js → phantom.ts} +0 -1
- package/src/functions/{pmb.js → pmb.ts} +0 -1
- package/src/functions/{raisebox.js → raisebox.ts} +0 -1
- package/src/functions/{relax.js → relax.ts} +0 -1
- package/src/functions/{rule.js → rule.ts} +0 -1
- package/src/functions/{sizing.js → sizing.ts} +0 -1
- package/src/functions/{smash.js → smash.ts} +2 -4
- package/src/functions/{sqrt.js → sqrt.ts} +0 -1
- package/src/functions/{styling.js → styling.ts} +3 -3
- package/src/functions/{supsub.js → supsub.ts} +6 -8
- package/src/functions/{symbolsOp.js → symbolsOp.ts} +0 -2
- package/src/functions/{symbolsOrd.js → symbolsOrd.ts} +1 -2
- package/src/functions/{symbolsSpacing.js → symbolsSpacing.ts} +2 -3
- package/src/functions/{tag.js → tag.ts} +0 -2
- package/src/functions/{text.js → text.ts} +7 -6
- package/src/functions/{underline.js → underline.ts} +0 -1
- package/src/functions/utils/{assembleSupSub.js → assembleSupSub.ts} +2 -3
- package/src/functions/{vcenter.js → vcenter.ts} +0 -2
- package/src/functions/{verb.js → verb.ts} +0 -1
- package/src/{functions.js → functions.ts} +0 -1
- package/src/{macros.js → macros.ts} +10 -8
- package/src/{mathMLTree.js → mathMLTree.ts} +5 -6
- package/src/parseNode.ts +522 -0
- package/src/{parseTree.js → parseTree.ts} +5 -3
- package/src/{spacingData.js → spacingData.ts} +11 -12
- package/src/{stretchy.js → stretchy.ts} +7 -7
- package/src/styles/katex-swap.scss +1 -4
- package/src/styles/katex.scss +9 -0
- package/src/{svgGeometry.js → svgGeometry.ts} +1 -2
- package/src/{symbols.js → symbols.ts} +6 -6
- package/src/{tree.js → tree.ts} +5 -7
- package/src/{types.js → types.ts} +1 -2
- package/src/unicodeAccents.js +4 -1
- package/src/{unicodeScripts.js → unicodeScripts.ts} +1 -3
- package/src/{unicodeSupOrSub.js → unicodeSupOrSub.ts} +1 -1
- package/src/unicodeSymbols.js +4 -3
- package/src/{units.js → units.ts} +2 -4
- package/src/{utils.js → utils.ts} +2 -3
- package/src/{wide-character.js → wide-character.ts} +8 -10
- package/types/katex.d.ts +13 -12
- package/src/parseNode.js +0 -523
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import SourceLocation from "./SourceLocation";
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* Interface required to break circular dependency between Token, Lexer, and
|
|
6
5
|
* ParseError.
|
|
7
6
|
*/
|
|
8
|
-
export interface LexerInterface {
|
|
7
|
+
export interface LexerInterface {
|
|
8
|
+
input: string;
|
|
9
|
+
tokenRegex: RegExp;
|
|
10
|
+
}
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* The resulting token returned from `lex`.
|
|
@@ -22,13 +24,13 @@ export interface LexerInterface {input: string, tokenRegex: RegExp}
|
|
|
22
24
|
*/
|
|
23
25
|
export class Token {
|
|
24
26
|
text: string;
|
|
25
|
-
loc:
|
|
26
|
-
noexpand:
|
|
27
|
-
treatAsRelax:
|
|
27
|
+
loc: SourceLocation | null | undefined;
|
|
28
|
+
noexpand: boolean | null | undefined; // don't expand the token
|
|
29
|
+
treatAsRelax: boolean | null | undefined; // used in \noexpand
|
|
28
30
|
|
|
29
31
|
constructor(
|
|
30
32
|
text: string, // the text of this token
|
|
31
|
-
loc
|
|
33
|
+
loc?: SourceLocation | null | undefined,
|
|
32
34
|
) {
|
|
33
35
|
this.text = text;
|
|
34
36
|
this.loc = loc;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
/* eslint no-console:0 */
|
|
3
2
|
/**
|
|
4
3
|
* This module contains general functions that can be used for building
|
|
@@ -29,13 +28,20 @@ const lookupSymbol = function(
|
|
|
29
28
|
// TODO(#963): Use a union type for this.
|
|
30
29
|
fontName: string,
|
|
31
30
|
mode: Mode,
|
|
32
|
-
): {
|
|
31
|
+
): {
|
|
32
|
+
value: string;
|
|
33
|
+
metrics: CharacterMetrics | null | undefined;
|
|
34
|
+
} {
|
|
33
35
|
// Replace the value with its replaced value from symbol.js
|
|
34
|
-
if (symbols[mode][value]
|
|
35
|
-
|
|
36
|
+
if (symbols[mode][value]) {
|
|
37
|
+
const replacement = symbols[mode][value].replace;
|
|
38
|
+
if (replacement) {
|
|
39
|
+
value = replacement;
|
|
40
|
+
}
|
|
36
41
|
}
|
|
42
|
+
|
|
37
43
|
return {
|
|
38
|
-
value
|
|
44
|
+
value,
|
|
39
45
|
metrics: getCharacterMetrics(value, fontName, mode),
|
|
40
46
|
};
|
|
41
47
|
};
|
|
@@ -99,7 +105,7 @@ export const mathsym = function(
|
|
|
99
105
|
value: string,
|
|
100
106
|
mode: Mode,
|
|
101
107
|
options: Options,
|
|
102
|
-
classes
|
|
108
|
+
classes: string[] = [],
|
|
103
109
|
): SymbolNode {
|
|
104
110
|
// Decide what font to render the symbol in by its entry in the symbols
|
|
105
111
|
// table.
|
|
@@ -132,7 +138,10 @@ const boldsymbol = function(
|
|
|
132
138
|
options: Options,
|
|
133
139
|
classes: string[],
|
|
134
140
|
type: "mathord" | "textord",
|
|
135
|
-
): {
|
|
141
|
+
): {
|
|
142
|
+
fontName: string;
|
|
143
|
+
fontClass: string;
|
|
144
|
+
} {
|
|
136
145
|
if (type !== "textord" &&
|
|
137
146
|
lookupSymbol(value, "Math-BoldItalic", mode).metrics) {
|
|
138
147
|
return {
|
|
@@ -152,7 +161,7 @@ const boldsymbol = function(
|
|
|
152
161
|
/**
|
|
153
162
|
* Makes either a mathord or textord in the correct font and color.
|
|
154
163
|
*/
|
|
155
|
-
export const makeOrd = function<NODETYPE
|
|
164
|
+
export const makeOrd = function<NODETYPE extends "spacing" | "mathord" | "textord">(
|
|
156
165
|
group: ParseNode<NODETYPE>,
|
|
157
166
|
options: Options,
|
|
158
167
|
type: "mathord" | "textord",
|
|
@@ -258,16 +267,14 @@ const canCombine = (prev: SymbolNode, next: SymbolNode) => {
|
|
|
258
267
|
}
|
|
259
268
|
}
|
|
260
269
|
|
|
261
|
-
for (const
|
|
262
|
-
if (prev.style.
|
|
263
|
-
&& prev.style[style] !== next.style[style]) {
|
|
270
|
+
for (const key of Object.keys(prev.style) as Array<keyof CssStyle>) {
|
|
271
|
+
if (prev.style[key] !== next.style[key]) {
|
|
264
272
|
return false;
|
|
265
273
|
}
|
|
266
274
|
}
|
|
267
275
|
|
|
268
|
-
for (const
|
|
269
|
-
if (
|
|
270
|
-
&& prev.style[style] !== next.style[style]) {
|
|
276
|
+
for (const key of Object.keys(next.style) as Array<keyof CssStyle>) {
|
|
277
|
+
if (prev.style[key] !== next.style[key]) {
|
|
271
278
|
return false;
|
|
272
279
|
}
|
|
273
280
|
}
|
|
@@ -419,36 +426,36 @@ export const wrapFragment = function(
|
|
|
419
426
|
return group;
|
|
420
427
|
};
|
|
421
428
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
429
|
+
export type VListElem = {
|
|
430
|
+
type: "elem";
|
|
431
|
+
elem: HtmlDomNode;
|
|
432
|
+
marginLeft?: string | null | undefined;
|
|
433
|
+
marginRight?: string;
|
|
434
|
+
wrapperClasses?: string[];
|
|
435
|
+
wrapperStyle?: CssStyle;
|
|
436
|
+
};
|
|
437
|
+
type VListElemAndShift = {
|
|
438
|
+
type: "elem";
|
|
439
|
+
elem: HtmlDomNode;
|
|
440
|
+
shift: number;
|
|
441
|
+
marginLeft?: string | null | undefined;
|
|
442
|
+
marginRight?: string;
|
|
443
|
+
wrapperClasses?: string[];
|
|
444
|
+
wrapperStyle?: CssStyle;
|
|
445
|
+
};
|
|
446
|
+
type VListKern = {
|
|
447
|
+
type: "kern";
|
|
448
|
+
size: number;
|
|
449
|
+
};
|
|
442
450
|
|
|
443
451
|
// A list of child or kern nodes to be stacked on top of each other (i.e. the
|
|
444
452
|
// first element will be at the bottom, and the last at the top).
|
|
445
453
|
type VListChild = VListElem | VListKern;
|
|
446
|
-
|
|
447
|
-
type VListParam = {|
|
|
454
|
+
type VListParam = {
|
|
448
455
|
// Each child contains how much it should be shifted downward.
|
|
449
|
-
positionType: "individualShift"
|
|
450
|
-
children: VListElemAndShift[]
|
|
451
|
-
|
|
456
|
+
positionType: "individualShift";
|
|
457
|
+
children: VListElemAndShift[];
|
|
458
|
+
} | {
|
|
452
459
|
// "top": The positionData specifies the topmost point of the vlist (note this
|
|
453
460
|
// is expected to be a height, so positive values move up).
|
|
454
461
|
// "bottom": The positionData specifies the bottommost point of the vlist (note
|
|
@@ -456,25 +463,24 @@ type VListParam = {|
|
|
|
456
463
|
// "shift": The vlist will be positioned such that its baseline is positionData
|
|
457
464
|
// away from the baseline of the first child which MUST be an
|
|
458
465
|
// "elem". Positive values move downwards.
|
|
459
|
-
positionType: "top" | "bottom" | "shift"
|
|
460
|
-
positionData: number
|
|
461
|
-
children: VListChild[]
|
|
462
|
-
|
|
466
|
+
positionType: "top" | "bottom" | "shift";
|
|
467
|
+
positionData: number;
|
|
468
|
+
children: VListChild[];
|
|
469
|
+
} | {
|
|
463
470
|
// The vlist is positioned so that its baseline is aligned with the baseline
|
|
464
471
|
// of the first child which MUST be an "elem". This is equivalent to "shift"
|
|
465
472
|
// with positionData=0.
|
|
466
|
-
positionType: "firstBaseline"
|
|
467
|
-
children: VListChild[]
|
|
468
|
-
|
|
469
|
-
|
|
473
|
+
positionType: "firstBaseline";
|
|
474
|
+
children: VListChild[];
|
|
475
|
+
};
|
|
470
476
|
|
|
471
477
|
// Computes the updated `children` list and the overall depth.
|
|
472
478
|
//
|
|
473
479
|
// This helper function for makeVList makes it easier to enforce type safety by
|
|
474
480
|
// allowing early exits (returns) in the logic.
|
|
475
481
|
const getVListChildrenAndDepth = function(params: VListParam): {
|
|
476
|
-
children: (VListChild | VListElemAndShift)[] | VListChild[]
|
|
477
|
-
depth: number
|
|
482
|
+
children: (VListChild | VListElemAndShift)[] | VListChild[];
|
|
483
|
+
depth: number;
|
|
478
484
|
} {
|
|
479
485
|
if (params.positionType === "individualShift") {
|
|
480
486
|
const oldChildren = params.children;
|
|
@@ -492,7 +498,6 @@ const getVListChildrenAndDepth = function(params: VListParam): {
|
|
|
492
498
|
oldChildren[i - 1].elem.depth);
|
|
493
499
|
|
|
494
500
|
currPos = currPos + diff;
|
|
495
|
-
|
|
496
501
|
children.push({type: "kern", size});
|
|
497
502
|
children.push(oldChildren[i]);
|
|
498
503
|
}
|
|
@@ -527,6 +532,7 @@ const getVListChildrenAndDepth = function(params: VListParam): {
|
|
|
527
532
|
throw new Error(`Invalid positionType ${params.positionType}.`);
|
|
528
533
|
}
|
|
529
534
|
}
|
|
535
|
+
|
|
530
536
|
return {children: params.children, depth};
|
|
531
537
|
};
|
|
532
538
|
|
|
@@ -680,7 +686,10 @@ const retrieveTextFontName = function(
|
|
|
680
686
|
* - fontName: the "style" parameter to fontMetrics.getCharacterMetrics
|
|
681
687
|
*/
|
|
682
688
|
// A map between tex font commands an MathML mathvariant attribute values
|
|
683
|
-
export const fontMap:
|
|
689
|
+
export const fontMap: Record<string, {
|
|
690
|
+
variant: FontVariant;
|
|
691
|
+
fontName: string;
|
|
692
|
+
}> = {
|
|
684
693
|
// styles
|
|
685
694
|
"mathbf": {
|
|
686
695
|
variant: "bold",
|
|
@@ -737,10 +746,8 @@ export const fontMap: {[string]: {| variant: FontVariant, fontName: string |}} =
|
|
|
737
746
|
},
|
|
738
747
|
};
|
|
739
748
|
|
|
740
|
-
export const svgData: {
|
|
741
|
-
|
|
742
|
-
} = {
|
|
743
|
-
// path, width, height
|
|
749
|
+
export const svgData: Record<string, [string, number, number]> = {
|
|
750
|
+
// path, width, height
|
|
744
751
|
vec: ["vec", 0.471, 0.714], // values from the font glyph
|
|
745
752
|
oiintSize1: ["oiintSize1", 0.957, 0.499], // oval to overlay the integrand
|
|
746
753
|
oiintSize2: ["oiintSize2", 1.472, 0.659],
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
/**
|
|
3
2
|
* This file does the main work of building a domTree structure from a parse
|
|
4
3
|
* tree. The entry point is the `buildHTML` function, which takes a parse tree.
|
|
@@ -48,7 +47,7 @@ const DomEnum = {
|
|
|
48
47
|
mpunct: "mpunct",
|
|
49
48
|
minner: "minner",
|
|
50
49
|
};
|
|
51
|
-
type DomType =
|
|
50
|
+
type DomType = keyof typeof DomEnum;
|
|
52
51
|
|
|
53
52
|
/**
|
|
54
53
|
* Take a list of nodes, build them in order, and return a list of the built
|
|
@@ -62,14 +61,14 @@ export const buildExpression = function(
|
|
|
62
61
|
expression: AnyParseNode[],
|
|
63
62
|
options: Options,
|
|
64
63
|
isRealGroup: boolean | "root",
|
|
65
|
-
surrounding: [
|
|
64
|
+
surrounding: [DomType | null | undefined, DomType | null | undefined] = [null, null],
|
|
66
65
|
): HtmlDomNode[] {
|
|
67
66
|
// Parse expressions into `groups`.
|
|
68
67
|
const groups: HtmlDomNode[] = [];
|
|
69
68
|
for (let i = 0; i < expression.length; i++) {
|
|
70
69
|
const output = buildGroup(expression[i], options);
|
|
71
70
|
if (output instanceof DocumentFragment) {
|
|
72
|
-
const children:
|
|
71
|
+
const children: ReadonlyArray<HtmlDomNode> = output.children;
|
|
73
72
|
groups.push(...children);
|
|
74
73
|
} else {
|
|
75
74
|
groups.push(output);
|
|
@@ -108,7 +107,7 @@ export const buildExpression = function(
|
|
|
108
107
|
// Before determining what spaces to insert, perform bin cancellation.
|
|
109
108
|
// Binary operators change to ordinary symbols in some contexts.
|
|
110
109
|
const isRoot = (isRealGroup === "root");
|
|
111
|
-
traverseNonSpaceNodes(groups, (node, prev) => {
|
|
110
|
+
traverseNonSpaceNodes(groups, (node, prev): void => {
|
|
112
111
|
const prevType = prev.classes[0];
|
|
113
112
|
const type = node.classes[0];
|
|
114
113
|
if (prevType === "mbin" && binRightCanceller.has(type)) {
|
|
@@ -118,14 +117,15 @@ export const buildExpression = function(
|
|
|
118
117
|
}
|
|
119
118
|
}, {node: dummyPrev}, dummyNext, isRoot);
|
|
120
119
|
|
|
121
|
-
traverseNonSpaceNodes(groups, (node, prev) => {
|
|
120
|
+
traverseNonSpaceNodes(groups, (node, prev): HtmlDomNode | undefined => {
|
|
122
121
|
const prevType = getTypeOfDomTree(prev);
|
|
123
122
|
const type = getTypeOfDomTree(node);
|
|
124
123
|
|
|
125
124
|
// 'mtight' indicates that the node is script or scriptscript style.
|
|
126
125
|
const space = prevType && type ? (node.hasClass("mtight")
|
|
127
|
-
? tightSpacings[prevType][type]
|
|
128
|
-
: spacings[prevType][type]) : null;
|
|
126
|
+
? tightSpacings[prevType]?.[type]
|
|
127
|
+
: spacings[prevType]?.[type]) : null;
|
|
128
|
+
|
|
129
129
|
if (space) { // Insert glue (spacing) after the `prev`.
|
|
130
130
|
return makeGlue(space, glueOptions);
|
|
131
131
|
}
|
|
@@ -141,12 +141,13 @@ export const buildExpression = function(
|
|
|
141
141
|
// Used for bin cancellation and inserting spacings.
|
|
142
142
|
const traverseNonSpaceNodes = function(
|
|
143
143
|
nodes: HtmlDomNode[],
|
|
144
|
-
callback: (HtmlDomNode, HtmlDomNode) =>
|
|
145
|
-
|
|
144
|
+
callback: (arg0: HtmlDomNode, arg1: HtmlDomNode) =>
|
|
145
|
+
HtmlDomNode | null | void,
|
|
146
|
+
prev: {
|
|
146
147
|
node: HtmlDomNode,
|
|
147
|
-
insertAfter?: HtmlDomNode => void,
|
|
148
|
-
|
|
149
|
-
next:
|
|
148
|
+
insertAfter?: (arg0: HtmlDomNode) => void,
|
|
149
|
+
},
|
|
150
|
+
next: HtmlDomNode | null | undefined,
|
|
150
151
|
isRoot: boolean,
|
|
151
152
|
) {
|
|
152
153
|
if (next) { // temporarily append the right node, if exists
|
|
@@ -156,9 +157,10 @@ const traverseNonSpaceNodes = function(
|
|
|
156
157
|
for (; i < nodes.length; i++) {
|
|
157
158
|
const node = nodes[i];
|
|
158
159
|
const partialGroup = checkPartialGroup(node);
|
|
160
|
+
|
|
159
161
|
if (partialGroup) { // Recursive DFS
|
|
160
|
-
//
|
|
161
|
-
traverseNonSpaceNodes(partialGroup.children,
|
|
162
|
+
// TODO(ts): make nodes a $ReadOnlyArray by returning a new array
|
|
163
|
+
traverseNonSpaceNodes(partialGroup.children as HtmlDomNode[],
|
|
162
164
|
callback, prev, null, isRoot);
|
|
163
165
|
continue;
|
|
164
166
|
}
|
|
@@ -188,6 +190,7 @@ const traverseNonSpaceNodes = function(
|
|
|
188
190
|
i++;
|
|
189
191
|
})(i);
|
|
190
192
|
}
|
|
193
|
+
|
|
191
194
|
if (next) {
|
|
192
195
|
nodes.pop();
|
|
193
196
|
}
|
|
@@ -196,7 +199,7 @@ const traverseNonSpaceNodes = function(
|
|
|
196
199
|
// Check if given node is a partial group, i.e., does not affect spacing around.
|
|
197
200
|
const checkPartialGroup = function(
|
|
198
201
|
node: HtmlDomNode,
|
|
199
|
-
):
|
|
202
|
+
): DocumentFragment<HtmlDomNode> | Anchor | DomSpan | null | undefined {
|
|
200
203
|
if (node instanceof DocumentFragment || node instanceof Anchor
|
|
201
204
|
|| (node instanceof Span && node.hasClass("enclosing"))) {
|
|
202
205
|
return node;
|
|
@@ -226,9 +229,9 @@ const getOutermostNode = function(
|
|
|
226
229
|
// Return math atom class (mclass) of a domTree.
|
|
227
230
|
// If `side` is given, it will get the type of the outermost node at given side.
|
|
228
231
|
export const getTypeOfDomTree = function(
|
|
229
|
-
node:
|
|
230
|
-
side
|
|
231
|
-
):
|
|
232
|
+
node: HtmlDomNode | null | undefined,
|
|
233
|
+
side?: Side | null | undefined,
|
|
234
|
+
): DomType | null | undefined {
|
|
232
235
|
if (!node) {
|
|
233
236
|
return null;
|
|
234
237
|
}
|
|
@@ -237,9 +240,9 @@ export const getTypeOfDomTree = function(
|
|
|
237
240
|
}
|
|
238
241
|
// This makes a lot of assumptions as to where the type of atom
|
|
239
242
|
// appears. We should do a better job of enforcing this.
|
|
240
|
-
|
|
243
|
+
const className = node.classes[0] as keyof typeof DomEnum;
|
|
244
|
+
return (DomEnum[className] as DomType | undefined) || null;
|
|
241
245
|
};
|
|
242
|
-
|
|
243
246
|
export const makeNullDelimiter = function(
|
|
244
247
|
options: Options,
|
|
245
248
|
classes: string[],
|
|
@@ -254,7 +257,7 @@ export const makeNullDelimiter = function(
|
|
|
254
257
|
* between parents and children.
|
|
255
258
|
*/
|
|
256
259
|
export const buildGroup = function(
|
|
257
|
-
group:
|
|
260
|
+
group: AnyParseNode | null | undefined,
|
|
258
261
|
options: Options,
|
|
259
262
|
baseOptions?: Options,
|
|
260
263
|
): HtmlDomNode {
|
|
@@ -264,7 +267,7 @@ export const buildGroup = function(
|
|
|
264
267
|
|
|
265
268
|
if (groupBuilders[group.type]) {
|
|
266
269
|
// Call the groupBuilders function
|
|
267
|
-
//
|
|
270
|
+
// TODO(ts)
|
|
268
271
|
let groupNode: HtmlDomNode = groupBuilders[group.type](group, options);
|
|
269
272
|
|
|
270
273
|
// If the size changed between the parent and the current group, account
|
|
@@ -293,7 +296,7 @@ export const buildGroup = function(
|
|
|
293
296
|
* guarantee correct vertical extent. `buildHTML` calls this repeatedly to
|
|
294
297
|
* make up the entire expression as a sequence of unbreakable units.
|
|
295
298
|
*/
|
|
296
|
-
function buildHTMLUnbreakable(children, options) {
|
|
299
|
+
function buildHTMLUnbreakable(children: HtmlDomNode[], options: Options) {
|
|
297
300
|
// Compute height and depth of this chunk.
|
|
298
301
|
const body = makeSpan(["base"], children, options);
|
|
299
302
|
|
|
@@ -382,7 +385,8 @@ export default function buildHTML(tree: AnyParseNode[], options: Options): DomSp
|
|
|
382
385
|
let tagChild;
|
|
383
386
|
if (tag) {
|
|
384
387
|
tagChild = buildHTMLUnbreakable(
|
|
385
|
-
buildExpression(tag, options, true)
|
|
388
|
+
buildExpression(tag, options, true),
|
|
389
|
+
options,
|
|
386
390
|
);
|
|
387
391
|
tagChild.classes = ["tag"];
|
|
388
392
|
children.push(tagChild);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
/**
|
|
3
2
|
* This file converts a parse tree into a corresponding MathML tree. The main
|
|
4
3
|
* entry point is the `buildMathML` function, which takes a parse tree from the
|
|
@@ -35,7 +34,7 @@ export const makeText = function(
|
|
|
35
34
|
!(ligatures.hasOwnProperty(text) && options &&
|
|
36
35
|
((options.fontFamily && options.fontFamily.slice(4, 6) === "tt") ||
|
|
37
36
|
(options.font && options.font.slice(4, 6) === "tt")))) {
|
|
38
|
-
text = symbols[mode][text].replace
|
|
37
|
+
text = symbols[mode][text].replace!;
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
return new TextNode(text);
|
|
@@ -45,7 +44,7 @@ export const makeText = function(
|
|
|
45
44
|
* Wrap the given array of nodes in an <mrow> node if needed, i.e.,
|
|
46
45
|
* unless the array has length 1. Always returns a single node.
|
|
47
46
|
*/
|
|
48
|
-
export const makeRow = function(body:
|
|
47
|
+
export const makeRow = function(body: MathDomNode[]): MathDomNode {
|
|
49
48
|
if (body.length === 1) {
|
|
50
49
|
return body[0];
|
|
51
50
|
} else {
|
|
@@ -59,7 +58,7 @@ export const makeRow = function(body: $ReadOnlyArray<MathDomNode>): MathDomNode
|
|
|
59
58
|
export const getVariant = function(
|
|
60
59
|
group: SymbolParseNode,
|
|
61
60
|
options: Options,
|
|
62
|
-
):
|
|
61
|
+
): FontVariant | null | undefined {
|
|
63
62
|
// Handle \text... font specifiers as best we can.
|
|
64
63
|
// MathML has a limited list of allowable mathvariant specifiers; see
|
|
65
64
|
// https://www.w3.org/TR/MathML3/chapter3.html#presm.commatt
|
|
@@ -117,8 +116,11 @@ export const getVariant = function(
|
|
|
117
116
|
return null;
|
|
118
117
|
}
|
|
119
118
|
|
|
120
|
-
if (symbols[mode][text]
|
|
121
|
-
|
|
119
|
+
if (symbols[mode][text]) {
|
|
120
|
+
const replacement = symbols[mode][text].replace;
|
|
121
|
+
if (replacement) {
|
|
122
|
+
text = replacement;
|
|
123
|
+
}
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
const fontName = fontMap[font].fontName;
|
|
@@ -134,7 +136,7 @@ export const getVariant = function(
|
|
|
134
136
|
* or <mo separator="true" lspace="0em" rspace="0em">,</mo>
|
|
135
137
|
* which is how a braced comma {,} renders in MathML
|
|
136
138
|
*/
|
|
137
|
-
function isNumberPunctuation(group:
|
|
139
|
+
function isNumberPunctuation(group: MathNode | null | undefined): boolean {
|
|
138
140
|
if (!group) {
|
|
139
141
|
return false;
|
|
140
142
|
}
|
|
@@ -247,7 +249,7 @@ export const buildExpressionRow = function(
|
|
|
247
249
|
* on it to produce a MathML node.
|
|
248
250
|
*/
|
|
249
251
|
export const buildGroup = function(
|
|
250
|
-
group:
|
|
252
|
+
group: AnyParseNode | null | undefined,
|
|
251
253
|
options: Options,
|
|
252
254
|
): MathNode {
|
|
253
255
|
if (!group) {
|
|
@@ -256,10 +258,10 @@ export const buildGroup = function(
|
|
|
256
258
|
|
|
257
259
|
if (groupBuilders[group.type]) {
|
|
258
260
|
// Call the groupBuilders function
|
|
259
|
-
//
|
|
261
|
+
// TODO(ts)
|
|
260
262
|
const result: MathDomNode = groupBuilders[group.type](group, options);
|
|
261
|
-
//
|
|
262
|
-
return result;
|
|
263
|
+
// TODO(ts)
|
|
264
|
+
return result as MathNode;
|
|
263
265
|
} else {
|
|
264
266
|
throw new ParseError(
|
|
265
267
|
"Got group of unknown type: '" + group.type + "'");
|
|
@@ -318,6 +320,6 @@ export default function buildMathML(
|
|
|
318
320
|
// we don't want to make the children type more generic since the children
|
|
319
321
|
// of span are expected to have more fields in `buildHtml` contexts.
|
|
320
322
|
const wrapperClass = forMathmlOnly ? "katex" : "katex-mathml";
|
|
321
|
-
//
|
|
322
|
-
return makeSpan([wrapperClass], [math]);
|
|
323
|
+
// TODO(ts)
|
|
324
|
+
return makeSpan([wrapperClass], [math as any]);
|
|
323
325
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import buildHTML from "./buildHTML";
|
|
3
2
|
import buildMathML from "./buildMathML";
|
|
4
3
|
import {makeSpan} from "./buildCommon";
|
|
@@ -39,7 +38,7 @@ export const buildTree = function(
|
|
|
39
38
|
const options = optionsFromSettings(settings);
|
|
40
39
|
let katexNode;
|
|
41
40
|
if (settings.output === "mathml") {
|
|
42
|
-
return
|
|
41
|
+
return buildMathML(tree, expression, options, settings.displayMode, true);
|
|
43
42
|
} else if (settings.output === "html") {
|
|
44
43
|
const htmlNode = buildHTML(tree, options);
|
|
45
44
|
katexNode = makeSpan(["katex"], [htmlNode]);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import {_htmlGroupBuilders, _mathmlGroupBuilders} from "./defineFunction";
|
|
3
2
|
|
|
4
3
|
import type Parser from "./Parser";
|
|
@@ -13,11 +12,11 @@ import type {HtmlBuilder, MathMLBuilder} from "./defineFunction";
|
|
|
13
12
|
* - envName: the name of the environment, one of the listed names.
|
|
14
13
|
* - parser: the parser object.
|
|
15
14
|
*/
|
|
16
|
-
type EnvContext = {
|
|
17
|
-
mode: Mode
|
|
18
|
-
envName: string
|
|
19
|
-
parser: Parser
|
|
20
|
-
|
|
15
|
+
type EnvContext = {
|
|
16
|
+
mode: Mode;
|
|
17
|
+
envName: string;
|
|
18
|
+
parser: Parser;
|
|
19
|
+
};
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
22
|
* - context: information and references provided by the parser
|
|
@@ -27,7 +26,7 @@ type EnvContext = {|
|
|
|
27
26
|
type EnvHandler = (
|
|
28
27
|
context: EnvContext,
|
|
29
28
|
args: AnyParseNode[],
|
|
30
|
-
optArgs: (
|
|
29
|
+
optArgs: (AnyParseNode | null | undefined)[],
|
|
31
30
|
) => AnyParseNode;
|
|
32
31
|
|
|
33
32
|
/**
|
|
@@ -38,7 +37,7 @@ type EnvHandler = (
|
|
|
38
37
|
* - numOptionalArgs: (default 0) Just like for a function
|
|
39
38
|
*/
|
|
40
39
|
type EnvProps = {
|
|
41
|
-
numArgs: number
|
|
40
|
+
numArgs: number;
|
|
42
41
|
};
|
|
43
42
|
|
|
44
43
|
/**
|
|
@@ -48,45 +47,45 @@ type EnvProps = {
|
|
|
48
47
|
* 2. requires all arguments except argType
|
|
49
48
|
* It is generated by `defineEnvironment()` below.
|
|
50
49
|
*/
|
|
51
|
-
export type EnvSpec<NODETYPE
|
|
52
|
-
type: NODETYPE
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
export type EnvSpec<NODETYPE extends NodeType> = {
|
|
51
|
+
type: NODETYPE;
|
|
52
|
+
// Need to use the type to avoid error. See NOTES below.
|
|
53
|
+
numArgs: number;
|
|
54
|
+
argTypes?: ArgType[];
|
|
55
|
+
allowedInText: boolean;
|
|
56
|
+
numOptionalArgs: number;
|
|
57
|
+
handler: EnvHandler;
|
|
58
|
+
};
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
61
|
* All registered environments.
|
|
62
62
|
* `environments.js` exports this same dictionary again and makes it public.
|
|
63
63
|
* `Parser.js` requires this dictionary via `environments.js`.
|
|
64
64
|
*/
|
|
65
|
-
export const _environments:
|
|
65
|
+
export const _environments: Record<string, EnvSpec<any>> = {};
|
|
66
66
|
|
|
67
|
-
type EnvDefSpec<NODETYPE
|
|
67
|
+
type EnvDefSpec<NODETYPE extends NodeType> = {
|
|
68
68
|
// Unique string to differentiate parse nodes.
|
|
69
|
-
type: NODETYPE
|
|
69
|
+
type: NODETYPE;
|
|
70
70
|
|
|
71
71
|
// List of functions which use the give handler, htmlBuilder,
|
|
72
72
|
// and mathmlBuilder.
|
|
73
|
-
names: Array<string
|
|
73
|
+
names: Array<string>;
|
|
74
74
|
|
|
75
75
|
// Properties that control how the environments are parsed.
|
|
76
|
-
props: EnvProps
|
|
77
|
-
|
|
78
|
-
handler: EnvHandler,
|
|
76
|
+
props: EnvProps;
|
|
77
|
+
handler: EnvHandler;
|
|
79
78
|
|
|
80
79
|
// This function returns an object representing the DOM structure to be
|
|
81
80
|
// created when rendering the defined LaTeX function.
|
|
82
|
-
htmlBuilder: HtmlBuilder<NODETYPE
|
|
81
|
+
htmlBuilder: HtmlBuilder<NODETYPE>;
|
|
83
82
|
|
|
84
83
|
// This function returns an object representing the MathML structure to be
|
|
85
84
|
// created when rendering the defined LaTeX function.
|
|
86
|
-
mathmlBuilder: MathMLBuilder<NODETYPE
|
|
87
|
-
|
|
85
|
+
mathmlBuilder: MathMLBuilder<NODETYPE>;
|
|
86
|
+
};
|
|
88
87
|
|
|
89
|
-
export default function defineEnvironment<NODETYPE
|
|
88
|
+
export default function defineEnvironment<NODETYPE extends NodeType>({
|
|
90
89
|
type,
|
|
91
90
|
names,
|
|
92
91
|
props,
|