temml 0.11.1 → 0.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/temml.mjs CHANGED
@@ -1181,9 +1181,6 @@ defineSymbol(math, textord, "\u29eb", "\\blacklozenge");
1181
1181
  defineSymbol(math, textord, "\u2605", "\\bigstar");
1182
1182
  defineSymbol(math, textord, "\u2222", "\\sphericalangle", true);
1183
1183
  defineSymbol(math, textord, "\u2201", "\\complement", true);
1184
- // unicode-math maps U+F0 to \matheth. We map to AMS function \eth
1185
- defineSymbol(math, textord, "\u00f0", "\\eth", true);
1186
- defineSymbol(text, textord, "\u00f0", "\u00f0");
1187
1184
  defineSymbol(math, textord, "\u2571", "\\diagup");
1188
1185
  defineSymbol(math, textord, "\u2572", "\\diagdown");
1189
1186
  defineSymbol(math, textord, "\u25a1", "\\square");
@@ -1543,6 +1540,46 @@ defineSymbol(math, mathord, "\u03e1", "\\sampi", true);
1543
1540
  defineSymbol(math, mathord, "\u03da", "\\Stigma", true);
1544
1541
  defineSymbol(math, mathord, "\u03db", "\\stigma", true);
1545
1542
  defineSymbol(math, mathord, "\u2aeb", "\\Bot");
1543
+
1544
+ // unicode-math maps U+F0 to \matheth. We map to AMS function \eth
1545
+ defineSymbol(math, textord, "\u00f0", "\\eth", true); // ð
1546
+ defineSymbol(text, textord, "\u00f0", "\u00f0");
1547
+ // Extended ASCII and non-ASCII Letters
1548
+ defineSymbol(math, textord, "\u00C5", "\\AA"); // Å
1549
+ defineSymbol(text, textord, "\u00C5", "\\AA", true);
1550
+ defineSymbol(math, textord, "\u00C6", "\\AE", true); // Æ
1551
+ defineSymbol(text, textord, "\u00C6", "\\AE", true);
1552
+ defineSymbol(math, textord, "\u00D0", "\\DH", true); // Ð
1553
+ defineSymbol(text, textord, "\u00D0", "\\DH", true);
1554
+ defineSymbol(math, textord, "\u00DE", "\\TH", true); // Þ
1555
+ defineSymbol(text, textord, "\u00DE", "\\TH", true);
1556
+ defineSymbol(math, textord, "\u00DF", "\\ss", true); // ß
1557
+ defineSymbol(text, textord, "\u00DF", "\\ss", true);
1558
+ defineSymbol(math, textord, "\u00E5", "\\aa"); // å
1559
+ defineSymbol(text, textord, "\u00E5", "\\aa", true);
1560
+ defineSymbol(math, textord, "\u00E6", "\\ae", true); // æ
1561
+ defineSymbol(text, textord, "\u00E6", "\\ae", true);
1562
+ defineSymbol(math, textord, "\u00F0", "\\dh"); // ð
1563
+ defineSymbol(text, textord, "\u00F0", "\\dh", true);
1564
+ defineSymbol(math, textord, "\u00FE", "\\th", true); // þ
1565
+ defineSymbol(text, textord, "\u00FE", "\\th", true);
1566
+ defineSymbol(math, textord, "\u0110", "\\DJ", true); // Đ
1567
+ defineSymbol(text, textord, "\u0110", "\\DJ", true);
1568
+ defineSymbol(math, textord, "\u0111", "\\dj", true); // đ
1569
+ defineSymbol(text, textord, "\u0111", "\\dj", true);
1570
+ defineSymbol(math, textord, "\u0141", "\\L", true); // Ł
1571
+ defineSymbol(text, textord, "\u0141", "\\L", true);
1572
+ defineSymbol(math, textord, "\u0141", "\\l", true); // ł
1573
+ defineSymbol(text, textord, "\u0141", "\\l", true);
1574
+ defineSymbol(math, textord, "\u014A", "\\NG", true); // Ŋ
1575
+ defineSymbol(text, textord, "\u014A", "\\NG", true);
1576
+ defineSymbol(math, textord, "\u014B", "\\ng", true); // ŋ
1577
+ defineSymbol(text, textord, "\u014B", "\\ng", true);
1578
+ defineSymbol(math, textord, "\u0152", "\\OE", true); // Œ
1579
+ defineSymbol(text, textord, "\u0152", "\\OE", true);
1580
+ defineSymbol(math, textord, "\u0153", "\\oe", true); // œ
1581
+ defineSymbol(text, textord, "\u0153", "\\oe", true);
1582
+
1546
1583
  defineSymbol(math, bin, "\u2217", "\u2217", true);
