temml 0.10.19 → 0.10.21

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
@@ -2073,20 +2073,22 @@ var temml = (function () {
2073
2073
  * Wrap the given array of nodes in an <mrow> node if needed, i.e.,
2074
2074
  * unless the array has length 1. Always returns a single node.
2075
2075
  */
2076
- const makeRow = function(body) {
2076
+ const makeRow = function(body, semisimple = false) {
2077
2077
  if (body.length === 1 && !(body[0] instanceof DocumentFragment)) {
2078
2078
  return body[0];
2079
- } else {
2079
+ } else if (!semisimple) {
2080
2080
  // Suppress spacing on <mo> nodes at both ends of the row.
2081
2081
  if (body[0] instanceof MathNode && body[0].type === "mo" && !body[0].attributes.fence) {
2082
2082
  body[0].attributes.lspace = "0em";
2083
+ body[0].attributes.rspace = "0em";
2083
2084
  }
2084
2085
  const end = body.length - 1;
2085
2086
  if (body[end] instanceof MathNode && body[end].type === "mo" && !body[end].attributes.fence) {
2087
+ body[end].attributes.lspace = "0em";
2086
2088
  body[end].attributes.rspace = "0em";
2087
2089
  }
2088
- return new mathMLTree.MathNode("mrow", body);
2089
2090
  }
2091
+ return new mathMLTree.MathNode("mrow", body);
2090
2092
  };
2091
2093
 
2092
2094
  const isRel = item => {
@@ -2100,10 +2102,10 @@ var temml = (function () {
2100
2102
  * (1) Suppress spacing when an author wraps an operator w/braces, as in {=}.
2101
2103
  * (2) Suppress spacing between two adjacent relations.
2102
2104
  */
2103
- const buildExpression = function(expression, style, isOrdgroup) {
2104
- if (expression.length === 1) {
2105
+ const buildExpression = function(expression, style, semisimple = false) {
2106
+ if (!semisimple && expression.length === 1) {
2105
2107
  const group = buildGroup$1(expression[0], style);
2106
- if (isOrdgroup && group instanceof MathNode && group.type === "mo") {
2108
+ if (group instanceof MathNode && group.type === "mo") {
2107
2109
  // When TeX writers want to suppress spacing on an operator,
2108
2110
  // they often put the operator by itself inside braces.
2109
2111
  group.setAttribute("lspace", "0em");
@@ -2133,8 +2135,8 @@ var temml = (function () {
2133
2135
  * Equivalent to buildExpression, but wraps the elements in an <mrow>
2134
2136
  * if there's more than one. Returns a single node instead of an array.
2135
2137
  */
2136
- const buildExpressionRow = function(expression, style, isOrdgroup) {
2137
- return makeRow(buildExpression(expression, style, isOrdgroup));
2138
+ const buildExpressionRow = function(expression, style, semisimple = false) {
2139
+ return makeRow(buildExpression(expression, style, semisimple), semisimple);
2138
2140
  };
2139
2141
 
2140
2142
  /**
@@ -2819,7 +2821,8 @@ var temml = (function () {
2819
2821
  const arrowGroup = {
2820
2822
  type: "ordgroup",
2821
2823
  mode: "math",
2822
- body: [leftLabel, sizedArrow, rightLabel]
2824
+ body: [leftLabel, sizedArrow, rightLabel],
2825
+ semisimple: true
2823
2826
  };
2824
2827
  return parser.callFunction("\\\\cdparent", [arrowGroup], []);
2825
2828
  }
@@ -3245,7 +3248,7 @@ var temml = (function () {
3245
3248
  allowedInText: true,
3246
3249
  argTypes: ["raw", "raw"]
3247
3250
  },
3248
- handler({ parser, token }, args, optArgs) {
3251
+ handler({ parser, breakOnTokenText, token }, args, optArgs) {
3249
3252
  const model = optArgs[0] && assertNodeType(optArgs[0], "raw").string;
3250
3253
  let color = "";
3251
3254
  if (model) {
@@ -3255,15 +3258,8 @@ var temml = (function () {
3255
3258
  color = validateColor(assertNodeType(args[0], "raw").string, parser.gullet.macros, token);
3256
3259
  }
3257
3260
 
3258
- // Set macro \current@color in current namespace to store the current
3259
- // color, mimicking the behavior of color.sty.
3260
- // This is currently used just to correctly color a \right
3261
- // that follows a \color command.
3262
- parser.gullet.macros.set("\\current@color", color);
3263
-
3264
3261
  // Parse out the implicit body that should be colored.
3265
- // Since \color nodes should not be nested, break on \color.
3266
- const body = parser.parseExpression(true, "\\color");
3262
+ const body = parser.parseExpression(true, breakOnTokenText);
3267
3263
 
3268
3264
  return {
3269
3265
  type: "color",
@@ -3803,18 +3799,10 @@ var temml = (function () {
3803
3799
  argTypes: ["primitive"]
3804
3800
  },
3805
3801
  handler: (context, args) => {
3806
- // \left case below triggers parsing of \right in
3807
- // `const right = parser.parseFunction();`
3808
- // uses this return value.
3809
- const color = context.parser.gullet.macros.get("\\current@color");
3810
- if (color && typeof color !== "string") {
3811
- throw new ParseError("\\current@color set to non-string in \\right");
3812
- }
3813
3802
  return {
3814
3803
  type: "leftright-right",
3815
3804
  mode: context.parser.mode,
3816
- delim: checkDelimiter(args[0], context).text,
3817
- color // undefined if not set via \color
3805
+ delim: checkDelimiter(args[0], context).text
3818
3806
  };
3819
3807
  }
3820
3808
  });
@@ -3843,8 +3831,7 @@ var temml = (function () {
3843
3831
  mode: parser.mode,
3844
3832
  body,
3845
3833
  left: delim.text,
3846
- right: right.delim,
3847
- rightColor: right.color
3834
+ right: right.delim
3848
3835
  };
3849
3836
  },
3850
3837
  mathmlBuilder: (group, style) => {
@@ -3867,7 +3854,6 @@ var temml = (function () {
3867
3854
  if (group.right === "\u2216" || group.right.indexOf("arrow") > -1) {
3868
3855
  rightNode.setAttribute("stretchy", "true");
3869
3856
  }
3870
- if (group.rightColor) { rightNode.style.color = group.rightColor; }
3871
3857
  inner.push(rightNode);
3872
3858
 
3873
3859
  return makeRow(inner);
@@ -3941,20 +3927,12 @@ var temml = (function () {
3941
3927
  node.style.borderBottom = "0.065em solid";
3942
3928
  break
3943
3929
  case "\\cancel":
3944
- node.style.background = `linear-gradient(to top left,
3945
- rgba(0,0,0,0) 0%,
3946
- rgba(0,0,0,0) calc(50% - 0.06em),
3947
- rgba(0,0,0,1) 50%,
3948
- rgba(0,0,0,0) calc(50% + 0.06em),
3949
- rgba(0,0,0,0) 100%);`;
3930
+ // We can't use an inline background-gradient. It does not work client-side.
3931
+ // So set a class and put the rule in the external CSS file.
3932
+ node.classes.push("tml-cancel");
3950
3933
  break
3951
3934
  case "\\bcancel":
3952
- node.style.background = `linear-gradient(to top right,
3953
- rgba(0,0,0,0) 0%,
3954
- rgba(0,0,0,0) calc(50% - 0.06em),
3955
- rgba(0,0,0,1) 50%,
3956
- rgba(0,0,0,0) calc(50% + 0.06em),
3957
- rgba(0,0,0,0) 100%);`;
3935
+ node.classes.push("tml-bcancel");
3958
3936
  break
3959
3937
  /*
3960
3938
  case "\\longdiv":
@@ -4001,18 +3979,7 @@ rgba(0,0,0,0) 100%);`;
4001
3979
  break
4002
3980
  }
4003
3981
  case "\\xcancel":
4004
- node.style.background = `linear-gradient(to top left,
4005
- rgba(0,0,0,0) 0%,
4006
- rgba(0,0,0,0) calc(50% - 0.06em),
4007
- rgba(0,0,0,1) 50%,
4008
- rgba(0,0,0,0) calc(50% + 0.06em),
4009
- rgba(0,0,0,0) 100%),
4010
- linear-gradient(to top right,
4011
- rgba(0,0,0,0) 0%,
4012
- rgba(0,0,0,0) calc(50% - 0.06em),
4013
- rgba(0,0,0,1) 50%,
4014
- rgba(0,0,0,0) calc(50% + 0.06em),
4015
- rgba(0,0,0,0) 100%);`;
3982
+ node.classes.push("tml-xcancel");
4016
3983
  break
4017
3984
  }
4018
3985
  if (group.backgroundColor) {
@@ -4210,7 +4177,7 @@ rgba(0,0,0,0) 100%);`;
4210
4177
  if (tagContents) {
4211
4178
  // The author has written a \tag or a \notag in this row.
4212
4179
  if (tagContents.body) {
4213
- tag = buildExpressionRow(tagContents.body, style);
4180
+ tag = buildExpressionRow(tagContents.body, style, true);
4214
4181
  tag.classes = ["tml-tag"];
4215
4182
  } else {
4216
4183
  // \notag. Return an empty span.
@@ -4257,7 +4224,9 @@ rgba(0,0,0,0) 100%);`;
4257
4224
  parser.gullet.macros.set("\\cr", "\\\\\\relax");
4258
4225
  }
4259
4226
  if (addEqnNum) {
4260
- parser.gullet.macros.set("\\tag", "\\env@tag{\\text{#1}}");
4227
+ parser.gullet.macros.set("\\tag", "\\@ifstar\\envtag@literal\\envtag@paren");
4228
+ parser.gullet.macros.set("\\envtag@paren", "\\env@tag{{(\\text{#1})}}");
4229
+ parser.gullet.macros.set("\\envtag@literal", "\\env@tag{\\text{#1}}");
4261
4230
  parser.gullet.macros.set("\\notag", "\\env@notag");
4262
4231
  parser.gullet.macros.set("\\nonumber", "\\env@notag");
4263
4232
  }
@@ -4298,7 +4267,8 @@ rgba(0,0,0,0) 100%);`;
4298
4267
  cell = {
4299
4268
  type: "ordgroup",
4300
4269
  mode: parser.mode,
4301
- body: cell
4270
+ body: cell,
4271
+ semisimple: true
4302
4272
  };
4303
4273
  row.push(cell);
4304
4274
  const next = parser.fetch().text;
@@ -5131,7 +5101,7 @@ rgba(0,0,0,0) 100%);`;
5131
5101
  const mathGroup = buildGroup$1(group.body, newStyle);
5132
5102
 
5133
5103
  if (mathGroup.children.length === 0) { return mathGroup } // empty group, e.g., \mathrm{}
5134
- if (font === "boldsymbol" && ["mo", "mpadded"].includes(mathGroup.type)) {
5104
+ if (font === "boldsymbol" && ["mo", "mpadded", "mrow"].includes(mathGroup.type)) {
5135
5105
  mathGroup.style.fontWeight = "bold";
5136
5106
  return mathGroup
5137
5107
  }
@@ -6488,10 +6458,10 @@ rgba(0,0,0,0) 100%);`;
6488
6458
  },
6489
6459
  mathmlBuilder(group, style) {
6490
6460
  if (group.isCharacterBox) {
6491
- const inner = buildExpression(group.body, style);
6461
+ const inner = buildExpression(group.body, style, true);
6492
6462
  return inner[0]
6493
6463
  } else {
6494
- return buildExpressionRow(group.body, style, true)
6464
+ return buildExpressionRow(group.body, style)
6495
6465
  }
6496
6466
  }
6497
6467
  });
@@ -6511,6 +6481,13 @@ rgba(0,0,0,0) 100%);`;
6511
6481
  // NOTE: Unlike most `builders`s, this one handles not only "op", but also
6512
6482
  // "supsub" since some of them (like \int) can affect super/subscripting.
6513
6483
 
6484
+ const setSpacing = node => {
6485
+ // The user wrote a \mathop{…} function. Change spacing from default to OP spacing.
6486
+ // The most likely spacing for an OP is a thin space per TeXbook p170.
6487
+ node.attributes.lspace = "0.1667em";
6488
+ node.attributes.rspace = "0.1667em";
6489
+ };
6490
+
6514
6491
  const mathmlBuilder$2 = (group, style) => {
6515
6492
  let node;
6516
6493
 
@@ -6522,9 +6499,11 @@ rgba(0,0,0,0) 100%);`;
6522
6499
  } else {
6523
6500
  node.setAttribute("movablelimits", "false");
6524
6501
  }
6502
+ if (group.fromMathOp) { setSpacing(node); }
6525
6503
  } else if (group.body) {
6526
6504
  // This is an operator with children. Add them.
6527
6505
  node = new MathNode("mo", buildExpression(group.body, style));
6506
+ if (group.fromMathOp) { setSpacing(node); }
6528
6507
  } else {
6529
6508
  // This is a text operator. Add all of the characters from the operator's name.
6530
6509
  node = new MathNode("mi", [new TextNode(group.name.slice(1))]);
@@ -6644,6 +6623,7 @@ rgba(0,0,0,0) 100%);`;
6644
6623
  limits: true,
6645
6624
  parentIsSupSub: false,
6646
6625
  symbol: isSymbol,
6626
+ fromMathOp: true,
6647
6627
  stack: false,
6648
6628
  name: isSymbol ? arr[0].text : null,
6649
6629
  body: isSymbol ? null : ordargument(body)
@@ -6977,7 +6957,7 @@ rgba(0,0,0,0) 100%);`;
6977
6957
  defineFunctionBuilders({
6978
6958
  type: "ordgroup",
6979
6959
  mathmlBuilder(group, style) {
6980
- return buildExpressionRow(group.body, style, true);
6960
+ return buildExpressionRow(group.body, style, group.semisimple);
6981
6961
  }
6982
6962
  });
6983
6963
 
@@ -10106,6 +10086,8 @@ rgba(0,0,0,0) 100%);`;
10106
10086
 
10107
10087
  /* eslint no-constant-condition:0 */
10108
10088
 
10089
+ const binLeftCancellers = ["bin", "op", "open", "punct", "rel"];
10090
+
10109
10091
  /**
10110
10092
  * This file contains the parser used to parse out a TeX expression from the
10111
10093
  * input. Since TeX isn't context-free, standard parsers don't work particularly
@@ -10875,8 +10857,7 @@ rgba(0,0,0,0) 100%);`;
10875
10857
  body: expression,
10876
10858
  // A group formed by \begingroup...\endgroup is a semi-simple group
10877
10859
  // which doesn't affect spacing in math mode, i.e., is transparent.
10878
- // https://tex.stackexchange.com/questions/1930/when-should-one-
10879
- // use-begingroup-instead-of-bgroup
10860
+ // https://tex.stackexchange.com/questions/1930/
10880
10861
  semisimple: text === "\\begingroup" || undefined
10881
10862
  };
10882
10863
  } else {
@@ -10990,7 +10971,11 @@ rgba(0,0,0,0) 100%);`;
10990
10971
  // Recognize base symbol
10991
10972
  let symbol;
10992
10973
  if (symbols[this.mode][text]) {
10993
- const group = symbols[this.mode][text].group;
10974
+ let group = symbols[this.mode][text].group;
10975
+ if (group === "bin" && binLeftCancellers.includes(this.prevAtomType)) {
10976
+ // Change from a binary operator to a unary (prefix) operator
10977
+ group = "open";
10978
+ }
10994
10979
  const loc = SourceLocation.range(nucleus);
10995
10980
  let s;
10996
10981
  if (Object.prototype.hasOwnProperty.call(ATOMS, group )) {
@@ -11260,7 +11245,7 @@ rgba(0,0,0,0) 100%);`;
11260
11245
  * https://mit-license.org/
11261
11246
  */
11262
11247
 
11263
- const version = "0.10.19";
11248
+ const version = "0.10.21";
11264
11249
 
11265
11250
  function postProcess(block) {
11266
11251
  const labelMap = {};