katex 0.16.45 → 0.16.46

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 (59) hide show
  1. package/README.md +3 -3
  2. package/contrib/copy-tex/README.md +2 -2
  3. package/contrib/mathtex-script-type/README.md +5 -5
  4. package/contrib/mathtex-script-type/mathtex-script-type.js +2 -1
  5. package/contrib/mhchem/README.md +1 -1
  6. package/contrib/render-a11y-string/render-a11y-string.ts +7 -5
  7. package/contrib/render-a11y-string/test/render-a11y-string-spec.ts +0 -1
  8. package/dist/README.md +3 -3
  9. package/dist/contrib/mathtex-script-type.js +2 -1
  10. package/dist/contrib/mathtex-script-type.min.js +1 -1
  11. package/dist/contrib/mathtex-script-type.mjs +2 -1
  12. package/dist/contrib/render-a11y-string.js +47 -8
  13. package/dist/contrib/render-a11y-string.min.js +1 -1
  14. package/dist/contrib/render-a11y-string.mjs +27 -2
  15. package/dist/katex-swap.css +5 -2
  16. package/dist/katex-swap.min.css +1 -1
  17. package/dist/katex.css +5 -2
  18. package/dist/katex.js +519 -315
  19. package/dist/katex.min.css +1 -1
  20. package/dist/katex.min.js +1 -1
  21. package/dist/katex.mjs +491 -320
  22. package/package.json +15 -15
  23. package/src/Options.ts +29 -28
  24. package/src/Parser.ts +12 -15
  25. package/src/Settings.ts +177 -60
  26. package/src/atoms.ts +33 -0
  27. package/src/buildCommon.ts +54 -46
  28. package/src/buildHTML.ts +4 -3
  29. package/src/buildMathML.ts +54 -47
  30. package/src/defineEnvironment.ts +1 -1
  31. package/src/defineFunction.ts +10 -3
  32. package/src/delimiter.ts +17 -13
  33. package/src/domTree.ts +28 -23
  34. package/src/environments/array.ts +12 -6
  35. package/src/environments/cd.ts +9 -2
  36. package/src/fontMetrics.ts +10 -23
  37. package/src/fontMetricsData.d.ts +6 -1
  38. package/src/functions/arrow.ts +4 -5
  39. package/src/functions/delimsizing.ts +22 -16
  40. package/src/functions/enclose.ts +6 -6
  41. package/src/functions/environment.ts +7 -2
  42. package/src/functions/font.ts +13 -8
  43. package/src/functions/hbox.ts +2 -2
  44. package/src/functions/horizBrace.ts +4 -6
  45. package/src/functions/math.ts +1 -0
  46. package/src/functions/op.ts +10 -5
  47. package/src/functions/smash.ts +1 -1
  48. package/src/functions/styling.ts +17 -5
  49. package/src/functions/supsub.ts +6 -3
  50. package/src/functions/text.ts +7 -3
  51. package/src/parseNode.ts +7 -5
  52. package/src/stretchy.ts +14 -14
  53. package/src/styles/katex.scss +3 -1
  54. package/src/symbols.ts +11 -26
  55. package/src/tree.ts +11 -5
  56. package/src/types/fonts.ts +73 -0
  57. package/src/{types.ts → types/index.ts} +4 -10
  58. package/src/utils.ts +0 -1
  59. package/src/wide-character.ts +101 -55
package/dist/katex.mjs CHANGED
@@ -7,10 +7,6 @@
7
7
  * about where in the source string the problem occurred.
8
8
  */
