temml 0.10.31 → 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-Asana.css +6 -0
- package/dist/Temml-Fira.css +6 -0
- package/dist/Temml-Latin-Modern.css +6 -0
- package/dist/Temml-Libertinus.css +6 -0
- package/dist/Temml-Local.css +6 -0
- package/dist/Temml-STIX2.css +6 -0
- package/dist/temml.cjs +251 -126
- package/dist/temml.js +251 -126
- package/dist/temml.min.js +1 -1
- package/dist/temml.mjs +251 -126
- 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 -1
- package/src/variant.js +2 -0
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,6 +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
|
1731
|
+
defineSymbol(text, textord, "\u22ee", "\\varvdots");
|
1697
1732
|
defineSymbol(math, accent, "\u02ca", "\\acute");
|
1698
1733
|
defineSymbol(math, accent, "\u0060", "\\grave");
|
1699
1734
|
defineSymbol(math, accent, "\u00a8", "\\ddot");
|
@@ -2146,61 +2181,6 @@ const consolidateText = mrow => {
|
|
2146
2181
|
}
|
2147
2182
|
};
|
2148
2183
|
|
2149
|
-
const numberRegEx$1 = /^[0-9]$/;
|
2150
|
-
const isDotOrComma = (node, followingNode) => {
|
2151
|
-
return ((node.type === "textord" && node.text === ".") ||
|
2152
|
-
(node.type === "atom" && node.text === ",")) &&
|
2153
|
-
// Don't consolidate if there is a space after the comma.
|
2154
|
-
node.loc && followingNode.loc && node.loc.end === followingNode.loc.start
|
2155
|
-
};
|
2156
|
-
const consolidateNumbers = expression => {
|
2157
|
-
// Consolidate adjacent numbers. We want to return <mn>1,506.3</mn>,
|
2158
|
-
// not <mn>1</mn><mo>,</mo><mn>5</mn><mn>0</mn><mn>6</mn><mi>.</mi><mn>3</mn>
|
2159
|
-
if (expression.length < 2) { return }
|
2160
|
-
const nums = [];
|
2161
|
-
let inNum = false;
|
2162
|
-
// Find adjacent numerals
|
2163
|
-
for (let i = 0; i < expression.length; i++) {
|
2164
|
-
const node = expression[i];
|
2165
|
-
if (node.type === "textord" && numberRegEx$1.test(node.text)) {
|
2166
|
-
if (!inNum) { nums.push({ start: i }); }
|
2167
|
-
inNum = true;
|
2168
|
-
} else {
|
2169
|
-
if (inNum) { nums[nums.length - 1].end = i - 1; }
|
2170
|
-
inNum = false;
|
2171
|
-
}
|
2172
|
-
}
|
2173
|
-
if (inNum) { nums[nums.length - 1].end = expression.length - 1; }
|
2174
|
-
|
2175
|
-
// Determine if numeral groups are separated by a comma or dot.
|
2176
|
-
for (let i = nums.length - 1; i > 0; i--) {
|
2177
|
-
if (nums[i - 1].end === nums[i].start - 2 &&
|
2178
|
-
isDotOrComma(expression[nums[i].start - 1], expression[nums[i].start])) {
|
2179
|
-
// Merge the two groups.
|
2180
|
-
nums[i - 1].end = nums[i].end;
|
2181
|
-
nums.splice(i, 1);
|
2182
|
-
}
|
2183
|
-
}
|
2184
|
-
|
2185
|
-
// Consolidate the number nodes
|
2186
|
-
for (let i = nums.length - 1; i >= 0; i--) {
|
2187
|
-
for (let j = nums[i].start + 1; j <= nums[i].end; j++) {
|
2188
|
-
expression[nums[i].start].text += expression[j].text;
|
2189
|
-
}
|
2190
|
-
expression.splice(nums[i].start + 1, nums[i].end - nums[i].start);
|
2191
|
-
// Check if the <mn> is followed by a numeric base in a supsub, e.g. the "3" in 123^4
|
2192
|
-
// If so, merge the first <mn> into the base.
|
2193
|
-
if (expression.length > nums[i].start + 1) {
|
2194
|
-
const nextTerm = expression[nums[i].start + 1];
|
2195
|
-
if (nextTerm.type === "supsub" && nextTerm.base && nextTerm.base.type === "textord" &&
|
2196
|
-
numberRegEx$1.test(nextTerm.base.text)) {
|
2197
|
-
nextTerm.base.text = expression[nums[i].start].text + nextTerm.base.text;
|
2198
|
-
expression.splice(nums[i].start, 1);
|
2199
|
-
}
|
2200
|
-
}
|
2201
|
-
}
|
2202
|
-
};
|
2203
|
-
|
2204
2184
|
/**
|
2205
2185
|
* Wrap the given array of nodes in an <mrow> node if needed, i.e.,
|
2206
2186
|
* unless the array has length 1. Always returns a single node.
|
@@ -2223,6 +2203,39 @@ const makeRow = function(body, semisimple = false) {
|
|
2223
2203
|
return new mathMLTree.MathNode("mrow", body);
|
2224
2204
|
};
|
2225
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
|
+
|
2226
2239
|
const isRel = item => {
|
2227
2240
|
return (item.type === "atom" && item.family === "rel") ||
|
2228
2241
|
(item.type === "mclass" && item.mclass === "mrel")
|
@@ -2246,11 +2259,16 @@ const buildExpression = function(expression, style, semisimple = false) {
|
|
2246
2259
|
return [group];
|
2247
2260
|
}
|
2248
2261
|
|
2249
|
-
consolidateNumbers(expression);
|
2250
|
-
|
2251
2262
|
const groups = [];
|
2263
|
+
const groupArray = [];
|
2264
|
+
let lastGroup;
|
2252
2265
|
for (let i = 0; i < expression.length; i++) {
|
2253
|
-
|
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
|
+
|
2254
2272
|
// Suppress spacing between adjacent relations
|
2255
2273
|
if (i < expression.length - 1 && isRel(expression[i]) && isRel(expression[i + 1])) {
|
2256
2274
|
group.setAttribute("rspace", "0em");
|
@@ -2258,9 +2276,39 @@ const buildExpression = function(expression, style, semisimple = false) {
|
|
2258
2276
|
if (i > 0 && isRel(expression[i]) && isRel(expression[i - 1])) {
|
2259
2277
|
group.setAttribute("lspace", "0em");
|
2260
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
|
+
}
|
2261
2308
|
groups.push(group);
|
2309
|
+
lastGroup = group;
|
2262
2310
|
}
|
2263
|
-
return groups
|
2311
|
+
return groups
|
2264
2312
|
};
|
2265
2313
|
|
2266
2314
|
/**
|
@@ -2322,6 +2370,11 @@ function buildMathML(tree, texExpression, style, settings) {
|
|
2322
2370
|
}
|
2323
2371
|
|
2324
2372
|
const expression = buildExpression(tree, style);
|
2373
|
+
|
2374
|
+
if (expression.length === 1 && expression[0] instanceof AnchorNode) {
|
2375
|
+
return expression[0]
|
2376
|
+
}
|
2377
|
+
|
2325
2378
|
const wrap = (settings.displayMode || settings.annotate) ? "none" : settings.wrap;
|
2326
2379
|
|
2327
2380
|
const n1 = expression.length === 0 ? null : expression[0];
|
@@ -2346,6 +2399,9 @@ function buildMathML(tree, texExpression, style, settings) {
|
|
2346
2399
|
if (settings.xml) {
|
2347
2400
|
math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML");
|
2348
2401
|
}
|
2402
|
+
if (wrapper.style.width) {
|
2403
|
+
math.style.width = "100%";
|
2404
|
+
}
|
2349
2405
|
if (settings.displayMode) {
|
2350
2406
|
math.setAttribute("display", "block");
|
2351
2407
|
math.style.display = "block math"; // necessary in Chromium.
|
@@ -2677,12 +2733,19 @@ const padding$2 = width => {
|
|
2677
2733
|
return node
|
2678
2734
|
};
|
2679
2735
|
|
2680
|
-
const paddedNode = (group, lspace = 0.3, rspace = 0) => {
|
2736
|
+
const paddedNode = (group, lspace = 0.3, rspace = 0, mustSmash = false) => {
|
2681
2737
|
if (group == null && rspace === 0) { return padding$2(lspace) }
|
2682
2738
|
const row = group ? [group] : [];
|
2683
2739
|
if (lspace !== 0) { row.unshift(padding$2(lspace)); }
|
2684
2740
|
if (rspace > 0) { row.push(padding$2(rspace)); }
|
2685
|
-
|
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
|
+
}
|
2686
2749
|
};
|
2687
2750
|
|
2688
2751
|
const labelSize = (size, scriptLevel) => Number(size) / emScale(scriptLevel);
|
@@ -2722,7 +2785,8 @@ const munderoverNode = (fName, body, below, style) => {
|
|
2722
2785
|
(body.body.body || body.body.length > 0));
|
2723
2786
|
if (gotUpper) {
|
2724
2787
|
let label = buildGroup$1(body, labelStyle);
|
2725
|
-
|
2788
|
+
const mustSmash = (fName === "\\\\cdrightarrow" || fName === "\\\\cdleftarrow");
|
2789
|
+
label = paddedNode(label, space, space, mustSmash);
|
2726
2790
|
// Since Firefox does not support minsize, stack a invisible node
|
2727
2791
|
// on top of the label. Its width will serve as a min-width.
|
2728
2792
|
// TODO: Refactor this after Firefox supports minsize.
|
@@ -3145,18 +3209,23 @@ defineFunction({
|
|
3145
3209
|
};
|
3146
3210
|
},
|
3147
3211
|
mathmlBuilder(group, style) {
|
3148
|
-
|
3149
|
-
|
3150
|
-
label.setAttribute("width", "0");
|
3151
|
-
if (group.side === "left") {
|
3152
|
-
label.setAttribute("lspace", "-1width");
|
3212
|
+
if (group.label.body.length === 0) {
|
3213
|
+
return new mathMLTree.MathNode("mrow", style) // empty label
|
3153
3214
|
}
|
3154
|
-
//
|
3155
|
-
|
3156
|
-
|
3157
|
-
|
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");
|
3158
3223
|
label.setAttribute("displaystyle", "false");
|
3159
3224
|
label.setAttribute("scriptlevel", "1");
|
3225
|
+
if (group.side === "left") {
|
3226
|
+
label.style.display = "flex";
|
3227
|
+
label.style.justifyContent = "flex-end";
|
3228
|
+
}
|
3160
3229
|
return label;
|
3161
3230
|
}
|
3162
3231
|
});
|
@@ -3746,10 +3815,13 @@ defineFunction({
|
|
3746
3815
|
// replacement text, enclosed in '{' and '}' and properly nested
|
3747
3816
|
const { tokens } = parser.gullet.consumeArg();
|
3748
3817
|
|
3749
|
-
parser.gullet.macros.
|
3750
|
-
|
3751
|
-
|
3752
|
-
|
3818
|
+
if (!(funcName === "\\providecommand" && parser.gullet.macros.has(name))) {
|
3819
|
+
// Ignore \providecommand
|
3820
|
+
parser.gullet.macros.set(
|
3821
|
+
name,
|
3822
|
+
{ tokens, numArgs }
|
3823
|
+
);
|
3824
|
+
}
|
3753
3825
|
|
3754
3826
|
return { type: "internal", mode: parser.mode };
|
3755
3827
|
|
@@ -3843,6 +3915,7 @@ const delimiters = [
|
|
3843
3915
|
"\\vert",
|
3844
3916
|
"\\|",
|
3845
3917
|
"\\Vert",
|
3918
|
+
"\u2016",
|
3846
3919
|
"\\uparrow",
|
3847
3920
|
"\\Uparrow",
|
3848
3921
|
"\\downarrow",
|
@@ -8075,6 +8148,7 @@ defineFunction({
|
|
8075
8148
|
"\\mathfrak",
|
8076
8149
|
"\\mathscr",
|
8077
8150
|
"\\mathsf",
|
8151
|
+
"\\mathsfit",
|
8078
8152
|
"\\mathtt",
|
8079
8153
|
|
8080
8154
|
// aliases
|
@@ -8144,10 +8218,19 @@ const mathmlBuilder$5 = (group, style) => {
|
|
8144
8218
|
? style.withLevel(StyleLevel.SCRIPT)
|
8145
8219
|
: style.withLevel(StyleLevel.SCRIPTSCRIPT);
|
8146
8220
|
|
8147
|
-
|
8148
|
-
|
8149
|
-
|
8150
|
-
|
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]);
|
8151
8234
|
|
8152
8235
|
if (!group.hasBarLine) {
|
8153
8236
|
node.setAttribute("linethickness", "0px");
|
@@ -8540,12 +8623,9 @@ defineFunction({
|
|
8540
8623
|
};
|
8541
8624
|
},
|
8542
8625
|
mathmlBuilder: (group, style) => {
|
8543
|
-
|
8544
|
-
|
8545
|
-
|
8546
|
-
}
|
8547
|
-
math.setAttribute("href", group.href);
|
8548
|
-
return math;
|
8626
|
+
const math = new MathNode("math", [buildExpressionRow(group.body, style)]);
|
8627
|
+
const anchorNode = new AnchorNode(group.href, [], [math]);
|
8628
|
+
return anchorNode
|
8549
8629
|
}
|
8550
8630
|
});
|
8551
8631
|
|
@@ -9417,13 +9497,6 @@ const mathmlBuilder$2 = (group, style) => {
|
|
9417
9497
|
node = new MathNode("mo", [makeText(group.name, group.mode)]);
|
9418
9498
|
if (noSuccessor.includes(group.name)) {
|
9419
9499
|
node.setAttribute("largeop", "false");
|
9420
|
-
} else if (group.limits) {
|
9421
|
-
// This is a workaround for a MathML/Chromium bug.
|
9422
|
-
// This is being applied to singleCharBigOps, which are not really stretchy.
|
9423
|
-
// But by setting the stretchy attribute, Chromium will vertically center
|
9424
|
-
// big ops around the math axis. This is needed since STIX TWO does not do so.
|
9425
|
-
// TODO: Remove this hack when MathML & Chromium fix their problem.
|
9426
|
-
node.setAttribute("stretchy", "true");
|
9427
9500
|
} else {
|
9428
9501
|
node.setAttribute("movablelimits", "false");
|
9429
9502
|
}
|
@@ -10058,12 +10131,10 @@ defineFunction({
|
|
10058
10131
|
};
|
10059
10132
|
},
|
10060
10133
|
mathmlBuilder(group, style) {
|
10061
|
-
// Create an empty
|
10134
|
+
// Create an empty <a> node. Set a class and an href attribute.
|
10062
10135
|
// The post-processor will populate with the target's tag or equation number.
|
10063
10136
|
const classes = group.funcName === "\\ref" ? ["tml-ref"] : ["tml-ref", "tml-eqref"];
|
10064
|
-
|
10065
|
-
node.setAttribute("href", "#" + group.string);
|
10066
|
-
return node
|
10137
|
+
return new AnchorNode("#" + group.string, classes, null)
|
10067
10138
|
}
|
10068
10139
|
});
|
10069
10140
|
|
@@ -10110,6 +10181,8 @@ defineFunction({
|
|
10110
10181
|
props: {
|
10111
10182
|
numArgs: 2,
|
10112
10183
|
numOptionalArgs: 1,
|
10184
|
+
allowedInText: true,
|
10185
|
+
allowedInMath: true,
|
10113
10186
|
argTypes: ["size", "size", "size"]
|
10114
10187
|
},
|
10115
10188
|
handler({ parser }, args, optArgs) {
|
@@ -10402,16 +10475,25 @@ defineFunctionBuilders({
|
|
10402
10475
|
? [buildGroup$1(group.base.body[0], style)]
|
10403
10476
|
: [buildGroup$1(group.base, style)];
|
10404
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
|
+
|
10405
10484
|
const childStyle = style.inSubOrSup();
|
10406
10485
|
if (group.sub) {
|
10407
|
-
|
10486
|
+
const sub = buildGroup$1(group.sub, childStyle);
|
10487
|
+
if (style.level === 3) { sub.setAttribute("scriptlevel", "2"); }
|
10488
|
+
children.push(sub);
|
10408
10489
|
}
|
10409
10490
|
|
10410
10491
|
if (group.sup) {
|
10411
10492
|
const sup = buildGroup$1(group.sup, childStyle);
|
10493
|
+
if (style.level === 3) { sup.setAttribute("scriptlevel", "2"); }
|
10412
10494
|
const testNode = sup.type === "mrow" ? sup.children[0] : sup;
|
10413
10495
|
if ((testNode && testNode.type === "mo" && testNode.classes.includes("tml-prime"))
|
10414
|
-
&& group.base && group.base.text && group.base.text
|
10496
|
+
&& group.base && group.base.text && "fF".indexOf(group.base.text) > -1) {
|
10415
10497
|
// Chromium does not address italic correction on prime. Prevent f′ from overlapping.
|
10416
10498
|
testNode.classes.push("prime-pad");
|
10417
10499
|
}
|
@@ -10638,6 +10720,8 @@ const getVariant = function(group, style) {
|
|
10638
10720
|
return "script"
|
10639
10721
|
case "mathsf":
|
10640
10722
|
return "sans-serif"
|
10723
|
+
case "mathsfit":
|
10724
|
+
return "sans-serif-italic"
|
10641
10725
|
case "mathtt":
|
10642
10726
|
return "monospace"
|
10643
10727
|
}
|
@@ -11102,6 +11186,32 @@ defineFunction({
|
|
11102
11186
|
}
|
11103
11187
|
});
|
11104
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
|
+
|
11105
11215
|
defineFunction({
|
11106
11216
|
type: "verb",
|
11107
11217
|
names: ["\\verb"],
|
@@ -13368,9 +13478,11 @@ class Style {
|
|
13368
13478
|
constructor(data) {
|
13369
13479
|
// Style.level can be 0 | 1 | 2 | 3, which correspond to
|
13370
13480
|
// displaystyle, textstyle, scriptstyle, and scriptscriptstyle.
|
13371
|
-
// style.level does not directly set MathML's script level. MathML does that itself.
|
13372
|
-
//
|
13373
|
-
//
|
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.
|
13374
13486
|
this.level = data.level;
|
13375
13487
|
this.color = data.color; // string | void
|
13376
13488
|
// A font family applies to a group of fonts (i.e. SansSerif), while a font
|
@@ -13494,39 +13606,47 @@ class Style {
|
|
13494
13606
|
}
|
13495
13607
|
|
13496
13608
|
/* Temml Post Process
|
13497
|
-
*
|
13498
|
-
* Given a block,
|
13499
|
-
* 1. At each AMS auto-numbered environment, assign an id.
|
13500
|
-
* 2. Populate the text contents of each \ref & \eqref
|
13609
|
+
* Populate the text contents of each \ref & \eqref
|
13501
13610
|
*
|
13502
13611
|
* As with other Temml code, this file is released under terms of the MIT license.
|
13503
13612
|
* https://mit-license.org/
|
13504
13613
|
*/
|
13505
13614
|
|
13506
|
-
const version = "0.10.
|
13615
|
+
const version = "0.10.33";
|
13507
13616
|
|
13508
13617
|
function postProcess(block) {
|
13509
13618
|
const labelMap = {};
|
13510
13619
|
let i = 0;
|
13511
13620
|
|
13512
13621
|
// Get a collection of the parents of each \tag & auto-numbered equation
|
13513
|
-
const
|
13514
|
-
for (
|
13515
|
-
|
13516
|
-
|
13517
|
-
|
13518
|
-
|
13519
|
-
|
13520
|
-
|
13521
|
-
|
13522
|
-
|
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
|
+
}
|
13523
13642
|
}
|
13524
|
-
|
13643
|
+
}
|
13644
|
+
|
13645
|
+
// Find \labels associated with \tag
|
13646
|
+
const taggedEqns = document.getElementsByClassName('tml-tageqn');
|
13647
|
+
for (const parent of taggedEqns) {
|
13525
13648
|
const labels = parent.getElementsByClassName("tml-label");
|
13526
|
-
if (labels.length
|
13527
|
-
if (eqns.length > 0) {
|
13528
|
-
labelMap[labels[0].id] = String(i);
|
13529
|
-
} else {
|
13649
|
+
if (labels.length > 0) {
|
13530
13650
|
const tags = parent.getElementsByClassName("tml-tag");
|
13531
13651
|
if (tags.length > 0) {
|
13532
13652
|
labelMap[labels[0].id] = tags[0].textContent;
|
@@ -13537,17 +13657,22 @@ function postProcess(block) {
|
|
13537
13657
|
// Populate \ref & \eqref text content
|
13538
13658
|
const refs = block.getElementsByClassName("tml-ref");
|
13539
13659
|
[...refs].forEach(ref => {
|
13540
|
-
|
13660
|
+
const attr = ref.getAttribute("href");
|
13661
|
+
let str = labelMap[attr.slice(1)];
|
13541
13662
|
if (ref.className.indexOf("tml-eqref") === -1) {
|
13542
13663
|
// \ref. Omit parens.
|
13543
13664
|
str = str.replace(/^\(/, "");
|
13544
|
-
str = str.replace(/\
|
13545
|
-
}
|
13665
|
+
str = str.replace(/\)$/, "");
|
13666
|
+
} else {
|
13546
13667
|
// \eqref. Include parens
|
13547
13668
|
if (str.charAt(0) !== "(") { str = "(" + str; }
|
13548
13669
|
if (str.slice(-1) !== ")") { str = str + ")"; }
|
13549
13670
|
}
|
13550
|
-
|
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);
|
13551
13676
|
});
|
13552
13677
|
}
|
13553
13678
|
|