temml 0.10.21 → 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;
@@ -3258,7 +3262,7 @@ defineFunction({
3258
3262
  }
3259
3263
 
3260
3264
  // Parse out the implicit body that should be colored.
3261
- const body = parser.parseExpression(true, breakOnTokenText);
3265
+ const body = parser.parseExpression(true, breakOnTokenText, true);
3262
3266
 
3263
3267
  return {
3264
3268
  type: "color",
@@ -3700,17 +3704,13 @@ const sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
3700
3704
 
3701
3705
  // Delimiter functions
3702
3706
  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
3707
  const symDelim = checkSymbolNodeType(delim);
3708
3708
  if (symDelim && delimiters.includes(symDelim.text)) {
3709
3709
  // If a character is not in the MathML operator dictionary, it will not stretch.
3710
3710
  // Replace such characters w/characters that will stretch.
3711
+ if (["/", "\u2044"].includes(symDelim.text)) { symDelim.text = "\u2215"; }
3711
3712
  if (["<", "\\lt"].includes(symDelim.text)) { symDelim.text = "⟨"; }
3712
3713
  if ([">", "\\gt"].includes(symDelim.text)) { symDelim.text = "⟩"; }
3713
- if (symDelim.text === "/") { symDelim.text = "\u2215"; }
3714
3714
  if (symDelim.text === "\\backslash") { symDelim.text = "\u2216"; }
3715
3715
  return symDelim;
3716
3716
  } else if (symDelim) {
@@ -3819,8 +3819,26 @@ defineFunction({
3819
3819
  const parser = context.parser;
3820
3820
  // Parse out the implicit body
3821
3821
  ++parser.leftrightDepth;
3822
- // parseExpression stops before '\\right'
3823
- 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
+ }
3824
3842
  --parser.leftrightDepth;
3825
3843
  // Check the next token
3826
3844
  parser.expect("\\right", false);
@@ -5195,7 +5213,7 @@ defineFunction({
5195
5213
  },
5196
5214
  handler: ({ parser, funcName, breakOnTokenText }, args) => {
5197
5215
  const { mode } = parser;
5198
- const body = parser.parseExpression(true, breakOnTokenText);
5216
+ const body = parser.parseExpression(true, breakOnTokenText, true);
5199
5217
  const fontStyle = `math${funcName.slice(1)}`;
5200
5218
 
5201
5219
  return {
@@ -6156,6 +6174,9 @@ function mathmlBuilder$3(group, style) {
6156
6174
  if (group.isCharacterBox || inner[0].type === "mathord") {
6157
6175
  node = inner[0];
6158
6176
  node.type = "mi";
6177
+ if (node.children.length === 1 && node.children[0].text && node.children[0].text === "∇") {
6178
+ node.setAttribute("mathvariant", "normal");
6179
+ }
6159
6180
  } else {
6160
6181
  node = new mathMLTree.MathNode("mi", inner);
6161
6182
  }
@@ -7143,6 +7164,28 @@ defineFunction({
7143
7164
  }
7144
7165
  });
7145
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
+
7146
7189
  defineFunction({
7147
7190
  type: "internal",
7148
7191
  names: ["\\relax"],
@@ -7248,7 +7291,7 @@ defineFunction({
7248
7291
  // eslint-disable-next-line no-console
7249
7292
  console.log(`Temml strict-mode warning: Command ${funcName} is invalid in math mode.`);
7250
7293
  }
7251
- const body = parser.parseExpression(false, breakOnTokenText);
7294
+ const body = parser.parseExpression(false, breakOnTokenText, true);
7252
7295
  return {
7253
7296
  type: "sizing",
7254
7297
  mode: parser.mode,
@@ -7381,7 +7424,7 @@ defineFunction({
7381
7424
  },
7382
7425
  handler({ breakOnTokenText, funcName, parser }, args) {
7383
7426
  // parse out the implicit body
7384
- const body = parser.parseExpression(true, breakOnTokenText);
7427
+ const body = parser.parseExpression(true, breakOnTokenText, true);
7385
7428
 
7386
7429
  const scriptLevel = funcName.slice(1, funcName.length - 5);
7387
7430
  return {
@@ -7812,22 +7855,22 @@ const offset = Object.freeze({
7812
7855
  "sans-serif-bold-italic": ch => { return 0x1D5F5 },
7813
7856
  "monospace": ch => { return 0x1D629 }
7814
7857
  },
7815
- upperCaseGreek: { // A-Ω
7858
+ upperCaseGreek: { // A-Ω
7816
7859
  "normal": ch => { return 0 },
7817
- "bold": ch => { return ch === "∇" ? 0x1B4BA : 0x1D317 },
7818
- "italic": ch => { return ch === "∇" ? 0x1B4F4 : 0x1D351 },
7860
+ "bold": ch => { return 0x1D317 },
7861
+ "italic": ch => { return 0x1D351 },
7819
7862
  // \boldsymbol actually returns upright bold for upperCaseGreek
7820
- "bold-italic": ch => { return ch === "∇" ? 0x1B4BA : 0x1D317 },
7863
+ "bold-italic": ch => { return 0x1D317 },
7821
7864
  "script": ch => { return 0 },
7822
7865
  "script-bold": ch => { return 0 },
7823
7866
  "fraktur": ch => { return 0 },
7824
7867
  "fraktur-bold": ch => { return 0 },
7825
7868
  "double-struck": ch => { return 0 },
7826
7869
  // 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 },
7870
+ "sans-serif": ch => { return 0x1D3C5 },
7871
+ "sans-serif-bold": ch => { return 0x1D3C5 },
7829
7872
  "sans-serif-italic": ch => { return 0 },
7830
- "sans-serif-bold-italic": ch => { return ch === "∇" ? 0x1B5A2 : 0x1D3FF },
7873
+ "sans-serif-bold-italic": ch => { return 0x1D3FF },
7831
7874
  "monospace": ch => { return 0 }
7832
7875
  },
7833
7876
  lowerCaseGreek: { // α-ω
@@ -7887,7 +7930,7 @@ const variantChar = (ch, variant) => {
7887
7930
  ? "upperCaseLatin"
7888
7931
  : 0x60 < codePoint && codePoint < 0x7b
7889
7932
  ? "lowerCaseLatin"
7890
- : (0x390 < codePoint && codePoint < 0x3AA) || ch === "∇"
7933
+ : (0x390 < codePoint && codePoint < 0x3AA)
7891
7934
  ? "upperCaseGreek"
7892
7935
  : 0x3B0 < codePoint && codePoint < 0x3CA || ch === "\u03d5"
7893
7936
  ? "lowerCaseGreek"
@@ -8016,8 +8059,6 @@ defineFunctionBuilders({
8016
8059
  node = new mathMLTree.MathNode("mi", [text]);
8017
8060
  if (text.text === origText && latinRegEx.test(origText)) {
8018
8061
  node.setAttribute("mathvariant", "italic");
8019
- } else if (text.text === "∇" && variant === "normal") {
8020
- node.setAttribute("mathvariant", "normal");
8021
8062
  }
8022
8063
  }
8023
8064
  return node
@@ -8654,6 +8695,24 @@ defineMacro("\\char", function(context) {
8654
8695
  return `\\@char{${number}}`;
8655
8696
  });
8656
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
+
8657
8716
  // The Latin Modern font renders <mi>√</mi> at the wrong vertical alignment.
8658
8717
  // This macro provides a better rendering.
8659
8718
  defineMacro("\\surd", '\\sqrt{\\vphantom{|}}');
@@ -8661,10 +8720,6 @@ defineMacro("\\surd", '\\sqrt{\\vphantom{|}}');
8661
8720
  // See comment for \oplus in symbols.js.
8662
8721
  defineMacro("\u2295", "\\oplus");
8663
8722
 
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
8723
  // Since Temml has no \par, ignore \long.
8669
8724
  defineMacro("\\long", "");
8670
8725
 
@@ -9042,6 +9097,11 @@ defineMacro("\\argmin", "\\DOTSB\\operatorname*{arg\\,min}");
9042
9097
  defineMacro("\\argmax", "\\DOTSB\\operatorname*{arg\\,max}");
9043
9098
  defineMacro("\\plim", "\\DOTSB\\operatorname*{plim}");
9044
9099
 
9100
+ //////////////////////////////////////////////////////////////////////
9101
+ // MnSymbol.sty
9102
+
9103
+ defineMacro("\\leftmodels", "\\mathop{\\reflectbox{$\\models$}}");
9104
+
9045
9105
  //////////////////////////////////////////////////////////////////////
9046
9106
  // braket.sty
9047
9107
  // http://ctan.math.washington.edu/tex-archive/macros/latex/contrib/braket/braket.pdf
@@ -9051,56 +9111,33 @@ defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}");
9051
9111
  defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}");
9052
9112
  defineMacro("\\Bra", "\\left\\langle#1\\right|");
9053
9113
  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
- };
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)
9095
9119
  };
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 \|
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
+ });
9104
9141
 
9105
9142
  //////////////////////////////////////////////////////////////////////
9106
9143
  // actuarialangle.dtx
@@ -12149,8 +12186,12 @@ class Parser {
12149
12186
  * `breakOnTokenText`: The text of the token that the expression should end
12150
12187
  * with, or `null` if something else should end the
12151
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`.
12152
12193
  */
12153
- parseExpression(breakOnInfix, breakOnTokenText) {
12194
+ parseExpression(breakOnInfix, breakOnTokenText, breakOnMiddle) {
12154
12195
  const body = [];
12155
12196
  // Keep adding atoms to the body until we can't parse any more atoms (either
12156
12197
  // we reached the end, a }, or a \right)
@@ -12166,6 +12207,9 @@ class Parser {
12166
12207
  if (breakOnTokenText && lex.text === breakOnTokenText) {
12167
12208
  break;
12168
12209
  }
12210
+ if (breakOnMiddle && lex.text === "\\middle") {
12211
+ break
12212
+ }
12169
12213
  if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) {
12170
12214
  break;
12171
12215
  }
@@ -13144,7 +13188,7 @@ class Style {
13144
13188
  * https://mit-license.org/
13145
13189
  */
13146
13190
 
13147
- const version = "0.10.21";
13191
+ const version = "0.10.22";
13148
13192
 
13149
13193
  function postProcess(block) {
13150
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: {