katex 0.16.28 → 0.16.30
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/cli.js +3 -1
- package/contrib/auto-render/auto-render.js +5 -5
- package/contrib/auto-render/index.html +3 -2
- package/contrib/copy-tex/README.md +2 -2
- package/contrib/mathtex-script-type/README.md +5 -5
- package/contrib/mhchem/README.md +1 -1
- package/dist/README.md +3 -3
- package/dist/contrib/auto-render.js +4 -4
- package/dist/contrib/auto-render.min.js +1 -1
- package/dist/contrib/auto-render.mjs +2 -2
- package/dist/contrib/copy-tex.js +2 -2
- package/dist/contrib/copy-tex.min.js +1 -1
- package/dist/contrib/mathtex-script-type.min.js +1 -1
- package/dist/contrib/mhchem.min.js +1 -1
- package/dist/contrib/render-a11y-string.min.js +1 -1
- package/dist/katex-swap.css +7 -5
- package/dist/katex-swap.min.css +1 -1
- package/dist/katex.css +6 -4
- package/dist/katex.js +460 -555
- package/dist/katex.min.css +1 -1
- package/dist/katex.min.js +1 -1
- package/dist/katex.mjs +415 -508
- package/katex.js +2 -2
- package/package.json +3 -4
- package/src/MacroExpander.js +2 -2
- package/src/Parser.js +4 -3
- package/src/Settings.js +2 -2
- package/src/buildCommon.js +15 -33
- package/src/buildHTML.js +11 -9
- package/src/buildMathML.js +17 -15
- package/src/buildTree.js +5 -5
- package/src/delimiter.js +32 -40
- package/src/domTree.js +17 -17
- package/src/environments/array.js +40 -39
- package/src/environments/cd.js +10 -10
- package/src/functions/accent.js +17 -17
- package/src/functions/accentunder.js +8 -8
- package/src/functions/arrow.js +16 -16
- package/src/functions/color.js +4 -4
- package/src/functions/cr.js +4 -4
- package/src/functions/delimsizing.js +18 -19
- package/src/functions/enclose.js +15 -15
- package/src/functions/font.js +2 -3
- package/src/functions/genfrac.js +25 -20
- package/src/functions/hbox.js +4 -4
- package/src/functions/horizBrace.js +12 -12
- package/src/functions/href.js +2 -2
- package/src/functions/html.js +2 -2
- package/src/functions/htmlmathml.js +3 -2
- package/src/functions/includegraphics.js +2 -2
- package/src/functions/kern.js +4 -4
- package/src/functions/lap.js +11 -11
- package/src/functions/mathchoice.js +2 -2
- package/src/functions/mclass.js +10 -12
- package/src/functions/op.js +20 -20
- package/src/functions/operatorname.js +12 -12
- package/src/functions/ordgroup.js +3 -3
- package/src/functions/overline.js +8 -8
- package/src/functions/phantom.js +14 -14
- package/src/functions/pmb.js +4 -4
- package/src/functions/raisebox.js +4 -4
- package/src/functions/rule.js +5 -5
- package/src/functions/sizing.js +4 -4
- package/src/functions/smash.js +6 -6
- package/src/functions/sqrt.js +12 -12
- package/src/functions/styling.js +2 -2
- package/src/functions/supsub.js +13 -13
- package/src/functions/symbolsOp.js +4 -4
- package/src/functions/symbolsOrd.js +9 -9
- package/src/functions/symbolsSpacing.js +9 -9
- package/src/functions/tag.js +6 -6
- package/src/functions/text.js +2 -2
- package/src/functions/underline.js +8 -8
- package/src/functions/utils/assembleSupSub.js +9 -9
- package/src/functions/vcenter.js +4 -4
- package/src/functions/verb.js +7 -7
- package/src/macros.js +5 -2
- package/src/mathMLTree.js +5 -12
- package/src/stretchy.js +18 -28
- package/src/styles/fonts.scss +5 -3
- package/src/styles/katex-swap.scss +4 -1
- package/src/styles/katex.scss +6 -4
- package/src/utils.js +10 -41
package/src/delimiter.js
CHANGED
|
@@ -26,7 +26,7 @@ import Style from "./Style";
|
|
|
26
26
|
|
|
27
27
|
import {PathNode, SvgNode, SymbolNode} from "./domTree";
|
|
28
28
|
import {sqrtPath, innerPath, tallDelim} from "./svgGeometry";
|
|
29
|
-
import
|
|
29
|
+
import {makeSpan, makeSymbol, makeSvgSpan, makeVList} from "./buildCommon";
|
|
30
30
|
import {getCharacterMetrics} from "./fontMetrics";
|
|
31
31
|
import symbols from "./symbols";
|
|
32
32
|
import {makeEm} from "./units";
|
|
@@ -69,7 +69,7 @@ const styleWrap = function(
|
|
|
69
69
|
): DomSpan {
|
|
70
70
|
const newOptions = options.havingBaseStyle(toStyle);
|
|
71
71
|
|
|
72
|
-
const span =
|
|
72
|
+
const span = makeSpan(
|
|
73
73
|
classes.concat(newOptions.sizingClasses(options)),
|
|
74
74
|
[delim], options);
|
|
75
75
|
|
|
@@ -111,7 +111,7 @@ const makeSmallDelim = function(
|
|
|
111
111
|
mode: Mode,
|
|
112
112
|
classes: string[],
|
|
113
113
|
): DomSpan {
|
|
114
|
-
const text =
|
|
114
|
+
const text = makeSymbol(delim, "Main-Regular", mode, options);
|
|
115
115
|
const span = styleWrap(text, style, options, classes);
|
|
116
116
|
if (center) {
|
|
117
117
|
centerSpan(span, options, style);
|
|
@@ -128,7 +128,7 @@ const mathrmSize = function(
|
|
|
128
128
|
mode: Mode,
|
|
129
129
|
options: Options,
|
|
130
130
|
): SymbolNode {
|
|
131
|
-
return
|
|
131
|
+
return makeSymbol(value, "Size" + size + "-Regular",
|
|
132
132
|
mode, options);
|
|
133
133
|
};
|
|
134
134
|
|
|
@@ -145,7 +145,7 @@ const makeLargeDelim = function(delim,
|
|
|
145
145
|
): DomSpan {
|
|
146
146
|
const inner = mathrmSize(delim, size, mode, options);
|
|
147
147
|
const span = styleWrap(
|
|
148
|
-
|
|
148
|
+
makeSpan(["delimsizing", "size" + size], [inner], options),
|
|
149
149
|
Style.TEXT, options, classes);
|
|
150
150
|
if (center) {
|
|
151
151
|
centerSpan(span, options, Style.TEXT);
|
|
@@ -170,9 +170,9 @@ const makeGlyphSpan = function(
|
|
|
170
170
|
sizeClass = "delim-size4";
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
const corner =
|
|
173
|
+
const corner = makeSpan(
|
|
174
174
|
["delimsizinginner", sizeClass],
|
|
175
|
-
[
|
|
175
|
+
[makeSpan([], [makeSymbol(symbol, font, mode)])]);
|
|
176
176
|
|
|
177
177
|
// Since this will be passed into `makeVList` in the end, wrap the element
|
|
178
178
|
// in the appropriate tag that VList uses.
|
|
@@ -197,7 +197,7 @@ const makeInner = function(
|
|
|
197
197
|
"viewBox": "0 0 " + 1000 * width + " " + Math.round(1000 * height),
|
|
198
198
|
"preserveAspectRatio": "xMinYMin",
|
|
199
199
|
});
|
|
200
|
-
const span =
|
|
200
|
+
const span = makeSvgSpan([], [svgNode], options);
|
|
201
201
|
span.height = height;
|
|
202
202
|
span.style.height = makeEm(height);
|
|
203
203
|
span.style.width = makeEm(width);
|
|
@@ -207,8 +207,8 @@ const makeInner = function(
|
|
|
207
207
|
// Helpers for makeStackedDelim
|
|
208
208
|
const lapInEms = 0.008;
|
|
209
209
|
const lap = {type: "kern", size: -1 * lapInEms};
|
|
210
|
-
const verts = ["|", "\\lvert", "\\rvert", "\\vert"];
|
|
211
|
-
const doubleVerts = ["\\|", "\\lVert", "\\rVert", "\\Vert"];
|
|
210
|
+
const verts = new Set(["|", "\\lvert", "\\rvert", "\\vert"]);
|
|
211
|
+
const doubleVerts = new Set(["\\|", "\\lVert", "\\rVert", "\\Vert"]);
|
|
212
212
|
|
|
213
213
|
/**
|
|
214
214
|
* Make a stacked delimiter out of a given delimiter, with the total height at
|
|
@@ -254,11 +254,11 @@ const makeStackedDelim = function(
|
|
|
254
254
|
top = "\\Uparrow";
|
|
255
255
|
repeat = "\u2016";
|
|
256
256
|
bottom = "\\Downarrow";
|
|
257
|
-
} else if (verts.
|
|
257
|
+
} else if (verts.has(delim)) {
|
|
258
258
|
repeat = "\u2223";
|
|
259
259
|
svgLabel = "vert";
|
|
260
260
|
viewBoxWidth = 333;
|
|
261
|
-
} else if (doubleVerts.
|
|
261
|
+
} else if (doubleVerts.has(delim)) {
|
|
262
262
|
repeat = "\u2225";
|
|
263
263
|
svgLabel = "doublevert";
|
|
264
264
|
viewBoxWidth = 556;
|
|
@@ -404,7 +404,7 @@ const makeStackedDelim = function(
|
|
|
404
404
|
"height": height,
|
|
405
405
|
"viewBox": `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
|
|
406
406
|
});
|
|
407
|
-
const wrapper =
|
|
407
|
+
const wrapper = makeSvgSpan([], [svg], options);
|
|
408
408
|
wrapper.height = viewBoxHeight / 1000;
|
|
409
409
|
wrapper.style.width = width;
|
|
410
410
|
wrapper.style.height = height;
|
|
@@ -441,14 +441,14 @@ const makeStackedDelim = function(
|
|
|
441
441
|
|
|
442
442
|
// Finally, build the vlist
|
|
443
443
|
const newOptions = options.havingBaseStyle(Style.TEXT);
|
|
444
|
-
const inner =
|
|
444
|
+
const inner = makeVList({
|
|
445
445
|
positionType: "bottom",
|
|
446
446
|
positionData: depth,
|
|
447
447
|
children: stack,
|
|
448
448
|
}, newOptions);
|
|
449
449
|
|
|
450
450
|
return styleWrap(
|
|
451
|
-
|
|
451
|
+
makeSpan(["delimsizing", "mult"], [inner], newOptions),
|
|
452
452
|
Style.TEXT, options, classes);
|
|
453
453
|
};
|
|
454
454
|
|
|
@@ -475,13 +475,13 @@ const sqrtSvg = function(
|
|
|
475
475
|
"preserveAspectRatio": "xMinYMin slice",
|
|
476
476
|
});
|
|
477
477
|
|
|
478
|
-
return
|
|
478
|
+
return makeSvgSpan(["hide-tail"], [svg], options);
|
|
479
479
|
};
|
|
480
480
|
|
|
481
481
|
/**
|
|
482
482
|
* Make a sqrt image of the given height,
|
|
483
483
|
*/
|
|
484
|
-
const makeSqrtImage = function(
|
|
484
|
+
export const makeSqrtImage = function(
|
|
485
485
|
height: number,
|
|
486
486
|
options: Options,
|
|
487
487
|
): {
|
|
@@ -573,39 +573,39 @@ const makeSqrtImage = function(
|
|
|
573
573
|
|
|
574
574
|
// There are three kinds of delimiters, delimiters that stack when they become
|
|
575
575
|
// too large
|
|
576
|
-
const stackLargeDelimiters = [
|
|
576
|
+
const stackLargeDelimiters = new Set([
|
|
577
577
|
"(", "\\lparen", ")", "\\rparen",
|
|
578
578
|
"[", "\\lbrack", "]", "\\rbrack",
|
|
579
579
|
"\\{", "\\lbrace", "\\}", "\\rbrace",
|
|
580
580
|
"\\lfloor", "\\rfloor", "\u230a", "\u230b",
|
|
581
581
|
"\\lceil", "\\rceil", "\u2308", "\u2309",
|
|
582
582
|
"\\surd",
|
|
583
|
-
];
|
|
583
|
+
]);
|
|
584
584
|
|
|
585
585
|
// delimiters that always stack
|
|
586
|
-
const stackAlwaysDelimiters = [
|
|
586
|
+
const stackAlwaysDelimiters = new Set([
|
|
587
587
|
"\\uparrow", "\\downarrow", "\\updownarrow",
|
|
588
588
|
"\\Uparrow", "\\Downarrow", "\\Updownarrow",
|
|
589
589
|
"|", "\\|", "\\vert", "\\Vert",
|
|
590
590
|
"\\lvert", "\\rvert", "\\lVert", "\\rVert",
|
|
591
591
|
"\\lgroup", "\\rgroup", "\u27ee", "\u27ef",
|
|
592
592
|
"\\lmoustache", "\\rmoustache", "\u23b0", "\u23b1",
|
|
593
|
-
];
|
|
593
|
+
]);
|
|
594
594
|
|
|
595
595
|
// and delimiters that never stack
|
|
596
|
-
const stackNeverDelimiters = [
|
|
596
|
+
const stackNeverDelimiters = new Set([
|
|
597
597
|
"<", ">", "\\langle", "\\rangle", "/", "\\backslash", "\\lt", "\\gt",
|
|
598
|
-
];
|
|
598
|
+
]);
|
|
599
599
|
|
|
600
600
|
// Metrics of the different sizes. Found by looking at TeX's output of
|
|
601
601
|
// $\bigl| // \Bigl| \biggl| \Biggl| \showlists$
|
|
602
602
|
// Used to create stacked delimiters of appropriate sizes in makeSizedDelim.
|
|
603
|
-
const sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
|
|
603
|
+
export const sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
|
|
604
604
|
|
|
605
605
|
/**
|
|
606
606
|
* Used to create a delimiter of a specific size, where `size` is 1, 2, 3, or 4.
|
|
607
607
|
*/
|
|
608
|
-
const makeSizedDelim = function(
|
|
608
|
+
export const makeSizedDelim = function(
|
|
609
609
|
delim: string,
|
|
610
610
|
size: number,
|
|
611
611
|
options: Options,
|
|
@@ -620,10 +620,10 @@ const makeSizedDelim = function(
|
|
|
620
620
|
}
|
|
621
621
|
|
|
622
622
|
// Sized delimiters are never centered.
|
|
623
|
-
if (stackLargeDelimiters.
|
|
624
|
-
stackNeverDelimiters.
|
|
623
|
+
if (stackLargeDelimiters.has(delim) ||
|
|
624
|
+
stackNeverDelimiters.has(delim)) {
|
|
625
625
|
return makeLargeDelim(delim, size, false, options, mode, classes);
|
|
626
|
-
} else if (stackAlwaysDelimiters.
|
|
626
|
+
} else if (stackAlwaysDelimiters.has(delim)) {
|
|
627
627
|
return makeStackedDelim(
|
|
628
628
|
delim, sizeToMaxHeight[size], false, options, mode, classes);
|
|
629
629
|
} else {
|
|
@@ -742,7 +742,7 @@ const traverseSequence = function(
|
|
|
742
742
|
* Make a delimiter of a given height+depth, with optional centering. Here, we
|
|
743
743
|
* traverse the sequences, and create a delimiter that the sequence tells us to.
|
|
744
744
|
*/
|
|
745
|
-
const makeCustomSizedDelim = function(
|
|
745
|
+
export const makeCustomSizedDelim = function(
|
|
746
746
|
delim: string,
|
|
747
747
|
height: number,
|
|
748
748
|
center: boolean,
|
|
@@ -758,9 +758,9 @@ const makeCustomSizedDelim = function(
|
|
|
758
758
|
|
|
759
759
|
// Decide what sequence to use
|
|
760
760
|
let sequence;
|
|
761
|
-
if (stackNeverDelimiters.
|
|
761
|
+
if (stackNeverDelimiters.has(delim)) {
|
|
762
762
|
sequence = stackNeverDelimiterSequence;
|
|
763
|
-
} else if (stackLargeDelimiters.
|
|
763
|
+
} else if (stackLargeDelimiters.has(delim)) {
|
|
764
764
|
sequence = stackLargeDelimiterSequence;
|
|
765
765
|
} else {
|
|
766
766
|
sequence = stackAlwaysDelimiterSequence;
|
|
@@ -788,7 +788,7 @@ const makeCustomSizedDelim = function(
|
|
|
788
788
|
* Make a delimiter for use with `\left` and `\right`, given a height and depth
|
|
789
789
|
* of an expression that the delimiters surround.
|
|
790
790
|
*/
|
|
791
|
-
const makeLeftRightDelim = function(
|
|
791
|
+
export const makeLeftRightDelim = function(
|
|
792
792
|
delim: string,
|
|
793
793
|
height: number,
|
|
794
794
|
depth: number,
|
|
@@ -824,11 +824,3 @@ const makeLeftRightDelim = function(
|
|
|
824
824
|
// height
|
|
825
825
|
return makeCustomSizedDelim(delim, totalHeight, true, options, mode, classes);
|
|
826
826
|
};
|
|
827
|
-
|
|
828
|
-
export default {
|
|
829
|
-
sqrtImage: makeSqrtImage,
|
|
830
|
-
sizedDelim: makeSizedDelim,
|
|
831
|
-
sizeToMaxHeight: sizeToMaxHeight,
|
|
832
|
-
customSizedDelim: makeCustomSizedDelim,
|
|
833
|
-
leftRightDelim: makeLeftRightDelim,
|
|
834
|
-
};
|
package/src/domTree.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* target environments support class inheritance
|
|
13
13
|
*/
|
|
14
14
|
import {scriptFromCodepoint} from "./unicodeScripts";
|
|
15
|
-
import
|
|
15
|
+
import {escape, hyphenate} from "./utils";
|
|
16
16
|
import {path} from "./svgGeometry";
|
|
17
17
|
import type Options from "./Options";
|
|
18
18
|
import {DocumentFragment} from "./tree";
|
|
@@ -102,7 +102,7 @@ const toMarkup = function(tagName: string): string {
|
|
|
102
102
|
|
|
103
103
|
// Add the class
|
|
104
104
|
if (this.classes.length) {
|
|
105
|
-
markup += ` class="${
|
|
105
|
+
markup += ` class="${escape(createClass(this.classes))}"`;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
let styles = "";
|
|
@@ -110,12 +110,12 @@ const toMarkup = function(tagName: string): string {
|
|
|
110
110
|
// Add the styles, after hyphenation
|
|
111
111
|
for (const style in this.style) {
|
|
112
112
|
if (this.style.hasOwnProperty(style)) {
|
|
113
|
-
styles += `${
|
|
113
|
+
styles += `${hyphenate(style)}:${this.style[style]};`;
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
if (styles) {
|
|
118
|
-
markup += ` style="${
|
|
118
|
+
markup += ` style="${escape(styles)}"`;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
// Add the attributes
|
|
@@ -124,7 +124,7 @@ const toMarkup = function(tagName: string): string {
|
|
|
124
124
|
if (invalidAttributeNameRegex.test(attr)) {
|
|
125
125
|
throw new ParseError(`Invalid attribute name '${attr}'`);
|
|
126
126
|
}
|
|
127
|
-
markup += ` ${attr}="${
|
|
127
|
+
markup += ` ${attr}="${escape(this.attributes[attr])}"`;
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
@@ -329,18 +329,18 @@ export class Img implements VirtualNode {
|
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
toMarkup(): string {
|
|
332
|
-
let markup = `<img src="${
|
|
333
|
-
` alt="${
|
|
332
|
+
let markup = `<img src="${escape(this.src)}"` +
|
|
333
|
+
` alt="${escape(this.alt)}"`;
|
|
334
334
|
|
|
335
335
|
// Add the styles, after hyphenation
|
|
336
336
|
let styles = "";
|
|
337
337
|
for (const style in this.style) {
|
|
338
338
|
if (this.style.hasOwnProperty(style)) {
|
|
339
|
-
styles += `${
|
|
339
|
+
styles += `${hyphenate(style)}:${this.style[style]};`;
|
|
340
340
|
}
|
|
341
341
|
}
|
|
342
342
|
if (styles) {
|
|
343
|
-
markup += ` style="${
|
|
343
|
+
markup += ` style="${escape(styles)}"`;
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
markup += "'/>";
|
|
@@ -460,7 +460,7 @@ export class SymbolNode implements HtmlDomNode {
|
|
|
460
460
|
if (this.classes.length) {
|
|
461
461
|
needsSpan = true;
|
|
462
462
|
markup += " class=\"";
|
|
463
|
-
markup +=
|
|
463
|
+
markup += escape(createClass(this.classes));
|
|
464
464
|
markup += "\"";
|
|
465
465
|
}
|
|
466
466
|
|
|
@@ -471,16 +471,16 @@ export class SymbolNode implements HtmlDomNode {
|
|
|
471
471
|
}
|
|
472
472
|
for (const style in this.style) {
|
|
473
473
|
if (this.style.hasOwnProperty(style)) {
|
|
474
|
-
styles +=
|
|
474
|
+
styles += hyphenate(style) + ":" + this.style[style] + ";";
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
|
|
478
478
|
if (styles) {
|
|
479
479
|
needsSpan = true;
|
|
480
|
-
markup += " style=\"" +
|
|
480
|
+
markup += " style=\"" + escape(styles) + "\"";
|
|
481
481
|
}
|
|
482
482
|
|
|
483
|
-
const escaped =
|
|
483
|
+
const escaped = escape(this.text);
|
|
484
484
|
if (needsSpan) {
|
|
485
485
|
markup += ">";
|
|
486
486
|
markup += escaped;
|
|
@@ -527,7 +527,7 @@ export class SvgNode implements VirtualNode {
|
|
|
527
527
|
// Apply attributes
|
|
528
528
|
for (const attr in this.attributes) {
|
|
529
529
|
if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
|
|
530
|
-
markup += ` ${attr}="${
|
|
530
|
+
markup += ` ${attr}="${escape(this.attributes[attr])}"`;
|
|
531
531
|
}
|
|
532
532
|
}
|
|
533
533
|
|
|
@@ -568,9 +568,9 @@ export class PathNode implements VirtualNode {
|
|
|
568
568
|
|
|
569
569
|
toMarkup(): string {
|
|
570
570
|
if (this.alternate) {
|
|
571
|
-
return `<path d="${
|
|
571
|
+
return `<path d="${escape(this.alternate)}"/>`;
|
|
572
572
|
} else {
|
|
573
|
-
return `<path d="${
|
|
573
|
+
return `<path d="${escape(path[this.pathName])}"/>`;
|
|
574
574
|
}
|
|
575
575
|
}
|
|
576
576
|
}
|
|
@@ -601,7 +601,7 @@ export class LineNode implements VirtualNode {
|
|
|
601
601
|
|
|
602
602
|
for (const attr in this.attributes) {
|
|
603
603
|
if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
|
|
604
|
-
markup += ` ${attr}="${
|
|
604
|
+
markup += ` ${attr}="${escape(this.attributes[attr])}"`;
|
|
605
605
|
}
|
|
606
606
|
}
|
|
607
607
|
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
// @flow
|
|
2
|
-
import
|
|
2
|
+
import {makeFragment, makeLineSpan, makeSpan, makeVList} from "../buildCommon";
|
|
3
3
|
import Style from "../Style";
|
|
4
4
|
import defineEnvironment from "../defineEnvironment";
|
|
5
5
|
import {parseCD} from "./cd";
|
|
6
6
|
import defineFunction from "../defineFunction";
|
|
7
7
|
import defineMacro from "../defineMacro";
|
|
8
|
-
import
|
|
8
|
+
import {MathNode} from "../mathMLTree";
|
|
9
9
|
import ParseError from "../ParseError";
|
|
10
10
|
import {assertNodeType, assertSymbolNodeType} from "../parseNode";
|
|
11
11
|
import {checkSymbolNodeType} from "../parseNode";
|
|
12
12
|
import {Token} from "../Token";
|
|
13
13
|
import {calculateSize, makeEm} from "../units";
|
|
14
|
-
import utils from "../utils";
|
|
15
14
|
|
|
16
15
|
import * as html from "../buildHTML";
|
|
17
16
|
import * as mml from "../buildMathML";
|
|
@@ -61,14 +60,16 @@ const validateAmsEnvironmentContext = context => {
|
|
|
61
60
|
}
|
|
62
61
|
};
|
|
63
62
|
|
|
63
|
+
const gatherEnvironments = new Set(["gather", "gather*"]);
|
|
64
|
+
|
|
64
65
|
// autoTag (an argument to parseArray) can be one of three values:
|
|
65
66
|
// * undefined: Regular (not-top-level) array; no tags on each row
|
|
66
67
|
// * true: Automatic equation numbering, overridable by \tag
|
|
67
68
|
// * false: Tags allowed on each row, but no automatic numbering
|
|
68
69
|
// This function *doesn't* work with the "split" environment name.
|
|
69
70
|
function getAutoTag(name): ?boolean {
|
|
70
|
-
if (name.
|
|
71
|
-
return name.
|
|
71
|
+
if (!name.includes("ed")) {
|
|
72
|
+
return !name.includes("*");
|
|
72
73
|
}
|
|
73
74
|
// return undefined;
|
|
74
75
|
}
|
|
@@ -394,12 +395,12 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
394
395
|
const tag = group.tags[r];
|
|
395
396
|
let tagSpan;
|
|
396
397
|
if (tag === true) { // automatic numbering
|
|
397
|
-
tagSpan =
|
|
398
|
+
tagSpan = makeSpan(["eqn-num"], [], options);
|
|
398
399
|
} else if (tag === false) {
|
|
399
400
|
// \nonumber/\notag or starred environment
|
|
400
|
-
tagSpan =
|
|
401
|
+
tagSpan = makeSpan([], [], options);
|
|
401
402
|
} else { // manual \tag
|
|
402
|
-
tagSpan =
|
|
403
|
+
tagSpan = makeSpan([],
|
|
403
404
|
html.buildExpression(tag, options, true), options);
|
|
404
405
|
}
|
|
405
406
|
tagSpan.depth = rw.depth;
|
|
@@ -421,7 +422,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
421
422
|
// If there is more than one separator in a row, add a space
|
|
422
423
|
// between them.
|
|
423
424
|
if (!firstSeparator) {
|
|
424
|
-
colSep =
|
|
425
|
+
colSep = makeSpan(["arraycolsep"], []);
|
|
425
426
|
colSep.style.width =
|
|
426
427
|
makeEm(options.fontMetrics().doubleRuleSep);
|
|
427
428
|
cols.push(colSep);
|
|
@@ -429,7 +430,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
429
430
|
|
|
430
431
|
if (colDescr.separator === "|" || colDescr.separator === ":") {
|
|
431
432
|
const lineType = (colDescr.separator === "|") ? "solid" : "dashed";
|
|
432
|
-
const separator =
|
|
433
|
+
const separator = makeSpan(
|
|
433
434
|
["vertical-separator"], [], options
|
|
434
435
|
);
|
|
435
436
|
separator.style.height = makeEm(totalHeight);
|
|
@@ -458,9 +459,9 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
458
459
|
|
|
459
460
|
let sepwidth;
|
|
460
461
|
if (c > 0 || group.hskipBeforeAndAfter) {
|
|
461
|
-
sepwidth =
|
|
462
|
+
sepwidth = colDescr.pregap ?? arraycolsep;
|
|
462
463
|
if (sepwidth !== 0) {
|
|
463
|
-
colSep =
|
|
464
|
+
colSep = makeSpan(["arraycolsep"], []);
|
|
464
465
|
colSep.style.width = makeEm(sepwidth);
|
|
465
466
|
cols.push(colSep);
|
|
466
467
|
}
|
|
@@ -479,30 +480,30 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
479
480
|
col.push({type: "elem", elem: elem, shift: shift});
|
|
480
481
|
}
|
|
481
482
|
|
|
482
|
-
col =
|
|
483
|
+
col = makeVList({
|
|
483
484
|
positionType: "individualShift",
|
|
484
485
|
children: col,
|
|
485
486
|
}, options);
|
|
486
|
-
col =
|
|
487
|
+
col = makeSpan(
|
|
487
488
|
["col-align-" + (colDescr.align || "c")],
|
|
488
489
|
[col]);
|
|
489
490
|
cols.push(col);
|
|
490
491
|
|
|
491
492
|
if (c < nc - 1 || group.hskipBeforeAndAfter) {
|
|
492
|
-
sepwidth =
|
|
493
|
+
sepwidth = colDescr.postgap ?? arraycolsep;
|
|
493
494
|
if (sepwidth !== 0) {
|
|
494
|
-
colSep =
|
|
495
|
+
colSep = makeSpan(["arraycolsep"], []);
|
|
495
496
|
colSep.style.width = makeEm(sepwidth);
|
|
496
497
|
cols.push(colSep);
|
|
497
498
|
}
|
|
498
499
|
}
|
|
499
500
|
}
|
|
500
|
-
body =
|
|
501
|
+
body = makeSpan(["mtable"], cols);
|
|
501
502
|
|
|
502
503
|
// Add \hline(s), if any.
|
|
503
504
|
if (hlines.length > 0) {
|
|
504
|
-
const line =
|
|
505
|
-
const dashes =
|
|
505
|
+
const line = makeLineSpan("hline", options, ruleThickness);
|
|
506
|
+
const dashes = makeLineSpan("hdashline", options,
|
|
506
507
|
ruleThickness);
|
|
507
508
|
const vListElems = [{type: "elem", elem: body, shift: 0}];
|
|
508
509
|
while (hlines.length > 0) {
|
|
@@ -514,21 +515,21 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
|
|
514
515
|
vListElems.push({type: "elem", elem: line, shift: lineShift});
|
|
515
516
|
}
|
|
516
517
|
}
|
|
517
|
-
body =
|
|
518
|
+
body = makeVList({
|
|
518
519
|
positionType: "individualShift",
|
|
519
520
|
children: vListElems,
|
|
520
521
|
}, options);
|
|
521
522
|
}
|
|
522
523
|
|
|
523
524
|
if (tagSpans.length === 0) {
|
|
524
|
-
return
|
|
525
|
+
return makeSpan(["mord"], [body], options);
|
|
525
526
|
} else {
|
|
526
|
-
let eqnNumCol =
|
|
527
|
+
let eqnNumCol = makeVList({
|
|
527
528
|
positionType: "individualShift",
|
|
528
529
|
children: tagSpans,
|
|
529
530
|
}, options);
|
|
530
|
-
eqnNumCol =
|
|
531
|
-
return
|
|
531
|
+
eqnNumCol = makeSpan(["tag"], [eqnNumCol], options);
|
|
532
|
+
return makeFragment([body, eqnNumCol]);
|
|
532
533
|
}
|
|
533
534
|
};
|
|
534
535
|
|
|
@@ -540,13 +541,13 @@ const alignMap = {
|
|
|
540
541
|
|
|
541
542
|
const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
542
543
|
const tbl = [];
|
|
543
|
-
const glue = new
|
|
544
|
-
const tag = new
|
|
544
|
+
const glue = new MathNode("mtd", [], ["mtr-glue"]);
|
|
545
|
+
const tag = new MathNode("mtd", [], ["mml-eqn-num"]);
|
|
545
546
|
for (let i = 0; i < group.body.length; i++) {
|
|
546
547
|
const rw = group.body[i];
|
|
547
548
|
const row = [];
|
|
548
549
|
for (let j = 0; j < rw.length; j++) {
|
|
549
|
-
row.push(new
|
|
550
|
+
row.push(new MathNode("mtd",
|
|
550
551
|
[mml.buildGroup(rw[j], options)]));
|
|
551
552
|
}
|
|
552
553
|
if (group.tags && group.tags[i]) {
|
|
@@ -558,9 +559,9 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
|
558
559
|
row.push(tag);
|
|
559
560
|
}
|
|
560
561
|
}
|
|
561
|
-
tbl.push(new
|
|
562
|
+
tbl.push(new MathNode("mtr", row));
|
|
562
563
|
}
|
|
563
|
-
let table = new
|
|
564
|
+
let table = new MathNode("mtable", tbl);
|
|
564
565
|
|
|
565
566
|
// Set column alignment, row spacing, column spacing, and
|
|
566
567
|
// array lines by setting attributes on the table element.
|
|
@@ -666,13 +667,13 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
|
666
667
|
}
|
|
667
668
|
|
|
668
669
|
if (menclose !== "") {
|
|
669
|
-
table = new
|
|
670
|
+
table = new MathNode("menclose", [table]);
|
|
670
671
|
table.setAttribute("notation", menclose.trim());
|
|
671
672
|
}
|
|
672
673
|
|
|
673
674
|
if (group.arraystretch && group.arraystretch < 1) {
|
|
674
675
|
// A small array. Wrap in scriptstyle so row gap is not too large.
|
|
675
|
-
table = new
|
|
676
|
+
table = new MathNode("mstyle", [table]);
|
|
676
677
|
table.setAttribute("scriptlevel", "1");
|
|
677
678
|
}
|
|
678
679
|
|
|
@@ -681,11 +682,11 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
|
|
681
682
|
|
|
682
683
|
// Convenience function for align, align*, aligned, alignat, alignat*, alignedat.
|
|
683
684
|
const alignedHandler = function(context, args) {
|
|
684
|
-
if (context.envName.
|
|
685
|
+
if (!context.envName.includes("ed")) {
|
|
685
686
|
validateAmsEnvironmentContext(context);
|
|
686
687
|
}
|
|
687
688
|
const cols = [];
|
|
688
|
-
const separationType = context.envName.
|
|
689
|
+
const separationType = context.envName.includes("at") ? "alignat" : "align";
|
|
689
690
|
const isSplit = context.envName === "split";
|
|
690
691
|
const res = parseArray(context.parser,
|
|
691
692
|
{
|
|
@@ -789,7 +790,7 @@ defineEnvironment({
|
|
|
789
790
|
const cols = colalign.map(function(nde) {
|
|
790
791
|
const node = assertSymbolNodeType(nde);
|
|
791
792
|
const ca = node.text;
|
|
792
|
-
if ("lcr".
|
|
793
|
+
if ("lcr".includes(ca)) {
|
|
793
794
|
return {
|
|
794
795
|
type: "align",
|
|
795
796
|
align: ca,
|
|
@@ -865,7 +866,7 @@ defineEnvironment({
|
|
|
865
866
|
parser.consume();
|
|
866
867
|
parser.consumeSpaces();
|
|
867
868
|
colAlign = parser.fetch().text;
|
|
868
|
-
if ("lcr".
|
|
869
|
+
if (!"lcr".includes(colAlign)) {
|
|
869
870
|
throw new ParseError("Expected l or c or r", parser.nextToken);
|
|
870
871
|
}
|
|
871
872
|
parser.consume();
|
|
@@ -926,7 +927,7 @@ defineEnvironment({
|
|
|
926
927
|
const node = assertSymbolNodeType(nde);
|
|
927
928
|
const ca = node.text;
|
|
928
929
|
// {subarray} only recognizes "l" & "c"
|
|
929
|
-
if ("lc".
|
|
930
|
+
if ("lc".includes(ca)) {
|
|
930
931
|
return {
|
|
931
932
|
type: "align",
|
|
932
933
|
align: ca,
|
|
@@ -994,8 +995,8 @@ defineEnvironment({
|
|
|
994
995
|
type: "leftright",
|
|
995
996
|
mode: context.mode,
|
|
996
997
|
body: [res],
|
|
997
|
-
left: context.envName.
|
|
998
|
-
right: context.envName.
|
|
998
|
+
left: context.envName.includes("r") ? "." : "\\{",
|
|
999
|
+
right: context.envName.includes("r") ? "\\}" : ".",
|
|
999
1000
|
rightColor: undefined,
|
|
1000
1001
|
};
|
|
1001
1002
|
},
|
|
@@ -1030,7 +1031,7 @@ defineEnvironment({
|
|
|
1030
1031
|
numArgs: 0,
|
|
1031
1032
|
},
|
|
1032
1033
|
handler(context) {
|
|
1033
|
-
if (
|
|
1034
|
+
if (gatherEnvironments.has(context.envName)) {
|
|
1034
1035
|
validateAmsEnvironmentContext(context);
|
|
1035
1036
|
}
|
|
1036
1037
|
const res = {
|
package/src/environments/cd.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @flow
|
|
2
|
-
import
|
|
2
|
+
import {wrapFragment} from "../buildCommon";
|
|
3
3
|
import defineFunction from "../defineFunction";
|
|
4
|
-
import
|
|
4
|
+
import {MathNode} from "../mathMLTree";
|
|
5
5
|
import * as html from "../buildHTML";
|
|
6
6
|
import * as mml from "../buildMathML";
|
|
7
7
|
import {assertSymbolNodeType} from "../parseNode";
|
|
@@ -141,10 +141,10 @@ export function parseCD(parser: Parser): ParseNode<"array"> {
|
|
|
141
141
|
labels[1] = {type: "ordgroup", mode: "math", body: []};
|
|
142
142
|
|
|
143
143
|
// Process the arrow.
|
|
144
|
-
if ("=|.".
|
|
144
|
+
if ("=|.".includes(arrowChar)) {
|
|
145
145
|
// Three "arrows", ``@=`, `@|`, and `@.`, do not take labels.
|
|
146
146
|
// Do nothing here.
|
|
147
|
-
} else if ("<>AV".
|
|
147
|
+
} else if ("<>AV".includes(arrowChar)) {
|
|
148
148
|
// Four arrows, `@>>>`, `@<<<`, `@AAA`, and `@VVV`, each take
|
|
149
149
|
// two optional labels. E.g. the right-point arrow syntax is
|
|
150
150
|
// really: @>{optional label}>{optional label}>
|
|
@@ -255,7 +255,7 @@ defineFunction({
|
|
|
255
255
|
},
|
|
256
256
|
htmlBuilder(group, options) {
|
|
257
257
|
const newOptions = options.havingStyle(options.style.sup());
|
|
258
|
-
const label =
|
|
258
|
+
const label = wrapFragment(
|
|
259
259
|
html.buildGroup(group.label, newOptions, options), options);
|
|
260
260
|
label.classes.push("cd-label-" + group.side);
|
|
261
261
|
label.style.bottom = makeEm(0.8 - label.depth);
|
|
@@ -266,9 +266,9 @@ defineFunction({
|
|
|
266
266
|
return label;
|
|
267
267
|
},
|
|
268
268
|
mathmlBuilder(group, options) {
|
|
269
|
-
let label = new
|
|
269
|
+
let label = new MathNode("mrow",
|
|
270
270
|
[mml.buildGroup(group.label, options)]);
|
|
271
|
-
label = new
|
|
271
|
+
label = new MathNode("mpadded", [label]);
|
|
272
272
|
label.setAttribute("width", "0");
|
|
273
273
|
if (group.side === "left") {
|
|
274
274
|
label.setAttribute("lspace", "-1width");
|
|
@@ -276,7 +276,7 @@ defineFunction({
|
|
|
276
276
|
// We have to guess at vertical alignment. We know the arrow is 1.8em tall,
|
|
277
277
|
// But we don't know the height or depth of the label.
|
|
278
278
|
label.setAttribute("voffset", "0.7em");
|
|
279
|
-
label = new
|
|
279
|
+
label = new MathNode("mstyle", [label]);
|
|
280
280
|
label.setAttribute("displaystyle", "false");
|
|
281
281
|
label.setAttribute("scriptlevel", "1");
|
|
282
282
|
return label;
|
|
@@ -300,14 +300,14 @@ defineFunction({
|
|
|
300
300
|
// Wrap the vertical arrow and its labels.
|
|
301
301
|
// The parent gets position: relative. The child gets position: absolute.
|
|
302
302
|
// So CSS can locate the label correctly.
|
|
303
|
-
const parent =
|
|
303
|
+
const parent = wrapFragment(
|
|
304
304
|
html.buildGroup(group.fragment, options), options
|
|
305
305
|
);
|
|
306
306
|
parent.classes.push("cd-vert-arrow");
|
|
307
307
|
return parent;
|
|
308
308
|
},
|
|
309
309
|
mathmlBuilder(group, options) {
|
|
310
|
-
return new
|
|
310
|
+
return new MathNode("mrow",
|
|
311
311
|
[mml.buildGroup(group.fragment, options)]);
|
|
312
312
|
},
|
|
313
313
|
});
|