katex 0.16.28 → 0.16.30

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 (84) hide show
  1. package/README.md +3 -3
  2. package/cli.js +3 -1
  3. package/contrib/auto-render/auto-render.js +5 -5
  4. package/contrib/auto-render/index.html +3 -2
  5. package/contrib/copy-tex/README.md +2 -2
  6. package/contrib/mathtex-script-type/README.md +5 -5
  7. package/contrib/mhchem/README.md +1 -1
  8. package/dist/README.md +3 -3
  9. package/dist/contrib/auto-render.js +4 -4
  10. package/dist/contrib/auto-render.min.js +1 -1
  11. package/dist/contrib/auto-render.mjs +2 -2
  12. package/dist/contrib/copy-tex.js +2 -2
  13. package/dist/contrib/copy-tex.min.js +1 -1
  14. package/dist/contrib/mathtex-script-type.min.js +1 -1
  15. package/dist/contrib/mhchem.min.js +1 -1
  16. package/dist/contrib/render-a11y-string.min.js +1 -1
  17. package/dist/katex-swap.css +7 -5
  18. package/dist/katex-swap.min.css +1 -1
  19. package/dist/katex.css +6 -4
  20. package/dist/katex.js +460 -555
  21. package/dist/katex.min.css +1 -1
  22. package/dist/katex.min.js +1 -1
  23. package/dist/katex.mjs +415 -508
  24. package/katex.js +2 -2
  25. package/package.json +3 -4
  26. package/src/MacroExpander.js +2 -2
  27. package/src/Parser.js +4 -3
  28. package/src/Settings.js +2 -2
  29. package/src/buildCommon.js +15 -33
  30. package/src/buildHTML.js +11 -9
  31. package/src/buildMathML.js +17 -15
  32. package/src/buildTree.js +5 -5
  33. package/src/delimiter.js +32 -40
  34. package/src/domTree.js +17 -17
  35. package/src/environments/array.js +40 -39
  36. package/src/environments/cd.js +10 -10
  37. package/src/functions/accent.js +17 -17
  38. package/src/functions/accentunder.js +8 -8
  39. package/src/functions/arrow.js +16 -16
  40. package/src/functions/color.js +4 -4
  41. package/src/functions/cr.js +4 -4
  42. package/src/functions/delimsizing.js +18 -19
  43. package/src/functions/enclose.js +15 -15
  44. package/src/functions/font.js +2 -3
  45. package/src/functions/genfrac.js +25 -20
  46. package/src/functions/hbox.js +4 -4
  47. package/src/functions/horizBrace.js +12 -12
  48. package/src/functions/href.js +2 -2
  49. package/src/functions/html.js +2 -2
  50. package/src/functions/htmlmathml.js +3 -2
  51. package/src/functions/includegraphics.js +2 -2
  52. package/src/functions/kern.js +4 -4
  53. package/src/functions/lap.js +11 -11
  54. package/src/functions/mathchoice.js +2 -2
  55. package/src/functions/mclass.js +10 -12
  56. package/src/functions/op.js +20 -20
  57. package/src/functions/operatorname.js +12 -12
  58. package/src/functions/ordgroup.js +3 -3
  59. package/src/functions/overline.js +8 -8
  60. package/src/functions/phantom.js +14 -14
  61. package/src/functions/pmb.js +4 -4
  62. package/src/functions/raisebox.js +4 -4
  63. package/src/functions/rule.js +5 -5
  64. package/src/functions/sizing.js +4 -4
  65. package/src/functions/smash.js +6 -6
  66. package/src/functions/sqrt.js +12 -12
  67. package/src/functions/styling.js +2 -2
  68. package/src/functions/supsub.js +13 -13
  69. package/src/functions/symbolsOp.js +4 -4
  70. package/src/functions/symbolsOrd.js +9 -9
  71. package/src/functions/symbolsSpacing.js +9 -9
  72. package/src/functions/tag.js +6 -6
  73. package/src/functions/text.js +2 -2
  74. package/src/functions/underline.js +8 -8
  75. package/src/functions/utils/assembleSupSub.js +9 -9
  76. package/src/functions/vcenter.js +4 -4
  77. package/src/functions/verb.js +7 -7
  78. package/src/macros.js +5 -2
  79. package/src/mathMLTree.js +5 -12
  80. package/src/stretchy.js +18 -28
  81. package/src/styles/fonts.scss +5 -3
  82. package/src/styles/katex-swap.scss +4 -1
  83. package/src/styles/katex.scss +6 -4
  84. package/src/utils.js +10 -41
