temml 0.13.4 → 0.14.0

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.
@@ -331,7 +331,7 @@ math > mrow {
331
331
 
332
332
  /* Default mtd top padding is 0.5ex per MathML-Core and user-agent CSS */
333
333
  /* We adjust for jot and small */
334
- mtable.tml-jot mtd {
334
+ mtable.tml-jot > mtr > mtd {
335
335
  padding-top: 0.7ex;
336
336
  padding-bottom: 0.7ex;
337
337
  }
@@ -347,7 +347,7 @@ mtable.tml-small mtd {
347
347
  math > mrow { padding: 0 }
348
348
  /* Adjust Firefox spacing between array rows */
349
349
  mtd, mtable.tml-small mtd { padding-top: 0; padding-bottom: 0; }
350
- mtable.tml-jot mtd { padding-top: 0.2ex; padding-bottom: 0.ex; }
350
+ mtable.tml-jot > mtr > mtd { padding-top: 0.2ex; padding-bottom: 0.2ex; }
351
351
  }
352
352
 
353
353
  /* AMS environment auto-numbering via CSS counter. */
@@ -349,7 +349,7 @@ math > mrow {
349
349
 
350
350
  /* Default mtd top padding is 0.5ex per MathML-Core and user-agent CSS */
351
351
  /* We adjust for jot and small */
352
- mtable.tml-jot mtd {
352
+ mtable.tml-jot > mtr > mtd {
353
353
  padding-top: 0.7ex;
354
354
  padding-bottom: 0.7ex;
355
355
  }
@@ -365,7 +365,7 @@ mtable.tml-small mtd {
365
365
  math > mrow { padding: 0 }
366
366
  /* Adjust Firefox spacing between array rows */
367
367
  mtd, mtable.tml-small mtd { padding-top: 0; padding-bottom: 0; }
368
- mtable.tml-jot mtd { padding-top: 0.2ex; padding-bottom: 0.ex; }
368
+ mtable.tml-jot > mtr > mtd { padding-top: 0.2ex; padding-bottom: 0.2ex; }
369
369
  }
370
370
 
371
371
  /* AMS environment auto-numbering via CSS counter. */
@@ -346,7 +346,7 @@ math > mrow {
346
346
 
347
347
  /* Default mtd top padding is 0.5ex per MathML-Core and user-agent CSS */
348
348
  /* We adjust for jot and small */
349
- mtable.tml-jot mtd {
349
+ mtable.tml-jot > mtr > mtd {
350
350
  padding-top: 0.7ex;
351
351
  padding-bottom: 0.7ex;
352
352
  }
@@ -362,7 +362,7 @@ mtable.tml-small mtd {
362
362
  math > mrow { padding: 0 }
363
363
  /* Adjust Firefox spacing between array rows */
364
364
  mtd, mtable.tml-small mtd { padding-top: 0; padding-bottom: 0; }
365
- mtable.tml-jot mtd { padding-top: 0.2ex; padding-bottom: 0.ex; }
365
+ mtable.tml-jot > mtr > mtd { padding-top: 0.2ex; padding-bottom: 0.2ex; }
366
366
  }
367
367
 
368
368
  /* AMS environment auto-numbering via CSS counter. */
@@ -342,7 +342,7 @@ math > mrow {
342
342
 
343
343
  /* Default mtd top padding is 0.5ex per MathML-Core and user-agent CSS */
344
344
  /* We adjust for jot and small */
345
- mtable.tml-jot mtd {
345
+ mtable.tml-jot > mtr > mtd {
346
346
  padding-top: 0.7ex;
347
347
  padding-bottom: 0.7ex;
348
348
  }
@@ -358,7 +358,7 @@ mtable.tml-small mtd {
358
358
  math > mrow { padding: 0 }
359
359
  /* Adjust Firefox spacing between array rows */
360
360
  mtd, mtable.tml-small mtd { padding-top: 0; padding-bottom: 0; }
361
- mtable.tml-jot mtd { padding-top: 0.2ex; padding-bottom: 0.ex; }
361
+ mtable.tml-jot > mtr > mtd { padding-top: 0.2ex; padding-bottom: 0.2ex; }
362
362
  }
363
363
 
364
364
  /* AMS environment auto-numbering via CSS counter. */
@@ -346,7 +346,7 @@ math > mrow {
346
346
 
347
347
  /* Default mtd top padding is 0.5ex per MathML-Core and user-agent CSS */
348
348
  /* We adjust for jot and small */
349
- mtable.tml-jot mtd {
349
+ mtable.tml-jot > mtr > mtd {
350
350
  padding-top: 0.7ex;
351
351
  padding-bottom: 0.7ex;
352
352
  }
@@ -362,7 +362,7 @@ mtable.tml-small mtd {
362
362
  math > mrow { padding: 0 }
363
363
  /* Adjust Firefox spacing between array rows */
364
364
  mtd, mtable.tml-small mtd { padding-top: 0; padding-bottom: 0; }
365
- mtable.tml-jot mtd { padding-top: 0.2ex; padding-bottom: 0.ex; }
365
+ mtable.tml-jot > mtr > mtd { padding-top: 0.2ex; padding-bottom: 0.2ex; }
366
366
  }
367
367
 
368
368
  /* AMS environment auto-numbering via CSS counter. */
@@ -337,7 +337,7 @@ math > mrow {
337
337
 
338
338
  /* Default mtd top padding is 0.5ex per MathML-Core and user-agent CSS */
339
339
  /* We adjust for jot and small */
340
- mtable.tml-jot mtd {
340
+ mtable.tml-jot > mtr > mtd {
341
341
  padding-top: 0.7ex;
342
342
  padding-bottom: 0.7ex;
343
343
  }
@@ -353,7 +353,7 @@ mtable.tml-small mtd {
353
353
  math > mrow { padding: 0 }
354
354
  /* Adjust Firefox spacing between array rows */
355
355
  mtd, mtable.tml-small mtd { padding-top: 0; padding-bottom: 0; }
356
- mtable.tml-jot mtd { padding-top: 0.2ex; padding-bottom: 0.ex; }
356
+ mtable.tml-jot > mtr > mtd { padding-top: 0.2ex; padding-bottom: 0.2ex; }
357
357
  }
358
358
 
359
359
  /* AMS environment auto-numbering via CSS counter. */
package/dist/temml.cjs CHANGED
@@ -70,9 +70,17 @@ ParseError.prototype.__proto__ = Error.prototype;
70
70
  */
71
71
 
72
72
  /**
73
- * Provide a default value if a setting is undefined
73
+ * Look up `key` on a user-supplied `options` object and return its value, or
74
+ * `defaultIfUndefined` if the setting is absent. Reads via
75
+ * `Object.prototype.hasOwnProperty.call` rather than plain property access,
76
+ * so a key that only exists because `Object.prototype` was polluted
77
+ * elsewhere is never mistaken for a setting the caller actually provided.
74
78
  */
75
- const deflt = function(setting, defaultIfUndefined) {
79
+ const deflt = function(options, key, defaultIfUndefined) {
80
+ if (!Object.prototype.hasOwnProperty.call(options, key)) {
81
+ return defaultIfUndefined;
82
+ }
83
+ const setting = options[key];
76
84
  return setting === undefined ? defaultIfUndefined : setting;
77
85
  };
78
86
 
@@ -190,6 +198,27 @@ const smalls = "acegıȷmnopqrsuvwxyzαγεηικμνοπρςστυχωϕ𝐚
190
198
  */
191
199
 
192
200
 
201
+ const FORBIDDEN_MACRO_KEYS = ["__proto__", "prototype", "constructor"];
202
+
203
+ // Sanitize a user-supplied macros object: strip its prototype (so later
204
+ // bracket-notation writes, e.g. from \gdef, can never reach Object.prototype)
205
+ // and delete any own key that could be used to pollute it. This mutates
206
+ // `macros` in place and returns the same reference, rather than a copy,
207
+ // because callers such as auto-render.js rely on that identity to share
208
+ // \gdef'd macros across multiple render calls that pass the same options
209
+ // object.
210
+ const sanitizeMacros = (macros) => {
211
+ if (macros == null || typeof macros !== "object") {
212
+ return Object.create(null);
213
+ }
214
+ for (const key of FORBIDDEN_MACRO_KEYS) {
215
+ if (Object.prototype.hasOwnProperty.call(macros, key)) {
216
+ delete macros[key];
217
+ }
218
+ }
219
+ return Object.setPrototypeOf(macros, null);
220
+ };
221
+
193
222
  /**
194
223
  * The main Settings object
195
224
  */
@@ -197,24 +226,29 @@ class Settings {
197
226
  constructor(options) {
198
227
  // allow null options
199
228
  options = options || {};
200
- this.displayMode = deflt(options.displayMode, false); // boolean
201
- this.annotate = deflt(options.annotate, false); // boolean
202
- this.leqno = deflt(options.leqno, false); // boolean
203
- this.throwOnError = deflt(options.throwOnError, false); // boolean
204
- this.errorColor = deflt(options.errorColor, "#b22222"); // string
205
- this.macros = options.macros || {};
206
- this.wrap = deflt(options.wrap, "none"); // "none" | "tex" | "="
207
- this.xml = deflt(options.xml, false); // boolean
208
- this.colorIsTextColor = deflt(options.colorIsTextColor, false); // boolean
209
- this.strict = deflt(options.strict, false); // boolean
210
- this.trust = deflt(options.trust, false); // trust context. See html.js.
211
- this.maxSize = (options.maxSize === undefined
212
- ? [Infinity, Infinity]
213
- : Array.isArray(options.maxSize)
229
+ this.displayMode = deflt(options, "displayMode", false); // boolean
230
+ this.annotate = deflt(options, "annotate", false); // boolean
231
+ this.leqno = deflt(options, "leqno", false); // boolean
232
+ this.throwOnError = deflt(options, "throwOnError", false); // boolean
233
+ this.errorColor = deflt(options, "errorColor", "#b22222"); // string
234
+ this.macros = sanitizeMacros(
235
+ Object.prototype.hasOwnProperty.call(options, "macros") ? options.macros : undefined
236
+ );
237
+ this.wrap = deflt(options, "wrap", "none"); // "none" | "tex" | "="
238
+ this.xml = deflt(options, "xml", false); // boolean
239
+ this.colorIsTextColor = deflt(options, "colorIsTextColor", false); // boolean
240
+ this.strict = deflt(options, "strict", false); // boolean
241
+ this.trust = deflt(options, "trust", false); // trust context. See html.js.
242
+ const maxSize = Object.prototype.hasOwnProperty.call(options, "maxSize")
214
243
  ? options.maxSize
244
+ : undefined;
245
+ this.maxSize = (maxSize === undefined
246
+ ? [Infinity, Infinity]
247
+ : Array.isArray(maxSize)
248
+ ? maxSize
215
249
  : [Infinity, Infinity]
216
250
  );
217
- this.maxExpand = Math.max(0, deflt(options.maxExpand, 1000)); // number
251
+ this.maxExpand = Math.max(0, deflt(options, "maxExpand", 1000)); // number
218
252
  this.wrapDelimiterPairs = true; // boolean
219
253
  }
220
254
 
@@ -914,22 +948,26 @@ const NON_ATOMS = {
914
948
  textord: 1
915
949
  };
916
950
 
917
- const symbols = {
918
- math: {},
919
- text: {}
920
- };
951
+ const symbols = Object.create(null);
952
+ symbols.math = Object.create(null);
953
+ symbols.text = Object.create(null);
921
954
 
922
- /** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
923
955
  function defineSymbol(mode, group, replace, name, acceptUnicodeChar) {
924
- symbols[mode][name] = { group, replace };
956
+ if (mode !== "math" && mode !== "text") {
957
+ throw new TypeError(`Invalid mode: ${mode} called in defineSymbol`);
958
+ }
959
+
960
+ const entry = { group, replace };
961
+ symbols[mode][name] = entry;
925
962
 
963
+ /** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
926
964
  if (acceptUnicodeChar && replace) {
927
- symbols[mode][replace] = symbols[mode][name];
965
+ symbols[mode][replace] = entry;
928
966
  }
929
967
  }
930
968
 
931
969
  // Some abbreviations for commonly used strings.
932
- // This helps minify the code, and also spotting typos using jshint.
970
+ // This helps minify the code, and also spotting typos via linter.
933
971
 
934
972
  // modes:
935
973
  const math = "math";
@@ -1767,9 +1805,11 @@ defineSymbol(math, op, "\u222b", "\\smallint");
1767
1805
  defineSymbol(text, inner, "\u2026", "\\textellipsis");
1768
1806
  defineSymbol(math, inner, "\u2026", "\\mathellipsis");
1769
1807
  defineSymbol(text, inner, "\u2026", "\\ldots", true);
1808
+ defineSymbol(math, inner, "\u2026", "\\dotso");
1809
+ defineSymbol(math, inner, "\u2026", "\\dotsc");
1770
1810
  defineSymbol(math, inner, "\u2026", "\\ldots", true);
1771
1811
  defineSymbol(math, inner, "\u22f0", "\\iddots", true);
1772
- defineSymbol(math, inner, "\u22ef", "\\@cdots", true);
1812
+ defineSymbol(math, inner, "\u22ef", "\\cdots", true);
1773
1813
  defineSymbol(math, inner, "\u22f1", "\\ddots", true);
1774
1814
  defineSymbol(math, textord, "\u22ee", "\\varvdots"); // \vdots is a macro
1775
1815
  defineSymbol(text, textord, "\u22ee", "\\varvdots");
@@ -3559,7 +3599,7 @@ const StyleLevel = {
3559
3599
  * `macros.js` exports this same dictionary again and makes it public.
3560
3600
  * `Parser.js` requires this dictionary via `macros.js`.
3561
3601
  */
3562
- const _macros = {};
3602
+ const _macros = Object.create(null);
3563
3603
 
3564
3604
  // This function might one day accept an additional argument and do more things.
3565
3605
  function defineMacro(name, body) {
@@ -3904,60 +3944,6 @@ defineMacro("\\dots", function(context) {
3904
3944
  return thedots;
3905
3945
  });
3906
3946
 
3907
- const spaceAfterDots = {
3908
- // \rightdelim@ checks for the following:
3909
- ")": true,
3910
- "]": true,
3911
- "\\rbrack": true,
3912
- "\\}": true,
3913
- "\\rbrace": true,
3914
- "\\rangle": true,
3915
- "\\rceil": true,
3916
- "\\rfloor": true,
3917
- "\\rgroup": true,
3918
- "\\rmoustache": true,
3919
- "\\right": true,
3920
- "\\bigr": true,
3921
- "\\biggr": true,
3922
- "\\Bigr": true,
3923
- "\\Biggr": true,
3924
- // \extra@ also tests for the following:
3925
- $: true,
3926
- // \extrap@ checks for the following:
3927
- ";": true,
3928
- ".": true,
3929
- ",": true
3930
- };
3931
-
3932
- defineMacro("\\dotso", function(context) {
3933
- const next = context.future().text;
3934
- if (next in spaceAfterDots) {
3935
- return "\\ldots\\,";
3936
- } else {
3937
- return "\\ldots";
3938
- }
3939
- });
3940
-
3941
- defineMacro("\\dotsc", function(context) {
3942
- const next = context.future().text;
3943
- // \dotsc uses \extra@ but not \extrap@, instead specially checking for
3944
- // ';' and '.', but doesn't check for ','.
3945
- if (next in spaceAfterDots && next !== ",") {
3946
- return "\\ldots\\,";
3947
- } else {
3948
- return "\\ldots";
3949
- }
3950
- });
3951
-
3952
- defineMacro("\\cdots", function(context) {
3953
- const next = context.future().text;
3954
- if (next in spaceAfterDots) {
3955
- return "\\@cdots\\,";
3956
- } else {
3957
- return "\\@cdots";
3958
- }
3959
- });
3960
-
3961
3947
  defineMacro("\\dotsb", "\\cdots");
3962
3948
  defineMacro("\\dotsm", "\\cdots");
3963
3949
  defineMacro("\\dotsi", "\\!\\cdots");
@@ -4087,7 +4073,7 @@ defineMacro("\\colon", `\\mathpunct{\\char"3a}`);
4087
4073
  //////////////////////////////////////////////////////////////////////
4088
4074
  // mathtools.sty
4089
4075
 
4090
- defineMacro("\\prescript", "\\pres@cript{_{#1}^{#2}}{}{#3}");
4076
+ defineMacro("\\prescript", "\\pres@cript{^{#1}_{#2}}{}{#3}");
4091
4077
 
4092
4078
  //\providecommand\ordinarycolon{:}
4093
4079
  defineMacro("\\ordinarycolon", `\\char"3a`);
@@ -11445,6 +11431,11 @@ const isArrow = str => {
11445
11431
  defineFunctionBuilders({
11446
11432
  type: "atom",
11447
11433
  mathmlBuilder(group, style) {
11434
+ if (group.family === "inner") {
11435
+ // Give \dots ORD spacing, not OP spacing.
11436
+ const tag = group.mode === "text" ? "mtext" : "mi";
11437
+ return new MathNode(tag, [makeText(group.text, group.mode)])
11438
+ }
11448
11439
  const node = new MathNode("mo", [makeText(group.text, group.mode)]);
11449
11440
  if (group.family === "punct") {
11450
11441
  node.setAttribute("separator", "true");
@@ -12000,7 +11991,7 @@ class Namespace {
12000
11991
  * of initial (global-level) mappings, which will constantly change
12001
11992
  * according to any global/top-level `set`s done.
12002
11993
  */
12003
- constructor(builtins = {}, globalMacros = {}) {
11994
+ constructor(builtins = Object.create(null), globalMacros = Object.create(null)) {
12004
11995
  this.current = globalMacros;
12005
11996
  this.builtins = builtins;
12006
11997
  this.undefStack = [];
@@ -12010,7 +12001,7 @@ class Namespace {
12010
12001
  * Start a new nested group, affecting future local `set`s.
12011
12002
  */
12012
12003
  beginGroup() {
12013
- this.undefStack.push({});
12004
+ this.undefStack.push(Object.create(null));
12014
12005
  }
12015
12006
 
12016
12007
  /**
@@ -14208,7 +14199,7 @@ class Style {
14208
14199
  * https://mit-license.org/
14209
14200
  */
14210
14201
 
14211
- const version = "0.13.4";
14202
+ const version = "0.14.0";
14212
14203
 
14213
14204
  function postProcess(block) {
14214
14205
  const labelMap = {};
@@ -14529,7 +14520,7 @@ const renderMathInElement = function(elem, options) {
14529
14520
 
14530
14521
  // Enable sharing of global macros defined via `\gdef` between different
14531
14522
  // math elements within a single call to `renderMathInElement`.
14532
- optionsCopy.macros = optionsCopy.macros || {};
14523
+ optionsCopy.macros = optionsCopy.macros || Object.create(null);
14533
14524
 
14534
14525
  renderElem(elem, optionsCopy);
14535
14526
  postProcess(elem);
@@ -14608,7 +14599,7 @@ const generateParseTree = function(expression, options) {
14608
14599
  */
14609
14600
  const definePreamble = function(expression, options) {
14610
14601
  const settings = new Settings(options);
14611
- settings.macros = {};
14602
+ settings.macros = Object.create(null);
14612
14603
  if (!(typeof expression === "string" || expression instanceof String)) {
14613
14604
  throw new TypeError("Temml can only parse string typed expression")
14614
14605
  }
package/dist/temml.js CHANGED
@@ -71,9 +71,17 @@ var temml = (function () {
71
71
  */
72
72
 
73
73
  /**
74
- * Provide a default value if a setting is undefined
74
+ * Look up `key` on a user-supplied `options` object and return its value, or
75
+ * `defaultIfUndefined` if the setting is absent. Reads via
76
+ * `Object.prototype.hasOwnProperty.call` rather than plain property access,
77
+ * so a key that only exists because `Object.prototype` was polluted
78
+ * elsewhere is never mistaken for a setting the caller actually provided.
75
79
  */
76
- const deflt = function(setting, defaultIfUndefined) {
80
+ const deflt = function(options, key, defaultIfUndefined) {
81
+ if (!Object.prototype.hasOwnProperty.call(options, key)) {
82
+ return defaultIfUndefined;
83
+ }
84
+ const setting = options[key];
77
85
  return setting === undefined ? defaultIfUndefined : setting;
78
86
  };
79
87
 
@@ -191,6 +199,27 @@ var temml = (function () {
191
199
  */
192
200
 
193
201
 
202
+ const FORBIDDEN_MACRO_KEYS = ["__proto__", "prototype", "constructor"];
203
+
204
+ // Sanitize a user-supplied macros object: strip its prototype (so later
205
+ // bracket-notation writes, e.g. from \gdef, can never reach Object.prototype)
206
+ // and delete any own key that could be used to pollute it. This mutates
207
+ // `macros` in place and returns the same reference, rather than a copy,
208
+ // because callers such as auto-render.js rely on that identity to share
209
+ // \gdef'd macros across multiple render calls that pass the same options
210
+ // object.
211
+ const sanitizeMacros = (macros) => {
212
+ if (macros == null || typeof macros !== "object") {
213
+ return Object.create(null);
214
+ }
215
+ for (const key of FORBIDDEN_MACRO_KEYS) {
216
+ if (Object.prototype.hasOwnProperty.call(macros, key)) {
217
+ delete macros[key];
218
+ }
219
+ }
220
+ return Object.setPrototypeOf(macros, null);
221
+ };
222
+
194
223
  /**
195
224
  * The main Settings object
196
225
  */
@@ -198,24 +227,29 @@ var temml = (function () {
198
227
  constructor(options) {
199
228
  // allow null options
200
229
  options = options || {};
201
- this.displayMode = deflt(options.displayMode, false); // boolean
202
- this.annotate = deflt(options.annotate, false); // boolean
203
- this.leqno = deflt(options.leqno, false); // boolean
204
- this.throwOnError = deflt(options.throwOnError, false); // boolean
205
- this.errorColor = deflt(options.errorColor, "#b22222"); // string
206
- this.macros = options.macros || {};
207
- this.wrap = deflt(options.wrap, "none"); // "none" | "tex" | "="
208
- this.xml = deflt(options.xml, false); // boolean
209
- this.colorIsTextColor = deflt(options.colorIsTextColor, false); // boolean
210
- this.strict = deflt(options.strict, false); // boolean
211
- this.trust = deflt(options.trust, false); // trust context. See html.js.
212
- this.maxSize = (options.maxSize === undefined
213
- ? [Infinity, Infinity]
214
- : Array.isArray(options.maxSize)
230
+ this.displayMode = deflt(options, "displayMode", false); // boolean
231
+ this.annotate = deflt(options, "annotate", false); // boolean
232
+ this.leqno = deflt(options, "leqno", false); // boolean
233
+ this.throwOnError = deflt(options, "throwOnError", false); // boolean
234
+ this.errorColor = deflt(options, "errorColor", "#b22222"); // string
235
+ this.macros = sanitizeMacros(
236
+ Object.prototype.hasOwnProperty.call(options, "macros") ? options.macros : undefined
237
+ );
238
+ this.wrap = deflt(options, "wrap", "none"); // "none" | "tex" | "="
239
+ this.xml = deflt(options, "xml", false); // boolean
240
+ this.colorIsTextColor = deflt(options, "colorIsTextColor", false); // boolean
241
+ this.strict = deflt(options, "strict", false); // boolean
242
+ this.trust = deflt(options, "trust", false); // trust context. See html.js.
243
+ const maxSize = Object.prototype.hasOwnProperty.call(options, "maxSize")
215
244
  ? options.maxSize
245
+ : undefined;
246
+ this.maxSize = (maxSize === undefined
247
+ ? [Infinity, Infinity]
248
+ : Array.isArray(maxSize)
249
+ ? maxSize
216
250
  : [Infinity, Infinity]
217
251
  );
218
- this.maxExpand = Math.max(0, deflt(options.maxExpand, 1000)); // number
252
+ this.maxExpand = Math.max(0, deflt(options, "maxExpand", 1000)); // number
219
253
  this.wrapDelimiterPairs = true; // boolean
220
254
  }
221
255
 
@@ -915,22 +949,26 @@ var temml = (function () {
915
949
  textord: 1
916
950
  };
917
951
 
918
- const symbols = {
919
- math: {},
920
- text: {}
921
- };
952
+ const symbols = Object.create(null);
953
+ symbols.math = Object.create(null);
954
+ symbols.text = Object.create(null);
922
955
 
923
- /** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
924
956
  function defineSymbol(mode, group, replace, name, acceptUnicodeChar) {
925
- symbols[mode][name] = { group, replace };
957
+ if (mode !== "math" && mode !== "text") {
958
+ throw new TypeError(`Invalid mode: ${mode} called in defineSymbol`);
959
+ }
960
+
961
+ const entry = { group, replace };
962
+ symbols[mode][name] = entry;
926
963
 
964
+ /** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
927
965
  if (acceptUnicodeChar && replace) {
928
- symbols[mode][replace] = symbols[mode][name];
966
+ symbols[mode][replace] = entry;
929
967
  }
930
968
  }
931
969
 
932
970
  // Some abbreviations for commonly used strings.
933
- // This helps minify the code, and also spotting typos using jshint.
971
+ // This helps minify the code, and also spotting typos via linter.
934
972
 
935
973
  // modes:
936
974
  const math = "math";
@@ -1768,9 +1806,11 @@ var temml = (function () {
1768
1806
  defineSymbol(text, inner, "\u2026", "\\textellipsis");
1769
1807
  defineSymbol(math, inner, "\u2026", "\\mathellipsis");
1770
1808
  defineSymbol(text, inner, "\u2026", "\\ldots", true);
1809
+ defineSymbol(math, inner, "\u2026", "\\dotso");
1810
+ defineSymbol(math, inner, "\u2026", "\\dotsc");
1771
1811
  defineSymbol(math, inner, "\u2026", "\\ldots", true);
1772
1812
  defineSymbol(math, inner, "\u22f0", "\\iddots", true);
1773
- defineSymbol(math, inner, "\u22ef", "\\@cdots", true);
1813
+ defineSymbol(math, inner, "\u22ef", "\\cdots", true);
1774
1814
  defineSymbol(math, inner, "\u22f1", "\\ddots", true);
1775
1815
  defineSymbol(math, textord, "\u22ee", "\\varvdots"); // \vdots is a macro
1776
1816
  defineSymbol(text, textord, "\u22ee", "\\varvdots");
@@ -3560,7 +3600,7 @@ var temml = (function () {
3560
3600
  * `macros.js` exports this same dictionary again and makes it public.
3561
3601
  * `Parser.js` requires this dictionary via `macros.js`.
3562
3602
  */
3563
- const _macros = {};
3603
+ const _macros = Object.create(null);
3564
3604
 
3565
3605
  // This function might one day accept an additional argument and do more things.
3566
3606
  function defineMacro(name, body) {
@@ -3905,60 +3945,6 @@ var temml = (function () {
3905
3945
  return thedots;
3906
3946
  });
3907
3947
 
3908
- const spaceAfterDots = {
3909
- // \rightdelim@ checks for the following:
3910
- ")": true,
3911
- "]": true,
3912
- "\\rbrack": true,
3913
- "\\}": true,
3914
- "\\rbrace": true,
3915
- "\\rangle": true,
3916
- "\\rceil": true,
3917
- "\\rfloor": true,
3918
- "\\rgroup": true,
3919
- "\\rmoustache": true,
3920
- "\\right": true,
3921
- "\\bigr": true,
3922
- "\\biggr": true,
3923
- "\\Bigr": true,
3924
- "\\Biggr": true,
3925
- // \extra@ also tests for the following:
3926
- $: true,
3927
- // \extrap@ checks for the following:
3928
- ";": true,
3929
- ".": true,
3930
- ",": true
3931
- };
3932
-
3933
- defineMacro("\\dotso", function(context) {
3934
- const next = context.future().text;
3935
- if (next in spaceAfterDots) {
3936
- return "\\ldots\\,";
3937
- } else {
3938
- return "\\ldots";
3939
- }
3940
- });
3941
-
3942
- defineMacro("\\dotsc", function(context) {
3943
- const next = context.future().text;
3944
- // \dotsc uses \extra@ but not \extrap@, instead specially checking for
3945
- // ';' and '.', but doesn't check for ','.
3946
- if (next in spaceAfterDots && next !== ",") {
3947
- return "\\ldots\\,";
3948
- } else {
3949
- return "\\ldots";
3950
- }
3951
- });
3952
-
3953
- defineMacro("\\cdots", function(context) {
3954
- const next = context.future().text;
3955
- if (next in spaceAfterDots) {
3956
- return "\\@cdots\\,";
3957
- } else {
3958
- return "\\@cdots";
3959
- }
3960
- });
3961
-
3962
3948
  defineMacro("\\dotsb", "\\cdots");
3963
3949
  defineMacro("\\dotsm", "\\cdots");
3964
3950
  defineMacro("\\dotsi", "\\!\\cdots");
@@ -4088,7 +4074,7 @@ var temml = (function () {
4088
4074
  //////////////////////////////////////////////////////////////////////
4089
4075
  // mathtools.sty
4090
4076
 
4091
- defineMacro("\\prescript", "\\pres@cript{_{#1}^{#2}}{}{#3}");
4077
+ defineMacro("\\prescript", "\\pres@cript{^{#1}_{#2}}{}{#3}");
4092
4078
 
4093
4079
  //\providecommand\ordinarycolon{:}
4094
4080
  defineMacro("\\ordinarycolon", `\\char"3a`);
@@ -9532,6 +9518,11 @@ var temml = (function () {
9532
9518
  defineFunctionBuilders({
9533
9519
  type: "atom",
9534
9520
  mathmlBuilder(group, style) {
9521
+ if (group.family === "inner") {
9522
+ // Give \dots ORD spacing, not OP spacing.
9523
+ const tag = group.mode === "text" ? "mtext" : "mi";
9524
+ return new MathNode(tag, [makeText(group.text, group.mode)])
9525
+ }
9535
9526
  const node = new MathNode("mo", [makeText(group.text, group.mode)]);
9536
9527
  if (group.family === "punct") {
9537
9528
  node.setAttribute("separator", "true");
@@ -10087,7 +10078,7 @@ var temml = (function () {
10087
10078
  * of initial (global-level) mappings, which will constantly change
10088
10079
  * according to any global/top-level `set`s done.
10089
10080
  */
10090
- constructor(builtins = {}, globalMacros = {}) {
10081
+ constructor(builtins = Object.create(null), globalMacros = Object.create(null)) {
10091
10082
  this.current = globalMacros;
10092
10083
  this.builtins = builtins;
10093
10084
  this.undefStack = [];
@@ -10097,7 +10088,7 @@ var temml = (function () {
10097
10088
  * Start a new nested group, affecting future local `set`s.
10098
10089
  */
10099
10090
  beginGroup() {
10100
- this.undefStack.push({});
10091
+ this.undefStack.push(Object.create(null));
10101
10092
  }
10102
10093
 
10103
10094
  /**
@@ -12295,7 +12286,7 @@ var temml = (function () {
12295
12286
  * https://mit-license.org/
12296
12287
  */
12297
12288
 
12298
- const version = "0.13.4";
12289
+ const version = "0.14.0";
12299
12290
 
12300
12291
  function postProcess(block) {
12301
12292
  const labelMap = {};
@@ -12616,7 +12607,7 @@ var temml = (function () {
12616
12607
 
12617
12608
  // Enable sharing of global macros defined via `\gdef` between different
12618
12609
  // math elements within a single call to `renderMathInElement`.
12619
- optionsCopy.macros = optionsCopy.macros || {};
12610
+ optionsCopy.macros = optionsCopy.macros || Object.create(null);
12620
12611
 
12621
12612
  renderElem(elem, optionsCopy);
12622
12613
  postProcess(elem);
@@ -12695,7 +12686,7 @@ var temml = (function () {
12695
12686
  */
12696
12687
  const definePreamble = function(expression, options) {
12697
12688
  const settings = new Settings(options);
12698
- settings.macros = {};
12689
+ settings.macros = Object.create(null);
12699
12690
  if (!(typeof expression === "string" || expression instanceof String)) {
12700
12691
  throw new TypeError("Temml can only parse string typed expression")
12701
12692
  }