temml 0.10.16 → 0.10.18

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
@@ -1362,7 +1362,7 @@ defineSymbol(math, open, "\u00ac", "\\lnot");
1362
1362
  defineSymbol(math, textord, "\u22a4", "\\top");
1363
1363
  defineSymbol(math, textord, "\u22a5", "\\bot");
1364
1364
  defineSymbol(math, textord, "\u2205", "\\emptyset");
1365
- defineSymbol(math, textord, "\u00f8", "\\varnothing");
1365
+ defineSymbol(math, textord, "\u2300", "\\varnothing");
1366
1366
  defineSymbol(math, mathord, "\u03b1", "\\alpha", true);
1367
1367
  defineSymbol(math, mathord, "\u03b2", "\\beta", true);
1368
1368
  defineSymbol(math, mathord, "\u03b3", "\\gamma", true);
@@ -1423,6 +1423,8 @@ defineSymbol(math, bin, "\u2228", "\\vee", true);
1423
1423
  defineSymbol(math, open, "\u27e6", "\\llbracket", true); // stmaryrd/semantic packages
1424
1424
  defineSymbol(math, close, "\u27e7", "\\rrbracket", true);
1425
1425
  defineSymbol(math, open, "\u27e8", "\\langle", true);
1426
+ defineSymbol(math, open, "\u27ea", "\\lAngle", true);
1427
+ defineSymbol(math, open, "\u2989", "\\llangle", true);
1426
1428
  defineSymbol(math, open, "|", "\\lvert");
1427
1429
  defineSymbol(math, open, "\u2016", "\\lVert");
1428
1430
  defineSymbol(math, textord, "!", "\\oc"); // cmll package
@@ -1434,6 +1436,8 @@ defineSymbol(math, close, "?", "?");
1434
1436
  defineSymbol(math, close, "!", "!");
1435
1437
  defineSymbol(math, close, "‼", "‼");
1436
1438
  defineSymbol(math, close, "\u27e9", "\\rangle", true);
1439
+ defineSymbol(math, close, "\u27eb", "\\rAngle", true);
1440
+ defineSymbol(math, close, "\u298a", "\\rrangle", true);
1437
1441
  defineSymbol(math, close, "|", "\\rvert");
1438
1442
  defineSymbol(math, close, "\u2016", "\\rVert");
1439
1443
  defineSymbol(math, open, "\u2983", "\\lBrace", true); // stmaryrd/semantic packages
@@ -1515,6 +1519,8 @@ defineSymbol(math, close, "]", "\\rbrack", true);
1515
1519
  defineSymbol(text, textord, "]", "\\rbrack", true);
1516
1520
  defineSymbol(math, open, "(", "\\lparen", true);
1517
1521
  defineSymbol(math, close, ")", "\\rparen", true);
1522
+ defineSymbol(math, open, "⦇", "\\llparenthesis", true);
1523
+ defineSymbol(math, close, "⦈", "\\rrparenthesis", true);
1518
1524
  defineSymbol(text, textord, "<", "\\textless", true); // in T1 fontenc
1519
1525
  defineSymbol(text, textord, ">", "\\textgreater", true); // in T1 fontenc
1520
1526
  defineSymbol(math, open, "\u230a", "\\lfloor", true);
@@ -1552,6 +1558,7 @@ defineSymbol(math, op, "\u2211", "\\sum");
1552
1558
  defineSymbol(math, op, "\u2a02", "\\bigotimes");
1553
1559
  defineSymbol(math, op, "\u2a01", "\\bigoplus");
1554
1560
  defineSymbol(math, op, "\u2a00", "\\bigodot");
1561
+ defineSymbol(math, op, "\u2a09", "\\bigtimes");
1555
1562
  defineSymbol(math, op, "\u222e", "\\oint");
1556
1563
  defineSymbol(math, op, "\u222f", "\\oiint");
1557
1564
  defineSymbol(math, op, "\u2230", "\\oiiint");
@@ -1671,6 +1678,8 @@ defineSymbol(text, textord, "\u20ac", "\\euro", true);
1671
1678
  defineSymbol(text, textord, "\u20ac", "\\texteuro");
1672
1679
  defineSymbol(math, textord, "\u00a9", "\\copyright", true);
1673
1680
  defineSymbol(text, textord, "\u00a9", "\\textcopyright");
1681
+ defineSymbol(math, textord, "\u2300", "\\diameter", true);
1682
+ defineSymbol(text, textord, "\u2300", "\\diameter");
1674
1683
 
1675
1684
  // Italic Greek
1676
1685
  defineSymbol(math, textord, "𝛤", "\\varGamma");
