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
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import buildCommon from "../buildCommon";
|
|
3
3
|
import Style from "../Style";
|
|
4
4
|
import defineEnvironment from "../defineEnvironment";
|
|
5
|
+
import {parseCD} from "./cd";
|
|
5
6
|
import defineFunction from "../defineFunction";
|
|
6
7
|
import mathMLTree from "../mathMLTree";
|
|
7
8
|
import ParseError from "../ParseError";
|
|
@@ -27,8 +28,9 @@ export type AlignSpec = { type: "separator", separator: string } | {
|
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
// Type to indicate column separation in MathML
|
|
30
|
-
export type ColSeparationType = "align" | "alignat" | "small";
|
|
31
|
+
export type ColSeparationType = "align" | "alignat" | "gather" | "small" | "CD";
|
|
31
32
|
|
|
33
|
+
// Helper functions
|
|
32
34
|
function getHLines(parser: Parser): boolean[] {
|
|
33
35
|
// Return an array. The array length = number of hlines.
|
|
34
36
|
// Each element in the array tells if the line is dashed.
|
|
@@ -44,6 +46,14 @@ function getHLines(parser: Parser): boolean[] {
|
|
|
44
46
|
return hlineInfo;
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
const validateAmsEnvironmentContext = context => {
|
|
50
|
+
const settings = context.parser.settings;
|
|
51
|
+
if (!settings.displayMode) {
|
|
52
|
+
throw new ParseError(`{${context.envName}} can be used only in` +
|
|
53
|
+
` display mode.`);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
47
57
|
/**
|
|
48
58
|
* Parse the body of the environment, with rows delimited by \\ and
|
|
49
59
|
* columns delimited by &, and create a nested list in row-major order
|
|
@@ -52,18 +62,37 @@ function getHLines(parser: Parser): boolean[] {
|
|
|
52
62
|
*/
|
|
53
63
|
function parseArray(
|
|
54
64
|
parser: Parser,
|
|
55
|
-
{
|
|
65
|
+
{
|
|
66
|
+
hskipBeforeAndAfter,
|
|
67
|
+
addJot,
|
|
68
|
+
cols,
|
|
69
|
+
arraystretch,
|
|
70
|
+
colSeparationType,
|
|
71
|
+
addEqnNum,
|
|
72
|
+
singleRow,
|
|
73
|
+
emptySingleRow,
|
|
74
|
+
maxNumCols,
|
|
75
|
+
leqno,
|
|
76
|
+
}: {|
|
|
56
77
|
hskipBeforeAndAfter?: boolean,
|
|
57
78
|
addJot?: boolean,
|
|
58
79
|
cols?: AlignSpec[],
|
|
59
80
|
arraystretch?: number,
|
|
60
81
|
colSeparationType?: ColSeparationType,
|
|
82
|
+
addEqnNum?: boolean,
|
|
83
|
+
singleRow?: boolean,
|
|
84
|
+
emptySingleRow?: boolean,
|
|
85
|
+
maxNumCols?: number,
|
|
86
|
+
leqno?: boolean,
|
|
61
87
|
|},
|
|
62
88
|
style: StyleStr,
|
|
63
89
|
): ParseNode<"array"> {
|
|
64
|
-
// Parse body of array with \\ temporarily mapped to \cr
|
|
65
90
|
parser.gullet.beginGroup();
|
|
66
|
-
|
|
91
|
+
if (!singleRow) {
|
|
92
|
+
// \cr is equivalent to \\ without the optional size argument (see below)
|
|
93
|
+
// TODO: provide helpful error when \cr is used outside array environment
|
|
94
|
+
parser.gullet.macros.set("\\cr", "\\\\\\relax");
|
|
95
|
+
}
|
|
67
96
|
|
|
68
97
|
// Get current arraystretch if it's not set by the environment
|
|
69
98
|
if (!arraystretch) {
|
|
@@ -92,7 +121,7 @@ function parseArray(
|
|
|
92
121
|
|
|
93
122
|
while (true) { // eslint-disable-line no-constant-condition
|
|
94
123
|
// Parse each cell in its own group (namespace)
|
|
95
|
-
let cell = parser.parseExpression(false, "\\
|
|
124
|
+
let cell = parser.parseExpression(false, singleRow ? "\\end" : "\\\\");
|
|
96
125
|
parser.gullet.endGroup();
|
|
97
126
|
parser.gullet.beginGroup();
|
|
98
127
|
|
|
@@ -112,22 +141,44 @@ function parseArray(
|
|
|
112
141
|
row.push(cell);
|
|
113
142
|
const next = parser.fetch().text;
|
|
114
143
|
if (next === "&") {
|
|
144
|
+
if (maxNumCols && row.length === maxNumCols) {
|
|
145
|
+
if (singleRow || colSeparationType) {
|
|
146
|
+
// {equation} or {split}
|
|
147
|
+
throw new ParseError("Too many tab characters: &",
|
|
148
|
+
parser.nextToken);
|
|
149
|
+
} else {
|
|
150
|
+
// {array} environment
|
|
151
|
+
parser.settings.reportNonstrict("textEnv", "Too few columns " +
|
|
152
|
+
"specified in the {array} column argument.");
|
|
153
|
+
}
|
|
154
|
+
}
|
|
115
155
|
parser.consume();
|
|
116
156
|
} else if (next === "\\end") {
|
|
117
157
|
// Arrays terminate newlines with `\crcr` which consumes a `\cr` if
|
|
118
|
-
// the last line is empty.
|
|
158
|
+
// the last line is empty. However, AMS environments keep the
|
|
159
|
+
// empty row if it's the only one.
|
|
119
160
|
// NOTE: Currently, `cell` is the last item added into `row`.
|
|
120
161
|
if (row.length === 1 && cell.type === "styling" &&
|
|
121
|
-
cell.body[0].body.length === 0
|
|
162
|
+
cell.body[0].body.length === 0 &&
|
|
163
|
+
(body.length > 1 || !emptySingleRow)) {
|
|
122
164
|
body.pop();
|
|
123
165
|
}
|
|
124
166
|
if (hLinesBeforeRow.length < body.length + 1) {
|
|
125
167
|
hLinesBeforeRow.push([]);
|
|
126
168
|
}
|
|
127
169
|
break;
|
|
128
|
-
} else if (next === "
|
|
129
|
-
|
|
130
|
-
|
|
170
|
+
} else if (next === "\\\\") {
|
|
171
|
+
parser.consume();
|
|
172
|
+
let size;
|
|
173
|
+
// \def\Let@{\let\\\math@cr}
|
|
174
|
+
// \def\math@cr{...\math@cr@}
|
|
175
|
+
// \def\math@cr@{\new@ifnextchar[\math@cr@@{\math@cr@@[\z@]}}
|
|
176
|
+
// \def\math@cr@@[#1]{...\math@cr@@@...}
|
|
177
|
+
// \def\math@cr@@@{\cr}
|
|
178
|
+
if (parser.gullet.future().text !== " ") {
|
|
179
|
+
size = parser.parseSizeGroup(true);
|
|
180
|
+
}
|
|
181
|
+
rowGaps.push(size ? size.value : null);
|
|
131
182
|
|
|
132
183
|
// check for \hline(s) following the row separator
|
|
133
184
|
hLinesBeforeRow.push(getHLines(parser));
|
|
@@ -142,7 +193,7 @@ function parseArray(
|
|
|
142
193
|
|
|
143
194
|
// End cell group
|
|
144
195
|
parser.gullet.endGroup();
|
|
145
|
-
// End array group defining
|
|
196
|
+
// End array group defining \cr
|
|
146
197
|
parser.gullet.endGroup();
|
|
147
198
|
|
|
148
199
|
return {
|
|
@@ -156,6 +207,8 @@ function parseArray(
|
|
|
156
207
|
hskipBeforeAndAfter,
|
|
157
208
|
hLinesBeforeRow,
|
|
158
209
|
colSeparationType,
|
|
210
|
+
addEqnNum,
|
|
211
|
+
leqno,
|
|
159
212
|
};
|
|
160
213
|
}
|
|
161
214
|
|
|
@@ -206,7 +259,9 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
206
259
|
}
|
|
207
260
|
|
|
208
261
|
// Vertical spacing
|
|
209
|
-
const baselineskip =
|
|
262
|
+
const baselineskip = group.colSeparationType === "CD"
|
|
263
|
+
? calculateSize({number: 3, unit: "ex"}, options)
|
|
264
|
+
: 12 * pt; // see size10.clo
|
|
210
265
|
// Default \jot from ltmath.dtx
|
|
211
266
|
// TODO(edemaine): allow overriding \jot via \setlength (#687)
|
|
212
267
|
const jot = 3 * pt;
|
|
@@ -283,6 +338,21 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
283
338
|
const cols = [];
|
|
284
339
|
let colSep;
|
|
285
340
|
let colDescrNum;
|
|
341
|
+
|
|
342
|
+
const eqnNumSpans = [];
|
|
343
|
+
if (group.addEqnNum) {
|
|
344
|
+
// An environment with automatic equation numbers.
|
|
345
|
+
// Create node(s) that will trigger CSS counter increment.
|
|
346
|
+
for (r = 0; r < nr; ++r) {
|
|
347
|
+
const rw = body[r];
|
|
348
|
+
const shift = rw.pos - offset;
|
|
349
|
+
const eqnTag = buildCommon.makeSpan(["eqn-num"], [], options);
|
|
350
|
+
eqnTag.depth = rw.depth;
|
|
351
|
+
eqnTag.height = rw.height;
|
|
352
|
+
eqnNumSpans.push({type: "elem", elem: eqnTag, shift});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
286
356
|
for (c = 0, colDescrNum = 0;
|
|
287
357
|
// Continue while either there are more columns or more column
|
|
288
358
|
// descriptions, so trailing separators don't get lost.
|
|
@@ -393,7 +463,16 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
393
463
|
}, options);
|
|
394
464
|
}
|
|
395
465
|
|
|
396
|
-
|
|
466
|
+
if (!group.addEqnNum) {
|
|
467
|
+
return buildCommon.makeSpan(["mord"], [body], options);
|
|
468
|
+
} else {
|
|
469
|
+
let eqnNumCol = buildCommon.makeVList({
|
|
470
|
+
positionType: "individualShift",
|
|
471
|
+
children: eqnNumSpans,
|
|
472
|
+
}, options);
|
|
473
|
+
eqnNumCol = buildCommon.makeSpan(["tag"], [eqnNumCol], options);
|
|
474
|
+
return buildCommon.makeFragment([body, eqnNumCol]);
|
|
475
|
+
}
|
|
397
476
|
};
|
|
398
477
|
|
|
399
478
|
const alignMap = {
|
|
@@ -403,14 +482,28 @@ const alignMap = {
|
|
|
403
482
|
};
|
|
404
483
|
|
|
405
484
|
const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
485
|
+
const tbl = [];
|
|
486
|
+
const glue = new mathMLTree.MathNode("mtd", [], ["mtr-glue"]);
|
|
487
|
+
const tag = new mathMLTree.MathNode("mtd", [], ["mml-eqn-num"]);
|
|
488
|
+
for (let i = 0; i < group.body.length; i++) {
|
|
489
|
+
const rw = group.body[i];
|
|
490
|
+
const row = [];
|
|
491
|
+
for (let j = 0; j < rw.length; j++) {
|
|
492
|
+
row.push(new mathMLTree.MathNode("mtd",
|
|
493
|
+
[mml.buildGroup(rw[j], options)]));
|
|
494
|
+
}
|
|
495
|
+
if (group.addEqnNum) {
|
|
496
|
+
row.unshift(glue);
|
|
497
|
+
row.push(glue);
|
|
498
|
+
if (group.leqno) {
|
|
499
|
+
row.unshift(tag);
|
|
500
|
+
} else {
|
|
501
|
+
row.push(tag);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
tbl.push(new mathMLTree.MathNode("mtr", row));
|
|
505
|
+
}
|
|
506
|
+
let table = new mathMLTree.MathNode("mtable", tbl);
|
|
414
507
|
|
|
415
508
|
// Set column alignment, row spacing, column spacing, and
|
|
416
509
|
// array lines by setting attributes on the table element.
|
|
@@ -428,7 +521,7 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
|
428
521
|
const gap = (group.arraystretch === 0.5)
|
|
429
522
|
? 0.1 // {smallmatrix}, {subarray}
|
|
430
523
|
: 0.16 + group.arraystretch - 1 + (group.addJot ? 0.09 : 0);
|
|
431
|
-
table.setAttribute("rowspacing", gap + "em");
|
|
524
|
+
table.setAttribute("rowspacing", gap.toFixed(4) + "em");
|
|
432
525
|
|
|
433
526
|
// MathML table lines go only between cells.
|
|
434
527
|
// To place a line on an edge we'll use <menclose>, if necessary.
|
|
@@ -487,10 +580,13 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
|
487
580
|
spacing += i % 2 ? "0em " : "1em ";
|
|
488
581
|
}
|
|
489
582
|
table.setAttribute("columnspacing", spacing.trim());
|
|
490
|
-
} else if (group.colSeparationType === "alignat"
|
|
583
|
+
} else if (group.colSeparationType === "alignat" ||
|
|
584
|
+
group.colSeparationType === "gather") {
|
|
491
585
|
table.setAttribute("columnspacing", "0em");
|
|
492
586
|
} else if (group.colSeparationType === "small") {
|
|
493
587
|
table.setAttribute("columnspacing", "0.2778em");
|
|
588
|
+
} else if (group.colSeparationType === "CD") {
|
|
589
|
+
table.setAttribute("columnspacing", "0.5em");
|
|
494
590
|
} else {
|
|
495
591
|
table.setAttribute("columnspacing", "1em");
|
|
496
592
|
}
|
|
@@ -526,10 +622,25 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
|
526
622
|
return table;
|
|
527
623
|
};
|
|
528
624
|
|
|
529
|
-
// Convenience function for aligned
|
|
625
|
+
// Convenience function for align, align*, aligned, alignat, alignat*, alignedat.
|
|
530
626
|
const alignedHandler = function(context, args) {
|
|
627
|
+
if (context.envName.indexOf("ed") === -1) {
|
|
628
|
+
validateAmsEnvironmentContext(context);
|
|
629
|
+
}
|
|
531
630
|
const cols = [];
|
|
532
|
-
const
|
|
631
|
+
const separationType = context.envName.indexOf("at") > -1 ? "alignat" : "align";
|
|
632
|
+
const res = parseArray(context.parser,
|
|
633
|
+
{
|
|
634
|
+
cols,
|
|
635
|
+
addJot: true,
|
|
636
|
+
addEqnNum: context.envName === "align" || context.envName === "alignat",
|
|
637
|
+
emptySingleRow: true,
|
|
638
|
+
colSeparationType: separationType,
|
|
639
|
+
maxNumCols: context.envName === "split" ? 2 : undefined,
|
|
640
|
+
leqno: context.parser.settings.leqno,
|
|
641
|
+
},
|
|
642
|
+
"display"
|
|
643
|
+
);
|
|
533
644
|
|
|
534
645
|
// Determining number of columns.
|
|
535
646
|
// 1. If the first argument is given, we use it as a number of columns,
|
|
@@ -641,6 +752,7 @@ defineEnvironment({
|
|
|
641
752
|
const res = {
|
|
642
753
|
cols,
|
|
643
754
|
hskipBeforeAndAfter: true, // \@preamble in lttab.dtx
|
|
755
|
+
maxNumCols: cols.length,
|
|
644
756
|
};
|
|
645
757
|
return parseArray(context.parser, res, dCellStyle(context.envName));
|
|
646
758
|
},
|
|
@@ -650,6 +762,8 @@ defineEnvironment({
|
|
|
650
762
|
|
|
651
763
|
// The matrix environments of amsmath builds on the array environment
|
|
652
764
|
// of LaTeX, which is discussed above.
|
|
765
|
+
// The mathtools package adds starred versions of the same environments.
|
|
766
|
+
// These have an optional argument to choose left|center|right justification.
|
|
653
767
|
defineEnvironment({
|
|
654
768
|
type: "array",
|
|
655
769
|
names: [
|
|
@@ -659,6 +773,12 @@ defineEnvironment({
|
|
|
659
773
|
"Bmatrix",
|
|
660
774
|
"vmatrix",
|
|
661
775
|
"Vmatrix",
|
|
776
|
+
"matrix*",
|
|
777
|
+
"pmatrix*",
|
|
778
|
+
"bmatrix*",
|
|
779
|
+
"Bmatrix*",
|
|
780
|
+
"vmatrix*",
|
|
781
|
+
"Vmatrix*",
|
|
662
782
|
],
|
|
663
783
|
props: {
|
|
664
784
|
numArgs: 0,
|
|
@@ -671,11 +791,38 @@ defineEnvironment({
|
|
|
671
791
|
"Bmatrix": ["\\{", "\\}"],
|
|
672
792
|
"vmatrix": ["|", "|"],
|
|
673
793
|
"Vmatrix": ["\\Vert", "\\Vert"],
|
|
674
|
-
}[context.envName];
|
|
794
|
+
}[context.envName.replace("*", "")];
|
|
675
795
|
// \hskip -\arraycolsep in amsmath
|
|
676
|
-
|
|
796
|
+
let colAlign = "c";
|
|
797
|
+
const payload = {
|
|
798
|
+
hskipBeforeAndAfter: false,
|
|
799
|
+
cols: [{type: "align", align: colAlign}],
|
|
800
|
+
};
|
|
801
|
+
if (context.envName.charAt(context.envName.length - 1) === "*") {
|
|
802
|
+
// It's one of the mathtools starred functions.
|
|
803
|
+
// Parse the optional alignment argument.
|
|
804
|
+
const parser = context.parser;
|
|
805
|
+
parser.consumeSpaces();
|
|
806
|
+
if (parser.fetch().text === "[") {
|
|
807
|
+
parser.consume();
|
|
808
|
+
parser.consumeSpaces();
|
|
809
|
+
colAlign = parser.fetch().text;
|
|
810
|
+
if ("lcr".indexOf(colAlign) === -1) {
|
|
811
|
+
throw new ParseError("Expected l or c or r", parser.nextToken);
|
|
812
|
+
}
|
|
813
|
+
parser.consume();
|
|
814
|
+
parser.consumeSpaces();
|
|
815
|
+
parser.expect("]");
|
|
816
|
+
parser.consume();
|
|
817
|
+
payload.cols = [{type: "align", align: colAlign}];
|
|
818
|
+
}
|
|
819
|
+
}
|
|
677
820
|
const res: ParseNode<"array"> =
|
|
678
821
|
parseArray(context.parser, payload, dCellStyle(context.envName));
|
|
822
|
+
// Populate cols with the correct number of column alignment specs.
|
|
823
|
+
res.cols = new Array(res.body[0].length).fill(
|
|
824
|
+
{type: "align", align: colAlign}
|
|
825
|
+
);
|
|
679
826
|
return delimiters ? {
|
|
680
827
|
type: "leftright",
|
|
681
828
|
mode: context.mode,
|
|
@@ -797,13 +944,15 @@ defineEnvironment({
|
|
|
797
944
|
mathmlBuilder,
|
|
798
945
|
});
|
|
799
946
|
|
|
800
|
-
//
|
|
801
|
-
//
|
|
947
|
+
// In the align environment, one uses ampersands, &, to specify number of
|
|
948
|
+
// columns in each row, and to locate spacing between each column.
|
|
949
|
+
// align gets automatic numbering. align* and aligned do not.
|
|
950
|
+
// The alignedat environment can be used in math mode.
|
|
802
951
|
// Note that we assume \nomallineskiplimit to be zero,
|
|
803
952
|
// so that \strut@ is the same as \strut.
|
|
804
953
|
defineEnvironment({
|
|
805
954
|
type: "array",
|
|
806
|
-
names: ["aligned"],
|
|
955
|
+
names: ["align", "align*", "aligned", "split"],
|
|
807
956
|
props: {
|
|
808
957
|
numArgs: 0,
|
|
809
958
|
},
|
|
@@ -817,17 +966,24 @@ defineEnvironment({
|
|
|
817
966
|
// and contents are set in \displaystyle.
|
|
818
967
|
defineEnvironment({
|
|
819
968
|
type: "array",
|
|
820
|
-
names: ["gathered"],
|
|
969
|
+
names: ["gathered", "gather", "gather*"],
|
|
821
970
|
props: {
|
|
822
971
|
numArgs: 0,
|
|
823
972
|
},
|
|
824
973
|
handler(context) {
|
|
974
|
+
if (utils.contains(["gather", "gather*"], context.envName)) {
|
|
975
|
+
validateAmsEnvironmentContext(context);
|
|
976
|
+
}
|
|
825
977
|
const res = {
|
|
826
978
|
cols: [{
|
|
827
979
|
type: "align",
|
|
828
980
|
align: "c",
|
|
829
981
|
}],
|
|
830
982
|
addJot: true,
|
|
983
|
+
colSeparationType: "gather",
|
|
984
|
+
addEqnNum: context.envName === "gather",
|
|
985
|
+
emptySingleRow: true,
|
|
986
|
+
leqno: context.parser.settings.leqno,
|
|
831
987
|
};
|
|
832
988
|
return parseArray(context.parser, res, "display");
|
|
833
989
|
},
|
|
@@ -840,10 +996,7 @@ defineEnvironment({
|
|
|
840
996
|
// each columns.
|
|
841
997
|
defineEnvironment({
|
|
842
998
|
type: "array",
|
|
843
|
-
names: ["alignedat"],
|
|
844
|
-
// One for numbered and for unnumbered;
|
|
845
|
-
// but, KaTeX doesn't supports math numbering yet,
|
|
846
|
-
// they make no difference for now.
|
|
999
|
+
names: ["alignat", "alignat*", "alignedat"],
|
|
847
1000
|
props: {
|
|
848
1001
|
numArgs: 1,
|
|
849
1002
|
},
|
|
@@ -852,6 +1005,41 @@ defineEnvironment({
|
|
|
852
1005
|
mathmlBuilder,
|
|
853
1006
|
});
|
|
854
1007
|
|
|
1008
|
+
defineEnvironment({
|
|
1009
|
+
type: "array",
|
|
1010
|
+
names: ["equation", "equation*"],
|
|
1011
|
+
props: {
|
|
1012
|
+
numArgs: 0,
|
|
1013
|
+
},
|
|
1014
|
+
handler(context) {
|
|
1015
|
+
validateAmsEnvironmentContext(context);
|
|
1016
|
+
const res = {
|
|
1017
|
+
addEqnNum: context.envName === "equation",
|
|
1018
|
+
emptySingleRow: true,
|
|
1019
|
+
singleRow: true,
|
|
1020
|
+
maxNumCols: 1,
|
|
1021
|
+
leqno: context.parser.settings.leqno,
|
|
1022
|
+
};
|
|
1023
|
+
return parseArray(context.parser, res, "display");
|
|
1024
|
+
},
|
|
1025
|
+
htmlBuilder,
|
|
1026
|
+
mathmlBuilder,
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
defineEnvironment({
|
|
1030
|
+
type: "array",
|
|
1031
|
+
names: ["CD"],
|
|
1032
|
+
props: {
|
|
1033
|
+
numArgs: 0,
|
|
1034
|
+
},
|
|
1035
|
+
handler(context) {
|
|
1036
|
+
validateAmsEnvironmentContext(context);
|
|
1037
|
+
return parseCD(context.parser);
|
|
1038
|
+
},
|
|
1039
|
+
htmlBuilder,
|
|
1040
|
+
mathmlBuilder,
|
|
1041
|
+
});
|
|
1042
|
+
|
|
855
1043
|
// Catch \hline outside array environment
|
|
856
1044
|
defineFunction({
|
|
857
1045
|
type: "text", // Doesn't matter what this is.
|