9
9
  class ParseError extends Error {
10
- // Error start position based on passed-in Token or ParseNode.
11
-
12
- // Length of affected text based on passed-in Token or ParseNode.
13
-
14
10
  // The underlying error message without any context added.
15
11
  constructor(message,
16
12
  // The error message
@@ -50,6 +46,11 @@ class ParseError extends Error {
50
46
  }
51
47
  super(error);
52
48
  this.name = "ParseError";
49
+ this.position = void 0;
50
+ // Error start position based on passed-in Token or ParseNode.
51
+ this.length = void 0;
52
+ // Length of affected text based on passed-in Token or ParseNode.
53
+ this.rawMessage = void 0;
53
54
  Object.setPrototypeOf(this, ParseError.prototype);
54
55
  this.position = start;
55
56
  if (start != null && end != null) {
@@ -118,7 +119,6 @@ var protocolFromUrl = url => {
118
119
  // Check for possible leading protocol.
119
120
  // https://url.spec.whatwg.org/#url-parsing strips leading whitespace
120
121
  // (U+20) or C0 control (U+00-U+1F) characters.
121
- // eslint-disable-next-line no-control-regex
122
122
  var protocol = /^[\x00-\x20]*([^\\/#?]*?)(:|&#0*58|&#x0*3a|&colon)/i.exec(url);
123
123
  if (!protocol) {
124
124
  return "_relative";
@@ -230,16 +230,11 @@ var SETTINGS_SCHEMA = {
230
230
  cli: false
231
231
  }
232
232
  };
233
- function getDefaultValue(schema) {
234
- if ("default" in schema) {
235
- return schema.default;
233
+ function getImplicitDefault(type) {
234
+ if (typeof type !== 'string') {
235
+ return type.enum[0];
236
236
  }
237
- var type = schema.type;
238
- var defaultType = Array.isArray(type) ? type[0] : type;
239
- if (typeof defaultType !== 'string') {
240
- return defaultType.enum[0];
241
- }
242
- switch (defaultType) {
237
+ switch (type) {
243
238
  case 'boolean':
244
239
  return false;
245
240
  case 'string':
@@ -248,7 +243,20 @@ function getDefaultValue(schema) {
248
243
  return 0;
249
244
  case 'object':
250
245
  return {};
246
+ default:
247
+ throw new Error("Unexpected schema type; settings must declare an explicit default.");
248
+ }
249
+ }
250
+ function getDefaultValue(schema) {
251
+ if (schema.default !== undefined) {
252
+ return schema.default;
251
253
  }
254
+ var type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
255
+ return getImplicitDefault(type);
256
+ }
257
+ function applySetting(target, prop, options, schema) {
258
+ var optionValue = options[prop];
259
+ target[prop] = optionValue !== undefined ? schema.processor ? schema.processor(optionValue) : optionValue : getDefaultValue(schema);
252
260
  }
253
261
  /**
254
262
  * The main Settings object
@@ -265,13 +273,28 @@ class Settings {
265
273
  if (options === void 0) {
266
274
  options = {};
267
275
  }
276
+ this.displayMode = void 0;
277
+ this.output = void 0;
278
+ this.leqno = void 0;
279
+ this.fleqn = void 0;
280
+ this.throwOnError = void 0;
281
+ this.errorColor = void 0;
282
+ this.macros = void 0;
283
+ this.minRuleThickness = void 0;
284
+ this.colorIsTextColor = void 0;
285
+ this.strict = void 0;
286
+ this.trust = void 0;
287
+ this.maxSize = void 0;
288
+ this.maxExpand = void 0;
289
+ this.globalGroup = void 0;
268
290
  // allow null options
269
291
  options = options || {};
270
292
  for (var prop of Object.keys(SETTINGS_SCHEMA)) {
271
293
  var schema = SETTINGS_SCHEMA[prop];
272
- var optionValue = options[prop];
273
- // TODO: validate options
274
- this[prop] = optionValue !== undefined ? schema.processor ? schema.processor(optionValue) : optionValue : getDefaultValue(schema);
294
+ if (schema) {
295
+ // TODO: validate options
296
+ applySetting(this, prop, options, schema);
297
+ }
275
298
  }
276
299
  }
277
300
  /**
@@ -364,6 +387,9 @@ class Settings {
364
387
  */
365
388
  class Style {
366
389
  constructor(id, size, cramped) {
390
+ this.id = void 0;
391
+ this.size = void 0;
392
+ this.cramped = void 0;
367
393
  this.id = id;
368
394
  this.size = size;
369
395
  this.cramped = cramped;
@@ -769,6 +795,9 @@ var tallDelim = function tallDelim(label, midHeight) {
769
795
  }
770
796
  };
771
797
 
798
+ function isMathDomNode(node) {
799
+ return 'toText' in node;
800
+ }
772
801
  /**
773
802
  * This node represents a document fragment, which contains elements, but when
774
803
  * placed into the DOM doesn't have any representation itself. It only contains
@@ -777,6 +806,12 @@ var tallDelim = function tallDelim(label, midHeight) {
777
806
  class DocumentFragment {
778
807
  // Never used; needed for satisfying interface.
779
808
  constructor(children) {
809
+ this.children = void 0;
810
+ this.classes = void 0;
811
+ this.height = void 0;
812
+ this.depth = void 0;
813
+ this.maxFontSize = void 0;
814
+ this.style = void 0;
780
815
  this.children = children;
781
816
  this.classes = [];
782
817
  this.height = 0;
@@ -809,11 +844,12 @@ class DocumentFragment {
809
844
  * MathDomNode's only.
810
845
  */
811
846
  toText() {
812
- // To avoid this, we would subclass documentFragment separately for
813
- // MathML, but polyfills for subclassing is expensive per PR 1469.
814
- // TODO(ts): Only works for ChildType = MathDomNode.
815
- var toText = child => child.toText();
816
- return this.children.map(toText).join("");
847
+ return this.children.map(child => {
848
+ if (isMathDomNode(child)) {
849
+ return child.toText();
850
+ }
851
+ throw new Error("Expected MathDomNode with toText, got " + child.constructor.name);
852
+ }).join("");
817
853
  }
818
854
  }
819
855
 
@@ -941,6 +977,20 @@ var makeEm = function makeEm(n) {
941
977
  var createClass = function createClass(classes) {
942
978
  return classes.filter(cls => cls).join(" ");
943
979
  };
980
+ /**
981
+ * Serialize a CssStyle object into a semicolon-delimited inline-style string
982
+ * (hyphenating camelCase property names). Returns "" when no property is set.
983
+ */
984
+ var cssStyleToString = function cssStyleToString(style) {
985
+ var styles = "";
986
+ for (var key of Object.keys(style)) {
987
+ var value = style[key];
988
+ if (value !== undefined) {
989
+ styles += hyphenate(key) + ":" + value + ";";
990
+ }
991
+ }
992
+ return styles;
993
+ };
944
994
  var initNode = function initNode(classes, options, style) {
945
995
  this.classes = classes || [];
946
996
  this.attributes = {};
@@ -966,9 +1016,7 @@ var toNode = function toNode(tagName) {
966
1016
  // Apply the class
967
1017
  node.className = createClass(this.classes);
968
1018
  // Apply inline styles
969
- for (var key of Object.keys(this.style)) {
970
- node.style[key] = this.style[key];
971
- }
1019
+ Object.assign(node.style, this.style);
972
1020
  // Apply attributes
973
1021
  for (var attr of Object.keys(this.attributes)) {
974
1022
  node.setAttribute(attr, this.attributes[attr]);
@@ -997,11 +1045,7 @@ var toMarkup = function toMarkup(tagName) {
997
1045
  if (this.classes.length) {
998
1046
  markup += " class=\"" + escape(createClass(this.classes)) + "\"";
999
1047
  }
1000
- var styles = "";
1001
- // Add the styles, after hyphenation
1002
- for (var key of Object.keys(this.style)) {
1003
- styles += hyphenate(key) + ":" + this.style[key] + ";";
1004
- }
1048
+ var styles = cssStyleToString(this.style);
1005
1049
  if (styles) {
1006
1050
  markup += " style=\"" + escape(styles) + "\"";
1007
1051
  }
@@ -1031,6 +1075,20 @@ var toMarkup = function toMarkup(tagName) {
1031
1075
  */
1032
1076
  class Span {
1033
1077
  constructor(classes, children, options, style) {
1078
+ this.children = void 0;
1079
+ this.attributes = void 0;
1080
+ this.classes = void 0;
1081
+ this.height = void 0;
1082
+ this.depth = void 0;
1083
+ this.width = void 0;
1084
+ this.maxFontSize = void 0;
1085
+ this.style = void 0;
1086
+ /**
1087
+ * Italic correction carried over from a SymbolNode when the symbol is
1088
+ * wrapped in a vlist (e.g. \oiint / \oiiint). Read by supsub to adjust
1089
+ * subscript positioning. Only set when nonzero; use `?? 0` at read sites.
1090
+ */
1091
+ this.italic = void 0;
1034
1092
  initNode.call(this, classes, options, style);
1035
1093
  this.children = children || [];
1036
1094
  }
@@ -1058,6 +1116,13 @@ class Span {
1058
1116
  */
1059
1117
  class Anchor {
1060
1118
  constructor(href, classes, children, options) {
1119
+ this.children = void 0;
1120
+ this.attributes = void 0;
1121
+ this.classes = void 0;
1122
+ this.height = void 0;
1123
+ this.depth = void 0;
1124
+ this.maxFontSize = void 0;
1125
+ this.style = void 0;
1061
1126
  initNode.call(this, classes, options);
1062
1127
  this.children = children || [];
1063
1128
  this.setAttribute('href', href);
@@ -1080,6 +1145,13 @@ class Anchor {
1080
1145
  */
1081
1146
  class Img {
1082
1147
  constructor(src, alt, style) {
1148
+ this.src = void 0;
1149
+ this.alt = void 0;
1150
+ this.classes = void 0;
1151
+ this.height = void 0;
1152
+ this.depth = void 0;
1153
+ this.maxFontSize = void 0;
1154
+ this.style = void 0;
1083
1155
  this.alt = alt;
1084
1156
  this.src = src;
1085
1157
  this.classes = ["mord"];
@@ -1097,18 +1169,12 @@ class Img {
1097
1169
  node.alt = this.alt;
1098
1170
  node.className = "mord";
1099
1171
  // Apply inline styles
1100
- for (var key of Object.keys(this.style)) {
1101
- node.style[key] = this.style[key];
1102
- }
1172
+ Object.assign(node.style, this.style);
1103
1173
  return node;
1104
1174
  }
1105
1175
  toMarkup() {
1106
1176
  var markup = "<img src=\"" + escape(this.src) + "\"" + (" alt=\"" + escape(this.alt) + "\"");
1107
- // Add the styles, after hyphenation
1108
- var styles = "";
1109
- for (var key of Object.keys(this.style)) {
1110
- styles += hyphenate(key) + ":" + this.style[key] + ";";
1111
- }
1177
+ var styles = cssStyleToString(this.style);
1112
1178
  if (styles) {
1113
1179
  markup += " style=\"" + escape(styles) + "\"";
1114
1180
  }
@@ -1130,6 +1196,15 @@ var iCombinations = {
1130
1196
  */
1131
1197
  class SymbolNode {
1132
1198
  constructor(text, height, depth, italic, skew, width, classes, style) {
1199
+ this.text = void 0;
1200
+ this.height = void 0;
1201
+ this.depth = void 0;
1202
+ this.italic = void 0;
1203
+ this.skew = void 0;
1204
+ this.width = void 0;
1205
+ this.maxFontSize = void 0;
1206
+ this.classes = void 0;
1207
+ this.style = void 0;
1133
1208
  this.text = text;
1134
1209
  this.height = height || 0;
1135
1210
  this.depth = depth || 0;
@@ -1173,9 +1248,9 @@ class SymbolNode {
1173
1248
  span = span || document.createElement("span");
1174
1249
  span.className = createClass(this.classes);
1175
1250
  }
1176
- for (var key of Object.keys(this.style)) {
1251
+ if (Object.keys(this.style).length > 0) {
1177
1252
  span = span || document.createElement("span");
1178
- span.style[key] = this.style[key];
1253
+ Object.assign(span.style, this.style);
1179
1254
  }
1180
1255
  if (span) {
1181
1256
  span.appendChild(node);
@@ -1202,9 +1277,7 @@ class SymbolNode {
1202
1277
  if (this.italic > 0) {
1203
1278
  styles += "margin-right:" + makeEm(this.italic) + ";";
1204
1279
  }
1205
- for (var key of Object.keys(this.style)) {
1206
- styles += hyphenate(key) + ":" + this.style[key] + ";";
1207
- }
1280
+ styles += cssStyleToString(this.style);
1208
1281
  if (styles) {
1209
1282
  needsSpan = true;
1210
1283
  markup += " style=\"" + escape(styles) + "\"";
@@ -1225,6 +1298,8 @@ class SymbolNode {
1225
1298
  */
1226
1299
  class SvgNode {
1227
1300
  constructor(children, attributes) {
1301
+ this.children = void 0;
1302
+ this.attributes = void 0;
1228
1303
  this.children = children || [];
1229
1304
  this.attributes = attributes || {};
1230
1305
  }
@@ -1256,6 +1331,8 @@ class SvgNode {
1256
1331
  }
1257
1332
  class PathNode {
1258
1333
  constructor(pathName, alternate) {
1334
+ this.pathName = void 0;
1335
+ this.alternate = void 0;
1259
1336
  this.pathName = pathName;
1260
1337
  this.alternate = alternate; // Used only for \sqrt, \phase, & tall delims
1261
1338
  }
@@ -1279,6 +1356,7 @@ class PathNode {
1279
1356
  }
1280
1357
  class LineNode {
1281
1358
  constructor(attributes) {
1359
+ this.attributes = void 0;
1282
1360
  this.attributes = attributes || {};
1283
1361
  }
1284
1362
  toNode() {
@@ -3680,25 +3758,6 @@ function getGlobalMetrics(size) {
3680
3758
  * The outermost map in the table indicates what mode the symbols should be
3681
3759
  * accepted in (e.g. "math" or "text").
3682
3760
  */
3683
- // Some of these have a "-token" suffix since these are also used as `ParseNode`
3684
- // types for raw text tokens, and we want to avoid conflicts with higher-level
3685
- // `ParseNode` types. These `ParseNode`s are constructed within `Parser` by
3686
- // looking up the `symbols` map.
3687
- var ATOMS = {
3688
- "bin": 1,
3689
- "close": 1,
3690
- "inner": 1,
3691
- "open": 1,
3692
- "punct": 1,
3693
- "rel": 1
3694
- };
3695
- var NON_ATOMS = {
3696
- "accent-token": 1,
3697
- "mathord": 1,
3698
- "op-token": 1,
3699
- "spacing": 1,
3700
- "textord": 1
3701
- };
3702
3761
  var symbols = {
3703
3762
  "math": {},
3704
3763
  "text": {}
@@ -4221,8 +4280,8 @@ defineSymbol(text, main, spacing, "\u00a0", "\\ ");
4221
4280
  defineSymbol(text, main, spacing, "\u00a0", " ");
4222
4281
  defineSymbol(text, main, spacing, "\u00a0", "\\space");
4223
4282
  defineSymbol(text, main, spacing, "\u00a0", "\\nobreakspace");
4224
- defineSymbol(math, main, spacing, null, "\\nobreak");
4225
- defineSymbol(math, main, spacing, null, "\\allowbreak");
4283
+ defineSymbol(math, main, spacing, "", "\\nobreak");
4284
+ defineSymbol(math, main, spacing, "", "\\allowbreak");
4226
4285
  defineSymbol(math, main, punct, ",", ",");
4227
4286
  defineSymbol(math, main, punct, ";", ";");
4228
4287
  defineSymbol(math, ams, bin, "\u22bc", "\\barwedge", true);
@@ -4418,7 +4477,7 @@ defineSymbol(text, main, mathord, "h", "\u210E");
4418
4477
  // Mathematical Alphanumeric Symbols.
4419
4478
  // Some editors do not deal well with wide characters. So don't write the
4420
4479
  // string into this file. Instead, create the string from the surrogate pair.
4421
- var wideChar = "";
4480
+ var wideChar;
4422
4481
  for (var _i3 = 0; _i3 < letters.length; _i3++) {
4423
4482
  var _ch3 = letters.charAt(_i3);
4424
4483
  // The hex numbers in the next line are a surrogate pair.
@@ -4501,101 +4560,134 @@ for (var _i5 = 0; _i5 < extraLatin.length; _i5++) {
4501
4560
  * Function wideCharacterFont takes a wide character as input and returns
4502
4561
  * the font information necessary to render it properly.
4503
4562
  */
4563
+ var boldUpright = {
4564
+ mathClass: "mathbf",
4565
+ textClass: "textbf",
4566
+ font: "Main-Bold"
4567
+ };
4568
+ var italic = {
4569
+ mathClass: "mathnormal",
4570
+ textClass: "textit",
4571
+ font: "Math-Italic"
4572
+ };
4573
+ var boldItalic = {
4574
+ mathClass: "boldsymbol",
4575
+ textClass: "boldsymbol",
4576
+ font: "Main-BoldItalic"
4577
+ };
4578
+ var script = {
4579
+ mathClass: "mathscr",
4580
+ textClass: "textscr",
4581
+ font: "Script-Regular"
4582
+ };
4583
+ var noFont = {
4584
+ mathClass: "",
4585
+ textClass: "",
4586
+ font: ""
4587
+ };
4588
+ var fraktur = {
4589
+ mathClass: "mathfrak",
4590
+ textClass: "textfrak",
4591
+ font: "Fraktur-Regular"
4592
+ };
4593
+ var doubleStruck = {
4594
+ mathClass: "mathbb",
4595
+ textClass: "textbb",
4596
+ font: "AMS-Regular"
4597
+ };
4598
+ var boldFraktur = {
4599
+ mathClass: "mathboldfrak",
4600
+ textClass: "textboldfrak",
4601
+ font: "Fraktur-Regular"
4602
+ };
4603
+ var sansSerif = {
4604
+ mathClass: "mathsf",
4605
+ textClass: "textsf",
4606
+ font: "SansSerif-Regular"
4607
+ };
4608
+ var boldSansSerif = {
4609
+ mathClass: "mathboldsf",
4610
+ textClass: "textboldsf",
4611
+ font: "SansSerif-Bold"
4612
+ };
4613
+ var italicSansSerif = {
4614
+ mathClass: "mathitsf",
4615
+ textClass: "textitsf",
4616
+ font: "SansSerif-Italic"
4617
+ };
4618
+ var monospace = {
4619
+ mathClass: "mathtt",
4620
+ textClass: "texttt",
4621
+ font: "Typewriter-Regular"
4622
+ };
4504
4623
  /**
4505
4624
  * Data below is from https://www.unicode.org/charts/PDF/U1D400.pdf
4506
4625
  * That document sorts characters into groups by font type, say bold or italic.
4507
4626
  *
4508
- * In the arrays below, each subarray consists three elements:
4627
+ * In the arrays below, each object consists of three properties:
4509
4628
  * * The CSS class of that group when in math mode.
4510
4629
  * * The CSS class of that group when in text mode.
4511
4630
  * * The font name, so that KaTeX can get font metrics.
4512
4631
  */
4513
- var wideLatinLetterData = [["mathbf", "textbf", "Main-Bold"],
4514
- // A-Z bold upright
4515
- ["mathbf", "textbf", "Main-Bold"],
4516
- // a-z bold upright
4517
- ["mathnormal", "textit", "Math-Italic"],
4518
- // A-Z italic
4519
- ["mathnormal", "textit", "Math-Italic"],
4520
- // a-z italic
4521
- ["boldsymbol", "boldsymbol", "Main-BoldItalic"],
4522
- // A-Z bold italic
4523
- ["boldsymbol", "boldsymbol", "Main-BoldItalic"],
4524
- // a-z bold italic
4632
+ var wideLatinLetterData = [boldUpright, boldUpright,
4633
+ // A-Z, a-z
4634
+ italic, italic,
4635
+ // A-Z, a-z
4636
+ boldItalic, boldItalic,
4637
+ // A-Z, a-z
4525
4638
  // Map fancy A-Z letters to script, not calligraphic.
4526
4639
  // This aligns with unicode-math and math fonts (except Cambria Math).
4527
- ["mathscr", "textscr", "Script-Regular"],
4528
- // A-Z script
4529
- ["", "", ""],
4530
- // a-z script. No font
4531
- ["", "", ""],
4532
- // A-Z bold script. No font
4533
- ["", "", ""],
4534
- // a-z bold script. No font
4535
- ["mathfrak", "textfrak", "Fraktur-Regular"],
4536
- // A-Z Fraktur
4537
- ["mathfrak", "textfrak", "Fraktur-Regular"],
4538
- // a-z Fraktur
4539
- ["mathbb", "textbb", "AMS-Regular"],
4540
- // A-Z double-struck
4541
- ["mathbb", "textbb", "AMS-Regular"],
4542
- // k double-struck
4640
+ script, noFont,
4641
+ // A-Z script, a-z — no font
4642
+ noFont, noFont,
4643
+ // A-Z bold script, a-z bold script — no font
4644
+ fraktur, fraktur,
4645
+ // A-Z, a-z
4646
+ doubleStruck, doubleStruck,
4647
+ // A-Z double-struck, k double-struck
4543
4648
  // Note that we are using a bold font, but font metrics for regular Fraktur.
4544
- ["mathboldfrak", "textboldfrak", "Fraktur-Regular"],
4545
- // A-Z bold Fraktur
4546
- ["mathboldfrak", "textboldfrak", "Fraktur-Regular"],
4547
- // a-z bold Fraktur
4548
- ["mathsf", "textsf", "SansSerif-Regular"],
4549
- // A-Z sans-serif
4550
- ["mathsf", "textsf", "SansSerif-Regular"],
4551
- // a-z sans-serif
4552
- ["mathboldsf", "textboldsf", "SansSerif-Bold"],
4553
- // A-Z bold sans-serif
4554
- ["mathboldsf", "textboldsf", "SansSerif-Bold"],
4555
- // a-z bold sans-serif
4556
- ["mathitsf", "textitsf", "SansSerif-Italic"],
4557
- // A-Z italic sans-serif
4558
- ["mathitsf", "textitsf", "SansSerif-Italic"],
4559
- // a-z italic sans-serif
4560
- ["", "", ""],
4561
- // A-Z bold italic sans. No font
4562
- ["", "", ""],
4563
- // a-z bold italic sans. No font
4564
- ["mathtt", "texttt", "Typewriter-Regular"],
4565
- // A-Z monospace
4566
- ["mathtt", "texttt", "Typewriter-Regular"] // a-z monospace
4649
+ boldFraktur, boldFraktur,
4650
+ // A-Z, a-z
4651
+ sansSerif, sansSerif,
4652
+ // A-Z, a-z
4653
+ boldSansSerif, boldSansSerif,
4654
+ // A-Z, a-z
4655
+ italicSansSerif, italicSansSerif,
4656
+ // A-Z, a-z
4657
+ noFont, noFont,
4658
+ // A-Z bold italic sans, a-z bold italic sans - no font
4659
+ monospace, monospace // A-Z, a-z
4567
4660
  ];
4568
- var wideNumeralData = [["mathbf", "textbf", "Main-Bold"],
4569
- // 0-9 bold
4570
- ["", "", ""],
4661
+ var wideNumeralData = [boldUpright,
4662
+ // 0-9
4663
+ noFont,
4571
4664
  // 0-9 double-struck. No KaTeX font.
4572
- ["mathsf", "textsf", "SansSerif-Regular"],
4573
- // 0-9 sans-serif
4574
- ["mathboldsf", "textboldsf", "SansSerif-Bold"],
4575
- // 0-9 bold sans-serif
4576
- ["mathtt", "texttt", "Typewriter-Regular"] // 0-9 monospace
4665
+ sansSerif,
4666
+ // 0-9
4667
+ boldSansSerif,
4668
+ // 0-9
4669
+ monospace // 0-9
4577
4670
  ];
4578
- var wideCharacterFont = (wideChar, mode) => {
4671
+ var wideCharacterFont = wideChar => {
4579
4672
  // IE doesn't support codePointAt(). So work with the surrogate pair.
4580
4673
  var H = wideChar.charCodeAt(0); // high surrogate
4581
4674
  var L = wideChar.charCodeAt(1); // low surrogate
4582
4675
  var codePoint = (H - 0xD800) * 0x400 + (L - 0xDC00) + 0x10000;
4583
- var j = mode === "math" ? 0 : 1; // column index for CSS class.
4584
4676
  if (0x1D400 <= codePoint && codePoint < 0x1D6A4) {
4585
4677
  // wideLatinLetterData contains exactly 26 chars on each row.
4586
4678
  // So we can calculate the relevant row. No traverse necessary.
4587
4679
  var i = Math.floor((codePoint - 0x1D400) / 26);
4588
- return [wideLatinLetterData[i][2], wideLatinLetterData[i][j]];
4680
+ return wideLatinLetterData[i];
4589
4681
  } else if (0x1D7CE <= codePoint && codePoint <= 0x1D7FF) {
4590
4682
  // Numerals, ten per row.
4591
4683
  var _i = Math.floor((codePoint - 0x1D7CE) / 10);
4592
- return [wideNumeralData[_i][2], wideNumeralData[_i][j]];
4684
+ return wideNumeralData[_i];
4593
4685
  } else if (codePoint === 0x1D6A5 || codePoint === 0x1D6A6) {
4594
4686
  // dotless i or j
4595
- return [wideLatinLetterData[0][2], wideLatinLetterData[0][j]];
4687
+ return wideLatinLetterData[0];
4596
4688
  } else if (0x1D6A6 < codePoint && codePoint < 0x1D7CE) {
4597
4689
  // Greek letters. Not supported, yet.
4598
- return ["", ""];
4690
+ return noFont;
4599
4691
  } else {
4600
4692
  // We don't support any wide characters outside 1D400–1D7FF.
4601
4693
  throw new ParseError("Unsupported character: " + wideChar);
@@ -4607,9 +4699,7 @@ var wideCharacterFont = (wideChar, mode) => {
4607
4699
  * Looks up the given symbol in fontMetrics, after applying any symbol
4608
4700
  * replacements defined in symbol.js
4609
4701
  */
4610
- var lookupSymbol = function lookupSymbol(value,
4611
- // TODO(#963): Use a union type for this.
4612
- fontName, mode) {
4702
+ var lookupSymbol = function lookupSymbol(value, fontName, mode) {
4613
4703
  // Replace the value with its replaced value from symbol.js
4614
4704
  if (symbols[mode][value]) {
4615
4705
  var replacement = symbols[mode][value].replace;
@@ -4689,7 +4779,7 @@ var mathsym = function mathsym(value, mode, options, classes) {
4689
4779
  * depending on the symbol. Use this function instead of fontMap for font
4690
4780
  * "boldsymbol".
4691
4781
  */
4692
- var boldsymbol = function boldsymbol(value, mode, options, classes, type) {
4782
+ var boldSymbol = function boldSymbol(value, mode, type) {
4693
4783
  if (type !== "textord" && lookupSymbol(value, "Math-BoldItalic", mode).metrics) {
4694
4784
  return {
4695
4785
  fontName: "Math-BoldItalic",
@@ -4711,30 +4801,38 @@ var makeOrd = function makeOrd(group, options, type) {
4711
4801
  var mode = group.mode;
4712
4802
  var text = group.text;
4713
4803
  var classes = ["mord"];
4804
+ var {
4805
+ font,
4806
+ fontFamily,
4807
+ fontWeight,
4808
+ fontShape
4809
+ } = options;
4714
4810
  // Math mode or Old font (i.e. \rm)
4715
- var isFont = mode === "math" || mode === "text" && options.font;
4716
- var fontOrFamily = isFont ? options.font : options.fontFamily;
4811
+ var useFont = mode === "math" || mode === "text" && !!font;
4812
+ var fontOrFamily = useFont ? font : fontFamily;
4717
4813
  var wideFontName = "";
4718
4814
  var wideFontClass = "";
4719
4815
  if (text.charCodeAt(0) === 0xD835) {
4720
- [wideFontName, wideFontClass] = wideCharacterFont(text, mode);
4816
+ var wideCharData = wideCharacterFont(text);
4817
+ wideFontName = wideCharData.font;
4818
+ wideFontClass = wideCharData[mode + "Class"];
4721
4819
  }
4722
- if (wideFontName.length > 0) {
4820
+ if (wideFontName) {
4723
4821
  // surrogate pairs get special treatment
4724
4822
  return makeSymbol(text, wideFontName, mode, options, classes.concat(wideFontClass));
4725
4823
  } else if (fontOrFamily) {
4726
4824
  var fontName;
4727
4825
  var fontClasses;
4728
4826
  if (fontOrFamily === "boldsymbol") {
4729
- var fontData = boldsymbol(text, mode, options, classes, type);
4827
+ var fontData = boldSymbol(text, mode, type);
4730
4828
  fontName = fontData.fontName;
4731
4829
  fontClasses = [fontData.fontClass];
4732
- } else if (isFont) {
4733
- fontName = fontMap[fontOrFamily].fontName;
4734
- fontClasses = [fontOrFamily];
4830
+ } else if (useFont) {
4831
+ fontName = fontMap[font].fontName;
4832
+ fontClasses = [font];
4735
4833
  } else {
4736
- fontName = retrieveTextFontName(fontOrFamily, options.fontWeight, options.fontShape);
4737
- fontClasses = [fontOrFamily, options.fontWeight, options.fontShape];
4834
+ fontName = retrieveTextFontName(fontFamily, fontWeight, fontShape);
4835
+ fontClasses = [fontFamily, fontWeight, fontShape];
4738
4836
  }
4739
4837
  if (lookupSymbol(text, fontName, mode).metrics) {
4740
4838
  return makeSymbol(text, fontName, mode, options, classes.concat(fontClasses));
@@ -4751,18 +4849,18 @@ var makeOrd = function makeOrd(group, options, type) {
4751
4849
  if (type === "mathord") {
4752
4850
  return makeSymbol(text, "Math-Italic", mode, options, classes.concat(["mathnormal"]));
4753
4851
  } else if (type === "textord") {
4754
- var font = symbols[mode][text] && symbols[mode][text].font;
4755
- if (font === "ams") {
4756
- var _fontName = retrieveTextFontName("amsrm", options.fontWeight, options.fontShape);
4757
- return makeSymbol(text, _fontName, mode, options, classes.concat("amsrm", options.fontWeight, options.fontShape));
4758
- } else if (font === "main" || !font) {
4759
- var _fontName2 = retrieveTextFontName("textrm", options.fontWeight, options.fontShape);
4760
- return makeSymbol(text, _fontName2, mode, options, classes.concat(options.fontWeight, options.fontShape));
4852
+ var _font = symbols[mode][text] && symbols[mode][text].font;
4853
+ if (_font === "ams") {
4854
+ var _fontName = retrieveTextFontName("amsrm", fontWeight, fontShape);
4855
+ return makeSymbol(text, _fontName, mode, options, classes.concat("amsrm", fontWeight, fontShape));
4856
+ } else if (_font === "main" || !_font) {
4857
+ var _fontName2 = retrieveTextFontName("textrm", fontWeight, fontShape);
4858
+ return makeSymbol(text, _fontName2, mode, options, classes.concat(fontWeight, fontShape));
4761
4859
  } else {
4762
4860
  // fonts added by plugins
4763
- var _fontName3 = retrieveTextFontName(font, options.fontWeight, options.fontShape);
4861
+ var _fontName3 = retrieveTextFontName(_font, fontWeight, fontShape);
4764
4862
  // We add font name as a css class
4765
- return makeSymbol(text, _fontName3, mode, options, classes.concat(_fontName3, options.fontWeight, options.fontShape));
4863
+ return makeSymbol(text, _fontName3, mode, options, classes.concat(_fontName3, fontWeight, fontShape));
4766
4864
  }
4767
4865
  } else {
4768
4866
  throw new Error("unexpected type: " + type + " in makeOrd");
@@ -5048,8 +5146,9 @@ var makeGlue = (measurement, options) => {
5048
5146
  return rule;
5049
5147
  };
5050
5148
  // Takes font options, and returns the appropriate fontLookup name
5051
- var retrieveTextFontName = function retrieveTextFontName(fontFamily, fontWeight, fontShape) {
5052
- var baseFontName = "";
5149
+ var retrieveTextFontName = (fontFamily, fontWeight, fontShape) => {
5150
+ var baseFontName;
5151
+ var fontStylesName;
5053
5152
  switch (fontFamily) {
5054
5153
  case "amsrm":
5055
5154
  baseFontName = "AMS";
@@ -5067,12 +5166,11 @@ var retrieveTextFontName = function retrieveTextFontName(fontFamily, fontWeight,
5067
5166
  baseFontName = fontFamily;
5068
5167
  // use fonts added by a plugin
5069
5168
  }
5070
- var fontStylesName;
5071
5169
  if (fontWeight === "textbf" && fontShape === "textit") {
5072
5170
  fontStylesName = "BoldItalic";
5073
5171
  } else if (fontWeight === "textbf") {
5074
5172
  fontStylesName = "Bold";
5075
- } else if (fontWeight === "textit") {
5173
+ } else if (fontShape === "textit") {
5076
5174
  fontStylesName = "Italic";
5077
5175
  } else {
5078
5176
  fontStylesName = "Regular";
@@ -5263,12 +5361,19 @@ var _functions = {};
5263
5361
  /**
5264
5362
  * All HTML builders. Should be only used in the `define*` and the `build*ML`
5265
5363
  * functions.
5364
+ *
5365
+ * Builders for different node types are stored side by side, but
5366
+ * `HtmlBuilder<T>` is contravariant in `T`, so there is no single type
5367
+ * argument that makes storing/retrieving them typecheck. `any` is used
5368
+ * as an existential-quantifier escape hatch.
5266
5369
  */
5370
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5267
5371
  var _htmlGroupBuilders = {};
5268
5372
  /**
5269
5373
  * All MathML builders. Should be only used in the `define*` and the `build*ML`
5270
- * functions.
5374
+ * functions. See `_htmlGroupBuilders` above for the rationale behind `any`.
5271
5375
  */
5376
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5272
5377
  var _mathmlGroupBuilders = {};
5273
5378
  function defineFunction(_ref) {
5274
5379
  var {
@@ -5456,7 +5561,8 @@ var _traverseNonSpaceNodes = function traverseNonSpaceNodes(nodes, callback, pre
5456
5561
  var partialGroup = checkPartialGroup(node);
5457
5562
  if (partialGroup) {
5458
5563
  // Recursive DFS
5459
- // TODO(ts): make nodes a $ReadOnlyArray by returning a new array
5564
+ // TODO(ts): partialGroup.children is ReadonlyArray but this
5565
+ // function mutates the array (insertAfter splices into it).
5460
5566
  _traverseNonSpaceNodes(partialGroup.children, callback, prev, null, isRoot);
5461
5567
  continue;
5462
5568
  }
@@ -5539,8 +5645,8 @@ var buildGroup$1 = function buildGroup(group, options, baseOptions) {
5539
5645
  return makeSpan();
5540
5646
  }
5541
5647
  if (_htmlGroupBuilders[group.type]) {
5542
- // Call the groupBuilders function
5543
- // TODO(ts)
5648
+ // TODO(ts): groupBuilders is Record<string, HtmlBuilder<any>>;
5649
+ // a type-safe registry would need a mapped type keyed by NodeType.
5544
5650
  var groupNode = _htmlGroupBuilders[group.type](group, options);
5545
5651
  // If the size changed between the parent and the current group, account
5546
5652
  // for that size difference.
@@ -5675,6 +5781,10 @@ function newDocumentFragment(children) {
5675
5781
  */
5676
5782
  class MathNode {
5677
5783
  constructor(type, children, classes) {
5784
+ this.type = void 0;
5785
+ this.attributes = void 0;
5786
+ this.children = void 0;
5787
+ this.classes = void 0;
5678
5788
  this.type = type;
5679
5789
  this.attributes = {};
5680
5790
  this.children = children || [];
@@ -5756,6 +5866,7 @@ class MathNode {
5756
5866
  */
5757
5867
  class TextNode {
5758
5868
  constructor(text) {
5869
+ this.text = void 0;
5759
5870
  this.text = text;
5760
5871
  }
5761
5872
  /**
@@ -5788,6 +5899,8 @@ class SpaceNode {
5788
5899
  * Create a Space node with width given in CSS ems.
5789
5900
  */
5790
5901
  constructor(width) {
5902
+ this.width = void 0;
5903
+ this.character = void 0;
5791
5904
  this.width = width;
5792
5905
  // See https://www.w3.org/TR/2000/WD-MathML2-20000328/chapter6.html
5793
5906
  // for a table of space-like characters. We use Unicode
@@ -5875,56 +5988,54 @@ var makeRow = function makeRow(body) {
5875
5988
  return new MathNode("mrow", body);
5876
5989
  }
5877
5990
  };
5991
+ var mathFontVariants = {
5992
+ mathit: "italic",
5993
+ boldsymbol: group => group.type === "textord" ? "bold" : "bold-italic",
5994
+ mathbf: "bold",
5995
+ mathbb: "double-struck",
5996
+ mathsfit: "sans-serif-italic",
5997
+ mathfrak: "fraktur",
5998
+ mathscr: "script",
5999
+ mathcal: "script",
6000
+ mathsf: "sans-serif",
6001
+ mathtt: "monospace"
6002
+ };
5878
6003
  /**
5879
6004
  * Returns the math variant as a string or null if none is required.
5880
6005
  */
5881
- var getVariant = function getVariant(group, options) {
6006
+ var getVariant = (group, options) => {
5882
6007
  // Handle \text... font specifiers as best we can.
5883
6008
  // MathML has a limited list of allowable mathvariant specifiers; see
5884
6009
  // https://www.w3.org/TR/MathML3/chapter3.html#presm.commatt
5885
- if (options.fontFamily === "texttt") {
5886
- return "monospace";
5887
- } else if (options.fontFamily === "textsf") {
5888
- if (options.fontShape === "textit" && options.fontWeight === "textbf") {
5889
- return "sans-serif-bold-italic";
6010
+ if (group.mode === "text") {
6011
+ if (options.fontFamily === "texttt") {
6012
+ return "monospace";
6013
+ } else if (options.fontFamily === "textsf") {
6014
+ if (options.fontShape === "textit" && options.fontWeight === "textbf") {
6015
+ return "sans-serif-bold-italic";
6016
+ } else if (options.fontShape === "textit") {
6017
+ return "sans-serif-italic";
6018
+ } else if (options.fontWeight === "textbf") {
6019
+ return "bold-sans-serif";
6020
+ } else {
6021
+ return "sans-serif";
6022
+ }
6023
+ } else if (options.fontShape === "textit" && options.fontWeight === "textbf") {
6024
+ return "bold-italic";
5890
6025
  } else if (options.fontShape === "textit") {
5891
- return "sans-serif-italic";
6026
+ return "italic";
5892
6027
  } else if (options.fontWeight === "textbf") {
5893
- return "bold-sans-serif";
5894
- } else {
5895
- return "sans-serif";
6028
+ return "bold";
5896
6029
  }
5897
- } else if (options.fontShape === "textit" && options.fontWeight === "textbf") {
5898
- return "bold-italic";
5899
- } else if (options.fontShape === "textit") {
5900
- return "italic";
5901
- } else if (options.fontWeight === "textbf") {
5902
- return "bold";
5903
6030
  }
5904
6031
  var font = options.font;
5905
6032
  if (!font || font === "mathnormal") {
5906
6033
  return null;
5907
6034
  }
5908
6035
  var mode = group.mode;
5909
- if (font === "mathit") {
5910
- return "italic";
5911
- } else if (font === "boldsymbol") {
5912
- return group.type === "textord" ? "bold" : "bold-italic";
5913
- } else if (font === "mathbf") {
5914
- return "bold";
5915
- } else if (font === "mathbb") {
5916
- return "double-struck";
5917
- } else if (font === "mathsfit") {
5918
- return "sans-serif-italic";
5919
- } else if (font === "mathfrak") {
5920
- return "fraktur";
5921
- } else if (font === "mathscr" || font === "mathcal") {
5922
- // MathML makes no distinction between script and calligraphic
5923
- return "script";
5924
- } else if (font === "mathsf") {
5925
- return "sans-serif";
5926
- } else if (font === "mathtt") {
5927
- return "monospace";
6036
+ var mathVariant = mathFontVariants[font];
6037
+ if (mathVariant) {
6038
+ return typeof mathVariant === "function" ? mathVariant(group) : mathVariant;
5928
6039
  }
5929
6040
  var text = group.text;
5930
6041
  if (noVariantSymbols.has(text)) {
@@ -6040,11 +6151,10 @@ var buildGroup = function buildGroup(group, options) {
6040
6151
  return new MathNode("mrow");
6041
6152
  }
6042
6153
  if (_mathmlGroupBuilders[group.type]) {
6043
- // Call the groupBuilders function
6044
- // TODO(ts)
6045
- var result = _mathmlGroupBuilders[group.type](group, options);
6046
- // TODO(ts)
6047
- return result;
6154
+ // TODO(ts): MathMLBuilder returns MathDomNode but all concrete
6155
+ // builders return MathNode. Widening the return type here would
6156
+ // require updating all callers that assume MathNode.
6157
+ return _mathmlGroupBuilders[group.type](group, options);
6048
6158
  } else {
6049
6159
  throw new ParseError("Got group of unknown type: '" + group.type + "'");
6050
6160
  }
@@ -6084,8 +6194,11 @@ function buildMathML(tree, texExpression, options, isDisplayMode, forMathmlOnly)
6084
6194
  // NOTE: The span class is not typed to have <math> nodes as children, and
6085
6195
  // we don't want to make the children type more generic since the children
6086
6196
  // of span are expected to have more fields in `buildHtml` contexts.
6197
+ // The MathNode implements VirtualNode (toNode/toMarkup) which is all that
6198
+ // Span needs from its children for rendering.
6199
+ // TODO(ts): Span's child type is HtmlDomNode, but MathNode only implements
6200
+ // VirtualNode. The double-cast acknowledges this architectural limitation.
6087
6201
  var wrapperClass = forMathmlOnly ? "katex" : "katex-mathml";
6088
- // TODO(ts)
6089
6202
  return makeSpan([wrapperClass], [math]);
6090
6203
  }
6091
6204
 
@@ -6136,6 +6249,22 @@ var sizeAtStyle = function sizeAtStyle(size, style) {
6136
6249
  */
6137
6250
  class Options {
6138
6251
  constructor(data) {
6252
+ this.style = void 0;
6253
+ this.color = void 0;
6254
+ this.size = void 0;
6255
+ this.textSize = void 0;
6256
+ this.phantom = void 0;
6257
+ // A font family applies to a group of fonts (i.e. SansSerif), while a font
6258
+ // represents a specific font (i.e. SansSerif Bold).
6259
+ // See: https://tex.stackexchange.com/questions/22350/difference-between-textrm-and-mathrm
6260
+ this.font = void 0;
6261
+ this.fontFamily = void 0;
6262
+ this.fontWeight = void 0;
6263
+ this.fontShape = void 0;
6264
+ this.sizeMultiplier = void 0;
6265
+ this.maxSize = void 0;
6266
+ this.minRuleThickness = void 0;
6267
+ this._fontMetrics = void 0;
6139
6268
  this.style = data.style;
6140
6269
  this.color = data.color;
6141
6270
  this.size = data.size || Options.BASESIZE;
@@ -6143,8 +6272,8 @@ class Options {
6143
6272
  this.phantom = !!data.phantom;
6144
6273
  this.font = data.font || "";
6145
6274
  this.fontFamily = data.fontFamily || "";
6146
- this.fontWeight = data.fontWeight || '';
6147
- this.fontShape = data.fontShape || '';
6275
+ this.fontWeight = data.fontWeight || "";
6276
+ this.fontShape = data.fontShape || "";
6148
6277
  this.sizeMultiplier = sizeMultipliers[this.size - 1];
6149
6278
  this.maxSize = data.maxSize;
6150
6279
  this.minRuleThickness = data.minRuleThickness;
@@ -6342,9 +6471,6 @@ class Options {
6342
6471
  }
6343
6472
  }
6344
6473
  }
6345
- // A font family applies to a group of fonts (i.e. SansSerif), while a font
6346
- // represents a specific font (i.e. SansSerif Bold).
6347
- // See: https://tex.stackexchange.com/questions/22350/difference-between-textrm-and-mathrm
6348
6474
  /**
6349
6475
  * The base size index.
6350
6476
  */
@@ -6450,32 +6576,6 @@ var stretchyMathML = function stretchyMathML(label) {
6450
6576
  node.setAttribute("stretchy", "true");
6451
6577
  return node;
6452
6578
  };
6453
- // Many of the KaTeX SVG images have been adapted from glyphs in KaTeX fonts.
6454
- // Copyright (c) 2009-2010, Design Science, Inc. (<www.mathjax.org>)
6455
- // Copyright (c) 2014-2017 Khan Academy (<www.khanacademy.org>)
6456
- // Licensed under the SIL Open Font License, Version 1.1.
6457
- // See \nhttp://scripts.sil.org/OFL
6458
- // Very Long SVGs
6459
- // Many of the KaTeX stretchy wide elements use a long SVG image and an
6460
- // overflow: hidden tactic to achieve a stretchy image while avoiding
6461
- // distortion of arrowheads or brace corners.
6462
- // The SVG typically contains a very long (400 em) arrow.
6463
- // The SVG is in a container span that has overflow: hidden, so the span
6464
- // acts like a window that exposes only part of the SVG.
6465
- // The SVG always has a longer, thinner aspect ratio than the container span.
6466
- // After the SVG fills 100% of the height of the container span,
6467
- // there is a long arrow shaft left over. That left-over shaft is not shown.
6468
- // Instead, it is sliced off because the span's CSS has overflow: hidden.
6469
- // Thus, the reader sees an arrow that matches the subject matter width
6470
- // without distortion.
6471
- // Some functions, such as \cancel, need to vary their aspect ratio. These
6472
- // functions do not get the overflow SVG treatment.
6473
- // In the katexImagesData object just below, the dimensions all
6474
- // correspond to path geometry inside the relevant SVG.
6475
- // For example, \overrightarrow uses the same arrowhead as glyph U+2192
6476
- // from the KaTeX Main font. The scaling factor is 1000.
6477
- // That is, inside the font, that arrowhead is 522 units tall, which
6478
- // corresponds to 0.522 em inside the document.
6479
6579
  var katexImagesData = {
6480
6580
  // path(s), minWidth, height, align
6481
6581
  overrightarrow: [["rightarrow"], 0.888, 522, "xMaxYMin"],
@@ -6532,14 +6632,10 @@ var stretchySvg = function stretchySvg(group, options) {
6532
6632
  function buildSvgSpan_() {
6533
6633
  var viewBoxWidth = 400000; // default
6534
6634
  var label = group.label.slice(1);
6535
- if (wideAccentLabels.has(label)) {
6536
- // Each type in the `if` statement corresponds to one of the ParseNode
6537
- // types below. This narrowing is required to access `grp.base`.
6538
- // TODO(ts)
6539
- var grp = group;
6635
+ if (wideAccentLabels.has(label) && 'base' in group) {
6540
6636
  // There are four SVG images available for each function.
6541
6637
  // Choose a taller image when there are more characters.
6542
- var numChars = grp.base.type === "ordgroup" ? grp.base.body.length : 1;
6638
+ var numChars = group.base.type === "ordgroup" ? group.base.body.length : 1;
6543
6639
  var viewBoxHeight;
6544
6640
  var pathName;
6545
6641
  var _height;
@@ -6584,16 +6680,20 @@ var stretchySvg = function stretchySvg(group, options) {
6584
6680
  } else {
6585
6681
  var spans = [];
6586
6682
  var data = katexImagesData[label];
6683
+ if (!data) {
6684
+ throw new Error("No SVG data for \"" + label + "\".");
6685
+ }
6587
6686
  var [paths, _minWidth, _viewBoxHeight] = data;
6588
6687
  var _height2 = _viewBoxHeight / 1000;
6589
6688
  var numSvgChildren = paths.length;
6590
6689
  var widthClasses;
6591
6690
  var aligns;
6592
6691
  if (numSvgChildren === 1) {
6593
- // TODO(ts): All these cases must be of the 4-tuple type.
6594
- var align1 = data[3];
6692
+ if (data.length !== 4) {
6693
+ throw new Error("Expected 4-tuple for single-path SVG data \"" + label + "\".");
6694
+ }
6595
6695
  widthClasses = ["hide-tail"];
6596
- aligns = [align1];
6696
+ aligns = [data[3]];
6597
6697
  } else if (numSvgChildren === 2) {
6598
6698
  widthClasses = ["halfarrow-left", "halfarrow-right"];
6599
6699
  aligns = ["xMinYMin", "xMaxYMin"];
@@ -6690,6 +6790,34 @@ var stretchyEnclose = function stretchyEnclose(inner, label, topPad, bottomPad,
6690
6790
  return img;
6691
6791
  };
6692
6792
 
6793
+ /**
6794
+ * Small module for atom-group constants and type guard. Kept separate from
6795
+ * `symbols.ts` so that consumers (notably `contrib/render-a11y-string`) can
6796
+ * pull in `isAtom` without dragging in the ~870-line symbol tables.
6797
+ */
6798
+ // Some of these have a "-token" suffix since these are also used as `ParseNode`
6799
+ // types for raw text tokens, and we want to avoid conflicts with higher-level
6800
+ // `ParseNode` types. These `ParseNode`s are constructed within `Parser` by
6801
+ // looking up the `symbols` map.
6802
+ var ATOMS = {
6803
+ "bin": 1,
6804
+ "close": 1,
6805
+ "inner": 1,
6806
+ "open": 1,
6807
+ "punct": 1,
6808
+ "rel": 1
6809
+ };
6810
+ var NON_ATOMS = {
6811
+ "accent-token": 1,
6812
+ "mathord": 1,
6813
+ "op-token": 1,
6814
+ "spacing": 1,
6815
+ "textord": 1
6816
+ };
6817
+ function isAtom(value) {
6818
+ return value in ATOMS;
6819
+ }
6820
+
6693
6821
  /**
6694
6822
  * Asserts that the node is of the given type and returns it with stricter
6695
6823
  * typing. Throws if the node's type does not match.
@@ -7061,7 +7189,8 @@ defineFunction({
7061
7189
  }, {
7062
7190
  type: "elem",
7063
7191
  elem: arrowBody,
7064
- shift: arrowShift
7192
+ shift: arrowShift,
7193
+ wrapperClasses: ["svg-align"]
7065
7194
  }, {
7066
7195
  type: "elem",
7067
7196
  elem: lowerGroup,
@@ -7078,12 +7207,11 @@ defineFunction({
7078
7207
  }, {
7079
7208
  type: "elem",
7080
7209
  elem: arrowBody,
7081
- shift: arrowShift
7210
+ shift: arrowShift,
7211
+ wrapperClasses: ["svg-align"]
7082
7212
  }]
7083
7213
  });
7084
7214
  }
7085
- // TODO(ts): Replace this with passing "svg-align" into makeVList.
7086
- vlist.children[0].children[0].children[1].classes.push("svg-align");
7087
7215
  return makeSpan(["mrel", "x-arrow"], [vlist], options);
7088
7216
  },
7089
7217
  mathmlBuilder(group, options) {
@@ -7318,7 +7446,8 @@ var newCell = () => {
7318
7446
  type: "styling",
7319
7447
  body: [],
7320
7448
  mode: "math",
7321
- style: "display"
7449
+ style: "display",
7450
+ resetFont: true
7322
7451
  };
7323
7452
  };
7324
7453
  var isStartOfArrow = node => {
@@ -7380,7 +7509,6 @@ function parseCD(parser) {
7380
7509
  parser.gullet.macros.set("\\cr", "\\\\\\relax");
7381
7510
  parser.gullet.beginGroup();
7382
7511
  while (true) {
7383
- // eslint-disable-line no-constant-condition
7384
7512
  // Get the parse nodes for the next row.
7385
7513
  parsedRows.push(parser.parseExpression(false, "\\\\"));
7386
7514
  parser.gullet.endGroup();
@@ -7464,7 +7592,9 @@ function parseCD(parser) {
7464
7592
  type: "styling",
7465
7593
  body: [arrow],
7466
7594
  mode: "math",
7467
- style: "display" // CD is always displaystyle.
7595
+ style: "display",
7596
+ // CD is always displaystyle.
7597
+ resetFont: true
7468
7598
  };
7469
7599
  row.push(wrappedArrow);
7470
7600
  // In CD's syntax, cells are implicit. That is, everything that
@@ -8341,9 +8471,9 @@ var makeSqrtImage = function makeSqrtImage(height, options) {
8341
8471
  var extraVinculum = Math.max(0, options.minRuleThickness - options.fontMetrics().sqrtRuleThickness);
8342
8472
  // Create a span containing an SVG image of a sqrt symbol.
8343
8473
  var span;
8344
- var spanHeight = 0;
8345
- var texHeight = 0;
8346
- var viewBoxHeight = 0;
8474
+ var spanHeight;
8475
+ var texHeight;
8476
+ var viewBoxHeight;
8347
8477
  var advanceWidth;
8348
8478
  // We create viewBoxes with 80 units of "padding" above each surd.
8349
8479
  // Then browser rounding error on the parent span height will not
@@ -8661,6 +8791,9 @@ var delimiterSizes = {
8661
8791
  }
8662
8792
  };
8663
8793
  var delimiters = new Set(["(", "\\lparen", ")", "\\rparen", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\u230a", "\u230b", "\\lceil", "\\rceil", "\u2308", "\u2309", "<", ">", "\\langle", "\u27e8", "\\rangle", "\u27e9", "\\lt", "\\gt", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\u27ee", "\u27ef", "\\lmoustache", "\\rmoustache", "\u23b0", "\u23b1", "/", "\\backslash", "|", "\\vert", "\\|", "\\Vert", "\\uparrow", "\\Uparrow", "\\downarrow", "\\Downarrow", "\\updownarrow", "\\Updownarrow", "."]);
8794
+ function isMiddleDelimNode(node) {
8795
+ return 'isMiddle' in node;
8796
+ }
8664
8797
  // Delimiter functions
8665
8798
  function checkDelimiter(delim, context) {
8666
8799
  var symDelim = checkSymbolNodeType(delim);
@@ -8783,10 +8916,8 @@ defineFunction({
8783
8916
  var hadMiddle = false;
8784
8917
  // Calculate its height and depth
8785
8918
  for (var i = 0; i < inner.length; i++) {
8786
- // Property `isMiddle` not defined on `span`. See comment in
8787
- // "middle"'s htmlBuilder.
8788
- // TODO(ts)
8789
- if (inner[i].isMiddle) {
8919
+ var node = inner[i];
8920
+ if (isMiddleDelimNode(node)) {
8790
8921
  hadMiddle = true;
8791
8922
  } else {
8792
8923
  innerHeight = Math.max(inner[i].height, innerHeight);
@@ -8813,11 +8944,8 @@ defineFunction({
8813
8944
  if (hadMiddle) {
8814
8945
  for (var _i = 1; _i < inner.length; _i++) {
8815
8946
  var middleDelim = inner[_i];
8816
- // Property `isMiddle` not defined on `span`. See comment in
8817
- // "middle"'s htmlBuilder.
8818
- // TODO(ts)
8819
- var isMiddle = middleDelim.isMiddle;
8820
- if (isMiddle) {
8947
+ if (isMiddleDelimNode(middleDelim)) {
8948
+ var isMiddle = middleDelim.isMiddle;
8821
8949
  // Apply the options that were active when \middle was called
8822
8950
  inner[_i] = makeLeftRightDelim(isMiddle.delim, innerHeight, innerDepth, isMiddle.options, group.mode, []);
8823
8951
  }
@@ -8878,16 +9006,14 @@ defineFunction({
8878
9006
  middleDelim = makeNullDelimiter(options, []);
8879
9007
  } else {
8880
9008
  middleDelim = makeSizedDelim(group.delim, 1, options, group.mode, []);
8881
- var isMiddle = {
9009
+ // Patch an ad-hoc property onto the node so the \left/\right
9010
+ // builder can reconstruct appropriately sized middle delimiters.
9011
+ // isMiddle is not part of HtmlDomNode; the read side uses
9012
+ // isMiddleDelimNode() to check before accessing.
9013
+ middleDelim.isMiddle = {
8882
9014
  delim: group.delim,
8883
9015
  options
8884
9016
  };
8885
- // Property `isMiddle` not defined on `span`. It is only used in
8886
- // this file above.
8887
- // TODO: Fix this violation of the `span` type and possibly rename
8888
- // things since `isMiddle` sounds like a boolean, but is a struct.
8889
- // TODO(ts)
8890
- middleDelim.isMiddle = isMiddle;
8891
9017
  }
8892
9018
  return middleDelim;
8893
9019
  },
@@ -8915,7 +9041,7 @@ var htmlBuilder$7 = (group, options) => {
8915
9041
  var label = group.label.slice(1);
8916
9042
  var scale = options.sizeMultiplier;
8917
9043
  var img;
8918
- var imgShift = 0;
9044
+ var imgShift;
8919
9045
  // In the LaTeX cancel package, line geometry is slightly different
8920
9046
  // depending on whether the subject is wider than it is tall, or vice versa.
8921
9047
  // We don't know the width of a group, so as a proxy, we test if
@@ -8967,8 +9093,8 @@ var htmlBuilder$7 = (group, options) => {
8967
9093
  inner.classes.push("boxpad");
8968
9094
  }
8969
9095
  // Add vertical padding
8970
- var topPad = 0;
8971
- var bottomPad = 0;
9096
+ var topPad;
9097
+ var bottomPad;
8972
9098
  var ruleThickness = 0;
8973
9099
  // ref: cancel package: \advance\totalheight2\p@ % "+2"
8974
9100
  if (/box/.test(label)) {
@@ -9049,7 +9175,7 @@ var htmlBuilder$7 = (group, options) => {
9049
9175
  }
9050
9176
  };
9051
9177
  var mathmlBuilder$6 = (group, options) => {
9052
- var fboxsep = 0;
9178
+ var fboxsep;
9053
9179
  var node = new MathNode(group.label.includes("colorbox") ? "mpadded" : "menclose", [buildGroup(group.body, options)]);
9054
9180
  switch (group.label) {
9055
9181
  case "\\cancel":
@@ -9101,7 +9227,7 @@ defineFunction({
9101
9227
  props: {
9102
9228
  numArgs: 2,
9103
9229
  allowedInText: true,
9104
- argTypes: ["color", "text"]
9230
+ argTypes: ["color", "hbox"]
9105
9231
  },
9106
9232
  handler(_ref, args, optArgs) {
9107
9233
  var {
@@ -9127,7 +9253,7 @@ defineFunction({
9127
9253
  props: {
9128
9254
  numArgs: 3,
9129
9255
  allowedInText: true,
9130
- argTypes: ["color", "color", "text"]
9256
+ argTypes: ["color", "color", "hbox"]
9131
9257
  },
9132
9258
  handler(_ref2, args, optArgs) {
9133
9259
  var {
@@ -9291,11 +9417,14 @@ function defineMacro(name, body) {
9291
9417
  * This object is immutable.
9292
9418
  */
9293
9419
  class SourceLocation {
9294
- // The + prefix indicates that these fields aren't writeable
9295
- // Lexer holding the input string.
9296
- // Start offset, zero-based inclusive.
9297
9420
  // End offset, zero-based exclusive.
9298
9421
  constructor(lexer, start, end) {
9422
+ // The + prefix indicates that these fields aren't writeable
9423
+ this.lexer = void 0;
9424
+ // Lexer holding the input string.
9425
+ this.start = void 0;
9426
+ // Start offset, zero-based inclusive.
9427
+ this.end = void 0;
9299
9428
  this.lexer = lexer;
9300
9429
  this.start = start;
9301
9430
  this.end = end;
@@ -9333,11 +9462,15 @@ class SourceLocation {
9333
9462
  * lead to degraded error reporting, though.
9334
9463
  */
9335
9464
  class Token {
9336
- // don't expand the token
9337
9465
  // used in \noexpand
9338
9466
  constructor(text,
9339
9467
  // the text of this token
9340
9468
  loc) {
9469
+ this.text = void 0;
9470
+ this.loc = void 0;
9471
+ this.noexpand = void 0;
9472
+ // don't expand the token
9473
+ this.treatAsRelax = void 0;
9341
9474
  this.text = text;
9342
9475
  this.loc = loc;
9343
9476
  }
@@ -9458,7 +9591,6 @@ function parseArray(parser, _ref, style) {
9458
9591
  // Test for \hline at the top of the array.
9459
9592
  hLinesBeforeRow.push(getHLines(parser));
9460
9593
  while (true) {
9461
- // eslint-disable-line no-constant-condition
9462
9594
  // Parse each cell in its own group (namespace)
9463
9595
  var cellBody = parser.parseExpression(false, singleRow ? "\\end" : "\\\\");
9464
9596
  parser.gullet.endGroup();
@@ -9473,6 +9605,7 @@ function parseArray(parser, _ref, style) {
9473
9605
  type: "styling",
9474
9606
  mode: parser.mode,
9475
9607
  style,
9608
+ resetFont: true,
9476
9609
  body: [cell]
9477
9610
  };
9478
9611
  }
@@ -9607,7 +9740,12 @@ var htmlBuilder$6 = function htmlBuilder(group, options) {
9607
9740
  if (nc < inrow.length) {
9608
9741
  nc = inrow.length;
9609
9742
  }
9610
- var outrow = new Array(inrow.length);
9743
+ var outrow = {
9744
+ cells: new Array(inrow.length),
9745
+ height: 0,
9746
+ depth: 0,
9747
+ pos: 0
9748
+ };
9611
9749
  for (c = 0; c < inrow.length; ++c) {
9612
9750
  var elt = buildGroup$1(inrow[c], options);
9613
9751
  if (depth < elt.depth) {
@@ -9616,7 +9754,7 @@ var htmlBuilder$6 = function htmlBuilder(group, options) {
9616
9754
  if (height < elt.height) {
9617
9755
  height = elt.height;
9618
9756
  }
9619
- outrow[c] = elt;
9757
+ outrow.cells[c] = elt;
9620
9758
  }
9621
9759
  var rowGap = group.rowGaps[r];
9622
9760
  var gap = 0;
@@ -9731,7 +9869,7 @@ var htmlBuilder$6 = function htmlBuilder(group, options) {
9731
9869
  var colElems = [];
9732
9870
  for (r = 0; r < nr; ++r) {
9733
9871
  var row = body[r];
9734
- var elem = row[c];
9872
+ var elem = row.cells[c];
9735
9873
  if (!elem) {
9736
9874
  continue;
9737
9875
  }
@@ -10382,7 +10520,10 @@ defineFunction({
10382
10520
  if (end.name !== envName) {
10383
10521
  throw new ParseError("Mismatch: \\begin{" + envName + "} matched by \\end{" + end.name + "}", endNameToken);
10384
10522
  }
10385
- // TODO(ts), "environment" handler returns an environment ParseNode
10523
+ // env.handler returns the specific node type (e.g. "array"),
10524
+ // not "environment". This cast is unavoidable: defineFunction
10525
+ // requires the handler to return ParseNode<"environment"> but
10526
+ // \begin delegates to environment handlers with different types.
10386
10527
  return result;
10387
10528
  }
10388
10529
  return {
@@ -10408,8 +10549,7 @@ var mathmlBuilder$4 = (group, options) => {
10408
10549
  var fontAliases = {
10409
10550
  "\\Bbb": "\\mathbb",
10410
10551
  "\\bold": "\\mathbf",
10411
- "\\frak": "\\mathfrak",
10412
- "\\bm": "\\boldsymbol"
10552
+ "\\frak": "\\mathfrak"
10413
10553
  };
10414
10554
  defineFunction({
10415
10555
  type: "font",
@@ -10489,11 +10629,10 @@ defineFunction({
10489
10629
  mode
10490
10630
  } = parser;
10491
10631
  var body = parser.parseExpression(true, breakOnTokenText);
10492
- var style = "math" + funcName.slice(1);
10493
10632
  return {
10494
10633
  type: "font",
10495
10634
  mode: mode,
10496
- font: style,
10635
+ font: "math" + funcName.slice(1),
10497
10636
  body: {
10498
10637
  type: "ordgroup",
10499
10638
  mode: parser.mode,
@@ -10948,18 +11087,18 @@ var htmlBuilder$3 = (grp, options) => {
10948
11087
  size: 0.1
10949
11088
  }, {
10950
11089
  type: "elem",
10951
- elem: braceBody
11090
+ elem: braceBody,
11091
+ wrapperClasses: ["svg-align"]
10952
11092
  }]
10953
11093
  });
10954
- // TODO(ts): Replace this with passing "svg-align" into makeVList.
10955
- vlist.children[0].children[0].children[1].classes.push("svg-align");
10956
11094
  } else {
10957
11095
  vlist = makeVList({
10958
11096
  positionType: "bottom",
10959
11097
  positionData: body.depth + 0.1 + braceBody.height,
10960
11098
  children: [{
10961
11099
  type: "elem",
10962
- elem: braceBody
11100
+ elem: braceBody,
11101
+ wrapperClasses: ["svg-align"]
10963
11102
  }, {
10964
11103
  type: "kern",
10965
11104
  size: 0.1
@@ -10968,8 +11107,6 @@ var htmlBuilder$3 = (grp, options) => {
10968
11107
  elem: body
10969
11108
  }]
10970
11109
  });
10971
- // TODO(ts): Replace this with passing "svg-align" into makeVList.
10972
- vlist.children[0].children[0].children[0].classes.push("svg-align");
10973
11110
  }
10974
11111
  if (supSubGroup) {
10975
11112
  // To write the supsub, wrap the first vlist in another vlist:
@@ -11151,11 +11288,11 @@ defineFunction({
11151
11288
  };
11152
11289
  },
11153
11290
  htmlBuilder(group, options) {
11154
- var elements = buildExpression$1(group.body, options, false);
11291
+ var elements = buildExpression$1(group.body, options.withFont(''), false);
11155
11292
  return makeFragment(elements);
11156
11293
  },
11157
11294
  mathmlBuilder(group, options) {
11158
- return new MathNode("mrow", buildExpression(group.body, options));
11295
+ return new MathNode("mrow", buildExpression(group.body, options.withFont('')));
11159
11296
  }
11160
11297
  });
11161
11298
 
@@ -11559,6 +11696,7 @@ defineFunction({
11559
11696
  type: "styling",
11560
11697
  mode: parser.mode,
11561
11698
  style: "text",
11699
+ resetFont: true,
11562
11700
  body
11563
11701
  };
11564
11702
  }
@@ -11768,6 +11906,9 @@ var htmlBuilder$2 = (grp, options) => {
11768
11906
  large = true;
11769
11907
  }
11770
11908
  var base;
11909
+ // Italic correction from the symbol glyph, captured before the symbol
11910
+ // may be wrapped in a vlist (for \oiint/\oiiint). Stays 0 for non-symbol ops.
11911
+ var symbolItalic;
11771
11912
  if (group.symbol) {
11772
11913
  // If this is a symbol, create the symbol.
11773
11914
  var fontName = large ? "Size2-Regular" : "Size1-Regular";
@@ -11779,10 +11920,10 @@ var htmlBuilder$2 = (grp, options) => {
11779
11920
  group.name = stash === "oiint" ? "\\iint" : "\\iiint";
11780
11921
  }
11781
11922
  base = makeSymbol(group.name, fontName, "math", options, ["mop", "op-symbol", large ? "large-op" : "small-op"]);
11923
+ symbolItalic = base.italic;
11782
11924
  if (stash.length > 0) {
11783
11925
  // We're in \oiint or \oiiint. Overlay the oval.
11784
11926
  // TODO: When font glyphs are available, delete this code.
11785
- var italic = base.italic;
11786
11927
  var oval = staticSvg(stash + "Size" + (large ? "2" : "1"), options);
11787
11928
  base = makeVList({
11788
11929
  positionType: "individualShift",
@@ -11798,8 +11939,9 @@ var htmlBuilder$2 = (grp, options) => {
11798
11939
  });
11799
11940
  group.name = "\\" + stash;
11800
11941
  base.classes.unshift("mop");
11801
- // TODO(ts)
11802
- base.italic = italic;
11942
+ // Carry the italic correction from the original symbol to the
11943
+ // vlist wrapper so supsub can use it for subscript positioning.
11944
+ base.italic = symbolItalic;
11803
11945
  }
11804
11946
  } else if (group.body) {
11805
11947
  // If this is a list, compose that list.
@@ -11823,6 +11965,7 @@ var htmlBuilder$2 = (grp, options) => {
11823
11965
  var baseShift = 0;
11824
11966
  var slant = 0;
11825
11967
  if ((base instanceof SymbolNode || group.name === "\\oiint" || group.name === "\\oiiint") && !group.suppressBaseShift) {
11968
+ var _base$italic;
11826
11969
  // We suppress the shift of the base of \overset and \underset. Otherwise,
11827
11970
  // shift the symbol so its center lies on the axis (rule 13). It
11828
11971
  // appears that our fonts have the centers of the symbols already
@@ -11831,8 +11974,9 @@ var htmlBuilder$2 = (grp, options) => {
11831
11974
  // the vlist creation or separately when there are no limits.
11832
11975
  baseShift = (base.height - base.depth) / 2 - options.fontMetrics().axisHeight;
11833
11976
  // The slant of the symbol is just its italic correction.
11834
- // TODO(ts)
11835
- slant = base.italic || 0;
11977
+ // SymbolNode carries .italic natively; Span (for \oiint/\oiiint)
11978
+ // only has it set when nonzero, so default to 0.
11979
+ slant = (_base$italic = base.italic) != null ? _base$italic : 0;
11836
11980
  }
11837
11981
  if (hasLimits) {
11838
11982
  return assembleSupSub(base, supGroup, subGroup, options, style, slant, baseShift);
@@ -12496,7 +12640,7 @@ defineFunction({
12496
12640
  // Optional [tb] argument is engaged.
12497
12641
  // ref: amsmath: \renewcommand{\smash}[1][tb]{%
12498
12642
  // def\mb@t{\ht}\def\mb@b{\dp}\def\mb@tb{\ht\z@\z@\dp}%
12499
- var letter = "";
12643
+ var letter;
12500
12644
  for (var i = 0; i < tbArg.body.length; ++i) {
12501
12645
  var node = tbArg.body[i];
12502
12646
  letter = assertSymbolNodeType(node).text;
@@ -12690,6 +12834,9 @@ var styleMap = {
12690
12834
  "script": Style$1.SCRIPT,
12691
12835
  "scriptscript": Style$1.SCRIPTSCRIPT
12692
12836
  };
12837
+ function isStyleStr(s) {
12838
+ return s in styleMap;
12839
+ }
12693
12840
  defineFunction({
12694
12841
  type: "styling",
12695
12842
  names: ["\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle"],
@@ -12708,8 +12855,10 @@ defineFunction({
12708
12855
  var body = parser.parseExpression(true, breakOnTokenText);
12709
12856
  // TODO: Refactor to avoid duplicating styleMap in multiple places (e.g.
12710
12857
  // here and in buildHTML and de-dupe the enumeration of all the styles).
12711
- // TODO(ts): The names above exactly match the styles.
12712
12858
  var style = funcName.slice(1, funcName.length - 5);
12859
+ if (!isStyleStr(style)) {
12860
+ throw new Error("Unknown style: " + style);
12861
+ }
12713
12862
  return {
12714
12863
  type: "styling",
12715
12864
  mode: parser.mode,
@@ -12722,13 +12871,19 @@ defineFunction({
12722
12871
  htmlBuilder(group, options) {
12723
12872
  // Style changes are handled in the TeXbook on pg. 442, Rule 3.
12724
12873
  var newStyle = styleMap[group.style];
12725
- var newOptions = options.havingStyle(newStyle).withFont('');
12874
+ var newOptions = options.havingStyle(newStyle);
12875
+ if (group.resetFont) {
12876
+ newOptions = newOptions.withFont('');
12877
+ }
12726
12878
  return sizingGroup(group.body, newOptions, options);
12727
12879
  },
12728
12880
  mathmlBuilder(group, options) {
12729
12881
  // Figure out what style we're changing to.
12730
12882
  var newStyle = styleMap[group.style];
12731
12883
  var newOptions = options.havingStyle(newStyle);
12884
+ if (group.resetFont) {
12885
+ newOptions = newOptions.withFont('');
12886
+ }
12732
12887
  var inner = buildExpression(group.body, newOptions);
12733
12888
  var node = new MathNode("mstyle", inner);
12734
12889
  var styleAttributes = {
@@ -12832,8 +12987,10 @@ defineFunctionBuilders({
12832
12987
  // amount. Note we only do this when the base is a single symbol.
12833
12988
  var isOiint = group.base && group.base.type === "op" && group.base.name && (group.base.name === "\\oiint" || group.base.name === "\\oiiint");
12834
12989
  if (base instanceof SymbolNode || isOiint) {
12835
- // @ts-ignore
12836
- marginLeft = makeEm(-base.italic);
12990
+ var _base$italic;
12991
+ // SymbolNode has .italic natively; for \oiint/\oiiint the
12992
+ // op builder stores .italic on the wrapping Span.
12993
+ marginLeft = makeEm(-((_base$italic = base.italic) != null ? _base$italic : 0));
12837
12994
  }
12838
12995
  }
12839
12996
  var supsub;
@@ -13376,10 +13533,13 @@ combiningDiacriticalMarkString + "*") +
13376
13533
  "|" + controlSymbolRegexString + ")"); // \\, \', etc.
13377
13534
  /** Main Lexer class */
13378
13535
  class Lexer {
13379
- // Category codes. The lexer only supports comment characters (14) for now.
13380
- // MacroExpander additionally distinguishes active (13).
13381
-
13382
13536
  constructor(input, settings) {
13537
+ this.input = void 0;
13538
+ this.settings = void 0;
13539
+ this.tokenRegex = void 0;
13540
+ // Category codes. The lexer only supports comment characters (14) for now.
13541
+ // MacroExpander additionally distinguishes active (13).
13542
+ this.catcodes = void 0;
13383
13543
  // Separate accents from characters
13384
13544
  this.input = input;
13385
13545
  this.settings = settings;
@@ -13443,6 +13603,9 @@ class Namespace {
13443
13603
  if (globalMacros === void 0) {
13444
13604
  globalMacros = {};
13445
13605
  }
13606
+ this.current = void 0;
13607
+ this.builtins = void 0;
13608
+ this.undefStack = void 0;
13446
13609
  this.current = globalMacros;
13447
13610
  this.builtins = builtins;
13448
13611
  this.undefStack = [];
@@ -14454,6 +14617,12 @@ var implicitCommands = {
14454
14617
  };
14455
14618
  class MacroExpander {
14456
14619
  constructor(input, settings, mode) {
14620
+ this.settings = void 0;
14621
+ this.expansionCount = void 0;
14622
+ this.lexer = void 0;
14623
+ this.macros = void 0;
14624
+ this.stack = void 0;
14625
+ this.mode = void 0;
14457
14626
  this.settings = settings;
14458
14627
  this.expansionCount = 0;
14459
14628
  this.feed(input);
@@ -15390,6 +15559,11 @@ var unicodeSymbols = {
15390
15559
  */
15391
15560
  class Parser {
15392
15561
  constructor(input, settings) {
15562
+ this.mode = void 0;
15563
+ this.gullet = void 0;
15564
+ this.settings = void 0;
15565
+ this.leftrightDepth = void 0;
15566
+ this.nextToken = void 0;
15393
15567
  // Start in math mode
15394
15568
  this.mode = "math";
15395
15569
  // Create a new macro expander (gullet) and (indirectly via that) also a
@@ -15863,13 +16037,16 @@ class Parser {
15863
16037
  case "hbox":
15864
16038
  {
15865
16039
  // hbox argument type wraps the argument in the equivalent of
15866
- // \hbox, which is like \text but switching to \textstyle size.
16040
+ // \hbox, which is like \text but switching to \textstyle size
16041
+ // and resetting math font.
15867
16042
  var group = this.parseArgumentGroup(optional, "text");
15868
16043
  return group != null ? {
15869
16044
  type: "styling",
15870
16045
  mode: group.mode,
15871
16046
  body: [group],
15872
- style: "text" // simulate \textstyle
16047
+ style: "text",
16048
+ // simulate \textstyle
16049
+ resetFont: true
15873
16050
  } : null;
15874
16051
  }
15875
16052
  case "raw":
@@ -16223,18 +16400,15 @@ class Parser {
16223
16400
  var group = symbols[this.mode][text].group;
16224
16401
  var loc = SourceLocation.range(nucleus);
16225
16402
  var s;
16226
- if (ATOMS.hasOwnProperty(group)) {
16227
- // TODO(ts)
16228
- var family = group;
16403
+ if (isAtom(group)) {
16229
16404
  s = {
16230
16405
  type: "atom",
16231
16406
  mode: this.mode,
16232
- family,
16407
+ family: group,
16233
16408
  loc,
16234
16409
  text
16235
16410
  };
16236
16411
  } else {
16237
- // TODO(ts)
16238
16412
  s = {
16239
16413
  type: group,
16240
16414
  mode: this.mode,
@@ -16242,7 +16416,6 @@ class Parser {
16242
16416
  text
16243
16417
  };
16244
16418
  }
16245
- // TODO(ts)
16246
16419
  symbol = s;
16247
16420
  } else if (text.charCodeAt(0) >= 0x80) {
16248
16421
  // no symbol for e.g. ^
@@ -16288,12 +16461,10 @@ class Parser {
16288
16461
  label: command,
16289
16462
  isStretchy: false,
16290
16463
  isShifty: true,
16291
- // TODO(ts)
16292
16464
  base: symbol
16293
16465
  };
16294
16466
  }
16295
16467
  }
16296
- // TODO(ts)
16297
16468
  return symbol;
16298
16469
  }
16299
16470
  }
@@ -16407,7 +16578,7 @@ var renderToHTMLTree = function renderToHTMLTree(expression, options) {
16407
16578
  return renderError(error, expression, settings);
16408
16579
  }
16409
16580
  };
16410
- var version = "0.16.45";
16581
+ var version = "0.16.46";
16411
16582
  var __domTree = {
16412
16583
  Span,
16413
16584
  Anchor,