@@ -1719,8 +1728,6 @@ for (let i = 0; i < letters.length; i++) {
1719
1728
  defineSymbol(math, mathord, ch, ch);
1720
1729
  defineSymbol(text, textord, ch, ch);
1721
1730
  }
1722
- // Prevent Firefox from using a dotless i.
1723
- defineSymbol(text, textord, "i\uFE0E", "i");
1724
1731
 
1725
1732
  // Some more letters in Unicode Basic Multilingual Plane.
1726
1733
  const narrow = "ÇÐÞçþℂℍℕℙℚℝℤℎℏℊℋℌℐℑℒℓ℘ℛℜℬℰℱℳℭℨ";
@@ -1964,7 +1971,7 @@ const makeText = function(text, mode, style) {
1964
1971
 
1965
1972
  const consolidateText = mrow => {
1966
1973
  // If possible, consolidate adjacent <mtext> elements into a single element.
1967
- if (mrow.type !== "mrow") { return mrow }
1974
+ if (mrow.type !== "mrow" && mrow.type !== "mstyle") { return mrow }
1968
1975
  if (mrow.children.length === 0) { return mrow } // empty group, e.g., \text{}
1969
1976
  if (!mrow.children[0].attributes || mrow.children[0].type !== "mtext") { return mrow }
1970
1977
  const variant = mrow.children[0].attributes.mathvariant || "";
@@ -2001,6 +2008,9 @@ const consolidateText = mrow => {
2001
2008
  if (L > 0 && mtext.children[0].text.charAt(L - 1) === " ") {
2002
2009
  mtext.children[0].text = mtext.children[0].text.slice(0, -1) + "\u00a0";
2003
2010
  }
2011
+ for (const [key, value] of Object.entries(mrow.attributes)) {
2012
+ mtext.attributes[key] = value;
2013
+ }
2004
2014
  return mtext
2005
2015
  };
2006
2016
 
@@ -2054,6 +2064,14 @@ const makeRow = function(body) {
2054
2064
  if (body.length === 1 && !(body[0] instanceof DocumentFragment)) {
2055
2065
  return body[0];
2056
2066
  } else {
2067
+ // Suppress spacing on <mo> nodes at both ends of the row.
2068
+ if (body[0] instanceof MathNode && body[0].type === "mo" && !body[0].attributes.fence) {
2069
+ body[0].attributes.lspace = "0em";
2070
+ }
2071
+ const end = body.length - 1;
2072
+ if (body[end] instanceof MathNode && body[end].type === "mo" && !body[end].attributes.fence) {
2073
+ body[end].attributes.rspace = "0em";
2074
+ }
2057
2075
  return new mathMLTree.MathNode("mrow", body);
2058
2076
  }
2059
2077
  };
@@ -2135,13 +2153,8 @@ const taggedExpression = (expression, tag, style, leqno) => {
2135
2153
 
2136
2154
  expression = new mathMLTree.MathNode("mtd", [expression]);
2137
2155
  const rowArray = [glue$1(), expression, glue$1()];
2138
- if (leqno) {
2139
- rowArray[0].children.push(tag);
2140
- rowArray[0].style.textAlign = "-webkit-left";
2141
- } else {
2142
- rowArray[2].children.push(tag);
2143
- rowArray[2].style.textAlign = "-webkit-right";
2144
- }
2156
+ rowArray[leqno ? 0 : 2].classes.push(leqno ? "tml-left" : "tml-right");
2157
+ rowArray[leqno ? 0 : 2].children.push(tag);
2145
2158
  const mtr = new mathMLTree.MathNode("mtr", rowArray, ["tml-tageqn"]);
2146
2159
  const table = new mathMLTree.MathNode("mtable", [mtr]);
2147
2160
  table.style.width = "100%";
@@ -2196,6 +2209,15 @@ function buildMathML(tree, texExpression, style, settings) {
2196
2209
  return math;
2197
2210
  }
2198
2211
 
2212
+ const smalls = "acegıȷmnopqrsuvwxyzαγεηικμνοπρςστυχωϕ𝐚𝐜𝐞𝐠𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐮𝐯𝐰𝐱𝐲𝐳";
2213
+ const talls = "ABCDEFGHIJKLMNOPQRSTUVWXYZbdfhkltΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩβδλζφθψ"
2214
+ + "𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙𝐛𝐝𝐟𝐡𝐤𝐥𝐭";
2215
+ const longSmalls = new Set(["\\alpha", "\\gamma", "\\delta", "\\epsilon", "\\eta", "\\iota",
2216
+ "\\kappa", "\\mu", "\\nu", "\\pi", "\\rho", "\\sigma", "\\tau", "\\upsilon", "\\chi", "\\psi",
2217
+ "\\omega", "\\imath", "\\jmath"]);
2218
+ const longTalls = new Set(["\\Gamma", "\\Delta", "\\Sigma", "\\Omega", "\\beta", "\\delta",
2219
+ "\\lambda", "\\theta", "\\psi"]);
2220
+
2199
2221
  const mathmlBuilder$a = (group, style) => {
2200
2222
  const accentNode = group.isStretchy
2201
2223
  ? stretchy.accentNode(group)
@@ -2206,6 +2228,13 @@ const mathmlBuilder$a = (group, style) => {
2206
2228
  } else {
2207
2229
  accentNode.style.mathStyle = "normal";
2208
2230
  accentNode.style.mathDepth = "0";
2231
+ if (needWebkitShift.has(group.label) && utils.isCharacterBox(group.base)) {
2232
+ let shift = "";
2233
+ const ch = group.base.text;
2234
+ if (smalls.indexOf(ch) > -1 || longSmalls.has(ch)) { shift = "tml-xshift"; }
2235
+ if (talls.indexOf(ch) > -1 || longTalls.has(ch)) { shift = "tml-capshift"; }
2236
+ if (shift) { accentNode.classes.push(shift); }
2237
+ }
2209
2238
  }
2210
2239
  if (!group.isStretchy) {
2211
2240
  accentNode.setAttribute("stretchy", "false");
@@ -2234,6 +2263,19 @@ const nonStretchyAccents = new Set([
2234
2263
  "\\mathring"
2235
2264
  ]);
2236
2265
 
2266
+ const needWebkitShift = new Set([
2267
+ "\\acute",
2268
+ "\\bar",
2269
+ "\\breve",
2270
+ "\\check",
2271
+ "\\dot",
2272
+ "\\ddot",
2273
+ "\\grave",
2274
+ "\\hat",
2275
+ "\\mathring",
2276
+ "\\'", "\\^", "\\~", "\\=", "\\u", "\\.", '\\"', "\\r", "\\H", "\\v"
2277
+ ]);
2278
+
2237
2279
  // Accents
2238
2280
  defineFunction({
2239
2281
  type: "accent",
@@ -3575,6 +3617,10 @@ const delimiters = [
3575
3617
  "\\lbrace",
3576
3618
  "\\}",
3577
3619
  "\\rbrace",
3620
+ "⦇",
3621
+ "\\llparenthesis",
3622
+ "⦈",
3623
+ "\\rrparenthesis",
3578
3624
  "\\lfloor",
3579
3625
  "\\rfloor",
3580
3626
  "\u230a",
@@ -3589,6 +3635,14 @@ const delimiters = [
3589
3635
  "\u27e8",
3590
3636
  "\\rangle",
3591
3637
  "\u27e9",
3638
+ "\\lAngle",
3639
+ "\u27ea",
3640
+ "\\rAngle",
3641
+ "\u27eb",
3642
+ "\\llangle",
3643
+ "⦉",
3644
+ "\\rrangle",
3645
+ "⦊",
3592
3646
  "\\lt",
3593
3647
  "\\gt",
3594
3648
  "\\lvert",
@@ -3710,9 +3764,9 @@ defineFunction({
3710
3764
  // defaults.
3711
3765
  node.setAttribute("fence", "false");
3712
3766
  }
3713
- if (group.delim === "\u2216" || group.delim.indexOf("arrow") > -1) {
3714
- // \backslash is not in the operator dictionary,
3715
- // so we have to explicitly set stretchy to true.
3767
+ if (group.delim === "\u2216" || group.delim === "\\vert" ||
3768
+ group.delim === "|" || group.delim.indexOf("arrow") > -1) {
3769
+ // We have to explicitly set stretchy to true.
3716
3770
  node.setAttribute("stretchy", "true");
3717
3771
  }
3718
3772
  node.setAttribute("symmetric", "true"); // Needed for tall arrows in Firefox.
@@ -3903,7 +3957,10 @@ rgba(0,0,0,0) 100%);`;
3903
3957
  node.style.marginRight = "0.03889em";
3904
3958
  break
3905
3959
  case "\\sout":
3906
- node.style["text-decoration"] = "line-through 0.08em solid";
3960
+ node.style.backgroundImage = 'linear-gradient(black, black)';
3961
+ node.style.backgroundRepeat = 'no-repeat';
3962
+ node.style.backgroundSize = '100% 1.5px';
3963
+ node.style.backgroundPosition = '0 center';
3907
3964
  break
3908
3965
  case "\\boxed":
3909
3966
  // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} from amsmath.sty
@@ -4154,8 +4211,9 @@ const getTag = (group, style, rowNum) => {
4154
4211
  return tag
4155
4212
  } else {
4156
4213
  // AMS automatcally numbered equaton.
4157
- // Insert a class so the element can be populated by a post-processor.
4158
- tag = new mathMLTree.MathNode("mtext", [], ["tml-eqn"]);
4214
+ // Insert a class so the element can be populated by a CSS counter.
4215
+ // WebKit will display the CSS counter only inside a span.
4216
+ tag = new mathMLTree.MathNode("mtext", [new Span(["tml-eqn"])]);
4159
4217
  }
4160
4218
  return tag
4161
4219
  };
@@ -4352,7 +4410,7 @@ const mathmlBuilder$7 = function(group, style) {
4352
4410
  const align = i === 0 ? "left" : i === numRows - 1 ? "right" : "center";
4353
4411
  mtd.setAttribute("columnalign", align);
4354
4412
  if (align !== "center") {
4355
- mtd.style.textAlign = "-webkit-" + align;
4413
+ mtd.classes.push("tml-" + align);
4356
4414
  }
4357
4415
  }
4358
4416
  row.push(mtd);
@@ -4363,10 +4421,10 @@ const mathmlBuilder$7 = function(group, style) {
4363
4421
  const tag = getTag(group, style.withLevel(cellLevel), i);
4364
4422
  if (group.leqno) {
4365
4423
  row[0].children.push(tag);
4366
- row[0].style.textAlign = "-webkit-left";
4424
+ row[0].classes.push("tml-left");
4367
4425
  } else {
4368
4426
  row[row.length - 1].children.push(tag);
4369
- row[row.length - 1].style.textAlign = "-webkit-right";
4427
+ row[row.length - 1].classes.push("tml-right");
4370
4428
  }
4371
4429
  }
4372
4430
  const mtr = new mathMLTree.MathNode("mtr", row, []);
@@ -4437,11 +4495,11 @@ const mathmlBuilder$7 = function(group, style) {
4437
4495
  for (let j = 0; j < row.children.length; j++) {
4438
4496
  // Chromium does not recognize text-align: left. Use -webkit-
4439
4497
  // TODO: Remove -webkit- when Chromium no longer needs it.
4440
- row.children[j].style.textAlign = "-webkit-" + (j % 2 ? "left" : "right");
4498
+ row.children[j].classes = ["tml-" + (j % 2 ? "left" : "right")];
4441
4499
  }
4442
4500
  if (group.addEqnNum) {
4443
4501
  const k = group.leqno ? 0 : row.children.length - 1;
4444
- row.children[k].style.textAlign = "-webkit-" + (group.leqno ? "left" : "right");
4502
+ row.children[k].classes = ["tml-" + (group.leqno ? "left" : "right")];
4445
4503
  }
4446
4504
  }
4447
4505
  if (row.children.length > 1 && group.envClasses.includes("cases")) {
@@ -4450,7 +4508,7 @@ const mathmlBuilder$7 = function(group, style) {
4450
4508
 
4451
4509
  if (group.envClasses.includes("cases") || group.envClasses.includes("subarray")) {
4452
4510
  for (const cell of row.children) {
4453
- cell.style.textAlign = "-webkit-" + "left";
4511
+ cell.classes.push("tml-left");
4454
4512
  }
4455
4513
  }
4456
4514
  }
@@ -4505,7 +4563,7 @@ const mathmlBuilder$7 = function(group, style) {
4505
4563
  iCol += 1;
4506
4564
  for (const row of table.children) {
4507
4565
  if (colAlign.trim() !== "center" && iCol < row.children.length) {
4508
- row.children[iCol].style.textAlign = "-webkit-" + colAlign.trim();
4566
+ row.children[iCol].classes = ["tml-" + colAlign.trim()];
4509
4567
  }
4510
4568
  }
4511
4569
  prevTypeWasAlign = true;
@@ -5498,6 +5556,33 @@ defineFunction({
5498
5556
  mathmlBuilder: mathmlBuilder$5
5499
5557
  });
5500
5558
 
5559
+ // \hbox is provided for compatibility with LaTeX functions that act on a box.
5560
+ // This function by itself doesn't do anything but set scriptlevel to \textstyle
5561
+ // and prevent a soft line break.
5562
+
5563
+ defineFunction({
5564
+ type: "hbox",
5565
+ names: ["\\hbox"],
5566
+ props: {
5567
+ numArgs: 1,
5568
+ argTypes: ["hbox"],
5569
+ allowedInArgument: true,
5570
+ allowedInText: false
5571
+ },
5572
+ handler({ parser }, args) {
5573
+ return {
5574
+ type: "hbox",
5575
+ mode: parser.mode,
5576
+ body: ordargument(args[0])
5577
+ };
5578
+ },
5579
+ mathmlBuilder(group, style) {
5580
+ const newStyle = style.withLevel(StyleLevel.TEXT);
5581
+ const mrow = buildExpressionRow(group.body, newStyle);
5582
+ return consolidateText(mrow)
5583
+ }
5584
+ });
5585
+
5501
5586
  const mathmlBuilder$4 = (group, style) => {
5502
5587
  const accentNode = stretchy.mathMLnode(group.label);
5503
5588
  accentNode.style["math-depth"] = 0;
@@ -6467,7 +6552,8 @@ const singleCharBigOps = {
6467
6552
  "\u2a02": "\\bigotimes",
6468
6553
  "\u2a04": "\\biguplus",
6469
6554
  "\u2a05": "\\bigsqcap",
6470
- "\u2a06": "\\bigsqcup"
6555
+ "\u2a06": "\\bigsqcup",
6556
+ "\u2a09": "\\bigtimes"
6471
6557
  };
6472
6558
 
6473
6559
  defineFunction({
@@ -6487,6 +6573,7 @@ defineFunction({
6487
6573
  "\\bigodot",
6488
6574
  "\\bigsqcap",
6489
6575
  "\\bigsqcup",
6576
+ "\\bigtimes",
6490
6577
  "\\smallint",
6491
6578
  "\u220F",
6492
6579
  "\u2210",
@@ -8582,8 +8669,6 @@ defineMacro("\\surd", '\\sqrt{\\vphantom{|}}');
8582
8669
  // See comment for \oplus in symbols.js.
8583
8670
  defineMacro("\u2295", "\\oplus");
8584
8671
 
8585
- defineMacro("\\hbox", "\\text{#1}");
8586
-
8587
8672
  // Per TeXbook p.122, "/" gets zero operator spacing.
8588
8673
  // And MDN recommends using U+2044 instead of / for inline
8589
8674
  defineMacro("/", "{\u2044}");
@@ -8666,6 +8751,7 @@ const dotsByToken = {
8666
8751
  "\\bigodot": "\\dotsb",
8667
8752
  "\\bigsqcap": "\\dotsb",
8668
8753
  "\\bigsqcup": "\\dotsb",
8754
+ "\\bigtimes": "\\dotsb",
8669
8755
  "\\And": "\\dotsb",
8670
8756
  "\\longrightarrow": "\\dotsb",
8671
8757
  "\\Longrightarrow": "\\dotsb",
@@ -13059,7 +13145,7 @@ class Style {
13059
13145
  * https://mit-license.org/
13060
13146
  */
13061
13147
 
13062
- const version = "0.10.16";
13148
+ const version = "0.10.18";
13063
13149
 
13064
13150
  function postProcess(block) {
13065
13151
  const labelMap = {};
@@ -13114,9 +13200,9 @@ function postProcess(block) {
13114
13200
  * Parse and build an expression, and place that expression in the DOM node
13115
13201
  * given.
13116
13202
  */
13117
- let render = function(expression, baseNode, options) {
13203
+ let render = function(expression, baseNode, options = {}) {
13118
13204
  baseNode.textContent = "";
13119
- const alreadyInMathElement = baseNode.tagName === "MATH";
13205
+ const alreadyInMathElement = baseNode.tagName.toLowerCase() === "math";
13120
13206
  if (alreadyInMathElement) { options.wrap = "none"; }
13121
13207
  const math = renderToMathMLTree(expression, options);
13122
13208
  if (alreadyInMathElement) {
@@ -14,7 +14,7 @@
14
14
  * https://mit-license.org/
15
15
  */
16
16
 
17
- const version = "0.10.16";
17
+ const version = "0.10.18";
18
18
 
19
19
  function postProcess(block) {
20
20
  const labelMap = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "temml",
3
- "version": "0.10.16",
3
+ "version": "0.10.18",
4
4
  "description": "TeX to MathML conversion in JavaScript.",
5
5
  "main": "dist/temml.js",
6
6
  "engines": {
@@ -36,7 +36,7 @@ export const makeText = function(text, mode, style) {
36
36
 
37
37
  export const consolidateText = mrow => {
38
38
  // If possible, consolidate adjacent <mtext> elements into a single element.
39
- if (mrow.type !== "mrow") { return mrow }
39
+ if (mrow.type !== "mrow" && mrow.type !== "mstyle") { return mrow }
40
40
  if (mrow.children.length === 0) { return mrow } // empty group, e.g., \text{}
41
41
  if (!mrow.children[0].attributes || mrow.children[0].type !== "mtext") { return mrow }
42
42
  const variant = mrow.children[0].attributes.mathvariant || ""
@@ -73,6 +73,9 @@ export const consolidateText = mrow => {
73
73
  if (L > 0 && mtext.children[0].text.charAt(L - 1) === " ") {
74
74
  mtext.children[0].text = mtext.children[0].text.slice(0, -1) + "\u00a0"
75
75
  }
76
+ for (const [key, value] of Object.entries(mrow.attributes)) {
77
+ mtext.attributes[key] = value
78
+ }
76
79
  return mtext
77
80
  }
78
81
 
@@ -126,6 +129,14 @@ export const makeRow = function(body) {
126
129
  if (body.length === 1 && !(body[0] instanceof DocumentFragment)) {
127
130
  return body[0];
128
131
  } else {
132
+ // Suppress spacing on <mo> nodes at both ends of the row.
133
+ if (body[0] instanceof MathNode && body[0].type === "mo" && !body[0].attributes.fence) {
134
+ body[0].attributes.lspace = "0em"
135
+ }
136
+ const end = body.length - 1
137
+ if (body[end] instanceof MathNode && body[end].type === "mo" && !body[end].attributes.fence) {
138
+ body[end].attributes.rspace = "0em"
139
+ }
129
140
  return new mathMLTree.MathNode("mrow", body);
130
141
  }
131
142
  };
@@ -207,13 +218,8 @@ const taggedExpression = (expression, tag, style, leqno) => {
207
218
 
208
219
  expression = new mathMLTree.MathNode("mtd", [expression])
209
220
  const rowArray = [glue(), expression, glue()]
210
- if (leqno) {
211
- rowArray[0].children.push(tag)
212
- rowArray[0].style.textAlign = "-webkit-left"
213
- } else {
214
- rowArray[2].children.push(tag)
215
- rowArray[2].style.textAlign = "-webkit-right"
216
- }
221
+ rowArray[leqno ? 0 : 2].classes.push(leqno ? "tml-left" : "tml-right")
222
+ rowArray[leqno ? 0 : 2].children.push(tag)
217
223
  const mtr = new mathMLTree.MathNode("mtr", rowArray, ["tml-tageqn"])
218
224
  const table = new mathMLTree.MathNode("mtable", [mtr])
219
225
  table.style.width = "100%"
@@ -2,6 +2,7 @@ import defineEnvironment from "../defineEnvironment";
2
2
  import { parseCD } from "./cd";
3
3
  import defineFunction from "../defineFunction";
4
4
  import mathMLTree from "../mathMLTree";
5
+ import { Span } from "../domTree"
5
6
  import { StyleLevel } from "../constants"
6
7
  import ParseError from "../ParseError";
7
8
  import { assertNodeType, assertSymbolNodeType } from "../parseNode";
@@ -57,8 +58,9 @@ const getTag = (group, style, rowNum) => {
57
58
  return tag
58
59
  } else {
59
60
  // AMS automatcally numbered equaton.
60
- // Insert a class so the element can be populated by a post-processor.
61
- tag = new mathMLTree.MathNode("mtext", [], ["tml-eqn"])
61
+ // Insert a class so the element can be populated by a CSS counter.
62
+ // WebKit will display the CSS counter only inside a span.
63
+ tag = new mathMLTree.MathNode("mtext", [new Span(["tml-eqn"])])
62
64
  }
63
65
  return tag
64
66
  }
@@ -255,7 +257,7 @@ const mathmlBuilder = function(group, style) {
255
257
  const align = i === 0 ? "left" : i === numRows - 1 ? "right" : "center"
256
258
  mtd.setAttribute("columnalign", align)
257
259
  if (align !== "center") {
258
- mtd.style.textAlign = "-webkit-" + align
260
+ mtd.classes.push("tml-" + align)
259
261
  }
260
262
  }
261
263
  row.push(mtd)
@@ -266,10 +268,10 @@ const mathmlBuilder = function(group, style) {
266
268
  const tag = getTag(group, style.withLevel(cellLevel), i)
267
269
  if (group.leqno) {
268
270
  row[0].children.push(tag)
269
- row[0].style.textAlign = "-webkit-left"
271
+ row[0].classes.push("tml-left")
270
272
  } else {
271
273
  row[row.length - 1].children.push(tag)
272
- row[row.length - 1].style.textAlign = "-webkit-right"
274
+ row[row.length - 1].classes.push("tml-right")
273
275
  }
274
276
  }
275
277
  const mtr = new mathMLTree.MathNode("mtr", row, [])
@@ -340,11 +342,11 @@ const mathmlBuilder = function(group, style) {
340
342
  for (let j = 0; j < row.children.length; j++) {
341
343
  // Chromium does not recognize text-align: left. Use -webkit-
342
344
  // TODO: Remove -webkit- when Chromium no longer needs it.
343
- row.children[j].style.textAlign = "-webkit-" + (j % 2 ? "left" : "right")
345
+ row.children[j].classes = ["tml-" + (j % 2 ? "left" : "right")]
344
346
  }
345
347
  if (group.addEqnNum) {
346
348
  const k = group.leqno ? 0 : row.children.length - 1
347
- row.children[k].style.textAlign = "-webkit-" + (group.leqno ? "left" : "right")
349
+ row.children[k].classes = ["tml-" + (group.leqno ? "left" : "right")]
348
350
  }
349
351
  }
350
352
  if (row.children.length > 1 && group.envClasses.includes("cases")) {
@@ -353,7 +355,7 @@ const mathmlBuilder = function(group, style) {
353
355
 
354
356
  if (group.envClasses.includes("cases") || group.envClasses.includes("subarray")) {
355
357
  for (const cell of row.children) {
356
- cell.style.textAlign = "-webkit-" + "left"
358
+ cell.classes.push("tml-left")
357
359
  }
358
360
  }
359
361
  }
@@ -408,7 +410,7 @@ const mathmlBuilder = function(group, style) {
408
410
  iCol += 1
409
411
  for (const row of table.children) {
410
412
  if (colAlign.trim() !== "center" && iCol < row.children.length) {
411
- row.children[iCol].style.textAlign = "-webkit-" + colAlign.trim()
413
+ row.children[iCol].classes = ["tml-" + colAlign.trim()]
412
414
  }
413
415
  }
414
416
  prevTypeWasAlign = true;
@@ -2,6 +2,16 @@ import defineFunction, { normalizeArgument } from "../defineFunction"
2
2
  import mathMLTree from "../mathMLTree"
3
3
  import stretchy from "../stretchy"
4
4
  import * as mml from "../buildMathML"
5
+ import utils from "../utils"
6
+
7
+ const smalls = "acegıȷmnopqrsuvwxyzαγεηικμνοπρςστυχωϕ𝐚𝐜𝐞𝐠𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐮𝐯𝐰𝐱𝐲𝐳"
8
+ const talls = "ABCDEFGHIJKLMNOPQRSTUVWXYZbdfhkltΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩβδλζφθψ"
9
+ + "𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙𝐛𝐝𝐟𝐡𝐤𝐥𝐭"
10
+ const longSmalls = new Set(["\\alpha", "\\gamma", "\\delta", "\\epsilon", "\\eta", "\\iota",
11
+ "\\kappa", "\\mu", "\\nu", "\\pi", "\\rho", "\\sigma", "\\tau", "\\upsilon", "\\chi", "\\psi",
12
+ "\\omega", "\\imath", "\\jmath"])
13
+ const longTalls = new Set(["\\Gamma", "\\Delta", "\\Sigma", "\\Omega", "\\beta", "\\delta",
14
+ "\\lambda", "\\theta", "\\psi"])
5
15
 
6
16
  const mathmlBuilder = (group, style) => {
7
17
  const accentNode = group.isStretchy
@@ -13,6 +23,13 @@ const mathmlBuilder = (group, style) => {
13
23
  } else {
14
24
  accentNode.style.mathStyle = "normal"
15
25
  accentNode.style.mathDepth = "0"
26
+ if (needWebkitShift.has(group.label) && utils.isCharacterBox(group.base)) {
27
+ let shift = ""
28
+ const ch = group.base.text
29
+ if (smalls.indexOf(ch) > -1 || longSmalls.has(ch)) { shift = "tml-xshift" }
30
+ if (talls.indexOf(ch) > -1 || longTalls.has(ch)) { shift = "tml-capshift" }
31
+ if (shift) { accentNode.classes.push(shift) }
32
+ }
16
33
  }
17
34
  if (!group.isStretchy) {
18
35
  accentNode.setAttribute("stretchy", "false")
@@ -41,6 +58,19 @@ const nonStretchyAccents = new Set([
41
58
  "\\mathring"
42
59
  ])
43
60
 
61
+ const needWebkitShift = new Set([
62
+ "\\acute",
63
+ "\\bar",
64
+ "\\breve",
65
+ "\\check",
66
+ "\\dot",
67
+ "\\ddot",
68
+ "\\grave",
69
+ "\\hat",
70
+ "\\mathring",
71
+ "\\'", "\\^", "\\~", "\\=", "\\u", "\\.", '\\"', "\\r", "\\H", "\\v"
72
+ ])
73
+
44
74
  // Accents
45
75
  defineFunction({
46
76
  type: "accent",
@@ -38,6 +38,10 @@ export const delimiters = [
38
38
  "\\lbrace",
39
39
  "\\}",
40
40
  "\\rbrace",
41
+ "⦇",
42
+ "\\llparenthesis",
43
+ "⦈",
44
+ "\\rrparenthesis",
41
45
  "\\lfloor",
42
46
  "\\rfloor",
43
47
  "\u230a",
@@ -52,6 +56,14 @@ export const delimiters = [
52
56
  "\u27e8",
53
57
  "\\rangle",
54
58
  "\u27e9",
59
+ "\\lAngle",
60
+ "\u27ea",
61
+ "\\rAngle",
62
+ "\u27eb",
63
+ "\\llangle",
64
+ "⦉",
65
+ "\\rrangle",
66
+ "⦊",
55
67
  "\\lt",
56
68
  "\\gt",
57
69
  "\\lvert",
@@ -173,9 +185,9 @@ defineFunction({
173
185
  // defaults.
174
186
  node.setAttribute("fence", "false");
175
187
  }
176
- if (group.delim === "\u2216" || group.delim.indexOf("arrow") > -1) {
177
- // \backslash is not in the operator dictionary,
178
- // so we have to explicitly set stretchy to true.
188
+ if (group.delim === "\u2216" || group.delim === "\\vert" ||
189
+ group.delim === "|" || group.delim.indexOf("arrow") > -1) {
190
+ // We have to explicitly set stretchy to true.
179
191
  node.setAttribute("stretchy", "true")
180
192
  }
181
193
  node.setAttribute("symmetric", "true"); // Needed for tall arrows in Firefox.
@@ -63,7 +63,10 @@ rgba(0,0,0,0) 100%);`
63
63
  node.style.marginRight = "0.03889em"
64
64
  break
65
65
  case "\\sout":
66
- node.style["text-decoration"] = "line-through 0.08em solid"
66
+ node.style.backgroundImage = 'linear-gradient(black, black)'
67
+ node.style.backgroundRepeat = 'no-repeat'
68
+ node.style.backgroundSize = '100% 1.5px'
69
+ node.style.backgroundPosition = '0 center'
67
70
  break
68
71
  case "\\boxed":
69
72
  // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} from amsmath.sty
@@ -1,10 +1,10 @@
1
1
  import defineFunction, { ordargument } from "../defineFunction";
2
2
  import { StyleLevel } from "../constants"
3
- import mathMLTree from "../mathMLTree";
4
3
  import * as mml from "../buildMathML";
5
4
 
6
5
  // \hbox is provided for compatibility with LaTeX functions that act on a box.
7
- // This function by itself doesn't do anything but prevent a soft line break.
6
+ // This function by itself doesn't do anything but set scriptlevel to \textstyle
7
+ // and prevent a soft line break.
8
8
 
9
9
  defineFunction({
10
10
  type: "hbox",
@@ -23,7 +23,8 @@ defineFunction({
23
23
  };
24
24
  },
25
25
  mathmlBuilder(group, style) {
26
- const newOptions = style.withLevel(StyleLevel.TEXT)
27
- return new mathMLTree.MathNode("mrow", mml.buildExpression(group.body, newOptions));
26
+ const newStyle = style.withLevel(StyleLevel.TEXT)
27
+ const mrow = mml.buildExpressionRow(group.body, newStyle)
28
+ return mml.consolidateText(mrow)
28
29
  }
29
30
  });
@@ -4,7 +4,7 @@ import mathMLTree from "../mathMLTree"
4
4
  import * as mml from "../buildMathML"
5
5
  import ParseError from "../ParseError";
6
6
 
7
- const textModeLap = ["\\clap", "\\llap", "\\rlap"]
7
+ const textModeLap = ["\\clap", "\\llap", "\\rlap"];
8
8
 
9
9
  defineFunction({
10
10
  type: "lap",
@@ -71,7 +71,8 @@ const singleCharBigOps = {
71
71
  "\u2a02": "\\bigotimes",
72
72
  "\u2a04": "\\biguplus",
73
73
  "\u2a05": "\\bigsqcap",
74
- "\u2a06": "\\bigsqcup"
74
+ "\u2a06": "\\bigsqcup",
75
+ "\u2a09": "\\bigtimes"
75
76
  };
76
77
 
77
78
  defineFunction({
@@ -91,6 +92,7 @@ defineFunction({
91
92
  "\\bigodot",
92
93
  "\\bigsqcap",
93
94
  "\\bigsqcup",
95
+ "\\bigtimes",
94
96
  "\\smallint",
95
97
  "\u220F",
96
98
  "\u2210",
package/src/functions.js CHANGED
@@ -21,6 +21,7 @@ import "./functions/environment";
21
21
  import "./functions/envTag";
22
22
  import "./functions/font";
23
23
  import "./functions/genfrac";
24
+ import "./functions/hbox";
24
25
  import "./functions/horizBrace";
25
26
  import "./functions/href";
26
27
  import "./functions/html";