temml 0.10.18 → 0.10.20

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.js CHANGED
@@ -941,8 +941,8 @@ var temml = (function () {
941
941
  defineSymbol(math, textord, "\u266d", "\\flat", true);
942
942
  defineSymbol(math, textord, "\u2113", "\\ell", true);
943
943
  defineSymbol(math, textord, "\u266e", "\\natural", true);
944
- defineSymbol(math, textord, "Å", "\\AA", true);
945
- defineSymbol(text, textord, "Å", "\\AA", true);
944
+ defineSymbol(math, textord, "Å", "\\Angstrom", true);
945
+ defineSymbol(text, textord, "Å", "\\Angstrom", true);
946
946
  defineSymbol(math, textord, "\u2663", "\\clubsuit", true);
947
947
  defineSymbol(math, textord, "\u2667", "\\varclubsuit", true);
948
948
  defineSymbol(math, textord, "\u2118", "\\wp", true);
@@ -2056,6 +2056,16 @@ var temml = (function () {
2056
2056
  expression[nums[i].start].text += expression[j].text;
2057
2057
  }
2058
2058
  expression.splice(nums[i].start + 1, nums[i].end - nums[i].start);
2059
+ // Check if the <mn> is followed by a numeric base in a supsub, e.g. the "3" in 123^4
2060
+ // If so, merge the first <mn> into the base.
2061
+ if (expression.length > nums[i].start + 1) {
2062
+ const nextTerm = expression[nums[i].start + 1];
2063
+ if (nextTerm.type === "supsub" && nextTerm.base && nextTerm.base.type === "textord" &&
2064
+ numberRegEx$1.test(nextTerm.base.text)) {
2065
+ nextTerm.base.text = expression[nums[i].start].text + nextTerm.base.text;
2066
+ expression.splice(nums[i].start, 1);
2067
+ }
2068
+ }
2059
2069
  }
2060
2070
  };
2061
2071
 
@@ -2063,20 +2073,22 @@ var temml = (function () {
2063
2073
  * Wrap the given array of nodes in an <mrow> node if needed, i.e.,
2064
2074
  * unless the array has length 1. Always returns a single node.
2065
2075
  */
2066
- const makeRow = function(body) {
2076
+ const makeRow = function(body, semisimple = false) {
2067
2077
  if (body.length === 1 && !(body[0] instanceof DocumentFragment)) {
2068
2078
  return body[0];
2069
- } else {
2079
+ } else if (!semisimple) {
2070
2080
  // Suppress spacing on <mo> nodes at both ends of the row.
2071
2081
  if (body[0] instanceof MathNode && body[0].type === "mo" && !body[0].attributes.fence) {
2072
2082
  body[0].attributes.lspace = "0em";
2083
+ body[0].attributes.rspace = "0em";
2073
2084
  }
2074
2085
  const end = body.length - 1;
2075
2086
  if (body[end] instanceof MathNode && body[end].type === "mo" && !body[end].attributes.fence) {
2087
+ body[end].attributes.lspace = "0em";
2076
2088
  body[end].attributes.rspace = "0em";
2077
2089
  }
2078
- return new mathMLTree.MathNode("mrow", body);
2079
2090
  }
2091
+ return new mathMLTree.MathNode("mrow", body);
2080
2092
  };
2081
2093
 
2082
2094
  const isRel = item => {
@@ -2090,10 +2102,10 @@ var temml = (function () {
2090
2102
  * (1) Suppress spacing when an author wraps an operator w/braces, as in {=}.
2091
2103
  * (2) Suppress spacing between two adjacent relations.
2092
2104
  */
2093
- const buildExpression = function(expression, style, isOrdgroup) {
2094
- if (expression.length === 1) {
2105
+ const buildExpression = function(expression, style, semisimple = false) {
2106
+ if (!semisimple && expression.length === 1) {
2095
2107
  const group = buildGroup$1(expression[0], style);
2096
- if (isOrdgroup && group instanceof MathNode && group.type === "mo") {
2108
+ if (group instanceof MathNode && group.type === "mo") {
2097
2109
  // When TeX writers want to suppress spacing on an operator,
2098
2110
  // they often put the operator by itself inside braces.
2099
2111
  group.setAttribute("lspace", "0em");
@@ -2123,8 +2135,8 @@ var temml = (function () {
2123
2135
  * Equivalent to buildExpression, but wraps the elements in an <mrow>
2124
2136
  * if there's more than one. Returns a single node instead of an array.
2125
2137
  */
2126
- const buildExpressionRow = function(expression, style, isOrdgroup) {
2127
- return makeRow(buildExpression(expression, style, isOrdgroup));
2138
+ const buildExpressionRow = function(expression, style, semisimple = false) {
2139
+ return makeRow(buildExpression(expression, style, semisimple), semisimple);
2128
2140
  };
2129
2141
 
2130
2142
  /**
@@ -2809,7 +2821,8 @@ var temml = (function () {
2809
2821
  const arrowGroup = {
2810
2822
  type: "ordgroup",
2811
2823
  mode: "math",
2812
- body: [leftLabel, sizedArrow, rightLabel]
2824
+ body: [leftLabel, sizedArrow, rightLabel],
2825
+ semisimple: true
2813
2826
  };
2814
2827
  return parser.callFunction("\\\\cdparent", [arrowGroup], []);
2815
2828
  }
@@ -3931,20 +3944,12 @@ var temml = (function () {
3931
3944
  node.style.borderBottom = "0.065em solid";
3932
3945
  break
3933
3946
  case "\\cancel":
3934
- node.style.background = `linear-gradient(to top left,
3935
- rgba(0,0,0,0) 0%,
3936
- rgba(0,0,0,0) calc(50% - 0.06em),
3937
- rgba(0,0,0,1) 50%,
3938
- rgba(0,0,0,0) calc(50% + 0.06em),
3939
- rgba(0,0,0,0) 100%);`;
3947
+ // We can't use an inline background-gradient. It does not work client-side.
3948
+ // So set a class and put the rule in the external CSS file.
3949
+ node.classes.push("tml-cancel");
3940
3950
  break
3941
3951
  case "\\bcancel":
3942
- node.style.background = `linear-gradient(to top right,
3943
- rgba(0,0,0,0) 0%,
3944
- rgba(0,0,0,0) calc(50% - 0.06em),
3945
- rgba(0,0,0,1) 50%,
3946
- rgba(0,0,0,0) calc(50% + 0.06em),
3947
- rgba(0,0,0,0) 100%);`;
3952
+ node.classes.push("tml-bcancel");
3948
3953
  break
3949
3954
  /*
3950
3955
  case "\\longdiv":
@@ -3991,18 +3996,7 @@ rgba(0,0,0,0) 100%);`;
3991
3996
  break
3992
3997
  }
3993
3998
  case "\\xcancel":
3994
- node.style.background = `linear-gradient(to top left,
3995
- rgba(0,0,0,0) 0%,
3996
- rgba(0,0,0,0) calc(50% - 0.06em),
3997
- rgba(0,0,0,1) 50%,
3998
- rgba(0,0,0,0) calc(50% + 0.06em),
3999
- rgba(0,0,0,0) 100%),
4000
- linear-gradient(to top right,
4001
- rgba(0,0,0,0) 0%,
4002
- rgba(0,0,0,0) calc(50% - 0.06em),
4003
- rgba(0,0,0,1) 50%,
4004
- rgba(0,0,0,0) calc(50% + 0.06em),
4005
- rgba(0,0,0,0) 100%);`;
3999
+ node.classes.push("tml-xcancel");
4006
4000
  break
4007
4001
  }
4008
4002
  if (group.backgroundColor) {
@@ -4200,7 +4194,7 @@ rgba(0,0,0,0) 100%);`;
4200
4194
  if (tagContents) {
4201
4195
  // The author has written a \tag or a \notag in this row.
4202
4196
  if (tagContents.body) {
4203
- tag = buildExpressionRow(tagContents.body, style);
4197
+ tag = buildExpressionRow(tagContents.body, style, true);
4204
4198
  tag.classes = ["tml-tag"];
4205
4199
  } else {
4206
4200
  // \notag. Return an empty span.
@@ -4247,7 +4241,9 @@ rgba(0,0,0,0) 100%);`;
4247
4241
  parser.gullet.macros.set("\\cr", "\\\\\\relax");
4248
4242
  }
4249
4243
  if (addEqnNum) {
4250
- parser.gullet.macros.set("\\tag", "\\env@tag{\\text{#1}}");
4244
+ parser.gullet.macros.set("\\tag", "\\@ifstar\\envtag@literal\\envtag@paren");
4245
+ parser.gullet.macros.set("\\envtag@paren", "\\env@tag{{(\\text{#1})}}");
4246
+ parser.gullet.macros.set("\\envtag@literal", "\\env@tag{\\text{#1}}");
4251
4247
  parser.gullet.macros.set("\\notag", "\\env@notag");
4252
4248
  parser.gullet.macros.set("\\nonumber", "\\env@notag");
4253
4249
  }
@@ -4288,7 +4284,8 @@ rgba(0,0,0,0) 100%);`;
4288
4284
  cell = {
4289
4285
  type: "ordgroup",
4290
4286
  mode: parser.mode,
4291
- body: cell
4287
+ body: cell,
4288
+ semisimple: true
4292
4289
  };
4293
4290
  row.push(cell);
4294
4291
  const next = parser.fetch().text;
@@ -5121,7 +5118,7 @@ rgba(0,0,0,0) 100%);`;
5121
5118
  const mathGroup = buildGroup$1(group.body, newStyle);
5122
5119
 
5123
5120
  if (mathGroup.children.length === 0) { return mathGroup } // empty group, e.g., \mathrm{}
5124
- if (font === "boldsymbol" && ["mo", "mpadded"].includes(mathGroup.type)) {
5121
+ if (font === "boldsymbol" && ["mo", "mpadded", "mrow"].includes(mathGroup.type)) {
5125
5122
  mathGroup.style.fontWeight = "bold";
5126
5123
  return mathGroup
5127
5124
  }
@@ -6478,10 +6475,10 @@ rgba(0,0,0,0) 100%);`;
6478
6475
  },
6479
6476
  mathmlBuilder(group, style) {
6480
6477
  if (group.isCharacterBox) {
6481
- const inner = buildExpression(group.body, style);
6478
+ const inner = buildExpression(group.body, style, true);
6482
6479
  return inner[0]
6483
6480
  } else {
6484
- return buildExpressionRow(group.body, style, true)
6481
+ return buildExpressionRow(group.body, style)
6485
6482
  }
6486
6483
  }
6487
6484
  });
@@ -6501,6 +6498,13 @@ rgba(0,0,0,0) 100%);`;
6501
6498
  // NOTE: Unlike most `builders`s, this one handles not only "op", but also
6502
6499
  // "supsub" since some of them (like \int) can affect super/subscripting.
6503
6500
 
6501
+ const setSpacing = node => {
6502
+ // The user wrote a \mathop{…} function. Change spacing from default to OP spacing.
6503
+ // The most likely spacing for an OP is a thin space per TeXbook p170.
6504
+ node.attributes.lspace = "0.1667em";
6505
+ node.attributes.rspace = "0.1667em";
6506
+ };
6507
+
6504
6508
  const mathmlBuilder$2 = (group, style) => {
6505
6509
  let node;
6506
6510
 
@@ -6512,9 +6516,11 @@ rgba(0,0,0,0) 100%);`;
6512
6516
  } else {
6513
6517
  node.setAttribute("movablelimits", "false");
6514
6518
  }
6519
+ if (group.fromMathOp) { setSpacing(node); }
6515
6520
  } else if (group.body) {
6516
6521
  // This is an operator with children. Add them.
6517
6522
  node = new MathNode("mo", buildExpression(group.body, style));
6523
+ if (group.fromMathOp) { setSpacing(node); }
6518
6524
  } else {
6519
6525
  // This is a text operator. Add all of the characters from the operator's name.
6520
6526
  node = new MathNode("mi", [new TextNode(group.name.slice(1))]);
@@ -6634,6 +6640,7 @@ rgba(0,0,0,0) 100%);`;
6634
6640
  limits: true,
6635
6641
  parentIsSupSub: false,
6636
6642
  symbol: isSymbol,
6643
+ fromMathOp: true,
6637
6644
  stack: false,
6638
6645
  name: isSymbol ? arr[0].text : null,
6639
6646
  body: isSymbol ? null : ordargument(body)
@@ -6967,7 +6974,7 @@ rgba(0,0,0,0) 100%);`;
6967
6974
  defineFunctionBuilders({
6968
6975
  type: "ordgroup",
6969
6976
  mathmlBuilder(group, style) {
6970
- return buildExpressionRow(group.body, style, true);
6977
+ return buildExpressionRow(group.body, style, group.semisimple);
6971
6978
  }
6972
6979
  });
6973
6980
 
@@ -8917,6 +8924,8 @@ rgba(0,0,0,0) 100%);`;
8917
8924
  // \def\qquad{\hskip2em\relax}
8918
8925
  defineMacro("\\qquad", "\\hskip2em\\relax");
8919
8926
 
8927
+ defineMacro("\\AA", "\\TextOrMath{\\Angstrom}{\\mathring{A}}\\relax");
8928
+
8920
8929
  // \tag@in@display form of \tag
8921
8930
  defineMacro("\\tag", "\\@ifstar\\tag@literal\\tag@paren");
8922
8931
  defineMacro("\\tag@paren", "\\tag@literal{({#1})}");
@@ -10094,6 +10103,8 @@ rgba(0,0,0,0) 100%);`;
10094
10103
 
10095
10104
  /* eslint no-constant-condition:0 */
10096
10105
 
10106
+ const binLeftCancellers = ["bin", "op", "open", "punct", "rel"];
10107
+
10097
10108
  /**
10098
10109
  * This file contains the parser used to parse out a TeX expression from the
10099
10110
  * input. Since TeX isn't context-free, standard parsers don't work particularly
@@ -10863,8 +10874,7 @@ rgba(0,0,0,0) 100%);`;
10863
10874
  body: expression,
10864
10875
  // A group formed by \begingroup...\endgroup is a semi-simple group
10865
10876
  // which doesn't affect spacing in math mode, i.e., is transparent.
10866
- // https://tex.stackexchange.com/questions/1930/when-should-one-
10867
- // use-begingroup-instead-of-bgroup
10877
+ // https://tex.stackexchange.com/questions/1930/
10868
10878
  semisimple: text === "\\begingroup" || undefined
10869
10879
  };
10870
10880
  } else {
@@ -10978,7 +10988,11 @@ rgba(0,0,0,0) 100%);`;
10978
10988
  // Recognize base symbol
10979
10989
  let symbol;
10980
10990
  if (symbols[this.mode][text]) {
10981
- const group = symbols[this.mode][text].group;
10991
+ let group = symbols[this.mode][text].group;
10992
+ if (group === "bin" && binLeftCancellers.includes(this.prevAtomType)) {
10993
+ // Change from a binary operator to a unary (prefix) operator
10994
+ group = "open";
10995
+ }
10982
10996
  const loc = SourceLocation.range(nucleus);
10983
10997
  let s;
10984
10998
  if (Object.prototype.hasOwnProperty.call(ATOMS, group )) {
@@ -11248,7 +11262,7 @@ rgba(0,0,0,0) 100%);`;
11248
11262
  * https://mit-license.org/
11249
11263
  */
11250
11264
 
11251
- const version = "0.10.18";
11265
+ const version = "0.10.20";
11252
11266
 
11253
11267
  function postProcess(block) {
11254
11268
  const labelMap = {};