temml 0.11.11 → 0.12.2

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 (62) hide show
  1. package/README.md +1 -1
  2. package/dist/Temml-Asana.css +28 -0
  3. package/dist/Temml-Latin-Modern.css +29 -1
  4. package/dist/Temml-Libertinus.css +28 -0
  5. package/dist/Temml-Local.css +28 -0
  6. package/dist/Temml-NotoSans.css +28 -0
  7. package/dist/Temml-STIX2.css +28 -0
  8. package/dist/temml.cjs +305 -253
  9. package/dist/temml.d.ts +2 -2
  10. package/dist/temml.js +305 -253
  11. package/dist/temml.min.js +1 -1
  12. package/dist/temml.mjs +305 -253
  13. package/dist/temmlPostProcess.js +1 -1
  14. package/package.json +1 -1
  15. package/src/Settings.js +3 -3
  16. package/src/buildMathML.js +1 -1
  17. package/src/canceltoArrow.svg +15 -0
  18. package/src/domTree.js +1 -1
  19. package/src/environments/array.js +7 -7
  20. package/src/environments/cd.js +1 -1
  21. package/src/functions/accent.js +3 -4
  22. package/src/functions/accentunder.js +2 -2
  23. package/src/functions/arrow.js +2 -2
  24. package/src/functions/cancelto.js +56 -16
  25. package/src/functions/color.js +1 -1
  26. package/src/functions/cr.js +1 -1
  27. package/src/functions/delimsizing.js +1 -1
  28. package/src/functions/enclose.js +8 -10
  29. package/src/functions/envTag.js +1 -1
  30. package/src/functions/font.js +1 -1
  31. package/src/functions/genfrac.js +1 -1
  32. package/src/functions/{horizBrace.js → horizBracket.js} +6 -6
  33. package/src/functions/includegraphics.js +1 -1
  34. package/src/functions/kern.js +1 -1
  35. package/src/functions/label.js +1 -1
  36. package/src/functions/lap.js +1 -1
  37. package/src/functions/mclass.js +2 -2
  38. package/src/functions/multiscript.js +1 -1
  39. package/src/functions/not.js +1 -1
  40. package/src/functions/op.js +2 -1
  41. package/src/functions/operatorname.js +1 -1
  42. package/src/functions/phantom.js +1 -1
  43. package/src/functions/raise.js +1 -1
  44. package/src/functions/rule.js +1 -1
  45. package/src/functions/sfrac.js +1 -1
  46. package/src/functions/smash.js +1 -1
  47. package/src/functions/sqrt.js +1 -1
  48. package/src/functions/supsub.js +6 -6
  49. package/src/functions/symbolsOp.js +1 -1
  50. package/src/functions/symbolsOrd.js +1 -1
  51. package/src/functions/symbolsSpacing.js +1 -1
  52. package/src/functions/tip.js +1 -1
  53. package/src/functions/toggle.js +1 -1
  54. package/src/functions/vcenter.js +1 -1
  55. package/src/functions/verb.js +1 -1
  56. package/src/functions.js +2 -2
  57. package/src/linebreaking.js +1 -1
  58. package/src/mathMLTree.js +1 -7
  59. package/src/postProcess.js +1 -1
  60. package/src/stretchy.js +5 -8
  61. package/src/units.js +1 -1
  62. package/src/utils.js +8 -15
package/dist/temml.cjs CHANGED
@@ -181,15 +181,8 @@ const round = function(n) {
181
181
  return +n.toFixed(4);
182
182
  };
183
183
 
184
- var utils = {
185
- deflt,
186
- escape,
187
- hyphenate,
188
- getBaseElem,
189
- isCharacterBox,
190
- protocolFromUrl,
191
- round
192
- };
184
+ // Identify short letters. Used for accents and \cancelto.
185
+ const smalls = "acegıȷmnopqrsuvwxyzαγεηικμνοπρςστυχωϕ𝐚𝐜𝐞𝐠𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐮𝐯𝐰𝐱𝐲𝐳";
193
186
 
194
187
  /**
195
188
  * This is a module for storing settings passed into Temml. It correctly handles
@@ -204,24 +197,24 @@ class Settings {
204
197
  constructor(options) {
205
198
  // allow null options
206
199
  options = options || {};
207
- this.displayMode = utils.deflt(options.displayMode, false); // boolean
208
- this.annotate = utils.deflt(options.annotate, false); // boolean
209
- this.leqno = utils.deflt(options.leqno, false); // boolean
210
- this.throwOnError = utils.deflt(options.throwOnError, false); // boolean
211
- this.errorColor = utils.deflt(options.errorColor, "#b22222"); // string
200
+ this.displayMode = deflt(options.displayMode, false); // boolean
201
+ this.annotate = deflt(options.annotate, false); // boolean
202
+ this.leqno = deflt(options.leqno, false); // boolean
203
+ this.throwOnError = deflt(options.throwOnError, false); // boolean
204
+ this.errorColor = deflt(options.errorColor, "#b22222"); // string
212
205
  this.macros = options.macros || {};
213
- this.wrap = utils.deflt(options.wrap, "tex"); // "tex" | "="
214
- this.xml = utils.deflt(options.xml, false); // boolean
215
- this.colorIsTextColor = utils.deflt(options.colorIsTextColor, false); // booelean
216
- this.strict = utils.deflt(options.strict, false); // boolean
217
- this.trust = utils.deflt(options.trust, false); // trust context. See html.js.
206
+ this.wrap = deflt(options.wrap, "none"); // "none" | "tex" | "="
207
+ this.xml = deflt(options.xml, false); // boolean
208
+ this.colorIsTextColor = deflt(options.colorIsTextColor, false); // boolean
209
+ this.strict = deflt(options.strict, false); // boolean
210
+ this.trust = deflt(options.trust, false); // trust context. See html.js.
218
211
  this.maxSize = (options.maxSize === undefined
219
212
  ? [Infinity, Infinity]
220
213
  : Array.isArray(options.maxSize)
221
214
  ? options.maxSize
222
215
  : [Infinity, Infinity]
223
216
  );
224
- this.maxExpand = Math.max(0, utils.deflt(options.maxExpand, 1000)); // number
217
+ this.maxExpand = Math.max(0, deflt(options.maxExpand, 1000)); // number
225
218
  }
226
219
 
227
220
  /**
@@ -234,7 +227,7 @@ class Settings {
234
227
  */
