temml 0.10.0 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 = {};