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.
@@ -47,6 +47,39 @@ mo.tml-prime {
47
47
  font-feature-settings: 'salt';
48
48
  }
49
49
 
50
+ mrow.tml-cancel {
51
+ background: linear-gradient(to top left,
52
+ rgba(0,0,0,0) 0%,
53
+ rgba(0,0,0,0) calc(50% - 0.06em),
54
+ rgba(0,0,0,1) 50%,
55
+ rgba(0,0,0,0) calc(50% + 0.06em),
56
+ rgba(0,0,0,0) 100%);
57
+ }
58
+
59
+ mrow.tml-bcancel {
60
+ background: linear-gradient(to top right,
61
+ rgba(0,0,0,0) 0%,
62
+ rgba(0,0,0,0) calc(50% - 0.06em),
63
+ rgba(0,0,0,1) 50%,
64
+ rgba(0,0,0,0) calc(50% + 0.06em),
65
+ rgba(0,0,0,0) 100%);
66
+ }
67
+
68
+ mrow.tml-xcancel {
69
+ background: linear-gradient(to top left,
70
+ rgba(0,0,0,0) 0%,
71
+ rgba(0,0,0,0) calc(50% - 0.06em),
72
+ rgba(0,0,0,1) 50%,
73
+ rgba(0,0,0,0) calc(50% + 0.06em),
74
+ rgba(0,0,0,0) 100%),
75
+ linear-gradient(to top right,
76
+ rgba(0,0,0,0) 0%,
77
+ rgba(0,0,0,0) calc(50% - 0.06em),
78
+ rgba(0,0,0,1) 50%,
79
+ rgba(0,0,0,0) calc(50% + 0.06em),
80
+ rgba(0,0,0,0) 100%)
81
+ }
82
+
50
83
  /* Prevent f' from overlapping in Chromium */
