katex 0.16.44 → 0.16.46
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/copy-tex/README.md +2 -2
- package/contrib/mathtex-script-type/README.md +5 -5
- package/contrib/mathtex-script-type/mathtex-script-type.js +2 -1
- package/contrib/mhchem/README.md +1 -1
- package/contrib/render-a11y-string/render-a11y-string.ts +7 -5
- package/contrib/render-a11y-string/test/render-a11y-string-spec.ts +0 -1
- package/dist/README.md +3 -3
- package/dist/contrib/mathtex-script-type.js +2 -1
- package/dist/contrib/mathtex-script-type.min.js +1 -1
- package/dist/contrib/mathtex-script-type.mjs +2 -1
- package/dist/contrib/render-a11y-string.js +47 -8
- package/dist/contrib/render-a11y-string.min.js +1 -1
- package/dist/contrib/render-a11y-string.mjs +27 -2
- package/dist/katex-swap.css +5 -2
- package/dist/katex-swap.min.css +1 -1
- package/dist/katex.css +5 -2
- package/dist/katex.js +551 -345
- package/dist/katex.min.css +1 -1
- package/dist/katex.min.js +1 -1
- package/dist/katex.mjs +522 -348
- package/package.json +15 -15
- package/src/Options.ts +29 -28
- package/src/Parser.ts +12 -15
- package/src/Settings.ts +177 -60
- package/src/atoms.ts +33 -0
- package/src/buildCommon.ts +54 -46
- package/src/buildHTML.ts +4 -3
- package/src/buildMathML.ts +54 -47
- package/src/defineEnvironment.ts +1 -1
- package/src/defineFunction.ts +10 -3
- package/src/delimiter.ts +17 -13
- package/src/domTree.ts +28 -23
- package/src/environments/array.ts +12 -6
- package/src/environments/cd.ts +9 -2
- package/src/fontMetrics.ts +10 -23
- package/src/fontMetricsData.d.ts +6 -1
- package/src/functions/arrow.ts +4 -5
- package/src/functions/delimsizing.ts +22 -16
- package/src/functions/enclose.ts +6 -6
- package/src/functions/environment.ts +7 -2
- package/src/functions/font.ts +13 -8
- package/src/functions/hbox.ts +2 -2
- package/src/functions/horizBrace.ts +4 -6
- package/src/functions/math.ts +1 -0
- package/src/functions/op.ts +10 -5
- package/src/functions/smash.ts +1 -1
- package/src/functions/styling.ts +17 -5
- package/src/functions/supsub.ts +6 -3
- package/src/functions/text.ts +7 -3
- package/src/functions/vcenter.ts +3 -1
- package/src/parseNode.ts +7 -5
- package/src/stretchy.ts +14 -26
- package/src/styles/katex.scss +3 -1
- package/src/svgGeometry.ts +32 -27
- package/src/symbols.ts +11 -26
- package/src/tree.ts +11 -5
- package/src/types/fonts.ts +73 -0
- package/src/{types.ts → types/index.ts} +4 -10
- package/src/utils.ts +0 -1
- package/src/wide-character.ts +101 -55
package/src/stretchy.ts
CHANGED
|
@@ -96,18 +96,6 @@ export const stretchyMathML = function(label: string): MathNode {
|
|
|
96
96
|
// Some functions, such as \cancel, need to vary their aspect ratio. These
|
|
97
97
|
// functions do not get the overflow SVG treatment.
|
|
98
98
|
|
|
99
|
-
// Second Brush Stroke
|
|
100
|
-
// Low resolution monitors struggle to display images in fine detail.
|
|
101
|
-
// So browsers apply anti-aliasing. A long straight arrow shaft therefore
|
|
102
|
-
// will sometimes appear as if it has a blurred edge.
|
|
103
|
-
|
|
104
|
-
// To mitigate this, these SVG files contain a second "brush-stroke" on the
|
|
105
|
-
// arrow shafts. That is, a second long thin rectangular SVG path has been
|
|
106
|
-
// written directly on top of each arrow shaft. This reinforcement causes
|
|
107
|
-
// some of the screen pixels to display as black instead of the anti-aliased
|
|
108
|
-
// gray pixel that a single path would generate. So we get arrow shafts
|
|
109
|
-
// whose edges appear to be sharper.
|
|
110
|
-
|
|
111
99
|
// In the katexImagesData object just below, the dimensions all
|
|
112
100
|
// correspond to path geometry inside the relevant SVG.
|
|
113
101
|
// For example, \overrightarrow uses the same arrowhead as glyph U+2192
|
|
@@ -115,9 +103,9 @@ export const stretchyMathML = function(label: string): MathNode {
|
|
|
115
103
|
// That is, inside the font, that arrowhead is 522 units tall, which
|
|
116
104
|
// corresponds to 0.522 em inside the document.
|
|
117
105
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
} = {
|
|
106
|
+
type SvgData = [string[], number, number, string?];
|
|
107
|
+
|
|
108
|
+
const katexImagesData: {[key: string]: SvgData} = {
|
|
121
109
|
// path(s), minWidth, height, align
|
|
122
110
|
overrightarrow: [["rightarrow"], 0.888, 522, "xMaxYMin"],
|
|
123
111
|
overleftarrow: [["leftarrow"], 0.888, 522, "xMinYMin"],
|
|
@@ -189,15 +177,11 @@ export const stretchySvg = function(
|
|
|
189
177
|
} {
|
|
190
178
|
let viewBoxWidth = 400000; // default
|
|
191
179
|
const label = group.label.slice(1);
|
|
192
|
-
if (wideAccentLabels.has(label)) {
|
|
193
|
-
// Each type in the `if` statement corresponds to one of the ParseNode
|
|
194
|
-
// types below. This narrowing is required to access `grp.base`.
|
|
195
|
-
// TODO(ts)
|
|
196
|
-
const grp = group as ParseNode<"accent"> | ParseNode<"accentUnder">;
|
|
180
|
+
if (wideAccentLabels.has(label) && 'base' in group) {
|
|
197
181
|
// There are four SVG images available for each function.
|
|
198
182
|
// Choose a taller image when there are more characters.
|
|
199
|
-
const numChars =
|
|
200
|
-
|
|
183
|
+
const numChars = group.base.type === "ordgroup" ?
|
|
184
|
+
group.base.body.length : 1;
|
|
201
185
|
let viewBoxHeight;
|
|
202
186
|
let pathName;
|
|
203
187
|
let height;
|
|
@@ -244,6 +228,9 @@ export const stretchySvg = function(
|
|
|
244
228
|
const spans = [];
|
|
245
229
|
|
|
246
230
|
const data = katexImagesData[label];
|
|
231
|
+
if (!data) {
|
|
232
|
+
throw new Error(`No SVG data for "${label}".`);
|
|
233
|
+
}
|
|
247
234
|
const [paths, minWidth, viewBoxHeight] = data;
|
|
248
235
|
const height = viewBoxHeight / 1000;
|
|
249
236
|
|
|
@@ -251,11 +238,12 @@ export const stretchySvg = function(
|
|
|
251
238
|
let widthClasses;
|
|
252
239
|
let aligns;
|
|
253
240
|
if (numSvgChildren === 1) {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
241
|
+
if (data.length !== 4) {
|
|
242
|
+
throw new Error(
|
|
243
|
+
`Expected 4-tuple for single-path SVG data "${label}".`);
|
|
244
|
+
}
|
|
257
245
|
widthClasses = ["hide-tail"];
|
|
258
|
-
aligns = [
|
|
246
|
+
aligns = [data[3]];
|
|
259
247
|
} else if (numSvgChildren === 2) {
|
|
260
248
|
widthClasses = ["halfarrow-left", "halfarrow-right"];
|
|
261
249
|
aligns = ["xMinYMin", "xMaxYMin"];
|
package/src/styles/katex.scss
CHANGED
|
@@ -49,7 +49,7 @@ $display-margin: 1em 0 !default;
|
|
|
49
49
|
/* Accessibility hack to only show to screen readers
|
|
50
50
|
Found at: http://a11yproject.com/posts/how-to-hide-content/ */
|
|
51
51
|
position: absolute;
|
|
52
|
-
clip:
|
|
52
|
+
clip-path: inset(50%);
|
|
53
53
|
padding: 0;
|
|
54
54
|
border: 0;
|
|
55
55
|
height: 1px;
|
|
@@ -349,7 +349,9 @@ $display-margin: 1em 0 !default;
|
|
|
349
349
|
> .root {
|
|
350
350
|
/* These values are taken from the definition of `\r@@t`,
|
|
351
351
|
`\mkern 5mu` and `\mkern -10mu`. */
|
|
352
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
352
353
|
margin-left: calc(5*$mu);
|
|
354
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
353
355
|
margin-right: calc(-10*$mu);
|
|
354
356
|
}
|
|
355
357
|
}
|
package/src/svgGeometry.ts
CHANGED
|
@@ -5,6 +5,19 @@
|
|
|
5
5
|
|
|
6
6
|
// In all paths below, the viewBox-to-em scale is 1000:1.
|
|
7
7
|
|
|
8
|
+
// Second Brush Stroke
|
|
9
|
+
// Low resolution monitors struggle to display images in fine detail.
|
|
10
|
+
// So browsers apply anti-aliasing. A long straight arrow shaft therefore
|
|
11
|
+
// will sometimes appear as if it has a blurred edge.
|
|
12
|
+
|
|
13
|
+
// To mitigate this, these SVG files contain a second "brush-stroke" on the
|
|
14
|
+
// arrow shafts. That is, a second long thin rectangular SVG path has been
|
|
15
|
+
// written directly on top of each arrow shaft. This reinforcement causes
|
|
16
|
+
// some of the screen pixels to display as black instead of the anti-aliased
|
|
17
|
+
// gray pixel that a single path would generate. So we get arrow shafts
|
|
18
|
+
// whose edges appear to be sharper.
|
|
19
|
+
const doubleBrushStroke = (svgPath: string): string => `${svgPath} ${svgPath}`;
|
|
20
|
+
|
|
8
21
|
const hLinePad = 80; // padding above a sqrt vinculum. Prevents image cropping.
|
|
9
22
|
|
|
10
23
|
// The vinculum of a \sqrt can be made thicker by a KaTeX rendering option.
|
|
@@ -154,25 +167,25 @@ export const innerPath = function(name: string, height: number): string {
|
|
|
154
167
|
// The inner part of stretchy tall delimiters
|
|
155
168
|
switch (name) {
|
|
156
169
|
case "\u239c":
|
|
157
|
-
return `M291 0 H417 V${height} H291z
|
|
170
|
+
return doubleBrushStroke(`M291 0 H417 V${height} H291z`);
|
|
158
171
|
case "\u2223":
|
|
159
|
-
return `M145 0 H188 V${height} H145z
|
|
172
|
+
return doubleBrushStroke(`M145 0 H188 V${height} H145z`);
|
|
160
173
|
case "\u2225":
|
|
161
|
-
return `M145 0 H188 V${height} H145z
|
|
162
|
-
`M367 0 H410 V${height} H367z
|
|
174
|
+
return doubleBrushStroke(`M145 0 H188 V${height} H145z`) +
|
|
175
|
+
doubleBrushStroke(`M367 0 H410 V${height} H367z`);
|
|
163
176
|
case "\u239f":
|
|
164
|
-
return `M457 0 H583 V${height} H457z
|
|
177
|
+
return doubleBrushStroke(`M457 0 H583 V${height} H457z`);
|
|
165
178
|
case "\u23a2":
|
|
166
|
-
return `M319 0 H403 V${height} H319z
|
|
179
|
+
return doubleBrushStroke(`M319 0 H403 V${height} H319z`);
|
|
167
180
|
case "\u23a5":
|
|
168
|
-
return `M263 0 H347 V${height} H263z
|
|
181
|
+
return doubleBrushStroke(`M263 0 H347 V${height} H263z`);
|
|
169
182
|
case "\u23aa":
|
|
170
|
-
return `M384 0 H504 V${height} H384z
|
|
183
|
+
return doubleBrushStroke(`M384 0 H504 V${height} H384z`);
|
|
171
184
|
case "\u23d0":
|
|
172
|
-
return `M312 0 H355 V${height} H312z
|
|
185
|
+
return doubleBrushStroke(`M312 0 H355 V${height} H312z`);
|
|
173
186
|
case "\u2016":
|
|
174
|
-
return `M257 0 H300 V${height} H257z
|
|
175
|
-
|
|
187
|
+
return doubleBrushStroke(`M257 0 H300 V${height} H257z`) +
|
|
188
|
+
doubleBrushStroke(`M478 0 H521 V${height} H478z`);
|
|
176
189
|
default:
|
|
177
190
|
return "";
|
|
178
191
|
}
|
|
@@ -256,17 +269,13 @@ v40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z`,
|
|
|
256
269
|
-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21
|
|
257
270
|
71.5 23h399859zM103 281v-40h399897v40z`,
|
|
258
271
|
|
|
259
|
-
leftlinesegment: `M40 281 V428 H0 V94 H40 V241 H400000 v40z
|
|
260
|
-
M40 281 V428 H0 V94 H40 V241 H400000 v40z`,
|
|
272
|
+
leftlinesegment: doubleBrushStroke(`M40 281 V428 H0 V94 H40 V241 H400000 v40z`),
|
|
261
273
|
|
|
262
|
-
leftbracketunder: `M0 0 h120 V290 H399995 v120 H0z
|
|
263
|
-
M0 0 h120 V290 H399995 v120 H0z`,
|
|
274
|
+
leftbracketunder: doubleBrushStroke(`M0 0 h120 V290 H399995 v120 H0z`),
|
|
264
275
|
|
|
265
|
-
leftbracketover: `M0 440 h120 V150 H399995 v-120 H0z
|
|
266
|
-
M0 440 h120 V150 H399995 v-120 H0z`,
|
|
276
|
+
leftbracketover: doubleBrushStroke(`M0 440 h120 V150 H399995 v-120 H0z`),
|
|
267
277
|
|
|
268
|
-
leftmapsto: `M40 281 V448H0V74H40V241H400000v40z
|
|
269
|
-
M40 281 V448H0V74H40V241H400000v40z`,
|
|
278
|
+
leftmapsto: doubleBrushStroke(`M40 281 V448H0V74H40V241H400000v40z`),
|
|
270
279
|
|
|
271
280
|
// tofrom is from glyph U+21C4 in font KaTeX AMS Regular
|
|
272
281
|
leftToFrom: `M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23
|
|
@@ -274,8 +283,7 @@ M40 281 V448H0V74H40V241H400000v40z`,
|
|
|
274
283
|
c28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3
|
|
275
284
|
68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z`,
|
|
276
285
|
|
|
277
|
-
longequal: `M0 50 h400000 v40H0z m0 194h40000v40H0z
|
|
278
|
-
M0 50 h400000 v40H0z m0 194h40000v40H0z`,
|
|
286
|
+
longequal: doubleBrushStroke(`M0 50 h400000 v40H0z m0 194h40000v40H0z`),
|
|
279
287
|
|
|
280
288
|
midbrace: `M200428 334
|
|
281
289
|
c-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14
|
|
@@ -358,14 +366,11 @@ m0-194v40h400000v-40zm0 0v40h400000v-40z`,
|
|
|
358
366
|
-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21
|
|
359
367
|
66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z`,
|
|
360
368
|
|
|
361
|
-
rightlinesegment: `M399960 241 V94 h40 V428 h-40 V281 H0 v-40z
|
|
362
|
-
M399960 241 V94 h40 V428 h-40 V281 H0 v-40z`,
|
|
369
|
+
rightlinesegment: doubleBrushStroke(`M399960 241 V94 h40 V428 h-40 V281 H0 v-40z`),
|
|
363
370
|
|
|
364
|
-
rightbracketunder: `M399995 0 h-120 V290 H0 v120 H400000z
|
|
365
|
-
M399995 0 h-120 V290 H0 v120 H400000z`,
|
|
371
|
+
rightbracketunder: doubleBrushStroke(`M399995 0 h-120 V290 H0 v120 H400000z`),
|
|
366
372
|
|
|
367
|
-
rightbracketover: `M399995 440 h-120 V150 H0 v-120 H399995z
|
|
368
|
-
M399995 440 h-120 V150 H0 v-120 H399995z`,
|
|
373
|
+
rightbracketover: doubleBrushStroke(`M399995 440 h-120 V150 H0 v-120 H399995z`),
|
|
369
374
|
|
|
370
375
|
rightToFrom: `M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23
|
|
371
376
|
1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32
|
package/src/symbols.ts
CHANGED
|
@@ -16,34 +16,19 @@
|
|
|
16
16
|
* accepted in (e.g. "math" or "text").
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
import type {Group} from "./atoms";
|
|
19
20
|
import type {Mode} from "./types";
|
|
21
|
+
import type {SymbolFont} from "./types/fonts";
|
|
20
22
|
|
|
21
|
-
type Font = "main" | "ams";
|
|
22
23
|
// Some of these have a "-token" suffix since these are also used as `ParseNode`
|
|
23
24
|
// types for raw text tokens, and we want to avoid conflicts with higher-level
|
|
24
25
|
// `ParseNode` types. These `ParseNode`s are constructed within `Parser` by
|
|
25
26
|
// looking up the `symbols` map.
|
|
26
|
-
export const ATOMS = {
|
|
27
|
-
"bin": 1,
|
|
28
|
-
"close": 1,
|
|
29
|
-
"inner": 1,
|
|
30
|
-
"open": 1,
|
|
31
|
-
"punct": 1,
|
|
32
|
-
"rel": 1,
|
|
33
|
-
};
|
|
34
|
-
export const NON_ATOMS = {
|
|
35
|
-
"accent-token": 1,
|
|
36
|
-
"mathord": 1,
|
|
37
|
-
"op-token": 1,
|
|
38
|
-
"spacing": 1,
|
|
39
|
-
"textord": 1,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export type Atom = keyof typeof ATOMS;
|
|
43
|
-
export type NonAtom = keyof typeof NON_ATOMS;
|
|
44
|
-
export type Group = Atom | NonAtom;
|
|
45
27
|
|
|
46
|
-
type CharInfoMap = Record<
|
|
28
|
+
type CharInfoMap = Record<
|
|
29
|
+
string,
|
|
30
|
+
{font: SymbolFont; group: Group; replace: string | null | undefined}
|
|
31
|
+
>;
|
|
47
32
|
|
|
48
33
|
const symbols: Record<Mode, CharInfoMap> = {
|
|
49
34
|
"math": {},
|
|
@@ -54,9 +39,9 @@ export default symbols;
|
|
|
54
39
|
/** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
|
|
55
40
|
export function defineSymbol(
|
|
56
41
|
mode: Mode,
|
|
57
|
-
font:
|
|
42
|
+
font: SymbolFont,
|
|
58
43
|
group: Group,
|
|
59
|
-
replace: string
|
|
44
|
+
replace: string,
|
|
60
45
|
name: string,
|
|
61
46
|
acceptUnicodeChar?: boolean,
|
|
62
47
|
) {
|
|
@@ -595,8 +580,8 @@ defineSymbol(text, main, spacing, "\u00a0", "\\ ");
|
|
|
595
580
|
defineSymbol(text, main, spacing, "\u00a0", " ");
|
|
596
581
|
defineSymbol(text, main, spacing, "\u00a0", "\\space");
|
|
597
582
|
defineSymbol(text, main, spacing, "\u00a0", "\\nobreakspace");
|
|
598
|
-
defineSymbol(math, main, spacing,
|
|
599
|
-
defineSymbol(math, main, spacing,
|
|
583
|
+
defineSymbol(math, main, spacing, "", "\\nobreak");
|
|
584
|
+
defineSymbol(math, main, spacing, "", "\\allowbreak");
|
|
600
585
|
defineSymbol(math, main, punct, ",", ",");
|
|
601
586
|
defineSymbol(math, main, punct, ";", ";");
|
|
602
587
|
defineSymbol(math, ams, bin, "\u22bc", "\\barwedge", true);
|
|
@@ -799,7 +784,7 @@ defineSymbol(text, main, mathord, "h", "\u210E");
|
|
|
799
784
|
// Mathematical Alphanumeric Symbols.
|
|
800
785
|
// Some editors do not deal well with wide characters. So don't write the
|
|
801
786
|
// string into this file. Instead, create the string from the surrogate pair.
|
|
802
|
-
let wideChar
|
|
787
|
+
let wideChar;
|
|
803
788
|
for (let i = 0; i < letters.length; i++) {
|
|
804
789
|
const ch = letters.charAt(i);
|
|
805
790
|
|
package/src/tree.ts
CHANGED
|
@@ -8,6 +8,10 @@ export interface VirtualNode {
|
|
|
8
8
|
toMarkup(): string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
function isMathDomNode(node: VirtualNode): node is MathDomNode {
|
|
12
|
+
return 'toText' in node;
|
|
13
|
+
}
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
/**
|
|
13
17
|
* This node represents a document fragment, which contains elements, but when
|
|
@@ -64,10 +68,12 @@ export class DocumentFragment<ChildType extends VirtualNode>
|
|
|
64
68
|
* MathDomNode's only.
|
|
65
69
|
*/
|
|
66
70
|
toText(): string {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
return this.children.map((child: ChildType): string => {
|
|
72
|
+
if (isMathDomNode(child)) {
|
|
73
|
+
return child.toText();
|
|
74
|
+
}
|
|
75
|
+
throw new Error(
|
|
76
|
+
`Expected MathDomNode with toText, got ${child.constructor.name}`);
|
|
77
|
+
}).join("");
|
|
72
78
|
}
|
|
73
79
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Math font variants.
|
|
2
|
+
export type FontVariant =
|
|
3
|
+
| "bold"
|
|
4
|
+
| "bold-italic"
|
|
5
|
+
| "bold-sans-serif"
|
|
6
|
+
| "double-struck"
|
|
7
|
+
| "fraktur"
|
|
8
|
+
| "italic"
|
|
9
|
+
| "monospace"
|
|
10
|
+
| "normal"
|
|
11
|
+
| "sans-serif"
|
|
12
|
+
| "sans-serif-bold-italic"
|
|
13
|
+
| "sans-serif-italic"
|
|
14
|
+
| "script";
|
|
15
|
+
|
|
16
|
+
export type FontName =
|
|
17
|
+
| "AMS-Regular"
|
|
18
|
+
| "Caligraphic-Regular"
|
|
19
|
+
| "Fraktur-Regular"
|
|
20
|
+
| "Main-Bold"
|
|
21
|
+
| "Main-BoldItalic"
|
|
22
|
+
| "Main-Italic"
|
|
23
|
+
| "Main-Regular"
|
|
24
|
+
| "Math-BoldItalic"
|
|
25
|
+
| "Math-Italic"
|
|
26
|
+
| "SansSerif-Regular"
|
|
27
|
+
| "SansSerif-Bold"
|
|
28
|
+
| "SansSerif-Italic"
|
|
29
|
+
| "Script-Regular"
|
|
30
|
+
| "Size1-Regular"
|
|
31
|
+
| "Size2-Regular"
|
|
32
|
+
| "Size3-Regular"
|
|
33
|
+
| "Size4-Regular"
|
|
34
|
+
| "Typewriter-Regular";
|
|
35
|
+
|
|
36
|
+
//[depth, height, italic, skew, width]
|
|
37
|
+
export type CharacterMetricsTuple = [depth: number, height: number, italic: number, skew: number, width: number];
|
|
38
|
+
|
|
39
|
+
export type CharacterMetrics = {
|
|
40
|
+
depth: number;
|
|
41
|
+
height: number;
|
|
42
|
+
italic: number;
|
|
43
|
+
skew: number;
|
|
44
|
+
width: number;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type FontMetrics = {
|
|
48
|
+
cssEmPerMu: number;
|
|
49
|
+
[key: string]: number;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type SymbolFont = "main" | "ams";
|
|
53
|
+
|
|
54
|
+
export type MathFont =
|
|
55
|
+
| ""
|
|
56
|
+
| "mathrm"
|
|
57
|
+
| "mathit"
|
|
58
|
+
| "mathbf"
|
|
59
|
+
| "mathnormal"
|
|
60
|
+
| "mathsfit"
|
|
61
|
+
| "mathbb"
|
|
62
|
+
| "mathcal"
|
|
63
|
+
| "mathfrak"
|
|
64
|
+
| "mathscr"
|
|
65
|
+
| "mathsf"
|
|
66
|
+
| "mathtt"
|
|
67
|
+
| "boldsymbol";
|
|
68
|
+
|
|
69
|
+
export type TextFont = "textrm" | "textsf" | "texttt" | "amsrm" | "";
|
|
70
|
+
|
|
71
|
+
// In these types, "" (empty string) means "no change".
|
|
72
|
+
export type FontWeight = "textbf" | "textmd" | "";
|
|
73
|
+
export type FontShape = "textit" | "textup" | "";
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* This file consists only of basic types used in multiple places.
|
|
4
|
-
* For types with javascript, create separate files by themselves.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
export type Mode = "math" | "text";
|
|
8
2
|
|
|
9
3
|
// LaTeX argument type.
|
|
@@ -29,7 +23,7 @@ export type StyleStr = "text" | "display" | "script" | "scriptscript";
|
|
|
29
23
|
export type BreakToken = "]" | "}" | "\\endgroup" | "$" | "\\)" | "\\\\" | "\\end" |
|
|
30
24
|
"EOF";
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
export type DelimiterSize = 1 | 2 | 3 | 4;
|
|
27
|
+
|
|
28
|
+
export type Slice1<S extends string> =
|
|
29
|
+
S extends `${string}${infer Rest}` ? Rest : "";
|
package/src/utils.ts
CHANGED
|
@@ -70,7 +70,6 @@ export const protocolFromUrl = (url: string): string | null => {
|
|
|
70
70
|
// Check for possible leading protocol.
|
|
71
71
|
// https://url.spec.whatwg.org/#url-parsing strips leading whitespace
|
|
72
72
|
// (U+20) or C0 control (U+00-U+1F) characters.
|
|
73
|
-
// eslint-disable-next-line no-control-regex
|
|
74
73
|
const protocol = /^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i
|
|
75
74
|
.exec(url);
|
|
76
75
|
if (!protocol) {
|
package/src/wide-character.ts
CHANGED
|
@@ -6,101 +6,147 @@
|
|
|
6
6
|
* the font information necessary to render it properly.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type {Mode} from "./types";
|
|
10
9
|
import ParseError from "./ParseError";
|
|
10
|
+
import type {FontName} from "./types/fonts";
|
|
11
|
+
|
|
12
|
+
type WideChar = {
|
|
13
|
+
readonly mathClass: string;
|
|
14
|
+
readonly textClass: string;
|
|
15
|
+
readonly font: Extract<FontName,
|
|
16
|
+
| "Main-Bold"
|
|
17
|
+
| "Math-Italic"
|
|
18
|
+
| "Main-BoldItalic"
|
|
19
|
+
| "Script-Regular"
|
|
20
|
+
| "Fraktur-Regular"
|
|
21
|
+
| "AMS-Regular"
|
|
22
|
+
| "SansSerif-Regular"
|
|
23
|
+
| "SansSerif-Bold"
|
|
24
|
+
| "SansSerif-Italic"
|
|
25
|
+
| "Typewriter-Regular"
|
|
26
|
+
> | "";
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const boldUpright: WideChar = {
|
|
30
|
+
mathClass: "mathbf",
|
|
31
|
+
textClass: "textbf",
|
|
32
|
+
font: "Main-Bold",
|
|
33
|
+
};
|
|
34
|
+
const italic: WideChar = {
|
|
35
|
+
mathClass: "mathnormal",
|
|
36
|
+
textClass: "textit",
|
|
37
|
+
font: "Math-Italic",
|
|
38
|
+
};
|
|
39
|
+
const boldItalic: WideChar = {
|
|
40
|
+
mathClass: "boldsymbol",
|
|
41
|
+
textClass: "boldsymbol",
|
|
42
|
+
font: "Main-BoldItalic",
|
|
43
|
+
};
|
|
44
|
+
const script: WideChar = {
|
|
45
|
+
mathClass: "mathscr",
|
|
46
|
+
textClass: "textscr",
|
|
47
|
+
font: "Script-Regular",
|
|
48
|
+
};
|
|
49
|
+
const noFont: WideChar = {mathClass: "", textClass: "", font: ""};
|
|
50
|
+
const fraktur: WideChar = {
|
|
51
|
+
mathClass: "mathfrak",
|
|
52
|
+
textClass: "textfrak",
|
|
53
|
+
font: "Fraktur-Regular",
|
|
54
|
+
};
|
|
55
|
+
const doubleStruck: WideChar = {
|
|
56
|
+
mathClass: "mathbb",
|
|
57
|
+
textClass: "textbb",
|
|
58
|
+
font: "AMS-Regular",
|
|
59
|
+
};
|
|
60
|
+
const boldFraktur: WideChar = {
|
|
61
|
+
mathClass: "mathboldfrak",
|
|
62
|
+
textClass: "textboldfrak",
|
|
63
|
+
font: "Fraktur-Regular",
|
|
64
|
+
};
|
|
65
|
+
const sansSerif: WideChar = {
|
|
66
|
+
mathClass: "mathsf",
|
|
67
|
+
textClass: "textsf",
|
|
68
|
+
font: "SansSerif-Regular",
|
|
69
|
+
};
|
|
70
|
+
const boldSansSerif: WideChar = {
|
|
71
|
+
mathClass: "mathboldsf",
|
|
72
|
+
textClass: "textboldsf",
|
|
73
|
+
font: "SansSerif-Bold",
|
|
74
|
+
};
|
|
75
|
+
const italicSansSerif: WideChar = {
|
|
76
|
+
mathClass: "mathitsf",
|
|
77
|
+
textClass: "textitsf",
|
|
78
|
+
font: "SansSerif-Italic",
|
|
79
|
+
};
|
|
80
|
+
const monospace: WideChar = {
|
|
81
|
+
mathClass: "mathtt",
|
|
82
|
+
textClass: "texttt",
|
|
83
|
+
font: "Typewriter-Regular",
|
|
84
|
+
};
|
|
11
85
|
|
|
12
86
|
/**
|
|
13
87
|
* Data below is from https://www.unicode.org/charts/PDF/U1D400.pdf
|
|
14
88
|
* That document sorts characters into groups by font type, say bold or italic.
|
|
15
89
|
*
|
|
16
|
-
* In the arrays below, each
|
|
90
|
+
* In the arrays below, each object consists of three properties:
|
|
17
91
|
* * The CSS class of that group when in math mode.
|
|
18
92
|
* * The CSS class of that group when in text mode.
|
|
19
93
|
* * The font name, so that KaTeX can get font metrics.
|
|
20
94
|
*/
|
|
21
95
|
|
|
22
96
|
const wideLatinLetterData = [
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
["mathnormal", "textit", "Math-Italic"], // A-Z italic
|
|
27
|
-
["mathnormal", "textit", "Math-Italic"], // a-z italic
|
|
28
|
-
|
|
29
|
-
["boldsymbol", "boldsymbol", "Main-BoldItalic"], // A-Z bold italic
|
|
30
|
-
["boldsymbol", "boldsymbol", "Main-BoldItalic"], // a-z bold italic
|
|
31
|
-
|
|
97
|
+
boldUpright, boldUpright, // A-Z, a-z
|
|
98
|
+
italic, italic, // A-Z, a-z
|
|
99
|
+
boldItalic, boldItalic, // A-Z, a-z
|
|
32
100
|
// Map fancy A-Z letters to script, not calligraphic.
|
|
33
101
|
// This aligns with unicode-math and math fonts (except Cambria Math).
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
["", "", ""], // a-z bold script. No font
|
|
39
|
-
|
|
40
|
-
["mathfrak", "textfrak", "Fraktur-Regular"], // A-Z Fraktur
|
|
41
|
-
["mathfrak", "textfrak", "Fraktur-Regular"], // a-z Fraktur
|
|
42
|
-
|
|
43
|
-
["mathbb", "textbb", "AMS-Regular"], // A-Z double-struck
|
|
44
|
-
["mathbb", "textbb", "AMS-Regular"], // k double-struck
|
|
45
|
-
|
|
102
|
+
script, noFont, // A-Z script, a-z — no font
|
|
103
|
+
noFont, noFont, // A-Z bold script, a-z bold script — no font
|
|
104
|
+
fraktur, fraktur, // A-Z, a-z
|
|
105
|
+
doubleStruck, doubleStruck, // A-Z double-struck, k double-struck
|
|
46
106
|
// Note that we are using a bold font, but font metrics for regular Fraktur.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
["mathboldsf", "textboldsf", "SansSerif-Bold"], // a-z bold sans-serif
|
|
55
|
-
|
|
56
|
-
["mathitsf", "textitsf", "SansSerif-Italic"], // A-Z italic sans-serif
|
|
57
|
-
["mathitsf", "textitsf", "SansSerif-Italic"], // a-z italic sans-serif
|
|
58
|
-
|
|
59
|
-
["", "", ""], // A-Z bold italic sans. No font
|
|
60
|
-
["", "", ""], // a-z bold italic sans. No font
|
|
61
|
-
|
|
62
|
-
["mathtt", "texttt", "Typewriter-Regular"], // A-Z monospace
|
|
63
|
-
["mathtt", "texttt", "Typewriter-Regular"], // a-z monospace
|
|
64
|
-
] as const satisfies readonly (readonly [string, string, string])[];
|
|
107
|
+
boldFraktur, boldFraktur, // A-Z, a-z
|
|
108
|
+
sansSerif, sansSerif, // A-Z, a-z
|
|
109
|
+
boldSansSerif, boldSansSerif, // A-Z, a-z
|
|
110
|
+
italicSansSerif, italicSansSerif, // A-Z, a-z
|
|
111
|
+
noFont, noFont, // A-Z bold italic sans, a-z bold italic sans - no font
|
|
112
|
+
monospace, monospace, // A-Z, a-z
|
|
113
|
+
] as const;
|
|
65
114
|
|
|
66
115
|
const wideNumeralData = [
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
] as const
|
|
116
|
+
boldUpright, // 0-9
|
|
117
|
+
noFont, // 0-9 double-struck. No KaTeX font.
|
|
118
|
+
sansSerif, // 0-9
|
|
119
|
+
boldSansSerif, // 0-9
|
|
120
|
+
monospace, // 0-9
|
|
121
|
+
] as const;
|
|
73
122
|
|
|
74
123
|
export const wideCharacterFont = (
|
|
75
124
|
wideChar: string,
|
|
76
|
-
|
|
77
|
-
): [string, string] => {
|
|
125
|
+
): WideChar => {
|
|
78
126
|
|
|
79
127
|
// IE doesn't support codePointAt(). So work with the surrogate pair.
|
|
80
128
|
const H = wideChar.charCodeAt(0); // high surrogate
|
|
81
129
|
const L = wideChar.charCodeAt(1); // low surrogate
|
|
82
130
|
const codePoint = ((H - 0xD800) * 0x400) + (L - 0xDC00) + 0x10000;
|
|
83
131
|
|
|
84
|
-
const j = mode === "math" ? 0 : 1; // column index for CSS class.
|
|
85
|
-
|
|
86
132
|
if (0x1D400 <= codePoint && codePoint < 0x1D6A4) {
|
|
87
133
|
// wideLatinLetterData contains exactly 26 chars on each row.
|
|
88
134
|
// So we can calculate the relevant row. No traverse necessary.
|
|
89
135
|
const i = Math.floor((codePoint - 0x1D400) / 26);
|
|
90
|
-
return
|
|
136
|
+
return wideLatinLetterData[i];
|
|
91
137
|
|
|
92
138
|
} else if (0x1D7CE <= codePoint && codePoint <= 0x1D7FF) {
|
|
93
139
|
// Numerals, ten per row.
|
|
94
140
|
const i = Math.floor((codePoint - 0x1D7CE) / 10);
|
|
95
|
-
return
|
|
141
|
+
return wideNumeralData[i];
|
|
96
142
|
|
|
97
143
|
} else if (codePoint === 0x1D6A5 || codePoint === 0x1D6A6) {
|
|
98
144
|
// dotless i or j
|
|
99
|
-
return
|
|
145
|
+
return wideLatinLetterData[0];
|
|
100
146
|
|
|
101
147
|
} else if (0x1D6A6 < codePoint && codePoint < 0x1D7CE) {
|
|
102
148
|
// Greek letters. Not supported, yet.
|
|
103
|
-
return
|
|
149
|
+
return noFont;
|
|
104
150
|
|
|
105
151
|
} else {
|
|
106
152
|
// We don't support any wide characters outside 1D400–1D7FF.
|