temml 0.10.19 → 0.10.21

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