1547
1584
  defineSymbol(math, bin, "+", "+");
1548
1585
  defineSymbol(math, bin, "\u2217", "*");
@@ -1751,13 +1788,8 @@ defineSymbol(math, textord, "\u0131", "\u0131");
1751
1788
  defineSymbol(math, textord, "\u0237", "\u0237");
1752
1789
  defineSymbol(text, textord, "\u0131", "\\i", true);
1753
1790
  defineSymbol(text, textord, "\u0237", "\\j", true);
1754
- defineSymbol(text, textord, "\u00df", "\\ss", true);
1755
- defineSymbol(text, textord, "\u00e6", "\\ae", true);
1756
- defineSymbol(text, textord, "\u0153", "\\oe", true);
1757
1791
  defineSymbol(text, textord, "\u00f8", "\\o", true);
1758
1792
  defineSymbol(math, mathord, "\u00f8", "\\o", true);
1759
- defineSymbol(text, textord, "\u00c6", "\\AE", true);
1760
- defineSymbol(text, textord, "\u0152", "\\OE", true);
1761
1793
  defineSymbol(text, textord, "\u00d8", "\\O", true);
1762
1794
  defineSymbol(math, mathord, "\u00d8", "\\O", true);
1763
1795
  defineSymbol(text, accent, "\u02ca", "\\'"); // acute
@@ -1770,7 +1802,7 @@ defineSymbol(text, accent, "\u02d9", "\\."); // dot above
1770
1802
  defineSymbol(text, accent, "\u00b8", "\\c"); // cedilla
1771
1803
  defineSymbol(text, accent, "\u02da", "\\r"); // ring above
1772
1804
  defineSymbol(text, accent, "\u02c7", "\\v"); // caron
1773
- defineSymbol(text, accent, "\u00a8", '\\"'); // diaresis
1805
+ defineSymbol(text, accent, "\u00a8", '\\"'); // diaeresis
1774
1806
  defineSymbol(text, accent, "\u02dd", "\\H"); // double acute
1775
1807
  defineSymbol(math, accent, "\u02ca", "\\'"); // acute
1776
1808
  defineSymbol(math, accent, "\u02cb", "\\`"); // grave
@@ -1782,7 +1814,7 @@ defineSymbol(math, accent, "\u02d9", "\\."); // dot above
1782
1814
  defineSymbol(math, accent, "\u00b8", "\\c"); // cedilla
1783
1815
  defineSymbol(math, accent, "\u02da", "\\r"); // ring above
1784
1816
  defineSymbol(math, accent, "\u02c7", "\\v"); // caron
1785
- defineSymbol(math, accent, "\u00a8", '\\"'); // diaresis
1817
+ defineSymbol(math, accent, "\u00a8", '\\"'); // diaeresis
1786
1818
  defineSymbol(math, accent, "\u02dd", "\\H"); // double acute
1787
1819
 
1788
1820
  // These ligatures are detected and created in Parser.js's `formLigatures`.