51
84
  mo.prime-pad {
52
85
  padding-left: 0.08em;
@@ -57,6 +57,39 @@ mo.tml-prime {
57
57
  font-family: Temml;
58
58
  }
59
59
 
60
+ mrow.tml-cancel {
61
+ background: linear-gradient(to top left,
62
+ rgba(0,0,0,0) 0%,
63
+ rgba(0,0,0,0) calc(50% - 0.06em),
64
+ rgba(0,0,0,1) 50%,
65
+ rgba(0,0,0,0) calc(50% + 0.06em),
66
+ rgba(0,0,0,0) 100%);
67
+ }
68
+
69
+ mrow.tml-bcancel {
70
+ background: linear-gradient(to top right,
71
+ rgba(0,0,0,0) 0%,
72
+ rgba(0,0,0,0) calc(50% - 0.06em),
73
+ rgba(0,0,0,1) 50%,
74
+ rgba(0,0,0,0) calc(50% + 0.06em),
75
+ rgba(0,0,0,0) 100%);
76
+ }
77
+
78
+ mrow.tml-xcancel {
79
+ background: linear-gradient(to top left,
80
+ rgba(0,0,0,0) 0%,
81
+ rgba(0,0,0,0) calc(50% - 0.06em),
82
+ rgba(0,0,0,1) 50%,
83
+ rgba(0,0,0,0) calc(50% + 0.06em),
84
+ rgba(0,0,0,0) 100%),
85
+ linear-gradient(to top right,
86
+ rgba(0,0,0,0) 0%,
87
+ rgba(0,0,0,0) calc(50% - 0.06em),
88
+ rgba(0,0,0,1) 50%,
89
+ rgba(0,0,0,0) calc(50% + 0.06em),
90
+ rgba(0,0,0,0) 100%)
91
+ }
92
+
60
93
  /* Prevent f' from overlapping in Chromium */
61
94
  mo.prime-pad {
62
95
  padding-left: 0.08em;
@@ -54,6 +54,39 @@ mo.tml-prime {
54
54
  font-feature-settings: 'ssty';
55
55
  }
56
56
 
57
+ mrow.tml-cancel {
58
+ background: linear-gradient(to top left,
59
+ rgba(0,0,0,0) 0%,
60
+ rgba(0,0,0,0) calc(50% - 0.06em),
61
+ rgba(0,0,0,1) 50%,
62
+ rgba(0,0,0,0) calc(50% + 0.06em),
63
+ rgba(0,0,0,0) 100%);
64
+ }
65
+
66
+ mrow.tml-bcancel {
67
+ background: linear-gradient(to top right,
68
+ rgba(0,0,0,0) 0%,
69
+ rgba(0,0,0,0) calc(50% - 0.06em),
70
+ rgba(0,0,0,1) 50%,
71
+ rgba(0,0,0,0) calc(50% + 0.06em),
72
+ rgba(0,0,0,0) 100%);
73
+ }
74
+
75
+ mrow.tml-xcancel {
76
+ background: linear-gradient(to top left,
77
+ rgba(0,0,0,0) 0%,
78
+ rgba(0,0,0,0) calc(50% - 0.06em),
79
+ rgba(0,0,0,1) 50%,
80
+ rgba(0,0,0,0) calc(50% + 0.06em),
81
+ rgba(0,0,0,0) 100%),
82
+ linear-gradient(to top right,
83
+ rgba(0,0,0,0) 0%,
84
+ rgba(0,0,0,0) calc(50% - 0.06em),
85
+ rgba(0,0,0,1) 50%,
86
+ rgba(0,0,0,0) calc(50% + 0.06em),
87
+ rgba(0,0,0,0) 100%)
88
+ }
89
+
57
90
  /* Prevent f' from overlapping in Chromium */
58
91
  mo.prime-pad {
59
92
  padding-left: 0.08em;
@@ -40,6 +40,39 @@ mo.tml-prime {
40
40
  font-family: Temml;
41
41
  }
42
42
 
43
+ mrow.tml-cancel {
44
+ background: linear-gradient(to top left,
45
+ rgba(0,0,0,0) 0%,
46
+ rgba(0,0,0,0) calc(50% - 0.06em),
47
+ rgba(0,0,0,1) 50%,
48
+ rgba(0,0,0,0) calc(50% + 0.06em),
49
+ rgba(0,0,0,0) 100%);
50
+ }
51
+
52
+ mrow.tml-bcancel {
53
+ background: linear-gradient(to top right,
54
+ rgba(0,0,0,0) 0%,
55
+ rgba(0,0,0,0) calc(50% - 0.06em),
56
+ rgba(0,0,0,1) 50%,
57
+ rgba(0,0,0,0) calc(50% + 0.06em),
58
+ rgba(0,0,0,0) 100%);
59
+ }
60
+
61
+ mrow.tml-xcancel {
62
+ background: linear-gradient(to top left,
63
+ rgba(0,0,0,0) 0%,
64
+ rgba(0,0,0,0) calc(50% - 0.06em),
65
+ rgba(0,0,0,1) 50%,
66
+ rgba(0,0,0,0) calc(50% + 0.06em),
67
+ rgba(0,0,0,0) 100%),
68
+ linear-gradient(to top right,
69
+ rgba(0,0,0,0) 0%,
70
+ rgba(0,0,0,0) calc(50% - 0.06em),
71
+ rgba(0,0,0,1) 50%,
72
+ rgba(0,0,0,0) calc(50% + 0.06em),
73
+ rgba(0,0,0,0) 100%)
74
+ }
75
+
43
76
  /* Prevent f' from overlapping in Chromium */
44
77
  mo.prime-pad {
45
78
  padding-left: 0.08em;
@@ -48,6 +48,39 @@ mo.tml-prime {
48
48
  font-feature-settings: 'ss04';
49
49
  }
50
50
 
51
+ mrow.tml-cancel {
52
+ background: linear-gradient(to top left,
53
+ rgba(0,0,0,0) 0%,
54
+ rgba(0,0,0,0) calc(50% - 0.06em),
55
+ rgba(0,0,0,1) 50%,
56
+ rgba(0,0,0,0) calc(50% + 0.06em),
57
+ rgba(0,0,0,0) 100%);
58
+ }
59
+
60
+ mrow.tml-bcancel {
61
+ background: linear-gradient(to top right,
62
+ rgba(0,0,0,0) 0%,
63
+ rgba(0,0,0,0) calc(50% - 0.06em),
64
+ rgba(0,0,0,1) 50%,
65
+ rgba(0,0,0,0) calc(50% + 0.06em),
66
+ rgba(0,0,0,0) 100%);
67
+ }
68
+
69
+ mrow.tml-xcancel {
70
+ background: linear-gradient(to top left,
71
+ rgba(0,0,0,0) 0%,
72
+ rgba(0,0,0,0) calc(50% - 0.06em),
73
+ rgba(0,0,0,1) 50%,
74
+ rgba(0,0,0,0) calc(50% + 0.06em),
75
+ rgba(0,0,0,0) 100%),
76
+ linear-gradient(to top right,
77
+ rgba(0,0,0,0) 0%,
78
+ rgba(0,0,0,0) calc(50% - 0.06em),
79
+ rgba(0,0,0,1) 50%,
80
+ rgba(0,0,0,0) calc(50% + 0.06em),
81
+ rgba(0,0,0,0) 100%)
82
+ }
83
+
51
84
  /* Prevent f' from overlapping in Chromium */
52
85
  mo.prime-pad {
53
86
  padding-left: 0.08em;
package/dist/temml.cjs CHANGED
@@ -940,8 +940,8 @@ defineSymbol(math, textord, "\u2207", "\\nabla", true);
940
940
  defineSymbol(math, textord, "\u266d", "\\flat", true);
941
941
  defineSymbol(math, textord, "\u2113", "\\ell", true);
942
942
  defineSymbol(math, textord, "\u266e", "\\natural", true);
943
- defineSymbol(math, textord, "Å", "\\AA", true);
944
- defineSymbol(text, textord, "Å", "\\AA", true);
943
+ defineSymbol(math, textord, "Å", "\\Angstrom", true);
944
+ defineSymbol(text, textord, "Å", "\\Angstrom", true);
945
945
  defineSymbol(math, textord, "\u2663", "\\clubsuit", true);
946
946
  defineSymbol(math, textord, "\u2667", "\\varclubsuit", true);
947
947
  defineSymbol(math, textord, "\u2118", "\\wp", true);
@@ -2055,6 +2055,16 @@ const consolidateNumbers = expression => {
2055
2055
  expression[nums[i].start].text += expression[j].text;
2056
2056
  }
2057
2057
  expression.splice(nums[i].start + 1, nums[i].end - nums[i].start);
2058
+ // Check if the <mn> is followed by a numeric base in a supsub, e.g. the "3" in 123^4
2059
+ // If so, merge the first <mn> into the base.
2060
+ if (expression.length > nums[i].start + 1) {
2061
+ const nextTerm = expression[nums[i].start + 1];
2062
+ if (nextTerm.type === "supsub" && nextTerm.base && nextTerm.base.type === "textord" &&
2063
+ numberRegEx$1.test(nextTerm.base.text)) {
2064
+ nextTerm.base.text = expression[nums[i].start].text + nextTerm.base.text;
2065
+ expression.splice(nums[i].start, 1);
2066
+ }
2067
+ }
2058
2068
  }
2059
2069
  };
2060
2070
 
@@ -2062,20 +2072,22 @@ const consolidateNumbers = expression => {
2062
2072
  * Wrap the given array of nodes in an <mrow> node if needed, i.e.,
2063
2073
  * unless the array has length 1. Always returns a single node.
2064
2074
  */
2065
- const makeRow = function(body) {
2075
+ const makeRow = function(body, semisimple = false) {
2066
2076
  if (body.length === 1 && !(body[0] instanceof DocumentFragment)) {
2067
2077
  return body[0];
2068
- } else {
2078
+ } else if (!semisimple) {
2069
2079
  // Suppress spacing on <mo> nodes at both ends of the row.
2070
2080
  if (body[0] instanceof MathNode && body[0].type === "mo" && !body[0].attributes.fence) {
2071
2081
  body[0].attributes.lspace = "0em";
2082
+ body[0].attributes.rspace = "0em";
2072
2083
  }
2073
2084
  const end = body.length - 1;
2074
2085
  if (body[end] instanceof MathNode && body[end].type === "mo" && !body[end].attributes.fence) {
2086
+ body[end].attributes.lspace = "0em";
2075
2087
  body[end].attributes.rspace = "0em";
2076
2088
  }
2077
- return new mathMLTree.MathNode("mrow", body);
2078
2089
  }
2090
+ return new mathMLTree.MathNode("mrow", body);
2079
2091
  };
2080
2092
 
2081
2093
  const isRel = item => {
@@ -2089,10 +2101,10 @@ const isRel = item => {
2089
2101
  * (1) Suppress spacing when an author wraps an operator w/braces, as in {=}.
2090
2102
  * (2) Suppress spacing between two adjacent relations.
2091
2103
  */
2092
- const buildExpression = function(expression, style, isOrdgroup) {
2093
- if (expression.length === 1) {
2104
+ const buildExpression = function(expression, style, semisimple = false) {
2105
+ if (!semisimple && expression.length === 1) {
2094
2106
  const group = buildGroup$1(expression[0], style);
2095
- if (isOrdgroup && group instanceof MathNode && group.type === "mo") {
2107
+ if (group instanceof MathNode && group.type === "mo") {
2096
2108
  // When TeX writers want to suppress spacing on an operator,
2097
2109
  // they often put the operator by itself inside braces.
2098
2110
  group.setAttribute("lspace", "0em");
@@ -2122,8 +2134,8 @@ const buildExpression = function(expression, style, isOrdgroup) {
2122
2134
  * Equivalent to buildExpression, but wraps the elements in an <mrow>
2123
2135
  * if there's more than one. Returns a single node instead of an array.
2124
2136
  */
2125
- const buildExpressionRow = function(expression, style, isOrdgroup) {
2126
- return makeRow(buildExpression(expression, style, isOrdgroup));
2137
+ const buildExpressionRow = function(expression, style, semisimple = false) {
2138
+ return makeRow(buildExpression(expression, style, semisimple), semisimple);
2127
2139
  };
2128
2140
 
2129
2141
  /**
@@ -2808,7 +2820,8 @@ function cdArrow(arrowChar, labels, parser) {
2808
2820
  const arrowGroup = {
2809
2821
  type: "ordgroup",
2810
2822
  mode: "math",
2811
- body: [leftLabel, sizedArrow, rightLabel]
2823
+ body: [leftLabel, sizedArrow, rightLabel],
2824
+ semisimple: true
2812
2825
  };
2813
2826
  return parser.callFunction("\\\\cdparent", [arrowGroup], []);
2814
2827
  }
@@ -3930,20 +3943,12 @@ const mathmlBuilder$8 = (group, style) => {
3930
3943
  node.style.borderBottom = "0.065em solid";
3931
3944
  break
3932
3945
  case "\\cancel":
3933
- node.style.background = `linear-gradient(to top left,
3934
- rgba(0,0,0,0) 0%,
3935
- rgba(0,0,0,0) calc(50% - 0.06em),
3936
- rgba(0,0,0,1) 50%,
3937
- rgba(0,0,0,0) calc(50% + 0.06em),
3938
- rgba(0,0,0,0) 100%);`;
3946
+ // We can't use an inline background-gradient. It does not work client-side.
3947
+ // So set a class and put the rule in the external CSS file.
3948
+ node.classes.push("tml-cancel");
3939
3949
  break
3940
3950
  case "\\bcancel":
3941
- node.style.background = `linear-gradient(to top right,
3942
- rgba(0,0,0,0) 0%,
3943
- rgba(0,0,0,0) calc(50% - 0.06em),
3944
- rgba(0,0,0,1) 50%,
3945
- rgba(0,0,0,0) calc(50% + 0.06em),
3946
- rgba(0,0,0,0) 100%);`;
3951
+ node.classes.push("tml-bcancel");
3947
3952
  break
3948
3953
  /*
3949
3954
  case "\\longdiv":
@@ -3990,18 +3995,7 @@ rgba(0,0,0,0) 100%);`;
3990
3995
  break
3991
3996
  }
3992
3997
  case "\\xcancel":
3993
- node.style.background = `linear-gradient(to top left,
3994
- rgba(0,0,0,0) 0%,
3995
- rgba(0,0,0,0) calc(50% - 0.06em),
3996
- rgba(0,0,0,1) 50%,
3997
- rgba(0,0,0,0) calc(50% + 0.06em),
3998
- rgba(0,0,0,0) 100%),
3999
- linear-gradient(to top right,
4000
- rgba(0,0,0,0) 0%,
4001
- rgba(0,0,0,0) calc(50% - 0.06em),
4002
- rgba(0,0,0,1) 50%,
4003
- rgba(0,0,0,0) calc(50% + 0.06em),
4004
- rgba(0,0,0,0) 100%);`;
3998
+ node.classes.push("tml-xcancel");
4005
3999
  break
4006
4000
  }
4007
4001
  if (group.backgroundColor) {
@@ -4199,7 +4193,7 @@ const getTag = (group, style, rowNum) => {
4199
4193
  if (tagContents) {
4200
4194
  // The author has written a \tag or a \notag in this row.
4201
4195
  if (tagContents.body) {
4202
- tag = buildExpressionRow(tagContents.body, style);
4196
+ tag = buildExpressionRow(tagContents.body, style, true);
4203
4197
  tag.classes = ["tml-tag"];
4204
4198
  } else {
4205
4199
  // \notag. Return an empty span.
@@ -4246,7 +4240,9 @@ function parseArray(
4246
4240
  parser.gullet.macros.set("\\cr", "\\\\\\relax");
4247
4241
  }
4248
4242
  if (addEqnNum) {
4249
- parser.gullet.macros.set("\\tag", "\\env@tag{\\text{#1}}");
4243
+ parser.gullet.macros.set("\\tag", "\\@ifstar\\envtag@literal\\envtag@paren");
4244
+ parser.gullet.macros.set("\\envtag@paren", "\\env@tag{{(\\text{#1})}}");
4245
+ parser.gullet.macros.set("\\envtag@literal", "\\env@tag{\\text{#1}}");
4250
4246
  parser.gullet.macros.set("\\notag", "\\env@notag");
4251
4247
  parser.gullet.macros.set("\\nonumber", "\\env@notag");
4252
4248
  }
@@ -4287,7 +4283,8 @@ function parseArray(
4287
4283
  cell = {
4288
4284
  type: "ordgroup",
4289
4285
  mode: parser.mode,
4290
- body: cell
4286
+ body: cell,
4287
+ semisimple: true
4291
4288
  };
4292
4289
  row.push(cell);
4293
4290
  const next = parser.fetch().text;
@@ -5120,7 +5117,7 @@ const mathmlBuilder$6 = (group, style) => {
5120
5117
  const mathGroup = buildGroup$1(group.body, newStyle);
5121
5118
 
5122
5119
  if (mathGroup.children.length === 0) { return mathGroup } // empty group, e.g., \mathrm{}
5123
- if (font === "boldsymbol" && ["mo", "mpadded"].includes(mathGroup.type)) {
5120
+ if (font === "boldsymbol" && ["mo", "mpadded", "mrow"].includes(mathGroup.type)) {
5124
5121
  mathGroup.style.fontWeight = "bold";
5125
5122
  return mathGroup
5126
5123
  }
@@ -6477,10 +6474,10 @@ defineFunction({
6477
6474
  },
6478
6475
  mathmlBuilder(group, style) {
6479
6476
  if (group.isCharacterBox) {
6480
- const inner = buildExpression(group.body, style);
6477
+ const inner = buildExpression(group.body, style, true);
6481
6478
  return inner[0]
6482
6479
  } else {
6483
- return buildExpressionRow(group.body, style, true)
6480
+ return buildExpressionRow(group.body, style)
6484
6481
  }
6485
6482
  }
6486
6483
  });
@@ -6500,6 +6497,13 @@ const ordTypes = ["textord", "mathord", "ordgroup", "close", "leftright"];
6500
6497
  // NOTE: Unlike most `builders`s, this one handles not only "op", but also
6501
6498
  // "supsub" since some of them (like \int) can affect super/subscripting.
6502
6499
 
6500
+ const setSpacing = node => {
6501
+ // The user wrote a \mathop{…} function. Change spacing from default to OP spacing.
6502
+ // The most likely spacing for an OP is a thin space per TeXbook p170.
6503
+ node.attributes.lspace = "0.1667em";
6504
+ node.attributes.rspace = "0.1667em";
6505
+ };
6506
+
6503
6507
  const mathmlBuilder$2 = (group, style) => {
6504
6508
  let node;
6505
6509
 
@@ -6511,9 +6515,11 @@ const mathmlBuilder$2 = (group, style) => {
6511
6515
  } else {
6512
6516
  node.setAttribute("movablelimits", "false");
6513
6517
  }
6518
+ if (group.fromMathOp) { setSpacing(node); }
6514
6519
  } else if (group.body) {
6515
6520
  // This is an operator with children. Add them.
6516
6521
  node = new MathNode("mo", buildExpression(group.body, style));
6522
+ if (group.fromMathOp) { setSpacing(node); }
6517
6523
  } else {
6518
6524
  // This is a text operator. Add all of the characters from the operator's name.
6519
6525
  node = new MathNode("mi", [new TextNode(group.name.slice(1))]);
@@ -6633,6 +6639,7 @@ defineFunction({
6633
6639
  limits: true,
6634
6640
  parentIsSupSub: false,
6635
6641
  symbol: isSymbol,
6642
+ fromMathOp: true,
6636
6643
  stack: false,
6637
6644
  name: isSymbol ? arr[0].text : null,
6638
6645
  body: isSymbol ? null : ordargument(body)
@@ -6966,7 +6973,7 @@ defineMacro("\\operatorname",
6966
6973
  defineFunctionBuilders({
6967
6974
  type: "ordgroup",
6968
6975
  mathmlBuilder(group, style) {
6969
- return buildExpressionRow(group.body, style, true);
6976
+ return buildExpressionRow(group.body, style, group.semisimple);
6970
6977
  }
6971
6978
  });
6972
6979
 
@@ -8916,6 +8923,8 @@ defineMacro("\\quad", "\\hskip1em\\relax");
8916
8923
  // \def\qquad{\hskip2em\relax}
8917
8924
  defineMacro("\\qquad", "\\hskip2em\\relax");
8918
8925
 
8926
+ defineMacro("\\AA", "\\TextOrMath{\\Angstrom}{\\mathring{A}}\\relax");
8927
+
8919
8928
  // \tag@in@display form of \tag
8920
8929
  defineMacro("\\tag", "\\@ifstar\\tag@literal\\tag@paren");
8921
8930
  defineMacro("\\tag@paren", "\\tag@literal{({#1})}");
@@ -11993,6 +12002,8 @@ var unicodeSymbols = {
11993
12002
 
11994
12003
  /* eslint no-constant-condition:0 */
11995
12004
 
12005
+ const binLeftCancellers = ["bin", "op", "open", "punct", "rel"];
12006
+
11996
12007
  /**
11997
12008
  * This file contains the parser used to parse out a TeX expression from the
11998
12009
  * input. Since TeX isn't context-free, standard parsers don't work particularly
@@ -12762,8 +12773,7 @@ class Parser {
12762
12773
  body: expression,
12763
12774
  // A group formed by \begingroup...\endgroup is a semi-simple group
12764
12775
  // which doesn't affect spacing in math mode, i.e., is transparent.
12765
- // https://tex.stackexchange.com/questions/1930/when-should-one-
12766
- // use-begingroup-instead-of-bgroup
12776
+ // https://tex.stackexchange.com/questions/1930/
12767
12777
  semisimple: text === "\\begingroup" || undefined
12768
12778
  };
12769
12779
  } else {
@@ -12877,7 +12887,11 @@ class Parser {
12877
12887
  // Recognize base symbol
12878
12888
  let symbol;
12879
12889
  if (symbols[this.mode][text]) {
12880
- const group = symbols[this.mode][text].group;
12890
+ let group = symbols[this.mode][text].group;
12891
+ if (group === "bin" && binLeftCancellers.includes(this.prevAtomType)) {
12892
+ // Change from a binary operator to a unary (prefix) operator
12893
+ group = "open";
12894
+ }
12881
12895
  const loc = SourceLocation.range(nucleus);
12882
12896
  let s;
12883
12897
  if (Object.prototype.hasOwnProperty.call(ATOMS, group )) {
@@ -13147,7 +13161,7 @@ class Style {
13147
13161
  * https://mit-license.org/
13148
13162
  */
13149
13163
 
13150
- const version = "0.10.18";
13164
+ const version = "0.10.20";
13151
13165
 
13152
13166
  function postProcess(block) {
13153
13167
  const labelMap = {};