katex 0.12.0 → 0.13.3
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/CHANGELOG.md +112 -0
- package/LICENSE +1 -1
- package/README.md +8 -7
- package/contrib/auto-render/auto-render.js +12 -19
- package/contrib/auto-render/index.html +9 -3
- package/contrib/auto-render/splitAtDelimiters.js +44 -61
- package/contrib/auto-render/test/auto-render-spec.js +88 -52
- package/contrib/copy-tex/README.md +5 -9
- package/contrib/copy-tex/copy-tex.css +0 -3
- package/contrib/mathtex-script-type/README.md +5 -5
- package/contrib/mhchem/README.md +4 -2
- package/contrib/render-a11y-string/render-a11y-string.js +31 -2
- package/contrib/render-a11y-string/test/render-a11y-string-spec.js +23 -0
- package/dist/README.md +8 -7
- package/dist/contrib/auto-render.js +148 -171
- package/dist/contrib/auto-render.min.js +1 -1
- package/dist/contrib/auto-render.mjs +91 -95
- package/dist/contrib/copy-tex.css +3 -3
- package/dist/contrib/copy-tex.js +11 -108
- package/dist/contrib/copy-tex.min.css +1 -1
- package/dist/contrib/copy-tex.min.js +1 -1
- package/dist/contrib/copy-tex.mjs +21 -20
- package/dist/contrib/mathtex-script-type.js +66 -91
- package/dist/contrib/mathtex-script-type.min.js +1 -1
- package/dist/contrib/mathtex-script-type.mjs +3 -3
- package/dist/contrib/mhchem.js +70 -95
- package/dist/contrib/mhchem.min.js +1 -1
- package/dist/contrib/mhchem.mjs +2 -2
- package/dist/contrib/render-a11y-string.js +97 -92
- package/dist/contrib/render-a11y-string.min.js +1 -1
- package/dist/contrib/render-a11y-string.mjs +86 -45
- package/dist/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Italic.woff +0 -0
- package/dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_Math-Italic.woff +0 -0
- package/dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Script-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dist/katex.css +66 -10
- package/dist/katex.js +2714 -1950
- package/dist/katex.min.css +1 -1
- package/dist/katex.min.js +1 -1
- package/dist/katex.mjs +3162 -2372
- package/katex.js +4 -3
- package/package.json +69 -59
- package/src/Lexer.js +4 -2
- package/src/MacroExpander.js +117 -37
- package/src/Options.js +2 -2
- package/src/ParseError.js +1 -1
- package/src/Parser.js +100 -159
- package/src/Settings.js +2 -2
- package/src/Style.js +4 -4
- package/src/Token.js +1 -1
- package/src/buildCommon.js +12 -5
- package/src/buildHTML.js +11 -0
- package/src/buildMathML.js +6 -0
- package/src/defineEnvironment.js +0 -3
- package/src/defineFunction.js +15 -22
- package/src/delimiter.js +61 -57
- package/src/domTree.js +1 -1
- package/src/environments/array.js +223 -35
- package/src/environments/cd.js +312 -0
- package/src/fontMetrics.js +1 -1
- package/src/fontMetricsData.js +2076 -0
- package/src/fonts/.gitignore +9 -0
- package/src/fonts/Makefile +139 -0
- package/src/fonts/default.cfg +20 -0
- package/src/fonts/generate_fonts.py +61 -0
- package/src/fonts/lib/Extra.otf +0 -0
- package/src/fonts/lib/Space.ttx +234 -0
- package/src/fonts/makeBlacker +49 -0
- package/src/fonts/makeFF +2003 -0
- package/src/fonts/xbbold.mf +182 -0
- package/src/fonts.less +64 -0
- package/src/functions/accent.js +3 -2
- package/src/functions/arrow.js +8 -2
- package/src/functions/color.js +4 -4
- package/src/functions/cr.js +7 -25
- package/src/functions/def.js +50 -24
- package/src/functions/delimsizing.js +8 -0
- package/src/functions/enclose.js +80 -12
- package/src/functions/environment.js +1 -1
- package/src/functions/font.js +3 -4
- package/src/functions/genfrac.js +36 -11
- package/src/functions/hbox.js +39 -0
- package/src/functions/kern.js +1 -0
- package/src/functions/mathchoice.js +1 -0
- package/src/functions/mclass.js +2 -1
- package/src/functions/op.js +3 -7
- package/src/functions/operatorname.js +1 -1
- package/src/functions/raisebox.js +0 -1
- package/src/functions/styling.js +1 -0
- package/src/functions/supsub.js +1 -3
- package/src/functions/symbolsOrd.js +0 -2
- package/src/functions/text.js +2 -3
- package/src/functions/vcenter.js +44 -0
- package/src/functions.js +3 -0
- package/src/katex.less +69 -16
- package/src/macros.js +42 -6
- package/src/mathMLTree.js +16 -1
- package/src/metrics/.gitignore +1 -0
- package/src/metrics/README.md +23 -0
- package/src/metrics/extract_tfms.py +114 -0
- package/src/metrics/extract_ttfs.py +119 -0
- package/src/metrics/format_json.py +28 -0
- package/src/metrics/mapping.pl +1224 -0
- package/src/metrics/parse_tfm.py +211 -0
- package/src/parseNode.js +29 -1
- package/src/parseTree.js +6 -0
- package/src/stretchy.js +12 -5
- package/src/svgGeometry.js +33 -4
- package/src/symbols.js +5 -3
- package/src/types.js +3 -2
- package/src/unicodeScripts.js +5 -0
package/src/functions/enclose.js
CHANGED
|
@@ -4,6 +4,9 @@ import buildCommon from "../buildCommon";
|
|
|
4
4
|
import mathMLTree from "../mathMLTree";
|
|
5
5
|
import utils from "../utils";
|
|
6
6
|
import stretchy from "../stretchy";
|
|
7
|
+
import {phasePath} from "../svgGeometry";
|
|
8
|
+
import {PathNode, SvgNode} from "../domTree";
|
|
9
|
+
import {calculateSize} from "../units";
|
|
7
10
|
import {assertNodeType} from "../parseNode";
|
|
8
11
|
|
|
9
12
|
import * as html from "../buildHTML";
|
|
@@ -11,14 +14,14 @@ import * as mml from "../buildMathML";
|
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
const htmlBuilder = (group, options) => {
|
|
14
|
-
// \cancel, \bcancel, \xcancel, \sout, \fbox, \colorbox, \fcolorbox
|
|
17
|
+
// \cancel, \bcancel, \xcancel, \sout, \fbox, \colorbox, \fcolorbox, \phase
|
|
15
18
|
// Some groups can return document fragments. Handle those by wrapping
|
|
16
19
|
// them in a span.
|
|
17
20
|
const inner = buildCommon.wrapFragment(
|
|
18
21
|
html.buildGroup(group.body, options), options);
|
|
19
22
|
|
|
20
23
|
const label = group.label.substr(1);
|
|
21
|
-
|
|
24
|
+
let scale = options.sizeMultiplier;
|
|
22
25
|
let img;
|
|
23
26
|
let imgShift = 0;
|
|
24
27
|
|
|
@@ -34,18 +37,48 @@ const htmlBuilder = (group, options) => {
|
|
|
34
37
|
img.height = options.fontMetrics().defaultRuleThickness / scale;
|
|
35
38
|
imgShift = -0.5 * options.fontMetrics().xHeight;
|
|
36
39
|
|
|
40
|
+
} else if (label === "phase") {
|
|
41
|
+
// Set a couple of dimensions from the steinmetz package.
|
|
42
|
+
const lineWeight = calculateSize({number: 0.6, unit: "pt"}, options);
|
|
43
|
+
const clearance = calculateSize({number: 0.35, unit: "ex"}, options);
|
|
44
|
+
|
|
45
|
+
// Prevent size changes like \Huge from affecting line thickness
|
|
46
|
+
const newOptions = options.havingBaseSizing();
|
|
47
|
+
scale = scale / newOptions.sizeMultiplier;
|
|
48
|
+
|
|
49
|
+
const angleHeight = inner.height + inner.depth + lineWeight + clearance;
|
|
50
|
+
// Reserve a left pad for the angle.
|
|
51
|
+
inner.style.paddingLeft = (angleHeight / 2 + lineWeight) + "em";
|
|
52
|
+
|
|
53
|
+
// Create an SVG
|
|
54
|
+
const viewBoxHeight = Math.floor(1000 * angleHeight * scale);
|
|
55
|
+
const path = phasePath(viewBoxHeight);
|
|
56
|
+
const svgNode = new SvgNode([new PathNode("phase", path)], {
|
|
57
|
+
"width": "400em",
|
|
58
|
+
"height": `${viewBoxHeight / 1000}em`,
|
|
59
|
+
"viewBox": `0 0 400000 ${viewBoxHeight}`,
|
|
60
|
+
"preserveAspectRatio": "xMinYMin slice",
|
|
61
|
+
});
|
|
62
|
+
// Wrap it in a span with overflow: hidden.
|
|
63
|
+
img = buildCommon.makeSvgSpan(["hide-tail"], [svgNode], options);
|
|
64
|
+
img.style.height = angleHeight + "em";
|
|
65
|
+
imgShift = inner.depth + lineWeight + clearance;
|
|
66
|
+
|
|
37
67
|
} else {
|
|
38
68
|
// Add horizontal padding
|
|
39
69
|
if (/cancel/.test(label)) {
|
|
40
70
|
if (!isSingleChar) {
|
|
41
71
|
inner.classes.push("cancel-pad");
|
|
42
72
|
}
|
|
73
|
+
} else if (label === "angl") {
|
|
74
|
+
inner.classes.push("anglpad");
|
|
43
75
|
} else {
|
|
44
76
|
inner.classes.push("boxpad");
|
|
45
77
|
}
|
|
46
78
|
|
|
47
79
|
// Add vertical padding
|
|
48
|
-
let
|
|
80
|
+
let topPad = 0;
|
|
81
|
+
let bottomPad = 0;
|
|
49
82
|
let ruleThickness = 0;
|
|
50
83
|
// ref: cancel package: \advance\totalheight2\p@ % "+2"
|
|
51
84
|
if (/box/.test(label)) {
|
|
@@ -53,18 +86,30 @@ const htmlBuilder = (group, options) => {
|
|
|
53
86
|
options.fontMetrics().fboxrule, // default
|
|
54
87
|
options.minRuleThickness, // User override.
|
|
55
88
|
);
|
|
56
|
-
|
|
89
|
+
topPad = options.fontMetrics().fboxsep +
|
|
57
90
|
(label === "colorbox" ? 0 : ruleThickness);
|
|
91
|
+
bottomPad = topPad;
|
|
92
|
+
} else if (label === "angl") {
|
|
93
|
+
ruleThickness = Math.max(
|
|
94
|
+
options.fontMetrics().defaultRuleThickness,
|
|
95
|
+
options.minRuleThickness
|
|
96
|
+
);
|
|
97
|
+
topPad = 4 * ruleThickness; // gap = 3 × line, plus the line itself.
|
|
98
|
+
bottomPad = Math.max(0, 0.25 - inner.depth);
|
|
58
99
|
} else {
|
|
59
|
-
|
|
100
|
+
topPad = isSingleChar ? 0.2 : 0;
|
|
101
|
+
bottomPad = topPad;
|
|
60
102
|
}
|
|
61
103
|
|
|
62
|
-
img = stretchy.encloseSpan(inner, label,
|
|
104
|
+
img = stretchy.encloseSpan(inner, label, topPad, bottomPad, options);
|
|
63
105
|
if (/fbox|boxed|fcolorbox/.test(label)) {
|
|
64
106
|
img.style.borderStyle = "solid";
|
|
65
107
|
img.style.borderWidth = `${ruleThickness}em`;
|
|
108
|
+
} else if (label === "angl" && ruleThickness !== 0.049) {
|
|
109
|
+
img.style.borderTopWidth = `${ruleThickness}em`;
|
|
110
|
+
img.style.borderRightWidth = `${ruleThickness}em`;
|
|
66
111
|
}
|
|
67
|
-
imgShift = inner.depth +
|
|
112
|
+
imgShift = inner.depth + bottomPad;
|
|
68
113
|
|
|
69
114
|
if (group.backgroundColor) {
|
|
70
115
|
img.style.backgroundColor = group.backgroundColor;
|
|
@@ -85,6 +130,7 @@ const htmlBuilder = (group, options) => {
|
|
|
85
130
|
],
|
|
86
131
|
}, options);
|
|
87
132
|
} else {
|
|
133
|
+
const classes = /cancel|phase/.test(label) ? ["svg-align"] : [];
|
|
88
134
|
vlist = buildCommon.makeVList({
|
|
89
135
|
positionType: "individualShift",
|
|
90
136
|
children: [
|
|
@@ -98,7 +144,7 @@ const htmlBuilder = (group, options) => {
|
|
|
98
144
|
type: "elem",
|
|
99
145
|
elem: img,
|
|
100
146
|
shift: imgShift,
|
|
101
|
-
wrapperClasses:
|
|
147
|
+
wrapperClasses: classes,
|
|
102
148
|
},
|
|
103
149
|
],
|
|
104
150
|
}, options);
|
|
@@ -132,12 +178,18 @@ const mathmlBuilder = (group, options) => {
|
|
|
132
178
|
case "\\bcancel":
|
|
133
179
|
node.setAttribute("notation", "downdiagonalstrike");
|
|
134
180
|
break;
|
|
181
|
+
case "\\phase":
|
|
182
|
+
node.setAttribute("notation", "phasorangle");
|
|
183
|
+
break;
|
|
135
184
|
case "\\sout":
|
|
136
185
|
node.setAttribute("notation", "horizontalstrike");
|
|
137
186
|
break;
|
|
138
187
|
case "\\fbox":
|
|
139
188
|
node.setAttribute("notation", "box");
|
|
140
189
|
break;
|
|
190
|
+
case "\\angl":
|
|
191
|
+
node.setAttribute("notation", "actuarial");
|
|
192
|
+
break;
|
|
141
193
|
case "\\fcolorbox":
|
|
142
194
|
case "\\colorbox":
|
|
143
195
|
// <menclose> doesn't have a good notation option. So use <mpadded>
|
|
@@ -173,7 +225,6 @@ defineFunction({
|
|
|
173
225
|
props: {
|
|
174
226
|
numArgs: 2,
|
|
175
227
|
allowedInText: true,
|
|
176
|
-
greediness: 3,
|
|
177
228
|
argTypes: ["color", "text"],
|
|
178
229
|
},
|
|
179
230
|
handler({parser, funcName}, args, optArgs) {
|
|
@@ -197,7 +248,6 @@ defineFunction({
|
|
|
197
248
|
props: {
|
|
198
249
|
numArgs: 3,
|
|
199
250
|
allowedInText: true,
|
|
200
|
-
greediness: 3,
|
|
201
251
|
argTypes: ["color", "color", "text"],
|
|
202
252
|
},
|
|
203
253
|
handler({parser, funcName}, args, optArgs) {
|
|
@@ -237,11 +287,11 @@ defineFunction({
|
|
|
237
287
|
|
|
238
288
|
defineFunction({
|
|
239
289
|
type: "enclose",
|
|
240
|
-
names: ["\\cancel", "\\bcancel", "\\xcancel", "\\sout"],
|
|
290
|
+
names: ["\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\phase"],
|
|
241
291
|
props: {
|
|
242
292
|
numArgs: 1,
|
|
243
293
|
},
|
|
244
|
-
handler({parser, funcName}, args
|
|
294
|
+
handler({parser, funcName}, args) {
|
|
245
295
|
const body = args[0];
|
|
246
296
|
return {
|
|
247
297
|
type: "enclose",
|
|
@@ -253,3 +303,21 @@ defineFunction({
|
|
|
253
303
|
htmlBuilder,
|
|
254
304
|
mathmlBuilder,
|
|
255
305
|
});
|
|
306
|
+
|
|
307
|
+
defineFunction({
|
|
308
|
+
type: "enclose",
|
|
309
|
+
names: ["\\angl"],
|
|
310
|
+
props: {
|
|
311
|
+
numArgs: 1,
|
|
312
|
+
argTypes: ["hbox"],
|
|
313
|
+
allowedInText: false,
|
|
314
|
+
},
|
|
315
|
+
handler({parser}, args) {
|
|
316
|
+
return {
|
|
317
|
+
type: "enclose",
|
|
318
|
+
mode: parser.mode,
|
|
319
|
+
label: "\\angl",
|
|
320
|
+
body: args[0],
|
|
321
|
+
};
|
|
322
|
+
},
|
|
323
|
+
});
|
|
@@ -6,7 +6,6 @@ import environments from "../environments";
|
|
|
6
6
|
|
|
7
7
|
// Environment delimiters. HTML/MathML rendering is defined in the corresponding
|
|
8
8
|
// defineEnvironment definitions.
|
|
9
|
-
// $FlowFixMe, "environment" handler returns an environment ParseNode
|
|
10
9
|
defineFunction({
|
|
11
10
|
type: "environment",
|
|
12
11
|
names: ["\\begin", "\\end"],
|
|
@@ -49,6 +48,7 @@ defineFunction({
|
|
|
49
48
|
`Mismatch: \\begin{${envName}} matched by \\end{${end.name}}`,
|
|
50
49
|
endNameToken);
|
|
51
50
|
}
|
|
51
|
+
// $FlowFixMe, "environment" handler returns an environment ParseNode
|
|
52
52
|
return result;
|
|
53
53
|
}
|
|
54
54
|
|
package/src/functions/font.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// TODO(kevinb): implement \\sl and \\sc
|
|
3
3
|
|
|
4
4
|
import {binrelClass} from "./mclass";
|
|
5
|
-
import defineFunction from "../defineFunction";
|
|
5
|
+
import defineFunction, {normalizeArgument} from "../defineFunction";
|
|
6
6
|
import utils from "../utils";
|
|
7
7
|
|
|
8
8
|
import * as html from "../buildHTML";
|
|
@@ -44,10 +44,10 @@ defineFunction({
|
|
|
44
44
|
],
|
|
45
45
|
props: {
|
|
46
46
|
numArgs: 1,
|
|
47
|
-
|
|
47
|
+
allowedInArgument: true,
|
|
48
48
|
},
|
|
49
49
|
handler: ({parser, funcName}, args) => {
|
|
50
|
-
const body = args[0];
|
|
50
|
+
const body = normalizeArgument(args[0]);
|
|
51
51
|
let func = funcName;
|
|
52
52
|
if (func in fontAliases) {
|
|
53
53
|
func = fontAliases[func];
|
|
@@ -68,7 +68,6 @@ defineFunction({
|
|
|
68
68
|
names: ["\\boldsymbol", "\\bm"],
|
|
69
69
|
props: {
|
|
70
70
|
numArgs: 1,
|
|
71
|
-
greediness: 2,
|
|
72
71
|
},
|
|
73
72
|
handler: ({parser}, args) => {
|
|
74
73
|
const body = args[0];
|
package/src/functions/genfrac.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @flow
|
|
2
|
-
import defineFunction from "../defineFunction";
|
|
2
|
+
import defineFunction, {normalizeArgument} from "../defineFunction";
|
|
3
3
|
import buildCommon from "../buildCommon";
|
|
4
4
|
import delimiter from "../delimiter";
|
|
5
5
|
import mathMLTree from "../mathMLTree";
|
|
@@ -241,14 +241,14 @@ const mathmlBuilder = (group, options) => {
|
|
|
241
241
|
defineFunction({
|
|
242
242
|
type: "genfrac",
|
|
243
243
|
names: [
|
|
244
|
-
"\\
|
|
244
|
+
"\\dfrac", "\\frac", "\\tfrac",
|
|
245
245
|
"\\dbinom", "\\binom", "\\tbinom",
|
|
246
246
|
"\\\\atopfrac", // can’t be entered directly
|
|
247
247
|
"\\\\bracefrac", "\\\\brackfrac", // ditto
|
|
248
248
|
],
|
|
249
249
|
props: {
|
|
250
250
|
numArgs: 2,
|
|
251
|
-
|
|
251
|
+
allowedInArgument: true,
|
|
252
252
|
},
|
|
253
253
|
handler: ({parser, funcName}, args) => {
|
|
254
254
|
const numer = args[0];
|
|
@@ -259,7 +259,6 @@ defineFunction({
|
|
|
259
259
|
let size = "auto";
|
|
260
260
|
|
|
261
261
|
switch (funcName) {
|
|
262
|
-
case "\\cfrac":
|
|
263
262
|
case "\\dfrac":
|
|
264
263
|
case "\\frac":
|
|
265
264
|
case "\\tfrac":
|
|
@@ -290,7 +289,6 @@ defineFunction({
|
|
|
290
289
|
}
|
|
291
290
|
|
|
292
291
|
switch (funcName) {
|
|
293
|
-
case "\\cfrac":
|
|
294
292
|
case "\\dfrac":
|
|
295
293
|
case "\\dbinom":
|
|
296
294
|
size = "display";
|
|
@@ -304,7 +302,7 @@ defineFunction({
|
|
|
304
302
|
return {
|
|
305
303
|
type: "genfrac",
|
|
306
304
|
mode: parser.mode,
|
|
307
|
-
continued:
|
|
305
|
+
continued: false,
|
|
308
306
|
numer,
|
|
309
307
|
denom,
|
|
310
308
|
hasBarLine,
|
|
@@ -319,6 +317,31 @@ defineFunction({
|
|
|
319
317
|
mathmlBuilder,
|
|
320
318
|
});
|
|
321
319
|
|
|
320
|
+
defineFunction({
|
|
321
|
+
type: "genfrac",
|
|
322
|
+
names: ["\\cfrac"],
|
|
323
|
+
props: {
|
|
324
|
+
numArgs: 2,
|
|
325
|
+
},
|
|
326
|
+
handler: ({parser, funcName}, args) => {
|
|
327
|
+
const numer = args[0];
|
|
328
|
+
const denom = args[1];
|
|
329
|
+
|
|
330
|
+
return {
|
|
331
|
+
type: "genfrac",
|
|
332
|
+
mode: parser.mode,
|
|
333
|
+
continued: true,
|
|
334
|
+
numer,
|
|
335
|
+
denom,
|
|
336
|
+
hasBarLine: true,
|
|
337
|
+
leftDelim: null,
|
|
338
|
+
rightDelim: null,
|
|
339
|
+
size: "display",
|
|
340
|
+
barSize: null,
|
|
341
|
+
};
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
|
|
322
345
|
// Infix generalized fractions -- these are not rendered directly, but replaced
|
|
323
346
|
// immediately by one of the variants above.
|
|
324
347
|
defineFunction({
|
|
@@ -374,7 +397,7 @@ defineFunction({
|
|
|
374
397
|
names: ["\\genfrac"],
|
|
375
398
|
props: {
|
|
376
399
|
numArgs: 6,
|
|
377
|
-
|
|
400
|
+
allowedInArgument: true,
|
|
378
401
|
argTypes: ["math", "math", "size", "text", "math", "math"],
|
|
379
402
|
},
|
|
380
403
|
handler({parser}, args) {
|
|
@@ -382,10 +405,12 @@ defineFunction({
|
|
|
382
405
|
const denom = args[5];
|
|
383
406
|
|
|
384
407
|
// Look into the parse nodes to get the desired delimiters.
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
408
|
+
const leftNode = normalizeArgument(args[0]);
|
|
409
|
+
const leftDelim = leftNode.type === "atom" && leftNode.family === "open"
|
|
410
|
+
? delimFromValue(leftNode.text) : null;
|
|
411
|
+
const rightNode = normalizeArgument(args[1]);
|
|
412
|
+
const rightDelim = rightNode.type === "atom" && rightNode.family === "close"
|
|
413
|
+
? delimFromValue(rightNode.text) : null;
|
|
389
414
|
|
|
390
415
|
const barNode = assertNodeType(args[2], "size");
|
|
391
416
|
let hasBarLine;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import defineFunction, {ordargument} from "../defineFunction";
|
|
3
|
+
import buildCommon from "../buildCommon";
|
|
4
|
+
import mathMLTree from "../mathMLTree";
|
|
5
|
+
|
|
6
|
+
import * as html from "../buildHTML";
|
|
7
|
+
import * as mml from "../buildMathML";
|
|
8
|
+
|
|
9
|
+
// \hbox is provided for compatibility with LaTeX \vcenter.
|
|
10
|
+
// In LaTeX, \vcenter can act only on a box, as in
|
|
11
|
+
// \vcenter{\hbox{$\frac{a+b}{\dfrac{c}{d}}$}}
|
|
12
|
+
// This function by itself doesn't do anything but prevent a soft line break.
|
|
13
|
+
|
|
14
|
+
defineFunction({
|
|
15
|
+
type: "hbox",
|
|
16
|
+
names: ["\\hbox"],
|
|
17
|
+
props: {
|
|
18
|
+
numArgs: 1,
|
|
19
|
+
argTypes: ["text"],
|
|
20
|
+
allowedInText: true,
|
|
21
|
+
primitive: true,
|
|
22
|
+
},
|
|
23
|
+
handler({parser}, args) {
|
|
24
|
+
return {
|
|
25
|
+
type: "hbox",
|
|
26
|
+
mode: parser.mode,
|
|
27
|
+
body: ordargument(args[0]),
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
htmlBuilder(group, options) {
|
|
31
|
+
const elements = html.buildExpression(group.body, options, false);
|
|
32
|
+
return buildCommon.makeFragment(elements);
|
|
33
|
+
},
|
|
34
|
+
mathmlBuilder(group, options) {
|
|
35
|
+
return new mathMLTree.MathNode(
|
|
36
|
+
"mrow", mml.buildExpression(group.body, options)
|
|
37
|
+
);
|
|
38
|
+
},
|
|
39
|
+
});
|
package/src/functions/kern.js
CHANGED
package/src/functions/mclass.js
CHANGED
|
@@ -65,6 +65,7 @@ defineFunction({
|
|
|
65
65
|
],
|
|
66
66
|
props: {
|
|
67
67
|
numArgs: 1,
|
|
68
|
+
primitive: true,
|
|
68
69
|
},
|
|
69
70
|
handler({parser, funcName}, args) {
|
|
70
71
|
const body = args[0];
|
|
@@ -106,7 +107,7 @@ defineFunction({
|
|
|
106
107
|
type: "mclass",
|
|
107
108
|
mode: parser.mode,
|
|
108
109
|
mclass: binrelClass(args[0]),
|
|
109
|
-
body:
|
|
110
|
+
body: ordargument(args[1]),
|
|
110
111
|
isCharacterBox: utils.isCharacterBox(args[1]),
|
|
111
112
|
};
|
|
112
113
|
},
|
package/src/functions/op.js
CHANGED
|
@@ -61,7 +61,6 @@ export const htmlBuilder: HtmlBuilderSupSub<"op"> = (grp, options) => {
|
|
|
61
61
|
// No font glyphs yet, so use a glyph w/o the oval.
|
|
62
62
|
// TODO: When font glyphs are available, delete this code.
|
|
63
63
|
stash = group.name.substr(1);
|
|
64
|
-
// $FlowFixMe
|
|
65
64
|
group.name = stash === "oiint" ? "\\iint" : "\\iiint";
|
|
66
65
|
}
|
|
67
66
|
|
|
@@ -82,7 +81,6 @@ export const htmlBuilder: HtmlBuilderSupSub<"op"> = (grp, options) => {
|
|
|
82
81
|
{type: "elem", elem: oval, shift: large ? 0.08 : 0},
|
|
83
82
|
],
|
|
84
83
|
}, options);
|
|
85
|
-
// $FlowFixMe
|
|
86
84
|
group.name = "\\" + stash;
|
|
87
85
|
base.classes.unshift("mop");
|
|
88
86
|
// $FlowFixMe
|
|
@@ -95,14 +93,11 @@ export const htmlBuilder: HtmlBuilderSupSub<"op"> = (grp, options) => {
|
|
|
95
93
|
base = inner[0];
|
|
96
94
|
base.classes[0] = "mop"; // replace old mclass
|
|
97
95
|
} else {
|
|
98
|
-
base = buildCommon.makeSpan(
|
|
99
|
-
["mop"], buildCommon.tryCombineChars(inner), options);
|
|
96
|
+
base = buildCommon.makeSpan(["mop"], inner, options);
|
|
100
97
|
}
|
|
101
98
|
} else {
|
|
102
99
|
// Otherwise, this is a text operator. Build the text from the
|
|
103
100
|
// operator's name.
|
|
104
|
-
// TODO(emily): Add a space in the middle of some of these
|
|
105
|
-
// operators, like \limsup
|
|
106
101
|
const output = [];
|
|
107
102
|
for (let i = 1; i < group.name.length; i++) {
|
|
108
103
|
output.push(buildCommon.mathsym(group.name[i], group.mode, options));
|
|
@@ -168,7 +163,7 @@ const mathmlBuilder: MathMLBuilder<"op"> = (group, options) => {
|
|
|
168
163
|
const operator = new mathMLTree.MathNode("mo",
|
|
169
164
|
[mml.makeText("\u2061", "text")]);
|
|
170
165
|
if (group.parentIsSupSub) {
|
|
171
|
-
node = new mathMLTree.MathNode("
|
|
166
|
+
node = new mathMLTree.MathNode("mrow", [node, operator]);
|
|
172
167
|
} else {
|
|
173
168
|
node = mathMLTree.newDocumentFragment([node, operator]);
|
|
174
169
|
}
|
|
@@ -229,6 +224,7 @@ defineFunction({
|
|
|
229
224
|
names: ["\\mathop"],
|
|
230
225
|
props: {
|
|
231
226
|
numArgs: 1,
|
|
227
|
+
primitive: true,
|
|
232
228
|
},
|
|
233
229
|
handler: ({parser}, args) => {
|
|
234
230
|
const body = args[0];
|
|
@@ -130,7 +130,7 @@ const mathmlBuilder: MathMLBuilder<"operatorname"> = (group, options) => {
|
|
|
130
130
|
[mml.makeText("\u2061", "text")]);
|
|
131
131
|
|
|
132
132
|
if (group.parentIsSupSub) {
|
|
133
|
-
return new mathMLTree.MathNode("
|
|
133
|
+
return new mathMLTree.MathNode("mrow", [identifier, operator]);
|
|
134
134
|
} else {
|
|
135
135
|
return mathMLTree.newDocumentFragment([identifier, operator]);
|
|
136
136
|
}
|
package/src/functions/styling.js
CHANGED
package/src/functions/supsub.js
CHANGED
|
@@ -47,8 +47,6 @@ defineFunctionBuilders({
|
|
|
47
47
|
if (group.mode === 'text') {
|
|
48
48
|
node = new mathMLTree.MathNode("mtext", [text]);
|
|
49
49
|
} else if (/[0-9]/.test(group.text)) {
|
|
50
|
-
// TODO(kevinb) merge adjacent <mn> nodes
|
|
51
|
-
// do it as a post processing step
|
|
52
50
|
node = new mathMLTree.MathNode("mn", [text]);
|
|
53
51
|
} else if (group.text === "\\prime") {
|
|
54
52
|
node = new mathMLTree.MathNode("mo", [text]);
|
package/src/functions/text.js
CHANGED
|
@@ -48,7 +48,7 @@ defineFunction({
|
|
|
48
48
|
props: {
|
|
49
49
|
numArgs: 1,
|
|
50
50
|
argTypes: ["text"],
|
|
51
|
-
|
|
51
|
+
allowedInArgument: true,
|
|
52
52
|
allowedInText: true,
|
|
53
53
|
},
|
|
54
54
|
handler({parser, funcName}, args) {
|
|
@@ -63,8 +63,7 @@ defineFunction({
|
|
|
63
63
|
htmlBuilder(group, options) {
|
|
64
64
|
const newOptions = optionsWithFont(group, options);
|
|
65
65
|
const inner = html.buildExpression(group.body, newOptions, true);
|
|
66
|
-
return buildCommon.makeSpan(
|
|
67
|
-
["mord", "text"], buildCommon.tryCombineChars(inner), newOptions);
|
|
66
|
+
return buildCommon.makeSpan(["mord", "text"], inner, newOptions);
|
|
68
67
|
},
|
|
69
68
|
mathmlBuilder(group, options) {
|
|
70
69
|
const newOptions = optionsWithFont(group, options);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import defineFunction from "../defineFunction";
|
|
3
|
+
import buildCommon from "../buildCommon";
|
|
4
|
+
import mathMLTree from "../mathMLTree";
|
|
5
|
+
|
|
6
|
+
import * as html from "../buildHTML";
|
|
7
|
+
import * as mml from "../buildMathML";
|
|
8
|
+
|
|
9
|
+
// \vcenter: Vertically center the argument group on the math axis.
|
|
10
|
+
|
|
11
|
+
defineFunction({
|
|
12
|
+
type: "vcenter",
|
|
13
|
+
names: ["\\vcenter"],
|
|
14
|
+
props: {
|
|
15
|
+
numArgs: 1,
|
|
16
|
+
argTypes: ["original"], // In LaTeX, \vcenter can act only on a box.
|
|
17
|
+
allowedInText: false,
|
|
18
|
+
},
|
|
19
|
+
handler({parser}, args) {
|
|
20
|
+
return {
|
|
21
|
+
type: "vcenter",
|
|
22
|
+
mode: parser.mode,
|
|
23
|
+
body: args[0],
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
htmlBuilder(group, options) {
|
|
27
|
+
const body = html.buildGroup(group.body, options);
|
|
28
|
+
const axisHeight = options.fontMetrics().axisHeight;
|
|
29
|
+
const dy = 0.5 * ((body.height - axisHeight) - (body.depth + axisHeight));
|
|
30
|
+
return buildCommon.makeVList({
|
|
31
|
+
positionType: "shift",
|
|
32
|
+
positionData: dy,
|
|
33
|
+
children: [{type: "elem", elem: body}],
|
|
34
|
+
}, options);
|
|
35
|
+
},
|
|
36
|
+
mathmlBuilder(group, options) {
|
|
37
|
+
// There is no way to do this in MathML.
|
|
38
|
+
// Write a class as a breadcrumb in case some post-processor wants
|
|
39
|
+
// to perform a vcenter adjustment.
|
|
40
|
+
return new mathMLTree.MathNode(
|
|
41
|
+
"mpadded", [mml.buildGroup(group.body, options)], ["vcenter"]);
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
|
package/src/functions.js
CHANGED
|
@@ -10,6 +10,7 @@ export default functions;
|
|
|
10
10
|
import "./functions/accent";
|
|
11
11
|
import "./functions/accentunder";
|
|
12
12
|
import "./functions/arrow";
|
|
13
|
+
import "./environments/cd";
|
|
13
14
|
import "./functions/char";
|
|
14
15
|
import "./functions/color";
|
|
15
16
|
import "./functions/cr";
|
|
@@ -21,6 +22,7 @@ import "./functions/font";
|
|
|
21
22
|
import "./functions/genfrac";
|
|
22
23
|
import "./functions/horizBrace";
|
|
23
24
|
import "./functions/href";
|
|
25
|
+
import "./functions/hbox";
|
|
24
26
|
import "./functions/html";
|
|
25
27
|
import "./functions/htmlmathml";
|
|
26
28
|
import "./functions/includegraphics";
|
|
@@ -47,4 +49,5 @@ import "./functions/symbolsSpacing";
|
|
|
47
49
|
import "./functions/tag";
|
|
48
50
|
import "./functions/text";
|
|
49
51
|
import "./functions/underline";
|
|
52
|
+
import "./functions/vcenter";
|
|
50
53
|
import "./functions/verb";
|