temml 0.10.0 → 0.10.2

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.
@@ -104,7 +104,7 @@ describe("A delimiter splitter", function() {
104
104
  ]);
105
105
  });
106
106
 
107
- it("splits mutliple times", function() {
107
+ it("splits multiple times", function() {
108
108
  expect("hello ( world ) boo ( more ) stuff").toSplitInto("(", ")", [
109
109
  { type: "text", data: "hello " },
110
110
  { type: "math", data: " world ", rawData: "( world )", display: false },
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable */
2
- /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
2
+ /* -*- Mode: JavaScript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
3
3
  /* vim: set ts=2 et sw=2 tw=80: */
4
4
 
5
5
  /*************************************************************
@@ -1696,7 +1696,7 @@ temml.__defineMacro("\\tripleDashBetweenDoubleLine", `\\kern0.075em\\mathrlap{\\
1696
1696
  };
1697
1697
 
1698
1698
  //
1699
- // Helpers for code anaylsis
1699
+ // Helpers for code analysis
1700
1700
  // Will show type error at calling position
1701
1701
  //
1702
1702
  /** @param {number} a */
package/dist/temml.cjs CHANGED
@@ -668,7 +668,7 @@ class TextNode {
668
668
 
669
669
  /**
670
670
  * Converts the text node into a string
671
- * (representing the text iteself).
671
+ * (representing the text itself).
672
672
  */
673
673
  toText() {
674
674
  return this.text;
@@ -845,7 +845,6 @@ defineSymbol(math, rel, "\u226a", "\\ll", true);
845
845
  defineSymbol(math, rel, "\u226b", "\\gg", true);
846
846
  defineSymbol(math, rel, "\u224d", "\\asymp", true);
847
847
  defineSymbol(math, rel, "\u2225", "\\parallel");
848
- defineSymbol(math, rel, "\u22c8", "\\bowtie", true);
849
848
  defineSymbol(math, rel, "\u2323", "\\smile", true);
850
849
  defineSymbol(math, rel, "\u2291", "\\sqsubseteq", true);
851
850
  defineSymbol(math, rel, "\u2292", "\\sqsupseteq", true);
@@ -1162,7 +1161,6 @@ defineSymbol(math, rel, "\u22d9", "\\gggtr");
1162
1161
  defineSymbol(math, bin, "\u22b2", "\\lhd");
1163
1162
  defineSymbol(math, bin, "\u22b3", "\\rhd");
1164
1163
  defineSymbol(math, rel, "\u2242", "\\eqsim", true);
1165
- defineSymbol(math, rel, "\u22c8", "\\Join");
1166
1164
  defineSymbol(math, rel, "\u2251", "\\Doteq", true);
1167
1165
  defineSymbol(math, rel, "\u297d", "\\strictif", true);
1168
1166
  defineSymbol(math, rel, "\u297c", "\\strictfi", true);
@@ -1188,6 +1186,11 @@ defineSymbol(math, bin, "\u22ba", "\\intercal", true);
1188
1186
  defineSymbol(math, bin, "\u22d2", "\\doublecap");
1189
1187
  defineSymbol(math, bin, "\u22d3", "\\doublecup");
1190
1188
  defineSymbol(math, bin, "\u22a0", "\\boxtimes", true);
1189
+ defineSymbol(math, bin, "\u22c8", "\\bowtie", true);
1190
+ defineSymbol(math, bin, "\u22c8", "\\Join");
1191
+ defineSymbol(math, bin, "\u27d5", "\\leftouterjoin", true);
1192
+ defineSymbol(math, bin, "\u27d6", "\\rightouterjoin", true);
1193
+ defineSymbol(math, bin, "\u27d7", "\\fullouterjoin", true);
1191
1194
 
1192
1195
  // AMS Arrows
1193
1196
  // Note: unicode-math maps \u21e2 to their own function \rightdasharrow.
@@ -1892,7 +1895,7 @@ function setLineBreaks(expression, wrapMode, isDisplayMode, color) {
1892
1895
  }
1893
1896
 
1894
1897
  /**
1895
- * This file converts a parse tree into a cooresponding MathML tree. The main
1898
+ * This file converts a parse tree into a corresponding MathML tree. The main
1896
1899
  * entry point is the `buildMathML` function, which takes a parse tree from the
1897
1900
  * parser.
1898
1901
  */
@@ -3523,6 +3526,11 @@ const delimiters = [
3523
3526
  "."
3524
3527
  ];
3525
3528
 
3529
+ // Export isDelimiter for benefit of parser.
3530
+ const dels = ["}", "\\left", "\\middle", "\\right"];
3531
+ const isDelimiter = str => str.length > 0 &&
3532
+ (delimiters.includes(str) || delimiterSizes[str] || dels.includes(str));
3533
+
3526
3534
  // Metrics of the different sizes. Found by looking at TeX's output of
3527
3535
  // $\bigl| // \Bigl| \biggl| \Biggl| \showlists$
3528
3536
  // Used to create stacked delimiters of appropriate sizes in makeSizedDelim.
@@ -6205,10 +6213,6 @@ const noSuccessor = ["\\smallint"];
6205
6213
  // Math operators (e.g. \sin) need a space between these types and themselves:
6206
6214
  const ordTypes = ["textord", "mathord", "ordgroup", "close", "leftright"];
6207
6215
 
6208
- const dels$1 = ["}", "\\left", "\\middle", "\\right"];
6209
- const isDelimiter$1 = str => str.length > 0 &&
6210
- (delimiters.includes(str) || delimiterSizes[str] || dels$1.includes(str));
6211
-
6212
6216
  // NOTE: Unlike most `builders`s, this one handles not only "op", but also
6213
6217
  // "supsub" since some of them (like \int) can affect super/subscripting.
6214
6218
 
@@ -6429,7 +6433,7 @@ defineFunction({
6429
6433
  parentIsSupSub: false,
6430
6434
  symbol: false,
6431
6435
  stack: false,
6432
- isFollowedByDelimiter: isDelimiter$1(next),
6436
+ isFollowedByDelimiter: isDelimiter(next),
6433
6437
  needsLeadingSpace: prevAtomType.length > 0 && ordTypes.includes(prevAtomType),
6434
6438
  name: funcName
6435
6439
  };
@@ -6454,7 +6458,7 @@ defineFunction({
6454
6458
  parentIsSupSub: false,
6455
6459
  symbol: false,
6456
6460
  stack: false,
6457
- isFollowedByDelimiter: isDelimiter$1(next),
6461
+ isFollowedByDelimiter: isDelimiter(next),
6458
6462
  needsLeadingSpace: prevAtomType.length > 0 && ordTypes.includes(prevAtomType),
6459
6463
  name: funcName
6460
6464
  };
@@ -6540,11 +6544,7 @@ function defineMacro(name, body) {
6540
6544
  _macros[name] = body;
6541
6545
  }
6542
6546
 
6543
- const dels = ["}", "\\left", "\\middle", "\\right"];
6544
- const isDelimiter = str => str.length > 0 &&
6545
- (delimiters.includes(str) || delimiterSizes[str] || dels.includes(str));
6546
-
6547
- // NOTE: Unlike most builders, this one handles not only
6547
+ // NOTE: Unlike most builders, this one handles not only
6548
6548
  // "operatorname", but also "supsub" since \operatorname* can
6549
6549
  // affect super/subscripting.
6550
6550
 
@@ -6554,8 +6554,12 @@ const mathmlBuilder$1 = (group, style) => {
6554
6554
  // Is expression a string or has it something like a fraction?
6555
6555
  let isAllString = true; // default
6556
6556
  for (let i = 0; i < expression.length; i++) {
6557
- const node = expression[i];
6557
+ let node = expression[i];
6558
6558
  if (node instanceof mathMLTree.MathNode) {
6559
+ if (node.type === "mrow" && node.children.length === 1 &&
6560
+ node.children[0] instanceof mathMLTree.MathNode) {
6561
+ node = node.children[0];
6562
+ }
6559
6563
  switch (node.type) {
6560
6564
  case "mi":
6561
6565
  case "mn":
@@ -6613,7 +6617,9 @@ const mathmlBuilder$1 = (group, style) => {
6613
6617
  let wrapper;
6614
6618
  if (isAllString) {
6615
6619
  wrapper = new mathMLTree.MathNode("mi", expression);
6616
- wrapper.setAttribute("mathvariant", "normal");
6620
+ if (expression[0].text.length === 1) {
6621
+ wrapper.setAttribute("mathvariant", "normal");
6622
+ }
6617
6623
  } else {
6618
6624
  wrapper = new mathMLTree.MathNode("mrow", expression);
6619
6625
  }
@@ -7151,6 +7157,7 @@ defineFunctionBuilders({
7151
7157
  let isOver;
7152
7158
  let isSup;
7153
7159
  let appendApplyFunction = false;
7160
+ let appendSpace = false;
7154
7161
  let needsLeadingSpace = false;
7155
7162
 
7156
7163
  if (group.base && group.base.type === "horizBrace") {
@@ -7165,6 +7172,7 @@ defineFunctionBuilders({
7165
7172
  (group.base.type === "op" || group.base.type === "operatorname")) {
7166
7173
  group.base.parentIsSupSub = true;
7167
7174
  appendApplyFunction = !group.base.symbol;
7175
+ appendSpace = appendApplyFunction && !group.isFollowedByDelimiter;
7168
7176
  needsLeadingSpace = group.base.needsLeadingSpace;
7169
7177
  }
7170
7178
 
@@ -7252,6 +7260,11 @@ defineFunctionBuilders({
7252
7260
  } else {
7253
7261
  node = mathMLTree.newDocumentFragment([node, operator]);
7254
7262
  }
7263
+ if (appendSpace) {
7264
+ const space = new mathMLTree.MathNode("mspace");
7265
+ space.setAttribute("width", "0.1667em"); // thin space.
7266
+ node.children.push(space);
7267
+ }
7255
7268
  } else if (symbolRegEx.test(nodeType)) {
7256
7269
  // Wrap in a <mrow>. Otherwise Firefox stretchy parens will not stretch to include limits.
7257
7270
  node = new mathMLTree.MathNode("mrow", [node]);
@@ -8884,7 +8897,7 @@ defineMacro("\\incoh", `{\\mkern5mu\\rule{}{0.7em}\\mathrlap{\\smash{\\raise2mu{
8884
8897
  defineMacro("\\standardstate", "\\text{\\tiny\\char`⦵}");
8885
8898
 
8886
8899
  /* eslint-disable */
8887
- /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
8900
+ /* -*- Mode: JavaScript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
8888
8901
  /* vim: set ts=2 et sw=2 tw=80: */
8889
8902
 
8890
8903
  /*************************************************************
@@ -10581,7 +10594,7 @@ defineMacro("\\tripleDashBetweenDoubleLine", `\\kern0.075em\\mathrlap{\\mathrlap
10581
10594
  };
10582
10595
 
10583
10596
  //
10584
- // Helpers for code anaylsis
10597
+ // Helpers for code analysis
10585
10598
  // Will show type error at calling position
10586
10599
  //
10587
10600
  /** @param {number} a */
@@ -11006,15 +11019,15 @@ class MacroExpander {
11006
11019
  * Expand the next token only once if possible.
11007
11020
  *
11008
11021
  * If the token is expanded, the resulting tokens will be pushed onto
11009
- * the stack in reverse order and will be returned as an array,
11010
- * also in reverse order.
11022
+ * the stack in reverse order, and the number of such tokens will be
11023
+ * returned. This number might be zero or positive.
11011
11024
  *
11012
- * If not, the next token will be returned without removing it
11013
- * from the stack. This case can be detected by a `Token` return value
11014
- * instead of an `Array` return value.
11025
+ * If not, the return value is `false`, and the next token remains at the
11026
+ * top of the stack.
11015
11027
  *
11016
11028
  * In either case, the next token will be on the top of the stack,
11017
- * or the stack will be empty.
11029
+ * or the stack will be empty (in case of empty expansion
11030
+ * and no other tokens).
11018
11031
  *
11019
11032
  * Used to implement `expandAfterFuture` and `expandNextToken`.
11020
11033
  *
@@ -11030,7 +11043,7 @@ class MacroExpander {
11030
11043
  throw new ParseError("Undefined control sequence: " + name);
11031
11044
  }
11032
11045
  this.pushToken(topToken);
11033
- return topToken;
11046
+ return false;
11034
11047
  }
11035
11048
  this.expansionCount++;
11036
11049
  if (this.expansionCount > this.settings.maxExpand) {
@@ -11064,7 +11077,7 @@ class MacroExpander {
11064
11077
  }
11065
11078
  // Concatenate expansion onto top of stack.
11066
11079
  this.pushTokens(tokens);
11067
- return tokens;
11080
+ return tokens.length;
11068
11081
  }
11069
11082
 
11070
11083
  /**
@@ -11083,14 +11096,13 @@ class MacroExpander {
11083
11096
  */
11084
11097
  expandNextToken() {
11085
11098
  for (;;) {
11086
- const expanded = this.expandOnce();
11087
- // expandOnce returns Token if and only if it's fully expanded.
11088
- if (expanded instanceof Token) {
11099
+ if (this.expandOnce() === false) { // fully expanded
11100
+ const token = this.stack.pop();
11089
11101
  // The token after \noexpand is interpreted as if its meaning were ‘\relax’
11090
- if (expanded.treatAsRelax) {
11091
- expanded.text = "\\relax";
11102
+ if (token.treatAsRelax) {
11103
+ token.text = "\\relax";
11092
11104
  }
11093
- return this.stack.pop(); // === expanded
11105
+ return token
11094
11106
  }
11095
11107
  }
11096
11108
 
@@ -11116,15 +11128,15 @@ class MacroExpander {
11116
11128
  const oldStackLength = this.stack.length;
11117
11129
  this.pushTokens(tokens);
11118
11130
  while (this.stack.length > oldStackLength) {
11119
- const expanded = this.expandOnce(true); // expand only expandable tokens
11120
- // expandOnce returns Token if and only if it's fully expanded.
11121
- if (expanded instanceof Token) {
11122
- if (expanded.treatAsRelax) {
11131
+ // Expand only expandable tokens
11132
+ if (this.expandOnce(true) === false) { // fully expanded
11133
+ const token = this.stack.pop();
11134
+ if (token.treatAsRelax) {
11123
11135
  // the expansion of \noexpand is the token itself
11124
- expanded.noexpand = false;
11125
- expanded.treatAsRelax = false;
11136
+ token.noexpand = false;
11137
+ token.treatAsRelax = false;
11126
11138
  }
11127
- output.push(this.stack.pop());
11139
+ output.push(token);
11128
11140
  }
11129
11141
  }
11130
11142
  return output;
@@ -11952,7 +11964,7 @@ class Parser {
11952
11964
  * Parses an "expression", which is a list of atoms.
11953
11965
  *
11954
11966
  * `breakOnInfix`: Should the parsing stop when we hit infix nodes? This
11955
- * happens when functions have higher precendence han infix
11967
+ * happens when functions have higher precedence han infix
11956
11968
  * nodes in implicit parses.
11957
11969
  *
11958
11970
  * `breakOnTokenText`: The text of the token that the expression should end
@@ -12203,12 +12215,16 @@ class Parser {
12203
12215
  return base
12204
12216
  } else {
12205
12217
  // We got either a superscript or subscript, create a supsub
12218
+ const isFollowedByDelimiter = (!base || base.type !== "op" && base.type !== "operatorname")
12219
+ ? undefined
12220
+ : isDelimiter(this.nextToken.text);
12206
12221
  return {
12207
12222
  type: "supsub",
12208
12223
  mode: this.mode,
12209
12224
  base: base,
12210
12225
  sup: superscript,
12211
- sub: subscript
12226
+ sub: subscript,
12227
+ isFollowedByDelimiter
12212
12228
  }
12213
12229
  }
12214
12230
  } else {
@@ -12369,7 +12385,7 @@ class Parser {
12369
12385
  while (true) {
12370
12386
  const ch = this.fetch().text;
12371
12387
  // \ufe0e is the Unicode variation selector to supress emoji. Ignore it.
12372
- if (ch === " " || ch === "\ufe0e") {
12388
+ if (ch === " " || ch === "\u00a0" || ch === "\ufe0e") {
12373
12389
  this.consume();
12374
12390
  } else {
12375
12391
  break
@@ -12961,7 +12977,7 @@ class Style {
12961
12977
  * https://mit-license.org/
12962
12978
  */
12963
12979
 
12964
- const version = "0.10.0";
12980
+ const version = "0.10.2";
12965
12981
 
12966
12982
  function postProcess(block) {
12967
12983
  const labelMap = {};
package/dist/temml.js CHANGED
@@ -669,7 +669,7 @@ var temml = (function () {
669
669
 
670
670
  /**
671
671
  * Converts the text node into a string
672
- * (representing the text iteself).
672
+ * (representing the text itself).
673
673
  */
674
674
  toText() {
675
675
  return this.text;
@@ -846,7 +846,6 @@ var temml = (function () {
846
846
  defineSymbol(math, rel, "\u226b", "\\gg", true);
847
847
  defineSymbol(math, rel, "\u224d", "\\asymp", true);
848
848
  defineSymbol(math, rel, "\u2225", "\\parallel");
849
- defineSymbol(math, rel, "\u22c8", "\\bowtie", true);
850
849
  defineSymbol(math, rel, "\u2323", "\\smile", true);
851
850
  defineSymbol(math, rel, "\u2291", "\\sqsubseteq", true);
852
851
  defineSymbol(math, rel, "\u2292", "\\sqsupseteq", true);
@@ -1163,7 +1162,6 @@ var temml = (function () {
1163
1162
  defineSymbol(math, bin, "\u22b2", "\\lhd");
1164
1163
  defineSymbol(math, bin, "\u22b3", "\\rhd");
1165
1164
  defineSymbol(math, rel, "\u2242", "\\eqsim", true);
1166
- defineSymbol(math, rel, "\u22c8", "\\Join");
1167
1165
  defineSymbol(math, rel, "\u2251", "\\Doteq", true);
1168
1166
  defineSymbol(math, rel, "\u297d", "\\strictif", true);
1169
1167
  defineSymbol(math, rel, "\u297c", "\\strictfi", true);
@@ -1189,6 +1187,11 @@ var temml = (function () {
1189
1187
  defineSymbol(math, bin, "\u22d2", "\\doublecap");
1190
1188
  defineSymbol(math, bin, "\u22d3", "\\doublecup");
1191
1189
  defineSymbol(math, bin, "\u22a0", "\\boxtimes", true);
1190
+ defineSymbol(math, bin, "\u22c8", "\\bowtie", true);
1191
+ defineSymbol(math, bin, "\u22c8", "\\Join");
1192
+ defineSymbol(math, bin, "\u27d5", "\\leftouterjoin", true);
1193
+ defineSymbol(math, bin, "\u27d6", "\\rightouterjoin", true);
1194
+ defineSymbol(math, bin, "\u27d7", "\\fullouterjoin", true);
1192
1195
 
1193
1196
  // AMS Arrows
1194
1197
  // Note: unicode-math maps \u21e2 to their own function \rightdasharrow.
@@ -1893,7 +1896,7 @@ var temml = (function () {
1893
1896
  }
1894
1897
 
1895
1898
  /**
1896
- * This file converts a parse tree into a cooresponding MathML tree. The main
1899
+ * This file converts a parse tree into a corresponding MathML tree. The main
1897
1900
  * entry point is the `buildMathML` function, which takes a parse tree from the
1898
1901
  * parser.
1899
1902
  */
@@ -3524,6 +3527,11 @@ var temml = (function () {
3524
3527
  "."
3525
3528
  ];
3526
3529
 
3530
+ // Export isDelimiter for benefit of parser.
3531
+ const dels = ["}", "\\left", "\\middle", "\\right"];
3532
+ const isDelimiter = str => str.length > 0 &&
3533
+ (delimiters.includes(str) || delimiterSizes[str] || dels.includes(str));
3534
+
3527
3535
  // Metrics of the different sizes. Found by looking at TeX's output of
3528
3536
  // $\bigl| // \Bigl| \biggl| \Biggl| \showlists$
3529
3537
  // Used to create stacked delimiters of appropriate sizes in makeSizedDelim.
@@ -6206,10 +6214,6 @@ var temml = (function () {
6206
6214
  // Math operators (e.g. \sin) need a space between these types and themselves:
6207
6215
  const ordTypes = ["textord", "mathord", "ordgroup", "close", "leftright"];
6208
6216
 
6209
- const dels$1 = ["}", "\\left", "\\middle", "\\right"];
6210
- const isDelimiter$1 = str => str.length > 0 &&
6211
- (delimiters.includes(str) || delimiterSizes[str] || dels$1.includes(str));
6212
-
6213
6217
  // NOTE: Unlike most `builders`s, this one handles not only "op", but also
6214
6218
  // "supsub" since some of them (like \int) can affect super/subscripting.
6215
6219
 
@@ -6430,7 +6434,7 @@ var temml = (function () {
6430
6434
  parentIsSupSub: false,
6431
6435
  symbol: false,
6432
6436
  stack: false,
6433
- isFollowedByDelimiter: isDelimiter$1(next),
6437
+ isFollowedByDelimiter: isDelimiter(next),
6434
6438
  needsLeadingSpace: prevAtomType.length > 0 && ordTypes.includes(prevAtomType),
6435
6439
  name: funcName
6436
6440
  };
@@ -6455,7 +6459,7 @@ var temml = (function () {
6455
6459
  parentIsSupSub: false,
6456
6460
  symbol: false,
6457
6461
  stack: false,
6458
- isFollowedByDelimiter: isDelimiter$1(next),
6462
+ isFollowedByDelimiter: isDelimiter(next),
6459
6463
  needsLeadingSpace: prevAtomType.length > 0 && ordTypes.includes(prevAtomType),
6460
6464
  name: funcName
6461
6465
  };
@@ -6541,11 +6545,7 @@ var temml = (function () {
6541
6545
  _macros[name] = body;
6542
6546
  }
6543
6547
 
6544
- const dels = ["}", "\\left", "\\middle", "\\right"];
6545
- const isDelimiter = str => str.length > 0 &&
6546
- (delimiters.includes(str) || delimiterSizes[str] || dels.includes(str));
6547
-
6548
- // NOTE: Unlike most builders, this one handles not only
6548
+ // NOTE: Unlike most builders, this one handles not only
6549
6549
  // "operatorname", but also "supsub" since \operatorname* can
6550
6550
  // affect super/subscripting.
6551
6551
 
@@ -6555,8 +6555,12 @@ var temml = (function () {
6555
6555
  // Is expression a string or has it something like a fraction?
6556
6556
  let isAllString = true; // default
6557
6557
  for (let i = 0; i < expression.length; i++) {
6558
- const node = expression[i];
6558
+ let node = expression[i];
6559
6559
  if (node instanceof mathMLTree.MathNode) {
6560
+ if (node.type === "mrow" && node.children.length === 1 &&
6561
+ node.children[0] instanceof mathMLTree.MathNode) {
6562
+ node = node.children[0];
6563
+ }
6560
6564
  switch (node.type) {
6561
6565
  case "mi":
6562
6566
  case "mn":
@@ -6614,7 +6618,9 @@ var temml = (function () {
6614
6618
  let wrapper;
6615
6619
  if (isAllString) {
6616
6620
  wrapper = new mathMLTree.MathNode("mi", expression);
6617
- wrapper.setAttribute("mathvariant", "normal");
6621
+ if (expression[0].text.length === 1) {
6622
+ wrapper.setAttribute("mathvariant", "normal");
6623
+ }
6618
6624
  } else {
6619
6625
  wrapper = new mathMLTree.MathNode("mrow", expression);
6620
6626
  }
@@ -7152,6 +7158,7 @@ var temml = (function () {
7152
7158
  let isOver;
7153
7159
  let isSup;
7154
7160
  let appendApplyFunction = false;
7161
+ let appendSpace = false;
7155
7162
  let needsLeadingSpace = false;
7156
7163
 
7157
7164
  if (group.base && group.base.type === "horizBrace") {
@@ -7166,6 +7173,7 @@ var temml = (function () {
7166
7173
  (group.base.type === "op" || group.base.type === "operatorname")) {
7167
7174
  group.base.parentIsSupSub = true;
7168
7175
  appendApplyFunction = !group.base.symbol;
7176
+ appendSpace = appendApplyFunction && !group.isFollowedByDelimiter;
7169
7177
  needsLeadingSpace = group.base.needsLeadingSpace;
7170
7178
  }
7171
7179
 
@@ -7253,6 +7261,11 @@ var temml = (function () {
7253
7261
  } else {
7254
7262
  node = mathMLTree.newDocumentFragment([node, operator]);
7255
7263
  }
7264
+ if (appendSpace) {
7265
+ const space = new mathMLTree.MathNode("mspace");
7266
+ space.setAttribute("width", "0.1667em"); // thin space.
7267
+ node.children.push(space);
7268
+ }
7256
7269
  } else if (symbolRegEx.test(nodeType)) {
7257
7270
  // Wrap in a <mrow>. Otherwise Firefox stretchy parens will not stretch to include limits.
7258
7271
  node = new mathMLTree.MathNode("mrow", [node]);
@@ -9107,15 +9120,15 @@ var temml = (function () {
9107
9120
  * Expand the next token only once if possible.
9108
9121
  *
9109
9122
  * If the token is expanded, the resulting tokens will be pushed onto
9110
- * the stack in reverse order and will be returned as an array,
9111
- * also in reverse order.
9123
+ * the stack in reverse order, and the number of such tokens will be
9124
+ * returned. This number might be zero or positive.
9112
9125
  *
9113
- * If not, the next token will be returned without removing it
9114
- * from the stack. This case can be detected by a `Token` return value
9115
- * instead of an `Array` return value.
9126
+ * If not, the return value is `false`, and the next token remains at the
9127
+ * top of the stack.
9116
9128
  *
9117
9129
  * In either case, the next token will be on the top of the stack,
9118
- * or the stack will be empty.
9130
+ * or the stack will be empty (in case of empty expansion
9131
+ * and no other tokens).
9119
9132
  *
9120
9133
  * Used to implement `expandAfterFuture` and `expandNextToken`.
9121
9134
  *
@@ -9131,7 +9144,7 @@ var temml = (function () {
9131
9144
  throw new ParseError("Undefined control sequence: " + name);
9132
9145
  }
9133
9146
  this.pushToken(topToken);
9134
- return topToken;
9147
+ return false;
9135
9148
  }
9136
9149
  this.expansionCount++;
9137
9150
  if (this.expansionCount > this.settings.maxExpand) {
@@ -9165,7 +9178,7 @@ var temml = (function () {
9165
9178
  }
9166
9179
  // Concatenate expansion onto top of stack.
9167
9180
  this.pushTokens(tokens);
9168
- return tokens;
9181
+ return tokens.length;
9169
9182
  }
9170
9183
 
9171
9184
  /**
@@ -9184,14 +9197,13 @@ var temml = (function () {
9184
9197
  */
9185
9198
  expandNextToken() {
9186
9199
  for (;;) {
9187
- const expanded = this.expandOnce();
9188
- // expandOnce returns Token if and only if it's fully expanded.
9189
- if (expanded instanceof Token) {
9200
+ if (this.expandOnce() === false) { // fully expanded
9201
+ const token = this.stack.pop();
9190
9202
  // The token after \noexpand is interpreted as if its meaning were ‘\relax’
9191
- if (expanded.treatAsRelax) {
9192
- expanded.text = "\\relax";
9203
+ if (token.treatAsRelax) {
9204
+ token.text = "\\relax";
9193
9205
  }
9194
- return this.stack.pop(); // === expanded
9206
+ return token
9195
9207
  }
9196
9208
  }
9197
9209
 
@@ -9217,15 +9229,15 @@ var temml = (function () {
9217
9229
  const oldStackLength = this.stack.length;
9218
9230
  this.pushTokens(tokens);
9219
9231
  while (this.stack.length > oldStackLength) {
9220
- const expanded = this.expandOnce(true); // expand only expandable tokens
9221
- // expandOnce returns Token if and only if it's fully expanded.
9222
- if (expanded instanceof Token) {
9223
- if (expanded.treatAsRelax) {
9232
+ // Expand only expandable tokens
9233
+ if (this.expandOnce(true) === false) { // fully expanded
9234
+ const token = this.stack.pop();
9235
+ if (token.treatAsRelax) {
9224
9236
  // the expansion of \noexpand is the token itself
9225
- expanded.noexpand = false;
9226
- expanded.treatAsRelax = false;
9237
+ token.noexpand = false;
9238
+ token.treatAsRelax = false;
9227
9239
  }
9228
- output.push(this.stack.pop());
9240
+ output.push(token);
9229
9241
  }
9230
9242
  }
9231
9243
  return output;
@@ -10053,7 +10065,7 @@ var temml = (function () {
10053
10065
  * Parses an "expression", which is a list of atoms.
10054
10066
  *
10055
10067
  * `breakOnInfix`: Should the parsing stop when we hit infix nodes? This
10056
- * happens when functions have higher precendence han infix
10068
+ * happens when functions have higher precedence han infix
10057
10069
  * nodes in implicit parses.
10058
10070
  *
10059
10071
  * `breakOnTokenText`: The text of the token that the expression should end
@@ -10304,12 +10316,16 @@ var temml = (function () {
10304
10316
  return base
10305
10317
  } else {
10306
10318
  // We got either a superscript or subscript, create a supsub
10319
+ const isFollowedByDelimiter = (!base || base.type !== "op" && base.type !== "operatorname")
10320
+ ? undefined
10321
+ : isDelimiter(this.nextToken.text);
10307
10322
  return {
10308
10323
  type: "supsub",
10309
10324
  mode: this.mode,
10310
10325
  base: base,
10311
10326
  sup: superscript,
10312
- sub: subscript
10327
+ sub: subscript,
10328
+ isFollowedByDelimiter
10313
10329
  }
10314
10330
  }
10315
10331
  } else {
@@ -10470,7 +10486,7 @@ var temml = (function () {
10470
10486
  while (true) {
10471
10487
  const ch = this.fetch().text;
10472
10488
  // \ufe0e is the Unicode variation selector to supress emoji. Ignore it.
10473
- if (ch === " " || ch === "\ufe0e") {
10489
+ if (ch === " " || ch === "\u00a0" || ch === "\ufe0e") {
10474
10490
  this.consume();
10475
10491
  } else {
10476
10492
  break
@@ -11062,7 +11078,7 @@ var temml = (function () {
11062
11078
  * https://mit-license.org/
11063
11079
  */
11064
11080
 
11065
- const version = "0.10.0";
11081
+ const version = "0.10.2";
11066
11082
 
11067
11083
  function postProcess(block) {
11068
11084
  const labelMap = {};