temml 0.10.0 → 0.10.3
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +3 -4
- package/contrib/auto-render/test/auto-render-spec.js +1 -1
- package/contrib/mhchem/mhchem.js +2 -2
- package/dist/Temml-Asana.css +17 -1
- package/dist/Temml-Latin-Modern.css +17 -5
- package/dist/Temml-Libertinus.css +17 -5
- package/dist/Temml-Local.css +16 -0
- package/dist/Temml-STIX2.css +16 -0
- package/dist/temml.cjs +67 -58
- package/dist/temml.js +65 -56
- package/dist/temml.min.js +1 -1
- package/dist/temml.mjs +67 -58
- package/dist/temmlPostProcess.js +1 -1
- package/package.json +2 -1
- package/src/MacroExpander.js +20 -21
- package/src/Parser.js +8 -3
- package/src/Settings.js +1 -1
- package/src/buildMathML.js +4 -13
- package/src/functions/delimsizing.js +5 -0
- package/src/functions/op.js +1 -5
- package/src/functions/operatorname.js +10 -8
- package/src/functions/supsub.js +7 -0
- package/src/linebreaking.js +3 -1
- package/src/mathMLTree.js +1 -1
- package/src/postProcess.js +1 -1
- package/src/symbols.js +5 -2
package/dist/temml.js
CHANGED
@@ -191,7 +191,7 @@ var temml = (function () {
|
|
191
191
|
this.leqno = utils.deflt(options.leqno, false); // boolean
|
192
192
|
this.errorColor = utils.deflt(options.errorColor, "#b22222"); // string
|
193
193
|
this.macros = options.macros || {};
|
194
|
-
this.wrap = utils.deflt(options.wrap, "
|
194
|
+
this.wrap = utils.deflt(options.wrap, "tex"); // "tex" | "="
|
195
195
|
this.xml = utils.deflt(options.xml, false); // boolean
|
196
196
|
this.colorIsTextColor = utils.deflt(options.colorIsTextColor, false); // booelean
|
197
197
|
this.strict = utils.deflt(options.strict, false); // boolean
|
@@ -669,7 +669,7 @@ var temml = (function () {
|
|
669
669
|
|
670
670
|
/**
|
671
671
|
* Converts the text node into a string
|
672
|
-
* (representing the text
|
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.
|
@@ -1747,10 +1750,12 @@ var temml = (function () {
|
|
1747
1750
|
* Then the top level of a <math> element can be occupied by <mrow> elements, and the browser
|
1748
1751
|
* will break after a <mrow> if the expression extends beyond the container limit.
|
1749
1752
|
*
|
1750
|
-
*
|
1753
|
+
* The default is for soft line breaks after each top-level binary or
|
1751
1754
|
* relational operator, per TeXbook p. 173. So we gather the expression into <mrow>s so that
|
1752
1755
|
* each <mrow> ends in a binary or relational operator.
|
1753
1756
|
*
|
1757
|
+
* An option is for soft line breaks before an "=" sign. That changes the <mrow>s.
|
1758
|
+
*
|
1754
1759
|
* Soft line breaks will not work in Chromium and Safari, only Firefox.
|
1755
1760
|
*
|
1756
1761
|
* Hopefully browsers will someday do their own linebreaking and we will be able to delete
|
@@ -1893,7 +1898,7 @@ var temml = (function () {
|
|
1893
1898
|
}
|
1894
1899
|
|
1895
1900
|
/**
|
1896
|
-
* This file converts a parse tree into a
|
1901
|
+
* This file converts a parse tree into a corresponding MathML tree. The main
|
1897
1902
|
* entry point is the `buildMathML` function, which takes a parse tree from the
|
1898
1903
|
* parser.
|
1899
1904
|
*/
|
@@ -2096,18 +2101,6 @@ var temml = (function () {
|
|
2096
2101
|
wrapper = new mathMLTree.MathNode("semantics", [wrapper, annotation]);
|
2097
2102
|
}
|
2098
2103
|
|
2099
|
-
if (wrap !== "none" && wrapper.children.length > 1) {
|
2100
|
-
const maths = [];
|
2101
|
-
for (let i = 0; i < wrapper.children.length; i++) {
|
2102
|
-
const math = new mathMLTree.MathNode("math", [wrapper.children[i]]);
|
2103
|
-
if (settings.xml) {
|
2104
|
-
math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML");
|
2105
|
-
}
|
2106
|
-
maths.push(math);
|
2107
|
-
}
|
2108
|
-
return mathMLTree.newDocumentFragment(maths)
|
2109
|
-
}
|
2110
|
-
|
2111
2104
|
const math = new mathMLTree.MathNode("math", [wrapper]);
|
2112
2105
|
|
2113
2106
|
if (settings.xml) {
|
@@ -2115,6 +2108,9 @@ var temml = (function () {
|
|
2115
2108
|
}
|
2116
2109
|
if (settings.displayMode) {
|
2117
2110
|
math.setAttribute("display", "block");
|
2111
|
+
math.style.display = math.children.length === 1 && math.children[0].type === "mtable"
|
2112
|
+
? "inline"
|
2113
|
+
: "inline-block";
|
2118
2114
|
}
|
2119
2115
|
return math;
|
2120
2116
|
}
|
@@ -3524,6 +3520,11 @@ var temml = (function () {
|
|
3524
3520
|
"."
|
3525
3521
|
];
|
3526
3522
|
|
3523
|
+
// Export isDelimiter for benefit of parser.
|
3524
|
+
const dels = ["}", "\\left", "\\middle", "\\right"];
|
3525
|
+
const isDelimiter = str => str.length > 0 &&
|
3526
|
+
(delimiters.includes(str) || delimiterSizes[str] || dels.includes(str));
|
3527
|
+
|
3527
3528
|
// Metrics of the different sizes. Found by looking at TeX's output of
|
3528
3529
|
// $\bigl| // \Bigl| \biggl| \Biggl| \showlists$
|
3529
3530
|
// Used to create stacked delimiters of appropriate sizes in makeSizedDelim.
|
@@ -6206,10 +6207,6 @@ var temml = (function () {
|
|
6206
6207
|
// Math operators (e.g. \sin) need a space between these types and themselves:
|
6207
6208
|
const ordTypes = ["textord", "mathord", "ordgroup", "close", "leftright"];
|
6208
6209
|
|
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
6210
|
// NOTE: Unlike most `builders`s, this one handles not only "op", but also
|
6214
6211
|
// "supsub" since some of them (like \int) can affect super/subscripting.
|
6215
6212
|
|
@@ -6430,7 +6427,7 @@ var temml = (function () {
|
|
6430
6427
|
parentIsSupSub: false,
|
6431
6428
|
symbol: false,
|
6432
6429
|
stack: false,
|
6433
|
-
isFollowedByDelimiter: isDelimiter
|
6430
|
+
isFollowedByDelimiter: isDelimiter(next),
|
6434
6431
|
needsLeadingSpace: prevAtomType.length > 0 && ordTypes.includes(prevAtomType),
|
6435
6432
|
name: funcName
|
6436
6433
|
};
|
@@ -6455,7 +6452,7 @@ var temml = (function () {
|
|
6455
6452
|
parentIsSupSub: false,
|
6456
6453
|
symbol: false,
|
6457
6454
|
stack: false,
|
6458
|
-
isFollowedByDelimiter: isDelimiter
|
6455
|
+
isFollowedByDelimiter: isDelimiter(next),
|
6459
6456
|
needsLeadingSpace: prevAtomType.length > 0 && ordTypes.includes(prevAtomType),
|
6460
6457
|
name: funcName
|
6461
6458
|
};
|
@@ -6541,11 +6538,7 @@ var temml = (function () {
|
|
6541
6538
|
_macros[name] = body;
|
6542
6539
|
}
|
6543
6540
|
|
6544
|
-
|
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
|
6541
|
+
// NOTE: Unlike most builders, this one handles not only
|
6549
6542
|
// "operatorname", but also "supsub" since \operatorname* can
|
6550
6543
|
// affect super/subscripting.
|
6551
6544
|
|
@@ -6555,8 +6548,12 @@ var temml = (function () {
|
|
6555
6548
|
// Is expression a string or has it something like a fraction?
|
6556
6549
|
let isAllString = true; // default
|
6557
6550
|
for (let i = 0; i < expression.length; i++) {
|
6558
|
-
|
6551
|
+
let node = expression[i];
|
6559
6552
|
if (node instanceof mathMLTree.MathNode) {
|
6553
|
+
if (node.type === "mrow" && node.children.length === 1 &&
|
6554
|
+
node.children[0] instanceof mathMLTree.MathNode) {
|
6555
|
+
node = node.children[0];
|
6556
|
+
}
|
6560
6557
|
switch (node.type) {
|
6561
6558
|
case "mi":
|
6562
6559
|
case "mn":
|
@@ -6614,7 +6611,9 @@ var temml = (function () {
|
|
6614
6611
|
let wrapper;
|
6615
6612
|
if (isAllString) {
|
6616
6613
|
wrapper = new mathMLTree.MathNode("mi", expression);
|
6617
|
-
|
6614
|
+
if (expression[0].text.length === 1) {
|
6615
|
+
wrapper.setAttribute("mathvariant", "normal");
|
6616
|
+
}
|
6618
6617
|
} else {
|
6619
6618
|
wrapper = new mathMLTree.MathNode("mrow", expression);
|
6620
6619
|
}
|
@@ -7152,6 +7151,7 @@ var temml = (function () {
|
|
7152
7151
|
let isOver;
|
7153
7152
|
let isSup;
|
7154
7153
|
let appendApplyFunction = false;
|
7154
|
+
let appendSpace = false;
|
7155
7155
|
let needsLeadingSpace = false;
|
7156
7156
|
|
7157
7157
|
if (group.base && group.base.type === "horizBrace") {
|
@@ -7166,6 +7166,7 @@ var temml = (function () {
|
|
7166
7166
|
(group.base.type === "op" || group.base.type === "operatorname")) {
|
7167
7167
|
group.base.parentIsSupSub = true;
|
7168
7168
|
appendApplyFunction = !group.base.symbol;
|
7169
|
+
appendSpace = appendApplyFunction && !group.isFollowedByDelimiter;
|
7169
7170
|
needsLeadingSpace = group.base.needsLeadingSpace;
|
7170
7171
|
}
|
7171
7172
|
|
@@ -7253,6 +7254,11 @@ var temml = (function () {
|
|
7253
7254
|
} else {
|
7254
7255
|
node = mathMLTree.newDocumentFragment([node, operator]);
|
7255
7256
|
}
|
7257
|
+
if (appendSpace) {
|
7258
|
+
const space = new mathMLTree.MathNode("mspace");
|
7259
|
+
space.setAttribute("width", "0.1667em"); // thin space.
|
7260
|
+
node.children.push(space);
|
7261
|
+
}
|
7256
7262
|
} else if (symbolRegEx.test(nodeType)) {
|
7257
7263
|
// Wrap in a <mrow>. Otherwise Firefox stretchy parens will not stretch to include limits.
|
7258
7264
|
node = new mathMLTree.MathNode("mrow", [node]);
|
@@ -9107,15 +9113,15 @@ var temml = (function () {
|
|
9107
9113
|
* Expand the next token only once if possible.
|
9108
9114
|
*
|
9109
9115
|
* If the token is expanded, the resulting tokens will be pushed onto
|
9110
|
-
* the stack in reverse order and
|
9111
|
-
*
|
9116
|
+
* the stack in reverse order, and the number of such tokens will be
|
9117
|
+
* returned. This number might be zero or positive.
|
9112
9118
|
*
|
9113
|
-
* If not, the
|
9114
|
-
*
|
9115
|
-
* instead of an `Array` return value.
|
9119
|
+
* If not, the return value is `false`, and the next token remains at the
|
9120
|
+
* top of the stack.
|
9116
9121
|
*
|
9117
9122
|
* In either case, the next token will be on the top of the stack,
|
9118
|
-
* or the stack will be empty
|
9123
|
+
* or the stack will be empty (in case of empty expansion
|
9124
|
+
* and no other tokens).
|
9119
9125
|
*
|
9120
9126
|
* Used to implement `expandAfterFuture` and `expandNextToken`.
|
9121
9127
|
*
|
@@ -9131,7 +9137,7 @@ var temml = (function () {
|
|
9131
9137
|
throw new ParseError("Undefined control sequence: " + name);
|
9132
9138
|
}
|
9133
9139
|
this.pushToken(topToken);
|
9134
|
-
return
|
9140
|
+
return false;
|
9135
9141
|
}
|
9136
9142
|
this.expansionCount++;
|
9137
9143
|
if (this.expansionCount > this.settings.maxExpand) {
|
@@ -9165,7 +9171,7 @@ var temml = (function () {
|
|
9165
9171
|
}
|
9166
9172
|
// Concatenate expansion onto top of stack.
|
9167
9173
|
this.pushTokens(tokens);
|
9168
|
-
return tokens;
|
9174
|
+
return tokens.length;
|
9169
9175
|
}
|
9170
9176
|
|
9171
9177
|
/**
|
@@ -9184,14 +9190,13 @@ var temml = (function () {
|
|
9184
9190
|
*/
|
9185
9191
|
expandNextToken() {
|
9186
9192
|
for (;;) {
|
9187
|
-
|
9188
|
-
|
9189
|
-
if (expanded instanceof Token) {
|
9193
|
+
if (this.expandOnce() === false) { // fully expanded
|
9194
|
+
const token = this.stack.pop();
|
9190
9195
|
// The token after \noexpand is interpreted as if its meaning were ‘\relax’
|
9191
|
-
if (
|
9192
|
-
|
9196
|
+
if (token.treatAsRelax) {
|
9197
|
+
token.text = "\\relax";
|
9193
9198
|
}
|
9194
|
-
return
|
9199
|
+
return token
|
9195
9200
|
}
|
9196
9201
|
}
|
9197
9202
|
|
@@ -9217,15 +9222,15 @@ var temml = (function () {
|
|
9217
9222
|
const oldStackLength = this.stack.length;
|
9218
9223
|
this.pushTokens(tokens);
|
9219
9224
|
while (this.stack.length > oldStackLength) {
|
9220
|
-
|
9221
|
-
|
9222
|
-
|
9223
|
-
if (
|
9225
|
+
// Expand only expandable tokens
|
9226
|
+
if (this.expandOnce(true) === false) { // fully expanded
|
9227
|
+
const token = this.stack.pop();
|
9228
|
+
if (token.treatAsRelax) {
|
9224
9229
|
// the expansion of \noexpand is the token itself
|
9225
|
-
|
9226
|
-
|
9230
|
+
token.noexpand = false;
|
9231
|
+
token.treatAsRelax = false;
|
9227
9232
|
}
|
9228
|
-
output.push(
|
9233
|
+
output.push(token);
|
9229
9234
|
}
|
9230
9235
|
}
|
9231
9236
|
return output;
|
@@ -10053,7 +10058,7 @@ var temml = (function () {
|
|
10053
10058
|
* Parses an "expression", which is a list of atoms.
|
10054
10059
|
*
|
10055
10060
|
* `breakOnInfix`: Should the parsing stop when we hit infix nodes? This
|
10056
|
-
* happens when functions have higher
|
10061
|
+
* happens when functions have higher precedence han infix
|
10057
10062
|
* nodes in implicit parses.
|
10058
10063
|
*
|
10059
10064
|
* `breakOnTokenText`: The text of the token that the expression should end
|
@@ -10304,12 +10309,16 @@ var temml = (function () {
|
|
10304
10309
|
return base
|
10305
10310
|
} else {
|
10306
10311
|
// We got either a superscript or subscript, create a supsub
|
10312
|
+
const isFollowedByDelimiter = (!base || base.type !== "op" && base.type !== "operatorname")
|
10313
|
+
? undefined
|
10314
|
+
: isDelimiter(this.nextToken.text);
|
10307
10315
|
return {
|
10308
10316
|
type: "supsub",
|
10309
10317
|
mode: this.mode,
|
10310
10318
|
base: base,
|
10311
10319
|
sup: superscript,
|
10312
|
-
sub: subscript
|
10320
|
+
sub: subscript,
|
10321
|
+
isFollowedByDelimiter
|
10313
10322
|
}
|
10314
10323
|
}
|
10315
10324
|
} else {
|
@@ -10470,7 +10479,7 @@ var temml = (function () {
|
|
10470
10479
|
while (true) {
|
10471
10480
|
const ch = this.fetch().text;
|
10472
10481
|
// \ufe0e is the Unicode variation selector to supress emoji. Ignore it.
|
10473
|
-
if (ch === " " || ch === "\ufe0e") {
|
10482
|
+
if (ch === " " || ch === "\u00a0" || ch === "\ufe0e") {
|
10474
10483
|
this.consume();
|
10475
10484
|
} else {
|
10476
10485
|
break
|
@@ -11062,7 +11071,7 @@ var temml = (function () {
|
|
11062
11071
|
* https://mit-license.org/
|
11063
11072
|
*/
|
11064
11073
|
|
11065
|
-
const version = "0.10.
|
11074
|
+
const version = "0.10.3";
|
11066
11075
|
|
11067
11076
|
function postProcess(block) {
|
11068
11077
|
const labelMap = {};
|