temml 0.10.16 → 0.10.18

Sign up to get free protection for your applications and to get access to all the features.
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";