temml 0.10.32 → 0.10.33
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/README.md +1 -1
- package/dist/temml.cjs +252 -128
- package/dist/temml.js +252 -128
- package/dist/temml.min.js +1 -1
- package/dist/temml.mjs +252 -128
- package/dist/temmlPostProcess.js +37 -24
- package/package.json +1 -1
- package/src/Style.js +5 -3
- package/src/buildMathML.js +84 -62
- package/src/domTree.js +34 -0
- package/src/environments/cd.js +15 -10
- package/src/functions/arrow.js +11 -3
- package/src/functions/def.js +7 -4
- package/src/functions/delimsizing.js +1 -0
- package/src/functions/font.js +1 -0
- package/src/functions/genfrac.js +13 -4
- package/src/functions/href.js +4 -6
- package/src/functions/op.js +0 -7
- package/src/functions/ref.js +3 -5
- package/src/functions/rule.js +2 -0
- package/src/functions/supsub.js +12 -3
- package/src/functions/vcenter.js +30 -0
- package/src/functions.js +1 -0
- package/src/macros.js +1 -1
- package/src/postProcess.js +37 -24
- package/src/symbols.js +2 -2
- package/src/variant.js +2 -0
package/README.md
CHANGED
package/dist/temml.cjs
CHANGED
@@ -501,6 +501,40 @@ let TextNode$1 = class TextNode {
|
|
501
501
|
}
|
502
502
|
};
|
503
503
|
|
504
|
+
// Create an <a href="…"> node.
|
505
|
+
class AnchorNode {
|
506
|
+
constructor(href, classes, children) {
|
507
|
+
this.href = href;
|
508
|
+
this.classes = classes;
|
509
|
+
this.children = children || [];
|
510
|
+
}
|
511
|
+
|
512
|
+
toNode() {
|
513
|
+
const node = document.createElement("a");
|
514
|
+
node.setAttribute("href", this.href);
|
515
|
+
if (this.classes.length > 0) {
|
516
|
+
node.className = createClass(this.classes);
|
517
|
+
}
|
518
|
+
for (let i = 0; i < this.children.length; i++) {
|
519
|
+
node.appendChild(this.children[i].toNode());
|
520
|
+
}
|
521
|
+
return node
|
522
|
+
}
|
523
|
+
|
524
|
+
toMarkup() {
|
525
|
+
let markup = `<a href='${utils.escape(this.href)}'`;
|
526
|
+
if (this.classes.length > 0) {
|
527
|
+
markup += ` class="${utils.escape(createClass(this.classes))}"`;
|
528
|
+
}
|
529
|
+
markup += ">";
|
530
|
+
for (let i = 0; i < this.children.length; i++) {
|
531
|
+
markup += this.children[i].toMarkup();
|
532
|
+
}
|
533
|
+
markup += "</a>";
|
534
|
+
return markup
|
535
|
+
}
|
536
|
+
}
|
537
|
+
|
504
538
|
/*
|
505
539
|
* This node represents an image embed (<img>) element.
|
506
540
|
*/
|
@@ -1530,7 +1564,7 @@ defineSymbol(math, open, "\u27e8", "\\langle", true);
|
|
1530
1564
|
defineSymbol(math, open, "\u27ea", "\\lAngle", true);
|
1531
1565
|
defineSymbol(math, open, "\u2989", "\\llangle", true);
|
1532
1566
|
defineSymbol(math, open, "|", "\\lvert");
|
1533
|
-
defineSymbol(math, open, "\u2016", "\\lVert");
|
1567
|
+
defineSymbol(math, open, "\u2016", "\\lVert", true);
|
1534
1568
|
defineSymbol(math, textord, "!", "\\oc"); // cmll package
|
1535
1569
|
defineSymbol(math, textord, "?", "\\wn");
|
1536
1570
|
defineSymbol(math, textord, "\u2193", "\\shpos");
|
@@ -1694,7 +1728,7 @@ defineSymbol(math, inner, "\u22f0", "\\iddots", true);
|
|
1694
1728
|
defineSymbol(math, inner, "\u22ef", "\\@cdots", true);
|
1695
1729
|
defineSymbol(math, inner, "\u22f1", "\\ddots", true);
|
1696
1730
|
defineSymbol(math, textord, "\u22ee", "\\varvdots"); // \vdots is a macro
|
1697
|
-
defineSymbol(text, textord, "\u22ee", "\\
|
1731
|
+
defineSymbol(text, textord, "\u22ee", "\\varvdots");
|
1698
1732
|
defineSymbol(math, accent, "\u02ca", "\\acute");
|
1699
1733
|
defineSymbol(math, accent, "\u0060", "\\grave");
|
1700
1734
|
defineSymbol(math, accent, "\u00a8", "\\ddot");
|
@@ -2147,61 +2181,6 @@ const consolidateText = mrow => {
|
|
2147
2181
|
}
|
2148
2182
|
};
|
2149
2183
|
|
2150
|
-
const numberRegEx$1 = /^[0-9]$/;
|
2151
|
-
const isDotOrComma = (node, followingNode) => {
|
2152
|
-
return ((node.type === "textord" && node.text === ".") ||
|
2153
|
-
(node.type === "atom" && node.text === ",")) &&
|
2154
|
-
// Don't consolidate if there is a space after the comma.
|
2155
|
-
node.loc && followingNode.loc && node.loc.end === followingNode.loc.start
|
2156
|
-
};
|
2157
|
-
const consolidateNumbers = expression => {
|
2158
|
-
// Consolidate adjacent numbers. We want to return <mn>1,506.3</mn>,
|
2159
|
-
// not <mn>1</mn><mo>,</mo><mn>5</mn><mn>0</mn><mn>6</mn><mi>.</mi><mn>3</mn>
|
2160
|
-
if (expression.length < 2) { return }
|
2161
|
-
const nums = [];
|
2162
|
-
let inNum = false;
|
2163
|
-
// Find adjacent numerals
|
2164
|
-
for (let i = 0; i < expression.length; i++) {
|
2165
|
-
const node = expression[i];
|
2166
|
-
if (node.type === "textord" && numberRegEx$1.test(node.text)) {
|
2167
|
-
if (!inNum) { nums.push({ start: i }); }
|
2168
|
-
inNum = true;
|
2169
|
-
} else {
|
2170
|
-
if (inNum) { nums[nums.length - 1].end = i - 1; }
|
2171
|
-
inNum = false;
|
2172
|
-
}
|
2173
|
-
}
|
2174
|
-
if (inNum) { nums[nums.length - 1].end = expression.length - 1; }
|
2175
|
-
|
2176
|
-
// Determine if numeral groups are separated by a comma or dot.
|
2177
|
-
for (let i = nums.length - 1; i > 0; i--) {
|
2178
|
-
if (nums[i - 1].end === nums[i].start - 2 &&
|
2179
|
-
isDotOrComma(expression[nums[i].start - 1], expression[nums[i].start])) {
|
2180
|
-
// Merge the two groups.
|
2181
|
-
nums[i - 1].end = nums[i].end;
|
2182
|
-
nums.splice(i, 1);
|
2183
|
-
}
|
2184
|
-
}
|
2185
|
-
|
2186
|
-
// Consolidate the number nodes
|
2187
|
-
for (let i = nums.length - 1; i >= 0; i--) {
|
2188
|
-
for (let j = nums[i].start + 1; j <= nums[i].end; j++) {
|
2189
|
-
expression[nums[i].start].text += expression[j].text;
|
2190
|
-
}
|
2191
|
-
expression.splice(nums[i].start + 1, nums[i].end - nums[i].start);
|
2192
|
-
// Check if the <mn> is followed by a numeric base in a supsub, e.g. the "3" in 123^4
|
2193
|
-
// If so, merge the first <mn> into the base.
|
2194
|
-
if (expression.length > nums[i].start + 1) {
|
2195
|
-
const nextTerm = expression[nums[i].start + 1];
|
2196
|
-
if (nextTerm.type === "supsub" && nextTerm.base && nextTerm.base.type === "textord" &&
|
2197
|
-
numberRegEx$1.test(nextTerm.base.text)) {
|
2198
|
-
nextTerm.base.text = expression[nums[i].start].text + nextTerm.base.text;
|
2199
|
-
expression.splice(nums[i].start, 1);
|
2200
|
-
}
|
2201
|
-
}
|
2202
|
-
}
|
2203
|
-
};
|
2204
|
-
|
2205
2184
|
/**
|
2206
2185
|
* Wrap the given array of nodes in an <mrow> node if needed, i.e.,
|
2207
2186
|
* unless the array has length 1. Always returns a single node.
|
@@ -2224,6 +2203,39 @@ const makeRow = function(body, semisimple = false) {
|
|
2224
2203
|
return new mathMLTree.MathNode("mrow", body);
|
2225
2204
|
};
|
2226
2205
|
|
2206
|
+
/**
|
2207
|
+
* Check for <mi>.</mi> which is how a dot renders in MathML,
|
2208
|
+
* or <mo separator="true" lspace="0em" rspace="0em">,</mo>
|
2209
|
+
* which is how a braced comma {,} renders in MathML
|
2210
|
+
*/
|
2211
|
+
function isNumberPunctuation(group) {
|
2212
|
+
if (!group) {
|
2213
|
+
return false
|
2214
|
+
}
|
2215
|
+
if (group.type === 'mi' && group.children.length === 1) {
|
2216
|
+
const child = group.children[0];
|
2217
|
+
return child instanceof TextNode && child.text === '.'
|
2218
|
+
} else if (group.type === "mtext" && group.children.length === 1) {
|
2219
|
+
const child = group.children[0];
|
2220
|
+
return child instanceof TextNode && child.text === '\u2008' // punctuation space
|
2221
|
+
} else if (group.type === 'mo' && group.children.length === 1 &&
|
2222
|
+
group.getAttribute('separator') === 'true' &&
|
2223
|
+
group.getAttribute('lspace') === '0em' &&
|
2224
|
+
group.getAttribute('rspace') === '0em') {
|
2225
|
+
const child = group.children[0];
|
2226
|
+
return child instanceof TextNode && child.text === ','
|
2227
|
+
} else {
|
2228
|
+
return false
|
2229
|
+
}
|
2230
|
+
}
|
2231
|
+
const isComma = (expression, i) => {
|
2232
|
+
const node = expression[i];
|
2233
|
+
const followingNode = expression[i + 1];
|
2234
|
+
return (node.type === "atom" && node.text === ",") &&
|
2235
|
+
// Don't consolidate if there is a space after the comma.
|
2236
|
+
node.loc && followingNode.loc && node.loc.end === followingNode.loc.start
|
2237
|
+
};
|
2238
|
+
|
2227
2239
|
const isRel = item => {
|
2228
2240
|
return (item.type === "atom" && item.family === "rel") ||
|
2229
2241
|
(item.type === "mclass" && item.mclass === "mrel")
|
@@ -2247,11 +2259,16 @@ const buildExpression = function(expression, style, semisimple = false) {
|
|
2247
2259
|
return [group];
|
2248
2260
|
}
|
2249
2261
|
|
2250
|
-
consolidateNumbers(expression);
|
2251
|
-
|
2252
2262
|
const groups = [];
|
2263
|
+
const groupArray = [];
|
2264
|
+
let lastGroup;
|
2253
2265
|
for (let i = 0; i < expression.length; i++) {
|
2254
|
-
|
2266
|
+
groupArray.push(buildGroup$1(expression[i], style));
|
2267
|
+
}
|
2268
|
+
|
2269
|
+
for (let i = 0; i < groupArray.length; i++) {
|
2270
|
+
const group = groupArray[i];
|
2271
|
+
|
2255
2272
|
// Suppress spacing between adjacent relations
|
2256
2273
|
if (i < expression.length - 1 && isRel(expression[i]) && isRel(expression[i + 1])) {
|
2257
2274
|
group.setAttribute("rspace", "0em");
|
@@ -2259,9 +2276,39 @@ const buildExpression = function(expression, style, semisimple = false) {
|
|
2259
2276
|
if (i > 0 && isRel(expression[i]) && isRel(expression[i - 1])) {
|
2260
2277
|
group.setAttribute("lspace", "0em");
|
2261
2278
|
}
|
2279
|
+
|
2280
|
+
// Concatenate numbers
|
2281
|
+
if (group.type === 'mn' && lastGroup && lastGroup.type === 'mn') {
|
2282
|
+
// Concatenate <mn>...</mn> followed by <mi>.</mi>
|
2283
|
+
lastGroup.children.push(...group.children);
|
2284
|
+
continue
|
2285
|
+
} else if (isNumberPunctuation(group) && lastGroup && lastGroup.type === 'mn') {
|
2286
|
+
// Concatenate <mn>...</mn> followed by <mi>.</mi>
|
2287
|
+
lastGroup.children.push(...group.children);
|
2288
|
+
continue
|
2289
|
+
} else if (lastGroup && lastGroup.type === "mn" && i < groupArray.length - 1 &&
|
2290
|
+
groupArray[i + 1].type === "mn" && isComma(expression, i)) {
|
2291
|
+
lastGroup.children.push(...group.children);
|
2292
|
+
continue
|
2293
|
+
} else if (group.type === 'mn' && isNumberPunctuation(lastGroup)) {
|
2294
|
+
// Concatenate <mi>.</mi> followed by <mn>...</mn>
|
2295
|
+
group.children = [...lastGroup.children, ...group.children];
|
2296
|
+
groups.pop();
|
2297
|
+
} else if ((group.type === 'msup' || group.type === 'msub') &&
|
2298
|
+
group.children.length >= 1 && lastGroup &&
|
2299
|
+
(lastGroup.type === 'mn' || isNumberPunctuation(lastGroup))) {
|
2300
|
+
// Put preceding <mn>...</mn> or <mi>.</mi> inside base of
|
2301
|
+
// <msup><mn>...base...</mn>...exponent...</msup> (or <msub>)
|
2302
|
+
const base = group.children[0];
|
2303
|
+
if (base instanceof MathNode && base.type === 'mn' && lastGroup) {
|
2304
|
+
base.children = [...lastGroup.children, ...base.children];
|
2305
|
+
groups.pop();
|
2306
|
+
}
|
2307
|
+
}
|
2262
2308
|
groups.push(group);
|
2309
|
+
lastGroup = group;
|
2263
2310
|
}
|
2264
|
-
return groups
|
2311
|
+
return groups
|
2265
2312
|
};
|
2266
2313
|
|
2267
2314
|
/**
|
@@ -2323,6 +2370,11 @@ function buildMathML(tree, texExpression, style, settings) {
|
|
2323
2370
|
}
|
2324
2371
|
|
2325
2372
|
const expression = buildExpression(tree, style);
|
2373
|
+
|
2374
|
+
if (expression.length === 1 && expression[0] instanceof AnchorNode) {
|
2375
|
+
return expression[0]
|
2376
|
+
}
|
2377
|
+
|
2326
2378
|
const wrap = (settings.displayMode || settings.annotate) ? "none" : settings.wrap;
|
2327
2379
|
|
2328
2380
|
const n1 = expression.length === 0 ? null : expression[0];
|
@@ -2347,6 +2399,9 @@ function buildMathML(tree, texExpression, style, settings) {
|
|
2347
2399
|
if (settings.xml) {
|
2348
2400
|
math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML");
|
2349
2401
|
}
|
2402
|
+
if (wrapper.style.width) {
|
2403
|
+
math.style.width = "100%";
|
2404
|
+
}
|
2350
2405
|
if (settings.displayMode) {
|
2351
2406
|
math.setAttribute("display", "block");
|
2352
2407
|
math.style.display = "block math"; // necessary in Chromium.
|
@@ -2678,12 +2733,19 @@ const padding$2 = width => {
|
|
2678
2733
|
return node
|
2679
2734
|
};
|
2680
2735
|
|
2681
|
-
const paddedNode = (group, lspace = 0.3, rspace = 0) => {
|
2736
|
+
const paddedNode = (group, lspace = 0.3, rspace = 0, mustSmash = false) => {
|
2682
2737
|
if (group == null && rspace === 0) { return padding$2(lspace) }
|
2683
2738
|
const row = group ? [group] : [];
|
2684
2739
|
if (lspace !== 0) { row.unshift(padding$2(lspace)); }
|
2685
2740
|
if (rspace > 0) { row.push(padding$2(rspace)); }
|
2686
|
-
|
2741
|
+
if (mustSmash) {
|
2742
|
+
// Used for the bottom arrow in a {CD} environment
|
2743
|
+
const mpadded = new mathMLTree.MathNode("mpadded", row);
|
2744
|
+
mpadded.setAttribute("height", "0");
|
2745
|
+
return mpadded
|
2746
|
+
} else {
|
2747
|
+
return new mathMLTree.MathNode("mrow", row)
|
2748
|
+
}
|
2687
2749
|
};
|
2688
2750
|
|
2689
2751
|
const labelSize = (size, scriptLevel) => Number(size) / emScale(scriptLevel);
|
@@ -2723,7 +2785,8 @@ const munderoverNode = (fName, body, below, style) => {
|
|
2723
2785
|
(body.body.body || body.body.length > 0));
|
2724
2786
|
if (gotUpper) {
|
2725
2787
|
let label = buildGroup$1(body, labelStyle);
|
2726
|
-
|
2788
|
+
const mustSmash = (fName === "\\\\cdrightarrow" || fName === "\\\\cdleftarrow");
|
2789
|
+
label = paddedNode(label, space, space, mustSmash);
|
2727
2790
|
// Since Firefox does not support minsize, stack a invisible node
|
2728
2791
|
// on top of the label. Its width will serve as a min-width.
|
2729
2792
|
// TODO: Refactor this after Firefox supports minsize.
|
@@ -3146,18 +3209,23 @@ defineFunction({
|
|
3146
3209
|
};
|
3147
3210
|
},
|
3148
3211
|
mathmlBuilder(group, style) {
|
3149
|
-
|
3150
|
-
|
3151
|
-
label.setAttribute("width", "0");
|
3152
|
-
if (group.side === "left") {
|
3153
|
-
label.setAttribute("lspace", "-1width");
|
3212
|
+
if (group.label.body.length === 0) {
|
3213
|
+
return new mathMLTree.MathNode("mrow", style) // empty label
|
3154
3214
|
}
|
3155
|
-
//
|
3156
|
-
|
3157
|
-
|
3158
|
-
|
3215
|
+
// Abuse an <mtable> to create vertically centered content.
|
3216
|
+
const mtd = new mathMLTree.MathNode("mtd", [buildGroup$1(group.label, style)]);
|
3217
|
+
mtd.style.padding = "0";
|
3218
|
+
const mtr = new mathMLTree.MathNode("mtr", [mtd]);
|
3219
|
+
const mtable = new mathMLTree.MathNode("mtable", [mtr]);
|
3220
|
+
const label = new mathMLTree.MathNode("mpadded", [mtable]);
|
3221
|
+
// Set the label width to zero so that the arrow will be centered under the corner cell.
|
3222
|
+
label.setAttribute("width", "0");
|
3159
3223
|
label.setAttribute("displaystyle", "false");
|
3160
3224
|
label.setAttribute("scriptlevel", "1");
|
3225
|
+
if (group.side === "left") {
|
3226
|
+
label.style.display = "flex";
|
3227
|
+
label.style.justifyContent = "flex-end";
|
3228
|
+
}
|
3161
3229
|
return label;
|
3162
3230
|
}
|
3163
3231
|
});
|
@@ -3747,10 +3815,13 @@ defineFunction({
|
|
3747
3815
|
// replacement text, enclosed in '{' and '}' and properly nested
|
3748
3816
|
const { tokens } = parser.gullet.consumeArg();
|
3749
3817
|
|
3750
|
-
parser.gullet.macros.
|
3751
|
-
|
3752
|
-
|
3753
|
-
|
3818
|
+
if (!(funcName === "\\providecommand" && parser.gullet.macros.has(name))) {
|
3819
|
+
// Ignore \providecommand
|
3820
|
+
parser.gullet.macros.set(
|
3821
|
+
name,
|
3822
|
+
{ tokens, numArgs }
|
3823
|
+
);
|
3824
|
+
}
|
3754
3825
|
|
3755
3826
|
return { type: "internal", mode: parser.mode };
|
3756
3827
|
|
@@ -3844,6 +3915,7 @@ const delimiters = [
|
|
3844
3915
|
"\\vert",
|
3845
3916
|
"\\|",
|
3846
3917
|
"\\Vert",
|
3918
|
+
"\u2016",
|
3847
3919
|
"\\uparrow",
|
3848
3920
|
"\\Uparrow",
|
3849
3921
|
"\\downarrow",
|
@@ -4613,7 +4685,7 @@ defineMacro("\\underbar", "\\underline{\\text{#1}}");
|
|
4613
4685
|
// \kern6\p@\hbox{.}\hbox{.}\hbox{.}}}
|
4614
4686
|
// We'll call \varvdots, which gets a glyph from symbols.js.
|
4615
4687
|
// The zero-width rule gets us an equivalent to the vertical 6pt kern.
|
4616
|
-
defineMacro("\\vdots", "
|
4688
|
+
defineMacro("\\vdots", "{\\varvdots\\rule{0pt}{15pt}}");
|
4617
4689
|
defineMacro("\u22ee", "\\vdots");
|
4618
4690
|
|
4619
4691
|
// {array} environment gaps
|
@@ -8076,6 +8148,7 @@ defineFunction({
|
|
8076
8148
|
"\\mathfrak",
|
8077
8149
|
"\\mathscr",
|
8078
8150
|
"\\mathsf",
|
8151
|
+
"\\mathsfit",
|
8079
8152
|
"\\mathtt",
|
8080
8153
|
|
8081
8154
|
// aliases
|
@@ -8145,10 +8218,19 @@ const mathmlBuilder$5 = (group, style) => {
|
|
8145
8218
|
? style.withLevel(StyleLevel.SCRIPT)
|
8146
8219
|
: style.withLevel(StyleLevel.SCRIPTSCRIPT);
|
8147
8220
|
|
8148
|
-
|
8149
|
-
|
8150
|
-
|
8151
|
-
|
8221
|
+
// Chromium (wrongly) continues to shrink fractions beyond scriptscriptlevel.
|
8222
|
+
// So we check for levels that Chromium shrinks too small.
|
8223
|
+
// If necessary, set an explicit fraction depth.
|
8224
|
+
const numer = buildGroup$1(group.numer, childOptions);
|
8225
|
+
const denom = buildGroup$1(group.denom, childOptions);
|
8226
|
+
if (style.level === 3) {
|
8227
|
+
numer.style.mathDepth = "2";
|
8228
|
+
numer.setAttribute("scriptlevel", "2");
|
8229
|
+
denom.style.mathDepth = "2";
|
8230
|
+
denom.setAttribute("scriptlevel", "2");
|
8231
|
+
}
|
8232
|
+
|
8233
|
+
let node = new mathMLTree.MathNode("mfrac", [numer, denom]);
|
8152
8234
|
|
8153
8235
|
if (!group.hasBarLine) {
|
8154
8236
|
node.setAttribute("linethickness", "0px");
|
@@ -8541,12 +8623,9 @@ defineFunction({
|
|
8541
8623
|
};
|
8542
8624
|
},
|
8543
8625
|
mathmlBuilder: (group, style) => {
|
8544
|
-
|
8545
|
-
|
8546
|
-
|
8547
|
-
}
|
8548
|
-
math.setAttribute("href", group.href);
|
8549
|
-
return math;
|
8626
|
+
const math = new MathNode("math", [buildExpressionRow(group.body, style)]);
|
8627
|
+
const anchorNode = new AnchorNode(group.href, [], [math]);
|
8628
|
+
return anchorNode
|
8550
8629
|
}
|
8551
8630
|
});
|
8552
8631
|
|
@@ -9418,13 +9497,6 @@ const mathmlBuilder$2 = (group, style) => {
|
|
9418
9497
|
node = new MathNode("mo", [makeText(group.name, group.mode)]);
|
9419
9498
|
if (noSuccessor.includes(group.name)) {
|
9420
9499
|
node.setAttribute("largeop", "false");
|
9421
|
-
} else if (group.limits) {
|
9422
|
-
// This is a workaround for a MathML/Chromium bug.
|
9423
|
-
// This is being applied to singleCharBigOps, which are not really stretchy.
|
9424
|
-
// But by setting the stretchy attribute, Chromium will vertically center
|
9425
|
-
// big ops around the math axis. This is needed since STIX TWO does not do so.
|
9426
|
-
// TODO: Remove this hack when MathML & Chromium fix their problem.
|
9427
|
-
node.setAttribute("stretchy", "true");
|
9428
9500
|
} else {
|
9429
9501
|
node.setAttribute("movablelimits", "false");
|
9430
9502
|
}
|
@@ -10059,12 +10131,10 @@ defineFunction({
|
|
10059
10131
|
};
|
10060
10132
|
},
|
10061
10133
|
mathmlBuilder(group, style) {
|
10062
|
-
// Create an empty
|
10134
|
+
// Create an empty <a> node. Set a class and an href attribute.
|
10063
10135
|
// The post-processor will populate with the target's tag or equation number.
|
10064
10136
|
const classes = group.funcName === "\\ref" ? ["tml-ref"] : ["tml-ref", "tml-eqref"];
|
10065
|
-
|
10066
|
-
node.setAttribute("href", "#" + group.string);
|
10067
|
-
return node
|
10137
|
+
return new AnchorNode("#" + group.string, classes, null)
|
10068
10138
|
}
|
10069
10139
|
});
|
10070
10140
|
|
@@ -10111,6 +10181,8 @@ defineFunction({
|
|
10111
10181
|
props: {
|
10112
10182
|
numArgs: 2,
|
10113
10183
|
numOptionalArgs: 1,
|
10184
|
+
allowedInText: true,
|
10185
|
+
allowedInMath: true,
|
10114
10186
|
argTypes: ["size", "size", "size"]
|
10115
10187
|
},
|
10116
10188
|
handler({ parser }, args, optArgs) {
|
@@ -10403,16 +10475,25 @@ defineFunctionBuilders({
|
|
10403
10475
|
? [buildGroup$1(group.base.body[0], style)]
|
10404
10476
|
: [buildGroup$1(group.base, style)];
|
10405
10477
|
|
10478
|
+
// Note regarding scriptstyle level.
|
10479
|
+
// (Sub|super)scripts should not shrink beyond MathML scriptlevel 2 aka \scriptscriptstyle
|
10480
|
+
// Ref: https://w3c.github.io/mathml-core/#the-displaystyle-and-scriptlevel-attributes
|
10481
|
+
// (BTW, MathML scriptlevel 2 is equal to Temml level 3.)
|
10482
|
+
// But Chromium continues to shrink the (sub|super)scripts. So we explicitly set scriptlevel 2.
|
10483
|
+
|
10406
10484
|
const childStyle = style.inSubOrSup();
|
10407
10485
|
if (group.sub) {
|
10408
|
-
|
10486
|
+
const sub = buildGroup$1(group.sub, childStyle);
|
10487
|
+
if (style.level === 3) { sub.setAttribute("scriptlevel", "2"); }
|
10488
|
+
children.push(sub);
|
10409
10489
|
}
|
10410
10490
|
|
10411
10491
|
if (group.sup) {
|
10412
10492
|
const sup = buildGroup$1(group.sup, childStyle);
|
10493
|
+
if (style.level === 3) { sup.setAttribute("scriptlevel", "2"); }
|
10413
10494
|
const testNode = sup.type === "mrow" ? sup.children[0] : sup;
|
10414
10495
|
if ((testNode && testNode.type === "mo" && testNode.classes.includes("tml-prime"))
|
10415
|
-
&& group.base && group.base.text && group.base.text
|
10496
|
+
&& group.base && group.base.text && "fF".indexOf(group.base.text) > -1) {
|
10416
10497
|
// Chromium does not address italic correction on prime. Prevent f′ from overlapping.
|
10417
10498
|
testNode.classes.push("prime-pad");
|
10418
10499
|
}
|
@@ -10639,6 +10720,8 @@ const getVariant = function(group, style) {
|
|
10639
10720
|
return "script"
|
10640
10721
|
case "mathsf":
|
10641
10722
|
return "sans-serif"
|
10723
|
+
case "mathsfit":
|
10724
|
+
return "sans-serif-italic"
|
10642
10725
|
case "mathtt":
|
10643
10726
|
return "monospace"
|
10644
10727
|
}
|
@@ -11103,6 +11186,32 @@ defineFunction({
|
|
11103
11186
|
}
|
11104
11187
|
});
|
11105
11188
|
|
11189
|
+
// \vcenter: Vertically center the argument group on the math axis.
|
11190
|
+
|
11191
|
+
defineFunction({
|
11192
|
+
type: "vcenter",
|
11193
|
+
names: ["\\vcenter"],
|
11194
|
+
props: {
|
11195
|
+
numArgs: 1,
|
11196
|
+
argTypes: ["original"],
|
11197
|
+
allowedInText: false
|
11198
|
+
},
|
11199
|
+
handler({ parser }, args) {
|
11200
|
+
return {
|
11201
|
+
type: "vcenter",
|
11202
|
+
mode: parser.mode,
|
11203
|
+
body: args[0]
|
11204
|
+
};
|
11205
|
+
},
|
11206
|
+
mathmlBuilder(group, style) {
|
11207
|
+
// Use a math table to create vertically centered content.
|
11208
|
+
const mtd = new mathMLTree.MathNode("mtd", [buildGroup$1(group.body, style)]);
|
11209
|
+
mtd.style.padding = "0";
|
11210
|
+
const mtr = new mathMLTree.MathNode("mtr", [mtd]);
|
11211
|
+
return new mathMLTree.MathNode("mtable", [mtr])
|
11212
|
+
}
|
11213
|
+
});
|
11214
|
+
|
11106
11215
|
defineFunction({
|
11107
11216
|
type: "verb",
|
11108
11217
|
names: ["\\verb"],
|
@@ -13369,9 +13478,11 @@ class Style {
|
|
13369
13478
|
constructor(data) {
|
13370
13479
|
// Style.level can be 0 | 1 | 2 | 3, which correspond to
|
13371
13480
|
// displaystyle, textstyle, scriptstyle, and scriptscriptstyle.
|
13372
|
-
// style.level does not directly set MathML's script level. MathML does that itself.
|
13373
|
-
//
|
13374
|
-
//
|
13481
|
+
// style.level usually does not directly set MathML's script level. MathML does that itself.
|
13482
|
+
// However, Chromium does not stop shrinking after scriptscriptstyle, so we do explicitly
|
13483
|
+
// set a scriptlevel attribute in those conditions.
|
13484
|
+
// We also use style.level to track math style so that we can get the correct
|
13485
|
+
// scriptlevel when needed in supsub.js, mathchoice.js, or for dimensions in em.
|
13375
13486
|
this.level = data.level;
|
13376
13487
|
this.color = data.color; // string | void
|
13377
13488
|
// A font family applies to a group of fonts (i.e. SansSerif), while a font
|
@@ -13495,39 +13606,47 @@ class Style {
|
|
13495
13606
|
}
|
13496
13607
|
|
13497
13608
|
/* Temml Post Process
|
13498
|
-
*
|
13499
|
-
* Given a block,
|
13500
|
-
* 1. At each AMS auto-numbered environment, assign an id.
|
13501
|
-
* 2. Populate the text contents of each \ref & \eqref
|
13609
|
+
* Populate the text contents of each \ref & \eqref
|
13502
13610
|
*
|
13503
13611
|
* As with other Temml code, this file is released under terms of the MIT license.
|
13504
13612
|
* https://mit-license.org/
|
13505
13613
|
*/
|
13506
13614
|
|
13507
|
-
const version = "0.10.
|
13615
|
+
const version = "0.10.33";
|
13508
13616
|
|
13509
13617
|
function postProcess(block) {
|
13510
13618
|
const labelMap = {};
|
13511
13619
|
let i = 0;
|
13512
13620
|
|
13513
13621
|
// Get a collection of the parents of each \tag & auto-numbered equation
|
13514
|
-
const
|
13515
|
-
for (
|
13516
|
-
|
13517
|
-
|
13518
|
-
|
13519
|
-
|
13520
|
-
|
13521
|
-
|
13522
|
-
|
13523
|
-
|
13622
|
+
const amsEqns = document.getElementsByClassName('tml-eqn');
|
13623
|
+
for (let parent of amsEqns) {
|
13624
|
+
// AMS automatically numbered equation.
|
13625
|
+
// Assign an id.
|
13626
|
+
i += 1;
|
13627
|
+
parent.setAttribute("id", "tml-eqn-" + String(i));
|
13628
|
+
// No need to write a number into the text content of the element.
|
13629
|
+
// A CSS counter has done that even if this postProcess() function is not used.
|
13630
|
+
|
13631
|
+
// Find any \label that refers to an AMS eqn number.
|
13632
|
+
while (true) {
|
13633
|
+
const labels = parent.getElementsByClassName("tml-label");
|
13634
|
+
if (labels.length > 0) {
|
13635
|
+
parent.setAttribute("id", labels[0].id);
|
13636
|
+
labelMap[labels[0].id] = String(i);
|
13637
|
+
break
|
13638
|
+
} else {
|
13639
|
+
if (parent.tagName === "mtable") { break }
|
13640
|
+
parent = parent.parentElement;
|
13641
|
+
}
|
13524
13642
|
}
|
13525
|
-
|
13643
|
+
}
|
13644
|
+
|
13645
|
+
// Find \labels associated with \tag
|
13646
|
+
const taggedEqns = document.getElementsByClassName('tml-tageqn');
|
13647
|
+
for (const parent of taggedEqns) {
|
13526
13648
|
const labels = parent.getElementsByClassName("tml-label");
|
13527
|
-
if (labels.length
|
13528
|
-
if (eqns.length > 0) {
|
13529
|
-
labelMap[labels[0].id] = String(i);
|
13530
|
-
} else {
|
13649
|
+
if (labels.length > 0) {
|
13531
13650
|
const tags = parent.getElementsByClassName("tml-tag");
|
13532
13651
|
if (tags.length > 0) {
|
13533
13652
|
labelMap[labels[0].id] = tags[0].textContent;
|
@@ -13538,17 +13657,22 @@ function postProcess(block) {
|
|
13538
13657
|
// Populate \ref & \eqref text content
|
13539
13658
|
const refs = block.getElementsByClassName("tml-ref");
|
13540
13659
|
[...refs].forEach(ref => {
|
13541
|
-
|
13660
|
+
const attr = ref.getAttribute("href");
|
13661
|
+
let str = labelMap[attr.slice(1)];
|
13542
13662
|
if (ref.className.indexOf("tml-eqref") === -1) {
|
13543
13663
|
// \ref. Omit parens.
|
13544
13664
|
str = str.replace(/^\(/, "");
|
13545
|
-
str = str.replace(/\
|
13546
|
-
}
|
13665
|
+
str = str.replace(/\)$/, "");
|
13666
|
+
} else {
|
13547
13667
|
// \eqref. Include parens
|
13548
13668
|
if (str.charAt(0) !== "(") { str = "(" + str; }
|
13549
13669
|
if (str.slice(-1) !== ")") { str = str + ")"; }
|
13550
13670
|
}
|
13551
|
-
|
13671
|
+
const mtext = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mtext");
|
13672
|
+
mtext.appendChild(document.createTextNode(str));
|
13673
|
+
const math = document.createElementNS("http://www.w3.org/1998/Math/MathML", "math");
|
13674
|
+
math.appendChild(mtext);
|
13675
|
+
ref.appendChild(math);
|
13552
13676
|
});
|
13553
13677
|
}
|
13554
13678
|
|