@@ -2750,17 +2782,17 @@ const calculateSize = function(sizeValue, style) {
2750
2782
 
2751
2783
  // Helper functions
2752
2784
 
2753
- const padding$2 = width => {
2785
+ const padding$1 = width => {
2754
2786
  const node = new mathMLTree.MathNode("mspace");
2755
2787
  node.setAttribute("width", width + "em");
2756
2788
  return node
2757
2789
  };
2758
2790
 
2759
2791
  const paddedNode = (group, lspace = 0.3, rspace = 0, mustSmash = false) => {
2760
- if (group == null && rspace === 0) { return padding$2(lspace) }
2792
+ if (group == null && rspace === 0) { return padding$1(lspace) }
2761
2793
  const row = group ? [group] : [];
2762
- if (lspace !== 0) { row.unshift(padding$2(lspace)); }
2763
- if (rspace > 0) { row.push(padding$2(rspace)); }
2794
+ if (lspace !== 0) { row.unshift(padding$1(lspace)); }
2795
+ if (rspace > 0) { row.push(padding$1(rspace)); }
2764
2796
  if (mustSmash) {
2765
2797
  // Used for the bottom arrow in a {CD} environment
2766
2798
  const mpadded = new mathMLTree.MathNode("mpadded", row);
@@ -2887,8 +2919,8 @@ defineFunction({
2887
2919
  const node = munderoverNode(group.name, group.body, group.below, style);
2888
2920
  // Create operator spacing for a relation.
2889
2921
  const row = [node];
2890
- row.unshift(padding$2(0.2778));
2891
- row.push(padding$2(0.2778));
2922
+ row.unshift(padding$1(0.2778));
2923
+ row.push(padding$1(0.2778));
2892
2924
  return new mathMLTree.MathNode("mrow", row)
2893
2925
  }
2894
2926
  });
@@ -2963,13 +2995,13 @@ defineFunction({
2963
2995
  botNode.setAttribute("width", "0.5em");
2964
2996
  wrapper = new mathMLTree.MathNode(
2965
2997
  "mpadded",
2966
- [padding$2(0.2778), botNode, raiseNode, padding$2(0.2778)]
2998
+ [padding$1(0.2778), botNode, raiseNode, padding$1(0.2778)]
2967
2999
  );
2968
3000
  } else {
2969
3001
  raiseNode.setAttribute("width", (group.name === "\\equilibriumRight" ? "0.5em" : "0"));
2970
3002
  wrapper = new mathMLTree.MathNode(
2971
3003
  "mpadded",
2972
- [padding$2(0.2778), raiseNode, botArrow, padding$2(0.2778)]
3004
+ [padding$1(0.2778), raiseNode, botArrow, padding$1(0.2778)]
2973
3005
  );
2974
3006
  }
2975
3007
 
@@ -3345,7 +3377,7 @@ const bordermatrixParseTree = (matrix, delimiters) => {
3345
3377
  // A vphantom with contents from the pmatrix, to set minimum cell height
3346
3378
  const phantomBody = [];
3347
3379
  for (let j = 0; j < body[i].length; j++) {
3348
- phantomBody.push(structuredClone(body[i][j]));
3380
+ phantomBody.push(body[i][j]);
3349
3381
  }
3350
3382
  leftColumnBody[i - 1].push(phantom(phantomBody, "vphantom"));
3351
3383
  }
@@ -3353,18 +3385,18 @@ const bordermatrixParseTree = (matrix, delimiters) => {
3353
3385
  // Create an array for the top row
3354
3386
  const topRowBody = new Array(body.length).fill().map(() => []);
3355
3387
  for (let j = 0; j < body[0].length; j++) {
3356
- topRowBody[0].push(structuredClone(body[0][j]));
3388
+ topRowBody[0].push(body[0][j]);
3357
3389
  }
3358
3390
  // Copy the rest of the pmatrix, but squashed via \hphantom
3359
3391
  for (let i = 1; i < body.length; i++) {
3360
3392
  for (let j = 0; j < body[0].length; j++) {
3361
- topRowBody[i].push(phantom(structuredClone(body[i][j]).body, "hphantom"));
3393
+ topRowBody[i].push(phantom(body[i][j].body, "hphantom"));
3362
3394
  }
3363
3395
  }
3364
3396
 
3365
3397
  // Squash the top row of the main {pmatrix}
3366
3398
  for (let j = 0; j < body[0].length; j++) {
3367
- body[0][j] = phantom(structuredClone(body[0][j]).body, "hphantom");
3399
+ body[0][j] = phantom(body[0][j].body, "hphantom");
3368
3400
  }
3369
3401
 
3370
3402
  // Now wrap the arrays in the proper parse nodes.
@@ -8081,7 +8113,7 @@ defineFunction({
8081
8113
  }
8082
8114
  });
8083
8115
 
8084
- const padding$1 = _ => {
8116
+ const padding = _ => {
8085
8117
  const node = new mathMLTree.MathNode("mspace");
8086
8118
  node.setAttribute("width", "3pt");
8087
8119
  return node
@@ -8094,9 +8126,9 @@ const mathmlBuilder$7 = (group, style) => {
8094
8126
  // Firefox does not reliably add side padding.
8095
8127
  // Insert <mspace>
8096
8128
  node = new mathMLTree.MathNode("mrow", [
8097
- padding$1(),
8129
+ padding(),
8098
8130
  buildGroup$1(group.body, style),
8099
- padding$1()
8131
+ padding()
8100
8132
  ]);
8101
8133
  } else {
8102
8134
  node = new mathMLTree.MathNode("menclose", [buildGroup$1(group.body, style)]);
@@ -8445,9 +8477,9 @@ const mathmlBuilder$6 = (group, style) => {
8445
8477
  const mi = mathGroup.children[0].children[0];
8446
8478
  delete mi.attributes.mathvariant;
8447
8479
  for (let i = 1; i < mathGroup.children.length; i++) {
8448
- mi.children[0].text += mathGroup.children[i].type === "mn"
8449
- ? mathGroup.children[i].children[0].text
8450
- : mathGroup.children[i].children[0].children[0].text;
8480
+ mi.children[0].text += mathGroup.children[i].children[0].children
8481
+ ? mathGroup.children[i].children[0].children[0].text
8482
+ : mathGroup.children[i].children[0].text;
8451
8483
  }
8452
8484
  // Wrap in a <mrow> to prevent the same Firefox bug.
8453
8485
  const bogus = new mathMLTree.MathNode("mtext", new mathMLTree.TextNode("\u200b"));
@@ -9496,12 +9528,6 @@ defineFunction({
9496
9528
 
9497
9529
  const textAtomTypes = ["text", "textord", "mathord", "atom"];
9498
9530
 
9499
- const padding = width => {
9500
- const node = new mathMLTree.MathNode("mspace");
9501
- node.setAttribute("width", width + "em");
9502
- return node
9503
- };
9504
-
9505
9531
  function mathmlBuilder$3(group, style) {
9506
9532
  let node;
9507
9533
  const inner = buildExpression(group.body, style);
@@ -9537,17 +9563,17 @@ function mathmlBuilder$3(group, style) {
9537
9563
  if (doSpacing ) {
9538
9564
  if (group.mclass === "mbin") {
9539
9565
  // medium space
9540
- node.children.unshift(padding(0.2222));
9541
- node.children.push(padding(0.2222));
9566
+ node.children.unshift(padding$1(0.2222));
9567
+ node.children.push(padding$1(0.2222));
9542
9568
  } else if (group.mclass === "mrel") {
9543
9569
  // thickspace
9544
- node.children.unshift(padding(0.2778));
9545
- node.children.push(padding(0.2778));
9570
+ node.children.unshift(padding$1(0.2778));
9571
+ node.children.push(padding$1(0.2778));
9546
9572
  } else if (group.mclass === "mpunct") {
9547
- node.children.push(padding(0.1667));
9573
+ node.children.push(padding$1(0.1667));
9548
9574
  } else if (group.mclass === "minner") {
9549
- node.children.unshift(padding(0.0556)); // 1 mu is the most likely option
9550
- node.children.push(padding(0.0556));
9575
+ node.children.unshift(padding$1(0.0556)); // 1 mu is the most likely option
9576
+ node.children.push(padding$1(0.0556));
9551
9577
  }
9552
9578
  }
9553
9579
  } else {
@@ -9617,14 +9643,19 @@ defineFunction({
9617
9643
  break
9618
9644
  }
9619
9645
  }
9620
- return {
9621
- type: "mclass",
9622
- mode: parser.mode,
9623
- mclass: "m" + funcName.slice(5),
9624
- body: ordargument(mustPromote ? mord : body),
9625
- isCharacterBox,
9626
- mustPromote
9627
- };
9646
+ if (mustPromote && funcName === "\\mathord" && mord.type === "mathord"
9647
+ && mord.text.length > 1) {
9648
+ return mord
9649
+ } else {
9650
+ return {
9651
+ type: "mclass",
9652
+ mode: parser.mode,
9653
+ mclass: "m" + funcName.slice(5),
9654
+ body: ordargument(mustPromote ? mord : body),
9655
+ isCharacterBox,
9656
+ mustPromote
9657
+ };
9658
+ }
9628
9659
  },
9629
9660
  mathmlBuilder: mathmlBuilder$3
9630
9661
  });
@@ -9942,8 +9973,13 @@ defineFunction({
9942
9973
  "\u2a00",
9943
9974
  "\u2a01",
9944
9975
  "\u2a02",
9976
+ "\u2a03",
9945
9977
  "\u2a04",
9946
- "\u2a06"
9978
+ "\u2a05",
9979
+ "\u2a06",
9980
+ "\u2a07",
9981
+ "\u2a08",
9982
+ "\u2a09"
9947
9983
  ],
9948
9984
  props: {
9949
9985
  numArgs: 0
@@ -10186,7 +10222,7 @@ const mathmlBuilder$1 = (group, style) => {
10186
10222
  for (let i = 0; i < expression.length; i++) {
10187
10223
  let node = expression[i];
10188
10224
  if (node instanceof mathMLTree.MathNode) {
10189
- if (node.type === "mrow" && node.children.length === 1 &&
10225
+ if ((node.type === "mrow" || node.type === "mpadded") && node.children.length === 1 &&
10190
10226
  node.children[0] instanceof mathMLTree.MathNode) {
10191
10227
  node = node.children[0];
10192
10228
  }
@@ -10804,7 +10840,7 @@ const symbolRegEx = /^m(over|under|underover)$/;
10804
10840
  defineFunctionBuilders({
10805
10841
  type: "supsub",
10806
10842
  mathmlBuilder(group, style) {
10807
- // Is the inner group a relevant horizonal brace?
10843
+ // Is the inner group a relevant horizontal brace?
10808
10844
  let isBrace = false;
10809
10845
  let isOver;
10810
10846
  let isSup;
@@ -10987,6 +11023,14 @@ defineFunctionBuilders({
10987
11023
  // ":" is not in the MathML operator dictionary. Give it BIN spacing.
10988
11024
  node.attributes.lspace = "0.2222em";
10989
11025
  node.attributes.rspace = "0.2222em";
11026
+ } else if (group.needsSpacing) {
11027
+ // Fix a MathML bug that occurs when a <mo> is between two <mtext> elements.
11028
+ if (group.family === "bin") {
11029
+ return new mathMLTree.MathNode("mrow", [padding$1(0.222), node, padding$1(0.222)])
11030
+ } else {
11031
+ // REL spacing
11032
+ return new mathMLTree.MathNode("mrow", [padding$1(0.2778), node, padding$1(0.2778)])
11033
+ }
10990
11034
  }
10991
11035
  return node;
10992
11036
  }
@@ -11354,7 +11398,8 @@ defineFunctionBuilders({
11354
11398
  node.setAttribute("mathvariant", "normal");
11355
11399
  if (text.text.length === 1) {
11356
11400
  // A Firefox bug will apply spacing here, but there should be none. Fix it.
11357
- node = new mathMLTree.MathNode("mrow", [node]);
11401
+ node = new mathMLTree.MathNode("mpadded", [node]);
11402
+ node.setAttribute("lspace", "0");
11358
11403
  }
11359
11404
  }
11360
11405
  return node
@@ -12733,6 +12778,7 @@ var unicodeSymbols = {
12733
12778
 
12734
12779
  const binLeftCancellers = ["bin", "op", "open", "punct", "rel"];
12735
12780
  const sizeRegEx = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/;
12781
+ const textRegEx = /^ *\\text/;
12736
12782
 
12737
12783
  /**
12738
12784
  * This file contains the parser used to parse out a TeX expression from the
@@ -13643,6 +13689,11 @@ class Parser {
13643
13689
  loc,
13644
13690
  text
13645
13691
  };
13692
+ if ((family === "rel" || family === "bin") && this.prevAtomType === "text") {
13693
+ if (textRegEx.test(loc.lexer.input.slice(loc.end))) {
13694
+ s.needsSpacing = true; // Fix a MathML bug.
13695
+ }
13696
+ }
13646
13697
  } else {
13647
13698
  if (asciiFromScript[text]) {
13648
13699
  // Unicode 14 disambiguates chancery from roundhand.
@@ -13900,7 +13951,7 @@ class Style {
13900
13951
  * https://mit-license.org/
13901
13952
  */
13902
13953
 
13903
- const version = "0.11.01";
13954
+ const version = "0.11.03";
13904
13955
 
13905
13956
  function postProcess(block) {
13906
13957
  const labelMap = {};
@@ -11,7 +11,7 @@
11
11
  * https://mit-license.org/
12
12
  */
13
13
 
14
- const version = "0.11.01";
14
+ const version = "0.11.03";
15
15
 
16
16
  function postProcess(block) {
17
17
  const labelMap = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "temml",
3
- "version": "0.11.01",
3
+ "version": "0.11.03",
4
4
  "description": "TeX to MathML conversion in JavaScript.",
5
5
  "main": "dist/temml.js",
6
6
  "engines": {
package/src/Parser.js CHANGED
@@ -17,6 +17,7 @@ import unicodeSymbols from /*preval*/ "./unicodeSymbols";
17
17
 
18
18
  const binLeftCancellers = ["bin", "op", "open", "punct", "rel"];
19
19
  const sizeRegEx = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/
20
+ const textRegEx = /^ *\\text/
20
21
 
21
22
  /**
22
23
  * This file contains the parser used to parse out a TeX expression from the
@@ -926,7 +927,12 @@ export default class Parser {
926
927
  family,
927
928
  loc,
928
929
  text
929
- };
930
+ }
931
+ if ((family === "rel" || family === "bin") && this.prevAtomType === "text") {
932
+ if (textRegEx.test(loc.lexer.input.slice(loc.end))) {
933
+ s.needsSpacing = true // Fix a MathML bug.
934
+ }
935
+ }
930
936
  } else {
931
937
  if (asciiFromScript[text]) {
932
938
  // Unicode 14 disambiguates chancery from roundhand.
@@ -47,7 +47,7 @@ export const bordermatrixParseTree = (matrix, delimiters) => {
47
47
  // A vphantom with contents from the pmatrix, to set minimum cell height
48
48
  const phantomBody = [];
49
49
  for (let j = 0; j < body[i].length; j++) {
50
- phantomBody.push(structuredClone(body[i][j]))
50
+ phantomBody.push(body[i][j])
51
51
  }
52
52
  leftColumnBody[i - 1].push(phantom(phantomBody, "vphantom"))
53
53
  }
@@ -55,18 +55,18 @@ export const bordermatrixParseTree = (matrix, delimiters) => {
55
55
  // Create an array for the top row
56
56
  const topRowBody = new Array(body.length).fill().map(() => [])
57
57
  for (let j = 0; j < body[0].length; j++) {
58
- topRowBody[0].push(structuredClone(body[0][j]))
58
+ topRowBody[0].push(body[0][j])
59
59
  }
60
60
  // Copy the rest of the pmatrix, but squashed via \hphantom
61
61
  for (let i = 1; i < body.length; i++) {
62
62
  for (let j = 0; j < body[0].length; j++) {
63
- topRowBody[i].push(phantom(structuredClone(body[i][j]).body, "hphantom"))
63
+ topRowBody[i].push(phantom(body[i][j].body, "hphantom"))
64
64
  }
65
65
  }
66
66
 
67
67
  // Squash the top row of the main {pmatrix}
68
68
  for (let j = 0; j < body[0].length; j++) {
69
- body[0][j] = phantom(structuredClone(body[0][j]).body, "hphantom")
69
+ body[0][j] = phantom(body[0][j].body, "hphantom")
70
70
  }
71
71
 
72
72
  // Now wrap the arrays in the proper parse nodes.
@@ -6,7 +6,7 @@ import * as mml from "../buildMathML";
6
6
 
7
7
  // Helper functions
8
8
 
9
- const padding = width => {
9
+ export const padding = width => {
10
10
  const node = new mathMLTree.MathNode("mspace")
11
11
  node.setAttribute("width", width + "em")
12
12
  return node
@@ -34,9 +34,9 @@ const mathmlBuilder = (group, style) => {
34
34
  const mi = mathGroup.children[0].children[0];
35
35
  delete mi.attributes.mathvariant
36
36
  for (let i = 1; i < mathGroup.children.length; i++) {
37
- mi.children[0].text += mathGroup.children[i].type === "mn"
38
- ? mathGroup.children[i].children[0].text
39
- : mathGroup.children[i].children[0].children[0].text
37
+ mi.children[0].text += mathGroup.children[i].children[0].children
38
+ ? mathGroup.children[i].children[0].children[0].text
39
+ : mathGroup.children[i].children[0].text
40
40
  }
41
41
  // Wrap in a <mrow> to prevent the same Firefox bug.
42
42
  const bogus = new mathMLTree.MathNode("mtext", new mathMLTree.TextNode("\u200b"))
@@ -1,18 +1,13 @@
1
1
  import defineFunction, { ordargument } from "../defineFunction";
2
2
  import symbols from "../symbols";
3
3
  import mathMLTree from "../mathMLTree";
4
- import utils from "../utils";
4
+ import utils from "../utils.js"
5
+ import { padding } from "./arrow";
5
6
 
6
7
  import * as mml from "../buildMathML";
7
8
 
8
9
  const textAtomTypes = ["text", "textord", "mathord", "atom"]
9
10
 
10
- const padding = width => {
11
- const node = new mathMLTree.MathNode("mspace")
12
- node.setAttribute("width", width + "em")
13
- return node
14
- }
15
-
16
11
  function mathmlBuilder(group, style) {
17
12
  let node;
18
13
  const inner = mml.buildExpression(group.body, style);
@@ -128,14 +123,19 @@ defineFunction({
128
123
  break
129
124
  }
130
125
  }
131
- return {
132
- type: "mclass",
133
- mode: parser.mode,
134
- mclass: "m" + funcName.slice(5),
135
- body: ordargument(mustPromote ? mord : body),
136
- isCharacterBox,
137
- mustPromote
138
- };
126
+ if (mustPromote && funcName === "\\mathord" && mord.type === "mathord"
127
+ && mord.text.length > 1) {
128
+ return mord
129
+ } else {
130
+ return {
131
+ type: "mclass",
132
+ mode: parser.mode,
133
+ mclass: "m" + funcName.slice(5),
134
+ body: ordargument(mustPromote ? mord : body),
135
+ isCharacterBox,
136
+ mustPromote
137
+ };
138
+ }
139
139
  },
140
140
  mathmlBuilder
141
141
  });
@@ -120,8 +120,13 @@ defineFunction({
120
120
  "\u2a00",
121
121
  "\u2a01",
122
122
  "\u2a02",
123
+ "\u2a03",
123
124
  "\u2a04",
124
- "\u2a06"
125
+ "\u2a05",
126
+ "\u2a06",
127
+ "\u2a07",
128
+ "\u2a08",
129
+ "\u2a09"
125
130
  ],
126
131
  props: {
127
132
  numArgs: 0
@@ -19,7 +19,7 @@ const mathmlBuilder = (group, style) => {
19
19
  for (let i = 0; i < expression.length; i++) {
20
20
  let node = expression[i]
21
21
  if (node instanceof mathMLTree.MathNode) {
22
- if (node.type === "mrow" && node.children.length === 1 &&
22
+ if ((node.type === "mrow" || node.type === "mpadded") && node.children.length === 1 &&
23
23
  node.children[0] instanceof mathMLTree.MathNode) {
24
24
  node = node.children[0]
25
25
  }
@@ -19,7 +19,7 @@ const symbolRegEx = /^m(over|under|underover)$/
19
19
  defineFunctionBuilders({
20
20
  type: "supsub",
21
21
  mathmlBuilder(group, style) {
22
- // Is the inner group a relevant horizonal brace?
22
+ // Is the inner group a relevant horizontal brace?
23
23
  let isBrace = false
24
24
  let isOver
25
25
  let isSup
@@ -1,6 +1,7 @@
1
1
  import { defineFunctionBuilders } from "../defineFunction";
2
2
  import mathMLTree from "../mathMLTree";
3
3
  import * as mml from "../buildMathML";
4
+ import { padding } from "./arrow";
4
5
 
5
6
  // Operator ParseNodes created in Parser.js from symbol Groups in src/symbols.js.
6
7
 
@@ -47,6 +48,14 @@ defineFunctionBuilders({
47
48
  // ":" is not in the MathML operator dictionary. Give it BIN spacing.
48
49
  node.attributes.lspace = "0.2222em"
49
50
  node.attributes.rspace = "0.2222em"
51
+ } else if (group.needsSpacing) {
52
+ // Fix a MathML bug that occurs when a <mo> is between two <mtext> elements.
53
+ if (group.family === "bin") {
54
+ return new mathMLTree.MathNode("mrow", [padding(0.222), node, padding(0.222)])
55
+ } else {
56
+ // REL spacing
57
+ return new mathMLTree.MathNode("mrow", [padding(0.2778), node, padding(0.2778)])
58
+ }
50
59
  }
51
60
  return node;
52
61
  }
@@ -41,7 +41,8 @@ defineFunctionBuilders({
41
41
  node.setAttribute("mathvariant", "normal")
42
42
  if (text.text.length === 1) {
43
43
  // A Firefox bug will apply spacing here, but there should be none. Fix it.
44
- node = new mathMLTree.MathNode("mrow", [node])
44
+ node = new mathMLTree.MathNode("mpadded", [node])
45
+ node.setAttribute("lspace", "0")
45
46
  }
46
47
  }
47
48
  return node
@@ -5,7 +5,7 @@
5
5
  * https://mit-license.org/
6
6
  */
7
7
 
8
- export const version = "0.11.01";
8
+ export const version = "0.11.03";
9
9
 
10
10
  export function postProcess(block) {
11
11
  const labelMap = {}