temml 0.10.21 → 0.10.23

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  | Library | Minified JavaScript + CSS |
4
4
  |:--------------|:-------------------------:|
5
- | Temml | 150 KB |
5
+ | Temml | 151 KB |
6
6
  | MathJax 2.7.5 | 338 KB |
7
7
  | KaTeX | 280 KB |
8
8
  | TeXZilla | 168 KB |
@@ -30,10 +30,6 @@ math * {
30
30
  border-color: currentColor;
31
31
  }
32
32
 
33
- mtext {
34
- font-family: Asana Math;
35
- }
36
-
37
33
  math {
38
34
  font-family: Asana Math, math;
39
35
  }
@@ -0,0 +1,152 @@
1
+ /*
2
+ Fira Math fonts are released under the SIL OPEN FONT LICENSE Version 1.1.
3
+
4
+ The Fira Math WOFF2 font has been obtained from
5
+ http://www.gust.org.pl/projects/e-foundry/
6
+
7
+ The Temml.woff2 is a clone of KaTeX_Script-Regular, except that the code points
8
+ have been changed from ASCII to Unicode Mathematical Alphanumeric Symbols Script capitals,
9
+ Unicode range 1D49C to 1D4B5.
10
+ */
11
+
12
+ @font-face {
13
+ font-family: 'Temml';
14
+ src: url('Temml.woff2') format('woff2');
15
+ font-weight: normal;
16
+ font-style: normal;
17
+ }
18
+
19
+ @font-face {
20
+ font-family: Fira Math;
21
+ src: url('FiraMath-Regular.woff2');
22
+ }
23
+
24
+ math {
25
+ font-style: normal;
26
+ font-weight: normal;
27
+ line-height: normal;
28
+ font-size-adjust: none;
29
+ text-indent: 0;
30
+ text-transform: none;
31
+ letter-spacing: normal;
32
+ word-wrap: normal;
33
+ direction: ltr;
34
+ }
35
+
36
+ math * {
37
+ border-color: currentColor;
38
+ }
39
+
40
+ math {
41
+ font-family: "Fira Math", math;
42
+ }
43
+
44
+ /* Next line is active in Firefox and Safari.
45
+ * Not in Chromium, which recognizes display: "block math" written inline. */
46
+ math.tml-display { display: block; }
47
+
48
+ *.mathscr {
49
+ font-family: "Temml";
50
+ }
51
+
52
+ /* Chromium prime alignment */
53
+ mo.tml-prime {
54
+ font-family: Temml;
55
+ }
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
+
90
+ /* Prevent f' from overlapping in Chromium */
91
+ mo.prime-pad {
92
+ padding-left: 0.08em;
93
+ }
94
+
95
+ /* Array cell justification in Firefox & WebKit */
96
+ .tml-right {
97
+ text-align: right;
98
+ }
99
+ .tml-left {
100
+ text-align: left;
101
+ }
102
+
103
+ /* Stretch \widetilde & set array cell justification in Chromium */
104
+ @supports (not (-webkit-backdrop-filter: blur(1px))) and (not (-moz-appearance: none)) {
105
+ .tml-crooked-2 {
106
+ transform: scale(2.0, 1.1)
107
+ }
108
+ .tml-crooked-3 {
109
+ transform: scale(3.0, 1.3)
110
+ }
111
+ .tml-crooked-4 {
112
+ transform: scale(4.0, 1.4)
113
+ }
114
+ .tml-right {
115
+ text-align: -webkit-right;
116
+ }
117
+ .tml-left {
118
+ text-align: -webkit-left;
119
+ }
120
+ }
121
+
122
+ /* Adjust WebKit accents */
123
+ @supports (-webkit-backdrop-filter: blur(1px)) {
124
+ .tml-xshift { transform: translate(0px, 0.45em) }
125
+ .tml-capshift { transform: translate(0px, 0.35em) }
126
+ }
127
+
128
+ /* flex-wrap for line-breaking in Chromium */
129
+ math {
130
+ display: inline-flex;
131
+ flex-wrap: wrap;
132
+ align-items: baseline;
133
+ }
134
+ math > mrow {
135
+ padding: 0.5ex 0ex;
136
+ }
137
+
138
+ /* Avoid flex-wrap in Firefox */
139
+ @-moz-document url-prefix() {
140
+ math { display: inline; }
141
+ math > mrow { padding: 0 }
142
+ }
143
+
144
+ /* AMS environment auto-numbering via CSS counter. */
145
+ .tml-eqn::before {
146
+ counter-increment: tmlEqnNo;
147
+ content: "(" counter(tmlEqnNo) ")";
148
+ }
149
+
150
+ body {
151
+ counter-reset: tmlEqnNo;
152
+ }
@@ -32,10 +32,6 @@ math * {
32
32
  * Not in Chromium, which recognizes display: "block math" written inline. */
33
33
  math.tml-display { display: block; }
34
34
 
35
- mtext {
36
- font-family: STIX2;
37
- }
38
-
39
35
  math {
40
36
  font-family: STIX2, math;
41
37
  }
package/dist/temml.cjs CHANGED
@@ -936,7 +936,8 @@ defineSymbol(math, textord, "\u2135", "\\aleph", true);
936
936
  defineSymbol(math, textord, "\u2200", "\\forall", true);
937
937
  defineSymbol(math, textord, "\u210f", "\\hbar", true);
938
938
  defineSymbol(math, textord, "\u2203", "\\exists", true);
939
- defineSymbol(math, textord, "\u2207", "\\nabla", true);
939
+ // is actually a unary operator, not binary. But this works.
940
+ defineSymbol(math, bin, "\u2207", "\\nabla", true);
940
941
  defineSymbol(math, textord, "\u266d", "\\flat", true);
941
942
  defineSymbol(math, textord, "\u2113", "\\ell", true);
942
943
  defineSymbol(math, textord, "\u266e", "\\natural", true);
@@ -990,6 +991,7 @@ defineSymbol(math, bin, "\u2021", "\\ddagger");
990
991
  defineSymbol(math, bin, "\u2240", "\\wr", true);
991
992
  defineSymbol(math, bin, "\u2a3f", "\\amalg");
992
993
  defineSymbol(math, bin, "\u0026", "\\And"); // from amsmath
994
+ defineSymbol(math, bin, "\u2AFD", "\\sslash", true); // from stmaryrd
993
995
 
994
996
  // Arrow Symbols
995
997
  defineSymbol(math, rel, "\u27f5", "\\longleftarrow", true);
@@ -1024,6 +1026,7 @@ defineSymbol(math, mathord, "\u2609", "\\astrosun", true);
1024
1026
  defineSymbol(math, mathord, "\u263c", "\\sun", true);
1025
1027
  defineSymbol(math, mathord, "\u263e", "\\leftmoon", true);
1026
1028
  defineSymbol(math, mathord, "\u263d", "\\rightmoon", true);
1029
+ defineSymbol(math, mathord, "\u2295", "\\Earth");
1027
1030
 
1028
1031
  // AMS Negated Binary Relations
1029
1032
  defineSymbol(math, rel, "\u226e", "\\nless", true);
@@ -1251,6 +1254,8 @@ defineSymbol(math, bin, "\u27d5", "\\leftouterjoin", true);
1251
1254
  defineSymbol(math, bin, "\u27d6", "\\rightouterjoin", true);
1252
1255
  defineSymbol(math, bin, "\u27d7", "\\fullouterjoin", true);
1253
1256
 
1257
+ defineSymbol(math, bin, "\u2238", "\\dotminus", true); // stix
1258
+
1254
1259
  // AMS Arrows
1255
1260
  // Note: unicode-math maps \u21e2 to their own function \rightdasharrow.
1256
1261
  // We'll map it to AMS function \dashrightarrow. It produces the same atom.
@@ -1408,6 +1413,7 @@ defineSymbol(math, mathord, "\u2aeb", "\\Bot");
1408
1413
  defineSymbol(math, bin, "\u2217", "\u2217", true);
1409
1414
  defineSymbol(math, bin, "+", "+");
1410
1415
  defineSymbol(math, bin, "*", "*");
1416
+ defineSymbol(math, bin, "\u2044", "/", true);
1411
1417
  defineSymbol(math, bin, "\u2044", "\u2044");
1412
1418
  defineSymbol(math, bin, "\u2212", "-", true);
1413
1419
  defineSymbol(math, bin, "\u22c5", "\\cdot", true);
@@ -1864,7 +1870,8 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
1864
1870
  continue
1865
1871
  }
