temml 0.11.8 → 0.11.10

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); }
@@ -2820,7 +2819,7 @@ const paddedNode = (group, lspace = 0.3, rspace = 0, mustSmash = false) => {
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)
@@ -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.
@@ -7963,13 +7950,25 @@ defineFunction({
7963
7950
  handler: (context, args) => {
7964
7951
  const delim = checkDelimiter(args[0], context);
7965
7952
 
7966
- return {
7953
+ const delimNode = {
7967
7954
  type: "delimsizing",
7968
7955
  mode: context.parser.mode,
7969
7956
  size: delimiterSizes[context.funcName].size,
7970
7957
  mclass: delimiterSizes[context.funcName].mclass,
7971
7958
  delim: delim.text
7972
7959
  };
7960
+ const nextToken = context.parser.fetch().text;
7961
+ if (nextToken !== "^" && nextToken !== "_") {
7962
+ return delimNode
7963
+ } else {
7964
+ // Chromium mis-renders a sized delim if it is the base of a supsub.
7965
+ // So wrap it in a ordgroup.
7966
+ return {
7967
+ type: "ordgroup",
7968
+ mode: "math",
7969
+ body: [delimNode, { type: "ordgroup", mode: "math", body: [] }]
7970
+ }
7971
+ }
7973
7972
  },
7974
7973
  mathmlBuilder: (group) => {
7975
7974
  const children = [];
@@ -9370,7 +9369,7 @@ defineFunction({
9370
9369
  const phantomInner = buildExpression(ordargument(group.body), style);
9371
9370
  const phantom = new mathMLTree.MathNode("mphantom", phantomInner);
9372
9371
  strut = new mathMLTree.MathNode("mpadded", [phantom]);
9373
- strut.setAttribute("width", "0px");
9372
+ strut.setAttribute("width", "0.1px"); // Don't use 0. WebKit would hide it.
9374
9373
  }
9375
9374
 
9376
9375
  const inner = buildGroup$1(group.body, style);
@@ -9399,7 +9398,7 @@ defineFunction({
9399
9398
  node.style.justifyContent = "center";
9400
9399
  }
9401
9400
  }
9402
- node.setAttribute("width", "0px");
9401
+ node.setAttribute("width", "0.1px"); // Don't use 0. WebKit would hide it.
9403
9402
  return node
9404
9403
  }
9405
9404
  });
@@ -10775,6 +10774,11 @@ defineFunction({
10775
10774
  }
10776
10775
  });
10777
10776
 
10777
+ // Letters that are x-height w/o a descender.
10778
+ const xHeights = ['a', 'c', 'e', 'ı', 'm', 'n', 'o', 'r', 's', 'u', 'v', 'w', 'x', 'z', 'α',
10779
+ 'ε', 'ι', 'κ', 'ν', 'ο', 'π', 'σ', 'τ', 'υ', 'ω', '\\alpha', '\\epsilon', "\\iota",
10780
+ '\\kappa', '\\nu', '\\omega', '\\pi', '\\tau', '\\omega'];
10781
+
10778
10782
  defineFunction({
10779
10783
  type: "sqrt",
10780
10784
  names: ["\\sqrt"],
@@ -10785,6 +10789,20 @@ defineFunction({
10785
10789
  handler({ parser }, args, optArgs) {
10786
10790
  const index = optArgs[0];
10787
10791
  const body = args[0];
10792
+ // Check if the body consists entirely of an x-height letter.
10793
+ // TODO: Remove this check after Chromium is fixed.
10794
+ if (body.body && body.body.length === 1 && body.body[0].text &&
10795
+ xHeights.includes(body.body[0].text)) {
10796
+ // Chromium does not put enough space above an x-height letter.
10797
+ // Insert a strut.
10798
+ body.body.push({
10799
+ "type": "rule",
10800
+ "mode": "math",
10801
+ "shift": null,
10802
+ "width": { "number": 0, "unit": "pt" },
10803
+ "height": { "number": 0.5, "unit": "em" }
10804
+ });
10805
+ }
10788
10806
  return {
10789
10807
  type: "sqrt",
10790
10808
  mode: parser.mode,
@@ -14008,7 +14026,7 @@ class Style {
14008
14026
  * https://mit-license.org/
14009
14027
  */
14010
14028
 
14011
- const version = "0.11.08";
14029
+ const version = "0.11.10";
14012
14030
 
14013
14031
  function postProcess(block) {
14014
14032
  const labelMap = {};
@@ -11,7 +11,7 @@
11
11
  * https://mit-license.org/
12
12
  */
13
13
 
14
- const version = "0.11.08";
14
+ const version = "0.11.10";
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.08",
3
+ "version": "0.11.10",
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)
@@ -159,13 +159,25 @@ defineFunction({
159
159
  handler: (context, args) => {
160
160
  const delim = checkDelimiter(args[0], context);
161
161
 
162
- return {
162
+ const delimNode = {
163
163
  type: "delimsizing",
164
164
  mode: context.parser.mode,
165
165
  size: delimiterSizes[context.funcName].size,
166
166
  mclass: delimiterSizes[context.funcName].mclass,
167
167
  delim: delim.text
168
- };
168
+ }
169
+ const nextToken = context.parser.fetch().text
170
+ if (nextToken !== "^" && nextToken !== "_") {
171
+ return delimNode
172
+ } else {
173
+ // Chromium mis-renders a sized delim if it is the base of a supsub.
174
+ // So wrap it in a ordgroup.
175
+ return {
176
+ type: "ordgroup",
177
+ mode: "math",
178
+ body: [delimNode, { type: "ordgroup", mode: "math", body: [] }]
179
+ }
180
+ }
169
181
  },
170
182
  mathmlBuilder: (group) => {
171
183
  const children = [];
@@ -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.08";
8
+ export const version = "0.11.10";
9
9
 
10
10
  export function postProcess(block) {
11
11
  const labelMap = {}