temml 0.11.6 → 0.11.8
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/contrib/mhchem/mhchem.js +2 -2
- package/contrib/mhchem/mhchem.min.js +1 -1
- package/dist/Temml-Asana.css +75 -16
- package/dist/Temml-Latin-Modern.css +77 -14
- package/dist/Temml-Libertinus.css +77 -13
- package/dist/Temml-Local.css +79 -11
- package/dist/Temml-NotoSans.css +78 -8
- package/dist/Temml-STIX2.css +77 -13
- package/dist/temml.cjs +193 -157
- package/dist/temml.js +191 -155
- package/dist/temml.min.js +1 -1
- package/dist/temml.mjs +193 -157
- package/dist/temmlPostProcess.js +1 -1
- package/package.json +1 -1
- package/src/environments/borderTree.js +1 -1
- package/src/functions/accent.js +55 -36
- package/src/functions/arrow.js +8 -14
- package/src/functions/enclose.js +2 -1
- package/src/functions/kern.js +12 -5
- package/src/functions/mclass.js +17 -3
- package/src/functions/sfrac.js +68 -0
- package/src/functions/supsub.js +20 -8
- package/src/functions.js +1 -1
- package/src/postProcess.js +1 -1
- package/src/stretchy.js +6 -1
- package/src/symbols.js +3 -3
- package/src/functions/href.js +0 -88
package/dist/temml.cjs
CHANGED
@@ -836,6 +836,9 @@ const stretchyCodePoint = {
|
|
836
836
|
xtwoheadrightarrow: "\u21a0",
|
837
837
|
xlongequal: "=",
|
838
838
|
xrightleftarrows: "\u21c4",
|
839
|
+
xtofrom: "\u21c4",
|
840
|
+
xleftrightharpoons: "\u21cb",
|
841
|
+
xrightleftharpoons: "\u21cc",
|
839
842
|
yields: "\u2192",
|
840
843
|
yieldsLeft: "\u2190",
|
841
844
|
mesomerism: "\u2194",
|
@@ -845,7 +848,9 @@ const stretchyCodePoint = {
|
|
845
848
|
eqleftharpoondown: "\u21bd",
|
846
849
|
"\\cdrightarrow": "\u2192",
|
847
850
|
"\\cdleftarrow": "\u2190",
|
848
|
-
"\\cdlongequal": "="
|
851
|
+
"\\cdlongequal": "=",
|
852
|
+
yieldsLeftRight: "\u21c4",
|
853
|
+
chemequilibrium: "\u21cc"
|
849
854
|
};
|
850
855
|
|
851
856
|
const mathMLnode = function(label) {
|
@@ -1773,7 +1778,7 @@ defineSymbol(math, inner, "\u22ef", "\\@cdots", true);
|
|
1773
1778
|
defineSymbol(math, inner, "\u22f1", "\\ddots", true);
|
1774
1779
|
defineSymbol(math, textord, "\u22ee", "\\varvdots"); // \vdots is a macro
|
1775
1780
|
defineSymbol(text, textord, "\u22ee", "\\varvdots");
|
1776
|
-
defineSymbol(math, accent, "\
|
1781
|
+
defineSymbol(math, accent, "\u00b4", "\\acute");
|
1777
1782
|
defineSymbol(math, accent, "\u0060", "\\grave");
|
1778
1783
|
defineSymbol(math, accent, "\u00a8", "\\ddot");
|
1779
1784
|
defineSymbol(math, accent, "\u2026", "\\dddot");
|
@@ -1799,7 +1804,7 @@ defineSymbol(math, mathord, "\u00d8", "\\O", true);
|
|
1799
1804
|
defineSymbol(text, accent, "\u02ca", "\\'"); // acute
|
1800
1805
|
defineSymbol(text, accent, "\u02cb", "\\`"); // grave
|
1801
1806
|
defineSymbol(text, accent, "\u02c6", "\\^"); // circumflex
|
1802
|
-
defineSymbol(text, accent, "\
|
1807
|
+
defineSymbol(text, accent, "\u007e", "\\~"); // tilde
|
1803
1808
|
defineSymbol(text, accent, "\u02c9", "\\="); // macron
|
1804
1809
|
defineSymbol(text, accent, "\u02d8", "\\u"); // breve
|
1805
1810
|
defineSymbol(text, accent, "\u02d9", "\\."); // dot above
|
@@ -1811,7 +1816,7 @@ defineSymbol(text, accent, "\u02dd", "\\H"); // double acute
|
|
1811
1816
|
defineSymbol(math, accent, "\u02ca", "\\'"); // acute
|
1812
1817
|
defineSymbol(math, accent, "\u02cb", "\\`"); // grave
|
1813
1818
|
defineSymbol(math, accent, "\u02c6", "\\^"); // circumflex
|
1814
|
-
defineSymbol(math, accent, "\
|
1819
|
+
defineSymbol(math, accent, "\u007e", "\\~"); // tilde
|
1815
1820
|
defineSymbol(math, accent, "\u02c9", "\\="); // macron
|
1816
1821
|
defineSymbol(math, accent, "\u02d8", "\\u"); // breve
|
1817
1822
|
defineSymbol(math, accent, "\u02d9", "\\."); // dot above
|
@@ -2468,46 +2473,61 @@ function buildMathML(tree, texExpression, style, settings) {
|
|
2468
2473
|
return math;
|
2469
2474
|
}
|
2470
2475
|
|
2476
|
+
// Identify letters to which we'll attach a combining accent character
|
2471
2477
|
const smalls = "acegıȷmnopqrsuvwxyzαγεηικμνοπρςστυχωϕ𝐚𝐜𝐞𝐠𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐮𝐯𝐰𝐱𝐲𝐳";
|
2472
|
-
|
2473
|
-
|
2474
|
-
const
|
2475
|
-
|
2476
|
-
|
2477
|
-
const longTalls = new Set(["\\Gamma", "\\Delta", "\\Sigma", "\\Omega", "\\beta", "\\delta",
|
2478
|
-
"\\lambda", "\\theta", "\\psi"]);
|
2478
|
+
|
2479
|
+
// From the KaTeX font metrics, identify letters whose accents need a italic correction.
|
2480
|
+
const smallNudge = "DHKLUcegorsuvxyzΠΥΨαδηιμνοτυχϵ";
|
2481
|
+
const mediumNudge = "BCEGIMNOPQRSTXZlpqtwΓΘΞΣΦΩβεζθξρςφψϑϕϱ";
|
2482
|
+
const largeNudge = "AFJdfΔΛ";
|
2479
2483
|
|
2480
2484
|
const mathmlBuilder$a = (group, style) => {
|
2481
2485
|
const accentNode = group.isStretchy
|
2482
2486
|
? stretchy.accentNode(group)
|
2483
2487
|
: new mathMLTree.MathNode("mo", [makeText(group.label, group.mode)]);
|
2484
|
-
|
2485
|
-
if (group.label === "\\vec") {
|
2486
|
-
accentNode.style.transform = "scale(0.75) translate(10%, 30%)";
|
2487
|
-
} else {
|
2488
|
-
accentNode.style.mathStyle = "normal";
|
2489
|
-
accentNode.style.mathDepth = "0";
|
2490
|
-
if (needWebkitShift.has(group.label) && utils.isCharacterBox(group.base)) {
|
2491
|
-
let shift = "";
|
2492
|
-
const ch = group.base.text;
|
2493
|
-
if (smalls.indexOf(ch) > -1 || longSmalls.has(ch)) { shift = "tml-xshift"; }
|
2494
|
-
if (talls.indexOf(ch) > -1 || longTalls.has(ch)) { shift = "tml-capshift"; }
|
2495
|
-
if (shift) { accentNode.classes.push(shift); }
|
2496
|
-
}
|
2497
|
-
}
|
2498
2488
|
if (!group.isStretchy) {
|
2499
|
-
accentNode.setAttribute("stretchy", "false");
|
2500
|
-
}
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2504
|
-
|
2505
|
-
|
2489
|
+
accentNode.setAttribute("stretchy", "false"); // Keep Firefox from stretching \check
|
2490
|
+
}
|
2491
|
+
if (group.label !== "\\vec") {
|
2492
|
+
accentNode.style.mathDepth = "0"; // not scriptstyle
|
2493
|
+
// Don't use attribute accent="true" because MathML Core eliminates a needed space.
|
2494
|
+
}
|
2495
|
+
const tag = group.label === "\\c" ? "munder" : "mover";
|
2496
|
+
const needsWbkVertShift = needsWebkitVerticalShift.has(group.label);
|
2497
|
+
if (tag === "mover" && group.mode === "math" && (!group.isStretchy) && group.base.text
|
2498
|
+
&& group.base.text.length === 1) {
|
2499
|
+
const text = group.base.text;
|
2500
|
+
const isVec = group.label === "\\vec";
|
2501
|
+
const vecPostfix = isVec === "\\vec" ? "-vec" : "";
|
2502
|
+
if (isVec) {
|
2503
|
+
accentNode.classes.push("tml-vec"); // Firefox sizing of \vec arrow
|
2504
|
+
}
|
2505
|
+
const wbkPostfix = isVec ? "-vec" : needsWbkVertShift ? "-acc" : "";
|
2506
|
+
if (smallNudge.indexOf(text) > -1) {
|
2507
|
+
accentNode.classes.push(`chr-sml${vecPostfix}`);
|
2508
|
+
accentNode.classes.push(`wbk-sml${wbkPostfix}`);
|
2509
|
+
} else if (mediumNudge.indexOf(text) > -1) {
|
2510
|
+
accentNode.classes.push(`chr-med${vecPostfix}`);
|
2511
|
+
accentNode.classes.push(`wbk-med${wbkPostfix}`);
|
2512
|
+
} else if (largeNudge.indexOf(text) > -1) {
|
2513
|
+
accentNode.classes.push(`chr-lrg${vecPostfix}`);
|
2514
|
+
accentNode.classes.push(`wbk-lrg${wbkPostfix}`);
|
2515
|
+
} else if (isVec) {
|
2516
|
+
accentNode.classes.push(`wbk-vec`);
|
2517
|
+
} else if (needsWbkVertShift) {
|
2518
|
+
accentNode.classes.push(`wbk-acc`);
|
2519
|
+
}
|
2520
|
+
} else if (needsWbkVertShift) {
|
2521
|
+
// text-mode accents
|
2522
|
+
accentNode.classes.push("wbk-acc");
|
2523
|
+
}
|
2524
|
+
const node = new mathMLTree.MathNode(tag, [buildGroup$1(group.base, style), accentNode]);
|
2506
2525
|
return node;
|
2507
2526
|
};
|
2508
2527
|
|
2509
2528
|
const nonStretchyAccents = new Set([
|
2510
2529
|
"\\acute",
|
2530
|
+
"\\check",
|
2511
2531
|
"\\grave",
|
2512
2532
|
"\\ddot",
|
2513
2533
|
"\\dddot",
|
@@ -2522,7 +2542,7 @@ const nonStretchyAccents = new Set([
|
|
2522
2542
|
"\\mathring"
|
2523
2543
|
]);
|
2524
2544
|
|
2525
|
-
const
|
2545
|
+
const needsWebkitVerticalShift = new Set([
|
2526
2546
|
"\\acute",
|
2527
2547
|
"\\bar",
|
2528
2548
|
"\\breve",
|
@@ -2532,7 +2552,7 @@ const needWebkitShift = new Set([
|
|
2532
2552
|
"\\grave",
|
2533
2553
|
"\\hat",
|
2534
2554
|
"\\mathring",
|
2535
|
-
"
|
2555
|
+
"\\`", "\\'", "\\^", "\\=", "\\u", "\\.", '\\"', "\\r", "\\H", "\\v"
|
2536
2556
|
]);
|
2537
2557
|
|
2538
2558
|
const combiningChar = {
|
@@ -2546,7 +2566,8 @@ const combiningChar = {
|
|
2546
2566
|
'\\"': "\u0308",
|
2547
2567
|
"\\r": "\u030A",
|
2548
2568
|
"\\H": "\u030B",
|
2549
|
-
"\\v": "\u030C"
|
2569
|
+
"\\v": "\u030C",
|
2570
|
+
"\\c": "\u0327"
|
2550
2571
|
};
|
2551
2572
|
|
2552
2573
|
// Accents
|
@@ -2591,8 +2612,8 @@ defineFunction({
|
|
2591
2612
|
type: "accent",
|
2592
2613
|
mode: context.parser.mode,
|
2593
2614
|
label: context.funcName,
|
2594
|
-
isStretchy
|
2595
|
-
base
|
2615
|
+
isStretchy,
|
2616
|
+
base
|
2596
2617
|
};
|
2597
2618
|
},
|
2598
2619
|
mathmlBuilder: mathmlBuilder$a
|
@@ -2619,21 +2640,25 @@ defineFunction({
|
|
2619
2640
|
}
|
2620
2641
|
|
2621
2642
|
if (mode === "text" && base.text && base.text.length === 1
|
2622
|
-
&& context.funcName in combiningChar
|
2643
|
+
&& context.funcName in combiningChar && smalls.indexOf(base.text) > -1) {
|
2623
2644
|
// Return a combining accent character
|
2624
2645
|
return {
|
2625
2646
|
type: "textord",
|
2626
2647
|
mode: "text",
|
2627
2648
|
text: base.text + combiningChar[context.funcName]
|
2628
2649
|
}
|
2650
|
+
} else if (context.funcName === "\\c" && mode === "text" && base.text
|
2651
|
+
&& base.text.length === 1) {
|
2652
|
+
// combining cedilla
|
2653
|
+
return { type: "textord", mode: "text", text: base.text + "\u0327" }
|
2629
2654
|
} else {
|
2630
2655
|
// Build up the accent
|
2631
2656
|
return {
|
2632
2657
|
type: "accent",
|
2633
|
-
mode
|
2658
|
+
mode,
|
2634
2659
|
label: context.funcName,
|
2635
2660
|
isStretchy: false,
|
2636
|
-
base
|
2661
|
+
base
|
2637
2662
|
}
|
2638
2663
|
}
|
2639
2664
|
},
|
@@ -2891,12 +2916,17 @@ defineFunction({
|
|
2891
2916
|
"\\xlongequal",
|
2892
2917
|
"\\xtwoheadrightarrow",
|
2893
2918
|
"\\xtwoheadleftarrow",
|
2894
|
-
//
|
2919
|
+
"\\xtofrom", // expfeil
|
2920
|
+
"\\xleftrightharpoons", // mathtools
|
2921
|
+
"\\xrightleftharpoons", // mathtools
|
2922
|
+
// The next 7 functions are here only to support mhchem
|
2895
2923
|
"\\yields",
|
2896
2924
|
"\\yieldsLeft",
|
2897
2925
|
"\\mesomerism",
|
2898
2926
|
"\\longrightharpoonup",
|
2899
2927
|
"\\longleftharpoondown",
|
2928
|
+
"\\yieldsLeftRight",
|
2929
|
+
"\\chemequilibrium",
|
2900
2930
|
// The next 3 functions are here only to support the {CD} environment.
|
2901
2931
|
"\\\\cdrightarrow",
|
2902
2932
|
"\\\\cdleftarrow",
|
@@ -2927,26 +2957,15 @@ defineFunction({
|
|
2927
2957
|
});
|
2928
2958
|
|
2929
2959
|
const arrowComponent = {
|
2930
|
-
"\\xtofrom": ["\\xrightarrow", "\\xleftarrow"],
|
2931
|
-
"\\xleftrightharpoons": ["\\xleftharpoonup", "\\xrightharpoondown"],
|
2932
|
-
"\\xrightleftharpoons": ["\\xrightharpoonup", "\\xleftharpoondown"],
|
2933
|
-
"\\yieldsLeftRight": ["\\yields", "\\yieldsLeft"],
|
2934
|
-
// The next three all get the same harpoon glyphs. Only the lengths and paddings differ.
|
2935
|
-
"\\equilibrium": ["\\longrightharpoonup", "\\longleftharpoondown"],
|
2936
2960
|
"\\equilibriumRight": ["\\longrightharpoonup", "\\eqleftharpoondown"],
|
2937
2961
|
"\\equilibriumLeft": ["\\eqrightharpoonup", "\\longleftharpoondown"]
|
2938
2962
|
};
|
2939
2963
|
|
2940
|
-
//
|
2941
|
-
// So we stack a pair of single
|
2964
|
+
// Math fonts do not have a single glyph for these two mhchem functions.
|
2965
|
+
// So we stack a pair of single harpoons.
|
2942
2966
|
defineFunction({
|
2943
2967
|
type: "stackedArrow",
|
2944
2968
|
names: [
|
2945
|
-
"\\xtofrom", // expfeil
|
2946
|
-
"\\xleftrightharpoons", // mathtools
|
2947
|
-
"\\xrightleftharpoons", // mathtools
|
2948
|
-
"\\yieldsLeftRight", // mhchem
|
2949
|
-
"\\equilibrium", // mhchem
|
2950
2969
|
"\\equilibriumRight",
|
2951
2970
|
"\\equilibriumLeft"
|
2952
2971
|
],
|
@@ -3453,7 +3472,6 @@ const bordermatrixParseTree = (matrix, delimiters) => {
|
|
3453
3472
|
alwaysHandleSupSub: true,
|
3454
3473
|
parentIsSupSub: true,
|
3455
3474
|
symbol: false,
|
3456
|
-
stack: true,
|
3457
3475
|
suppressBaseShift: true,
|
3458
3476
|
body: [container]
|
3459
3477
|
};
|
@@ -3461,6 +3479,7 @@ const bordermatrixParseTree = (matrix, delimiters) => {
|
|
3461
3479
|
const mover = {
|
3462
3480
|
type: "supsub", // We're using the MathML equivalent
|
3463
3481
|
mode: "math", // of TeX \overset.
|
3482
|
+
stack: true,
|
3464
3483
|
base: base, // That keeps the {pmatrix} aligned with
|
3465
3484
|
sup: topWrapper, // the math centerline.
|
3466
3485
|
sub: null
|
@@ -5924,8 +5943,8 @@ defineMacro("\\tripleDashBetweenDoubleLine", `\\kern0.075em\\mathrlap{\\mathrlap
|
|
5924
5943
|
case "<-": return "\\yieldsLeft";
|
5925
5944
|
case "<->": return "\\mesomerism";
|
5926
5945
|
case "<-->": return "\\yieldsLeftRight";
|
5927
|
-
case "<=>": return "\\
|
5928
|
-
case "\u21CC": return "\\
|
5946
|
+
case "<=>": return "\\chemequilibrium";
|
5947
|
+
case "\u21CC": return "\\chemequilibrium";
|
5929
5948
|
case "<=>>": return "\\equilibriumRight";
|
5930
5949
|
case "<<=>": return "\\equilibriumLeft";
|
5931
5950
|
default:
|
@@ -8188,7 +8207,8 @@ const mathmlBuilder$7 = (group, style) => {
|
|
8188
8207
|
case "\\boxed":
|
8189
8208
|
// \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}} from amsmath.sty
|
8190
8209
|
node.setAttribute("notation", "box");
|
8191
|
-
node.
|
8210
|
+
node.style.padding = "padding: 3pt 0 3pt 0";
|
8211
|
+
node.style.border = "1px solid";
|
8192
8212
|
node.setAttribute("scriptlevel", "0");
|
8193
8213
|
node.setAttribute("displaystyle", "true");
|
8194
8214
|
break
|
@@ -8994,88 +9014,6 @@ defineFunction({
|
|
8994
9014
|
mathmlBuilder: mathmlBuilder$4
|
8995
9015
|
});
|
8996
9016
|
|
8997
|
-
defineFunction({
|
8998
|
-
type: "href",
|
8999
|
-
names: ["\\href"],
|
9000
|
-
props: {
|
9001
|
-
numArgs: 2,
|
9002
|
-
argTypes: ["url", "original"],
|
9003
|
-
allowedInText: true
|
9004
|
-
},
|
9005
|
-
handler: ({ parser, token }, args) => {
|
9006
|
-
const body = args[1];
|
9007
|
-
const href = assertNodeType(args[0], "url").url;
|
9008
|
-
|
9009
|
-
if (
|
9010
|
-
!parser.settings.isTrusted({
|
9011
|
-
command: "\\href",
|
9012
|
-
url: href
|
9013
|
-
})
|
9014
|
-
) {
|
9015
|
-
throw new ParseError(`Function "\\href" is not trusted`, token)
|
9016
|
-
}
|
9017
|
-
|
9018
|
-
return {
|
9019
|
-
type: "href",
|
9020
|
-
mode: parser.mode,
|
9021
|
-
href,
|
9022
|
-
body: ordargument(body)
|
9023
|
-
};
|
9024
|
-
},
|
9025
|
-
mathmlBuilder: (group, style) => {
|
9026
|
-
const math = new MathNode("math", [buildExpressionRow(group.body, style)]);
|
9027
|
-
const anchorNode = new AnchorNode(group.href, [], [math]);
|
9028
|
-
return anchorNode
|
9029
|
-
}
|
9030
|
-
});
|
9031
|
-
|
9032
|
-
defineFunction({
|
9033
|
-
type: "href",
|
9034
|
-
names: ["\\url"],
|
9035
|
-
props: {
|
9036
|
-
numArgs: 1,
|
9037
|
-
argTypes: ["url"],
|
9038
|
-
allowedInText: true
|
9039
|
-
},
|
9040
|
-
handler: ({ parser, token }, args) => {
|
9041
|
-
const href = assertNodeType(args[0], "url").url;
|
9042
|
-
|
9043
|
-
if (
|
9044
|
-
!parser.settings.isTrusted({
|
9045
|
-
command: "\\url",
|
9046
|
-
url: href
|
9047
|
-
})
|
9048
|
-
) {
|
9049
|
-
throw new ParseError(`Function "\\url" is not trusted`, token)
|
9050
|
-
}
|
9051
|
-
|
9052
|
-
const chars = [];
|
9053
|
-
for (let i = 0; i < href.length; i++) {
|
9054
|
-
let c = href[i];
|
9055
|
-
if (c === "~") {
|
9056
|
-
c = "\\textasciitilde";
|
9057
|
-
}
|
9058
|
-
chars.push({
|
9059
|
-
type: "textord",
|
9060
|
-
mode: "text",
|
9061
|
-
text: c
|
9062
|
-
});
|
9063
|
-
}
|
9064
|
-
const body = {
|
9065
|
-
type: "text",
|
9066
|
-
mode: parser.mode,
|
9067
|
-
font: "\\texttt",
|
9068
|
-
body: chars
|
9069
|
-
};
|
9070
|
-
return {
|
9071
|
-
type: "href",
|
9072
|
-
mode: parser.mode,
|
9073
|
-
href,
|
9074
|
-
body: ordargument(body)
|
9075
|
-
};
|
9076
|
-
}
|
9077
|
-
});
|
9078
|
-
|
9079
9017
|
defineFunction({
|
9080
9018
|
type: "html",
|
9081
9019
|
names: ["\\class", "\\id", "\\style", "\\data"],
|
@@ -9333,17 +9271,24 @@ defineFunction({
|
|
9333
9271
|
},
|
9334
9272
|
mathmlBuilder(group, style) {
|
9335
9273
|
const dimension = calculateSize(group.dimension, style);
|
9336
|
-
const ch = dimension.
|
9274
|
+
const ch = dimension.number > 0 && dimension.unit === "em"
|
9275
|
+
? spaceCharacter(dimension.number)
|
9276
|
+
: "";
|
9337
9277
|
if (group.mode === "text" && ch.length > 0) {
|
9338
9278
|
const character = new mathMLTree.TextNode(ch);
|
9339
9279
|
return new mathMLTree.MathNode("mtext", [character]);
|
9340
9280
|
} else {
|
9341
|
-
|
9342
|
-
|
9343
|
-
|
9281
|
+
if (dimension.number >= 0) {
|
9282
|
+
const node = new mathMLTree.MathNode("mspace");
|
9283
|
+
node.setAttribute("width", dimension.number + dimension.unit);
|
9284
|
+
return node
|
9285
|
+
} else {
|
9286
|
+
// Don't use <mspace> or <mpadded> because
|
9287
|
+
// WebKit recognizes negative left margin only on a <mrow> element
|
9288
|
+
const node = new mathMLTree.MathNode("mrow");
|
9344
9289
|
node.style.marginLeft = dimension.number + dimension.unit;
|
9290
|
+
return node
|
9345
9291
|
}
|
9346
|
-
return node;
|
9347
9292
|
}
|
9348
9293
|
}
|
9349
9294
|
});
|
@@ -9676,7 +9621,9 @@ const binrelClass = (arg) => {
|
|
9676
9621
|
// (by rendering separately and with {}s before and after, and measuring
|
9677
9622
|
// the change in spacing). We'll do roughly the same by detecting the
|
9678
9623
|
// atom type directly.
|
9679
|
-
const atom = arg.type === "ordgroup" && arg.body.length
|
9624
|
+
const atom = arg.type === "ordgroup" && arg.body.length && arg.body.length === 1
|
9625
|
+
? arg.body[0]
|
9626
|
+
: arg;
|
9680
9627
|
if (atom.type === "atom" && (atom.family === "bin" || atom.family === "rel")) {
|
9681
9628
|
return "m" + atom.family;
|
9682
9629
|
} else {
|
@@ -9714,14 +9661,25 @@ defineFunction({
|
|
9714
9661
|
const baseArg = args[1];
|
9715
9662
|
const shiftedArg = args[0];
|
9716
9663
|
|
9664
|
+
let mclass;
|
9665
|
+
if (funcName !== "\\stackrel") {
|
9666
|
+
// LaTeX applies \binrel spacing to \overset and \underset.
|
9667
|
+
mclass = binrelClass(baseArg);
|
9668
|
+
} else {
|
9669
|
+
mclass = "mrel"; // for \stackrel
|
9670
|
+
}
|
9671
|
+
|
9672
|
+
const baseType = mclass === "mrel" || mclass === "mbin"
|
9673
|
+
? "op"
|
9674
|
+
: "ordgroup";
|
9675
|
+
|
9717
9676
|
const baseOp = {
|
9718
|
-
type:
|
9677
|
+
type: baseType,
|
9719
9678
|
mode: baseArg.mode,
|
9720
9679
|
limits: true,
|
9721
9680
|
alwaysHandleSupSub: true,
|
9722
9681
|
parentIsSupSub: false,
|
9723
9682
|
symbol: false,
|
9724
|
-
stack: true,
|
9725
9683
|
suppressBaseShift: funcName !== "\\stackrel",
|
9726
9684
|
body: ordargument(baseArg)
|
9727
9685
|
};
|
@@ -9729,6 +9687,7 @@ defineFunction({
|
|
9729
9687
|
return {
|
9730
9688
|
type: "supsub",
|
9731
9689
|
mode: shiftedArg.mode,
|
9690
|
+
stack: true,
|
9732
9691
|
base: baseOp,
|
9733
9692
|
sup: funcName === "\\underset" ? null : shiftedArg,
|
9734
9693
|
sub: funcName === "\\underset" ? shiftedArg : null
|
@@ -10630,6 +10589,71 @@ defineFunction({
|
|
10630
10589
|
}
|
10631
10590
|
});
|
10632
10591
|
|
10592
|
+
const numRegEx = /^[0-9]$/;
|
10593
|
+
const unicodeNumSubs = {
|
10594
|
+
'0': '₀',
|
10595
|
+
'1': '₁',
|
10596
|
+
'2': '₂',
|
10597
|
+
'3': '₃',
|
10598
|
+
'4': '₄',
|
10599
|
+
'5': '₅',
|
10600
|
+
'6': '₆',
|
10601
|
+
'7': '₇',
|
10602
|
+
'8': '₈',
|
10603
|
+
'9': '₉'
|
10604
|
+
};
|
10605
|
+
const unicodeNumSups = {
|
10606
|
+
'0': '⁰',
|
10607
|
+
'1': '¹',
|
10608
|
+
'2': '²',
|
10609
|
+
'3': '³',
|
10610
|
+
'4': '⁴',
|
10611
|
+
'5': '⁵',
|
10612
|
+
'6': '⁶',
|
10613
|
+
'7': '⁷',
|
10614
|
+
'8': '⁸',
|
10615
|
+
'9': '⁹'
|
10616
|
+
};
|
10617
|
+
|
10618
|
+
defineFunction({
|
10619
|
+
type: "sfrac",
|
10620
|
+
names: ["\\sfrac"],
|
10621
|
+
props: {
|
10622
|
+
numArgs: 2,
|
10623
|
+
allowedInText: true,
|
10624
|
+
allowedInMath: true
|
10625
|
+
},
|
10626
|
+
handler({ parser }, args) {
|
10627
|
+
let numerator = "";
|
10628
|
+
for (const node of args[0].body) {
|
10629
|
+
if (node.type !== "textord" || !numRegEx.test(node.text)) {
|
10630
|
+
throw new ParseError("Numerator must be an integer.", node)
|
10631
|
+
}
|
10632
|
+
numerator += node.text;
|
10633
|
+
}
|
10634
|
+
let denominator = "";
|
10635
|
+
for (const node of args[1].body) {
|
10636
|
+
if (node.type !== "textord" || !numRegEx.test(node.text)) {
|
10637
|
+
throw new ParseError("Denominator must be an integer.", node)
|
10638
|
+
}
|
10639
|
+
denominator += node.text;
|
10640
|
+
}
|
10641
|
+
return {
|
10642
|
+
type: "sfrac",
|
10643
|
+
mode: parser.mode,
|
10644
|
+
numerator,
|
10645
|
+
denominator
|
10646
|
+
};
|
10647
|
+
},
|
10648
|
+
mathmlBuilder(group, style) {
|
10649
|
+
const numerator = group.numerator.split('').map(c => unicodeNumSups[c]).join('');
|
10650
|
+
const denominator = group.denominator.split('').map(c => unicodeNumSubs[c]).join('');
|
10651
|
+
// Use a fraction slash.
|
10652
|
+
const text = new mathMLTree.TextNode(numerator + "\u2044" + denominator, group.mode, style);
|
10653
|
+
return new mathMLTree.MathNode("mn", [text], ["special-fraction"])
|
10654
|
+
}
|
10655
|
+
});
|
10656
|
+
|
10633
10657
|
// The size mappings are taken from TeX with \normalsize=10pt.
|
10634
10658
|
// We don't have to track script level. MathML does that.
|
10635
10659
|
const sizeMap = {
|
@@ -10847,6 +10871,11 @@ defineFunction({
|
|
10847
10871
|
// Helpers
|
10848
10872
|
const symbolRegEx = /^m(over|under|underover)$/;
|
10849
10873
|
|
10874
|
+
// From the KaTeX font metrics, identify letters that encroach on a superscript.
|
10875
|
+
const smallPad = "DHKLUcegorsuvxyzΠΥΨαδηιμνοτυχϵ";
|
10876
|
+
const mediumPad = "BCEFGIMNOPQRSTXZlpqtwΓΘΞΣΦΩβεζθξρςφψϑϕϱ";
|
10877
|
+
const largePad = "AJdfΔΛ";
|
10878
|
+
|
10850
10879
|
// Super scripts and subscripts, whose precise placement can depend on other
|
10851
10880
|
// functions that precede them.
|
10852
10881
|
defineFunctionBuilders({
|
@@ -10868,7 +10897,7 @@ defineFunctionBuilders({
|
|
10868
10897
|
}
|
10869
10898
|
}
|
10870
10899
|
|
10871
|
-
if (group.base && !group.
|
10900
|
+
if (group.base && !group.stack &&
|
10872
10901
|
(group.base.type === "op" || group.base.type === "operatorname")) {
|
10873
10902
|
group.base.parentIsSupSub = true;
|
10874
10903
|
appendApplyFunction = !group.base.symbol;
|
@@ -10876,7 +10905,7 @@ defineFunctionBuilders({
|
|
10876
10905
|
needsLeadingSpace = group.base.needsLeadingSpace;
|
10877
10906
|
}
|
10878
10907
|
|
10879
|
-
const children = group.
|
10908
|
+
const children = group.stack && group.base.body.length === 1
|
10880
10909
|
? [buildGroup$1(group.base.body[0], style)]
|
10881
10910
|
: [buildGroup$1(group.base, style)];
|
10882
10911
|
|
@@ -10896,11 +10925,16 @@ defineFunctionBuilders({
|
|
10896
10925
|
if (group.sup) {
|
10897
10926
|
const sup = buildGroup$1(group.sup, childStyle);
|
10898
10927
|
if (style.level === 3) { sup.setAttribute("scriptlevel", "2"); }
|
10899
|
-
|
10900
|
-
|
10901
|
-
|
10902
|
-
|
10903
|
-
|
10928
|
+
if (group.base && group.base.text && group.base.text.length === 1) {
|
10929
|
+
// Make an italic correction on the superscript.
|
10930
|
+
const text = group.base.text;
|
10931
|
+
if (smallPad.indexOf(text) > -1) {
|
10932
|
+
sup.classes.push("tml-sml-pad");
|
10933
|
+
} else if (mediumPad.indexOf(text) > -1) {
|
10934
|
+
sup.classes.push("tml-med-pad");
|
10935
|
+
} else if (largePad.indexOf(text) > -1) {
|
10936
|
+
sup.classes.push("tml-lrg-pad");
|
10937
|
+
}
|
10904
10938
|
}
|
10905
10939
|
children.push(sup);
|
10906
10940
|
}
|
@@ -10929,7 +10963,9 @@ defineFunctionBuilders({
|
|
10929
10963
|
}
|
10930
10964
|
} else if (!group.sup) {
|
10931
10965
|
const base = group.base;
|
10932
|
-
if (
|
10966
|
+
if (group.stack) {
|
10967
|
+
nodeType = "munder";
|
10968
|
+
} else if (
|
10933
10969
|
base &&
|
10934
10970
|
base.type === "op" &&
|
10935
10971
|
base.limits &&
|
@@ -13974,7 +14010,7 @@ class Style {
|
|
13974
14010
|
* https://mit-license.org/
|
13975
14011
|
*/
|
13976
14012
|
|
13977
|
-
const version = "0.11.
|
14013
|
+
const version = "0.11.08";
|
13978
14014
|
|
13979
14015
|
function postProcess(block) {
|
13980
14016
|
const labelMap = {};
|