1866
1872
  block.push(node);
1867
- if (node.type && node.type === "mo" && node.children.length === 1) {
1873
+ if (node.type && node.type === "mo" && node.children.length === 1 &&
1874
+ !Object.hasOwn(node.attributes, "movablelimits")) {
1868
1875
  const ch = node.children[0].text;
1869
1876
  if (openDelims.indexOf(ch) > -1) {
1870
1877
  level += 1;
@@ -1879,7 +1886,7 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
1879
1886
  mrows.push(element);
1880
1887
  block = [node];
1881
1888
  }
1882
- } else if (level === 0 && wrapMode === "tex") {
1889
+ } else if (level === 0 && wrapMode === "tex" && ch !== "∇") {
1883
1890
  // Check if the following node is a \nobreak text node, e.g. "~""
1884
1891
  const next = i < expression.length - 1 ? expression[i + 1] : null;
1885
1892
  let glueIsFreeOfNobreak = true;
@@ -2017,9 +2024,11 @@ const consolidateText = mrow => {
2017
2024
  };
2018
2025
 
2019
2026
  const numberRegEx$1 = /^[0-9]$/;
2020
- const isCommaOrDot = node => {
2021
- return (node.type === "atom" && node.text === ",") ||
2022
- (node.type === "textord" && node.text === ".")
2027
+ const isDotOrComma = (node, followingNode) => {
2028
+ return ((node.type === "textord" && node.text === ".") ||
2029
+ (node.type === "atom" && node.text === ",")) &&
2030
+ // Don't consolidate if there is a space after the comma.
2031
+ node.loc && followingNode.loc && node.loc.end === followingNode.loc.start
2023
2032
  };
2024
2033
  const consolidateNumbers = expression => {
2025
2034
  // Consolidate adjacent numbers. We want to return <mn>1,506.3</mn>,
@@ -2042,7 +2051,8 @@ const consolidateNumbers = expression => {
2042
2051
 
2043
2052
  // Determine if numeral groups are separated by a comma or dot.
2044
2053
  for (let i = nums.length - 1; i > 0; i--) {
2045
- if (nums[i - 1].end === nums[i].start - 2 && isCommaOrDot(expression[nums[i].start - 1])) {
2054
+ if (nums[i - 1].end === nums[i].start - 2 &&
2055
+ isDotOrComma(expression[nums[i].start - 1], expression[nums[i].start])) {
2046
2056
  // Merge the two groups.
2047
2057
  nums[i - 1].end = nums[i].end;
2048
2058
  nums.splice(i, 1);
@@ -3258,7 +3268,7 @@ defineFunction({
3258
3268
  }
3259
3269
 
3260
3270
  // Parse out the implicit body that should be colored.
3261
- const body = parser.parseExpression(true, breakOnTokenText);
3271
+ const body = parser.parseExpression(true, breakOnTokenText, true);
3262
3272
 
3263
3273
  return {
3264
3274
  type: "color",
@@ -3700,17 +3710,13 @@ const sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
3700
3710
 
3701
3711
  // Delimiter functions
3702
3712
  function checkDelimiter(delim, context) {
3703
- if (delim.type === "ordgroup" && delim.body.length === 1 && delim.body[0].text === "\u2044") {
3704
- // Recover "/" from the zero spacing group. (See macros.js)
3705
- delim = { type: "textord", text: "/", mode: "math" };
3706
- }
3707
3713
  const symDelim = checkSymbolNodeType(delim);
3708
3714
  if (symDelim && delimiters.includes(symDelim.text)) {
3709
3715
  // If a character is not in the MathML operator dictionary, it will not stretch.
3710
3716
  // Replace such characters w/characters that will stretch.
3717
+ if (["/", "\u2044"].includes(symDelim.text)) { symDelim.text = "\u2215"; }
3711
3718
  if (["<", "\\lt"].includes(symDelim.text)) { symDelim.text = "⟨"; }
3712
3719
  if ([">", "\\gt"].includes(symDelim.text)) { symDelim.text = "⟩"; }
3713
- if (symDelim.text === "/") { symDelim.text = "\u2215"; }
3714
3720
  if (symDelim.text === "\\backslash") { symDelim.text = "\u2216"; }
3715
3721
  return symDelim;
3716
3722
  } else if (symDelim) {
@@ -3819,8 +3825,26 @@ defineFunction({
3819
3825
  const parser = context.parser;
3820
3826
  // Parse out the implicit body
3821
3827
  ++parser.leftrightDepth;
3822
- // parseExpression stops before '\\right'
3823
- const body = parser.parseExpression(false);
3828
+ // parseExpression stops before '\\right' or `\\middle`
3829
+ let body = parser.parseExpression(false, null, true);
3830
+ let nextToken = parser.fetch();
3831
+ while (nextToken.text === "\\middle") {
3832
+ // `\middle`, from the ε-TeX package, ends one group and starts another group.
3833
+ // We had to parse this expression with `breakOnMiddle` enabled in order
3834
+ // to get TeX-compliant parsing of \over.
3835
+ // But we do not want, at this point, to end on \middle, so continue
3836
+ // to parse until we fetch a `\right`.
3837
+ parser.consume();
3838
+ const middle = parser.fetch().text;
3839
+ if (!symbols.math[middle]) {
3840
+ throw new ParseError(`Invalid delimiter '${middle}' after '\\middle'`);
3841
+ }
3842
+ checkDelimiter({ type: "atom", mode: "math", text: middle }, { funcName: "\\middle" });
3843
+ body.push({ type: "middle", mode: "math", delim: middle });
3844
+ parser.consume();
3845
+ body = body.concat(parser.parseExpression(false, null, true));
3846
+ nextToken = parser.fetch();
3847
+ }
3824
3848
  --parser.leftrightDepth;
3825
3849
  // Check the next token
3826
3850
  parser.expect("\\right", false);
@@ -5094,6 +5118,21 @@ defineFunction({
5094
5118
  }
5095
5119
  });
5096
5120
 
5121
+ const isLongVariableName = (group, font) => {
5122
+ if (font !== "mathrm" || group.body.type !== "ordgroup" || group.body.body.length === 1) {
5123
+ return false
5124
+ }
5125
+ if (group.body.body[0].type !== "mathord") { return false }
5126
+ for (let i = 1; i < group.body.body.length; i++) {
5127
+ const parseNodeType = group.body.body[i].type;
5128
+ if (!(parseNodeType === "mathord" ||
5129
+ (parseNodeType === "textord" && !isNaN(group.body.body[i].text)))) {
5130
+ return false
5131
+ }
5132
+ }
5133
+ return true
5134
+ };
5135
+
5097
5136
  const mathmlBuilder$6 = (group, style) => {
5098
5137
  const font = group.font;
5099
5138
  const newStyle = style.withFont(font);
@@ -5105,6 +5144,20 @@ const mathmlBuilder$6 = (group, style) => {
5105
5144
  return mathGroup
5106
5145
  }
5107
5146
  // Check if it is possible to consolidate elements into a single <mi> element.
5147
+ if (isLongVariableName(group, font)) {
5148
+ // This is a \mathrm{…} group. It gets special treatment because symbolsOrd.js
5149
+ // wraps <mi> elements with <mrow>s to work around a Firefox bug.
5150
+ const mi = mathGroup.children[0].children[0];
5151
+ delete mi.attributes.mathvariant;
5152
+ for (let i = 1; i < mathGroup.children.length; i++) {
5153
+ mi.children[0].text += mathGroup.children[i].type === "mn"
5154
+ ? mathGroup.children[i].children[0].text
5155
+ : mathGroup.children[i].children[0].children[0].text;
5156
+ }
5157
+ // Wrap in a <mrow> to prevent the same Firefox bug.
5158
+ const bogus = new mathMLTree.MathNode("mtext", new mathMLTree.TextNode("\u200b"));
5159
+ return new mathMLTree.MathNode("mrow", [bogus, mi])
5160
+ }
5108
5161
  let canConsolidate = mathGroup.children[0].type === "mo";
5109
5162
  for (let i = 1; i < mathGroup.children.length; i++) {
5110
5163
  if (mathGroup.children[i].type === "mo" && font === "boldsymbol") {
@@ -5195,7 +5248,7 @@ defineFunction({
5195
5248
  },
5196
5249
  handler: ({ parser, funcName, breakOnTokenText }, args) => {
5197
5250
  const { mode } = parser;
5198
- const body = parser.parseExpression(true, breakOnTokenText);
5251
+ const body = parser.parseExpression(true, breakOnTokenText, true);
5199
5252
  const fontStyle = `math${funcName.slice(1)}`;
5200
5253
 
5201
5254
  return {
@@ -6156,6 +6209,9 @@ function mathmlBuilder$3(group, style) {
6156
6209
  if (group.isCharacterBox || inner[0].type === "mathord") {
6157
6210
  node = inner[0];
6158
6211
  node.type = "mi";
6212
+ if (node.children.length === 1 && node.children[0].text && node.children[0].text === "∇") {
6213
+ node.setAttribute("mathvariant", "normal");
6214
+ }
6159
6215
  } else {
6160
6216
  node = new mathMLTree.MathNode("mi", inner);
6161
6217
  }
@@ -7143,6 +7199,28 @@ defineFunction({
7143
7199
  }
7144
7200
  });
7145
7201
 
7202
+ defineFunction({
7203
+ type: "reflect",
7204
+ names: ["\\reflectbox"],
7205
+ props: {
7206
+ numArgs: 1,
7207
+ argTypes: ["hbox"],
7208
+ allowedInText: true
7209
+ },
7210
+ handler({ parser }, args) {
7211
+ return {
7212
+ type: "reflect",
7213
+ mode: parser.mode,
7214
+ body: args[0]
7215
+ };
7216
+ },
7217
+ mathmlBuilder(group, style) {
7218
+ const node = buildGroup$1(group.body, style);
7219
+ node.style.transform = "scaleX(-1)";
7220
+ return node
7221
+ }
7222
+ });
7223
+
7146
7224
  defineFunction({
7147
7225
  type: "internal",
7148
7226
  names: ["\\relax"],
@@ -7248,7 +7326,7 @@ defineFunction({
7248
7326
  // eslint-disable-next-line no-console
7249
7327
  console.log(`Temml strict-mode warning: Command ${funcName} is invalid in math mode.`);
7250
7328
  }
7251
- const body = parser.parseExpression(false, breakOnTokenText);
7329
+ const body = parser.parseExpression(false, breakOnTokenText, true);
7252
7330
  return {
7253
7331
  type: "sizing",
7254
7332
  mode: parser.mode,
@@ -7381,7 +7459,7 @@ defineFunction({
7381
7459
  },
7382
7460
  handler({ breakOnTokenText, funcName, parser }, args) {
7383
7461
  // parse out the implicit body
7384
- const body = parser.parseExpression(true, breakOnTokenText);
7462
+ const body = parser.parseExpression(true, breakOnTokenText, true);
7385
7463
 
7386
7464
  const scriptLevel = funcName.slice(1, funcName.length - 5);
7387
7465
  return {
@@ -7812,22 +7890,22 @@ const offset = Object.freeze({
7812
7890
  "sans-serif-bold-italic": ch => { return 0x1D5F5 },
7813
7891
  "monospace": ch => { return 0x1D629 }
7814
7892
  },
7815
- upperCaseGreek: { // A-Ω
7893
+ upperCaseGreek: { // A-Ω
7816
7894
  "normal": ch => { return 0 },
7817
- "bold": ch => { return ch === "∇" ? 0x1B4BA : 0x1D317 },
7818
- "italic": ch => { return ch === "∇" ? 0x1B4F4 : 0x1D351 },
7895
+ "bold": ch => { return 0x1D317 },
7896
+ "italic": ch => { return 0x1D351 },
7819
7897
  // \boldsymbol actually returns upright bold for upperCaseGreek
7820
- "bold-italic": ch => { return ch === "∇" ? 0x1B4BA : 0x1D317 },
7898
+ "bold-italic": ch => { return 0x1D317 },
7821
7899
  "script": ch => { return 0 },
7822
7900
  "script-bold": ch => { return 0 },
7823
7901
  "fraktur": ch => { return 0 },
7824
7902
  "fraktur-bold": ch => { return 0 },
7825
7903
  "double-struck": ch => { return 0 },
7826
7904
  // Unicode has no code points for regular-weight san-serif Greek. Use bold.
7827
- "sans-serif": ch => { return ch === "∇" ? 0x1B568 : 0x1D3C5 },
7828
- "sans-serif-bold": ch => { return ch === "∇" ? 0x1B568 : 0x1D3C5 },
7905
+ "sans-serif": ch => { return 0x1D3C5 },
7906
+ "sans-serif-bold": ch => { return 0x1D3C5 },
7829
7907
  "sans-serif-italic": ch => { return 0 },
7830
- "sans-serif-bold-italic": ch => { return ch === "∇" ? 0x1B5A2 : 0x1D3FF },
7908
+ "sans-serif-bold-italic": ch => { return 0x1D3FF },
7831
7909
  "monospace": ch => { return 0 }
7832
7910
  },
7833
7911
  lowerCaseGreek: { // α-ω
@@ -7887,7 +7965,7 @@ const variantChar = (ch, variant) => {
7887
7965
  ? "upperCaseLatin"
7888
7966
  : 0x60 < codePoint && codePoint < 0x7b
7889
7967
  ? "lowerCaseLatin"
7890
- : (0x390 < codePoint && codePoint < 0x3AA) || ch === "∇"
7968
+ : (0x390 < codePoint && codePoint < 0x3AA)
7891
7969
  ? "upperCaseGreek"
7892
7970
  : 0x3B0 < codePoint && codePoint < 0x3CA || ch === "\u03d5"
7893
7971
  ? "lowerCaseGreek"
@@ -8016,8 +8094,6 @@ defineFunctionBuilders({
8016
8094
  node = new mathMLTree.MathNode("mi", [text]);
8017
8095
  if (text.text === origText && latinRegEx.test(origText)) {
8018
8096
  node.setAttribute("mathvariant", "italic");
8019
- } else if (text.text === "∇" && variant === "normal") {
8020
- node.setAttribute("mathvariant", "normal");
8021
8097
  }
8022
8098
  }
8023
8099
  return node
@@ -8654,6 +8730,24 @@ defineMacro("\\char", function(context) {
8654
8730
  return `\\@char{${number}}`;
8655
8731
  });
8656
8732
 
8733
+ function recreateArgStr(context) {
8734
+ // Recreate the macro's original argument string from the array of parse tokens.
8735
+ const tokens = context.consumeArgs(1)[0];
8736
+ let str = "";
8737
+ let expectedLoc = tokens[tokens.length - 1].loc.start;
8738
+ for (let i = tokens.length - 1; i >= 0; i--) {
8739
+ const actualLoc = tokens[i].loc.start;
8740
+ if (actualLoc > expectedLoc) {
8741
+ // context.consumeArgs has eaten a space.
8742
+ str += " ";
8743
+ expectedLoc = actualLoc;
8744
+ }
8745
+ str += tokens[i].text;
8746
+ expectedLoc += tokens[i].text.length;
8747
+ }
8748
+ return str
8749
+ }
8750
+
8657
8751
  // The Latin Modern font renders <mi>√</mi> at the wrong vertical alignment.
8658
8752
  // This macro provides a better rendering.
8659
8753
  defineMacro("\\surd", '\\sqrt{\\vphantom{|}}');
@@ -8661,10 +8755,6 @@ defineMacro("\\surd", '\\sqrt{\\vphantom{|}}');
8661
8755
  // See comment for \oplus in symbols.js.
8662
8756
  defineMacro("\u2295", "\\oplus");
8663
8757
 
8664
- // Per TeXbook p.122, "/" gets zero operator spacing.
8665
- // And MDN recommends using U+2044 instead of / for inline
8666
- defineMacro("/", "{\u2044}");
8667
-
8668
8758
  // Since Temml has no \par, ignore \long.
8669
8759
  defineMacro("\\long", "");
8670
8760
 
@@ -9042,6 +9132,11 @@ defineMacro("\\argmin", "\\DOTSB\\operatorname*{arg\\,min}");
9042
9132
  defineMacro("\\argmax", "\\DOTSB\\operatorname*{arg\\,max}");
9043
9133
  defineMacro("\\plim", "\\DOTSB\\operatorname*{plim}");
9044
9134
 
9135
+ //////////////////////////////////////////////////////////////////////
9136
+ // MnSymbol.sty
9137
+
9138
+ defineMacro("\\leftmodels", "\\mathop{\\reflectbox{$\\models$}}");
9139
+
9045
9140
  //////////////////////////////////////////////////////////////////////
9046
9141
  // braket.sty
9047
9142
  // http://ctan.math.washington.edu/tex-archive/macros/latex/contrib/braket/braket.pdf
@@ -9051,56 +9146,33 @@ defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}");
9051
9146
  defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}");
9052
9147
  defineMacro("\\Bra", "\\left\\langle#1\\right|");
9053
9148
  defineMacro("\\Ket", "\\left|#1\\right\\rangle");
9054
- const braketHelper = (one) => (context) => {
9055
- const left = context.consumeArg().tokens;
9056
- const middle = context.consumeArg().tokens;
9057
- const middleDouble = context.consumeArg().tokens;
9058
- const right = context.consumeArg().tokens;
9059
- const oldMiddle = context.macros.get("|");
9060
- const oldMiddleDouble = context.macros.get("\\|");
9061
- context.macros.beginGroup();
9062
- const midMacro = (double) => (context) => {
9063
- if (one) {
9064
- // Only modify the first instance of | or \|
9065
- context.macros.set("|", oldMiddle);
9066
- if (middleDouble.length) {
9067
- context.macros.set("\\|", oldMiddleDouble);
9068
- }
9069
- }
9070
- let doubled = double;
9071
- if (!double && middleDouble.length) {
9072
- // Mimic \@ifnextchar
9073
- const nextToken = context.future();
9074
- if (nextToken.text === "|") {
9075
- context.popToken();
9076
- doubled = true;
9077
- }
9078
- }
9079
- return {
9080
- tokens: doubled ? middleDouble : middle,
9081
- numArgs: 0
9082
- };
9083
- };
9084
- context.macros.set("|", midMacro(false));
9085
- if (middleDouble.length) {
9086
- context.macros.set("\\|", midMacro(true));
9087
- }
9088
- const arg = context.consumeArg().tokens;
9089
- const expanded = context.expandTokens([...right, ...arg, ...left]); // reversed
9090
- context.macros.endGroup();
9091
- return {
9092
- tokens: expanded.reverse(),
9093
- numArgs: 0
9094
- };
9149
+ // A helper for \Braket and \Set
9150
+ const replaceVert = (argStr, match) => {
9151
+ const ch = match[0] === "|" ? "\\vert" : "\\Vert";
9152
+ const replaceStr = `}\\,\\middle${ch}\\,{`;
9153
+ return argStr.slice(0, match.index) + replaceStr + argStr.slice(match.index + match[0].length)
9095
9154
  };
9096
- defineMacro("\\bra@ket", braketHelper(false));
9097
- defineMacro("\\bra@set", braketHelper(true));
9098
- defineMacro("\\Braket", "\\bra@ket{\\left\\langle}" +
9099
- "{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");
9100
- defineMacro("\\Set", "\\bra@set{\\left\\{\\:}" +
9101
- "{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");
9102
- defineMacro("\\set", "\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");
9103
- // has no support for special || or \|
9155
+ defineMacro("\\Braket", function(context) {
9156
+ let argStr = recreateArgStr(context);
9157
+ const regEx = /\|\||\||\\\|/g;
9158
+ let match;
9159
+ while ((match = regEx.exec(argStr)) !== null) {
9160
+ argStr = replaceVert(argStr, match);
9161
+ }
9162
+ return "\\left\\langle{" + argStr + "}\\right\\rangle"
9163
+ });
9164
+ defineMacro("\\Set", function(context) {
9165
+ let argStr = recreateArgStr(context);
9166
+ const match = /\|\||\||\\\|/.exec(argStr);
9167
+ if (match) {
9168
+ argStr = replaceVert(argStr, match);
9169
+ }
9170
+ return "\\left\\{\\:{" + argStr + "}\\:\\right\\}"
9171
+ });
9172
+ defineMacro("\\set", function(context) {
9173
+ const argStr = recreateArgStr(context);
9174
+ return "\\{{" + argStr.replace(/\|/, "}\\mid{") + "}\\}"
9175
+ });
9104
9176
 
9105
9177
  //////////////////////////////////////////////////////////////////////
9106
9178
  // actuarialangle.dtx
@@ -12149,8 +12221,12 @@ class Parser {
12149
12221
  * `breakOnTokenText`: The text of the token that the expression should end
12150
12222
  * with, or `null` if something else should end the
12151
12223
  * expression.
12224
+ *
12225
+ * `breakOnMiddle`: \color, \over, and old styling functions work on an implicit group.
12226
+ * These groups end just before the usual tokens, but they also
12227
+ * end just before `\middle`.
12152
12228
  */
12153
- parseExpression(breakOnInfix, breakOnTokenText) {
12229
+ parseExpression(breakOnInfix, breakOnTokenText, breakOnMiddle) {
12154
12230
  const body = [];
12155
12231
  // Keep adding atoms to the body until we can't parse any more atoms (either
12156
12232
  // we reached the end, a }, or a \right)
@@ -12166,6 +12242,9 @@ class Parser {
12166
12242
  if (breakOnTokenText && lex.text === breakOnTokenText) {
12167
12243
  break;
12168
12244
  }
12245
+ if (breakOnMiddle && lex.text === "\\middle") {
12246
+ break
12247
+ }
12169
12248
  if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) {
12170
12249
  break;
12171
12250
  }
@@ -13144,7 +13223,7 @@ class Style {
13144
13223
  * https://mit-license.org/
13145
13224
  */
13146
13225
 
13147
- const version = "0.10.21";
13226
+ const version = "0.10.23";
13148
13227
 
13149
13228
  function postProcess(block) {
13150
13229
  const labelMap = {};
package/dist/temml.d.ts CHANGED
@@ -41,7 +41,7 @@ declare class ParseError {
41
41
  constructor(
42
42
  message: string, // The error message
43
43
  token: any, // An object providing position information
44
- ) {}
44
+ );
45
45
  }
46
46
 
47
47
  declare const Temml: {