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