temml 0.10.20 → 0.10.22

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.
@@ -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
  }
@@ -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);
@@ -1408,6 +1410,7 @@ defineSymbol(math, mathord, "\u2aeb", "\\Bot");
1408
1410
  defineSymbol(math, bin, "\u2217", "\u2217", true);
1409
1411
  defineSymbol(math, bin, "+", "+");
1410
1412
  defineSymbol(math, bin, "*", "*");
1413
+ defineSymbol(math, bin, "\u2044", "/", true);
1411
1414
  defineSymbol(math, bin, "\u2044", "\u2044");
1412
1415
  defineSymbol(math, bin, "\u2212", "-", true);
1413
1416
  defineSymbol(math, bin, "\u22c5", "\\cdot", true);
@@ -1864,7 +1867,8 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
1864
1867
  continue
1865
1868
  }
1866
1869
  block.push(node);
1867
- if (node.type && node.type === "mo" && node.children.length === 1) {
1870
+ if (node.type && node.type === "mo" && node.children.length === 1 &&
1871
+ !Object.hasOwn(node.attributes, "movablelimits")) {
1868
1872
  const ch = node.children[0].text;
1869
1873
  if (openDelims.indexOf(ch) > -1) {
1870
1874
  level += 1;
@@ -1879,7 +1883,7 @@ function setLineBreaks(expression, wrapMode, isDisplayMode) {
1879
1883
  mrows.push(element);
1880
1884
  block = [node];
1881
1885
  }
1882
- } else if (level === 0 && wrapMode === "tex") {
1886
+ } else if (level === 0 && wrapMode === "tex" && ch !== "∇") {
1883
1887
  // Check if the following node is a \nobreak text node, e.g. "~""
1884
1888
  const next = i < expression.length - 1 ? expression[i + 1] : null;
1885
1889
  let glueIsFreeOfNobreak = true;
@@ -3247,7 +3251,7 @@ defineFunction({
3247
3251
  allowedInText: true,
3248
3252
  argTypes: ["raw", "raw"]
3249
3253
  },
3250
- handler({ parser, token }, args, optArgs) {
3254
+ handler({ parser, breakOnTokenText, token }, args, optArgs) {
3251
3255
  const model = optArgs[0] && assertNodeType(optArgs[0], "raw").string;
3252
3256
  let color = "";
3253
3257
  if (model) {
@@ -3257,15 +3261,8 @@ defineFunction({
3257
3261
  color = validateColor(assertNodeType(args[0], "raw").string, parser.gullet.macros, token);
3258
3262
  }
3259
3263
 
3260
- // Set macro \current@color in current namespace to store the current
3261
- // color, mimicking the behavior of color.sty.
3262
- // This is currently used just to correctly color a \right
3263
- // that follows a \color command.
3264
- parser.gullet.macros.set("\\current@color", color);
3265
-
3266
3264
  // Parse out the implicit body that should be colored.
3267
- // Since \color nodes should not be nested, break on \color.
3268
- const body = parser.parseExpression(true, "\\color");
3265
+ const body = parser.parseExpression(true, breakOnTokenText, true);
3269
3266
 
3270
3267
  return {
3271
3268
  type: "color",
@@ -3707,17 +3704,13 @@ const sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
3707
3704
 
3708
3705
  // Delimiter functions
3709
3706
  function checkDelimiter(delim, context) {
3710
- if (delim.type === "ordgroup" && delim.body.length === 1 && delim.body[0].text === "\u2044") {
3711
- // Recover "/" from the zero spacing group. (See macros.js)
3712
- delim = { type: "textord", text: "/", mode: "math" };
3713
- }
3714
3707
  const symDelim = checkSymbolNodeType(delim);
3715
3708
  if (symDelim && delimiters.includes(symDelim.text)) {
3716
3709
  // If a character is not in the MathML operator dictionary, it will not stretch.
3717
3710
  // Replace such characters w/characters that will stretch.
3711
+ if (["/", "\u2044"].includes(symDelim.text)) { symDelim.text = "\u2215"; }
3718
3712
  if (["<", "\\lt"].includes(symDelim.text)) { symDelim.text = "⟨"; }
3719
3713
  if ([">", "\\gt"].includes(symDelim.text)) { symDelim.text = "⟩"; }
3720
- if (symDelim.text === "/") { symDelim.text = "\u2215"; }
3721
3714
  if (symDelim.text === "\\backslash") { symDelim.text = "\u2216"; }
3722
3715
  return symDelim;
3723
3716
  } else if (symDelim) {
@@ -3805,18 +3798,10 @@ defineFunction({
3805
3798
  argTypes: ["primitive"]
3806
3799
  },
3807
3800
  handler: (context, args) => {
3808
- // \left case below triggers parsing of \right in
3809
- // `const right = parser.parseFunction();`
3810
- // uses this return value.
3811
- const color = context.parser.gullet.macros.get("\\current@color");
3812
- if (color && typeof color !== "string") {
3813
- throw new ParseError("\\current@color set to non-string in \\right");
3814
- }
3815
3801
  return {
3816
3802
  type: "leftright-right",
3817
3803
  mode: context.parser.mode,
3818
- delim: checkDelimiter(args[0], context).text,
3819
- color // undefined if not set via \color
3804
+ delim: checkDelimiter(args[0], context).text
3820
3805
  };
3821
3806
  }
3822
3807
  });
@@ -3834,8 +3819,26 @@ defineFunction({
3834
3819
  const parser = context.parser;
3835
3820
  // Parse out the implicit body
3836
3821
  ++parser.leftrightDepth;
3837
- // parseExpression stops before '\\right'
3838
- const body = parser.parseExpression(false);
3822
+ // parseExpression stops before '\\right' or `\\middle`
3823
+ let body = parser.parseExpression(false, null, true);
3824
+ let nextToken = parser.fetch();
3825
+ while (nextToken.text === "\\middle") {
3826
+ // `\middle`, from the ε-TeX package, ends one group and starts another group.
3827
+ // We had to parse this expression with `breakOnMiddle` enabled in order
3828
+ // to get TeX-compliant parsing of \over.
3829
+ // But we do not want, at this point, to end on \middle, so continue
3830
+ // to parse until we fetch a `\right`.
3831
+ parser.consume();
3832
+ const middle = parser.fetch().text;
3833
+ if (!symbols.math[middle]) {
3834
+ throw new ParseError(`Invalid delimiter '${middle}' after '\\middle'`);
3835
+ }
3836
+ checkDelimiter({ type: "atom", mode: "math", text: middle }, { funcName: "\\middle" });
3837
+ body.push({ type: "middle", mode: "math", delim: middle });
3838
+ parser.consume();
3839
+ body = body.concat(parser.parseExpression(false, null, true));
3840
+ nextToken = parser.fetch();
3841
+ }
3839
3842
  --parser.leftrightDepth;
3840
3843
  // Check the next token
3841
3844
  parser.expect("\\right", false);
@@ -3845,8 +3848,7 @@ defineFunction({
3845
3848
  mode: parser.mode,
3846
3849
  body,
3847
3850
  left: delim.text,
3848
- right: right.delim,
3849
- rightColor: right.color
3851
+ right: right.delim
3850
3852
  };
3851
3853
  },
3852
3854
  mathmlBuilder: (group, style) => {
@@ -3869,7 +3871,6 @@ defineFunction({
3869
3871
  if (group.right === "\u2216" || group.right.indexOf("arrow") > -1) {
3870
3872
  rightNode.setAttribute("stretchy", "true");
3871
3873
  }
3872
- if (group.rightColor) { rightNode.style.color = group.rightColor; }
3873
3874
  inner.push(rightNode);
3874
3875
 
3875
3876
  return makeRow(inner);
@@ -5212,7 +5213,7 @@ defineFunction({
5212
5213
  },
5213
5214
  handler: ({ parser, funcName, breakOnTokenText }, args) => {
5214
5215
  const { mode } = parser;
5215
- const body = parser.parseExpression(true, breakOnTokenText);
5216
+ const body = parser.parseExpression(true, breakOnTokenText, true);
5216
5217
  const fontStyle = `math${funcName.slice(1)}`;
5217
5218
 
5218
5219
  return {
@@ -6173,6 +6174,9 @@ function mathmlBuilder$3(group, style) {
6173
6174
  if (group.isCharacterBox || inner[0].type === "mathord") {
6174
6175
  node = inner[0];
6175
6176
  node.type = "mi";
6177
+ if (node.children.length === 1 && node.children[0].text && node.children[0].text === "∇") {
6178
+ node.setAttribute("mathvariant", "normal");
6179
+ }
6176
6180
  } else {
6177
6181
  node = new mathMLTree.MathNode("mi", inner);
6178
6182
  }
@@ -7160,6 +7164,28 @@ defineFunction({
7160
7164
  }
7161
7165
  });
7162
7166
 
7167
+ defineFunction({
7168
+ type: "reflect",
7169
+ names: ["\\reflectbox"],
7170
+ props: {
7171
+ numArgs: 1,
7172
+ argTypes: ["hbox"],
7173
+ allowedInText: true
7174
+ },
7175
+ handler({ parser }, args) {
7176
+ return {
7177
+ type: "reflect",
7178
+ mode: parser.mode,
7179
+ body: args[0]
7180
+ };
7181
+ },
7182
+ mathmlBuilder(group, style) {
7183
+ const node = buildGroup$1(group.body, style);
7184
+ node.style.transform = "scaleX(-1)";
7185
+ return node
7186
+ }
7187
+ });
7188
+
7163
7189
  defineFunction({
7164
7190
  type: "internal",
7165
7191
  names: ["\\relax"],
@@ -7265,7 +7291,7 @@ defineFunction({
7265
7291
  // eslint-disable-next-line no-console
7266
7292
  console.log(`Temml strict-mode warning: Command ${funcName} is invalid in math mode.`);
7267
7293
  }
7268
- const body = parser.parseExpression(false, breakOnTokenText);
7294
+ const body = parser.parseExpression(false, breakOnTokenText, true);
7269
7295
  return {
7270
7296
  type: "sizing",
7271
7297
  mode: parser.mode,
@@ -7398,7 +7424,7 @@ defineFunction({
7398
7424
  },
7399
7425
  handler({ breakOnTokenText, funcName, parser }, args) {
7400
7426
  // parse out the implicit body
7401
- const body = parser.parseExpression(true, breakOnTokenText);
7427
+ const body = parser.parseExpression(true, breakOnTokenText, true);
7402
7428
 
7403
7429
  const scriptLevel = funcName.slice(1, funcName.length - 5);
7404
7430
  return {
@@ -7829,22 +7855,22 @@ const offset = Object.freeze({
7829
7855
  "sans-serif-bold-italic": ch => { return 0x1D5F5 },
7830
7856
  "monospace": ch => { return 0x1D629 }
7831
7857
  },
7832
- upperCaseGreek: { // A-Ω
7858
+ upperCaseGreek: { // A-Ω
7833
7859
  "normal": ch => { return 0 },
7834
- "bold": ch => { return ch === "∇" ? 0x1B4BA : 0x1D317 },
7835
- "italic": ch => { return ch === "∇" ? 0x1B4F4 : 0x1D351 },
7860
+ "bold": ch => { return 0x1D317 },
7861
+ "italic": ch => { return 0x1D351 },
7836
7862
  // \boldsymbol actually returns upright bold for upperCaseGreek
7837
- "bold-italic": ch => { return ch === "∇" ? 0x1B4BA : 0x1D317 },
7863
+ "bold-italic": ch => { return 0x1D317 },
7838
7864
  "script": ch => { return 0 },
7839
7865
  "script-bold": ch => { return 0 },
7840
7866
  "fraktur": ch => { return 0 },
7841
7867
  "fraktur-bold": ch => { return 0 },
7842
7868
  "double-struck": ch => { return 0 },
7843
7869
  // Unicode has no code points for regular-weight san-serif Greek. Use bold.
7844
- "sans-serif": ch => { return ch === "∇" ? 0x1B568 : 0x1D3C5 },
7845
- "sans-serif-bold": ch => { return ch === "∇" ? 0x1B568 : 0x1D3C5 },
7870
+ "sans-serif": ch => { return 0x1D3C5 },
7871
+ "sans-serif-bold": ch => { return 0x1D3C5 },
7846
7872
  "sans-serif-italic": ch => { return 0 },
7847
- "sans-serif-bold-italic": ch => { return ch === "∇" ? 0x1B5A2 : 0x1D3FF },
7873
+ "sans-serif-bold-italic": ch => { return 0x1D3FF },
7848
7874
  "monospace": ch => { return 0 }
7849
7875
  },
7850
7876
  lowerCaseGreek: { // α-ω
@@ -7904,7 +7930,7 @@ const variantChar = (ch, variant) => {
7904
7930
  ? "upperCaseLatin"
7905
7931
  : 0x60 < codePoint && codePoint < 0x7b
7906
7932
  ? "lowerCaseLatin"
7907
- : (0x390 < codePoint && codePoint < 0x3AA) || ch === "∇"
7933
+ : (0x390 < codePoint && codePoint < 0x3AA)
7908
7934
  ? "upperCaseGreek"
7909
7935
  : 0x3B0 < codePoint && codePoint < 0x3CA || ch === "\u03d5"
7910
7936
  ? "lowerCaseGreek"
@@ -8033,8 +8059,6 @@ defineFunctionBuilders({
8033
8059
  node = new mathMLTree.MathNode("mi", [text]);
8034
8060
  if (text.text === origText && latinRegEx.test(origText)) {
8035
8061
  node.setAttribute("mathvariant", "italic");
8036
- } else if (text.text === "∇" && variant === "normal") {
8037
- node.setAttribute("mathvariant", "normal");
8038
8062
  }
8039
8063
  }
8040
8064
  return node
@@ -8671,6 +8695,24 @@ defineMacro("\\char", function(context) {
8671
8695
  return `\\@char{${number}}`;
8672
8696
  });
8673
8697
 
8698
+ function recreateArgStr(context) {
8699
+ // Recreate the macro's original argument string from the array of parse tokens.
8700
+ const tokens = context.consumeArgs(1)[0];
8701
+ let str = "";
8702
+ let expectedLoc = tokens[tokens.length - 1].loc.start;
8703
+ for (let i = tokens.length - 1; i >= 0; i--) {
8704
+ const actualLoc = tokens[i].loc.start;
8705
+ if (actualLoc > expectedLoc) {
8706
+ // context.consumeArgs has eaten a space.
8707
+ str += " ";
8708
+ expectedLoc = actualLoc;
8709
+ }
8710
+ str += tokens[i].text;
8711
+ expectedLoc += tokens[i].text.length;
8712
+ }
8713
+ return str
8714
+ }
8715
+
8674
8716
  // The Latin Modern font renders <mi>√</mi> at the wrong vertical alignment.
8675
8717
  // This macro provides a better rendering.
8676
8718
  defineMacro("\\surd", '\\sqrt{\\vphantom{|}}');
@@ -8678,10 +8720,6 @@ defineMacro("\\surd", '\\sqrt{\\vphantom{|}}');
8678
8720
  // See comment for \oplus in symbols.js.
8679
8721
  defineMacro("\u2295", "\\oplus");
8680
8722
 
8681
- // Per TeXbook p.122, "/" gets zero operator spacing.
8682
- // And MDN recommends using U+2044 instead of / for inline
8683
- defineMacro("/", "{\u2044}");
8684
-
8685
8723
  // Since Temml has no \par, ignore \long.
8686
8724
  defineMacro("\\long", "");
8687
8725
 
@@ -9059,6 +9097,11 @@ defineMacro("\\argmin", "\\DOTSB\\operatorname*{arg\\,min}");
9059
9097
  defineMacro("\\argmax", "\\DOTSB\\operatorname*{arg\\,max}");
9060
9098
  defineMacro("\\plim", "\\DOTSB\\operatorname*{plim}");
9061
9099
 
9100
+ //////////////////////////////////////////////////////////////////////
9101
+ // MnSymbol.sty
9102
+
9103
+ defineMacro("\\leftmodels", "\\mathop{\\reflectbox{$\\models$}}");
9104
+
9062
9105
  //////////////////////////////////////////////////////////////////////
9063
9106
  // braket.sty
9064
9107
  // http://ctan.math.washington.edu/tex-archive/macros/latex/contrib/braket/braket.pdf
@@ -9068,56 +9111,33 @@ defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}");
9068
9111
  defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}");
9069
9112
  defineMacro("\\Bra", "\\left\\langle#1\\right|");
9070
9113
  defineMacro("\\Ket", "\\left|#1\\right\\rangle");
9071
- const braketHelper = (one) => (context) => {
9072
- const left = context.consumeArg().tokens;
9073
- const middle = context.consumeArg().tokens;
9074
- const middleDouble = context.consumeArg().tokens;
9075
- const right = context.consumeArg().tokens;
9076
- const oldMiddle = context.macros.get("|");
9077
- const oldMiddleDouble = context.macros.get("\\|");
9078
- context.macros.beginGroup();
9079
- const midMacro = (double) => (context) => {
9080
- if (one) {
9081
- // Only modify the first instance of | or \|
9082
- context.macros.set("|", oldMiddle);
9083
- if (middleDouble.length) {
9084
- context.macros.set("\\|", oldMiddleDouble);
9085
- }
9086
- }
9087
- let doubled = double;
9088
- if (!double && middleDouble.length) {
9089
- // Mimic \@ifnextchar
9090
- const nextToken = context.future();
9091
- if (nextToken.text === "|") {
9092
- context.popToken();
9093
- doubled = true;
9094
- }
9095
- }
9096
- return {
9097
- tokens: doubled ? middleDouble : middle,
9098
- numArgs: 0
9099
- };
9100
- };
9101
- context.macros.set("|", midMacro(false));
9102
- if (middleDouble.length) {
9103
- context.macros.set("\\|", midMacro(true));
9104
- }
9105
- const arg = context.consumeArg().tokens;
9106
- const expanded = context.expandTokens([...right, ...arg, ...left]); // reversed
9107
- context.macros.endGroup();
9108
- return {
9109
- tokens: expanded.reverse(),
9110
- numArgs: 0
9111
- };
9114
+ // A helper for \Braket and \Set
9115
+ const replaceVert = (argStr, match) => {
9116
+ const ch = match[0] === "|" ? "\\vert" : "\\Vert";
9117
+ const replaceStr = `}\\,\\middle${ch}\\,{`;
9118
+ return argStr.slice(0, match.index) + replaceStr + argStr.slice(match.index + match[0].length)
9112
9119
  };
9113
- defineMacro("\\bra@ket", braketHelper(false));
9114
- defineMacro("\\bra@set", braketHelper(true));
9115
- defineMacro("\\Braket", "\\bra@ket{\\left\\langle}" +
9116
- "{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");
9117
- defineMacro("\\Set", "\\bra@set{\\left\\{\\:}" +
9118
- "{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");
9119
- defineMacro("\\set", "\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");
9120
- // has no support for special || or \|
9120
+ defineMacro("\\Braket", function(context) {
9121
+ let argStr = recreateArgStr(context);
9122
+ const regEx = /\|\||\||\\\|/g;
9123
+ let match;
9124
+ while ((match = regEx.exec(argStr)) !== null) {
9125
+ argStr = replaceVert(argStr, match);
9126
+ }
9127
+ return "\\left\\langle{" + argStr + "}\\right\\rangle"
9128
+ });
9129
+ defineMacro("\\Set", function(context) {
9130
+ let argStr = recreateArgStr(context);
9131
+ const match = /\|\||\||\\\|/.exec(argStr);
9132
+ if (match) {
9133
+ argStr = replaceVert(argStr, match);
9134
+ }
9135
+ return "\\left\\{\\:{" + argStr + "}\\:\\right\\}"
9136
+ });
9137
+ defineMacro("\\set", function(context) {
9138
+ const argStr = recreateArgStr(context);
9139
+ return "\\{{" + argStr.replace(/\|/, "}\\mid{") + "}\\}"
9140
+ });
9121
9141
 
9122
9142
  //////////////////////////////////////////////////////////////////////
9123
9143
  // actuarialangle.dtx
@@ -12166,8 +12186,12 @@ class Parser {
12166
12186
  * `breakOnTokenText`: The text of the token that the expression should end
12167
12187
  * with, or `null` if something else should end the
12168
12188
  * expression.
12189
+ *
12190
+ * `breakOnMiddle`: \color, \over, and old styling functions work on an implicit group.
12191
+ * These groups end just before the usual tokens, but they also
12192
+ * end just before `\middle`.
12169
12193
  */
12170
- parseExpression(breakOnInfix, breakOnTokenText) {
12194
+ parseExpression(breakOnInfix, breakOnTokenText, breakOnMiddle) {
12171
12195
  const body = [];
12172
12196
  // Keep adding atoms to the body until we can't parse any more atoms (either
12173
12197
  // we reached the end, a }, or a \right)
@@ -12183,6 +12207,9 @@ class Parser {
12183
12207
  if (breakOnTokenText && lex.text === breakOnTokenText) {
12184
12208
  break;
12185
12209
  }
12210
+ if (breakOnMiddle && lex.text === "\\middle") {
12211
+ break
12212
+ }
12186
12213
  if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) {
12187
12214
  break;
12188
12215
  }
@@ -13161,7 +13188,7 @@ class Style {
13161
13188
  * https://mit-license.org/
13162
13189
  */
13163
13190
 
13164
- const version = "0.10.20";
13191
+ const version = "0.10.22";
13165
13192
 
13166
13193
  function postProcess(block) {
13167
13194
  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: {