235
228
  isTrusted(context) {
236
229
  if (context.url && !context.protocol) {
237
- const protocol = utils.protocolFromUrl(context.url);
230
+ const protocol = protocolFromUrl(context.url);
238
231
  if (protocol == null) {
239
232
  return false
240
233
  }
@@ -430,7 +423,7 @@ const toMarkup = function(tagName) {
430
423
 
431
424
  // Add the class
432
425
  if (this.classes.length) {
433
- markup += ` class="${utils.escape(createClass(this.classes))}"`;
426
+ markup += ` class="${escape(createClass(this.classes))}"`;
434
427
  }
435
428
 
436
429
  let styles = "";
@@ -438,7 +431,7 @@ const toMarkup = function(tagName) {
438
431
  // Add the styles, after hyphenation
439
432
  for (const style in this.style) {
440
433
  if (Object.prototype.hasOwnProperty.call(this.style, style )) {
441
- styles += `${utils.hyphenate(style)}:${this.style[style]};`;
434
+ styles += `${hyphenate(style)}:${this.style[style]};`;
442
435
  }
443
436
  }
444
437
 
@@ -449,7 +442,7 @@ const toMarkup = function(tagName) {
449
442
  // Add the attributes
450
443
  for (const attr in this.attributes) {
451
444
  if (Object.prototype.hasOwnProperty.call(this.attributes, attr )) {
452
- markup += ` ${attr}="${utils.escape(this.attributes[attr])}"`;
445
+ markup += ` ${attr}="${escape(this.attributes[attr])}"`;
453
446
  }
454
447
  }
455
448
 
@@ -497,7 +490,7 @@ let TextNode$1 = class TextNode {
497
490
  return document.createTextNode(this.text);
498
491
  }
499
492
  toMarkup() {
500
- return utils.escape(this.text);
493
+ return escape(this.text);
501
494
  }
502
495
  };
503
496
 
@@ -522,9 +515,9 @@ class AnchorNode {
522
515
  }
523
516
 
524
517
  toMarkup() {
525
- let markup = `<a href='${utils.escape(this.href)}'`;
518
+ let markup = `<a href='${escape(this.href)}'`;
526
519
  if (this.classes.length > 0) {
527
- markup += ` class="${utils.escape(createClass(this.classes))}"`;
520
+ markup += ` class="${escape(createClass(this.classes))}"`;
528
521
  }
529
522
  markup += ">";
530
523
  for (let i = 0; i < this.children.length; i++) {
@@ -573,11 +566,11 @@ class Img {
573
566
  let styles = "";
574
567
  for (const style in this.style) {
575
568
  if (Object.prototype.hasOwnProperty.call(this.style, style )) {
576
- styles += `${utils.hyphenate(style)}:${this.style[style]};`;
569
+ styles += `${hyphenate(style)}:${this.style[style]};`;
577
570
  }
578
571
  }
579
572
  if (styles) {
580
- markup += ` style="${utils.escape(styles)}"`;
573
+ markup += ` style="${escape(styles)}"`;
581
574
  }
582
575
 
583
576
  markup += ">";
@@ -671,13 +664,13 @@ class MathNode {
671
664
  for (const attr in this.attributes) {
672
665
  if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
673
666
  markup += " " + attr + '="';
674
- markup += utils.escape(this.attributes[attr]);
667
+ markup += escape(this.attributes[attr]);
675
668
  markup += '"';
676
669
  }
677
670
  }
678
671
 
679
672
  if (this.classes.length > 0) {
680
- markup += ` class="${utils.escape(createClass(this.classes))}"`;
673
+ markup += ` class="${escape(createClass(this.classes))}"`;
681
674
  }
682
675
 
683
676
  let styles = "";
@@ -685,7 +678,7 @@ class MathNode {
685
678
  // Add the styles, after hyphenation
686
679
  for (const style in this.style) {
687
680
  if (Object.prototype.hasOwnProperty.call(this.style, style )) {
688
- styles += `${utils.hyphenate(style)}:${this.style[style]};`;
681
+ styles += `${hyphenate(style)}:${this.style[style]};`;
689
682
  }
690
683
  }
691
684
 
@@ -732,7 +725,7 @@ class TextNode {
732
725
  * (representing the text itself).
733
726
  */
734
727
  toMarkup() {
735
- return utils.escape(this.toText());
728
+ return escape(this.toText());
736
729
  }
737
730
 
738
731
  /**
@@ -757,12 +750,6 @@ const wrapWithMstyle = expression => {
757
750
  return node
758
751
  };
759
752
 
760
- var mathMLTree = {
761
- MathNode,
762
- TextNode,
763
- newDocumentFragment
764
- };
765
-
766
753
  /**
767
754
  * This file provides support for building horizontal stretchy elements.
768
755
  */
@@ -812,6 +799,8 @@ const stretchyCodePoint = {
812
799
  xrightarrow: "\u2192",
813
800
  underbrace: "\u23df",
814
801
  overbrace: "\u23de",
802
+ overbracket: "\u23b4",
803
+ underbracket: "\u23b5",
815
804
  overgroup: "\u23e0",
816
805
  overparen: "⏜",
817
806
  undergroup: "\u23e1",
@@ -854,8 +843,8 @@ const stretchyCodePoint = {
854
843
  };
855
844
 
856
845
  const mathMLnode = function(label) {
857
- const child = new mathMLTree.TextNode(stretchyCodePoint[label.slice(1)]);
858
- const node = new mathMLTree.MathNode("mo", [child]);
846
+ const child = new TextNode(stretchyCodePoint[label.slice(1)]);
847
+ const node = new MathNode("mo", [child]);
859
848
  node.setAttribute("stretchy", "true");
860
849
  return node
861
850
  };
@@ -878,11 +867,6 @@ const accentNode = (group) => {
878
867
  return mo
879
868
  };
880
869
 
881
- var stretchy = {
882
- mathMLnode,
883
- accentNode
884
- };
885
-
886
870
  /**
887
871
  * This file holds a list of all no-argument functions and single-character
888
872
  * symbols (like 'a' or ';').
@@ -2036,13 +2020,13 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
2036
2020
  node.attributes.linebreak === "newline") {
2037
2021
  // A hard line break. Create a <mtr> for the current block.
2038
2022
  if (block.length > 0) {
2039
- mrows.push(new mathMLTree.MathNode("mrow", block));
2023
+ mrows.push(new MathNode("mrow", block));
2040
2024
  }
2041
2025
  mrows.push(node);
2042
2026
  block = [];
2043
- const mtd = new mathMLTree.MathNode("mtd", mrows);
2027
+ const mtd = new MathNode("mtd", mrows);
2044
2028
  mtd.style.textAlign = "left";
2045
- mtrs.push(new mathMLTree.MathNode("mtr", [mtd]));
2029
+ mtrs.push(new MathNode("mtr", [mtd]));
2046
2030
  mrows = [];
2047
2031
  i += 1;
2048
2032
  continue
@@ -2060,7 +2044,7 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
2060
2044
  if (numTopLevelEquals > 1) {
2061
2045
  block.pop();
2062
2046
  // Start a new block. (Insert a soft linebreak.)
2063
- const element = new mathMLTree.MathNode("mrow", block);
2047
+ const element = new MathNode("mrow", block);
2064
2048
  mrows.push(element);
2065
2049
  block = [node];
2066
2050
  }
@@ -2101,7 +2085,7 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
2101
2085
  }
2102
2086
  if (glueIsFreeOfNobreak) {
2103
2087
  // Start a new block. (Insert a soft linebreak.)
2104
- const element = new mathMLTree.MathNode("mrow", block);
2088
+ const element = new MathNode("mrow", block);
2105
2089
  mrows.push(element);
2106
2090
  block = [];
2107
2091
  }
@@ -2110,22 +2094,22 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
2110
2094
  i += 1;
2111
2095
  }
2112
2096
  if (block.length > 0) {
2113
- const element = new mathMLTree.MathNode("mrow", block);
2097
+ const element = new MathNode("mrow", block);
2114
2098
  mrows.push(element);
2115
2099
  }
2116
2100
  if (mtrs.length > 0) {
2117
- const mtd = new mathMLTree.MathNode("mtd", mrows);
2101
+ const mtd = new MathNode("mtd", mrows);
2118
2102
  mtd.style.textAlign = "left";
2119
- const mtr = new mathMLTree.MathNode("mtr", [mtd]);
2103
+ const mtr = new MathNode("mtr", [mtd]);
2120
2104
  mtrs.push(mtr);
2121
- const mtable = new mathMLTree.MathNode("mtable", mtrs);
2105
+ const mtable = new MathNode("mtable", mtrs);
2122
2106
  if (!isDisplayMode) {
2123
2107
  mtable.setAttribute("columnalign", "left");
2124
2108
  mtable.setAttribute("rowspacing", "0em");
2125
2109
  }
2126
2110
  return mtable
2127
2111
  }
2128
- return mathMLTree.newDocumentFragment(mrows);
2112
+ return newDocumentFragment(mrows);
2129
2113
  }
2130
2114
 
2131
2115
  /**
@@ -2154,15 +2138,15 @@ const makeText = function(text, mode, style) {
2154
2138
  text = symbols[mode][text].replace;
2155
2139
  }
2156
2140
 
2157
- return new mathMLTree.TextNode(text);
2141
+ return new TextNode(text);
2158
2142
  };
2159
2143
 
2160
2144
  const copyChar = (newRow, child) => {
2161
2145
  if (newRow.children.length === 0 ||
2162
2146
  newRow.children[newRow.children.length - 1].type !== "mtext") {
2163
- const mtext = new mathMLTree.MathNode(
2147
+ const mtext = new MathNode(
2164
2148
  "mtext",
2165
- [new mathMLTree.TextNode(child.children[0].text)]
2149
+ [new TextNode(child.children[0].text)]
2166
2150
  );
2167
2151
  newRow.children.push(mtext);
2168
2152
  } else {
@@ -2174,7 +2158,7 @@ const consolidateText = mrow => {
2174
2158
  // If possible, consolidate adjacent <mtext> elements into a single element.
2175
2159
  if (mrow.type !== "mrow" && mrow.type !== "mstyle") { return mrow }
2176
2160
  if (mrow.children.length === 0) { return mrow } // empty group, e.g., \text{}
2177
- const newRow = new mathMLTree.MathNode("mrow");
2161
+ const newRow = new MathNode("mrow");
2178
2162
  for (let i = 0; i < mrow.children.length; i++) {
2179
2163
  const child = mrow.children[i];
2180
2164
  if (child.type === "mtext" && Object.keys(child.attributes).length === 0) {
@@ -2244,7 +2228,7 @@ const makeRow = function(body, semisimple = false) {
2244
2228
  body[end].attributes.rspace = "0em";
2245
2229
  }
2246
2230
  }
2247
- return new mathMLTree.MathNode("mrow", body);
2231
+ return new MathNode("mrow", body);
2248
2232
  };
2249
2233
 
2250
2234
  /**
@@ -2369,7 +2353,7 @@ const buildExpressionRow = function(expression, style, semisimple = false) {
2369
2353
  */
2370
2354
  const buildGroup$1 = function(group, style) {
2371
2355
  if (!group) {
2372
- return new mathMLTree.MathNode("mrow");
2356
+ return new MathNode("mrow");
2373
2357
  }
2374
2358
 
2375
2359
  if (_mathmlGroupBuilders[group.type]) {
@@ -2382,7 +2366,7 @@ const buildGroup$1 = function(group, style) {
2382
2366
  };
2383
2367
 
2384
2368
  const glue$1 = _ => {
2385
- return new mathMLTree.MathNode("mtd", [], [], { padding: "0", width: "50%" })
2369
+ return new MathNode("mtd", [], [], { padding: "0", width: "50%" })
2386
2370
  };
2387
2371
 
2388
2372
  const labelContainers = ["mrow", "mtd", "mtable", "mtr"];
@@ -2409,12 +2393,12 @@ const taggedExpression = (expression, tag, style, leqno) => {
2409
2393
  tag.classes.push("tml-tag"); // to be available for \ref
2410
2394
 
2411
2395
  const label = getLabel(expression); // from a \label{} function.
2412
- expression = new mathMLTree.MathNode("mtd", [expression]);
2396
+ expression = new MathNode("mtd", [expression]);
2413
2397
  const rowArray = [glue$1(), expression, glue$1()];
2414
2398
  rowArray[leqno ? 0 : 2].children.push(tag);
2415
- const mtr = new mathMLTree.MathNode("mtr", rowArray, ["tml-tageqn"]);
2399
+ const mtr = new MathNode("mtr", rowArray, ["tml-tageqn"]);
2416
2400
  if (label) { mtr.setAttribute("id", label); }
2417
- const table = new mathMLTree.MathNode("mtable", [mtr]);
2401
+ const table = new MathNode("mtable", [mtr]);
2418
2402
  table.style.width = "100%";
2419
2403
  table.setAttribute("displaystyle", "true");
2420
2404
  return table
@@ -2451,13 +2435,13 @@ function buildMathML(tree, texExpression, style, settings) {
2451
2435
 
2452
2436
  if (settings.annotate) {
2453
2437
  // Build a TeX annotation of the source
2454
- const annotation = new mathMLTree.MathNode(
2455
- "annotation", [new mathMLTree.TextNode(texExpression)]);
2438
+ const annotation = new MathNode(
2439
+ "annotation", [new TextNode(texExpression)]);
2456
2440
  annotation.setAttribute("encoding", "application/x-tex");
2457
- wrapper = new mathMLTree.MathNode("semantics", [wrapper, annotation]);
2441
+ wrapper = new MathNode("semantics", [wrapper, annotation]);
2458
2442
  }
2459
2443
 
2460
- const math = new mathMLTree.MathNode("math", [wrapper]);
2444
+ const math = new MathNode("math", [wrapper]);
2461
2445
 
2462
2446
  if (settings.xml) {
2463
2447
  math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML");
@@ -2472,23 +2456,20 @@ function buildMathML(tree, texExpression, style, settings) {
2472
2456
  return math;
2473
2457
  }
2474
2458
 
2475
- // Identify letters to which we'll attach a combining accent character
2476
- const smalls = "acegıȷmnopqrsuvwxyzαγεηικμνοπρςστυχωϕ𝐚𝐜𝐞𝐠𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐮𝐯𝐰𝐱𝐲𝐳";
2477
-
2478
2459
  // From the KaTeX font metrics, identify letters whose accents need a italic correction.
2479
2460
  const smallNudge = "DHKLUcegorsuvxyzΠΥΨαδηιμνοτυχϵ";
2480
2461
  const mediumNudge = "BCEGIMNOPQRSTXZlpqtwΓΘΞΣΦΩβεζθξρςφψϑϕϱ";
2481
2462
  const largeNudge = "AFJdfΔΛ";
2482
2463
 
2483
2464
  const mathmlBuilder$a = (group, style) => {
2484
- const accentNode = group.isStretchy
2485
- ? stretchy.accentNode(group)
2486
- : new mathMLTree.MathNode("mo", [makeText(group.label, group.mode)]);
2465
+ const accentNode$1 = group.isStretchy
2466
+ ? accentNode(group)
2467
+ : new MathNode("mo", [makeText(group.label, group.mode)]);
2487
2468
  if (!group.isStretchy) {
2488
- accentNode.setAttribute("stretchy", "false"); // Keep Firefox from stretching \check
2469
+ accentNode$1.setAttribute("stretchy", "false"); // Keep Firefox from stretching \check
2489
2470
  }
2490
2471
  if (group.label !== "\\vec") {
2491
- accentNode.style.mathDepth = "0"; // not scriptstyle
2472
+ accentNode$1.style.mathDepth = "0"; // not scriptstyle
2492
2473
  // Don't use attribute accent="true" because MathML Core eliminates a needed space.
2493
2474
  }
2494
2475
  const tag = group.label === "\\c" ? "munder" : "mover";
@@ -2499,28 +2480,28 @@ const mathmlBuilder$a = (group, style) => {
2499
2480
  const isVec = group.label === "\\vec";
2500
2481
  const vecPostfix = isVec === "\\vec" ? "-vec" : "";
2501
2482
  if (isVec) {
2502
- accentNode.classes.push("tml-vec"); // Firefox sizing of \vec arrow
2483
+ accentNode$1.classes.push("tml-vec"); // Firefox sizing of \vec arrow
2503
2484
  }
2504
2485
  const wbkPostfix = isVec ? "-vec" : needsWbkVertShift ? "-acc" : "";
2505
2486
  if (smallNudge.indexOf(text) > -1) {
2506
- accentNode.classes.push(`chr-sml${vecPostfix}`);
2507
- accentNode.classes.push(`wbk-sml${wbkPostfix}`);
2487
+ accentNode$1.classes.push(`chr-sml${vecPostfix}`);
2488
+ accentNode$1.classes.push(`wbk-sml${wbkPostfix}`);
2508
2489
  } else if (mediumNudge.indexOf(text) > -1) {
2509
- accentNode.classes.push(`chr-med${vecPostfix}`);
2510
- accentNode.classes.push(`wbk-med${wbkPostfix}`);
2490
+ accentNode$1.classes.push(`chr-med${vecPostfix}`);
2491
+ accentNode$1.classes.push(`wbk-med${wbkPostfix}`);
2511
2492
  } else if (largeNudge.indexOf(text) > -1) {
2512
- accentNode.classes.push(`chr-lrg${vecPostfix}`);
2513
- accentNode.classes.push(`wbk-lrg${wbkPostfix}`);
2493
+ accentNode$1.classes.push(`chr-lrg${vecPostfix}`);
2494
+ accentNode$1.classes.push(`wbk-lrg${wbkPostfix}`);
2514
2495
  } else if (isVec) {
2515
- accentNode.classes.push(`wbk-vec`);
2496
+ accentNode$1.classes.push(`wbk-vec`);
2516
2497
  } else if (needsWbkVertShift) {
2517
- accentNode.classes.push(`wbk-acc`);
2498
+ accentNode$1.classes.push(`wbk-acc`);
2518
2499
  }
2519
2500
  } else if (needsWbkVertShift) {
2520
2501
  // text-mode accents
2521
- accentNode.classes.push("wbk-acc");
2502
+ accentNode$1.classes.push("wbk-acc");
2522
2503
  }
2523
- const node = new mathMLTree.MathNode(tag, [buildGroup$1(group.base, style), accentNode]);
2504
+ const node = new MathNode(tag, [buildGroup$1(group.base, style), accentNode$1]);
2524
2505
  return node;
2525
2506
  };
2526
2507
 
@@ -2687,11 +2668,11 @@ defineFunction({
2687
2668
  };
2688
2669
  },
2689
2670
  mathmlBuilder: (group, style) => {
2690
- const accentNode = stretchy.accentNode(group);
2691
- accentNode.style["math-depth"] = 0;
2692
- const node = new mathMLTree.MathNode("munder", [
2671
+ const accentNode$1 = accentNode(group);
2672
+ accentNode$1.style["math-depth"] = 0;
2673
+ const node = new MathNode("munder", [
2693
2674
  buildGroup$1(group.base, style),
2694
- accentNode
2675
+ accentNode$1
2695
2676
  ]);
2696
2677
  return node;
2697
2678
  }
@@ -2780,7 +2761,7 @@ const calculateSize = function(sizeValue, style) {
2780
2761
  // In TeX, em and ex do not change size in \scriptstyle.
2781
2762
  if (unit === "ex") { number *= 0.431; }
2782
2763
  number = Math.min(number / emScale(style.level), style.maxSize[0]);
2783
- return { number: utils.round(number), unit: "em" };
2764
+ return { number: round(number), unit: "em" };
2784
2765
  }
2785
2766
  case "bp": {
2786
2767
  if (number > style.maxSize[1]) { number = style.maxSize[1]; }
@@ -2794,11 +2775,11 @@ const calculateSize = function(sizeValue, style) {
2794
2775
  case "nc":
2795
2776
  case "sp": {
2796
2777
  number = Math.min(number * ptPerUnit[unit], style.maxSize[1]);
2797
- return { number: utils.round(number), unit: "pt" }
2778
+ return { number: round(number), unit: "pt" }
2798
2779
  }
2799
2780
  case "mu": {
2800
2781
  number = Math.min(number / 18, style.maxSize[0]);
2801
- return { number: utils.round(number), unit: "em" }
2782
+ return { number: round(number), unit: "em" }
2802
2783
  }
2803
2784
  default:
2804
2785
  throw new ParseError("Invalid unit: '" + unit + "'")
@@ -2808,7 +2789,7 @@ const calculateSize = function(sizeValue, style) {
2808
2789
  // Helper functions
2809
2790
 
2810
2791
  const padding = width => {
2811
- const node = new mathMLTree.MathNode("mspace");
2792
+ const node = new MathNode("mspace");
2812
2793
  node.setAttribute("width", width + "em");
2813
2794
  return node
2814
2795
  };
@@ -2820,18 +2801,18 @@ const paddedNode = (group, lspace = 0.3, rspace = 0, mustSmash = false) => {
2820
2801
  if (rspace > 0) { row.push(padding(rspace)); }
2821
2802
  if (mustSmash) {
2822
2803
  // Used for the bottom arrow in a {CD} environment
2823
- const mpadded = new mathMLTree.MathNode("mpadded", row);
2804
+ const mpadded = new MathNode("mpadded", row);
2824
2805
  mpadded.setAttribute("height", "0.1px"); // Don't use 0. WebKit would hide it.
2825
2806
  return mpadded
2826
2807
  } else {
2827
- return new mathMLTree.MathNode("mrow", row)
2808
+ return new MathNode("mrow", row)
2828
2809
  }
2829
2810
  };
2830
2811
 
2831
2812
  const labelSize = (size, scriptLevel) => Number(size) / emScale(scriptLevel);
2832
2813
 
2833
2814
  const munderoverNode = (fName, body, below, style) => {
2834
- const arrowNode = stretchy.mathMLnode(fName);
2815
+ const arrowNode = mathMLnode(fName);
2835
2816
  // Is this the short part of a mhchem equilibrium arrow?
2836
2817
  const isEq = fName.slice(1, 3) === "eq";
2837
2818
  const minWidth = fName.charAt(1) === "x"
@@ -2870,25 +2851,25 @@ const munderoverNode = (fName, body, below, style) => {
2870
2851
  // Since Firefox does not support minsize, stack a invisible node
2871
2852
  // on top of the label. Its width will serve as a min-width.
2872
2853
  // TODO: Refactor this after Firefox supports minsize.
2873
- upperNode = new mathMLTree.MathNode("mover", [label, dummyNode]);
2854
+ upperNode = new MathNode("mover", [label, dummyNode]);
2874
2855
  }
2875
2856
  const gotLower = (below && below.body &&
2876
2857
  (below.body.body || below.body.length > 0));
2877
2858
  if (gotLower) {
2878
2859
  let label = buildGroup$1(below, labelStyle);
2879
2860
  label = paddedNode(label, space, space);
2880
- lowerNode = new mathMLTree.MathNode("munder", [label, dummyNode]);
2861
+ lowerNode = new MathNode("munder", [label, dummyNode]);
2881
2862
  }
2882
2863
 
2883
2864
  let node;
2884
2865
  if (!gotUpper && !gotLower) {
2885
- node = new mathMLTree.MathNode("mover", [arrowNode, emptyLabel]);
2866
+ node = new MathNode("mover", [arrowNode, emptyLabel]);
2886
2867
  } else if (gotUpper && gotLower) {
2887
- node = new mathMLTree.MathNode("munderover", [arrowNode, lowerNode, upperNode]);
2868
+ node = new MathNode("munderover", [arrowNode, lowerNode, upperNode]);
2888
2869
  } else if (gotUpper) {
2889
- node = new mathMLTree.MathNode("mover", [arrowNode, upperNode]);
2870
+ node = new MathNode("mover", [arrowNode, upperNode]);
2890
2871
  } else {
2891
- node = new mathMLTree.MathNode("munder", [arrowNode, lowerNode]);
2872
+ node = new MathNode("munder", [arrowNode, lowerNode]);
2892
2873
  }
2893
2874
  if (minWidth === "3.0") { node.style.height = "1em"; } // CD environment
2894
2875
  node.setAttribute("accent", "false"); // Necessary for MS Word
@@ -2951,7 +2932,7 @@ defineFunction({
2951
2932
  const row = [node];
2952
2933
  row.unshift(padding(0.2778));
2953
2934
  row.push(padding(0.2778));
2954
- return new mathMLTree.MathNode("mrow", row)
2935
+ return new MathNode("mrow", row)
2955
2936
  }
2956
2937
  });
2957
2938
 
@@ -3004,21 +2985,21 @@ defineFunction({
3004
2985
  const botArrow = munderoverNode(botLabel, group.lowerArrowBody, group.below, style);
3005
2986
  let wrapper;
3006
2987
 
3007
- const raiseNode = new mathMLTree.MathNode("mpadded", [topArrow]);
2988
+ const raiseNode = new MathNode("mpadded", [topArrow]);
3008
2989
  raiseNode.setAttribute("voffset", "0.3em");
3009
2990
  raiseNode.setAttribute("height", "+0.3em");
3010
2991
  raiseNode.setAttribute("depth", "-0.3em");
3011
2992
  // One of the arrows is given ~zero width. so the other has the same horzontal alignment.
3012
2993
  if (group.name === "\\equilibriumLeft") {
3013
- const botNode = new mathMLTree.MathNode("mpadded", [botArrow]);
2994
+ const botNode = new MathNode("mpadded", [botArrow]);
3014
2995
  botNode.setAttribute("width", "0.5em");
3015
- wrapper = new mathMLTree.MathNode(
2996
+ wrapper = new MathNode(
3016
2997
  "mpadded",
3017
2998
  [padding(0.2778), botNode, raiseNode, padding(0.2778)]
3018
2999
  );
3019
3000
  } else {
3020
3001
  raiseNode.setAttribute("width", (group.name === "\\equilibriumRight" ? "0.5em" : "0"));
3021
- wrapper = new mathMLTree.MathNode(
3002
+ wrapper = new MathNode(
3022
3003
  "mpadded",
3023
3004
  [padding(0.2778), raiseNode, botArrow, padding(0.2778)]
3024
3005
  );
@@ -3310,18 +3291,18 @@ defineFunction({
3310
3291
  },
3311
3292
  mathmlBuilder(group, style) {
3312
3293
  if (group.label.body.length === 0) {
3313
- return new mathMLTree.MathNode("mrow", style) // empty label
3294
+ return new MathNode("mrow", style) // empty label
3314
3295
  }
3315
3296
  // Abuse an <mtable> to create vertically centered content.
3316
3297
  const mrow = buildGroup$1(group.label, style);
3317
3298
  if (group.side === "left") {
3318
3299
  mrow.classes.push("tml-shift-left");
3319
3300
  }
3320
- const mtd = new mathMLTree.MathNode("mtd", [mrow]);
3301
+ const mtd = new MathNode("mtd", [mrow]);
3321
3302
  mtd.style.padding = "0";
3322
- const mtr = new mathMLTree.MathNode("mtr", [mtd]);
3323
- const mtable = new mathMLTree.MathNode("mtable", [mtr]);
3324
- const label = new mathMLTree.MathNode("mpadded", [mtable]);
3303
+ const mtr = new MathNode("mtr", [mtd]);
3304
+ const mtable = new MathNode("mtable", [mtr]);
3305
+ const label = new MathNode("mpadded", [mtable]);
3325
3306
  // Set the label width to zero so that the arrow will be centered under the corner cell.
3326
3307
  label.setAttribute("width", "0.1px"); // Don't use 0. WebKit would hide it.
3327
3308
  label.setAttribute("displaystyle", "false");
@@ -3344,7 +3325,7 @@ defineFunction({
3344
3325
  };
3345
3326
  },
3346
3327
  mathmlBuilder(group, style) {
3347
- return new mathMLTree.MathNode("mrow", [buildGroup$1(group.fragment, style)]);
3328
+ return new MathNode("mrow", [buildGroup$1(group.fragment, style)]);
3348
3329
  }
3349
3330
  });
3350
3331
 
@@ -6443,7 +6424,7 @@ const alignMap = {
6443
6424
  };
6444
6425
 
6445
6426
  const glue = group => {
6446
- const glueNode = new mathMLTree.MathNode("mtd", []);
6427
+ const glueNode = new MathNode("mtd", []);
6447
6428
  glueNode.style = { padding: "0", width: "50%" };
6448
6429
  if (group.envClasses.includes("multline")) {
6449
6430
  glueNode.style.width = "7.5%";
@@ -6455,6 +6436,7 @@ const mathmlBuilder$9 = function(group, style) {
6455
6436
  const tbl = [];
6456
6437
  const numRows = group.body.length;
6457
6438
  const hlines = group.hLinesBeforeRow;
6439
+ const tagIsPresent = (group.tags && group.tags.some((tag) => tag));
6458
6440
 
6459
6441
  for (let i = 0; i < numRows; i++) {
6460
6442
  const rw = group.body[i];
@@ -6466,7 +6448,7 @@ const mathmlBuilder$9 = function(group, style) {
6466
6448
  : StyleLevel.DISPLAY;
6467
6449
 
6468
6450
  for (let j = 0; j < rw.length; j++) {
6469
- const mtd = new mathMLTree.MathNode(
6451
+ const mtd = new MathNode(
6470
6452
  "mtd",
6471
6453
  [buildGroup$1(rw[j], style.withLevel(cellLevel))]
6472
6454
  );
@@ -6482,16 +6464,16 @@ const mathmlBuilder$9 = function(group, style) {
6482
6464
  const numColumns = group.body[0].length;
6483
6465
  // Fill out a short row with empty <mtd> elements.
6484
6466
  for (let k = 0; k < numColumns - rw.length; k++) {
6485
- row.push(new mathMLTree.MathNode("mtd", [], [], style));
6467
+ row.push(new MathNode("mtd", [], [], style));
6486
6468
  }
6487
- if (group.autoTag) {
6469
+ if (tagIsPresent) {
6488
6470
  const tag = group.tags[i];
6489
6471
  let tagElement;
6490
6472
  if (tag === true) { // automatic numbering
6491
- tagElement = new mathMLTree.MathNode("mtext", [new Span(["tml-eqn"])]);
6473
+ tagElement = new MathNode("mtext", [new Span(["tml-eqn"])]);
6492
6474
  } else if (tag === false) {
6493
6475
  // \nonumber/\notag or starred environment
6494
- tagElement = new mathMLTree.MathNode("mtext", [], []);
6476
+ tagElement = new MathNode("mtext", [], []);
6495
6477
  } else { // manual \tag
6496
6478
  tagElement = buildExpressionRow(tag[0].body, style.withLevel(cellLevel), true);
6497
6479
  tagElement = consolidateText(tagElement);
@@ -6507,7 +6489,7 @@ const mathmlBuilder$9 = function(group, style) {
6507
6489
  }
6508
6490
  }
6509
6491
  }
6510
- const mtr = new mathMLTree.MathNode("mtr", row, []);
6492
+ const mtr = new MathNode("mtr", row, []);
6511
6493
  const label = group.labels.shift();
6512
6494
  if (label && group.tags && group.tags[i]) {
6513
6495
  mtr.setAttribute("id", label);
@@ -6596,7 +6578,7 @@ const mathmlBuilder$9 = function(group, style) {
6596
6578
  if (j === numCols - 1 && hand === 1) { return "0" }
6597
6579
  if (group.envClasses[0] !== "align") { return sidePadding }
6598
6580
  if (hand === 1) { return "0" }
6599
- if (group.autoTag) {
6581
+ if (tagIsPresent) {
6600
6582
  return (j % 2) ? "1" : "0"
6601
6583
  } else {
6602
6584
  return (j % 2) ? "0" : "1"
@@ -6632,7 +6614,7 @@ const mathmlBuilder$9 = function(group, style) {
6632
6614
  // TODO: Remove -webkit- when Chromium no longer needs it.
6633
6615
  row.children[j].classes = ["tml-" + (j % 2 ? "left" : "right")];
6634
6616
  }
6635
- if (group.autoTag) {
6617
+ if (tagIsPresent) {
6636
6618
  const k = group.leqno ? 0 : row.children.length - 1;
6637
6619
  row.children[k].classes = []; // Default is center.
6638
6620
  }
@@ -6649,7 +6631,7 @@ const mathmlBuilder$9 = function(group, style) {
6649
6631
  }
6650
6632
  }
6651
6633
 
6652
- let table = new mathMLTree.MathNode("mtable", tbl);
6634
+ let table = new MathNode("mtable", tbl);
6653
6635
  if (group.envClasses.length > 0) {
6654
6636
  // Top & bottom padding
6655
6637
  if (group.envClasses.includes("jot")) {
@@ -6689,7 +6671,7 @@ const mathmlBuilder$9 = function(group, style) {
6689
6671
  row.children[0].style.borderLeft = sep;
6690
6672
  }
6691
6673
  }
6692
- let iCol = group.autoTag ? 0 : -1;
6674
+ let iCol = tagIsPresent ? 0 : -1;
6693
6675
  for (let i = iStart; i < iEnd; i++) {
6694
6676
  if (cols[i].type === "align") {
6695
6677
  const colAlign = alignMap[cols[i].align];
@@ -6733,7 +6715,7 @@ const mathmlBuilder$9 = function(group, style) {
6733
6715
 
6734
6716
  if (group.envClasses.includes("small")) {
6735
6717
  // A small array. Wrap in scriptstyle.
6736
- table = new mathMLTree.MathNode("mstyle", [table]);
6718
+ table = new MathNode("mstyle", [table]);
6737
6719
  table.setAttribute("scriptlevel", "1");
6738
6720
  }
6739
6721
 
@@ -6980,9 +6962,8 @@ defineEnvironment({
6980
6962
  numArgs: 0
6981
6963
  },
6982
6964
  handler(context) {
6983
- const payload = { type: "small" };
6965
+ const payload = { envClasses: ["small"] };
6984
6966
  const res = parseArray(context.parser, payload, "script");
6985
- res.envClasses = ["small"];
6986
6967
  return res;
6987
6968
  },
6988
6969
  mathmlBuilder: mathmlBuilder$9
@@ -7216,6 +7197,78 @@ defineFunction({
7216
7197
  }
7217
7198
  });
7218
7199
 
7200
+ defineFunction({
7201
+ type: "cancelto",
7202
+ names: ["\\cancelto"],
7203
+ props: {
7204
+ numArgs: 2
7205
+ },
7206
+ handler({ parser }, args) {
7207
+ const to = args[0];
7208
+ const body = args[1];
7209
+ return {
7210
+ type: "cancelto",
7211
+ mode: parser.mode,
7212
+ body,
7213
+ to,
7214
+ isCharacterBox: isCharacterBox(body)
7215
+ };
7216
+ },
7217
+ mathmlBuilder(group, style) {
7218
+ const fromNode = new MathNode(
7219
+ "mrow",
7220
+ [buildGroup$1(group.body, style)],
7221
+ ["ff-narrow"] // A zero-width mrow.
7222
+ );
7223
+ // Write the arrow in a node written after the content.
7224
+ // That way, the arrow will be an overlay on the content.
7225
+ const phantom = new MathNode("mphantom", [buildGroup$1(group.body, style)]);
7226
+ const arrow = new MathNode("mrow", [phantom], ["tml-cancelto"]);
7227
+ if (group.isCharacterBox && smalls.indexOf(group.body.body[0].text) > -1) {
7228
+ arrow.style.left = "0.1em";
7229
+ arrow.style.width = "90%";
7230
+ }
7231
+ const node = new MathNode("mrow", [fromNode, arrow], ["menclose"]);
7232
+ if (!group.isCharacterBox || /[f∫∑]/.test(group.body.body[0].text)) {
7233
+ // Add 0.2em space to right of content to make room for the arrowhead.
7234
+ phantom.style.paddingRight = "0.2em";
7235
+ } else {
7236
+ phantom.style.padding = "0.5ex 0.1em 0 0";
7237
+ const strut = new MathNode('mspace', []);
7238
+ strut.setAttribute('height', "0.85em");
7239
+ fromNode.children.push(strut);
7240
+ }
7241
+
7242
+ // Create the "to" value above and to the right of the arrow.
7243
+ // First, we want a dummy node with the same height as the `from` content.
7244
+ // We'll place the `to` node above the dummy to get the correct vertical alignment.
7245
+ let dummyNode;
7246
+ if (group.isCharacterBox) {
7247
+ dummyNode = new MathNode('mspace', []);
7248
+ dummyNode.setAttribute('height', "1em");
7249
+ } else {
7250
+ // Create a phantom node with the same content as the body.
7251
+ const inner = buildGroup$1(group.body, style);
7252
+ // The phantom node will be zero-width, so it won't affect horizontal spacing.
7253
+ const zeroWidthNode = new MathNode("mpadded", [inner]);
7254
+ zeroWidthNode.setAttribute("width", "0.1px"); // Don't use 0. WebKit would omit it.
7255
+ dummyNode = new MathNode("mphantom", [zeroWidthNode]); // Hide it.
7256
+ }
7257
+ const toNode = buildGroup$1(group.to, style);
7258
+ const zeroWidthToNode = new MathNode("mpadded", [toNode]);
7259
+ if (!group.isCharacterBox || /[f∫∑]/.test(group.body.body[0].text)) {
7260
+ const w = new MathNode("mspace", []);
7261
+ w.setAttribute('width', "0.2em");
7262
+ zeroWidthToNode.children.unshift(w);
7263
+ }
7264
+ zeroWidthToNode.setAttribute("width", "0.1px"); // Don't use 0. WebKit would hide it.
7265
+ const mover = new MathNode("mover", [dummyNode, zeroWidthToNode]);
7266
+ // Fix Firefox positioning.
7267
+ const nudgeLeft = new MathNode('mrow', [], ["ff-nudge-left"]);
7268
+ return newDocumentFragment([makeRow([node, mover]), nudgeLeft])
7269
+ }
7270
+ });
7271
+
7219
7272
  // \@char is an internal function that takes a grouped decimal argument like
7220
7273
  // {123} and converts into symbol with code 123. It is used by the *macro*
7221
7274
  // \char defined in macros.js.
@@ -7399,13 +7452,13 @@ const mathmlBuilder$8 = (group, style) => {
7399
7452
  // the color individually to each node and return a document fragment.
7400
7453
  let expr = buildExpression(group.body, style.withColor(group.color));
7401
7454
  if (expr.length === 0) {
7402
- expr.push(new mathMLTree.MathNode("mrow"));
7455
+ expr.push(new MathNode("mrow"));
7403
7456
  }
7404
7457
  expr = expr.map(e => {
7405
7458
  e.style.color = group.color;
7406
7459
  return e
7407
7460
  });
7408
- return mathMLTree.newDocumentFragment(expr)
7461
+ return newDocumentFragment(expr)
7409
7462
  };
7410
7463
 
7411
7464
  defineFunction({
@@ -7526,7 +7579,7 @@ defineFunction({
7526
7579
  mathmlBuilder(group, style) {
7527
7580
  // MathML 3.0 calls for newline to occur in an <mo> or an <mspace>.
7528
7581
  // Ref: https://www.w3.org/TR/MathML3/chapter3.html#presm.linebreaking
7529
- const node = new mathMLTree.MathNode("mo");
7582
+ const node = new MathNode("mo");
7530
7583
  if (group.newLine) {
7531
7584
  node.setAttribute("linebreak", "newline");
7532
7585
  if (group.size) {
@@ -7981,7 +8034,7 @@ defineFunction({
7981
8034
  if (group.delim === ".") { group.delim = ""; }
7982
8035
  children.push(makeText(group.delim, group.mode));
7983
8036
 
7984
- const node = new mathMLTree.MathNode("mo", children);
8037
+ const node = new MathNode("mo", children);
7985
8038
 
7986
8039
  if (group.mclass === "mopen" || group.mclass === "mclose") {
7987
8040
  // Only some of the delimsizing functions act as fences, and they
@@ -8075,7 +8128,7 @@ defineFunction({
8075
8128
  const inner = buildExpression(group.body, style);
8076
8129
 
8077
8130
  if (group.left === ".") { group.left = ""; }
8078
- const leftNode = new mathMLTree.MathNode("mo", [makeText(group.left, group.mode)]);
8131
+ const leftNode = new MathNode("mo", [makeText(group.left, group.mode)]);
8079
8132
  leftNode.setAttribute("fence", "true");
8080
8133
  leftNode.setAttribute("form", "prefix");
8081
8134
  if (group.left === "/" || group.left === "\u005C" || group.left.indexOf("arrow") > -1) {
@@ -8084,7 +8137,7 @@ defineFunction({
8084
8137
  inner.unshift(leftNode);
8085
8138
 
8086
8139
  if (group.right === ".") { group.right = ""; }
8087
- const rightNode = new mathMLTree.MathNode("mo", [makeText(group.right, group.mode)]);
8140
+ const rightNode = new MathNode("mo", [makeText(group.right, group.mode)]);
8088
8141
  rightNode.setAttribute("fence", "true");
8089
8142
  rightNode.setAttribute("form", "postfix");
8090
8143
  if (group.right === "\u2216" || group.right.indexOf("arrow") > -1) {
@@ -8126,7 +8179,7 @@ defineFunction({
8126
8179
  },
8127
8180
  mathmlBuilder: (group, style) => {
8128
8181
  const textNode = makeText(group.delim, group.mode);
8129
- const middleNode = new mathMLTree.MathNode("mo", [textNode]);
8182
+ const middleNode = new MathNode("mo", [textNode]);
8130
8183
  middleNode.setAttribute("fence", "true");
8131
8184
  if (group.delim.indexOf("arrow") > -1) {
8132
8185
  middleNode.setAttribute("stretchy", "true");
@@ -8142,8 +8195,11 @@ defineFunction({
8142
8195
  }
8143
8196
  });
8144
8197
 
8198
+ const boxTags = ["\\boxed", "\\fcolorbox", "\\colorbox"];
8199
+
8145
8200
  const mathmlBuilder$7 = (group, style) => {
8146
- const node = new mathMLTree.MathNode("menclose", [buildGroup$1(group.body, style)]);
8201
+ const tag = boxTags.includes(group.label) ? "mrow" : "menclose";
8202
+ const node = new MathNode(tag, [buildGroup$1(group.body, style)]);
8147
8203
  switch (group.label) {
8148
8204
  case "\\overline":
8149
8205
  node.setAttribute("notation", "top"); // for Firefox & WebKit
@@ -8155,34 +8211,35 @@ const mathmlBuilder$7 = (group, style) => {
8155
8211
  break
8156
8212
  case "\\cancel":
8157
8213
  node.setAttribute("notation", "updiagonalstrike");
8158
- node.children.push(new mathMLTree.MathNode("mrow", [], ["tml-cancel", "upstrike"]));
8214
+ node.children.push(new MathNode("mrow", [], ["tml-cancel", "upstrike"]));
8159
8215
  break
8160
8216
  case "\\bcancel":
8161
8217
  node.setAttribute("notation", "downdiagonalstrike");
8162
- node.children.push(new mathMLTree.MathNode("mrow", [], ["tml-cancel", "downstrike"]));
8218
+ node.children.push(new MathNode("mrow", [], ["tml-cancel", "downstrike"]));
8163
8219
  break
8164
8220
  case "\\sout":
8165
8221
  node.setAttribute("notation", "horizontalstrike");
8166
- node.children.push(new mathMLTree.MathNode("mrow", [], ["tml-cancel", "sout"]));
8222
+ node.children.push(new MathNode("mrow", [], ["tml-cancel", "sout"]));
8167
8223
  break
8168
8224
  case "\\xcancel":
8169
8225
  node.setAttribute("notation", "updiagonalstrike downdiagonalstrike");
8170
8226
  node.classes.push("tml-xcancel");
8171
8227
  break
8228
+ // cancelto is handled in cancelto.js
8172
8229
  case "\\longdiv":
8173
8230
  node.setAttribute("notation", "longdiv");
8174
8231
  node.classes.push("longdiv-top");
8175
- node.children.push(new mathMLTree.MathNode("mrow", [], ["longdiv-arc"]));
8232
+ node.children.push(new MathNode("mrow", [], ["longdiv-arc"]));
8176
8233
  break
8177
8234
  case "\\phase":
8178
8235
  node.setAttribute("notation", "phasorangle");
8179
8236
  node.classes.push("phasor-bottom");
8180
- node.children.push(new mathMLTree.MathNode("mrow", [], ["phasor-angle"]));
8237
+ node.children.push(new MathNode("mrow", [], ["phasor-angle"]));
8181
8238
  break
8182
8239
  case "\\textcircled":
8183
8240
  node.setAttribute("notation", "circle");
8184
8241
  node.classes.push("circle-pad");
8185
- node.children.push(new mathMLTree.MathNode("mrow", [], ["textcircle"]));
8242
+ node.children.push(new MathNode("mrow", [], ["textcircle"]));
8186
8243
  break
8187
8244
  case "\\angl":
8188
8245
  node.setAttribute("notation", "actuarial");
@@ -8190,7 +8247,6 @@ const mathmlBuilder$7 = (group, style) => {
8190
8247
  break
8191
8248
  case "\\boxed":
8192
8249
  // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} from amsmath.sty
8193
- node.setAttribute("notation", "box");
8194
8250
  node.style.padding = "3pt";
8195
8251
  node.style.border = "1px solid";
8196
8252
  node.setAttribute("scriptlevel", "0");
@@ -8202,13 +8258,8 @@ const mathmlBuilder$7 = (group, style) => {
8202
8258
  break
8203
8259
  case "\\fcolorbox":
8204
8260
  case "\\colorbox": {
8205
- // <menclose> doesn't have a good notation option for \colorbox.
8206
- // So use <mpadded> instead. Set some attributes that come
8207
- // included with <menclose>.
8208
- //const fboxsep = 3; // 3 pt from LaTeX source2e
8209
- //node.setAttribute("height", `+${2 * fboxsep}pt`)
8210
- //node.setAttribute("voffset", `${fboxsep}pt`)
8211
- node.style.padding = "3pt";
8261
+ // Don't use <menclose>. WebKit would show a radical.
8262
+ node.style.padding = "0.3em"; // 3 pt from LaTeX source2e for a 10pt font
8212
8263
  if (group.label === "\\fcolorbox") {
8213
8264
  node.style.border = "0.0667em solid " + String(group.borderColor);
8214
8265
  }
@@ -8434,7 +8485,7 @@ defineFunction({
8434
8485
  };
8435
8486
  },
8436
8487
  mathmlBuilder(group, style) {
8437
- return new mathMLTree.MathNode("mrow");
8488
+ return new MathNode("mrow");
8438
8489
  }
8439
8490
  });
8440
8491
 
@@ -8451,7 +8502,7 @@ defineFunction({
8451
8502
  };
8452
8503
  },
8453
8504
  mathmlBuilder(group, style) {
8454
- return new mathMLTree.MathNode("mrow");
8505
+ return new MathNode("mrow");
8455
8506
  }
8456
8507
  });
8457
8508
 
@@ -8494,7 +8545,7 @@ const mathmlBuilder$6 = (group, style) => {
8494
8545
  : mathGroup.children[i].children[0].text;
8495
8546
  }
8496
8547
  // Wrap in a <mpadded> to prevent the same Firefox bug.
8497
- const mpadded = new mathMLTree.MathNode("mpadded", [mi]);
8548
+ const mpadded = new MathNode("mpadded", [mi]);
8498
8549
  mpadded.setAttribute("lspace", "0");
8499
8550
  return mpadded
8500
8551
  }
@@ -8520,8 +8571,8 @@ const mathmlBuilder$6 = (group, style) => {
8520
8571
  // Ref: https://bugs.webkit.org/show_bug.cgi?id=129097
8521
8572
  // We insert a text node that contains a zero-width space and wrap in an mrow.
8522
8573
  // TODO: Get rid of this <mi> workaround when the Firefox bug is fixed.
8523
- const bogus = new mathMLTree.MathNode("mtext", new mathMLTree.TextNode("\u200b"));
8524
- return new mathMLTree.MathNode("mrow", [bogus, mi])
8574
+ const bogus = new MathNode("mtext", new TextNode("\u200b"));
8575
+ return new MathNode("mrow", [bogus, mi])
8525
8576
  }
8526
8577
  return mi
8527
8578
  };
@@ -8632,7 +8683,7 @@ const mathmlBuilder$5 = (group, style) => {
8632
8683
  denom.setAttribute("scriptlevel", "2");
8633
8684
  }
8634
8685
 
8635
- let node = new mathMLTree.MathNode("mfrac", [numer, denom]);
8686
+ let node = new MathNode("mfrac", [numer, denom]);
8636
8687
 
8637
8688
  if (!group.hasBarLine) {
8638
8689
  node.setAttribute("linethickness", "0px");
@@ -8645,8 +8696,8 @@ const mathmlBuilder$5 = (group, style) => {
8645
8696
  const withDelims = [];
8646
8697
 
8647
8698
  if (group.leftDelim != null) {
8648
- const leftOp = new mathMLTree.MathNode("mo", [
8649
- new mathMLTree.TextNode(group.leftDelim.replace("\\", ""))
8699
+ const leftOp = new MathNode("mo", [
8700
+ new TextNode(group.leftDelim.replace("\\", ""))
8650
8701
  ]);
8651
8702
  leftOp.setAttribute("fence", "true");
8652
8703
  withDelims.push(leftOp);
@@ -8655,8 +8706,8 @@ const mathmlBuilder$5 = (group, style) => {
8655
8706
  withDelims.push(node);
8656
8707
 
8657
8708
  if (group.rightDelim != null) {
8658
- const rightOp = new mathMLTree.MathNode("mo", [
8659
- new mathMLTree.TextNode(group.rightDelim.replace("\\", ""))
8709
+ const rightOp = new MathNode("mo", [
8710
+ new TextNode(group.rightDelim.replace("\\", ""))
8660
8711
  ]);
8661
8712
  rightOp.setAttribute("fence", "true");
8662
8713
  withDelims.push(rightOp);
@@ -8666,7 +8717,7 @@ const mathmlBuilder$5 = (group, style) => {
8666
8717
  }
8667
8718
 
8668
8719
  if (group.scriptLevel !== "auto") {
8669
- node = new mathMLTree.MathNode("mstyle", [node]);
8720
+ node = new MathNode("mstyle", [node]);
8670
8721
  node.setAttribute("displaystyle", String(group.scriptLevel === "display"));
8671
8722
  node.setAttribute("scriptlevel", scriptLevel[group.scriptLevel]);
8672
8723
  }
@@ -8969,24 +9020,24 @@ defineFunction({
8969
9020
  });
8970
9021
 
8971
9022
  const mathmlBuilder$4 = (group, style) => {
8972
- const accentNode = stretchy.mathMLnode(group.label);
9023
+ const accentNode = mathMLnode(group.label);
8973
9024
  accentNode.style["math-depth"] = 0;
8974
- return new mathMLTree.MathNode(group.isOver ? "mover" : "munder", [
9025
+ return new MathNode(group.isOver ? "mover" : "munder", [
8975
9026
  buildGroup$1(group.base, style),
8976
9027
  accentNode
8977
9028
  ]);
8978
9029
  };
8979
9030
 
8980
- // Horizontal stretchy braces
9031
+ // Horizontal stretchy brackets
8981
9032
  defineFunction({
8982
- type: "horizBrace",
8983
- names: ["\\overbrace", "\\underbrace"],
9033
+ type: "horizBracket",
9034
+ names: ["\\overbrace", "\\underbrace", "\\overbracket", "\\underbracket"],
8984
9035
  props: {
8985
9036
  numArgs: 1
8986
9037
  },
8987
9038
  handler({ parser, funcName }, args) {
8988
9039
  return {
8989
- type: "horizBrace",
9040
+ type: "horizBracket",
8990
9041
  mode: parser.mode,
8991
9042
  label: funcName,
8992
9043
  isOver: /^\\over/.test(funcName),
@@ -9207,7 +9258,7 @@ defineFunction({
9207
9258
  const node = new Img(group.src, group.alt, graphicStyle);
9208
9259
  node.height = height;
9209
9260
  node.depth = depth;
9210
- return new mathMLTree.MathNode("mtext", [node])
9261
+ return new MathNode("mtext", [node])
9211
9262
  }
9212
9263
  });
9213
9264
 
@@ -9257,17 +9308,17 @@ defineFunction({
9257
9308
  ? spaceCharacter(dimension.number)
9258
9309
  : "";
9259
9310
  if (group.mode === "text" && ch.length > 0) {
9260
- const character = new mathMLTree.TextNode(ch);
9261
- return new mathMLTree.MathNode("mtext", [character]);
9311
+ const character = new TextNode(ch);
9312
+ return new MathNode("mtext", [character]);
9262
9313
  } else {
9263
9314
  if (dimension.number >= 0) {
9264
- const node = new mathMLTree.MathNode("mspace");
9315
+ const node = new MathNode("mspace");
9265
9316
  node.setAttribute("width", dimension.number + dimension.unit);
9266
9317
  return node
9267
9318
  } else {
9268
9319
  // Don't use <mspace> or <mpadded> because
9269
9320
  // WebKit recognizes negative left margin only on a <mrow> element
9270
- const node = new mathMLTree.MathNode("mrow");
9321
+ const node = new MathNode("mrow");
9271
9322
  node.style.marginLeft = dimension.number + dimension.unit;
9272
9323
  return node
9273
9324
  }
@@ -9308,7 +9359,7 @@ defineFunction({
9308
9359
  },
9309
9360
  mathmlBuilder(group, style) {
9310
9361
  // Return a no-width, no-ink element with an HTML id.
9311
- const node = new mathMLTree.MathNode("mrow", [], ["tml-label"]);
9362
+ const node = new MathNode("mrow", [], ["tml-label"]);
9312
9363
  if (group.string.length > 0) {
9313
9364
  node.setLabel(group.string);
9314
9365
  }
@@ -9352,8 +9403,8 @@ defineFunction({
9352
9403
  // We need an invisible strut with the same depth as the group.
9353
9404
  // We can't just read the depth, so we use \vphantom methods.
9354
9405
  const phantomInner = buildExpression(ordargument(group.body), style);
9355
- const phantom = new mathMLTree.MathNode("mphantom", phantomInner);
9356
- strut = new mathMLTree.MathNode("mpadded", [phantom]);
9406
+ const phantom = new MathNode("mphantom", phantomInner);
9407
+ strut = new MathNode("mpadded", [phantom]);
9357
9408
  strut.setAttribute("width", "0.1px"); // Don't use 0. WebKit would hide it.
9358
9409
  }
9359
9410
 
@@ -9363,9 +9414,9 @@ defineFunction({
9363
9414
  inner.style.position = "absolute";
9364
9415
  inner.style.right = "0";
9365
9416
  inner.style.bottom = `0`; // If we could have read the ink depth, it would go here.
9366
- node = new mathMLTree.MathNode("mpadded", [strut, inner]);
9417
+ node = new MathNode("mpadded", [strut, inner]);
9367
9418
  } else {
9368
- node = new mathMLTree.MathNode("mpadded", [inner]);
9419
+ node = new MathNode("mpadded", [inner]);
9369
9420
  }
9370
9421
 
9371
9422
  if (group.alignment === "rlap") {
@@ -9471,7 +9522,7 @@ function mathmlBuilder$3(group, style) {
9471
9522
  const inner = buildExpression(group.body, style);
9472
9523
 
9473
9524
  if (group.mclass === "minner") {
9474
- node = new mathMLTree.MathNode("mpadded", inner);
9525
+ node = new MathNode("mpadded", inner);
9475
9526
  } else if (group.mclass === "mord") {
9476
9527
  if (group.isCharacterBox || inner[0].type === "mathord") {
9477
9528
  node = inner[0];
@@ -9480,10 +9531,10 @@ function mathmlBuilder$3(group, style) {
9480
9531
  node.setAttribute("mathvariant", "normal");
9481
9532
  }
9482
9533
  } else {
9483
- node = new mathMLTree.MathNode("mi", inner);
9534
+ node = new MathNode("mi", inner);
9484
9535
  }
9485
9536
  } else {
9486
- node = new mathMLTree.MathNode("mrow", inner);
9537
+ node = new MathNode("mrow", inner);
9487
9538
  if (group.mustPromote) {
9488
9539
  node = inner[0];
9489
9540
  node.type = "mo";
@@ -9491,7 +9542,7 @@ function mathmlBuilder$3(group, style) {
9491
9542
  node.setAttribute("mathvariant", "italic");
9492
9543
  }
9493
9544
  } else {
9494
- node = new mathMLTree.MathNode("mrow", inner);
9545
+ node = new MathNode("mrow", inner);
9495
9546
  }
9496
9547
 
9497
9548
  // Set spacing based on what is the most likely adjacent atom type.
@@ -9561,7 +9612,7 @@ defineFunction({
9561
9612
  },
9562
9613
  handler({ parser, funcName }, args) {
9563
9614
  const body = args[0];
9564
- const isCharacterBox = utils.isCharacterBox(body);
9615
+ const isCharacterBox$1 = isCharacterBox(body);
9565
9616
  // We should not wrap a <mo> around a <mi> or <mord>. That would be invalid MathML.
9566
9617
  // In that case, we instead promote the text contents of the body to the parent.
9567
9618
  let mustPromote = true;
@@ -9590,7 +9641,7 @@ defineFunction({
9590
9641
  mode: parser.mode,
9591
9642
  mclass: "m" + funcName.slice(5),
9592
9643
  body: ordargument(mustPromote ? mord : body),
9593
- isCharacterBox,
9644
+ isCharacterBox: isCharacterBox$1,
9594
9645
  mustPromote
9595
9646
  };
9596
9647
  }
@@ -9627,7 +9678,7 @@ defineFunction({
9627
9678
  mode: parser.mode,
9628
9679
  mclass: binrelClass(args[0]),
9629
9680
  body: ordargument(args[1]),
9630
- isCharacterBox: utils.isCharacterBox(args[1])
9681
+ isCharacterBox: isCharacterBox(args[1])
9631
9682
  };
9632
9683
  }
9633
9684
  });
@@ -9741,8 +9792,8 @@ defineFunction({
9741
9792
  mathmlBuilder(group, style) {
9742
9793
  const base = buildGroup$1(group.base, style);
9743
9794
 
9744
- const prescriptsNode = new mathMLTree.MathNode("mprescripts");
9745
- const noneNode = new mathMLTree.MathNode("none");
9795
+ const prescriptsNode = new MathNode("mprescripts");
9796
+ const noneNode = new MathNode("none");
9746
9797
  let children = [];
9747
9798
 
9748
9799
  const preSub = buildGroup(group.prescripts.sub, style, noneNode);
@@ -9761,7 +9812,7 @@ defineFunction({
9761
9812
  children = [base, prescriptsNode, preSub, preSup];
9762
9813
  }
9763
9814
 
9764
- return new mathMLTree.MathNode("mmultiscripts", children);
9815
+ return new MathNode("mmultiscripts", children);
9765
9816
  }
9766
9817
  });
9767
9818
 
@@ -9774,9 +9825,9 @@ defineFunction({
9774
9825
  allowedInText: false
9775
9826
  },
9776
9827
  handler({ parser }, args) {
9777
- const isCharacterBox = utils.isCharacterBox(args[0]);
9828
+ const isCharacterBox$1 = isCharacterBox(args[0]);
9778
9829
  let body;
9779
- if (isCharacterBox) {
9830
+ if (isCharacterBox$1) {
9780
9831
  body = ordargument(args[0]);
9781
9832
  if (body[0].text.charAt(0) === "\\") {
9782
9833
  body[0].text = symbols.math[body[0].text].replace;
@@ -9794,7 +9845,7 @@ defineFunction({
9794
9845
  type: "not",
9795
9846
  mode: parser.mode,
9796
9847
  body,
9797
- isCharacterBox
9848
+ isCharacterBox: isCharacterBox$1
9798
9849
  };
9799
9850
  },
9800
9851
  mathmlBuilder(group, style) {
@@ -10142,7 +10193,8 @@ defineFunction({
10142
10193
  "\u2a1a"
10143
10194
  ],
10144
10195
  props: {
10145
- numArgs: 0
10196
+ numArgs: 0,
10197
+ allowedInArgument: true
10146
10198
  },
10147
10199
  handler({ parser, funcName }) {
10148
10200
  let fName = funcName;
@@ -10173,9 +10225,9 @@ const mathmlBuilder$1 = (group, style) => {
10173
10225
  let isAllString = true; // default
10174
10226
  for (let i = 0; i < expression.length; i++) {
10175
10227
  let node = expression[i];
10176
- if (node instanceof mathMLTree.MathNode) {
10228
+ if (node instanceof MathNode) {
10177
10229
  if ((node.type === "mrow" || node.type === "mpadded") && node.children.length === 1 &&
10178
- node.children[0] instanceof mathMLTree.MathNode) {
10230
+ node.children[0] instanceof MathNode) {
10179
10231
  node = node.children[0];
10180
10232
  }
10181
10233
  switch (node.type) {
@@ -10192,14 +10244,14 @@ const mathmlBuilder$1 = (group, style) => {
10192
10244
  if (ch === "") {
10193
10245
  isAllString = false;
10194
10246
  } else {
10195
- expression[i] = new mathMLTree.MathNode("mtext", [new mathMLTree.TextNode(ch)]);
10247
+ expression[i] = new MathNode("mtext", [new TextNode(ch)]);
10196
10248
  }
10197
10249
  }
10198
10250
  }
10199
10251
  break
10200
10252
  case "mo": {
10201
10253
  const child = node.children[0];
10202
- if (node.children.length === 1 && child instanceof mathMLTree.TextNode) {
10254
+ if (node.children.length === 1 && child instanceof TextNode) {
10203
10255
  child.text = child.text.replace(/\u2212/, "-").replace(/\u2217/, "*");
10204
10256
  } else {
10205
10257
  isAllString = false;
@@ -10217,7 +10269,7 @@ const mathmlBuilder$1 = (group, style) => {
10217
10269
  if (isAllString) {
10218
10270
  // Write a single TextNode instead of multiple nested tags.
10219
10271
  const word = expression.map((node) => node.toText()).join("");
10220
- expression = [new mathMLTree.TextNode(word)];
10272
+ expression = [new TextNode(word)];
10221
10273
  } else if (
10222
10274
  expression.length === 1
10223
10275
  && ["mover", "munder"].includes(expression[0].type) &&
@@ -10225,41 +10277,41 @@ const mathmlBuilder$1 = (group, style) => {
10225
10277
  ) {
10226
10278
  expression[0].children[0].type = "mi";
10227
10279
  if (group.parentIsSupSub) {
10228
- return new mathMLTree.MathNode("mrow", expression)
10280
+ return new MathNode("mrow", expression)
10229
10281
  } else {
10230
- const operator = new mathMLTree.MathNode("mo", [makeText("\u2061", "text")]);
10231
- return mathMLTree.newDocumentFragment([expression[0], operator])
10282
+ const operator = new MathNode("mo", [makeText("\u2061", "text")]);
10283
+ return newDocumentFragment([expression[0], operator])
10232
10284
  }
10233
10285
  }
10234
10286
 
10235
10287
  let wrapper;
10236
10288
  if (isAllString) {
10237
- wrapper = new mathMLTree.MathNode("mi", expression);
10289
+ wrapper = new MathNode("mi", expression);
10238
10290
  if (expression[0].text.length === 1) {
10239
10291
  wrapper.setAttribute("mathvariant", "normal");
10240
10292
  }
10241
10293
  } else {
10242
- wrapper = new mathMLTree.MathNode("mrow", expression);
10294
+ wrapper = new MathNode("mrow", expression);
10243
10295
  }
10244
10296
 
10245
10297
  if (!group.parentIsSupSub) {
10246
10298
  // Append an <mo>&ApplyFunction;</mo>.
10247
10299
  // ref: https://www.w3.org/TR/REC-MathML/chap3_2.html#sec3.2.4
10248
- const operator = new mathMLTree.MathNode("mo", [makeText("\u2061", "text")]);
10300
+ const operator = new MathNode("mo", [makeText("\u2061", "text")]);
10249
10301
  const fragment = [wrapper, operator];
10250
10302
  if (group.needsLeadingSpace) {
10251
10303
  // LaTeX gives operator spacing, but a <mi> gets ord spacing.
10252
10304
  // So add a leading space.
10253
- const space = new mathMLTree.MathNode("mspace");
10305
+ const space = new MathNode("mspace");
10254
10306
  space.setAttribute("width", "0.1667em"); // thin space.
10255
10307
  fragment.unshift(space);
10256
10308
  }
10257
10309
  if (!group.isFollowedByDelimiter) {
10258
- const trail = new mathMLTree.MathNode("mspace");
10310
+ const trail = new MathNode("mspace");
10259
10311
  trail.setAttribute("width", "0.1667em"); // thin space.
10260
10312
  fragment.push(trail);
10261
10313
  }
10262
- return mathMLTree.newDocumentFragment(fragment)
10314
+ return newDocumentFragment(fragment)
10263
10315
  }
10264
10316
 
10265
10317
  return wrapper
@@ -10319,7 +10371,7 @@ defineFunction({
10319
10371
  },
10320
10372
  mathmlBuilder: (group, style) => {
10321
10373
  const inner = buildExpression(group.body, style);
10322
- return new mathMLTree.MathNode("mphantom", inner);
10374
+ return new MathNode("mphantom", inner);
10323
10375
  }
10324
10376
  });
10325
10377
 
@@ -10340,8 +10392,8 @@ defineFunction({
10340
10392
  },
10341
10393
  mathmlBuilder: (group, style) => {
10342
10394
  const inner = buildExpression(ordargument(group.body), style);
10343
- const phantom = new mathMLTree.MathNode("mphantom", inner);
10344
- const node = new mathMLTree.MathNode("mpadded", [phantom]);
10395
+ const phantom = new MathNode("mphantom", inner);
10396
+ const node = new MathNode("mpadded", [phantom]);
10345
10397
  node.setAttribute("height", "0px");
10346
10398
  node.setAttribute("depth", "0px");
10347
10399
  return node;
@@ -10365,8 +10417,8 @@ defineFunction({
10365
10417
  },
10366
10418
  mathmlBuilder: (group, style) => {
10367
10419
  const inner = buildExpression(ordargument(group.body), style);
10368
- const phantom = new mathMLTree.MathNode("mphantom", inner);
10369
- const node = new mathMLTree.MathNode("mpadded", [phantom]);
10420
+ const phantom = new MathNode("mphantom", inner);
10421
+ const node = new MathNode("mpadded", [phantom]);
10370
10422
  node.setAttribute("width", "0px");
10371
10423
  return node;
10372
10424
  }
@@ -10403,7 +10455,7 @@ defineFunction({
10403
10455
 
10404
10456
  const mathmlBuilder = (group, style) => {
10405
10457
  const newStyle = style.withLevel(StyleLevel.TEXT);
10406
- const node = new mathMLTree.MathNode("mpadded", [buildGroup$1(group.body, newStyle)]);
10458
+ const node = new MathNode("mpadded", [buildGroup$1(group.body, newStyle)]);
10407
10459
  const dy = calculateSize(group.dy, style);
10408
10460
  node.setAttribute("voffset", dy.number + dy.unit);
10409
10461
  // Add padding, which acts to increase height in Chromium.
@@ -10551,7 +10603,7 @@ defineFunction({
10551
10603
  : { number: 0, unit: "em" };
10552
10604
  const color = (style.color && style.getColor()) || "black";
10553
10605
 
10554
- const rule = new mathMLTree.MathNode("mspace");
10606
+ const rule = new MathNode("mspace");
10555
10607
  if (width.number > 0 && height.number > 0) {
10556
10608
  rule.setAttribute("mathbackground", color);
10557
10609
  }
@@ -10559,7 +10611,7 @@ defineFunction({
10559
10611
  rule.setAttribute("height", height.number + height.unit);
10560
10612
  if (shift.number === 0) { return rule }
10561
10613
 
10562
- const wrapper = new mathMLTree.MathNode("mpadded", [rule]);
10614
+ const wrapper = new MathNode("mpadded", [rule]);
10563
10615
  if (shift.number >= 0) {
10564
10616
  wrapper.setAttribute("height", "+" + shift.number + shift.unit);
10565
10617
  } else {
@@ -10631,8 +10683,8 @@ defineFunction({
10631
10683
  const numerator = group.numerator.split('').map(c => unicodeNumSups[c]).join('');
10632
10684
  const denominator = group.denominator.split('').map(c => unicodeNumSubs[c]).join('');
10633
10685
  // Use a fraction slash.
10634
- const text = new mathMLTree.TextNode(numerator + "\u2044" + denominator, group.mode, style);
10635
- return new mathMLTree.MathNode("mn", [text], ["special-fraction"])
10686
+ const text = new TextNode(numerator + "\u2044" + denominator, group.mode, style);
10687
+ return new MathNode("mn", [text], ["special-fraction"])
10636
10688
  }
10637
10689
  });
10638
10690
 
@@ -10745,7 +10797,7 @@ defineFunction({
10745
10797
  };
10746
10798
  },
10747
10799
  mathmlBuilder: (group, style) => {
10748
- const node = new mathMLTree.MathNode("mpadded", [buildGroup$1(group.body, style)]);
10800
+ const node = new MathNode("mpadded", [buildGroup$1(group.body, style)]);
10749
10801
 
10750
10802
  if (group.smashHeight) {
10751
10803
  node.setAttribute("height", "0px");
@@ -10798,11 +10850,11 @@ defineFunction({
10798
10850
  mathmlBuilder(group, style) {
10799
10851
  const { body, index } = group;
10800
10852
  return index
10801
- ? new mathMLTree.MathNode("mroot", [
10853
+ ? new MathNode("mroot", [
10802
10854
  buildGroup$1(body, style),
10803
10855
  buildGroup$1(index, style.incrementLevel())
10804
10856
  ])
10805
- : new mathMLTree.MathNode("msqrt", [buildGroup$1(body, style)]);
10857
+ : new MathNode("msqrt", [buildGroup$1(body, style)]);
10806
10858
  }
10807
10859
  });
10808
10860
 
@@ -10882,18 +10934,18 @@ const largePad = "AJdfΔΛ";
10882
10934
  defineFunctionBuilders({
10883
10935
  type: "supsub",
10884
10936
  mathmlBuilder(group, style) {
10885
- // Is the inner group a relevant horizontal brace?
10886
- let isBrace = false;
10937
+ // Is the inner group a relevant horizontal brace or bracket?
10938
+ let isBracket = false;
10887
10939
  let isOver;
10888
10940
  let isSup;
10889
10941
  let appendApplyFunction = false;
10890
10942
  let appendSpace = false;
10891
10943
  let needsLeadingSpace = false;
10892
10944
 
10893
- if (group.base && group.base.type === "horizBrace") {
10945
+ if (group.base && group.base.type === "horizBracket") {
10894
10946
  isSup = !!group.sup;
10895
10947
  if (isSup === group.base.isOver) {
10896
- isBrace = true;
10948
+ isBracket = true;
10897
10949
  isOver = group.base.isOver;
10898
10950
  }
10899
10951
  }
@@ -10941,7 +10993,7 @@ defineFunctionBuilders({
10941
10993
  }
10942
10994
 
10943
10995
  let nodeType;
10944
- if (isBrace) {
10996
+ if (isBracket) {
10945
10997
  nodeType = isOver ? "mover" : "munder";
10946
10998
  } else if (!group.sub) {
10947
10999
  const base = group.base;
@@ -11001,26 +11053,26 @@ defineFunctionBuilders({
11001
11053
  }
11002
11054
  }
11003
11055
 
11004
- let node = new mathMLTree.MathNode(nodeType, children);
11056
+ let node = new MathNode(nodeType, children);
11005
11057
  if (appendApplyFunction) {
11006
11058
  // Append an <mo>&ApplyFunction;</mo>.
11007
11059
  // ref: https://www.w3.org/TR/REC-MathML/chap3_2.html#sec3.2.4
11008
- const operator = new mathMLTree.MathNode("mo", [makeText("\u2061", "text")]);
11060
+ const operator = new MathNode("mo", [makeText("\u2061", "text")]);
11009
11061
  if (needsLeadingSpace) {
11010
- const space = new mathMLTree.MathNode("mspace");
11062
+ const space = new MathNode("mspace");
11011
11063
  space.setAttribute("width", "0.1667em"); // thin space.
11012
- node = mathMLTree.newDocumentFragment([space, node, operator]);
11064
+ node = newDocumentFragment([space, node, operator]);
11013
11065
  } else {
11014
- node = mathMLTree.newDocumentFragment([node, operator]);
11066
+ node = newDocumentFragment([node, operator]);
11015
11067
  }
11016
11068
  if (appendSpace) {
11017
- const space = new mathMLTree.MathNode("mspace");
11069
+ const space = new MathNode("mspace");
11018
11070
  space.setAttribute("width", "0.1667em"); // thin space.
11019
11071
  node.children.push(space);
11020
11072
  }
11021
11073
  } else if (symbolRegEx.test(nodeType)) {
11022
11074
  // Wrap in a <mrow>. Otherwise Firefox stretchy parens will not stretch to include limits.
11023
- node = new mathMLTree.MathNode("mrow", [node]);
11075
+ node = new MathNode("mrow", [node]);
11024
11076
  }
11025
11077
 
11026
11078
  return node
@@ -11045,7 +11097,7 @@ const isArrow = str => {
11045
11097
  defineFunctionBuilders({
11046
11098
  type: "atom",
11047
11099
  mathmlBuilder(group, style) {
11048
- const node = new mathMLTree.MathNode("mo", [makeText(group.text, group.mode)]);
11100
+ const node = new MathNode("mo", [makeText(group.text, group.mode)]);
11049
11101
  if (group.family === "punct") {
11050
11102
  node.setAttribute("separator", "true");
11051
11103
  } else if (group.family === "open" || group.family === "close") {
@@ -11075,10 +11127,10 @@ defineFunctionBuilders({
11075
11127
  } else if (group.needsSpacing) {
11076
11128
  // Fix a MathML bug that occurs when a <mo> is between two <mtext> elements.
11077
11129
  if (group.family === "bin") {
11078
- return new mathMLTree.MathNode("mrow", [padding(0.222), node, padding(0.222)])
11130
+ return new MathNode("mrow", [padding(0.222), node, padding(0.222)])
11079
11131
  } else {
11080
11132
  // REL spacing
11081
- return new mathMLTree.MathNode("mrow", [padding(0.2778), node, padding(0.2778)])
11133
+ return new MathNode("mrow", [padding(0.2778), node, padding(0.2778)])
11082
11134
  }
11083
11135
  }
11084
11136
  return node;
@@ -11419,8 +11471,8 @@ const primes = new Set(["\\prime", "\\dprime", "\\trprime", "\\qprime",
11419
11471
  "\\backprime", "\\backdprime", "\\backtrprime"]);
11420
11472
 
11421
11473
  const italicNumber = (text, variant, tag) => {
11422
- const mn = new mathMLTree.MathNode(tag, [text]);
11423
- const wrapper = new mathMLTree.MathNode("mstyle", [mn]);
11474
+ const mn = new MathNode(tag, [text]);
11475
+ const wrapper = new MathNode("mstyle", [mn]);
11424
11476
  wrapper.style["font-style"] = "italic";
11425
11477
  wrapper.style["font-family"] = "Cambria, 'Times New Roman', serif";
11426
11478
  if (variant === "bold-italic") { wrapper.style["font-weight"] = "bold"; }
@@ -11437,17 +11489,17 @@ defineFunctionBuilders({
11437
11489
  const variant = getVariant(group, style) || defaultVariant;
11438
11490
  if (variant === "script") {
11439
11491
  text.text = variantChar(text.text, variant);
11440
- return new mathMLTree.MathNode("mi", [text], [style.font])
11492
+ return new MathNode("mi", [text], [style.font])
11441
11493
  } else if (variant !== "italic") {
11442
11494
  text.text = variantChar(text.text, variant);
11443
11495
  }
11444
- let node = new mathMLTree.MathNode("mi", [text]);
11496
+ let node = new MathNode("mi", [text]);
11445
11497
  // TODO: Handle U+1D49C - U+1D4CF per https://www.unicode.org/charts/PDF/U1D400.pdf
11446
11498
  if (variant === "normal") {
11447
11499
  node.setAttribute("mathvariant", "normal");
11448
11500
  if (text.text.length === 1) {
11449
11501
  // A Firefox bug will apply spacing here, but there should be none. Fix it.
11450
- node = new mathMLTree.MathNode("mpadded", [node]);
11502
+ node = new MathNode("mpadded", [node]);
11451
11503
  node.setAttribute("lspace", "0");
11452
11504
  }
11453
11505
  }
@@ -11478,15 +11530,15 @@ defineFunctionBuilders({
11478
11530
  if (variant !== "normal") {
11479
11531
  text.text = text.text.split("").map(c => variantChar(c, variant)).join("");
11480
11532
  }
11481
- node = new mathMLTree.MathNode(tag, [text]);
11533
+ node = new MathNode(tag, [text]);
11482
11534
  }
11483
11535
  } else if (group.mode === "text") {
11484
11536
  if (variant !== "normal") {
11485
11537
  text.text = variantChar(text.text, variant);
11486
11538
  }
11487
- node = new mathMLTree.MathNode("mtext", [text]);
11539
+ node = new MathNode("mtext", [text]);
11488
11540
  } else if (primes.has(group.text)) {
11489
- node = new mathMLTree.MathNode("mo", [text]);
11541
+ node = new MathNode("mo", [text]);
11490
11542
  // TODO: If/when Chromium uses ssty variant for prime, remove the next line.
11491
11543
  node.classes.push("tml-prime");
11492
11544
  } else {
@@ -11494,7 +11546,7 @@ defineFunctionBuilders({
11494
11546
  if (variant !== "italic") {
11495
11547
  text.text = variantChar(text.text, variant);
11496
11548
  }
11497
- node = new mathMLTree.MathNode("mi", [text]);
11549
+ node = new MathNode("mi", [text]);
11498
11550
  if (text.text === origText && latinRegEx.test(origText)) {
11499
11551
  node.setAttribute("mathvariant", "italic");
11500
11552
  }
@@ -11537,11 +11589,11 @@ defineFunctionBuilders({
11537
11589
  // Firefox does not render a space in a <mtext> </mtext>. So write a no-break space.
11538
11590
  // TODO: If Firefox fixes that bug, uncomment the next line and write ch into the node.
11539
11591
  //const ch = (regularSpace[group.text].className === "nobreak") ? "\u00a0" : " "
11540
- node = new mathMLTree.MathNode("mtext", [new mathMLTree.TextNode("\u00a0")]);
11592
+ node = new MathNode("mtext", [new TextNode("\u00a0")]);
11541
11593
  } else if (Object.prototype.hasOwnProperty.call(cssSpace, group.text)) {
11542
11594
  // MathML 3.0 calls for nobreak to occur in an <mo>, not an <mtext>
11543
11595
  // Ref: https://www.w3.org/Math/draft-spec/mathml.html#chapter3_presm.lbattrs
11544
- node = new mathMLTree.MathNode("mo");
11596
+ node = new MathNode("mo");
11545
11597
  if (group.text === "\\nobreak") {
11546
11598
  node.setAttribute("linebreak", "nobreak");
11547
11599
  }
@@ -11656,10 +11708,10 @@ defineFunction({
11656
11708
  },
11657
11709
  mathmlBuilder(group, style) {
11658
11710
  // Use a math table to create vertically centered content.
11659
- const mtd = new mathMLTree.MathNode("mtd", [buildGroup$1(group.body, style)]);
11711
+ const mtd = new MathNode("mtd", [buildGroup$1(group.body, style)]);
11660
11712
  mtd.style.padding = "0";
11661
- const mtr = new mathMLTree.MathNode("mtr", [mtd]);
11662
- return new mathMLTree.MathNode("mtable", [mtr])
11713
+ const mtr = new MathNode("mtr", [mtd]);
11714
+ return new MathNode("mtable", [mtr])
11663
11715
  }
11664
11716
  });
11665
11717
 
@@ -11678,8 +11730,8 @@ defineFunction({
11678
11730
  throw new ParseError("\\verb ended by end of line instead of matching delimiter");
11679
11731
  },
11680
11732
  mathmlBuilder(group, style) {
11681
- const text = new mathMLTree.TextNode(makeVerb(group));
11682
- const node = new mathMLTree.MathNode("mtext", [text]);
11733
+ const text = new TextNode(makeVerb(group));
11734
+ const node = new MathNode("mtext", [text]);
11683
11735
  node.setAttribute("mathvariant", "monospace");
11684
11736
  return node;
11685
11737
  }
@@ -14011,7 +14063,7 @@ class Style {
14011
14063
  * https://mit-license.org/
14012
14064
  */
14013
14065
 
14014
- const version = "0.11.11";
14066
+ const version = "0.12.02";
14015
14067
 
14016
14068
  function postProcess(block) {
14017
14069
  const labelMap = {};