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.
Files changed (93) hide show
  1. package/README.md +5 -10
  2. package/cli.js +6 -9
  3. package/contrib/auto-render/index.html +1 -1
  4. package/contrib/copy-tex/README.md +3 -3
  5. package/contrib/copy-tex/index.html +1 -1
  6. package/contrib/mathtex-script-type/README.md +5 -5
  7. package/contrib/mhchem/README.md +1 -1
  8. package/contrib/render-a11y-string/render-a11y-string.ts +1 -1
  9. package/dist/README.md +5 -10
  10. package/dist/contrib/render-a11y-string.js +15 -40
  11. package/dist/contrib/render-a11y-string.min.js +1 -1
  12. package/dist/contrib/render-a11y-string.mjs +13 -33
  13. package/dist/katex-swap.css +159 -164
  14. package/dist/katex-swap.min.css +1 -1
  15. package/dist/katex.css +159 -164
  16. package/dist/katex.js +509 -849
  17. package/dist/katex.min.css +1 -1
  18. package/dist/katex.min.js +1 -1
  19. package/dist/katex.mjs +498 -831
  20. package/katex.ts +1 -1
  21. package/package.json +12 -16
  22. package/src/MacroExpander.ts +11 -8
  23. package/src/Namespace.ts +17 -21
  24. package/src/Options.ts +2 -2
  25. package/src/ParseError.ts +1 -1
  26. package/src/Parser.ts +44 -50
  27. package/src/Settings.ts +1 -1
  28. package/src/SourceLocation.ts +2 -2
  29. package/src/atoms.ts +22 -22
  30. package/src/buildCommon.ts +8 -8
  31. package/src/buildHTML.ts +12 -13
  32. package/src/buildMathML.ts +4 -4
  33. package/src/buildTree.ts +1 -1
  34. package/src/defineEnvironment.ts +1 -2
  35. package/src/defineFunction.ts +104 -112
  36. package/src/environments/array.ts +11 -15
  37. package/src/environments/cd.ts +8 -8
  38. package/src/fontMetrics.ts +2 -4
  39. package/src/functions/accent.ts +12 -15
  40. package/src/functions/accentunder.ts +4 -4
  41. package/src/functions/arrow.ts +5 -5
  42. package/src/functions/char.ts +3 -4
  43. package/src/functions/color.ts +10 -13
  44. package/src/functions/cr.ts +4 -6
  45. package/src/functions/def.ts +15 -19
  46. package/src/functions/delimsizing.ts +23 -23
  47. package/src/functions/enclose.ts +23 -34
  48. package/src/functions/environment.ts +5 -6
  49. package/src/functions/font.ts +15 -27
  50. package/src/functions/genfrac.ts +19 -23
  51. package/src/functions/hbox.ts +6 -6
  52. package/src/functions/horizBrace.ts +4 -4
  53. package/src/functions/href.ts +10 -11
  54. package/src/functions/html.ts +8 -8
  55. package/src/functions/htmlmathml.ts +5 -5
  56. package/src/functions/includegraphics.ts +7 -7
  57. package/src/functions/kern.ts +6 -6
  58. package/src/functions/lap.ts +11 -11
  59. package/src/functions/math.ts +8 -10
  60. package/src/functions/mathchoice.ts +5 -5
  61. package/src/functions/mclass.ts +16 -28
  62. package/src/functions/op.ts +16 -30
  63. package/src/functions/operatorname.ts +4 -4
  64. package/src/functions/overline.ts +4 -4
  65. package/src/functions/phantom.ts +10 -10
  66. package/src/functions/pmb.ts +5 -5
  67. package/src/functions/raisebox.ts +5 -5
  68. package/src/functions/relax.ts +4 -5
  69. package/src/functions/rule.ts +8 -8
  70. package/src/functions/sizing.ts +7 -7
  71. package/src/functions/smash.ts +6 -6
  72. package/src/functions/sqrt.ts +5 -5
  73. package/src/functions/styling.ts +5 -5
  74. package/src/functions/supsub.ts +1 -1
  75. package/src/functions/symbolsOrd.ts +3 -3
  76. package/src/functions/symbolsSpacing.ts +21 -22
  77. package/src/functions/text.ts +7 -7
  78. package/src/functions/underline.ts +5 -5
  79. package/src/functions/utils/assembleSupSub.ts +1 -1
  80. package/src/functions/vcenter.ts +5 -5
  81. package/src/functions/verb.ts +5 -5
  82. package/src/macros.ts +3 -3
  83. package/src/mathMLTree.ts +6 -10
  84. package/src/parseNode.ts +6 -480
  85. package/src/parseTree.ts +1 -6
  86. package/src/spacingData.ts +2 -1
  87. package/src/stretchy.ts +3 -3
  88. package/src/styles/katex.scss +31 -37
  89. package/src/types/index.ts +12 -0
  90. package/src/types/nodes.ts +456 -0
  91. package/src/units.ts +1 -2
  92. package/src/utils.ts +1 -1
  93. 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 {Span, Anchor} from "./domTree";
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 "./parseNode";
19
- import type {HtmlDomNode, DomSpan} from "./domTree";
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);
@@ -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
- !(ligatures.hasOwnProperty(text) && options &&
36
- ((options.fontFamily && options.fontFamily.slice(4, 6) === "tt") ||
37
- (options.font && options.font.slice(4, 6) === "tt")))) {
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 "./parseNode";
8
+ import type {AnyParseNode} from "./types/nodes";
9
9
  import type {DomSpan} from "./domTree";
10
10
 
11
11
  const optionsFromSettings = function(settings: Settings) {
@@ -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 "./parseNode";
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
  /**
@@ -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: string;
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<NODETYPE extends NodeType> = (
19
- context: FunctionContext,
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 | undefined)[],
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
- export type FunctionPropSpec = {
38
- // The number of arguments the function takes.
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
- // An array corresponding to each argument of the function, giving the
42
- // type of argument that should be parsed. Its length should be equal
43
- // to `numOptionalArgs + numArgs`, and types for optional arguments
44
- // should appear before types for mandatory arguments.
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
- // Whether it expands to a single token or a braced group of tokens.
48
- // If it's grouped, it can be used as an argument to primitive commands,
49
- // such as \sqrt (without the optional argument) and super/subscript.
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
- // Whether or not the function is allowed inside text mode
53
- // (default false)
72
+ /**
73
+ * Whether or not the function is allowed inside text mode
74
+ * (default false)
75
+ */
54
76
  allowedInText?: boolean;
55
77
 
56
- // Whether or not the function is allowed inside text mode
57
- // (default true)
78
+ /**
79
+ * Whether or not the function is allowed inside math mode
80
+ * (default true)
81
+ */
58
82
  allowedInMath?: boolean;
59
83
 
60
- // (optional) The number of optional arguments the function
61
- // should parse. If the optional arguments aren't found,
62
- // `null` will be passed to the handler in their place.
63
- // (default 0)
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
- // Must be true if the function is an infix operator.
92
+ /** Must be true if the function is an infix operator. */
67
93
  infix?: boolean;
68
94
 
69
- // Whether or not the function is a TeX primitive.
95
+ /** Whether or not the function is a TeX primitive. */
70
96
  primitive?: boolean;
71
- };
72
97
 
73
- type FunctionDefSpec<NODETYPE extends NodeType> = {
74
- // Unique string to differentiate parse nodes.
75
- // Also determines the type of the value returned by `handler`.
76
- type: NODETYPE;
77
-
78
- // The first argument to defineFunction is a single name or a list of names.
79
- // All functions named in such a list will share a single implementation.
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
- // This function returns an object representing the DOM structure to be
90
- // created when rendering the defined LaTeX function.
91
- // This should not modify the `ParseNode`.
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
- // This function returns an object representing the MathML structure to be
95
- // created when rendering the defined LaTeX function.
96
- // This should not modify the `ParseNode`.
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
- * Final function spec for use at parse time.
102
- * This is almost identical to `FunctionPropSpec`, except it
103
- * 1. includes the function handler, and
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
- export type FunctionSpec<NODETYPE extends NodeType> = {
108
- type: NODETYPE; // Need to use the type to avoid error. See NOTES below.
109
- numArgs: number;
110
- argTypes?: ArgType[];
111
- allowedInArgument: boolean;
112
- allowedInText: boolean;
113
- allowedInMath: boolean;
114
- numOptionalArgs: number;
115
- infix: boolean;
116
- primitive: boolean;
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<NODETYPE extends NodeType>({
163
- type,
164
- names,
165
- props,
166
- handler,
167
- htmlBuilder,
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
- defineFunction({
211
- type,
212
- names: [],
213
- props: {numArgs: 0},
214
- handler() { throw new Error('Should never be called.'); },
215
- htmlBuilder,
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: separationType,
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: ParseNode<"array"> =
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: ParseNode<"array"> =
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
- props: {
1128
- numArgs: 0,
1129
- allowedInText: true,
1130
- allowedInMath: true,
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`);
@@ -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 {ParseNode, AnyParseNode} from "../parseNode";
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
- props: {
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
- props: {
295
- numArgs: 1,
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.
@@ -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 in sigmasAndXis) {
261
- if (sigmasAndXis.hasOwnProperty(key)) {
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]!;
@@ -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, "textord");
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
- props: {
227
- numArgs: 1,
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
- props: {
259
- numArgs: 1,
260
- allowedInText: true,
261
- allowedInMath: true, // unless in strict mode
262
- argTypes: ["primitive"],
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
  });