temml 0.11.9 → 0.11.11

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
@@ -2403,13 +2403,12 @@ const getLabel = parent => {
2403
2403
 
2404
2404
  const taggedExpression = (expression, tag, style, leqno) => {
2405
2405
  tag = buildExpressionRow(tag[0].body, style);
2406
- tag = consolidateText(tag);
2407
- tag.classes.push("tml-tag");
2406
+ tag = consolidateText(tag); // tag is now an <mtext> element
2407
+ tag.classes.push("tml-tag"); // to be available for \ref
2408
2408
 
2409
2409
  const label = getLabel(expression); // from a \label{} function.
2410
2410
  expression = new mathMLTree.MathNode("mtd", [expression]);
2411
2411
  const rowArray = [glue$1(), expression, glue$1()];
2412
- rowArray[leqno ? 0 : 2].classes.push(leqno ? "tml-left" : "tml-right");
2413
2412
  rowArray[leqno ? 0 : 2].children.push(tag);
2414
2413
  const mtr = new mathMLTree.MathNode("mtr", rowArray, ["tml-tageqn"]);
2415
2414
  if (label) { mtr.setAttribute("id", label); }
@@ -2806,21 +2805,21 @@ const calculateSize = function(sizeValue, style) {
2806
2805
 
2807
2806
  // Helper functions
2808
2807
 
2809
- const padding$1 = width => {
2808
+ const padding = width => {
2810
2809
  const node = new mathMLTree.MathNode("mspace");
2811
2810
  node.setAttribute("width", width + "em");
2812
2811
  return node
2813
2812
  };
2814
2813
 
2815
2814
  const paddedNode = (group, lspace = 0.3, rspace = 0, mustSmash = false) => {
2816
- if (group == null && rspace === 0) { return padding$1(lspace) }
2815
+ if (group == null && rspace === 0) { return padding(lspace) }
2817
2816
  const row = group ? [group] : [];
2818
- if (lspace !== 0) { row.unshift(padding$1(lspace)); }
2819
- if (rspace > 0) { row.push(padding$1(rspace)); }
2817
+ if (lspace !== 0) { row.unshift(padding(lspace)); }
2818
+ if (rspace > 0) { row.push(padding(rspace)); }
2820
2819
  if (mustSmash) {
2821
2820
  // Used for the bottom arrow in a {CD} environment
2822
2821
  const mpadded = new mathMLTree.MathNode("mpadded", row);
2823
- mpadded.setAttribute("height", "0");
2822
+ mpadded.setAttribute("height", "0.1px"); // Don't use 0. WebKit would hide it.
2824
2823
  return mpadded
2825
2824
  } else {
2826
2825
  return new mathMLTree.MathNode("mrow", row)
@@ -2948,8 +2947,8 @@ defineFunction({
2948
2947
  const node = munderoverNode(group.name, group.body, group.below, style);
2949
2948
  // Create operator spacing for a relation.
2950
2949
  const row = [node];
2951
- row.unshift(padding$1(0.2778));
2952
- row.push(padding$1(0.2778));
2950
+ row.unshift(padding(0.2778));
2951
+ row.push(padding(0.2778));
2953
2952
  return new mathMLTree.MathNode("mrow", row)
2954
2953
  }
2955
2954
  });
@@ -3013,13 +3012,13 @@ defineFunction({
3013
3012
  botNode.setAttribute("width", "0.5em");
3014
3013
  wrapper = new mathMLTree.MathNode(
3015
3014
  "mpadded",
3016
- [padding$1(0.2778), botNode, raiseNode, padding$1(0.2778)]
3015
+ [padding(0.2778), botNode, raiseNode, padding(0.2778)]
3017
3016
  );
3018
3017
  } else {
3019
3018
  raiseNode.setAttribute("width", (group.name === "\\equilibriumRight" ? "0.5em" : "0"));
3020
3019
  wrapper = new mathMLTree.MathNode(
3021
3020
  "mpadded",
3022
- [padding$1(0.2778), raiseNode, botArrow, padding$1(0.2778)]
3021
+ [padding(0.2778), raiseNode, botArrow, padding(0.2778)]
3023
3022
  );
3024
3023
  }
3025
3024
 
@@ -3312,19 +3311,19 @@ defineFunction({
3312
3311
  return new mathMLTree.MathNode("mrow", style) // empty label
3313
3312
  }
3314
3313
  // Abuse an <mtable> to create vertically centered content.
3315
- const mtd = new mathMLTree.MathNode("mtd", [buildGroup$1(group.label, style)]);
3314
+ const mrow = buildGroup$1(group.label, style);
3315
+ if (group.side === "left") {
3316
+ mrow.classes.push("tml-shift-left");
3317
+ }
3318
+ const mtd = new mathMLTree.MathNode("mtd", [mrow]);
3316
3319
  mtd.style.padding = "0";
3317
3320
  const mtr = new mathMLTree.MathNode("mtr", [mtd]);
3318
3321
  const mtable = new mathMLTree.MathNode("mtable", [mtr]);
3319
3322
  const label = new mathMLTree.MathNode("mpadded", [mtable]);
3320
3323
  // Set the label width to zero so that the arrow will be centered under the corner cell.
3321
- label.setAttribute("width", "0");
3324
+ label.setAttribute("width", "0.1px"); // Don't use 0. WebKit would hide it.
3322
3325
  label.setAttribute("displaystyle", "false");
3323
3326
  label.setAttribute("scriptlevel", "1");
3324
- if (group.side === "left") {
3325
- label.style.display = "flex";
3326
- label.style.justifyContent = "flex-end";
3327
- }
3328
3327
  return label;
3329
3328
  }
3330
3329
  });
@@ -6472,7 +6471,6 @@ const mathmlBuilder$9 = function(group, style) {
6472
6471
 
6473
6472
  if (group.envClasses.includes("multline")) {
6474
6473
  const align = i === 0 ? "left" : i === numRows - 1 ? "right" : "center";
6475
- mtd.setAttribute("columnalign", align);
6476
6474
  if (align !== "center") {
6477
6475
  mtd.classes.push("tml-" + align);
6478
6476
  }
@@ -6502,10 +6500,8 @@ const mathmlBuilder$9 = function(group, style) {
6502
6500
  row.push(glue(group));
6503
6501
  if (group.leqno) {
6504
6502
  row[0].children.push(tagElement);
6505
- row[0].classes.push("tml-left");
6506
6503
  } else {
6507
6504
  row[row.length - 1].children.push(tagElement);
6508
- row[row.length - 1].classes.push("tml-right");
6509
6505
  }
6510
6506
  }
6511
6507
  }
@@ -6546,8 +6542,10 @@ const mathmlBuilder$9 = function(group, style) {
6546
6542
  }
6547
6543
  }
6548
6544
  if (mustSquashRow) {
6549
- // All the cell contents are \hphantom. Squash the padding.
6545
+ // All the cell contents are \hphantom. Squash the cell.
6550
6546
  for (let j = 0; j < mtr.children.length; j++) {
6547
+ mtr.children[j].style.display = "block"; // necessary in Firefox only
6548
+ mtr.children[j].style.height = "0"; // necessary in Firefox only
6551
6549
  mtr.children[j].style.paddingTop = "0";
6552
6550
  mtr.children[j].style.paddingBottom = "0";
6553
6551
  }
@@ -6634,7 +6632,7 @@ const mathmlBuilder$9 = function(group, style) {
6634
6632
  }
6635
6633
  if (group.autoTag) {
6636
6634
  const k = group.leqno ? 0 : row.children.length - 1;
6637
- row.children[k].classes = ["tml-" + (group.leqno ? "left" : "right")];
6635
+ row.children[k].classes = []; // Default is center.
6638
6636
  }
6639
6637
  }
6640
6638
  if (row.children.length > 1 && group.envClasses.includes("cases")) {
@@ -6665,7 +6663,6 @@ const mathmlBuilder$9 = function(group, style) {
6665
6663
  }
6666
6664
 
6667
6665
  // Column separator lines and column alignment
6668
- let align = "";
6669
6666
 
6670
6667
  if (group.cols && group.cols.length > 0) {
6671
6668
  const cols = group.cols;
@@ -6694,7 +6691,6 @@ const mathmlBuilder$9 = function(group, style) {
6694
6691
  for (let i = iStart; i < iEnd; i++) {
6695
6692
  if (cols[i].type === "align") {
6696
6693
  const colAlign = alignMap[cols[i].align];
6697
- align += colAlign;
6698
6694
  iCol += 1;
6699
6695
  for (const row of table.children) {
6700
6696
  if (colAlign.trim() !== "center" && iCol < row.children.length) {
@@ -6732,15 +6728,6 @@ const mathmlBuilder$9 = function(group, style) {
6732
6728
  }
6733
6729
  }
6734
6730
  }
6735
- if (group.autoTag) {
6736
- // allow for glue cells on each side
6737
- align = "left " + (align.length > 0 ? align : "center ") + "right ";
6738
- }
6739
- if (align) {
6740
- // Firefox reads this attribute, not the -webkit-left|right written above.
6741
- // TODO: When Chrome no longer needs "-webkit-", use CSS and delete the next line.
6742
- table.setAttribute("columnalign", align.trim());
6743
- }
6744
6731
 
6745
6732
  if (group.envClasses.includes("small")) {
6746
6733
  // A small array. Wrap in scriptstyle.
@@ -7919,6 +7906,9 @@ const sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
7919
7906
 
7920
7907
  // Delimiter functions
7921
7908
  function checkDelimiter(delim, context) {
7909
+ if (delim.type === "ordgroup" && delim.body.length === 1) {
7910
+ delim = delim.body[0]; // Unwrap the braces
7911
+ }
7922
7912
  const symDelim = checkSymbolNodeType(delim);
7923
7913
  if (symDelim && delimiters.includes(symDelim.text)) {
7924
7914
  // If a character is not in the MathML operator dictionary, it will not stretch.
@@ -8150,26 +8140,8 @@ defineFunction({
8150
8140
  }
8151
8141
  });
8152
8142
 
8153
- const padding = _ => {
8154
- const node = new mathMLTree.MathNode("mspace");
8155
- node.setAttribute("width", "3pt");
8156
- return node
8157
- };
8158
-
8159
8143
  const mathmlBuilder$7 = (group, style) => {
8160
- let node;
8161
- if (group.label.indexOf("colorbox") > -1 || group.label === "\\boxed") {
8162
- // MathML core does not support +width attribute in <mpadded>.
8163
- // Firefox does not reliably add side padding.
8164
- // Insert <mspace>
8165
- node = new mathMLTree.MathNode("mrow", [
8166
- padding(),
8167
- buildGroup$1(group.body, style),
8168
- padding()
8169
- ]);
8170
- } else {
8171
- node = new mathMLTree.MathNode("menclose", [buildGroup$1(group.body, style)]);
8172
- }
8144
+ const node = new mathMLTree.MathNode("menclose", [buildGroup$1(group.body, style)]);
8173
8145
  switch (group.label) {
8174
8146
  case "\\overline":
8175
8147
  node.setAttribute("notation", "top"); // for Firefox & WebKit
@@ -8217,7 +8189,7 @@ const mathmlBuilder$7 = (group, style) => {
8217
8189
  case "\\boxed":
8218
8190
  // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} from amsmath.sty
8219
8191
  node.setAttribute("notation", "box");
8220
- node.style.padding = "padding: 3pt 0 3pt 0";
8192
+ node.style.padding = "3pt";
8221
8193
  node.style.border = "1px solid";
8222
8194
  node.setAttribute("scriptlevel", "0");
8223
8195
  node.setAttribute("displaystyle", "true");
@@ -8234,12 +8206,10 @@ const mathmlBuilder$7 = (group, style) => {
8234
8206
  //const fboxsep = 3; // 3 pt from LaTeX source2e
8235
8207
  //node.setAttribute("height", `+${2 * fboxsep}pt`)
8236
8208
  //node.setAttribute("voffset", `${fboxsep}pt`)
8237
- const style = { padding: "3pt 0 3pt 0" };
8238
-
8209
+ node.style.padding = "3pt";
8239
8210
  if (group.label === "\\fcolorbox") {
8240
- style.border = "0.0667em solid " + String(group.borderColor);
8211
+ node.style.border = "0.0667em solid " + String(group.borderColor);
8241
8212
  }
8242
- node.style = style;
8243
8213
  break
8244
8214
  }
8245
8215
  }
@@ -9382,7 +9352,7 @@ defineFunction({
9382
9352
  const phantomInner = buildExpression(ordargument(group.body), style);
9383
9353
  const phantom = new mathMLTree.MathNode("mphantom", phantomInner);
9384
9354
  strut = new mathMLTree.MathNode("mpadded", [phantom]);
9385
- strut.setAttribute("width", "0px");
9355
+ strut.setAttribute("width", "0.1px"); // Don't use 0. WebKit would hide it.
9386
9356
  }
9387
9357
 
9388
9358
  const inner = buildGroup$1(group.body, style);
@@ -9411,7 +9381,7 @@ defineFunction({
9411
9381
  node.style.justifyContent = "center";
9412
9382
  }
9413
9383
  }
9414
- node.setAttribute("width", "0px");
9384
+ node.setAttribute("width", "0.1px"); // Don't use 0. WebKit would hide it.
9415
9385
  return node
9416
9386
  }
9417
9387
  });
@@ -9529,17 +9499,17 @@ function mathmlBuilder$3(group, style) {
9529
9499
  if (doSpacing ) {
9530
9500
  if (group.mclass === "mbin") {
9531
9501
  // medium space
9532
- node.children.unshift(padding$1(0.2222));
9533
- node.children.push(padding$1(0.2222));
9502
+ node.children.unshift(padding(0.2222));
9503
+ node.children.push(padding(0.2222));
9534
9504
  } else if (group.mclass === "mrel") {
9535
9505
  // thickspace
9536
- node.children.unshift(padding$1(0.2778));
9537
- node.children.push(padding$1(0.2778));
9506
+ node.children.unshift(padding(0.2778));
9507
+ node.children.push(padding(0.2778));
9538
9508
  } else if (group.mclass === "mpunct") {
9539
- node.children.push(padding$1(0.1667));
9509
+ node.children.push(padding(0.1667));
9540
9510
  } else if (group.mclass === "minner") {
9541
- node.children.unshift(padding$1(0.0556)); // 1 mu is the most likely option
9542
- node.children.push(padding$1(0.0556));
9511
+ node.children.unshift(padding(0.0556)); // 1 mu is the most likely option
9512
+ node.children.push(padding(0.0556));
9543
9513
  }
9544
9514
  }
9545
9515
  } else {
@@ -10787,6 +10757,11 @@ defineFunction({
10787
10757
  }
10788
10758
  });
10789
10759
 
10760
+ // Letters that are x-height w/o a descender.
10761
+ const xHeights = ['a', 'c', 'e', 'ı', 'm', 'n', 'o', 'r', 's', 'u', 'v', 'w', 'x', 'z', 'α',
10762
+ 'ε', 'ι', 'κ', 'ν', 'ο', 'π', 'σ', 'τ', 'υ', 'ω', '\\alpha', '\\epsilon', "\\iota",
10763
+ '\\kappa', '\\nu', '\\omega', '\\pi', '\\tau', '\\omega'];
10764
+
10790
10765
  defineFunction({
10791
10766
  type: "sqrt",
10792
10767
  names: ["\\sqrt"],
@@ -10797,6 +10772,20 @@ defineFunction({
10797
10772
  handler({ parser }, args, optArgs) {
10798
10773
  const index = optArgs[0];
10799
10774
  const body = args[0];
10775
+ // Check if the body consists entirely of an x-height letter.
10776
+ // TODO: Remove this check after Chromium is fixed.
10777
+ if (body.body && body.body.length === 1 && body.body[0].text &&
10778
+ xHeights.includes(body.body[0].text)) {
10779
+ // Chromium does not put enough space above an x-height letter.
10780
+ // Insert a strut.
10781
+ body.body.push({
10782
+ "type": "rule",
10783
+ "mode": "math",
10784
+ "shift": null,
10785
+ "width": { "number": 0, "unit": "pt" },
10786
+ "height": { "number": 0.5, "unit": "em" }
10787
+ });
10788
+ }
10800
10789
  return {
10801
10790
  type: "sqrt",
10802
10791
  mode: parser.mode,
@@ -11084,10 +11073,10 @@ defineFunctionBuilders({
11084
11073
  } else if (group.needsSpacing) {
11085
11074
  // Fix a MathML bug that occurs when a <mo> is between two <mtext> elements.
11086
11075
  if (group.family === "bin") {
11087
- return new mathMLTree.MathNode("mrow", [padding$1(0.222), node, padding$1(0.222)])
11076
+ return new mathMLTree.MathNode("mrow", [padding(0.222), node, padding(0.222)])
11088
11077
  } else {
11089
11078
  // REL spacing
11090
- return new mathMLTree.MathNode("mrow", [padding$1(0.2778), node, padding$1(0.2778)])
11079
+ return new mathMLTree.MathNode("mrow", [padding(0.2778), node, padding(0.2778)])
11091
11080
  }
11092
11081
  }
11093
11082
  return node;
@@ -14020,7 +14009,7 @@ class Style {
14020
14009
  * https://mit-license.org/
14021
14010
  */
14022
14011
 
14023
- const version = "0.11.09";
14012
+ const version = "0.11.11";
14024
14013
 
14025
14014
  function postProcess(block) {
14026
14015
  const labelMap = {};
@@ -11,7 +11,7 @@
11
11
  * https://mit-license.org/
12
12
  */
13
13
 
14
- const version = "0.11.09";
14
+ const version = "0.11.11";
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.09",
3
+ "version": "0.11.11",
4
4
  "description": "TeX to MathML conversion in JavaScript.",
5
5
  "main": "dist/temml.js",
6
6
  "engines": {
@@ -283,13 +283,12 @@ const getLabel = parent => {
283
283
 
284
284
  const taggedExpression = (expression, tag, style, leqno) => {
285
285
  tag = buildExpressionRow(tag[0].body, style)
286
- tag = consolidateText(tag)
287
- tag.classes.push("tml-tag")
286
+ tag = consolidateText(tag) // tag is now an <mtext> element
287
+ tag.classes.push("tml-tag") // to be available for \ref
288
288
 
289
289
  const label = getLabel(expression) // from a \label{} function.
290
290
  expression = new mathMLTree.MathNode("mtd", [expression])
291
- const rowArray = [glue(), expression, glue()]
292
- rowArray[leqno ? 0 : 2].classes.push(leqno ? "tml-left" : "tml-right")
291
+ const rowArray = [glue(), expression, glue()];
293
292
  rowArray[leqno ? 0 : 2].children.push(tag)
294
293
  const mtr = new mathMLTree.MathNode("mtr", rowArray, ["tml-tageqn"])
295
294
  if (label) { mtr.setAttribute("id", label) }
@@ -285,7 +285,6 @@ const mathmlBuilder = function(group, style) {
285
285
 
286
286
  if (group.envClasses.includes("multline")) {
287
287
  const align = i === 0 ? "left" : i === numRows - 1 ? "right" : "center"
288
- mtd.setAttribute("columnalign", align)
289
288
  if (align !== "center") {
290
289
  mtd.classes.push("tml-" + align)
291
290
  }
@@ -315,10 +314,8 @@ const mathmlBuilder = function(group, style) {
315
314
  row.push(glue(group))
316
315
  if (group.leqno) {
317
316
  row[0].children.push(tagElement)
318
- row[0].classes.push("tml-left")
319
317
  } else {
320
318
  row[row.length - 1].children.push(tagElement)
321
- row[row.length - 1].classes.push("tml-right")
322
319
  }
323
320
  }
324
321
  }
@@ -359,8 +356,10 @@ const mathmlBuilder = function(group, style) {
359
356
  }
360
357
  }
361
358
  if (mustSquashRow) {
362
- // All the cell contents are \hphantom. Squash the padding.
359
+ // All the cell contents are \hphantom. Squash the cell.
363
360
  for (let j = 0; j < mtr.children.length; j++) {
361
+ mtr.children[j].style.display = "block" // necessary in Firefox only
362
+ mtr.children[j].style.height = "0" // necessary in Firefox only
364
363
  mtr.children[j].style.paddingTop = "0"
365
364
  mtr.children[j].style.paddingBottom = "0"
366
365
  }
@@ -447,7 +446,7 @@ const mathmlBuilder = function(group, style) {
447
446
  }
448
447
  if (group.autoTag) {
449
448
  const k = group.leqno ? 0 : row.children.length - 1
450
- row.children[k].classes = ["tml-" + (group.leqno ? "left" : "right")]
449
+ row.children[k].classes = []; // Default is center.
451
450
  }
452
451
  }
453
452
  if (row.children.length > 1 && group.envClasses.includes("cases")) {
@@ -478,7 +477,6 @@ const mathmlBuilder = function(group, style) {
478
477
  }
479
478
 
480
479
  // Column separator lines and column alignment
481
- let align = "";
482
480
 
483
481
  if (group.cols && group.cols.length > 0) {
484
482
  const cols = group.cols;
@@ -507,7 +505,6 @@ const mathmlBuilder = function(group, style) {
507
505
  for (let i = iStart; i < iEnd; i++) {
508
506
  if (cols[i].type === "align") {
509
507
  const colAlign = alignMap[cols[i].align];
510
- align += colAlign
511
508
  iCol += 1
512
509
  for (const row of table.children) {
513
510
  if (colAlign.trim() !== "center" && iCol < row.children.length) {
@@ -545,15 +542,6 @@ const mathmlBuilder = function(group, style) {
545
542
  }
546
543
  }
547
544
  }
548
- if (group.autoTag) {
549
- // allow for glue cells on each side
550
- align = "left " + (align.length > 0 ? align : "center ") + "right "
551
- }
552
- if (align) {
553
- // Firefox reads this attribute, not the -webkit-left|right written above.
554
- // TODO: When Chrome no longer needs "-webkit-", use CSS and delete the next line.
555
- table.setAttribute("columnalign", align.trim())
556
- }
557
545
 
558
546
  if (group.envClasses.includes("small")) {
559
547
  // A small array. Wrap in scriptstyle.
@@ -224,19 +224,19 @@ defineFunction({
224
224
  return new mathMLTree.MathNode("mrow", style) // empty label
225
225
  }
226
226
  // Abuse an <mtable> to create vertically centered content.
227
- const mtd = new mathMLTree.MathNode("mtd", [mml.buildGroup(group.label, style)])
227
+ const mrow = mml.buildGroup(group.label, style)
228
+ if (group.side === "left") {
229
+ mrow.classes.push("tml-shift-left")
230
+ }
231
+ const mtd = new mathMLTree.MathNode("mtd", [mrow])
228
232
  mtd.style.padding = "0"
229
233
  const mtr = new mathMLTree.MathNode("mtr", [mtd])
230
234
  const mtable = new mathMLTree.MathNode("mtable", [mtr])
231
235
  const label = new mathMLTree.MathNode("mpadded", [mtable])
232
236
  // Set the label width to zero so that the arrow will be centered under the corner cell.
233
- label.setAttribute("width", "0")
237
+ label.setAttribute("width", "0.1px") // Don't use 0. WebKit would hide it.
234
238
  label.setAttribute("displaystyle", "false")
235
239
  label.setAttribute("scriptlevel", "1")
236
- if (group.side === "left") {
237
- label.style.display = "flex"
238
- label.style.justifyContent = "flex-end"
239
- }
240
240
  return label;
241
241
  }
242
242
  });
@@ -20,7 +20,7 @@ const paddedNode = (group, lspace = 0.3, rspace = 0, mustSmash = false) => {
20
20
  if (mustSmash) {
21
21
  // Used for the bottom arrow in a {CD} environment
22
22
  const mpadded = new mathMLTree.MathNode("mpadded", row)
23
- mpadded.setAttribute("height", "0")
23
+ mpadded.setAttribute("height", "0.1px") // Don't use 0. WebKit would hide it.
24
24
  return mpadded
25
25
  } else {
26
26
  return new mathMLTree.MathNode("mrow", row)
@@ -115,6 +115,9 @@ const sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
115
115
 
116
116
  // Delimiter functions
117
117
  function checkDelimiter(delim, context) {
118
+ if (delim.type === "ordgroup" && delim.body.length === 1) {
119
+ delim = delim.body[0]; // Unwrap the braces
120
+ }
118
121
  const symDelim = checkSymbolNodeType(delim)
119
122
  if (symDelim && delimiters.includes(symDelim.text)) {
120
123
  // If a character is not in the MathML operator dictionary, it will not stretch.
@@ -4,26 +4,8 @@ import { assertNodeType } from "../parseNode";
4
4
  import { colorFromSpec, validateColor } from "./color"
5
5
  import * as mml from "../buildMathML";
6
6
 
7
- const padding = _ => {
8
- const node = new mathMLTree.MathNode("mspace")
9
- node.setAttribute("width", "3pt")
10
- return node
11
- }
12
-
13
7
  const mathmlBuilder = (group, style) => {
14
- let node
15
- if (group.label.indexOf("colorbox") > -1 || group.label === "\\boxed") {
16
- // MathML core does not support +width attribute in <mpadded>.
17
- // Firefox does not reliably add side padding.
18
- // Insert <mspace>
19
- node = new mathMLTree.MathNode("mrow", [
20
- padding(),
21
- mml.buildGroup(group.body, style),
22
- padding()
23
- ])
24
- } else {
25
- node = new mathMLTree.MathNode("menclose", [mml.buildGroup(group.body, style)])
26
- }
8
+ const node = new mathMLTree.MathNode("menclose", [mml.buildGroup(group.body, style)])
27
9
  switch (group.label) {
28
10
  case "\\overline":
29
11
  node.setAttribute("notation", "top") // for Firefox & WebKit
@@ -71,7 +53,7 @@ const mathmlBuilder = (group, style) => {
71
53
  case "\\boxed":
72
54
  // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} from amsmath.sty
73
55
  node.setAttribute("notation", "box")
74
- node.style.padding = "padding: 3pt 0 3pt 0"
56
+ node.style.padding = "3pt"
75
57
  node.style.border = "1px solid"
76
58
  node.setAttribute("scriptlevel", "0")
77
59
  node.setAttribute("displaystyle", "true")
@@ -88,12 +70,10 @@ const mathmlBuilder = (group, style) => {
88
70
  //const fboxsep = 3; // 3 pt from LaTeX source2e
89
71
  //node.setAttribute("height", `+${2 * fboxsep}pt`)
90
72
  //node.setAttribute("voffset", `${fboxsep}pt`)
91
- const style = { padding: "3pt 0 3pt 0" }
92
-
73
+ node.style.padding = "3pt"
93
74
  if (group.label === "\\fcolorbox") {
94
- style.border = "0.0667em solid " + String(group.borderColor)
75
+ node.style.border = "0.0667em solid " + String(group.borderColor)
95
76
  }
96
- node.style = style
97
77
  break
98
78
  }
99
79
  }
@@ -40,7 +40,7 @@ defineFunction({
40
40
  const phantomInner = mml.buildExpression(ordargument(group.body), style);
41
41
  const phantom = new mathMLTree.MathNode("mphantom", phantomInner);
42
42
  strut = new mathMLTree.MathNode("mpadded", [phantom]);
43
- strut.setAttribute("width", "0px");
43
+ strut.setAttribute("width", "0.1px") // Don't use 0. WebKit would hide it.
44
44
  }
45
45
 
46
46
  const inner = mml.buildGroup(group.body, style)
@@ -69,7 +69,7 @@ defineFunction({
69
69
  node.style.justifyContent = "center"
70
70
  }
71
71
  }
72
- node.setAttribute("width", "0px")
72
+ node.setAttribute("width", "0.1px") // Don't use 0. WebKit would hide it.
73
73
  return node
74
74
  }
75
75
  })
@@ -2,6 +2,11 @@ import defineFunction from "../defineFunction";
2
2
  import mathMLTree from "../mathMLTree";
3
3
  import * as mml from "../buildMathML";
4
4
 
5
+ // Letters that are x-height w/o a descender.
6
+ const xHeights = ['a', 'c', 'e', 'ı', 'm', 'n', 'o', 'r', 's', 'u', 'v', 'w', 'x', 'z', 'α',
7
+ 'ε', 'ι', 'κ', 'ν', 'ο', 'π', 'σ', 'τ', 'υ', 'ω', '\\alpha', '\\epsilon', "\\iota",
8
+ '\\kappa', '\\nu', '\\omega', '\\pi', '\\tau', '\\omega']
9
+
5
10
  defineFunction({
6
11
  type: "sqrt",
7
12
  names: ["\\sqrt"],
@@ -12,6 +17,20 @@ defineFunction({
12
17
  handler({ parser }, args, optArgs) {
13
18
  const index = optArgs[0];
14
19
  const body = args[0];
20
+ // Check if the body consists entirely of an x-height letter.
21
+ // TODO: Remove this check after Chromium is fixed.
22
+ if (body.body && body.body.length === 1 && body.body[0].text &&
23
+ xHeights.includes(body.body[0].text)) {
24
+ // Chromium does not put enough space above an x-height letter.
25
+ // Insert a strut.
26
+ body.body.push({
27
+ "type": "rule",
28
+ "mode": "math",
29
+ "shift": null,
30
+ "width": { "number": 0, "unit": "pt" },
31
+ "height": { "number": 0.5, "unit": "em" }
32
+ })
33
+ }
15
34
  return {
16
35
  type: "sqrt",
17
36
  mode: parser.mode,
@@ -5,7 +5,7 @@
5
5
  * https://mit-license.org/
6
6
  */
7
7
 
8
- export const version = "0.11.09";
8
+ export const version = "0.11.11";
9
9
 
10
10
  export function postProcess(block) {
11
11
  const labelMap = {}