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.
- package/dist/Temml-Asana.css +2 -2
- package/dist/Temml-Latin-Modern.css +2 -2
- package/dist/Temml-Libertinus.css +2 -2
- package/dist/Temml-Local.css +2 -2
- package/dist/Temml-NotoSans.css +2 -2
- package/dist/Temml-STIX2.css +2 -2
- package/dist/temml.cjs +78 -87
- package/dist/temml.js +78 -87
- package/dist/temml.min.js +1 -1
- package/dist/temml.mjs +78 -87
- package/dist/temmlPostProcess.js +1 -1
- package/package.json +2 -2
- package/src/Namespace.js +2 -2
- package/src/Settings.js +41 -15
- package/src/auto-render.js +1 -1
- package/src/defineMacro.js +1 -1
- package/src/functions/symbolsOp.js +5 -0
- package/src/macros.js +1 -55
- package/src/postProcess.js +1 -1
- package/src/symbols.js +15 -9
- package/src/utils.js +10 -2
- package/temml.js +1 -1
package/dist/temml.mjs
CHANGED
|
@@ -68,9 +68,17 @@ ParseError.prototype.__proto__ = Error.prototype;
|
|
|
68
68
|
*/
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
|
-
*
|
|
71
|
+
* Look up `key` on a user-supplied `options` object and return its value, or
|
|
72
|
+
* `defaultIfUndefined` if the setting is absent. Reads via
|
|
73
|
+
* `Object.prototype.hasOwnProperty.call` rather than plain property access,
|
|
74
|
+
* so a key that only exists because `Object.prototype` was polluted
|
|
75
|
+
* elsewhere is never mistaken for a setting the caller actually provided.
|
|
72
76
|
*/
|
|
73
|
-
const deflt = function(
|
|
77
|
+
const deflt = function(options, key, defaultIfUndefined) {
|
|
78
|
+
if (!Object.prototype.hasOwnProperty.call(options, key)) {
|
|
79
|
+
return defaultIfUndefined;
|
|
80
|
+
}
|
|
81
|
+
const setting = options[key];
|
|
74
82
|
return setting === undefined ? defaultIfUndefined : setting;
|
|
75
83
|
};
|
|
76
84
|
|
|
@@ -188,6 +196,27 @@ const smalls = "acegıȷmnopqrsuvwxyzαγεηικμνοπρςστυχωϕ𝐚
|
|
|
188
196
|
*/
|
|
189
197
|
|
|
190
198
|
|
|
199
|
+
const FORBIDDEN_MACRO_KEYS = ["__proto__", "prototype", "constructor"];
|
|
200
|
+
|
|
201
|
+
// Sanitize a user-supplied macros object: strip its prototype (so later
|
|
202
|
+
// bracket-notation writes, e.g. from \gdef, can never reach Object.prototype)
|
|
203
|
+
// and delete any own key that could be used to pollute it. This mutates
|
|
204
|
+
// `macros` in place and returns the same reference, rather than a copy,
|
|
205
|
+
// because callers such as auto-render.js rely on that identity to share
|
|
206
|
+
// \gdef'd macros across multiple render calls that pass the same options
|
|
207
|
+
// object.
|
|
208
|
+
const sanitizeMacros = (macros) => {
|
|
209
|
+
if (macros == null || typeof macros !== "object") {
|
|
210
|
+
return Object.create(null);
|
|
211
|
+
}
|
|
212
|
+
for (const key of FORBIDDEN_MACRO_KEYS) {
|
|
213
|
+
if (Object.prototype.hasOwnProperty.call(macros, key)) {
|
|
214
|
+
delete macros[key];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return Object.setPrototypeOf(macros, null);
|
|
218
|
+
};
|
|
219
|
+
|
|
191
220
|
/**
|
|
192
221
|
* The main Settings object
|
|
193
222
|
*/
|
|
@@ -195,24 +224,29 @@ class Settings {
|
|
|
195
224
|
constructor(options) {
|
|
196
225
|
// allow null options
|
|
197
226
|
options = options || {};
|
|
198
|
-
this.displayMode = deflt(options
|
|
199
|
-
this.annotate = deflt(options
|
|
200
|
-
this.leqno = deflt(options
|
|
201
|
-
this.throwOnError = deflt(options
|
|
202
|
-
this.errorColor = deflt(options
|
|
203
|
-
this.macros =
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
this.
|
|
207
|
-
this.
|
|
208
|
-
this.
|
|
209
|
-
this.
|
|
210
|
-
|
|
211
|
-
|
|
227
|
+
this.displayMode = deflt(options, "displayMode", false); // boolean
|
|
228
|
+
this.annotate = deflt(options, "annotate", false); // boolean
|
|
229
|
+
this.leqno = deflt(options, "leqno", false); // boolean
|
|
230
|
+
this.throwOnError = deflt(options, "throwOnError", false); // boolean
|
|
231
|
+
this.errorColor = deflt(options, "errorColor", "#b22222"); // string
|
|
232
|
+
this.macros = sanitizeMacros(
|
|
233
|
+
Object.prototype.hasOwnProperty.call(options, "macros") ? options.macros : undefined
|
|
234
|
+
);
|
|
235
|
+
this.wrap = deflt(options, "wrap", "none"); // "none" | "tex" | "="
|
|
236
|
+
this.xml = deflt(options, "xml", false); // boolean
|
|
237
|
+
this.colorIsTextColor = deflt(options, "colorIsTextColor", false); // boolean
|
|
238
|
+
this.strict = deflt(options, "strict", false); // boolean
|
|
239
|
+
this.trust = deflt(options, "trust", false); // trust context. See html.js.
|
|
240
|
+
const maxSize = Object.prototype.hasOwnProperty.call(options, "maxSize")
|
|
212
241
|
? options.maxSize
|
|
242
|
+
: undefined;
|
|
243
|
+
this.maxSize = (maxSize === undefined
|
|
244
|
+
? [Infinity, Infinity]
|
|
245
|
+
: Array.isArray(maxSize)
|
|
246
|
+
? maxSize
|
|
213
247
|
: [Infinity, Infinity]
|
|
214
248
|
);
|
|
215
|
-
this.maxExpand = Math.max(0, deflt(options
|
|
249
|
+
this.maxExpand = Math.max(0, deflt(options, "maxExpand", 1000)); // number
|
|
216
250
|
this.wrapDelimiterPairs = true; // boolean
|
|
217
251
|
}
|
|
218
252
|
|
|
@@ -912,22 +946,26 @@ const NON_ATOMS = {
|
|
|
912
946
|
textord: 1
|
|
913
947
|
};
|
|
914
948
|
|
|
915
|
-
const symbols =
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
};
|
|
949
|
+
const symbols = Object.create(null);
|
|
950
|
+
symbols.math = Object.create(null);
|
|
951
|
+
symbols.text = Object.create(null);
|
|
919
952
|
|
|
920
|
-
/** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
|
|
921
953
|
function defineSymbol(mode, group, replace, name, acceptUnicodeChar) {
|
|
922
|
-
|
|
954
|
+
if (mode !== "math" && mode !== "text") {
|
|
955
|
+
throw new TypeError(`Invalid mode: ${mode} called in defineSymbol`);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
const entry = { group, replace };
|
|
959
|
+
symbols[mode][name] = entry;
|
|
923
960
|
|
|
961
|
+
/** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
|
|
924
962
|
if (acceptUnicodeChar && replace) {
|
|
925
|
-
symbols[mode][replace] =
|
|
963
|
+
symbols[mode][replace] = entry;
|
|
926
964
|
}
|
|
927
965
|
}
|
|
928
966
|
|
|
929
967
|
// Some abbreviations for commonly used strings.
|
|
930
|
-
// This helps minify the code, and also spotting typos
|
|
968
|
+
// This helps minify the code, and also spotting typos via linter.
|
|
931
969
|
|
|
932
970
|
// modes:
|
|
933
971
|
const math = "math";
|
|
@@ -1765,9 +1803,11 @@ defineSymbol(math, op, "\u222b", "\\smallint");
|
|
|
1765
1803
|
defineSymbol(text, inner, "\u2026", "\\textellipsis");
|
|
1766
1804
|
defineSymbol(math, inner, "\u2026", "\\mathellipsis");
|
|
1767
1805
|
defineSymbol(text, inner, "\u2026", "\\ldots", true);
|
|
1806
|
+
defineSymbol(math, inner, "\u2026", "\\dotso");
|
|
1807
|
+
defineSymbol(math, inner, "\u2026", "\\dotsc");
|
|
1768
1808
|
defineSymbol(math, inner, "\u2026", "\\ldots", true);
|
|
1769
1809
|
defineSymbol(math, inner, "\u22f0", "\\iddots", true);
|
|
1770
|
-
defineSymbol(math, inner, "\u22ef", "
|
|
1810
|
+
defineSymbol(math, inner, "\u22ef", "\\cdots", true);
|
|
1771
1811
|
defineSymbol(math, inner, "\u22f1", "\\ddots", true);
|
|
1772
1812
|
defineSymbol(math, textord, "\u22ee", "\\varvdots"); // \vdots is a macro
|
|
1773
1813
|
defineSymbol(text, textord, "\u22ee", "\\varvdots");
|
|
@@ -3557,7 +3597,7 @@ const StyleLevel = {
|
|
|
3557
3597
|
* `macros.js` exports this same dictionary again and makes it public.
|
|
3558
3598
|
* `Parser.js` requires this dictionary via `macros.js`.
|
|
3559
3599
|
*/
|
|
3560
|
-
const _macros =
|
|
3600
|
+
const _macros = Object.create(null);
|
|
3561
3601
|
|
|
3562
3602
|
// This function might one day accept an additional argument and do more things.
|
|
3563
3603
|
function defineMacro(name, body) {
|
|
@@ -3902,60 +3942,6 @@ defineMacro("\\dots", function(context) {
|
|
|
3902
3942
|
return thedots;
|
|
3903
3943
|
});
|
|
3904
3944
|
|
|
3905
|
-
const spaceAfterDots = {
|
|
3906
|
-
// \rightdelim@ checks for the following:
|
|
3907
|
-
")": true,
|
|
3908
|
-
"]": true,
|
|
3909
|
-
"\\rbrack": true,
|
|
3910
|
-
"\\}": true,
|
|
3911
|
-
"\\rbrace": true,
|
|
3912
|
-
"\\rangle": true,
|
|
3913
|
-
"\\rceil": true,
|
|
3914
|
-
"\\rfloor": true,
|
|
3915
|
-
"\\rgroup": true,
|
|
3916
|
-
"\\rmoustache": true,
|
|
3917
|
-
"\\right": true,
|
|
3918
|
-
"\\bigr": true,
|
|
3919
|
-
"\\biggr": true,
|
|
3920
|
-
"\\Bigr": true,
|
|
3921
|
-
"\\Biggr": true,
|
|
3922
|
-
// \extra@ also tests for the following:
|
|
3923
|
-
$: true,
|
|
3924
|
-
// \extrap@ checks for the following:
|
|
3925
|
-
";": true,
|
|
3926
|
-
".": true,
|
|
3927
|
-
",": true
|
|
3928
|
-
};
|
|
3929
|
-
|
|
3930
|
-
defineMacro("\\dotso", function(context) {
|
|
3931
|
-
const next = context.future().text;
|
|
3932
|
-
if (next in spaceAfterDots) {
|
|
3933
|
-
return "\\ldots\\,";
|
|
3934
|
-
} else {
|
|
3935
|
-
return "\\ldots";
|
|
3936
|
-
}
|
|
3937
|
-
});
|
|
3938
|
-
|
|
3939
|
-
defineMacro("\\dotsc", function(context) {
|
|
3940
|
-
const next = context.future().text;
|
|
3941
|
-
// \dotsc uses \extra@ but not \extrap@, instead specially checking for
|
|
3942
|
-
// ';' and '.', but doesn't check for ','.
|
|
3943
|
-
if (next in spaceAfterDots && next !== ",") {
|
|
3944
|
-
return "\\ldots\\,";
|
|
3945
|
-
} else {
|
|
3946
|
-
return "\\ldots";
|
|
3947
|
-
}
|
|
3948
|
-
});
|
|
3949
|
-
|
|
3950
|
-
defineMacro("\\cdots", function(context) {
|
|
3951
|
-
const next = context.future().text;
|
|
3952
|
-
if (next in spaceAfterDots) {
|
|
3953
|
-
return "\\@cdots\\,";
|
|
3954
|
-
} else {
|
|
3955
|
-
return "\\@cdots";
|
|
3956
|
-
}
|
|
3957
|
-
});
|
|
3958
|
-
|
|
3959
3945
|
defineMacro("\\dotsb", "\\cdots");
|
|
3960
3946
|
defineMacro("\\dotsm", "\\cdots");
|
|
3961
3947
|
defineMacro("\\dotsi", "\\!\\cdots");
|
|
@@ -4085,7 +4071,7 @@ defineMacro("\\colon", `\\mathpunct{\\char"3a}`);
|
|
|
4085
4071
|
//////////////////////////////////////////////////////////////////////
|
|
4086
4072
|
// mathtools.sty
|
|
4087
4073
|
|
|
4088
|
-
defineMacro("\\prescript", "\\pres@cript{
|
|
4074
|
+
defineMacro("\\prescript", "\\pres@cript{^{#1}_{#2}}{}{#3}");
|
|
4089
4075
|
|
|
4090
4076
|
//\providecommand\ordinarycolon{:}
|
|
4091
4077
|
defineMacro("\\ordinarycolon", `\\char"3a`);
|
|
@@ -11443,6 +11429,11 @@ const isArrow = str => {
|
|
|
11443
11429
|
defineFunctionBuilders({
|
|
11444
11430
|
type: "atom",
|
|
11445
11431
|
mathmlBuilder(group, style) {
|
|
11432
|
+
if (group.family === "inner") {
|
|
11433
|
+
// Give \dots ORD spacing, not OP spacing.
|
|
11434
|
+
const tag = group.mode === "text" ? "mtext" : "mi";
|
|
11435
|
+
return new MathNode(tag, [makeText(group.text, group.mode)])
|
|
11436
|
+
}
|
|
11446
11437
|
const node = new MathNode("mo", [makeText(group.text, group.mode)]);
|
|
11447
11438
|
if (group.family === "punct") {
|
|
11448
11439
|
node.setAttribute("separator", "true");
|
|
@@ -11998,7 +11989,7 @@ class Namespace {
|
|
|
11998
11989
|
* of initial (global-level) mappings, which will constantly change
|
|
11999
11990
|
* according to any global/top-level `set`s done.
|
|
12000
11991
|
*/
|
|
12001
|
-
constructor(builtins =
|
|
11992
|
+
constructor(builtins = Object.create(null), globalMacros = Object.create(null)) {
|
|
12002
11993
|
this.current = globalMacros;
|
|
12003
11994
|
this.builtins = builtins;
|
|
12004
11995
|
this.undefStack = [];
|
|
@@ -12008,7 +11999,7 @@ class Namespace {
|
|
|
12008
11999
|
* Start a new nested group, affecting future local `set`s.
|
|
12009
12000
|
*/
|
|
12010
12001
|
beginGroup() {
|
|
12011
|
-
this.undefStack.push(
|
|
12002
|
+
this.undefStack.push(Object.create(null));
|
|
12012
12003
|
}
|
|
12013
12004
|
|
|
12014
12005
|
/**
|
|
@@ -14206,7 +14197,7 @@ class Style {
|
|
|
14206
14197
|
* https://mit-license.org/
|
|
14207
14198
|
*/
|
|
14208
14199
|
|
|
14209
|
-
const version = "0.
|
|
14200
|
+
const version = "0.14.0";
|
|
14210
14201
|
|
|
14211
14202
|
function postProcess(block) {
|
|
14212
14203
|
const labelMap = {};
|
|
@@ -14527,7 +14518,7 @@ const renderMathInElement = function(elem, options) {
|
|
|
14527
14518
|
|
|
14528
14519
|
// Enable sharing of global macros defined via `\gdef` between different
|
|
14529
14520
|
// math elements within a single call to `renderMathInElement`.
|
|
14530
|
-
optionsCopy.macros = optionsCopy.macros ||
|
|
14521
|
+
optionsCopy.macros = optionsCopy.macros || Object.create(null);
|
|
14531
14522
|
|
|
14532
14523
|
renderElem(elem, optionsCopy);
|
|
14533
14524
|
postProcess(elem);
|
|
@@ -14606,7 +14597,7 @@ const generateParseTree = function(expression, options) {
|
|
|
14606
14597
|
*/
|
|
14607
14598
|
const definePreamble = function(expression, options) {
|
|
14608
14599
|
const settings = new Settings(options);
|
|
14609
|
-
settings.macros =
|
|
14600
|
+
settings.macros = Object.create(null);
|
|
14610
14601
|
if (!(typeof expression === "string" || expression instanceof String)) {
|
|
14611
14602
|
throw new TypeError("Temml can only parse string typed expression")
|
|
14612
14603
|
}
|
package/dist/temmlPostProcess.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "temml",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "TeX to MathML conversion in JavaScript.",
|
|
5
5
|
"main": "dist/temml.js",
|
|
6
6
|
"engines": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"homepage": "https://temml.org",
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
20
|
-
"url": "git://github.com/ronkok/Temml"
|
|
20
|
+
"url": "git+https://github.com/ronkok/Temml.git"
|
|
21
21
|
},
|
|
22
22
|
"packageManager": "yarn@3.3.1",
|
|
23
23
|
"files": [
|
package/src/Namespace.js
CHANGED
|
@@ -15,7 +15,7 @@ export default class Namespace {
|
|
|
15
15
|
* of initial (global-level) mappings, which will constantly change
|
|
16
16
|
* according to any global/top-level `set`s done.
|
|
17
17
|
*/
|
|
18
|
-
constructor(builtins =
|
|
18
|
+
constructor(builtins = Object.create(null), globalMacros = Object.create(null)) {
|
|
19
19
|
this.current = globalMacros;
|
|
20
20
|
this.builtins = builtins;
|
|
21
21
|
this.undefStack = [];
|
|
@@ -25,7 +25,7 @@ export default class Namespace {
|
|
|
25
25
|
* Start a new nested group, affecting future local `set`s.
|
|
26
26
|
*/
|
|
27
27
|
beginGroup() {
|
|
28
|
-
this.undefStack.push(
|
|
28
|
+
this.undefStack.push(Object.create(null));
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
package/src/Settings.js
CHANGED
|
@@ -5,6 +5,27 @@
|
|
|
5
5
|
|
|
6
6
|
import * as utils from "./utils";
|
|
7
7
|
|
|
8
|
+
const FORBIDDEN_MACRO_KEYS = ["__proto__", "prototype", "constructor"];
|
|
9
|
+
|
|
10
|
+
// Sanitize a user-supplied macros object: strip its prototype (so later
|
|
11
|
+
// bracket-notation writes, e.g. from \gdef, can never reach Object.prototype)
|
|
12
|
+
// and delete any own key that could be used to pollute it. This mutates
|
|
13
|
+
// `macros` in place and returns the same reference, rather than a copy,
|
|
14
|
+
// because callers such as auto-render.js rely on that identity to share
|
|
15
|
+
// \gdef'd macros across multiple render calls that pass the same options
|
|
16
|
+
// object.
|
|
17
|
+
const sanitizeMacros = (macros) => {
|
|
18
|
+
if (macros == null || typeof macros !== "object") {
|
|
19
|
+
return Object.create(null);
|
|
20
|
+
}
|
|
21
|
+
for (const key of FORBIDDEN_MACRO_KEYS) {
|
|
22
|
+
if (Object.prototype.hasOwnProperty.call(macros, key)) {
|
|
23
|
+
delete macros[key];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return Object.setPrototypeOf(macros, null);
|
|
27
|
+
};
|
|
28
|
+
|
|
8
29
|
/**
|
|
9
30
|
* The main Settings object
|
|
10
31
|
*/
|
|
@@ -12,24 +33,29 @@ export default class Settings {
|
|
|
12
33
|
constructor(options) {
|
|
13
34
|
// allow null options
|
|
14
35
|
options = options || {};
|
|
15
|
-
this.displayMode = utils.deflt(options
|
|
16
|
-
this.annotate = utils.deflt(options
|
|
17
|
-
this.leqno = utils.deflt(options
|
|
18
|
-
this.throwOnError = utils.deflt(options
|
|
19
|
-
this.errorColor = utils.deflt(options
|
|
20
|
-
this.macros =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
27
|
-
|
|
28
|
-
|
|
36
|
+
this.displayMode = utils.deflt(options, "displayMode", false); // boolean
|
|
37
|
+
this.annotate = utils.deflt(options, "annotate", false) // boolean
|
|
38
|
+
this.leqno = utils.deflt(options, "leqno", false); // boolean
|
|
39
|
+
this.throwOnError = utils.deflt(options, "throwOnError", false); // boolean
|
|
40
|
+
this.errorColor = utils.deflt(options, "errorColor", "#b22222"); // string
|
|
41
|
+
this.macros = sanitizeMacros(
|
|
42
|
+
Object.prototype.hasOwnProperty.call(options, "macros") ? options.macros : undefined
|
|
43
|
+
);
|
|
44
|
+
this.wrap = utils.deflt(options, "wrap", "none") // "none" | "tex" | "="
|
|
45
|
+
this.xml = utils.deflt(options, "xml", false); // boolean
|
|
46
|
+
this.colorIsTextColor = utils.deflt(options, "colorIsTextColor", false); // boolean
|
|
47
|
+
this.strict = utils.deflt(options, "strict", false); // boolean
|
|
48
|
+
this.trust = utils.deflt(options, "trust", false); // trust context. See html.js.
|
|
49
|
+
const maxSize = Object.prototype.hasOwnProperty.call(options, "maxSize")
|
|
29
50
|
? options.maxSize
|
|
51
|
+
: undefined;
|
|
52
|
+
this.maxSize = (maxSize === undefined
|
|
53
|
+
? [Infinity, Infinity]
|
|
54
|
+
: Array.isArray(maxSize)
|
|
55
|
+
? maxSize
|
|
30
56
|
: [Infinity, Infinity]
|
|
31
57
|
)
|
|
32
|
-
this.maxExpand = Math.max(0, utils.deflt(options
|
|
58
|
+
this.maxExpand = Math.max(0, utils.deflt(options, "maxExpand", 1000)); // number
|
|
33
59
|
this.wrapDelimiterPairs = true; // boolean
|
|
34
60
|
}
|
|
35
61
|
|
package/src/auto-render.js
CHANGED
|
@@ -256,7 +256,7 @@ export const renderMathInElement = function(elem, options) {
|
|
|
256
256
|
|
|
257
257
|
// Enable sharing of global macros defined via `\gdef` between different
|
|
258
258
|
// math elements within a single call to `renderMathInElement`.
|
|
259
|
-
optionsCopy.macros = optionsCopy.macros ||
|
|
259
|
+
optionsCopy.macros = optionsCopy.macros || Object.create(null);
|
|
260
260
|
|
|
261
261
|
renderElem(elem, optionsCopy);
|
|
262
262
|
postProcess(elem);
|
package/src/defineMacro.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* `macros.js` exports this same dictionary again and makes it public.
|
|
4
4
|
* `Parser.js` requires this dictionary via `macros.js`.
|
|
5
5
|
*/
|
|
6
|
-
export const _macros =
|
|
6
|
+
export const _macros = Object.create(null);
|
|
7
7
|
|
|
8
8
|
// This function might one day accept an additional argument and do more things.
|
|
9
9
|
export default function defineMacro(name, body) {
|
|
@@ -21,6 +21,11 @@ const isArrow = str => {
|
|
|
21
21
|
defineFunctionBuilders({
|
|
22
22
|
type: "atom",
|
|
23
23
|
mathmlBuilder(group, style) {
|
|
24
|
+
if (group.family === "inner") {
|
|
25
|
+
// Give \dots ORD spacing, not OP spacing.
|
|
26
|
+
const tag = group.mode === "text" ? "mtext" : "mi"
|
|
27
|
+
return new mathMLTree.MathNode(tag, [mml.makeText(group.text, group.mode)])
|
|
28
|
+
}
|
|
24
29
|
const node = new mathMLTree.MathNode("mo", [mml.makeText(group.text, group.mode)]);
|
|
25
30
|
if (group.family === "punct") {
|
|
26
31
|
node.setAttribute("separator", "true");
|
package/src/macros.js
CHANGED
|
@@ -342,60 +342,6 @@ defineMacro("\\dots", function(context) {
|
|
|
342
342
|
return thedots;
|
|
343
343
|
});
|
|
344
344
|
|
|
345
|
-
const spaceAfterDots = {
|
|
346
|
-
// \rightdelim@ checks for the following:
|
|
347
|
-
")": true,
|
|
348
|
-
"]": true,
|
|
349
|
-
"\\rbrack": true,
|
|
350
|
-
"\\}": true,
|
|
351
|
-
"\\rbrace": true,
|
|
352
|
-
"\\rangle": true,
|
|
353
|
-
"\\rceil": true,
|
|
354
|
-
"\\rfloor": true,
|
|
355
|
-
"\\rgroup": true,
|
|
356
|
-
"\\rmoustache": true,
|
|
357
|
-
"\\right": true,
|
|
358
|
-
"\\bigr": true,
|
|
359
|
-
"\\biggr": true,
|
|
360
|
-
"\\Bigr": true,
|
|
361
|
-
"\\Biggr": true,
|
|
362
|
-
// \extra@ also tests for the following:
|
|
363
|
-
$: true,
|
|
364
|
-
// \extrap@ checks for the following:
|
|
365
|
-
";": true,
|
|
366
|
-
".": true,
|
|
367
|
-
",": true
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
defineMacro("\\dotso", function(context) {
|
|
371
|
-
const next = context.future().text;
|
|
372
|
-
if (next in spaceAfterDots) {
|
|
373
|
-
return "\\ldots\\,";
|
|
374
|
-
} else {
|
|
375
|
-
return "\\ldots";
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
defineMacro("\\dotsc", function(context) {
|
|
380
|
-
const next = context.future().text;
|
|
381
|
-
// \dotsc uses \extra@ but not \extrap@, instead specially checking for
|
|
382
|
-
// ';' and '.', but doesn't check for ','.
|
|
383
|
-
if (next in spaceAfterDots && next !== ",") {
|
|
384
|
-
return "\\ldots\\,";
|
|
385
|
-
} else {
|
|
386
|
-
return "\\ldots";
|
|
387
|
-
}
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
defineMacro("\\cdots", function(context) {
|
|
391
|
-
const next = context.future().text;
|
|
392
|
-
if (next in spaceAfterDots) {
|
|
393
|
-
return "\\@cdots\\,";
|
|
394
|
-
} else {
|
|
395
|
-
return "\\@cdots";
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
|
-
|
|
399
345
|
defineMacro("\\dotsb", "\\cdots");
|
|
400
346
|
defineMacro("\\dotsm", "\\cdots");
|
|
401
347
|
defineMacro("\\dotsi", "\\!\\cdots");
|
|
@@ -525,7 +471,7 @@ defineMacro("\\colon", `\\mathpunct{\\char"3a}`)
|
|
|
525
471
|
//////////////////////////////////////////////////////////////////////
|
|
526
472
|
// mathtools.sty
|
|
527
473
|
|
|
528
|
-
defineMacro("\\prescript", "\\pres@cript{
|
|
474
|
+
defineMacro("\\prescript", "\\pres@cript{^{#1}_{#2}}{}{#3}")
|
|
529
475
|
|
|
530
476
|
//\providecommand\ordinarycolon{:}
|
|
531
477
|
defineMacro("\\ordinarycolon", `\\char"3a`);
|
package/src/postProcess.js
CHANGED
package/src/symbols.js
CHANGED
|
@@ -33,23 +33,27 @@ export const NON_ATOMS = {
|
|
|
33
33
|
textord: 1
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
const symbols =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
};
|
|
36
|
+
const symbols = Object.create(null);
|
|
37
|
+
symbols.math = Object.create(null);
|
|
38
|
+
symbols.text = Object.create(null);
|
|
40
39
|
export default symbols;
|
|
41
40
|
|
|
42
|
-
/** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
|
|
43
41
|
export function defineSymbol(mode, group, replace, name, acceptUnicodeChar) {
|
|
44
|
-
|
|
42
|
+
if (mode !== "math" && mode !== "text") {
|
|
43
|
+
throw new TypeError(`Invalid mode: ${mode} called in defineSymbol`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const entry = { group, replace };
|
|
47
|
+
symbols[mode][name] = entry;
|
|
45
48
|
|
|
49
|
+
/** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
|
|
46
50
|
if (acceptUnicodeChar && replace) {
|
|
47
|
-
symbols[mode][replace] =
|
|
51
|
+
symbols[mode][replace] = entry;
|
|
48
52
|
}
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
// Some abbreviations for commonly used strings.
|
|
52
|
-
// This helps minify the code, and also spotting typos
|
|
56
|
+
// This helps minify the code, and also spotting typos via linter.
|
|
53
57
|
|
|
54
58
|
// modes:
|
|
55
59
|
const math = "math";
|
|
@@ -887,9 +891,11 @@ defineSymbol(math, op, "\u222b", "\\smallint");
|
|
|
887
891
|
defineSymbol(text, inner, "\u2026", "\\textellipsis");
|
|
888
892
|
defineSymbol(math, inner, "\u2026", "\\mathellipsis");
|
|
889
893
|
defineSymbol(text, inner, "\u2026", "\\ldots", true);
|
|
894
|
+
defineSymbol(math, inner, "\u2026", "\\dotso");
|
|
895
|
+
defineSymbol(math, inner, "\u2026", "\\dotsc");
|
|
890
896
|
defineSymbol(math, inner, "\u2026", "\\ldots", true);
|
|
891
897
|
defineSymbol(math, inner, "\u22f0", "\\iddots", true);
|
|
892
|
-
defineSymbol(math, inner, "\u22ef", "
|
|
898
|
+
defineSymbol(math, inner, "\u22ef", "\\cdots", true);
|
|
893
899
|
defineSymbol(math, inner, "\u22f1", "\\ddots", true);
|
|
894
900
|
defineSymbol(math, textord, "\u22ee", "\\varvdots"); // \vdots is a macro
|
|
895
901
|
defineSymbol(text, textord, "\u22ee", "\\varvdots");
|
package/src/utils.js
CHANGED
|
@@ -5,9 +5,17 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Look up `key` on a user-supplied `options` object and return its value, or
|
|
9
|
+
* `defaultIfUndefined` if the setting is absent. Reads via
|
|
10
|
+
* `Object.prototype.hasOwnProperty.call` rather than plain property access,
|
|
11
|
+
* so a key that only exists because `Object.prototype` was polluted
|
|
12
|
+
* elsewhere is never mistaken for a setting the caller actually provided.
|
|
9
13
|
*/
|
|
10
|
-
export const deflt = function(
|
|
14
|
+
export const deflt = function(options, key, defaultIfUndefined) {
|
|
15
|
+
if (!Object.prototype.hasOwnProperty.call(options, key)) {
|
|
16
|
+
return defaultIfUndefined;
|
|
17
|
+
}
|
|
18
|
+
const setting = options[key];
|
|
11
19
|
return setting === undefined ? defaultIfUndefined : setting;
|
|
12
20
|
};
|
|
13
21
|
|
package/temml.js
CHANGED
|
@@ -84,7 +84,7 @@ const generateParseTree = function(expression, options) {
|
|
|
84
84
|
*/
|
|
85
85
|
const definePreamble = function(expression, options) {
|
|
86
86
|
const settings = new Settings(options);
|
|
87
|
-
settings.macros =
|
|
87
|
+
settings.macros = Object.create(null);
|
|
88
88
|
if (!(typeof expression === "string" || expression instanceof String)) {
|
|
89
89
|
throw new TypeError("Temml can only parse string typed expression")
|
|
90
90
|
}
|