@@ -1,7 +1,7 @@
1
1
  // @flow
2
2
  import defineFunction from "../defineFunction";
3
- import buildCommon from "../buildCommon";
4
- import mathMLTree from "../mathMLTree";
3
+ import {makeLineSpan, makeSpan, makeVList} from "../buildCommon";
4
+ import {MathNode, TextNode} from "../mathMLTree";
5
5
 
6
6
  import * as html from "../buildHTML";
7
7
  import * as mml from "../buildMathML";
@@ -26,11 +26,11 @@ defineFunction({
26
26
  const innerGroup = html.buildGroup(group.body, options);
27
27
 
28
28
  // Create the line to go below the body
29
- const line = buildCommon.makeLineSpan("underline-line", options);
29
+ const line = makeLineSpan("underline-line", options);
30
30
 
31
31
  // Generate the vlist, with the appropriate kerns
32
32
  const defaultRuleThickness = options.fontMetrics().defaultRuleThickness;
33
- const vlist = buildCommon.makeVList({
33
+ const vlist = makeVList({
34
34
  positionType: "top",
35
35
  positionData: innerGroup.height,
36
36
  children: [
@@ -41,14 +41,14 @@ defineFunction({
41
41
  ],
42
42
  }, options);
43
43
 
44
- return buildCommon.makeSpan(["mord", "underline"], [vlist], options);
44
+ return makeSpan(["mord", "underline"], [vlist], options);
45
45
  },
46
46
  mathmlBuilder(group, options) {
47
- const operator = new mathMLTree.MathNode(
48
- "mo", [new mathMLTree.TextNode("\u203e")]);
47
+ const operator = new MathNode(
48
+ "mo", [new TextNode("\u203e")]);
49
49
  operator.setAttribute("stretchy", "true");
50
50
 
51
- const node = new mathMLTree.MathNode(
51
+ const node = new MathNode(
52
52
  "munder",
53
53
  [mml.buildGroup(group.body, options), operator]);
54
54
  node.setAttribute("accentunder", "true");
@@ -1,7 +1,7 @@
1
1
  // @flow
2
- import buildCommon from "../../buildCommon";
2
+ import {makeSpan, makeVList} from "../../buildCommon";
3
3
  import * as html from "../../buildHTML";
4
- import utils from "../../utils";
4
+ import {isCharacterBox} from "../../utils";
5
5
  import type {StyleInterface} from "../../Style";
6
6
  import type Options from "../../Options";
7
7
  import type {DomSpan, SymbolNode} from "../../domTree";
@@ -19,8 +19,8 @@ export const assembleSupSub = (
19
19
  slant: number,
20
20
  baseShift: number,
21
21
  ): DomSpan => {
22
- base = buildCommon.makeSpan([], [base]);
23
- const subIsSingleCharacter = subGroup && utils.isCharacterBox(subGroup);
22
+ base = makeSpan([], [base]);
23
+ const subIsSingleCharacter = subGroup && isCharacterBox(subGroup);
24
24
  let sub;
25
25
  let sup;
26
26
  // We manually have to handle the superscripts and subscripts. This,
@@ -58,7 +58,7 @@ export const assembleSupSub = (
58
58
  sub.kern +
59
59
  base.depth + baseShift;
60
60
 
61
- finalGroup = buildCommon.makeVList({
61
+ finalGroup = makeVList({
62
62
  positionType: "bottom",
63
63
  positionData: bottom,
64
64
  children: [
@@ -78,7 +78,7 @@ export const assembleSupSub = (
78
78
  // that we are supposed to shift the limits by 1/2 of the slant,
79
79
  // but since we are centering the limits adding a full slant of
80
80
  // margin will shift by 1/2 that.
81
- finalGroup = buildCommon.makeVList({
81
+ finalGroup = makeVList({
82
82
  positionType: "top",
83
83
  positionData: top,
84
84
  children: [
@@ -91,7 +91,7 @@ export const assembleSupSub = (
91
91
  } else if (sup) {
92
92
  const bottom = base.depth + baseShift;
93
93
 
94
- finalGroup = buildCommon.makeVList({
94
+ finalGroup = makeVList({
95
95
  positionType: "bottom",
96
96
  positionData: bottom,
97
97
  children: [
@@ -112,9 +112,9 @@ export const assembleSupSub = (
112
112
  if (sub && slant !== 0 && !subIsSingleCharacter) {
113
113
  // A negative margin-left was applied to the lower limit.
114
114
  // Avoid an overlap by placing a spacer on the left on the group.
115
- const spacer = buildCommon.makeSpan(["mspace"], [], options);
115
+ const spacer = makeSpan(["mspace"], [], options);
116
116
  spacer.style.marginRight = makeEm(slant);
117
117
  parts.unshift(spacer);
118
118
  }
119
- return buildCommon.makeSpan(["mop", "op-limits"], parts, options);
119
+ return makeSpan(["mop", "op-limits"], parts, options);
120
120
  };
@@ -1,7 +1,7 @@
1
1
  // @flow
2
2
  import defineFunction from "../defineFunction";
3
- import buildCommon from "../buildCommon";
4
- import mathMLTree from "../mathMLTree";
3
+ import {makeVList} from "../buildCommon";
4
+ import {MathNode} from "../mathMLTree";
5
5
 
6
6
  import * as html from "../buildHTML";
7
7
  import * as mml from "../buildMathML";
@@ -27,7 +27,7 @@ defineFunction({
27
27
  const body = html.buildGroup(group.body, options);
28
28
  const axisHeight = options.fontMetrics().axisHeight;
29
29
  const dy = 0.5 * ((body.height - axisHeight) - (body.depth + axisHeight));
30
- return buildCommon.makeVList({
30
+ return makeVList({
31
31
  positionType: "shift",
32
32
  positionData: dy,
33
33
  children: [{type: "elem", elem: body}],
@@ -37,7 +37,7 @@ defineFunction({
37
37
  // There is no way to do this in MathML.
38
38
  // Write a class as a breadcrumb in case some post-processor wants
39
39
  // to perform a vcenter adjustment.
40
- return new mathMLTree.MathNode(
40
+ return new MathNode(
41
41
  "mpadded", [mml.buildGroup(group.body, options)], ["vcenter"]);
42
42
  },
43
43
  });
@@ -1,7 +1,7 @@
1
1
  // @flow
2
2
  import defineFunction from "../defineFunction";
3
- import buildCommon from "../buildCommon";
4
- import mathMLTree from "../mathMLTree";
3
+ import {makeSpan, makeSymbol, tryCombineChars} from "../buildCommon";
4
+ import {MathNode, TextNode} from "../mathMLTree";
5
5
  import ParseError from "../ParseError";
6
6
 
7
7
  import type {ParseNode} from "../parseNode";
@@ -31,18 +31,18 @@ defineFunction({
31
31
  if (c === '~') {
32
32
  c = '\\textasciitilde';
33
33
  }
34
- body.push(buildCommon.makeSymbol(c, "Typewriter-Regular",
34
+ body.push(makeSymbol(c, "Typewriter-Regular",
35
35
  group.mode, newOptions, ["mord", "texttt"]));
36
36
  }
37
- return buildCommon.makeSpan(
37
+ return makeSpan(
38
38
  ["mord", "text"].concat(newOptions.sizingClasses(options)),
39
- buildCommon.tryCombineChars(body),
39
+ tryCombineChars(body),
40
40
  newOptions,
41
41
  );
42
42
  },
43
43
  mathmlBuilder(group, options) {
44
- const text = new mathMLTree.TextNode(makeVerb(group));
45
- const node = new mathMLTree.MathNode("mtext", [text]);
44
+ const text = new TextNode(makeVerb(group));
45
+ const node = new MathNode("mtext", [text]);
46
46
  node.setAttribute("mathvariant", "monospace");
47
47
  return node;
48
48
  },
package/src/macros.js CHANGED
@@ -287,7 +287,8 @@ defineMacro("\\underbar", "\\underline{\\text{#1}}");
287
287
  // It's thus treated like a \mathrel, but defined by a symbol that has zero
288
288
  // width but extends to the right. We use \rlap to get that spacing.
289
289
  // For MathML we write U+0338 here. buildMathML.js will then do the overlay.
290
- defineMacro("\\not", '\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}');
290
+ defineMacro("\\not", "\\html@mathml{\\mathrel{\\mathrlap\\@not}\\nobreak}" +
291
+ "{\\char\"338}");
291
292
 
292
293
  // Negated symbols from base/fontmath.ltx:
293
294
  // \def\neq{\not=} \let\ne=\neq
@@ -449,6 +450,8 @@ const dotsByToken = {
449
450
  '\\DOTSX': '\\dotsx',
450
451
  };
451
452
 
453
+ const dotsbGroups = new Set(['bin', 'rel']);
454
+
452
455
  defineMacro("\\dots", function(context) {
453
456
  // TODO: If used in text mode, should expand to \textellipsis.
454
457
  // However, in KaTeX, \textellipsis and \ldots behave the same
@@ -462,7 +465,7 @@ defineMacro("\\dots", function(context) {
462
465
  } else if (next.slice(0, 4) === '\\not') {
463
466
  thedots = '\\dotsb';
464
467
  } else if (next in symbols.math) {
465
- if (['bin', 'rel'].includes(symbols.math[next].group)) {
468
+ if (dotsbGroups.has(symbols.math[next].group)) {
466
469
  thedots = '\\dotsb';
467
470
  }
468
471
  }
package/src/mathMLTree.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * domTree.js, creating namespaced DOM nodes and HTML text markup respectively.
10
10
  */
11
11
 
12
- import utils from "./utils";
12
+ import {escape} from "./utils";
13
13
  import {DocumentFragment} from "./tree";
14
14
  import {createClass} from "./domTree";
15
15
  import {makeEm} from "./units";
@@ -122,13 +122,13 @@ export class MathNode implements MathDomNode {
122
122
  for (const attr in this.attributes) {
123
123
  if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
124
124
  markup += " " + attr + "=\"";
125
- markup += utils.escape(this.attributes[attr]);
125
+ markup += escape(this.attributes[attr]);
126
126
  markup += "\"";
127
127
  }
128
128
  }
129
129
 
130
130
  if (this.classes.length > 0) {
131
- markup += ` class ="${utils.escape(createClass(this.classes))}"`;
131
+ markup += ` class ="${escape(createClass(this.classes))}"`;
132
132
  }
133
133
 
134
134
  markup += ">";
@@ -172,7 +172,7 @@ export class TextNode implements MathDomNode {
172
172
  * (representing the text itself).
173
173
  */
174
174
  toMarkup(): string {
175
- return utils.escape(this.toText());
175
+ return escape(this.toText());
176
176
  }
177
177
 
178
178
  /**
@@ -188,7 +188,7 @@ export class TextNode implements MathDomNode {
188
188
  * This node represents a space, but may render as <mspace.../> or as text,
189
189
  * depending on the width.
190
190
  */
191
- class SpaceNode implements MathDomNode {
191
+ export class SpaceNode implements MathDomNode {
192
192
  width: number;
193
193
  character: ?string;
194
194
 
@@ -258,10 +258,3 @@ class SpaceNode implements MathDomNode {
258
258
  }
259
259
  }
260
260
  }
261
-
262
- export default {
263
- MathNode,
264
- TextNode,
265
- SpaceNode,
266
- newDocumentFragment,
267
- };
package/src/stretchy.js CHANGED
@@ -6,12 +6,12 @@
6
6
  */
7
7
 
8
8
  import {LineNode, PathNode, SvgNode} from "./domTree";
9
- import buildCommon from "./buildCommon";
10
- import mathMLTree from "./mathMLTree";
9
+ import {makeSpan, makeSvgSpan} from "./buildCommon";
10
+ import {MathNode, TextNode} from "./mathMLTree";
11
11
  import {makeEm} from "./units";
12
12
 
13
13
  import type Options from "./Options";
14
- import type {ParseNode, AnyParseNode} from "./parseNode";
14
+ import type {ParseNode} from "./parseNode";
15
15
  import type {DomSpan, HtmlDomNode, SvgSpan} from "./domTree";
16
16
 
17
17
  const stretchyCodePoint: {[string]: string} = {
@@ -59,10 +59,10 @@ const stretchyCodePoint: {[string]: string} = {
59
59
  "\\cdlongequal": "=",
60
60
  };
61
61
 
62
- const mathMLnode = function(label: string): mathMLTree.MathNode {
63
- const node = new mathMLTree.MathNode(
62
+ export const stretchyMathML = function(label: string): MathNode {
63
+ const node = new MathNode(
64
64
  "mo",
65
- [new mathMLTree.TextNode(stretchyCodePoint[label.replace(/^\\/, '')])],
65
+ [new TextNode(stretchyCodePoint[label.replace(/^\\/, '')])],
66
66
  );
67
67
  node.setAttribute("stretchy", "true");
68
68
  return node;
@@ -170,15 +170,10 @@ const katexImagesData: {
170
170
  "shortrightharpoonabovebar"], 1.75, 716],
171
171
  };
172
172
 
173
- const groupLength = function(arg: AnyParseNode): number {
174
- if (arg.type === "ordgroup") {
175
- return arg.body.length;
176
- } else {
177
- return 1;
178
- }
179
- };
173
+ const wideAccentLabels =
174
+ new Set(["widehat", "widecheck", "widetilde", "utilde"]);
180
175
 
181
- const svgSpan = function(
176
+ export const stretchySvg = function(
182
177
  group: ParseNode<"accent"> | ParseNode<"accentUnder"> | ParseNode<"xArrow">
183
178
  | ParseNode<"horizBrace">,
184
179
  options: Options,
@@ -191,14 +186,15 @@ const svgSpan = function(
191
186
  } {
192
187
  let viewBoxWidth = 400000; // default
193
188
  const label = group.label.slice(1);
194
- if (["widehat", "widecheck", "widetilde", "utilde"].includes(label)) {
189
+ if (wideAccentLabels.has(label)) {
195
190
  // Each type in the `if` statement corresponds to one of the ParseNode
196
191
  // types below. This narrowing is required to access `grp.base`.
197
192
  // $FlowFixMe
198
193
  const grp: ParseNode<"accent"> | ParseNode<"accentUnder"> = group;
199
194
  // There are four SVG images available for each function.
200
195
  // Choose a taller image when there are more characters.
201
- const numChars = groupLength(grp.base);
196
+ const numChars = grp.base.type === "ordgroup" ?
197
+ grp.base.body.length : 1;
202
198
  let viewBoxHeight;
203
199
  let pathName;
204
200
  let height;
@@ -237,7 +233,7 @@ const svgSpan = function(
237
233
  "preserveAspectRatio": "none",
238
234
  });
239
235
  return {
240
- span: buildCommon.makeSvgSpan([], [svgNode], options),
236
+ span: makeSvgSpan([], [svgNode], options),
241
237
  minWidth: 0,
242
238
  height,
243
239
  };
@@ -278,7 +274,7 @@ const svgSpan = function(
278
274
  "preserveAspectRatio": aligns[i] + " slice",
279
275
  });
280
276
 
281
- const span = buildCommon.makeSvgSpan(
277
+ const span = makeSvgSpan(
282
278
  [widthClasses[i]], [svgNode], options);
283
279
  if (numSvgChildren === 1) {
284
280
  return {span, minWidth, height};
@@ -289,7 +285,7 @@ const svgSpan = function(
289
285
  }
290
286
 
291
287
  return {
292
- span: buildCommon.makeSpan(["stretchy"], spans, options),
288
+ span: makeSpan(["stretchy"], spans, options),
293
289
  minWidth,
294
290
  height,
295
291
  };
@@ -308,7 +304,7 @@ const svgSpan = function(
308
304
  return span;
309
305
  };
310
306
 
311
- const encloseSpan = function(
307
+ export const stretchyEnclose = function(
312
308
  inner: HtmlDomNode,
313
309
  label: string,
314
310
  topPad: number,
@@ -320,7 +316,7 @@ const encloseSpan = function(
320
316
  const totalHeight = inner.height + inner.depth + topPad + bottomPad;
321
317
 
322
318
  if (/fbox|color|angl/.test(label)) {
323
- img = buildCommon.makeSpan(["stretchy", label], [], options);
319
+ img = makeSpan(["stretchy", label], [], options);
324
320
 
325
321
  if (label === "fbox") {
326
322
  const color = options.color && options.getColor();
@@ -360,7 +356,7 @@ const encloseSpan = function(
360
356
  "height": makeEm(totalHeight),
361
357
  });
362
358
 
363
- img = buildCommon.makeSvgSpan([], [svgNode], options);
359
+ img = makeSvgSpan([], [svgNode], options);
364
360
  }
365
361
 
366
362
  img.height = totalHeight;
@@ -368,9 +364,3 @@ const encloseSpan = function(
368
364
 
369
365
  return img;
370
366
  };
371
-
372
- export default {
373
- encloseSpan,
374
- mathMLnode,
375
- svgSpan,
376
- };
@@ -1,3 +1,5 @@
1
+ @use "sass:list";
2
+
1
3
  $font-folder: "../../fonts" !default;
2
4
  $use-woff2: true !default;
3
5
  $use-woff: true !default;
@@ -7,13 +9,13 @@ $font-display: block !default;
7
9
  @function generate-src($family, $family-suffix) {
8
10
  $src: null;
9
11
  @if $use-woff2 {
10
- $src: append($src, url('#{$font-folder}/KaTeX_#{$family}-#{$family-suffix}.woff2') format('woff2'), comma);
12
+ $src: list.append($src, url('#{$font-folder}/KaTeX_#{$family}-#{$family-suffix}.woff2') format('woff2'), comma);
11
13
  }
12
14
  @if $use-woff {
13
- $src: append($src, url('#{$font-folder}/KaTeX_#{$family}-#{$family-suffix}.woff') format('woff'), comma);
15
+ $src: list.append($src, url('#{$font-folder}/KaTeX_#{$family}-#{$family-suffix}.woff') format('woff'), comma);
14
16
  }
15
17
  @if $use-ttf {
16
- $src: append($src, url('#{$font-folder}/KaTeX_#{$family}-#{$family-suffix}.ttf') format('truetype'), comma);
18
+ $src: list.append($src, url('#{$font-folder}/KaTeX_#{$family}-#{$family-suffix}.ttf') format('truetype'), comma);
17
19
  }
18
20
 
19
21
  @return $src;
@@ -1,4 +1,7 @@
1
- @use 'katex' with (
1
+ @use 'fonts.scss' with (
2
2
  $font-display: swap,
3
+ );
4
+
5
+ @use 'katex' with (
3
6
  $version: $version,
4
7
  );
@@ -1,5 +1,7 @@
1
1
  /* stylelint-disable font-family-no-missing-generic-family-keyword */
2
- @import "./fonts.scss";
2
+ @use "sass:list";
3
+ @use "sass:math";
4
+ @use "fonts.scss";
3
5
 
4
6
  // The mu unit is defined as 1/18 em
5
7
  $mu: calc(1em / 18);
@@ -341,11 +343,11 @@ $display-margin: 1em 0 !default;
341
343
  .fontsize-ensurer {
342
344
  $sizes: 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.2, 1.44, 1.728, 2.074, 2.488;
343
345
 
344
- @for $from from 1 through length($sizes) {
345
- @for $to from 1 through length($sizes) {
346
+ @for $from from 1 through list.length($sizes) {
347
+ @for $to from 1 through list.length($sizes) {
346
348
  &.reset-size#{$from}.size#{$to} {
347
349
  /* stylelint-disable-next-line */
348
- font-size: calc((nth($sizes, $to) / nth($sizes, $from)) * 1em);
350
+ font-size: calc(math.div(list.nth($sizes, $to), list.nth($sizes, $from)) * 1em);
349
351
  }
350
352
  }
351
353
  }
package/src/utils.js CHANGED
@@ -6,20 +6,10 @@
6
6
 
7
7
  import type {AnyParseNode} from "./parseNode";
8
8
 
9
- /**
10
- * Provide a default value if a setting is undefined
11
- * NOTE: Couldn't use `T` as the output type due to facebook/flow#5022.
12
- */
13
- const deflt = function<T>(setting: T | void, defaultIfUndefined: T): * {
14
- return setting === undefined ? defaultIfUndefined : setting;
15
- };
16
-
17
9
  // hyphenate and escape adapted from Facebook's React under Apache 2 license
18
-
19
10
  const uppercase = /([A-Z])/g;
20
- const hyphenate = function(str: string): string {
21
- return str.replace(uppercase, "-$1").toLowerCase();
22
- };
11
+ export const hyphenate = (str: string): string =>
12
+ str.replace(uppercase, "-$1").toLowerCase();
23
13
 
24
14
  const ESCAPE_LOOKUP = {
25
15
  "&": "&amp;",
@@ -34,16 +24,15 @@ const ESCAPE_REGEX = /[&><"']/g;
34
24
  /**
35
25
  * Escapes text to prevent scripting attacks.
36
26
  */
37
- function escape(text: mixed): string {
38
- return String(text).replace(ESCAPE_REGEX, match => ESCAPE_LOOKUP[match]);
39
- }
27
+ export const escape = (text: mixed): string =>
28
+ String(text).replace(ESCAPE_REGEX, match => ESCAPE_LOOKUP[match]);
40
29
 
41
30
  /**
42
31
  * Sometimes we want to pull out the innermost element of a group. In most
43
32
  * cases, this will just be the group itself, but when ordgroups and colors have
44
33
  * a single element, we want to pull that out.
45
34
  */
46
- const getBaseElem = function(group: AnyParseNode): AnyParseNode {
35
+ export const getBaseElem = (group: AnyParseNode): AnyParseNode => {
47
36
  if (group.type === "ordgroup") {
48
37
  if (group.body.length === 1) {
49
38
  return getBaseElem(group.body[0]);
@@ -63,33 +52,22 @@ const getBaseElem = function(group: AnyParseNode): AnyParseNode {
63
52
  }
64
53
  };
65
54
 
55
+ const characterNodesTypes = new Set(["mathord", "textord", "atom"]);
56
+
66
57
  /**
67
58
  * TeXbook algorithms often reference "character boxes", which are simply groups
68
59
  * with a single character in them. To decide if something is a character box,
69
60
  * we find its innermost group, and see if it is a single character.
70
61
  */
71
- const isCharacterBox = function(group: AnyParseNode): boolean {
72
- const baseElem = getBaseElem(group);
73
-
74
- // These are all they types of groups which hold single characters
75
- return baseElem.type === "mathord" ||
76
- baseElem.type === "textord" ||
77
- baseElem.type === "atom";
78
- };
79
-
80
- export const assert = function<T>(value: ?T): T {
81
- if (!value) {
82
- throw new Error('Expected non-null, but got ' + String(value));
83
- }
84
- return value;
85
- };
62
+ export const isCharacterBox = (group: AnyParseNode): boolean =>
63
+ characterNodesTypes.has(getBaseElem(group).type);
86
64
 
87
65
  /**
88
66
  * Return the protocol of a URL, or "_relative" if the URL does not specify a
89
67
  * protocol (and thus is relative), or `null` if URL has invalid protocol
90
68
  * (so should be outright rejected).
91
69
  */
92
- export const protocolFromUrl = function(url: string): string | null {
70
+ export const protocolFromUrl = (url: string): string | null => {
93
71
  // Check for possible leading protocol.
94
72
  // https://url.spec.whatwg.org/#url-parsing strips leading whitespace
95
73
  // (U+20) or C0 control (U+00-U+1F) characters.
@@ -111,12 +89,3 @@ export const protocolFromUrl = function(url: string): string | null {
111
89
  // Lowercase the protocol
112
90
  return protocol[1].toLowerCase();
113
91
  };
114
-
115
- export default {
116
- deflt,
117
- escape,
118
- hyphenate,
119
- getBaseElem,
120
- isCharacterBox,
121
- protocolFromUrl,
122
- };