katex 0.16.32 → 0.16.34
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 +3 -3
- package/contrib/auto-render/{auto-render.js → auto-render.ts} +41 -19
- package/contrib/auto-render/{splitAtDelimiters.js → splitAtDelimiters.ts} +18 -4
- package/contrib/auto-render/test/{auto-render-spec.js → auto-render-spec.ts} +10 -2
- package/contrib/copy-tex/README.md +2 -2
- package/contrib/copy-tex/{copy-tex.js → copy-tex.ts} +4 -6
- package/contrib/copy-tex/{katex2tex.js → katex2tex.ts} +2 -3
- package/contrib/mathtex-script-type/README.md +5 -5
- package/contrib/mhchem/README.md +1 -1
- package/contrib/render-a11y-string/{render-a11y-string.js → render-a11y-string.ts} +18 -33
- package/contrib/render-a11y-string/test/{render-a11y-string-spec.js → render-a11y-string-spec.ts} +0 -1
- package/dist/README.md +3 -3
- package/dist/contrib/auto-render.js +24 -57
- package/dist/contrib/auto-render.min.js +1 -1
- package/dist/contrib/auto-render.mjs +16586 -210
- package/dist/contrib/copy-tex.js +23 -37
- package/dist/contrib/copy-tex.min.js +1 -1
- package/dist/contrib/copy-tex.mjs +77 -95
- package/dist/contrib/mathtex-script-type.js +0 -3
- package/dist/contrib/mathtex-script-type.mjs +16427 -4
- package/dist/contrib/mhchem.js +55 -303
- package/dist/contrib/mhchem.mjs +12884 -723
- package/dist/contrib/render-a11y-string.js +13 -108
- package/dist/contrib/render-a11y-string.min.js +1 -1
- package/dist/contrib/render-a11y-string.mjs +17020 -760
- package/dist/katex-swap.css +2 -1
- package/dist/katex-swap.min.css +1 -1
- package/dist/katex.css +2 -1
- package/dist/katex.js +4547 -5680
- package/dist/katex.min.css +1 -1
- package/dist/katex.min.js +1 -1
- package/dist/katex.mjs +11854 -13828
- package/{katex.js → katex.ts} +8 -5
- package/package.json +34 -31
- package/src/{Lexer.js → Lexer.ts} +1 -2
- package/src/{MacroExpander.js → MacroExpander.ts} +11 -15
- package/src/{Namespace.js → Namespace.ts} +4 -6
- package/src/{Options.js → Options.ts} +7 -12
- package/src/{ParseError.js → ParseError.ts} +16 -26
- package/src/{Parser.js → Parser.ts} +68 -56
- package/src/{Settings.js → Settings.ts} +70 -70
- package/src/{SourceLocation.js → SourceLocation.ts} +6 -7
- package/src/{Style.js → Style.ts} +4 -5
- package/src/{Token.js → Token.ts} +8 -6
- package/src/{buildCommon.js → buildCommon.ts} +62 -55
- package/src/{buildHTML.js → buildHTML.ts} +29 -25
- package/src/{buildMathML.js → buildMathML.ts} +15 -13
- package/src/{buildTree.js → buildTree.ts} +1 -2
- package/src/{defineEnvironment.js → defineEnvironment.ts} +26 -27
- package/src/{defineFunction.js → defineFunction.ts} +54 -56
- package/src/{defineMacro.js → defineMacro.ts} +12 -13
- package/src/{delimiter.js → delimiter.ts} +19 -17
- package/src/{domTree.js → domTree.ts} +94 -103
- package/src/environments/{array.js → array.ts} +109 -99
- package/src/environments/{cd.js → cd.ts} +9 -11
- package/src/{environments.js → environments.ts} +0 -1
- package/src/{fontMetrics.js → fontMetrics.ts} +10 -12
- package/src/fontMetricsData.d.ts +3 -0
- package/src/functions/{accent.js → accent.ts} +1 -2
- package/src/functions/{accentunder.js → accentunder.ts} +0 -1
- package/src/functions/{arrow.js → arrow.ts} +4 -6
- package/src/functions/{char.js → char.ts} +0 -1
- package/src/functions/{color.js → color.ts} +5 -6
- package/src/functions/{cr.js → cr.ts} +0 -1
- package/src/functions/{def.js → def.ts} +9 -7
- package/src/functions/{delimsizing.js → delimsizing.ts} +11 -9
- package/src/functions/{enclose.js → enclose.ts} +3 -4
- package/src/functions/{environment.js → environment.ts} +2 -3
- package/src/functions/{font.js → font.ts} +4 -4
- package/src/functions/{genfrac.js → genfrac.ts} +14 -15
- package/src/functions/{hbox.js → hbox.ts} +0 -1
- package/src/functions/{horizBrace.js → horizBrace.ts} +4 -5
- package/src/functions/{href.js → href.ts} +4 -4
- package/src/functions/{html.js → html.ts} +3 -3
- package/src/functions/{htmlmathml.js → htmlmathml.ts} +0 -1
- package/src/functions/{includegraphics.js → includegraphics.ts} +0 -1
- package/src/functions/{kern.js → kern.ts} +0 -1
- package/src/functions/{lap.js → lap.ts} +0 -1
- package/src/functions/{math.js → math.ts} +0 -1
- package/src/functions/{mathchoice.js → mathchoice.ts} +2 -2
- package/src/functions/{mclass.js → mclass.ts} +5 -6
- package/src/functions/{op.js → op.ts} +9 -11
- package/src/functions/{operatorname.js → operatorname.ts} +4 -7
- package/src/functions/{ordgroup.js → ordgroup.ts} +0 -2
- package/src/functions/{overline.js → overline.ts} +0 -1
- package/src/functions/{phantom.js → phantom.ts} +0 -1
- package/src/functions/{pmb.js → pmb.ts} +0 -1
- package/src/functions/{raisebox.js → raisebox.ts} +0 -1
- package/src/functions/{relax.js → relax.ts} +0 -1
- package/src/functions/{rule.js → rule.ts} +0 -1
- package/src/functions/{sizing.js → sizing.ts} +0 -1
- package/src/functions/{smash.js → smash.ts} +2 -4
- package/src/functions/{sqrt.js → sqrt.ts} +0 -1
- package/src/functions/{styling.js → styling.ts} +3 -3
- package/src/functions/{supsub.js → supsub.ts} +6 -8
- package/src/functions/{symbolsOp.js → symbolsOp.ts} +0 -2
- package/src/functions/{symbolsOrd.js → symbolsOrd.ts} +1 -2
- package/src/functions/{symbolsSpacing.js → symbolsSpacing.ts} +2 -3
- package/src/functions/{tag.js → tag.ts} +0 -2
- package/src/functions/{text.js → text.ts} +7 -6
- package/src/functions/{underline.js → underline.ts} +0 -1
- package/src/functions/utils/{assembleSupSub.js → assembleSupSub.ts} +2 -3
- package/src/functions/{vcenter.js → vcenter.ts} +0 -2
- package/src/functions/{verb.js → verb.ts} +0 -1
- package/src/{functions.js → functions.ts} +0 -1
- package/src/{macros.js → macros.ts} +10 -8
- package/src/{mathMLTree.js → mathMLTree.ts} +5 -6
- package/src/parseNode.ts +522 -0
- package/src/{parseTree.js → parseTree.ts} +5 -3
- package/src/{spacingData.js → spacingData.ts} +11 -12
- package/src/{stretchy.js → stretchy.ts} +7 -7
- package/src/styles/katex-swap.scss +1 -4
- package/src/styles/katex.scss +9 -0
- package/src/{svgGeometry.js → svgGeometry.ts} +1 -2
- package/src/{symbols.js → symbols.ts} +6 -6
- package/src/{tree.js → tree.ts} +5 -7
- package/src/{types.js → types.ts} +1 -2
- package/src/unicodeAccents.js +4 -1
- package/src/{unicodeScripts.js → unicodeScripts.ts} +1 -3
- package/src/{unicodeSupOrSub.js → unicodeSupOrSub.ts} +1 -1
- package/src/unicodeSymbols.js +4 -3
- package/src/{units.js → units.ts} +2 -4
- package/src/{utils.js → utils.ts} +2 -3
- package/src/{wide-character.js → wide-character.ts} +8 -10
- package/types/katex.d.ts +13 -12
- package/src/parseNode.js +0 -523
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import {makeFragment, makeLineSpan, makeSpan, makeVList} from "../buildCommon";
|
|
3
2
|
import Style from "../Style";
|
|
4
3
|
import defineEnvironment from "../defineEnvironment";
|
|
@@ -17,15 +16,22 @@ import * as mml from "../buildMathML";
|
|
|
17
16
|
|
|
18
17
|
import type Parser from "../Parser";
|
|
19
18
|
import type {ParseNode, AnyParseNode} from "../parseNode";
|
|
20
|
-
import type {StyleStr} from "../types";
|
|
19
|
+
import type {StyleStr, Mode} from "../types";
|
|
21
20
|
import type {HtmlBuilder, MathMLBuilder} from "../defineFunction";
|
|
21
|
+
import type {HtmlDomNode} from "../domTree";
|
|
22
|
+
|
|
23
|
+
type EnvContextLike = {
|
|
24
|
+
parser: Parser;
|
|
25
|
+
envName: string;
|
|
26
|
+
mode: Mode;
|
|
27
|
+
};
|
|
22
28
|
|
|
23
29
|
// Data stored in the ParseNode associated with the environment.
|
|
24
|
-
export type AlignSpec = {
|
|
25
|
-
type: "align"
|
|
26
|
-
align: string
|
|
27
|
-
pregap?: number
|
|
28
|
-
postgap?: number
|
|
30
|
+
export type AlignSpec = {type: "separator", separator: string} | {
|
|
31
|
+
type: "align";
|
|
32
|
+
align: string;
|
|
33
|
+
pregap?: number;
|
|
34
|
+
postgap?: number;
|
|
29
35
|
};
|
|
30
36
|
|
|
31
37
|
// Type to indicate column separation in MathML
|
|
@@ -52,7 +58,7 @@ function getHLines(parser: Parser): boolean[] {
|
|
|
52
58
|
return hlineInfo;
|
|
53
59
|
}
|
|
54
60
|
|
|
55
|
-
const validateAmsEnvironmentContext = context => {
|
|
61
|
+
const validateAmsEnvironmentContext = (context: EnvContextLike) => {
|
|
56
62
|
const settings = context.parser.settings;
|
|
57
63
|
if (!settings.displayMode) {
|
|
58
64
|
throw new ParseError(`{${context.envName}} can be used only in` +
|
|
@@ -67,7 +73,7 @@ const gatherEnvironments = new Set(["gather", "gather*"]);
|
|
|
67
73
|
// * true: Automatic equation numbering, overridable by \tag
|
|
68
74
|
// * false: Tags allowed on each row, but no automatic numbering
|
|
69
75
|
// This function *doesn't* work with the "split" environment name.
|
|
70
|
-
function getAutoTag(name):
|
|
76
|
+
function getAutoTag(name: string): boolean | null | undefined {
|
|
71
77
|
if (!name.includes("ed")) {
|
|
72
78
|
return !name.includes("*");
|
|
73
79
|
}
|
|
@@ -93,18 +99,18 @@ function parseArray(
|
|
|
93
99
|
emptySingleRow,
|
|
94
100
|
maxNumCols,
|
|
95
101
|
leqno,
|
|
96
|
-
}: {
|
|
97
|
-
hskipBeforeAndAfter?: boolean
|
|
98
|
-
addJot?: boolean
|
|
99
|
-
cols?: AlignSpec[]
|
|
100
|
-
arraystretch?: number
|
|
101
|
-
colSeparationType?: ColSeparationType
|
|
102
|
-
autoTag?:
|
|
103
|
-
singleRow?: boolean
|
|
104
|
-
emptySingleRow?: boolean
|
|
105
|
-
maxNumCols?: number
|
|
106
|
-
leqno?: boolean
|
|
107
|
-
|
|
102
|
+
}: {
|
|
103
|
+
hskipBeforeAndAfter?: boolean;
|
|
104
|
+
addJot?: boolean;
|
|
105
|
+
cols?: AlignSpec[];
|
|
106
|
+
arraystretch?: number;
|
|
107
|
+
colSeparationType?: ColSeparationType;
|
|
108
|
+
autoTag?: boolean | null | undefined;
|
|
109
|
+
singleRow?: boolean;
|
|
110
|
+
emptySingleRow?: boolean;
|
|
111
|
+
maxNumCols?: number;
|
|
112
|
+
leqno?: boolean;
|
|
113
|
+
},
|
|
108
114
|
style: StyleStr,
|
|
109
115
|
): ParseNode<"array"> {
|
|
110
116
|
parser.gullet.beginGroup();
|
|
@@ -131,12 +137,12 @@ function parseArray(
|
|
|
131
137
|
// Start group for first cell
|
|
132
138
|
parser.gullet.beginGroup();
|
|
133
139
|
|
|
134
|
-
let row = [];
|
|
135
|
-
const body = [row];
|
|
140
|
+
let row: AnyParseNode[] = [];
|
|
141
|
+
const body: AnyParseNode[][] = [row];
|
|
136
142
|
const rowGaps = [];
|
|
137
143
|
const hLinesBeforeRow = [];
|
|
138
|
-
|
|
139
|
-
|
|
144
|
+
const tags: Array<AnyParseNode[] | boolean> | undefined =
|
|
145
|
+
(autoTag != null ? [] : undefined);
|
|
140
146
|
|
|
141
147
|
// amsmath uses \global\@eqnswtrue and \global\@eqnswfalse to represent
|
|
142
148
|
// whether this row should have an equation number. Simulate this with
|
|
@@ -164,14 +170,13 @@ function parseArray(
|
|
|
164
170
|
|
|
165
171
|
while (true) { // eslint-disable-line no-constant-condition
|
|
166
172
|
// Parse each cell in its own group (namespace)
|
|
167
|
-
|
|
173
|
+
const cellBody = parser.parseExpression(false, singleRow ? "\\end" : "\\\\");
|
|
168
174
|
parser.gullet.endGroup();
|
|
169
175
|
parser.gullet.beginGroup();
|
|
170
|
-
|
|
171
|
-
cell = {
|
|
176
|
+
let cell: AnyParseNode = {
|
|
172
177
|
type: "ordgroup",
|
|
173
178
|
mode: parser.mode,
|
|
174
|
-
body:
|
|
179
|
+
body: cellBody,
|
|
175
180
|
};
|
|
176
181
|
if (style) {
|
|
177
182
|
cell = {
|
|
@@ -203,6 +208,7 @@ function parseArray(
|
|
|
203
208
|
// empty row if it's the only one.
|
|
204
209
|
// NOTE: Currently, `cell` is the last item added into `row`.
|
|
205
210
|
if (row.length === 1 && cell.type === "styling" &&
|
|
211
|
+
cell.body.length === 1 && cell.body[0].type === "ordgroup" &&
|
|
206
212
|
cell.body[0].body.length === 0 &&
|
|
207
213
|
(body.length > 1 || !emptySingleRow)) {
|
|
208
214
|
body.pop();
|
|
@@ -258,10 +264,9 @@ function parseArray(
|
|
|
258
264
|
};
|
|
259
265
|
}
|
|
260
266
|
|
|
261
|
-
|
|
262
267
|
// Decides on a style for cells in an array according to whether the given
|
|
263
268
|
// environment name starts with the letter 'd'.
|
|
264
|
-
function dCellStyle(envName): StyleStr {
|
|
269
|
+
function dCellStyle(envName: string): StyleStr {
|
|
265
270
|
if (envName.slice(0, 1) === "d") {
|
|
266
271
|
return "display";
|
|
267
272
|
} else {
|
|
@@ -270,10 +275,10 @@ function dCellStyle(envName): StyleStr {
|
|
|
270
275
|
}
|
|
271
276
|
|
|
272
277
|
type Outrow = {
|
|
273
|
-
[idx: number]:
|
|
274
|
-
height: number
|
|
275
|
-
depth: number
|
|
276
|
-
pos: number
|
|
278
|
+
[idx: number]: any;
|
|
279
|
+
height: number;
|
|
280
|
+
depth: number;
|
|
281
|
+
pos: number;
|
|
277
282
|
};
|
|
278
283
|
|
|
279
284
|
const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
@@ -282,13 +287,12 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
282
287
|
const nr = group.body.length;
|
|
283
288
|
const hLinesBeforeRow = group.hLinesBeforeRow;
|
|
284
289
|
let nc = 0;
|
|
285
|
-
|
|
286
|
-
const hlines = [];
|
|
287
|
-
|
|
290
|
+
const body = new Array(nr);
|
|
291
|
+
const hlines: Array<{pos: number; isDashed: boolean}> = [];
|
|
288
292
|
const ruleThickness = Math.max(
|
|
289
293
|
// From LaTeX \showthe\arrayrulewidth. Equals 0.04 em.
|
|
290
|
-
|
|
291
|
-
options.minRuleThickness,
|
|
294
|
+
options.fontMetrics().arrayRuleWidth,
|
|
295
|
+
options.minRuleThickness, // User override.
|
|
292
296
|
);
|
|
293
297
|
|
|
294
298
|
// Horizontal spacing
|
|
@@ -306,8 +310,8 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
306
310
|
|
|
307
311
|
// Vertical spacing
|
|
308
312
|
const baselineskip = group.colSeparationType === "CD"
|
|
309
|
-
|
|
310
|
-
|
|
313
|
+
? calculateSize({number: 3, unit: "ex"}, options)
|
|
314
|
+
: 12 * pt; // see size10.clo
|
|
311
315
|
// Default \jot from ltmath.dtx
|
|
312
316
|
// TODO(edemaine): allow overriding \jot via \setlength (#687)
|
|
313
317
|
const jot = 3 * pt;
|
|
@@ -337,7 +341,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
337
341
|
nc = inrow.length;
|
|
338
342
|
}
|
|
339
343
|
|
|
340
|
-
const outrow: Outrow = (new Array(inrow.length)
|
|
344
|
+
const outrow: Outrow = (new Array(inrow.length) as any);
|
|
341
345
|
for (c = 0; c < inrow.length; ++c) {
|
|
342
346
|
const elt = html.buildGroup(inrow[c], options);
|
|
343
347
|
if (depth < elt.depth) {
|
|
@@ -381,12 +385,16 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
381
385
|
|
|
382
386
|
const offset = totalHeight / 2 + options.fontMetrics().axisHeight;
|
|
383
387
|
const colDescriptions = group.cols || [];
|
|
384
|
-
const cols = [];
|
|
388
|
+
const cols: HtmlDomNode[] = [];
|
|
385
389
|
let colSep;
|
|
386
390
|
let colDescrNum;
|
|
391
|
+
const tagSpans: Array<{
|
|
392
|
+
type: "elem";
|
|
393
|
+
elem: HtmlDomNode;
|
|
394
|
+
shift: number;
|
|
395
|
+
}> = [];
|
|
387
396
|
|
|
388
|
-
|
|
389
|
-
if (group.tags && group.tags.some((tag) => tag)) {
|
|
397
|
+
if (group.tags && group.tags.some(tag => tag)) {
|
|
390
398
|
// An environment with manual tags and/or automatic equation numbers.
|
|
391
399
|
// Create node(s), the latter of which trigger CSS counter increment.
|
|
392
400
|
for (r = 0; r < nr; ++r) {
|
|
@@ -414,11 +422,10 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
414
422
|
// descriptions, so trailing separators don't get lost.
|
|
415
423
|
c < nc || colDescrNum < colDescriptions.length;
|
|
416
424
|
++c, ++colDescrNum) {
|
|
417
|
-
|
|
418
|
-
let colDescr = colDescriptions[colDescrNum] || {};
|
|
425
|
+
let colDescr: AlignSpec | undefined = colDescriptions[colDescrNum];
|
|
419
426
|
|
|
420
427
|
let firstSeparator = true;
|
|
421
|
-
while (colDescr
|
|
428
|
+
while (colDescr?.type === "separator") {
|
|
422
429
|
// If there is more than one separator in a row, add a space
|
|
423
430
|
// between them.
|
|
424
431
|
if (!firstSeparator) {
|
|
@@ -429,10 +436,8 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
429
436
|
}
|
|
430
437
|
|
|
431
438
|
if (colDescr.separator === "|" || colDescr.separator === ":") {
|
|
432
|
-
const lineType =
|
|
433
|
-
const separator = makeSpan(
|
|
434
|
-
["vertical-separator"], [], options
|
|
435
|
-
);
|
|
439
|
+
const lineType = colDescr.separator === "|" ? "solid" : "dashed";
|
|
440
|
+
const separator = makeSpan(["vertical-separator"], [], options);
|
|
436
441
|
separator.style.height = makeEm(totalHeight);
|
|
437
442
|
separator.style.borderRightWidth = makeEm(ruleThickness);
|
|
438
443
|
separator.style.borderRightStyle = lineType;
|
|
@@ -449,7 +454,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
449
454
|
}
|
|
450
455
|
|
|
451
456
|
colDescrNum++;
|
|
452
|
-
colDescr = colDescriptions[colDescrNum]
|
|
457
|
+
colDescr = colDescriptions[colDescrNum];
|
|
453
458
|
firstSeparator = false;
|
|
454
459
|
}
|
|
455
460
|
|
|
@@ -459,7 +464,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
459
464
|
|
|
460
465
|
let sepwidth;
|
|
461
466
|
if (c > 0 || group.hskipBeforeAndAfter) {
|
|
462
|
-
sepwidth = colDescr
|
|
467
|
+
sepwidth = colDescr?.pregap ?? arraycolsep;
|
|
463
468
|
if (sepwidth !== 0) {
|
|
464
469
|
colSep = makeSpan(["arraycolsep"], []);
|
|
465
470
|
colSep.style.width = makeEm(sepwidth);
|
|
@@ -467,7 +472,11 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
467
472
|
}
|
|
468
473
|
}
|
|
469
474
|
|
|
470
|
-
|
|
475
|
+
const colElems: Array<{
|
|
476
|
+
type: "elem";
|
|
477
|
+
elem: HtmlDomNode;
|
|
478
|
+
shift: number;
|
|
479
|
+
}> = [];
|
|
471
480
|
for (r = 0; r < nr; ++r) {
|
|
472
481
|
const row = body[r];
|
|
473
482
|
const elem = row[c];
|
|
@@ -477,20 +486,21 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
477
486
|
const shift = row.pos - offset;
|
|
478
487
|
elem.depth = row.depth;
|
|
479
488
|
elem.height = row.height;
|
|
480
|
-
|
|
489
|
+
colElems.push({type: "elem", elem: elem, shift: shift});
|
|
481
490
|
}
|
|
482
491
|
|
|
483
|
-
|
|
492
|
+
const colVList = makeVList({
|
|
484
493
|
positionType: "individualShift",
|
|
485
|
-
children:
|
|
494
|
+
children: colElems,
|
|
486
495
|
}, options);
|
|
487
|
-
|
|
488
|
-
["col-align-" + (colDescr
|
|
489
|
-
[
|
|
490
|
-
|
|
496
|
+
const colSpan = makeSpan(
|
|
497
|
+
["col-align-" + (colDescr?.align || "c")],
|
|
498
|
+
[colVList],
|
|
499
|
+
);
|
|
500
|
+
cols.push(colSpan);
|
|
491
501
|
|
|
492
502
|
if (c < nc - 1 || group.hskipBeforeAndAfter) {
|
|
493
|
-
sepwidth = colDescr
|
|
503
|
+
sepwidth = colDescr?.postgap ?? arraycolsep;
|
|
494
504
|
if (sepwidth !== 0) {
|
|
495
505
|
colSep = makeSpan(["arraycolsep"], []);
|
|
496
506
|
colSep.style.width = makeEm(sepwidth);
|
|
@@ -498,42 +508,43 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
498
508
|
}
|
|
499
509
|
}
|
|
500
510
|
}
|
|
501
|
-
|
|
511
|
+
|
|
512
|
+
let tableBody: HtmlDomNode = makeSpan(["mtable"], cols);
|
|
502
513
|
|
|
503
514
|
// Add \hline(s), if any.
|
|
504
515
|
if (hlines.length > 0) {
|
|
505
516
|
const line = makeLineSpan("hline", options, ruleThickness);
|
|
506
|
-
const dashes = makeLineSpan("hdashline", options,
|
|
507
|
-
|
|
508
|
-
const vListElems = [{type: "elem", elem: body, shift: 0}];
|
|
517
|
+
const dashes = makeLineSpan("hdashline", options, ruleThickness);
|
|
518
|
+
const vListElems = [{type: "elem" as const, elem: tableBody, shift: 0}];
|
|
509
519
|
while (hlines.length > 0) {
|
|
510
|
-
const hline = hlines.pop()
|
|
520
|
+
const hline = hlines.pop()!;
|
|
511
521
|
const lineShift = hline.pos - offset;
|
|
512
522
|
if (hline.isDashed) {
|
|
513
|
-
vListElems.push({type: "elem", elem: dashes, shift: lineShift});
|
|
523
|
+
vListElems.push({type: "elem" as const, elem: dashes, shift: lineShift});
|
|
514
524
|
} else {
|
|
515
|
-
vListElems.push({type: "elem", elem: line, shift: lineShift});
|
|
525
|
+
vListElems.push({type: "elem" as const, elem: line, shift: lineShift});
|
|
516
526
|
}
|
|
517
527
|
}
|
|
518
|
-
|
|
528
|
+
|
|
529
|
+
tableBody = makeVList({
|
|
519
530
|
positionType: "individualShift",
|
|
520
531
|
children: vListElems,
|
|
521
532
|
}, options);
|
|
522
533
|
}
|
|
523
534
|
|
|
524
535
|
if (tagSpans.length === 0) {
|
|
525
|
-
return makeSpan(["mord"], [
|
|
536
|
+
return makeSpan(["mord"], [tableBody], options);
|
|
526
537
|
} else {
|
|
527
|
-
|
|
538
|
+
const eqnNumCol = makeVList({
|
|
528
539
|
positionType: "individualShift",
|
|
529
540
|
children: tagSpans,
|
|
530
541
|
}, options);
|
|
531
|
-
|
|
532
|
-
return makeFragment([
|
|
542
|
+
const tagCol = makeSpan(["tag"], [eqnNumCol], options);
|
|
543
|
+
return makeFragment([tableBody, tagCol]);
|
|
533
544
|
}
|
|
534
545
|
};
|
|
535
546
|
|
|
536
|
-
const alignMap = {
|
|
547
|
+
const alignMap: Record<string, string> = {
|
|
537
548
|
c: "center ",
|
|
538
549
|
l: "left ",
|
|
539
550
|
r: "right ",
|
|
@@ -604,20 +615,19 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
|
604
615
|
}
|
|
605
616
|
|
|
606
617
|
for (let i = iStart; i < iEnd; i++) {
|
|
607
|
-
|
|
608
|
-
|
|
618
|
+
const col = cols[i];
|
|
619
|
+
if (col.type === "align") {
|
|
620
|
+
align += alignMap[col.align];
|
|
609
621
|
|
|
610
622
|
if (prevTypeWasAlign) {
|
|
611
623
|
columnLines += "none ";
|
|
612
624
|
}
|
|
613
625
|
prevTypeWasAlign = true;
|
|
614
|
-
} else if (
|
|
626
|
+
} else if (col.type === "separator") {
|
|
615
627
|
// MathML accepts only single lines between cells.
|
|
616
628
|
// So we read only the first of consecutive separators.
|
|
617
629
|
if (prevTypeWasAlign) {
|
|
618
|
-
columnLines +=
|
|
619
|
-
? "solid "
|
|
620
|
-
: "dashed ";
|
|
630
|
+
columnLines += col.separator === "|" ? "solid " : "dashed ";
|
|
621
631
|
prevTypeWasAlign = false;
|
|
622
632
|
}
|
|
623
633
|
}
|
|
@@ -681,12 +691,12 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
|
681
691
|
};
|
|
682
692
|
|
|
683
693
|
// Convenience function for align, align*, aligned, alignat, alignat*, alignedat.
|
|
684
|
-
const alignedHandler = function(context, args) {
|
|
694
|
+
const alignedHandler = function(context: EnvContextLike, args: AnyParseNode[]) {
|
|
685
695
|
if (!context.envName.includes("ed")) {
|
|
686
696
|
validateAmsEnvironmentContext(context);
|
|
687
697
|
}
|
|
688
|
-
const cols = [];
|
|
689
|
-
const separationType = context.envName.includes("at") ? "alignat" : "align";
|
|
698
|
+
const cols: AlignSpec[] = [];
|
|
699
|
+
const separationType: ColSeparationType = context.envName.includes("at") ? "alignat" : "align";
|
|
690
700
|
const isSplit = context.envName === "split";
|
|
691
701
|
const res = parseArray(context.parser,
|
|
692
702
|
{
|
|
@@ -710,9 +720,9 @@ const alignedHandler = function(context, args) {
|
|
|
710
720
|
// At the same time, prepend empty group {} at beginning of every second
|
|
711
721
|
// cell in each row (starting with second cell) so that operators become
|
|
712
722
|
// binary. This behavior is implemented in amsmath's \start@aligned.
|
|
713
|
-
let numMaths;
|
|
723
|
+
let numMaths = 0;
|
|
714
724
|
let numCols = 0;
|
|
715
|
-
const emptyGroup = {
|
|
725
|
+
const emptyGroup: ParseNode<"ordgroup"> = {
|
|
716
726
|
type: "ordgroup",
|
|
717
727
|
mode: context.mode,
|
|
718
728
|
body: [],
|
|
@@ -787,7 +797,7 @@ defineEnvironment({
|
|
|
787
797
|
const symNode = checkSymbolNodeType(args[0]);
|
|
788
798
|
const colalign: AnyParseNode[] =
|
|
789
799
|
symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body;
|
|
790
|
-
const cols = colalign.map(function(nde) {
|
|
800
|
+
const cols: AlignSpec[] = colalign.map(function(nde) {
|
|
791
801
|
const node = assertSymbolNodeType(nde);
|
|
792
802
|
const ca = node.text;
|
|
793
803
|
if ("lcr".includes(ca)) {
|
|
@@ -808,7 +818,7 @@ defineEnvironment({
|
|
|
808
818
|
}
|
|
809
819
|
throw new ParseError("Unknown column alignment: " + ca, nde);
|
|
810
820
|
});
|
|
811
|
-
const res = {
|
|
821
|
+
const res: Parameters<typeof parseArray>[1] = {
|
|
812
822
|
cols,
|
|
813
823
|
hskipBeforeAndAfter: true, // \@preamble in lttab.dtx
|
|
814
824
|
maxNumCols: cols.length,
|
|
@@ -853,7 +863,7 @@ defineEnvironment({
|
|
|
853
863
|
}[context.envName.replace("*", "")];
|
|
854
864
|
// \hskip -\arraycolsep in amsmath
|
|
855
865
|
let colAlign = "c";
|
|
856
|
-
const payload = {
|
|
866
|
+
const payload: Parameters<typeof parseArray>[1] = {
|
|
857
867
|
hskipBeforeAndAfter: false,
|
|
858
868
|
cols: [{type: "align", align: colAlign}],
|
|
859
869
|
};
|
|
@@ -879,7 +889,7 @@ defineEnvironment({
|
|
|
879
889
|
const res: ParseNode<"array"> =
|
|
880
890
|
parseArray(context.parser, payload, dCellStyle(context.envName));
|
|
881
891
|
// Populate cols with the correct number of column alignment specs.
|
|
882
|
-
const numCols = Math.max(0, ...res.body.map(
|
|
892
|
+
const numCols = Math.max(0, ...res.body.map(row => row.length));
|
|
883
893
|
res.cols = new Array(numCols).fill(
|
|
884
894
|
{type: "align", align: colAlign}
|
|
885
895
|
);
|
|
@@ -903,7 +913,7 @@ defineEnvironment({
|
|
|
903
913
|
numArgs: 0,
|
|
904
914
|
},
|
|
905
915
|
handler(context) {
|
|
906
|
-
const payload = {arraystretch: 0.5};
|
|
916
|
+
const payload: Parameters<typeof parseArray>[1] = {arraystretch: 0.5};
|
|
907
917
|
const res = parseArray(context.parser, payload, "script");
|
|
908
918
|
res.colSeparationType = "small";
|
|
909
919
|
return res;
|
|
@@ -923,7 +933,7 @@ defineEnvironment({
|
|
|
923
933
|
const symNode = checkSymbolNodeType(args[0]);
|
|
924
934
|
const colalign: AnyParseNode[] =
|
|
925
935
|
symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body;
|
|
926
|
-
const cols = colalign.map(function(nde) {
|
|
936
|
+
const cols: AlignSpec[] = colalign.map(function(nde) {
|
|
927
937
|
const node = assertSymbolNodeType(nde);
|
|
928
938
|
const ca = node.text;
|
|
929
939
|
// {subarray} only recognizes "l" & "c"
|
|
@@ -938,12 +948,12 @@ defineEnvironment({
|
|
|
938
948
|
if (cols.length > 1) {
|
|
939
949
|
throw new ParseError("{subarray} can contain only one column");
|
|
940
950
|
}
|
|
941
|
-
|
|
951
|
+
const payload: Parameters<typeof parseArray>[1] = {
|
|
942
952
|
cols,
|
|
943
953
|
hskipBeforeAndAfter: false,
|
|
944
954
|
arraystretch: 0.5,
|
|
945
955
|
};
|
|
946
|
-
res = parseArray(context.parser,
|
|
956
|
+
const res = parseArray(context.parser, payload, "script");
|
|
947
957
|
if (res.body.length > 0 && res.body[0].length > 1) {
|
|
948
958
|
throw new ParseError("{subarray} can contain only one column");
|
|
949
959
|
}
|
|
@@ -971,7 +981,7 @@ defineEnvironment({
|
|
|
971
981
|
numArgs: 0,
|
|
972
982
|
},
|
|
973
983
|
handler(context) {
|
|
974
|
-
const payload = {
|
|
984
|
+
const payload: Parameters<typeof parseArray>[1] = {
|
|
975
985
|
arraystretch: 1.2,
|
|
976
986
|
cols: [{
|
|
977
987
|
type: "align",
|
|
@@ -1034,7 +1044,7 @@ defineEnvironment({
|
|
|
1034
1044
|
if (gatherEnvironments.has(context.envName)) {
|
|
1035
1045
|
validateAmsEnvironmentContext(context);
|
|
1036
1046
|
}
|
|
1037
|
-
const res = {
|
|
1047
|
+
const res: Parameters<typeof parseArray>[1] = {
|
|
1038
1048
|
cols: [{
|
|
1039
1049
|
type: "align",
|
|
1040
1050
|
align: "c",
|
|
@@ -1073,7 +1083,7 @@ defineEnvironment({
|
|
|
1073
1083
|
},
|
|
1074
1084
|
handler(context) {
|
|
1075
1085
|
validateAmsEnvironmentContext(context);
|
|
1076
|
-
const res = {
|
|
1086
|
+
const res: Parameters<typeof parseArray>[1] = {
|
|
1077
1087
|
autoTag: getAutoTag(context.envName),
|
|
1078
1088
|
emptySingleRow: true,
|
|
1079
1089
|
singleRow: true,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import {wrapFragment} from "../buildCommon";
|
|
3
2
|
import defineFunction from "../defineFunction";
|
|
4
3
|
import {MathNode} from "../mathMLTree";
|
|
@@ -11,7 +10,7 @@ import {makeEm} from "../units";
|
|
|
11
10
|
import type Parser from "../Parser";
|
|
12
11
|
import type {ParseNode, AnyParseNode} from "../parseNode";
|
|
13
12
|
|
|
14
|
-
const cdArrowFunctionName = {
|
|
13
|
+
const cdArrowFunctionName: Record<string, string> = {
|
|
15
14
|
">": "\\\\cdrightarrow",
|
|
16
15
|
"<": "\\\\cdleftarrow",
|
|
17
16
|
"=": "\\\\cdlongequal",
|
|
@@ -21,12 +20,11 @@ const cdArrowFunctionName = {
|
|
|
21
20
|
".": "no arrow",
|
|
22
21
|
};
|
|
23
22
|
|
|
24
|
-
const newCell = () => {
|
|
23
|
+
const newCell = (): ParseNode<"styling"> => {
|
|
25
24
|
// Create an empty cell, to be filled below with parse nodes.
|
|
26
25
|
// The parseTree from this module must be constructed like the
|
|
27
26
|
// one created by parseArray(), so an empty CD cell must
|
|
28
27
|
// be a ParseNode<"styling">. And CD is always displaystyle.
|
|
29
|
-
// So these values are fixed and flow can do implicit typing.
|
|
30
28
|
return {type: "styling", body: [], mode: "math", style: "display"};
|
|
31
29
|
};
|
|
32
30
|
|
|
@@ -58,7 +56,7 @@ function cdArrow(
|
|
|
58
56
|
const leftLabel = parser.callFunction(
|
|
59
57
|
"\\\\cdleft", [labels[0]], []
|
|
60
58
|
);
|
|
61
|
-
const bareArrow = {
|
|
59
|
+
const bareArrow: ParseNode<"atom"> = {
|
|
62
60
|
type: "atom",
|
|
63
61
|
text: funcName,
|
|
64
62
|
mode: "math",
|
|
@@ -68,7 +66,7 @@ function cdArrow(
|
|
|
68
66
|
const rightLabel = parser.callFunction(
|
|
69
67
|
"\\\\cdright", [labels[1]], []
|
|
70
68
|
);
|
|
71
|
-
const arrowGroup = {
|
|
69
|
+
const arrowGroup: ParseNode<"ordgroup"> = {
|
|
72
70
|
type: "ordgroup",
|
|
73
71
|
mode: "math",
|
|
74
72
|
body: [leftLabel, sizedArrow, rightLabel],
|
|
@@ -78,7 +76,7 @@ function cdArrow(
|
|
|
78
76
|
case "\\\\cdlongequal":
|
|
79
77
|
return parser.callFunction("\\\\cdlongequal", [], []);
|
|
80
78
|
case "\\Vert": {
|
|
81
|
-
const arrow = {type: "textord", text: "\\Vert", mode: "math"};
|
|
79
|
+
const arrow: ParseNode<"textord"> = {type: "textord", text: "\\Vert", mode: "math"};
|
|
82
80
|
return parser.callFunction("\\Big", [arrow], []);
|
|
83
81
|
}
|
|
84
82
|
default:
|
|
@@ -111,8 +109,8 @@ export function parseCD(parser: Parser): ParseNode<"array"> {
|
|
|
111
109
|
}
|
|
112
110
|
}
|
|
113
111
|
|
|
114
|
-
let row = [];
|
|
115
|
-
const body = [row];
|
|
112
|
+
let row: ParseNode<"styling">[] = [];
|
|
113
|
+
const body: ParseNode<"styling">[][] = [row];
|
|
116
114
|
|
|
117
115
|
// Loop thru the parse nodes. Collect them into cells and arrows.
|
|
118
116
|
for (let i = 0; i < parsedRows.length; i++) {
|
|
@@ -180,7 +178,7 @@ export function parseCD(parser: Parser): ParseNode<"array"> {
|
|
|
180
178
|
|
|
181
179
|
// Wrap the arrow in ParseNode<"styling">.
|
|
182
180
|
// This is done to match parseArray() behavior.
|
|
183
|
-
const wrappedArrow = {
|
|
181
|
+
const wrappedArrow: ParseNode<"styling"> = {
|
|
184
182
|
type: "styling",
|
|
185
183
|
body: [arrow],
|
|
186
184
|
mode: "math",
|
|
@@ -308,6 +306,6 @@ defineFunction({
|
|
|
308
306
|
},
|
|
309
307
|
mathmlBuilder(group, options) {
|
|
310
308
|
return new MathNode("mrow",
|
|
311
|
-
|
|
309
|
+
[mml.buildGroup(group.fragment, options)]);
|
|
312
310
|
},
|
|
313
311
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import {supportedCodepoint} from "./unicodeScripts";
|
|
3
2
|
|
|
4
3
|
import type {Mode} from "./types";
|
|
@@ -33,7 +32,7 @@ import type {Mode} from "./types";
|
|
|
33
32
|
//
|
|
34
33
|
// The output of each of these commands is quite lengthy. The only part we
|
|
35
34
|
// care about is the FONTDIMEN section. Each value is measured in EMs.
|
|
36
|
-
const sigmasAndXis = {
|
|
35
|
+
const sigmasAndXis: Record<string, [number, number, number]> = {
|
|
37
36
|
slant: [0.250, 0.250, 0.250], // sigma1
|
|
38
37
|
space: [0.000, 0.000, 0.000], // sigma2
|
|
39
38
|
stretch: [0.000, 0.000, 0.000], // sigma3
|
|
@@ -105,7 +104,7 @@ import metricMap from "./fontMetricsData";
|
|
|
105
104
|
// descenders we prefer approximations with ascenders, primarily to prevent
|
|
106
105
|
// the fraction bar or root line from intersecting the glyph.
|
|
107
106
|
// TODO(kevinb) allow union of multiple glyph metrics for better accuracy.
|
|
108
|
-
const extraCharacterMap = {
|
|
107
|
+
const extraCharacterMap: Record<string, string> = {
|
|
109
108
|
// Latin-1
|
|
110
109
|
'Å': 'A',
|
|
111
110
|
'Ð': 'D',
|
|
@@ -190,8 +189,8 @@ export type CharacterMetrics = {
|
|
|
190
189
|
};
|
|
191
190
|
|
|
192
191
|
export type MetricMap = {
|
|
193
|
-
[string]: number
|
|
194
|
-
}
|
|
192
|
+
[key: string]: [number, number, number, number, number];
|
|
193
|
+
};
|
|
195
194
|
|
|
196
195
|
/**
|
|
197
196
|
* This function adds new font metrics to default metricMap
|
|
@@ -212,7 +211,7 @@ export function getCharacterMetrics(
|
|
|
212
211
|
character: string,
|
|
213
212
|
font: string,
|
|
214
213
|
mode: Mode,
|
|
215
|
-
):
|
|
214
|
+
): CharacterMetrics | null | undefined {
|
|
216
215
|
if (!metricMap[font]) {
|
|
217
216
|
throw new Error(`Font metrics not found for font: ${font}.`);
|
|
218
217
|
}
|
|
@@ -250,11 +249,10 @@ export function getCharacterMetrics(
|
|
|
250
249
|
|
|
251
250
|
type FontSizeIndex = 0 | 1 | 2;
|
|
252
251
|
export type FontMetrics = {
|
|
253
|
-
cssEmPerMu: number
|
|
254
|
-
[string]: number
|
|
252
|
+
cssEmPerMu: number;
|
|
253
|
+
[key: string]: number;
|
|
255
254
|
};
|
|
256
|
-
|
|
257
|
-
const fontMetricsBySizeIndex: {[FontSizeIndex]: FontMetrics} = {};
|
|
255
|
+
const fontMetricsBySizeIndex: Partial<Record<FontSizeIndex, FontMetrics>> = {};
|
|
258
256
|
|
|
259
257
|
/**
|
|
260
258
|
* Get the font metrics for a given size.
|
|
@@ -269,7 +267,7 @@ export function getGlobalMetrics(size: number): FontMetrics {
|
|
|
269
267
|
sizeIndex = 2;
|
|
270
268
|
}
|
|
271
269
|
if (!fontMetricsBySizeIndex[sizeIndex]) {
|
|
272
|
-
const metrics = fontMetricsBySizeIndex[sizeIndex] = {
|
|
270
|
+
const metrics: FontMetrics = fontMetricsBySizeIndex[sizeIndex] = {
|
|
273
271
|
cssEmPerMu: sigmasAndXis.quad[sizeIndex] / 18,
|
|
274
272
|
};
|
|
275
273
|
for (const key in sigmasAndXis) {
|
|
@@ -278,5 +276,5 @@ export function getGlobalMetrics(size: number): FontMetrics {
|
|
|
278
276
|
}
|
|
279
277
|
}
|
|
280
278
|
}
|
|
281
|
-
return fontMetricsBySizeIndex[sizeIndex]
|
|
279
|
+
return fontMetricsBySizeIndex[sizeIndex]!;
|
|
282
280
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import defineFunction, {normalizeArgument} from "../defineFunction";
|
|
3
2
|
import {makeOrd, makeSpan, makeVList, staticSvg, svgData} from "../buildCommon";
|
|
4
3
|
import {getBaseElem, isCharacterBox} from "../utils";
|
|
@@ -98,7 +97,7 @@ export const htmlBuilder: HtmlBuilderSupSub<"accent"> = (grp, options) => {
|
|
|
98
97
|
accent = staticSvg("vec", options);
|
|
99
98
|
width = svgData.vec[1];
|
|
100
99
|
} else {
|
|
101
|
-
accent = makeOrd({mode: group.mode, text: group.label},
|
|
100
|
+
accent = makeOrd({type: "textord", mode: group.mode, text: group.label},
|
|
102
101
|
options, "textord");
|
|
103
102
|
accent = assertSymbolDomNode(accent);
|
|
104
103
|
// Remove the italic correction of the accent, because it only serves to
|