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