temml 0.10.18 → 0.10.20

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