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/dist/katex.js
CHANGED
|
@@ -49,10 +49,6 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
49
49
|
* about where in the source string the problem occurred.
|
|
50
50
|
*/
|
|
51
51
|
class ParseError extends Error {
|
|
52
|
-
// Error start position based on passed-in Token or ParseNode.
|
|
53
|
-
|
|
54
|
-
// Length of affected text based on passed-in Token or ParseNode.
|
|
55
|
-
|
|
56
52
|
// The underlying error message without any context added.
|
|
57
53
|
|
|
58
54
|
constructor(message,
|
|
@@ -97,6 +93,11 @@ class ParseError extends Error {
|
|
|
97
93
|
}
|
|
98
94
|
super(error);
|
|
99
95
|
this.name = "ParseError";
|
|
96
|
+
this.position = void 0;
|
|
97
|
+
// Error start position based on passed-in Token or ParseNode.
|
|
98
|
+
this.length = void 0;
|
|
99
|
+
// Length of affected text based on passed-in Token or ParseNode.
|
|
100
|
+
this.rawMessage = void 0;
|
|
100
101
|
Object.setPrototypeOf(this, ParseError.prototype);
|
|
101
102
|
this.position = start;
|
|
102
103
|
if (start != null && end != null) {
|
|
@@ -171,7 +172,6 @@ const protocolFromUrl = url => {
|
|
|
171
172
|
// Check for possible leading protocol.
|
|
172
173
|
// https://url.spec.whatwg.org/#url-parsing strips leading whitespace
|
|
173
174
|
// (U+20) or C0 control (U+00-U+1F) characters.
|
|
174
|
-
// eslint-disable-next-line no-control-regex
|
|
175
175
|
const protocol = /^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(url);
|
|
176
176
|
if (!protocol) {
|
|
177
177
|
return "_relative";
|
|
@@ -197,6 +197,13 @@ const protocolFromUrl = url => {
|
|
|
197
197
|
|
|
198
198
|
|
|
199
199
|
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Union of all values that appear as schema defaults, cliDefaults, or
|
|
203
|
+
* cliProcessor return values. StrictFunction / TrustFunction are
|
|
204
|
+
* option-value types, not default/schema values, so they are excluded.
|
|
205
|
+
*/
|
|
206
|
+
|
|
200
207
|
// TODO: automatically generate documentation
|
|
201
208
|
// TODO: check all properties on Settings exist
|
|
202
209
|
// TODO: check the type of a property on Settings matches
|
|
@@ -290,16 +297,11 @@ const SETTINGS_SCHEMA = {
|
|
|
290
297
|
cli: false
|
|
291
298
|
}
|
|
292
299
|
};
|
|
293
|
-
function
|
|
294
|
-
if (
|
|
295
|
-
return
|
|
296
|
-
}
|
|
297
|
-
const type = schema.type;
|
|
298
|
-
const defaultType = Array.isArray(type) ? type[0] : type;
|
|
299
|
-
if (typeof defaultType !== 'string') {
|
|
300
|
-
return defaultType.enum[0];
|
|
300
|
+
function getImplicitDefault(type) {
|
|
301
|
+
if (typeof type !== 'string') {
|
|
302
|
+
return type.enum[0];
|
|
301
303
|
}
|
|
302
|
-
switch (
|
|
304
|
+
switch (type) {
|
|
303
305
|
case 'boolean':
|
|
304
306
|
return false;
|
|
305
307
|
case 'string':
|
|
@@ -308,8 +310,21 @@ function getDefaultValue(schema) {
|
|
|
308
310
|
return 0;
|
|
309
311
|
case 'object':
|
|
310
312
|
return {};
|
|
313
|
+
default:
|
|
314
|
+
throw new Error("Unexpected schema type; settings must declare an explicit default.");
|
|
311
315
|
}
|
|
312
316
|
}
|
|
317
|
+
function getDefaultValue(schema) {
|
|
318
|
+
if (schema.default !== undefined) {
|
|
319
|
+
return schema.default;
|
|
320
|
+
}
|
|
321
|
+
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
322
|
+
return getImplicitDefault(type);
|
|
323
|
+
}
|
|
324
|
+
function applySetting(target, prop, options, schema) {
|
|
325
|
+
const optionValue = options[prop];
|
|
326
|
+
target[prop] = optionValue !== undefined ? schema.processor ? schema.processor(optionValue) : optionValue : getDefaultValue(schema);
|
|
327
|
+
}
|
|
313
328
|
|
|
314
329
|
/**
|
|
315
330
|
* The main Settings object
|
|
@@ -326,13 +341,28 @@ class Settings {
|
|
|
326
341
|
if (options === void 0) {
|
|
327
342
|
options = {};
|
|
328
343
|
}
|
|
344
|
+
this.displayMode = void 0;
|
|
345
|
+
this.output = void 0;
|
|
346
|
+
this.leqno = void 0;
|
|
347
|
+
this.fleqn = void 0;
|
|
348
|
+
this.throwOnError = void 0;
|
|
349
|
+
this.errorColor = void 0;
|
|
350
|
+
this.macros = void 0;
|
|
351
|
+
this.minRuleThickness = void 0;
|
|
352
|
+
this.colorIsTextColor = void 0;
|
|
353
|
+
this.strict = void 0;
|
|
354
|
+
this.trust = void 0;
|
|
355
|
+
this.maxSize = void 0;
|
|
356
|
+
this.maxExpand = void 0;
|
|
357
|
+
this.globalGroup = void 0;
|
|
329
358
|
// allow null options
|
|
330
359
|
options = options || {};
|
|
331
360
|
for (const prop of Object.keys(SETTINGS_SCHEMA)) {
|
|
332
361
|
const schema = SETTINGS_SCHEMA[prop];
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
362
|
+
if (schema) {
|
|
363
|
+
// TODO: validate options
|
|
364
|
+
applySetting(this, prop, options, schema);
|
|
365
|
+
}
|
|
336
366
|
}
|
|
337
367
|
}
|
|
338
368
|
|
|
@@ -429,6 +459,9 @@ class Settings {
|
|
|
429
459
|
*/
|
|
430
460
|
class Style {
|
|
431
461
|
constructor(id, size, cramped) {
|
|
462
|
+
this.id = void 0;
|
|
463
|
+
this.size = void 0;
|
|
464
|
+
this.cramped = void 0;
|
|
432
465
|
this.id = id;
|
|
433
466
|
this.size = size;
|
|
434
467
|
this.cramped = cramped;
|
|
@@ -640,6 +673,18 @@ function supportedCodepoint(codepoint) {
|
|
|
640
673
|
|
|
641
674
|
// In all paths below, the viewBox-to-em scale is 1000:1.
|
|
642
675
|
|
|
676
|
+
// Second Brush Stroke
|
|
677
|
+
// Low resolution monitors struggle to display images in fine detail.
|
|
678
|
+
// So browsers apply anti-aliasing. A long straight arrow shaft therefore
|
|
679
|
+
// will sometimes appear as if it has a blurred edge.
|
|
680
|
+
|
|
681
|
+
// To mitigate this, these SVG files contain a second "brush-stroke" on the
|
|
682
|
+
// arrow shafts. That is, a second long thin rectangular SVG path has been
|
|
683
|
+
// written directly on top of each arrow shaft. This reinforcement causes
|
|
684
|
+
// some of the screen pixels to display as black instead of the anti-aliased
|
|
685
|
+
// gray pixel that a single path would generate. So we get arrow shafts
|
|
686
|
+
// whose edges appear to be sharper.
|
|
687
|
+
const doubleBrushStroke = svgPath => svgPath + " " + svgPath;
|
|
643
688
|
const hLinePad = 80; // padding above a sqrt vinculum. Prevents image cropping.
|
|
644
689
|
|
|
645
690
|
// The vinculum of a \sqrt can be made thicker by a KaTeX rendering option.
|
|
@@ -720,23 +765,23 @@ const innerPath = function (name, height) {
|
|
|
720
765
|
// The inner part of stretchy tall delimiters
|
|
721
766
|
switch (name) {
|
|
722
767
|
case "\u239c":
|
|
723
|
-
return "M291 0 H417 V" + height + " H291z
|
|
768
|
+
return doubleBrushStroke("M291 0 H417 V" + height + " H291z");
|
|
724
769
|
case "\u2223":
|
|
725
|
-
return "M145 0 H188 V" + height + " H145z
|
|
770
|
+
return doubleBrushStroke("M145 0 H188 V" + height + " H145z");
|
|
726
771
|
case "\u2225":
|
|
727
|
-
return "M145 0 H188 V" + height + " H145z
|
|
772
|
+
return doubleBrushStroke("M145 0 H188 V" + height + " H145z") + doubleBrushStroke("M367 0 H410 V" + height + " H367z");
|
|
728
773
|
case "\u239f":
|
|
729
|
-
return "M457 0 H583 V" + height + " H457z
|
|
774
|
+
return doubleBrushStroke("M457 0 H583 V" + height + " H457z");
|
|
730
775
|
case "\u23a2":
|
|
731
|
-
return "M319 0 H403 V" + height + " H319z
|
|
776
|
+
return doubleBrushStroke("M319 0 H403 V" + height + " H319z");
|
|
732
777
|
case "\u23a5":
|
|
733
|
-
return "M263 0 H347 V" + height + " H263z
|
|
778
|
+
return doubleBrushStroke("M263 0 H347 V" + height + " H263z");
|
|
734
779
|
case "\u23aa":
|
|
735
|
-
return "M384 0 H504 V" + height + " H384z
|
|
780
|
+
return doubleBrushStroke("M384 0 H504 V" + height + " H384z");
|
|
736
781
|
case "\u23d0":
|
|
737
|
-
return "M312 0 H355 V" + height + " H312z
|
|
782
|
+
return doubleBrushStroke("M312 0 H355 V" + height + " H312z");
|
|
738
783
|
case "\u2016":
|
|
739
|
-
return "M257 0 H300 V" + height + " H257z
|
|
784
|
+
return doubleBrushStroke("M257 0 H300 V" + height + " H257z") + doubleBrushStroke("M478 0 H521 V" + height + " H478z");
|
|
740
785
|
default:
|
|
741
786
|
return "";
|
|
742
787
|
}
|
|
@@ -761,13 +806,13 @@ const path = {
|
|
|
761
806
|
leftharpoondownplus: "M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",
|
|
762
807
|
// hook is from glyph U+21A9 in font KaTeX Main
|
|
763
808
|
lefthook: "M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-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\n 71.5 23h399859zM103 281v-40h399897v40z",
|
|
764
|
-
leftlinesegment: "M40 281 V428 H0 V94 H40 V241 H400000 v40z
|
|
765
|
-
leftbracketunder: "M0 0 h120 V290 H399995 v120 H0z
|
|
766
|
-
leftbracketover: "M0 440 h120 V150 H399995 v-120 H0z
|
|
767
|
-
leftmapsto: "M40 281 V448H0V74H40V241H400000v40z
|
|
809
|
+
leftlinesegment: doubleBrushStroke("M40 281 V428 H0 V94 H40 V241 H400000 v40z"),
|
|
810
|
+
leftbracketunder: doubleBrushStroke("M0 0 h120 V290 H399995 v120 H0z"),
|
|
811
|
+
leftbracketover: doubleBrushStroke("M0 440 h120 V150 H399995 v-120 H0z"),
|
|
812
|
+
leftmapsto: doubleBrushStroke("M40 281 V448H0V74H40V241H400000v40z"),
|
|
768
813
|
// tofrom is from glyph U+21C4 in font KaTeX AMS Regular
|
|
769
814
|
leftToFrom: "M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.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\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",
|
|
770
|
-
longequal: "M0 50 h400000 v40H0z m0 194h40000v40H0z
|
|
815
|
+
longequal: doubleBrushStroke("M0 50 h400000 v40H0z m0 194h40000v40H0z"),
|
|
771
816
|
midbrace: "M200428 334\nc-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\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",
|
|
772
817
|
midbraceunder: "M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",
|
|
773
818
|
oiintSize1: "M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",
|
|
@@ -784,9 +829,9 @@ const path = {
|
|
|
784
829
|
rightharpoondown: "M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",
|
|
785
830
|
rightharpoondownplus: "M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",
|
|
786
831
|
righthook: "M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-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\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",
|
|
787
|
-
rightlinesegment: "M399960 241 V94 h40 V428 h-40 V281 H0 v-40z
|
|
788
|
-
rightbracketunder: "M399995 0 h-120 V290 H0 v120 H400000z
|
|
789
|
-
rightbracketover: "M399995 440 h-120 V150 H0 v-120 H399995z
|
|
832
|
+
rightlinesegment: doubleBrushStroke("M399960 241 V94 h40 V428 h-40 V281 H0 v-40z"),
|
|
833
|
+
rightbracketunder: doubleBrushStroke("M399995 0 h-120 V290 H0 v120 H400000z"),
|
|
834
|
+
rightbracketover: doubleBrushStroke("M399995 440 h-120 V150 H0 v-120 H399995z"),
|
|
790
835
|
rightToFrom: "M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",
|
|
791
836
|
// twoheadleftarrow is from glyph U+219E in font KaTeX AMS Regular
|
|
792
837
|
twoheadleftarrow: "M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",
|
|
@@ -854,6 +899,10 @@ const tallDelim = function (label, midHeight) {
|
|
|
854
899
|
;// ./src/tree.ts
|
|
855
900
|
// To ensure that all nodes have compatible signatures for these methods.
|
|
856
901
|
|
|
902
|
+
function isMathDomNode(node) {
|
|
903
|
+
return 'toText' in node;
|
|
904
|
+
}
|
|
905
|
+
|
|
857
906
|
/**
|
|
858
907
|
* This node represents a document fragment, which contains elements, but when
|
|
859
908
|
* placed into the DOM doesn't have any representation itself. It only contains
|
|
@@ -863,6 +912,12 @@ class DocumentFragment {
|
|
|
863
912
|
// Never used; needed for satisfying interface.
|
|
864
913
|
|
|
865
914
|
constructor(children) {
|
|
915
|
+
this.children = void 0;
|
|
916
|
+
this.classes = void 0;
|
|
917
|
+
this.height = void 0;
|
|
918
|
+
this.depth = void 0;
|
|
919
|
+
this.maxFontSize = void 0;
|
|
920
|
+
this.style = void 0;
|
|
866
921
|
this.children = children;
|
|
867
922
|
this.classes = [];
|
|
868
923
|
this.height = 0;
|
|
@@ -899,11 +954,12 @@ class DocumentFragment {
|
|
|
899
954
|
* MathDomNode's only.
|
|
900
955
|
*/
|
|
901
956
|
toText() {
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
957
|
+
return this.children.map(child => {
|
|
958
|
+
if (isMathDomNode(child)) {
|
|
959
|
+
return child.toText();
|
|
960
|
+
}
|
|
961
|
+
throw new Error("Expected MathDomNode with toText, got " + child.constructor.name);
|
|
962
|
+
}).join("");
|
|
907
963
|
}
|
|
908
964
|
}
|
|
909
965
|
;// ./src/units.ts
|
|
@@ -1042,6 +1098,21 @@ const makeEm = function (n) {
|
|
|
1042
1098
|
const createClass = function (classes) {
|
|
1043
1099
|
return classes.filter(cls => cls).join(" ");
|
|
1044
1100
|
};
|
|
1101
|
+
|
|
1102
|
+
/**
|
|
1103
|
+
* Serialize a CssStyle object into a semicolon-delimited inline-style string
|
|
1104
|
+
* (hyphenating camelCase property names). Returns "" when no property is set.
|
|
1105
|
+
*/
|
|
1106
|
+
const cssStyleToString = function (style) {
|
|
1107
|
+
let styles = "";
|
|
1108
|
+
for (const key of Object.keys(style)) {
|
|
1109
|
+
const value = style[key];
|
|
1110
|
+
if (value !== undefined) {
|
|
1111
|
+
styles += hyphenate(key) + ":" + value + ";";
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
return styles;
|
|
1115
|
+
};
|
|
1045
1116
|
const initNode = function (classes, options, style) {
|
|
1046
1117
|
this.classes = classes || [];
|
|
1047
1118
|
this.attributes = {};
|
|
@@ -1070,9 +1141,7 @@ const toNode = function (tagName) {
|
|
|
1070
1141
|
node.className = createClass(this.classes);
|
|
1071
1142
|
|
|
1072
1143
|
// Apply inline styles
|
|
1073
|
-
|
|
1074
|
-
node.style[key] = this.style[key];
|
|
1075
|
-
}
|
|
1144
|
+
Object.assign(node.style, this.style);
|
|
1076
1145
|
|
|
1077
1146
|
// Apply attributes
|
|
1078
1147
|
for (const attr of Object.keys(this.attributes)) {
|
|
@@ -1106,12 +1175,7 @@ const toMarkup = function (tagName) {
|
|
|
1106
1175
|
if (this.classes.length) {
|
|
1107
1176
|
markup += " class=\"" + utils_escape(createClass(this.classes)) + "\"";
|
|
1108
1177
|
}
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
// Add the styles, after hyphenation
|
|
1112
|
-
for (const key of Object.keys(this.style)) {
|
|
1113
|
-
styles += hyphenate(key) + ":" + this.style[key] + ";";
|
|
1114
|
-
}
|
|
1178
|
+
const styles = cssStyleToString(this.style);
|
|
1115
1179
|
if (styles) {
|
|
1116
1180
|
markup += " style=\"" + utils_escape(styles) + "\"";
|
|
1117
1181
|
}
|
|
@@ -1156,6 +1220,20 @@ const toMarkup = function (tagName) {
|
|
|
1156
1220
|
*/
|
|
1157
1221
|
class Span {
|
|
1158
1222
|
constructor(classes, children, options, style) {
|
|
1223
|
+
this.children = void 0;
|
|
1224
|
+
this.attributes = void 0;
|
|
1225
|
+
this.classes = void 0;
|
|
1226
|
+
this.height = void 0;
|
|
1227
|
+
this.depth = void 0;
|
|
1228
|
+
this.width = void 0;
|
|
1229
|
+
this.maxFontSize = void 0;
|
|
1230
|
+
this.style = void 0;
|
|
1231
|
+
/**
|
|
1232
|
+
* Italic correction carried over from a SymbolNode when the symbol is
|
|
1233
|
+
* wrapped in a vlist (e.g. \oiint / \oiiint). Read by supsub to adjust
|
|
1234
|
+
* subscript positioning. Only set when nonzero; use `?? 0` at read sites.
|
|
1235
|
+
*/
|
|
1236
|
+
this.italic = void 0;
|
|
1159
1237
|
initNode.call(this, classes, options, style);
|
|
1160
1238
|
this.children = children || [];
|
|
1161
1239
|
}
|
|
@@ -1185,6 +1263,13 @@ class Span {
|
|
|
1185
1263
|
*/
|
|
1186
1264
|
class Anchor {
|
|
1187
1265
|
constructor(href, classes, children, options) {
|
|
1266
|
+
this.children = void 0;
|
|
1267
|
+
this.attributes = void 0;
|
|
1268
|
+
this.classes = void 0;
|
|
1269
|
+
this.height = void 0;
|
|
1270
|
+
this.depth = void 0;
|
|
1271
|
+
this.maxFontSize = void 0;
|
|
1272
|
+
this.style = void 0;
|
|
1188
1273
|
initNode.call(this, classes, options);
|
|
1189
1274
|
this.children = children || [];
|
|
1190
1275
|
this.setAttribute('href', href);
|
|
@@ -1208,6 +1293,13 @@ class Anchor {
|
|
|
1208
1293
|
*/
|
|
1209
1294
|
class Img {
|
|
1210
1295
|
constructor(src, alt, style) {
|
|
1296
|
+
this.src = void 0;
|
|
1297
|
+
this.alt = void 0;
|
|
1298
|
+
this.classes = void 0;
|
|
1299
|
+
this.height = void 0;
|
|
1300
|
+
this.depth = void 0;
|
|
1301
|
+
this.maxFontSize = void 0;
|
|
1302
|
+
this.style = void 0;
|
|
1211
1303
|
this.alt = alt;
|
|
1212
1304
|
this.src = src;
|
|
1213
1305
|
this.classes = ["mord"];
|
|
@@ -1226,19 +1318,12 @@ class Img {
|
|
|
1226
1318
|
node.className = "mord";
|
|
1227
1319
|
|
|
1228
1320
|
// Apply inline styles
|
|
1229
|
-
|
|
1230
|
-
node.style[key] = this.style[key];
|
|
1231
|
-
}
|
|
1321
|
+
Object.assign(node.style, this.style);
|
|
1232
1322
|
return node;
|
|
1233
1323
|
}
|
|
1234
1324
|
toMarkup() {
|
|
1235
1325
|
let markup = "<img src=\"" + utils_escape(this.src) + "\"" + (" alt=\"" + utils_escape(this.alt) + "\"");
|
|
1236
|
-
|
|
1237
|
-
// Add the styles, after hyphenation
|
|
1238
|
-
let styles = "";
|
|
1239
|
-
for (const key of Object.keys(this.style)) {
|
|
1240
|
-
styles += hyphenate(key) + ":" + this.style[key] + ";";
|
|
1241
|
-
}
|
|
1326
|
+
const styles = cssStyleToString(this.style);
|
|
1242
1327
|
if (styles) {
|
|
1243
1328
|
markup += " style=\"" + utils_escape(styles) + "\"";
|
|
1244
1329
|
}
|
|
@@ -1261,6 +1346,15 @@ const iCombinations = {
|
|
|
1261
1346
|
*/
|
|
1262
1347
|
class SymbolNode {
|
|
1263
1348
|
constructor(text, height, depth, italic, skew, width, classes, style) {
|
|
1349
|
+
this.text = void 0;
|
|
1350
|
+
this.height = void 0;
|
|
1351
|
+
this.depth = void 0;
|
|
1352
|
+
this.italic = void 0;
|
|
1353
|
+
this.skew = void 0;
|
|
1354
|
+
this.width = void 0;
|
|
1355
|
+
this.maxFontSize = void 0;
|
|
1356
|
+
this.classes = void 0;
|
|
1357
|
+
this.style = void 0;
|
|
1264
1358
|
this.text = text;
|
|
1265
1359
|
this.height = height || 0;
|
|
1266
1360
|
this.depth = depth || 0;
|
|
@@ -1306,9 +1400,9 @@ class SymbolNode {
|
|
|
1306
1400
|
span = span || document.createElement("span");
|
|
1307
1401
|
span.className = createClass(this.classes);
|
|
1308
1402
|
}
|
|
1309
|
-
|
|
1403
|
+
if (Object.keys(this.style).length > 0) {
|
|
1310
1404
|
span = span || document.createElement("span");
|
|
1311
|
-
span.style
|
|
1405
|
+
Object.assign(span.style, this.style);
|
|
1312
1406
|
}
|
|
1313
1407
|
if (span) {
|
|
1314
1408
|
span.appendChild(node);
|
|
@@ -1336,9 +1430,7 @@ class SymbolNode {
|
|
|
1336
1430
|
if (this.italic > 0) {
|
|
1337
1431
|
styles += "margin-right:" + makeEm(this.italic) + ";";
|
|
1338
1432
|
}
|
|
1339
|
-
|
|
1340
|
-
styles += hyphenate(key) + ":" + this.style[key] + ";";
|
|
1341
|
-
}
|
|
1433
|
+
styles += cssStyleToString(this.style);
|
|
1342
1434
|
if (styles) {
|
|
1343
1435
|
needsSpan = true;
|
|
1344
1436
|
markup += " style=\"" + utils_escape(styles) + "\"";
|
|
@@ -1360,6 +1452,8 @@ class SymbolNode {
|
|
|
1360
1452
|
*/
|
|
1361
1453
|
class SvgNode {
|
|
1362
1454
|
constructor(children, attributes) {
|
|
1455
|
+
this.children = void 0;
|
|
1456
|
+
this.attributes = void 0;
|
|
1363
1457
|
this.children = children || [];
|
|
1364
1458
|
this.attributes = attributes || {};
|
|
1365
1459
|
}
|
|
@@ -1393,6 +1487,8 @@ class SvgNode {
|
|
|
1393
1487
|
}
|
|
1394
1488
|
class PathNode {
|
|
1395
1489
|
constructor(pathName, alternate) {
|
|
1490
|
+
this.pathName = void 0;
|
|
1491
|
+
this.alternate = void 0;
|
|
1396
1492
|
this.pathName = pathName;
|
|
1397
1493
|
this.alternate = alternate; // Used only for \sqrt, \phase, & tall delims
|
|
1398
1494
|
}
|
|
@@ -1416,6 +1512,7 @@ class PathNode {
|
|
|
1416
1512
|
}
|
|
1417
1513
|
class LineNode {
|
|
1418
1514
|
constructor(attributes) {
|
|
1515
|
+
this.attributes = void 0;
|
|
1419
1516
|
this.attributes = attributes || {};
|
|
1420
1517
|
}
|
|
1421
1518
|
toNode() {
|
|
@@ -3539,6 +3636,12 @@ const hasHtmlDomChildren = node => node instanceof Span || node instanceof Ancho
|
|
|
3539
3636
|
});
|
|
3540
3637
|
;// ./src/fontMetrics.ts
|
|
3541
3638
|
|
|
3639
|
+
// This map contains a mapping from font name and character code to character
|
|
3640
|
+
// metrics, including height, depth, italic correction, and skew (kern from the
|
|
3641
|
+
// character to the corresponding \skewchar)
|
|
3642
|
+
// This map is generated via `make metrics`. It should not be changed manually.
|
|
3643
|
+
|
|
3644
|
+
|
|
3542
3645
|
/**
|
|
3543
3646
|
* This file contains metrics regarding fonts and individual symbols. The sigma
|
|
3544
3647
|
* and xi variables, as well as the metricMap map contain data extracted from
|
|
@@ -3653,12 +3756,6 @@ const sigmasAndXis = {
|
|
|
3653
3756
|
fboxrule: [0.04, 0.04, 0.04] // 0.4 pt / ptPerEm
|
|
3654
3757
|
};
|
|
3655
3758
|
|
|
3656
|
-
// This map contains a mapping from font name and character code to character
|
|
3657
|
-
// metrics, including height, depth, italic correction, and skew (kern from the
|
|
3658
|
-
// character to the corresponding \skewchar)
|
|
3659
|
-
// This map is generated via `make metrics`. It should not be changed manually.
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
3759
|
// These are very rough approximations. We default to Times New Roman which
|
|
3663
3760
|
// should have Latin-1 and Cyrillic characters, but may not depending on the
|
|
3664
3761
|
// operating system. The metrics do not account for extra height from the
|
|
@@ -3740,6 +3837,7 @@ const extraCharacterMap = {
|
|
|
3740
3837
|
'ю': 'm',
|
|
3741
3838
|
'я': 'r'
|
|
3742
3839
|
};
|
|
3840
|
+
|
|
3743
3841
|
/**
|
|
3744
3842
|
* This function adds new font metrics to default metricMap
|
|
3745
3843
|
* It can also override existing metrics
|
|
@@ -3837,21 +3935,7 @@ function getGlobalMetrics(size) {
|
|
|
3837
3935
|
// types for raw text tokens, and we want to avoid conflicts with higher-level
|
|
3838
3936
|
// `ParseNode` types. These `ParseNode`s are constructed within `Parser` by
|
|
3839
3937
|
// looking up the `symbols` map.
|
|
3840
|
-
|
|
3841
|
-
"bin": 1,
|
|
3842
|
-
"close": 1,
|
|
3843
|
-
"inner": 1,
|
|
3844
|
-
"open": 1,
|
|
3845
|
-
"punct": 1,
|
|
3846
|
-
"rel": 1
|
|
3847
|
-
};
|
|
3848
|
-
const NON_ATOMS = {
|
|
3849
|
-
"accent-token": 1,
|
|
3850
|
-
"mathord": 1,
|
|
3851
|
-
"op-token": 1,
|
|
3852
|
-
"spacing": 1,
|
|
3853
|
-
"textord": 1
|
|
3854
|
-
};
|
|
3938
|
+
|
|
3855
3939
|
const symbols = {
|
|
3856
3940
|
"math": {},
|
|
3857
3941
|
"text": {}
|
|
@@ -4397,8 +4481,8 @@ defineSymbol(symbols_text, main, spacing, "\u00a0", "\\ ");
|
|
|
4397
4481
|
defineSymbol(symbols_text, main, spacing, "\u00a0", " ");
|
|
4398
4482
|
defineSymbol(symbols_text, main, spacing, "\u00a0", "\\space");
|
|
4399
4483
|
defineSymbol(symbols_text, main, spacing, "\u00a0", "\\nobreakspace");
|
|
4400
|
-
defineSymbol(math, main, spacing,
|
|
4401
|
-
defineSymbol(math, main, spacing,
|
|
4484
|
+
defineSymbol(math, main, spacing, "", "\\nobreak");
|
|
4485
|
+
defineSymbol(math, main, spacing, "", "\\allowbreak");
|
|
4402
4486
|
defineSymbol(math, main, punct, ",", ",");
|
|
4403
4487
|
defineSymbol(math, main, punct, ";", ";");
|
|
4404
4488
|
defineSymbol(math, ams, bin, "\u22bc", "\\barwedge", true);
|
|
@@ -4600,7 +4684,7 @@ defineSymbol(symbols_text, main, mathord, "h", "\u210E");
|
|
|
4600
4684
|
// Mathematical Alphanumeric Symbols.
|
|
4601
4685
|
// Some editors do not deal well with wide characters. So don't write the
|
|
4602
4686
|
// string into this file. Instead, create the string from the surrogate pair.
|
|
4603
|
-
let wideChar
|
|
4687
|
+
let wideChar;
|
|
4604
4688
|
for (let i = 0; i < letters.length; i++) {
|
|
4605
4689
|
const ch = letters.charAt(i);
|
|
4606
4690
|
|
|
@@ -4689,116 +4773,136 @@ for (let i = 0; i < extraLatin.length; i++) {
|
|
|
4689
4773
|
*/
|
|
4690
4774
|
|
|
4691
4775
|
|
|
4776
|
+
const boldUpright = {
|
|
4777
|
+
mathClass: "mathbf",
|
|
4778
|
+
textClass: "textbf",
|
|
4779
|
+
font: "Main-Bold"
|
|
4780
|
+
};
|
|
4781
|
+
const italic = {
|
|
4782
|
+
mathClass: "mathnormal",
|
|
4783
|
+
textClass: "textit",
|
|
4784
|
+
font: "Math-Italic"
|
|
4785
|
+
};
|
|
4786
|
+
const boldItalic = {
|
|
4787
|
+
mathClass: "boldsymbol",
|
|
4788
|
+
textClass: "boldsymbol",
|
|
4789
|
+
font: "Main-BoldItalic"
|
|
4790
|
+
};
|
|
4791
|
+
const script = {
|
|
4792
|
+
mathClass: "mathscr",
|
|
4793
|
+
textClass: "textscr",
|
|
4794
|
+
font: "Script-Regular"
|
|
4795
|
+
};
|
|
4796
|
+
const noFont = {
|
|
4797
|
+
mathClass: "",
|
|
4798
|
+
textClass: "",
|
|
4799
|
+
font: ""
|
|
4800
|
+
};
|
|
4801
|
+
const fraktur = {
|
|
4802
|
+
mathClass: "mathfrak",
|
|
4803
|
+
textClass: "textfrak",
|
|
4804
|
+
font: "Fraktur-Regular"
|
|
4805
|
+
};
|
|
4806
|
+
const doubleStruck = {
|
|
4807
|
+
mathClass: "mathbb",
|
|
4808
|
+
textClass: "textbb",
|
|
4809
|
+
font: "AMS-Regular"
|
|
4810
|
+
};
|
|
4811
|
+
const boldFraktur = {
|
|
4812
|
+
mathClass: "mathboldfrak",
|
|
4813
|
+
textClass: "textboldfrak",
|
|
4814
|
+
font: "Fraktur-Regular"
|
|
4815
|
+
};
|
|
4816
|
+
const sansSerif = {
|
|
4817
|
+
mathClass: "mathsf",
|
|
4818
|
+
textClass: "textsf",
|
|
4819
|
+
font: "SansSerif-Regular"
|
|
4820
|
+
};
|
|
4821
|
+
const boldSansSerif = {
|
|
4822
|
+
mathClass: "mathboldsf",
|
|
4823
|
+
textClass: "textboldsf",
|
|
4824
|
+
font: "SansSerif-Bold"
|
|
4825
|
+
};
|
|
4826
|
+
const italicSansSerif = {
|
|
4827
|
+
mathClass: "mathitsf",
|
|
4828
|
+
textClass: "textitsf",
|
|
4829
|
+
font: "SansSerif-Italic"
|
|
4830
|
+
};
|
|
4831
|
+
const monospace = {
|
|
4832
|
+
mathClass: "mathtt",
|
|
4833
|
+
textClass: "texttt",
|
|
4834
|
+
font: "Typewriter-Regular"
|
|
4835
|
+
};
|
|
4692
4836
|
|
|
4693
4837
|
/**
|
|
4694
4838
|
* Data below is from https://www.unicode.org/charts/PDF/U1D400.pdf
|
|
4695
4839
|
* That document sorts characters into groups by font type, say bold or italic.
|
|
4696
4840
|
*
|
|
4697
|
-
* In the arrays below, each
|
|
4841
|
+
* In the arrays below, each object consists of three properties:
|
|
4698
4842
|
* * The CSS class of that group when in math mode.
|
|
4699
4843
|
* * The CSS class of that group when in text mode.
|
|
4700
4844
|
* * The font name, so that KaTeX can get font metrics.
|
|
4701
4845
|
*/
|
|
4702
4846
|
|
|
4703
|
-
const wideLatinLetterData = [
|
|
4704
|
-
// A-Z
|
|
4705
|
-
|
|
4706
|
-
// a-z
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
// A-Z italic
|
|
4710
|
-
["mathnormal", "textit", "Math-Italic"],
|
|
4711
|
-
// a-z italic
|
|
4712
|
-
|
|
4713
|
-
["boldsymbol", "boldsymbol", "Main-BoldItalic"],
|
|
4714
|
-
// A-Z bold italic
|
|
4715
|
-
["boldsymbol", "boldsymbol", "Main-BoldItalic"],
|
|
4716
|
-
// a-z bold italic
|
|
4717
|
-
|
|
4847
|
+
const wideLatinLetterData = [boldUpright, boldUpright,
|
|
4848
|
+
// A-Z, a-z
|
|
4849
|
+
italic, italic,
|
|
4850
|
+
// A-Z, a-z
|
|
4851
|
+
boldItalic, boldItalic,
|
|
4852
|
+
// A-Z, a-z
|
|
4718
4853
|
// Map fancy A-Z letters to script, not calligraphic.
|
|
4719
4854
|
// This aligns with unicode-math and math fonts (except Cambria Math).
|
|
4720
|
-
|
|
4721
|
-
// A-Z script
|
|
4722
|
-
|
|
4723
|
-
// a-z script
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
// a-z bold script. No font
|
|
4729
|
-
|
|
4730
|
-
["mathfrak", "textfrak", "Fraktur-Regular"],
|
|
4731
|
-
// A-Z Fraktur
|
|
4732
|
-
["mathfrak", "textfrak", "Fraktur-Regular"],
|
|
4733
|
-
// a-z Fraktur
|
|
4734
|
-
|
|
4735
|
-
["mathbb", "textbb", "AMS-Regular"],
|
|
4736
|
-
// A-Z double-struck
|
|
4737
|
-
["mathbb", "textbb", "AMS-Regular"],
|
|
4738
|
-
// k double-struck
|
|
4739
|
-
|
|
4855
|
+
script, noFont,
|
|
4856
|
+
// A-Z script, a-z — no font
|
|
4857
|
+
noFont, noFont,
|
|
4858
|
+
// A-Z bold script, a-z bold script — no font
|
|
4859
|
+
fraktur, fraktur,
|
|
4860
|
+
// A-Z, a-z
|
|
4861
|
+
doubleStruck, doubleStruck,
|
|
4862
|
+
// A-Z double-struck, k double-struck
|
|
4740
4863
|
// Note that we are using a bold font, but font metrics for regular Fraktur.
|
|
4741
|
-
|
|
4742
|
-
// A-Z
|
|
4743
|
-
|
|
4744
|
-
// a-z
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
// A-Z bold sans-serif
|
|
4753
|
-
["mathboldsf", "textboldsf", "SansSerif-Bold"],
|
|
4754
|
-
// a-z bold sans-serif
|
|
4755
|
-
|
|
4756
|
-
["mathitsf", "textitsf", "SansSerif-Italic"],
|
|
4757
|
-
// A-Z italic sans-serif
|
|
4758
|
-
["mathitsf", "textitsf", "SansSerif-Italic"],
|
|
4759
|
-
// a-z italic sans-serif
|
|
4760
|
-
|
|
4761
|
-
["", "", ""],
|
|
4762
|
-
// A-Z bold italic sans. No font
|
|
4763
|
-
["", "", ""],
|
|
4764
|
-
// a-z bold italic sans. No font
|
|
4765
|
-
|
|
4766
|
-
["mathtt", "texttt", "Typewriter-Regular"],
|
|
4767
|
-
// A-Z monospace
|
|
4768
|
-
["mathtt", "texttt", "Typewriter-Regular"] // a-z monospace
|
|
4864
|
+
boldFraktur, boldFraktur,
|
|
4865
|
+
// A-Z, a-z
|
|
4866
|
+
sansSerif, sansSerif,
|
|
4867
|
+
// A-Z, a-z
|
|
4868
|
+
boldSansSerif, boldSansSerif,
|
|
4869
|
+
// A-Z, a-z
|
|
4870
|
+
italicSansSerif, italicSansSerif,
|
|
4871
|
+
// A-Z, a-z
|
|
4872
|
+
noFont, noFont,
|
|
4873
|
+
// A-Z bold italic sans, a-z bold italic sans - no font
|
|
4874
|
+
monospace, monospace // A-Z, a-z
|
|
4769
4875
|
];
|
|
4770
|
-
const wideNumeralData = [
|
|
4771
|
-
// 0-9
|
|
4772
|
-
|
|
4876
|
+
const wideNumeralData = [boldUpright,
|
|
4877
|
+
// 0-9
|
|
4878
|
+
noFont,
|
|
4773
4879
|
// 0-9 double-struck. No KaTeX font.
|
|
4774
|
-
|
|
4775
|
-
// 0-9
|
|
4776
|
-
|
|
4777
|
-
// 0-9
|
|
4778
|
-
|
|
4880
|
+
sansSerif,
|
|
4881
|
+
// 0-9
|
|
4882
|
+
boldSansSerif,
|
|
4883
|
+
// 0-9
|
|
4884
|
+
monospace // 0-9
|
|
4779
4885
|
];
|
|
4780
|
-
const wideCharacterFont =
|
|
4886
|
+
const wideCharacterFont = wideChar => {
|
|
4781
4887
|
// IE doesn't support codePointAt(). So work with the surrogate pair.
|
|
4782
4888
|
const H = wideChar.charCodeAt(0); // high surrogate
|
|
4783
4889
|
const L = wideChar.charCodeAt(1); // low surrogate
|
|
4784
4890
|
const codePoint = (H - 0xD800) * 0x400 + (L - 0xDC00) + 0x10000;
|
|
4785
|
-
const j = mode === "math" ? 0 : 1; // column index for CSS class.
|
|
4786
|
-
|
|
4787
4891
|
if (0x1D400 <= codePoint && codePoint < 0x1D6A4) {
|
|
4788
4892
|
// wideLatinLetterData contains exactly 26 chars on each row.
|
|
4789
4893
|
// So we can calculate the relevant row. No traverse necessary.
|
|
4790
4894
|
const i = Math.floor((codePoint - 0x1D400) / 26);
|
|
4791
|
-
return
|
|
4895
|
+
return wideLatinLetterData[i];
|
|
4792
4896
|
} else if (0x1D7CE <= codePoint && codePoint <= 0x1D7FF) {
|
|
4793
4897
|
// Numerals, ten per row.
|
|
4794
4898
|
const i = Math.floor((codePoint - 0x1D7CE) / 10);
|
|
4795
|
-
return
|
|
4899
|
+
return wideNumeralData[i];
|
|
4796
4900
|
} else if (codePoint === 0x1D6A5 || codePoint === 0x1D6A6) {
|
|
4797
4901
|
// dotless i or j
|
|
4798
|
-
return
|
|
4902
|
+
return wideLatinLetterData[0];
|
|
4799
4903
|
} else if (0x1D6A6 < codePoint && codePoint < 0x1D7CE) {
|
|
4800
4904
|
// Greek letters. Not supported, yet.
|
|
4801
|
-
return
|
|
4905
|
+
return noFont;
|
|
4802
4906
|
} else {
|
|
4803
4907
|
// We don't support any wide characters outside 1D400–1D7FF.
|
|
4804
4908
|
throw new src_ParseError("Unsupported character: " + wideChar);
|
|
@@ -4821,9 +4925,7 @@ const wideCharacterFont = (wideChar, mode) => {
|
|
|
4821
4925
|
* Looks up the given symbol in fontMetrics, after applying any symbol
|
|
4822
4926
|
* replacements defined in symbol.js
|
|
4823
4927
|
*/
|
|
4824
|
-
const lookupSymbol = function (value,
|
|
4825
|
-
// TODO(#963): Use a union type for this.
|
|
4826
|
-
fontName, mode) {
|
|
4928
|
+
const lookupSymbol = function (value, fontName, mode) {
|
|
4827
4929
|
// Replace the value with its replaced value from symbol.js
|
|
4828
4930
|
if (src_symbols[mode][value]) {
|
|
4829
4931
|
const replacement = src_symbols[mode][value].replace;
|
|
@@ -4906,7 +5008,7 @@ const mathsym = function (value, mode, options, classes) {
|
|
|
4906
5008
|
* depending on the symbol. Use this function instead of fontMap for font
|
|
4907
5009
|
* "boldsymbol".
|
|
4908
5010
|
*/
|
|
4909
|
-
const
|
|
5011
|
+
const boldSymbol = function (value, mode, type) {
|
|
4910
5012
|
if (type !== "textord" && lookupSymbol(value, "Math-BoldItalic", mode).metrics) {
|
|
4911
5013
|
return {
|
|
4912
5014
|
fontName: "Math-BoldItalic",
|
|
@@ -4929,31 +5031,39 @@ const makeOrd = function (group, options, type) {
|
|
|
4929
5031
|
const mode = group.mode;
|
|
4930
5032
|
const text = group.text;
|
|
4931
5033
|
const classes = ["mord"];
|
|
5034
|
+
const {
|
|
5035
|
+
font,
|
|
5036
|
+
fontFamily,
|
|
5037
|
+
fontWeight,
|
|
5038
|
+
fontShape
|
|
5039
|
+
} = options;
|
|
4932
5040
|
|
|
4933
5041
|
// Math mode or Old font (i.e. \rm)
|
|
4934
|
-
const
|
|
4935
|
-
const fontOrFamily =
|
|
5042
|
+
const useFont = mode === "math" || mode === "text" && !!font;
|
|
5043
|
+
const fontOrFamily = useFont ? font : fontFamily;
|
|
4936
5044
|
let wideFontName = "";
|
|
4937
5045
|
let wideFontClass = "";
|
|
4938
5046
|
if (text.charCodeAt(0) === 0xD835) {
|
|
4939
|
-
|
|
5047
|
+
const wideCharData = wideCharacterFont(text);
|
|
5048
|
+
wideFontName = wideCharData.font;
|
|
5049
|
+
wideFontClass = wideCharData[mode + "Class"];
|
|
4940
5050
|
}
|
|
4941
|
-
if (wideFontName
|
|
5051
|
+
if (wideFontName) {
|
|
4942
5052
|
// surrogate pairs get special treatment
|
|
4943
5053
|
return makeSymbol(text, wideFontName, mode, options, classes.concat(wideFontClass));
|
|
4944
5054
|
} else if (fontOrFamily) {
|
|
4945
5055
|
let fontName;
|
|
4946
5056
|
let fontClasses;
|
|
4947
5057
|
if (fontOrFamily === "boldsymbol") {
|
|
4948
|
-
const fontData =
|
|
5058
|
+
const fontData = boldSymbol(text, mode, type);
|
|
4949
5059
|
fontName = fontData.fontName;
|
|
4950
5060
|
fontClasses = [fontData.fontClass];
|
|
4951
|
-
} else if (
|
|
4952
|
-
fontName = fontMap[
|
|
4953
|
-
fontClasses = [
|
|
5061
|
+
} else if (useFont) {
|
|
5062
|
+
fontName = fontMap[font].fontName;
|
|
5063
|
+
fontClasses = [font];
|
|
4954
5064
|
} else {
|
|
4955
|
-
fontName = retrieveTextFontName(
|
|
4956
|
-
fontClasses = [
|
|
5065
|
+
fontName = retrieveTextFontName(fontFamily, fontWeight, fontShape);
|
|
5066
|
+
fontClasses = [fontFamily, fontWeight, fontShape];
|
|
4957
5067
|
}
|
|
4958
5068
|
if (lookupSymbol(text, fontName, mode).metrics) {
|
|
4959
5069
|
return makeSymbol(text, fontName, mode, options, classes.concat(fontClasses));
|
|
@@ -4973,16 +5083,16 @@ const makeOrd = function (group, options, type) {
|
|
|
4973
5083
|
} else if (type === "textord") {
|
|
4974
5084
|
const font = src_symbols[mode][text] && src_symbols[mode][text].font;
|
|
4975
5085
|
if (font === "ams") {
|
|
4976
|
-
const fontName = retrieveTextFontName("amsrm",
|
|
4977
|
-
return makeSymbol(text, fontName, mode, options, classes.concat("amsrm",
|
|
5086
|
+
const fontName = retrieveTextFontName("amsrm", fontWeight, fontShape);
|
|
5087
|
+
return makeSymbol(text, fontName, mode, options, classes.concat("amsrm", fontWeight, fontShape));
|
|
4978
5088
|
} else if (font === "main" || !font) {
|
|
4979
|
-
const fontName = retrieveTextFontName("textrm",
|
|
4980
|
-
return makeSymbol(text, fontName, mode, options, classes.concat(
|
|
5089
|
+
const fontName = retrieveTextFontName("textrm", fontWeight, fontShape);
|
|
5090
|
+
return makeSymbol(text, fontName, mode, options, classes.concat(fontWeight, fontShape));
|
|
4981
5091
|
} else {
|
|
4982
5092
|
// fonts added by plugins
|
|
4983
|
-
const fontName = retrieveTextFontName(font,
|
|
5093
|
+
const fontName = retrieveTextFontName(font, fontWeight, fontShape);
|
|
4984
5094
|
// We add font name as a css class
|
|
4985
|
-
return makeSymbol(text, fontName, mode, options, classes.concat(fontName,
|
|
5095
|
+
return makeSymbol(text, fontName, mode, options, classes.concat(fontName, fontWeight, fontShape));
|
|
4986
5096
|
}
|
|
4987
5097
|
} else {
|
|
4988
5098
|
throw new Error("unexpected type: " + type + " in makeOrd");
|
|
@@ -5290,8 +5400,9 @@ const makeGlue = (measurement, options) => {
|
|
|
5290
5400
|
};
|
|
5291
5401
|
|
|
5292
5402
|
// Takes font options, and returns the appropriate fontLookup name
|
|
5293
|
-
const retrieveTextFontName =
|
|
5294
|
-
let baseFontName
|
|
5403
|
+
const retrieveTextFontName = (fontFamily, fontWeight, fontShape) => {
|
|
5404
|
+
let baseFontName;
|
|
5405
|
+
let fontStylesName;
|
|
5295
5406
|
switch (fontFamily) {
|
|
5296
5407
|
case "amsrm":
|
|
5297
5408
|
baseFontName = "AMS";
|
|
@@ -5309,12 +5420,11 @@ const retrieveTextFontName = function (fontFamily, fontWeight, fontShape) {
|
|
|
5309
5420
|
baseFontName = fontFamily;
|
|
5310
5421
|
// use fonts added by a plugin
|
|
5311
5422
|
}
|
|
5312
|
-
let fontStylesName;
|
|
5313
5423
|
if (fontWeight === "textbf" && fontShape === "textit") {
|
|
5314
5424
|
fontStylesName = "BoldItalic";
|
|
5315
5425
|
} else if (fontWeight === "textbf") {
|
|
5316
5426
|
fontStylesName = "Bold";
|
|
5317
|
-
} else if (
|
|
5427
|
+
} else if (fontShape === "textit") {
|
|
5318
5428
|
fontStylesName = "Italic";
|
|
5319
5429
|
} else {
|
|
5320
5430
|
fontStylesName = "Regular";
|
|
@@ -5537,13 +5647,20 @@ const _functions = {};
|
|
|
5537
5647
|
/**
|
|
5538
5648
|
* All HTML builders. Should be only used in the `define*` and the `build*ML`
|
|
5539
5649
|
* functions.
|
|
5650
|
+
*
|
|
5651
|
+
* Builders for different node types are stored side by side, but
|
|
5652
|
+
* `HtmlBuilder<T>` is contravariant in `T`, so there is no single type
|
|
5653
|
+
* argument that makes storing/retrieving them typecheck. `any` is used
|
|
5654
|
+
* as an existential-quantifier escape hatch.
|
|
5540
5655
|
*/
|
|
5656
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5541
5657
|
const _htmlGroupBuilders = {};
|
|
5542
5658
|
|
|
5543
5659
|
/**
|
|
5544
5660
|
* All MathML builders. Should be only used in the `define*` and the `build*ML`
|
|
5545
|
-
* functions.
|
|
5661
|
+
* functions. See `_htmlGroupBuilders` above for the rationale behind `any`.
|
|
5546
5662
|
*/
|
|
5663
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5547
5664
|
const _mathmlGroupBuilders = {};
|
|
5548
5665
|
function defineFunction(_ref) {
|
|
5549
5666
|
let {
|
|
@@ -5749,7 +5866,8 @@ const traverseNonSpaceNodes = function (nodes, callback, prev, next, isRoot) {
|
|
|
5749
5866
|
const partialGroup = checkPartialGroup(node);
|
|
5750
5867
|
if (partialGroup) {
|
|
5751
5868
|
// Recursive DFS
|
|
5752
|
-
// TODO(ts):
|
|
5869
|
+
// TODO(ts): partialGroup.children is ReadonlyArray but this
|
|
5870
|
+
// function mutates the array (insertAfter splices into it).
|
|
5753
5871
|
traverseNonSpaceNodes(partialGroup.children, callback, prev, null, isRoot);
|
|
5754
5872
|
continue;
|
|
5755
5873
|
}
|
|
@@ -5837,8 +5955,8 @@ const buildGroup = function (group, options, baseOptions) {
|
|
|
5837
5955
|
return makeSpan();
|
|
5838
5956
|
}
|
|
5839
5957
|
if (_htmlGroupBuilders[group.type]) {
|
|
5840
|
-
//
|
|
5841
|
-
//
|
|
5958
|
+
// TODO(ts): groupBuilders is Record<string, HtmlBuilder<any>>;
|
|
5959
|
+
// a type-safe registry would need a mapped type keyed by NodeType.
|
|
5842
5960
|
let groupNode = _htmlGroupBuilders[group.type](group, options);
|
|
5843
5961
|
|
|
5844
5962
|
// If the size changed between the parent and the current group, account
|
|
@@ -5994,6 +6112,10 @@ function newDocumentFragment(children) {
|
|
|
5994
6112
|
*/
|
|
5995
6113
|
class MathNode {
|
|
5996
6114
|
constructor(type, children, classes) {
|
|
6115
|
+
this.type = void 0;
|
|
6116
|
+
this.attributes = void 0;
|
|
6117
|
+
this.children = void 0;
|
|
6118
|
+
this.classes = void 0;
|
|
5997
6119
|
this.type = type;
|
|
5998
6120
|
this.attributes = {};
|
|
5999
6121
|
this.children = children || [];
|
|
@@ -6082,6 +6204,7 @@ class MathNode {
|
|
|
6082
6204
|
*/
|
|
6083
6205
|
class TextNode {
|
|
6084
6206
|
constructor(text) {
|
|
6207
|
+
this.text = void 0;
|
|
6085
6208
|
this.text = text;
|
|
6086
6209
|
}
|
|
6087
6210
|
|
|
@@ -6118,6 +6241,8 @@ class SpaceNode {
|
|
|
6118
6241
|
* Create a Space node with width given in CSS ems.
|
|
6119
6242
|
*/
|
|
6120
6243
|
constructor(width) {
|
|
6244
|
+
this.width = void 0;
|
|
6245
|
+
this.character = void 0;
|
|
6121
6246
|
this.width = width;
|
|
6122
6247
|
// See https://www.w3.org/TR/2000/WD-MathML2-20000328/chapter6.html
|
|
6123
6248
|
// for a table of space-like characters. We use Unicode
|
|
@@ -6217,57 +6342,55 @@ const makeRow = function (body) {
|
|
|
6217
6342
|
return new MathNode("mrow", body);
|
|
6218
6343
|
}
|
|
6219
6344
|
};
|
|
6345
|
+
const mathFontVariants = {
|
|
6346
|
+
mathit: "italic",
|
|
6347
|
+
boldsymbol: group => group.type === "textord" ? "bold" : "bold-italic",
|
|
6348
|
+
mathbf: "bold",
|
|
6349
|
+
mathbb: "double-struck",
|
|
6350
|
+
mathsfit: "sans-serif-italic",
|
|
6351
|
+
mathfrak: "fraktur",
|
|
6352
|
+
mathscr: "script",
|
|
6353
|
+
mathcal: "script",
|
|
6354
|
+
mathsf: "sans-serif",
|
|
6355
|
+
mathtt: "monospace"
|
|
6356
|
+
};
|
|
6220
6357
|
|
|
6221
6358
|
/**
|
|
6222
6359
|
* Returns the math variant as a string or null if none is required.
|
|
6223
6360
|
*/
|
|
6224
|
-
const getVariant =
|
|
6361
|
+
const getVariant = (group, options) => {
|
|
6225
6362
|
// Handle \text... font specifiers as best we can.
|
|
6226
6363
|
// MathML has a limited list of allowable mathvariant specifiers; see
|
|
6227
6364
|
// https://www.w3.org/TR/MathML3/chapter3.html#presm.commatt
|
|
6228
|
-
if (
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
if (options.
|
|
6232
|
-
|
|
6365
|
+
if (group.mode === "text") {
|
|
6366
|
+
if (options.fontFamily === "texttt") {
|
|
6367
|
+
return "monospace";
|
|
6368
|
+
} else if (options.fontFamily === "textsf") {
|
|
6369
|
+
if (options.fontShape === "textit" && options.fontWeight === "textbf") {
|
|
6370
|
+
return "sans-serif-bold-italic";
|
|
6371
|
+
} else if (options.fontShape === "textit") {
|
|
6372
|
+
return "sans-serif-italic";
|
|
6373
|
+
} else if (options.fontWeight === "textbf") {
|
|
6374
|
+
return "bold-sans-serif";
|
|
6375
|
+
} else {
|
|
6376
|
+
return "sans-serif";
|
|
6377
|
+
}
|
|
6378
|
+
} else if (options.fontShape === "textit" && options.fontWeight === "textbf") {
|
|
6379
|
+
return "bold-italic";
|
|
6233
6380
|
} else if (options.fontShape === "textit") {
|
|
6234
|
-
return "
|
|
6381
|
+
return "italic";
|
|
6235
6382
|
} else if (options.fontWeight === "textbf") {
|
|
6236
|
-
return "bold
|
|
6237
|
-
} else {
|
|
6238
|
-
return "sans-serif";
|
|
6383
|
+
return "bold";
|
|
6239
6384
|
}
|
|
6240
|
-
} else if (options.fontShape === "textit" && options.fontWeight === "textbf") {
|
|
6241
|
-
return "bold-italic";
|
|
6242
|
-
} else if (options.fontShape === "textit") {
|
|
6243
|
-
return "italic";
|
|
6244
|
-
} else if (options.fontWeight === "textbf") {
|
|
6245
|
-
return "bold";
|
|
6246
6385
|
}
|
|
6247
6386
|
const font = options.font;
|
|
6248
6387
|
if (!font || font === "mathnormal") {
|
|
6249
6388
|
return null;
|
|
6250
6389
|
}
|
|
6251
6390
|
const mode = group.mode;
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
return group.type === "textord" ? "bold" : "bold-italic";
|
|
6256
|
-
} else if (font === "mathbf") {
|
|
6257
|
-
return "bold";
|
|
6258
|
-
} else if (font === "mathbb") {
|
|
6259
|
-
return "double-struck";
|
|
6260
|
-
} else if (font === "mathsfit") {
|
|
6261
|
-
return "sans-serif-italic";
|
|
6262
|
-
} else if (font === "mathfrak") {
|
|
6263
|
-
return "fraktur";
|
|
6264
|
-
} else if (font === "mathscr" || font === "mathcal") {
|
|
6265
|
-
// MathML makes no distinction between script and calligraphic
|
|
6266
|
-
return "script";
|
|
6267
|
-
} else if (font === "mathsf") {
|
|
6268
|
-
return "sans-serif";
|
|
6269
|
-
} else if (font === "mathtt") {
|
|
6270
|
-
return "monospace";
|
|
6391
|
+
const mathVariant = mathFontVariants[font];
|
|
6392
|
+
if (mathVariant) {
|
|
6393
|
+
return typeof mathVariant === "function" ? mathVariant(group) : mathVariant;
|
|
6271
6394
|
}
|
|
6272
6395
|
let text = group.text;
|
|
6273
6396
|
if (noVariantSymbols.has(text)) {
|
|
@@ -6387,11 +6510,10 @@ const buildMathML_buildGroup = function (group, options) {
|
|
|
6387
6510
|
return new MathNode("mrow");
|
|
6388
6511
|
}
|
|
6389
6512
|
if (_mathmlGroupBuilders[group.type]) {
|
|
6390
|
-
//
|
|
6391
|
-
//
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
return result;
|
|
6513
|
+
// TODO(ts): MathMLBuilder returns MathDomNode but all concrete
|
|
6514
|
+
// builders return MathNode. Widening the return type here would
|
|
6515
|
+
// require updating all callers that assume MathNode.
|
|
6516
|
+
return _mathmlGroupBuilders[group.type](group, options);
|
|
6395
6517
|
} else {
|
|
6396
6518
|
throw new src_ParseError("Got group of unknown type: '" + group.type + "'");
|
|
6397
6519
|
}
|
|
@@ -6436,8 +6558,11 @@ function buildMathML(tree, texExpression, options, isDisplayMode, forMathmlOnly)
|
|
|
6436
6558
|
// NOTE: The span class is not typed to have <math> nodes as children, and
|
|
6437
6559
|
// we don't want to make the children type more generic since the children
|
|
6438
6560
|
// of span are expected to have more fields in `buildHtml` contexts.
|
|
6561
|
+
// The MathNode implements VirtualNode (toNode/toMarkup) which is all that
|
|
6562
|
+
// Span needs from its children for rendering.
|
|
6563
|
+
// TODO(ts): Span's child type is HtmlDomNode, but MathNode only implements
|
|
6564
|
+
// VirtualNode. The double-cast acknowledges this architectural limitation.
|
|
6439
6565
|
const wrapperClass = forMathmlOnly ? "katex" : "katex-mathml";
|
|
6440
|
-
// TODO(ts)
|
|
6441
6566
|
return makeSpan([wrapperClass], [math]);
|
|
6442
6567
|
}
|
|
6443
6568
|
;// ./src/Options.ts
|
|
@@ -6481,9 +6606,6 @@ const sizeMultipliers = [
|
|
|
6481
6606
|
const sizeAtStyle = function (size, style) {
|
|
6482
6607
|
return style.size < 2 ? size : sizeStyleMap[size - 1][style.size - 1];
|
|
6483
6608
|
};
|
|
6484
|
-
|
|
6485
|
-
// In these types, "" (empty string) means "no change".
|
|
6486
|
-
|
|
6487
6609
|
/**
|
|
6488
6610
|
* This is the main options class. It contains the current style, size, color,
|
|
6489
6611
|
* and font.
|
|
@@ -6493,6 +6615,22 @@ const sizeAtStyle = function (size, style) {
|
|
|
6493
6615
|
*/
|
|
6494
6616
|
class Options {
|
|
6495
6617
|
constructor(data) {
|
|
6618
|
+
this.style = void 0;
|
|
6619
|
+
this.color = void 0;
|
|
6620
|
+
this.size = void 0;
|
|
6621
|
+
this.textSize = void 0;
|
|
6622
|
+
this.phantom = void 0;
|
|
6623
|
+
// A font family applies to a group of fonts (i.e. SansSerif), while a font
|
|
6624
|
+
// represents a specific font (i.e. SansSerif Bold).
|
|
6625
|
+
// See: https://tex.stackexchange.com/questions/22350/difference-between-textrm-and-mathrm
|
|
6626
|
+
this.font = void 0;
|
|
6627
|
+
this.fontFamily = void 0;
|
|
6628
|
+
this.fontWeight = void 0;
|
|
6629
|
+
this.fontShape = void 0;
|
|
6630
|
+
this.sizeMultiplier = void 0;
|
|
6631
|
+
this.maxSize = void 0;
|
|
6632
|
+
this.minRuleThickness = void 0;
|
|
6633
|
+
this._fontMetrics = void 0;
|
|
6496
6634
|
this.style = data.style;
|
|
6497
6635
|
this.color = data.color;
|
|
6498
6636
|
this.size = data.size || Options.BASESIZE;
|
|
@@ -6500,8 +6638,8 @@ class Options {
|
|
|
6500
6638
|
this.phantom = !!data.phantom;
|
|
6501
6639
|
this.font = data.font || "";
|
|
6502
6640
|
this.fontFamily = data.fontFamily || "";
|
|
6503
|
-
this.fontWeight = data.fontWeight ||
|
|
6504
|
-
this.fontShape = data.fontShape ||
|
|
6641
|
+
this.fontWeight = data.fontWeight || "";
|
|
6642
|
+
this.fontShape = data.fontShape || "";
|
|
6505
6643
|
this.sizeMultiplier = sizeMultipliers[this.size - 1];
|
|
6506
6644
|
this.maxSize = data.maxSize;
|
|
6507
6645
|
this.minRuleThickness = data.minRuleThickness;
|
|
@@ -6715,9 +6853,6 @@ class Options {
|
|
|
6715
6853
|
}
|
|
6716
6854
|
}
|
|
6717
6855
|
}
|
|
6718
|
-
// A font family applies to a group of fonts (i.e. SansSerif), while a font
|
|
6719
|
-
// represents a specific font (i.e. SansSerif Bold).
|
|
6720
|
-
// See: https://tex.stackexchange.com/questions/22350/difference-between-textrm-and-mathrm
|
|
6721
6856
|
/**
|
|
6722
6857
|
* The base size index.
|
|
6723
6858
|
*/
|
|
@@ -6863,18 +6998,6 @@ const stretchyMathML = function (label) {
|
|
|
6863
6998
|
// Some functions, such as \cancel, need to vary their aspect ratio. These
|
|
6864
6999
|
// functions do not get the overflow SVG treatment.
|
|
6865
7000
|
|
|
6866
|
-
// Second Brush Stroke
|
|
6867
|
-
// Low resolution monitors struggle to display images in fine detail.
|
|
6868
|
-
// So browsers apply anti-aliasing. A long straight arrow shaft therefore
|
|
6869
|
-
// will sometimes appear as if it has a blurred edge.
|
|
6870
|
-
|
|
6871
|
-
// To mitigate this, these SVG files contain a second "brush-stroke" on the
|
|
6872
|
-
// arrow shafts. That is, a second long thin rectangular SVG path has been
|
|
6873
|
-
// written directly on top of each arrow shaft. This reinforcement causes
|
|
6874
|
-
// some of the screen pixels to display as black instead of the anti-aliased
|
|
6875
|
-
// gray pixel that a single path would generate. So we get arrow shafts
|
|
6876
|
-
// whose edges appear to be sharper.
|
|
6877
|
-
|
|
6878
7001
|
// In the katexImagesData object just below, the dimensions all
|
|
6879
7002
|
// correspond to path geometry inside the relevant SVG.
|
|
6880
7003
|
// For example, \overrightarrow uses the same arrowhead as glyph U+2192
|
|
@@ -6938,14 +7061,10 @@ const stretchySvg = function (group, options) {
|
|
|
6938
7061
|
function buildSvgSpan_() {
|
|
6939
7062
|
let viewBoxWidth = 400000; // default
|
|
6940
7063
|
const label = group.label.slice(1);
|
|
6941
|
-
if (wideAccentLabels.has(label)) {
|
|
6942
|
-
// Each type in the `if` statement corresponds to one of the ParseNode
|
|
6943
|
-
// types below. This narrowing is required to access `grp.base`.
|
|
6944
|
-
// TODO(ts)
|
|
6945
|
-
const grp = group;
|
|
7064
|
+
if (wideAccentLabels.has(label) && 'base' in group) {
|
|
6946
7065
|
// There are four SVG images available for each function.
|
|
6947
7066
|
// Choose a taller image when there are more characters.
|
|
6948
|
-
const numChars =
|
|
7067
|
+
const numChars = group.base.type === "ordgroup" ? group.base.body.length : 1;
|
|
6949
7068
|
let viewBoxHeight;
|
|
6950
7069
|
let pathName;
|
|
6951
7070
|
let height;
|
|
@@ -6990,16 +7109,20 @@ const stretchySvg = function (group, options) {
|
|
|
6990
7109
|
} else {
|
|
6991
7110
|
const spans = [];
|
|
6992
7111
|
const data = katexImagesData[label];
|
|
7112
|
+
if (!data) {
|
|
7113
|
+
throw new Error("No SVG data for \"" + label + "\".");
|
|
7114
|
+
}
|
|
6993
7115
|
const [paths, minWidth, viewBoxHeight] = data;
|
|
6994
7116
|
const height = viewBoxHeight / 1000;
|
|
6995
7117
|
const numSvgChildren = paths.length;
|
|
6996
7118
|
let widthClasses;
|
|
6997
7119
|
let aligns;
|
|
6998
7120
|
if (numSvgChildren === 1) {
|
|
6999
|
-
|
|
7000
|
-
|
|
7121
|
+
if (data.length !== 4) {
|
|
7122
|
+
throw new Error("Expected 4-tuple for single-path SVG data \"" + label + "\".");
|
|
7123
|
+
}
|
|
7001
7124
|
widthClasses = ["hide-tail"];
|
|
7002
|
-
aligns = [
|
|
7125
|
+
aligns = [data[3]];
|
|
7003
7126
|
} else if (numSvgChildren === 2) {
|
|
7004
7127
|
widthClasses = ["halfarrow-left", "halfarrow-right"];
|
|
7005
7128
|
aligns = ["xMinYMin", "xMaxYMin"];
|
|
@@ -7097,6 +7220,35 @@ const stretchyEnclose = function (inner, label, topPad, bottomPad, options) {
|
|
|
7097
7220
|
img.style.height = makeEm(totalHeight);
|
|
7098
7221
|
return img;
|
|
7099
7222
|
};
|
|
7223
|
+
;// ./src/atoms.ts
|
|
7224
|
+
/**
|
|
7225
|
+
* Small module for atom-group constants and type guard. Kept separate from
|
|
7226
|
+
* `symbols.ts` so that consumers (notably `contrib/render-a11y-string`) can
|
|
7227
|
+
* pull in `isAtom` without dragging in the ~870-line symbol tables.
|
|
7228
|
+
*/
|
|
7229
|
+
|
|
7230
|
+
// Some of these have a "-token" suffix since these are also used as `ParseNode`
|
|
7231
|
+
// types for raw text tokens, and we want to avoid conflicts with higher-level
|
|
7232
|
+
// `ParseNode` types. These `ParseNode`s are constructed within `Parser` by
|
|
7233
|
+
// looking up the `symbols` map.
|
|
7234
|
+
const ATOMS = {
|
|
7235
|
+
"bin": 1,
|
|
7236
|
+
"close": 1,
|
|
7237
|
+
"inner": 1,
|
|
7238
|
+
"open": 1,
|
|
7239
|
+
"punct": 1,
|
|
7240
|
+
"rel": 1
|
|
7241
|
+
};
|
|
7242
|
+
const NON_ATOMS = {
|
|
7243
|
+
"accent-token": 1,
|
|
7244
|
+
"mathord": 1,
|
|
7245
|
+
"op-token": 1,
|
|
7246
|
+
"spacing": 1,
|
|
7247
|
+
"textord": 1
|
|
7248
|
+
};
|
|
7249
|
+
function isAtom(value) {
|
|
7250
|
+
return value in ATOMS;
|
|
7251
|
+
}
|
|
7100
7252
|
;// ./src/parseNode.ts
|
|
7101
7253
|
|
|
7102
7254
|
|
|
@@ -7526,7 +7678,8 @@ defineFunction({
|
|
|
7526
7678
|
}, {
|
|
7527
7679
|
type: "elem",
|
|
7528
7680
|
elem: arrowBody,
|
|
7529
|
-
shift: arrowShift
|
|
7681
|
+
shift: arrowShift,
|
|
7682
|
+
wrapperClasses: ["svg-align"]
|
|
7530
7683
|
}, {
|
|
7531
7684
|
type: "elem",
|
|
7532
7685
|
elem: lowerGroup,
|
|
@@ -7543,13 +7696,11 @@ defineFunction({
|
|
|
7543
7696
|
}, {
|
|
7544
7697
|
type: "elem",
|
|
7545
7698
|
elem: arrowBody,
|
|
7546
|
-
shift: arrowShift
|
|
7699
|
+
shift: arrowShift,
|
|
7700
|
+
wrapperClasses: ["svg-align"]
|
|
7547
7701
|
}]
|
|
7548
7702
|
}, options);
|
|
7549
7703
|
}
|
|
7550
|
-
|
|
7551
|
-
// TODO(ts): Replace this with passing "svg-align" into makeVList.
|
|
7552
|
-
vlist.children[0].children[0].children[1].classes.push("svg-align");
|
|
7553
7704
|
return makeSpan(["mrel", "x-arrow"], [vlist], options);
|
|
7554
7705
|
},
|
|
7555
7706
|
mathmlBuilder(group, options) {
|
|
@@ -7809,7 +7960,8 @@ const newCell = () => {
|
|
|
7809
7960
|
type: "styling",
|
|
7810
7961
|
body: [],
|
|
7811
7962
|
mode: "math",
|
|
7812
|
-
style: "display"
|
|
7963
|
+
style: "display",
|
|
7964
|
+
resetFont: true
|
|
7813
7965
|
};
|
|
7814
7966
|
};
|
|
7815
7967
|
const isStartOfArrow = node => {
|
|
@@ -7871,7 +8023,6 @@ function parseCD(parser) {
|
|
|
7871
8023
|
parser.gullet.macros.set("\\cr", "\\\\\\relax");
|
|
7872
8024
|
parser.gullet.beginGroup();
|
|
7873
8025
|
while (true) {
|
|
7874
|
-
// eslint-disable-line no-constant-condition
|
|
7875
8026
|
// Get the parse nodes for the next row.
|
|
7876
8027
|
parsedRows.push(parser.parseExpression(false, "\\\\"));
|
|
7877
8028
|
parser.gullet.endGroup();
|
|
@@ -7964,7 +8115,9 @@ function parseCD(parser) {
|
|
|
7964
8115
|
type: "styling",
|
|
7965
8116
|
body: [arrow],
|
|
7966
8117
|
mode: "math",
|
|
7967
|
-
style: "display"
|
|
8118
|
+
style: "display",
|
|
8119
|
+
// CD is always displaystyle.
|
|
8120
|
+
resetFont: true
|
|
7968
8121
|
};
|
|
7969
8122
|
row.push(wrappedArrow);
|
|
7970
8123
|
// In CD's syntax, cells are implicit. That is, everything that
|
|
@@ -8909,9 +9062,9 @@ const makeSqrtImage = function (height, options) {
|
|
|
8909
9062
|
|
|
8910
9063
|
// Create a span containing an SVG image of a sqrt symbol.
|
|
8911
9064
|
let span;
|
|
8912
|
-
let spanHeight
|
|
8913
|
-
let texHeight
|
|
8914
|
-
let viewBoxHeight
|
|
9065
|
+
let spanHeight;
|
|
9066
|
+
let texHeight;
|
|
9067
|
+
let viewBoxHeight;
|
|
8915
9068
|
let advanceWidth;
|
|
8916
9069
|
|
|
8917
9070
|
// We create viewBoxes with 80 units of "padding" above each surd.
|
|
@@ -9273,6 +9426,16 @@ const delimiterSizes = {
|
|
|
9273
9426
|
}
|
|
9274
9427
|
};
|
|
9275
9428
|
const delimiters = new Set(["(", "\\lparen", ")", "\\rparen", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\u230a", "\u230b", "\\lceil", "\\rceil", "\u2308", "\u2309", "<", ">", "\\langle", "\u27e8", "\\rangle", "\u27e9", "\\lt", "\\gt", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\u27ee", "\u27ef", "\\lmoustache", "\\rmoustache", "\u23b0", "\u23b1", "/", "\\backslash", "|", "\\vert", "\\|", "\\Vert", "\\uparrow", "\\Uparrow", "\\downarrow", "\\Downarrow", "\\updownarrow", "\\Updownarrow", "."]);
|
|
9429
|
+
|
|
9430
|
+
/**
|
|
9431
|
+
* An HtmlDomNode that carries an `isMiddle` property, used by the
|
|
9432
|
+
* \middle command to communicate delimiter info to the \left/\right builder.
|
|
9433
|
+
*/
|
|
9434
|
+
|
|
9435
|
+
function isMiddleDelimNode(node) {
|
|
9436
|
+
return 'isMiddle' in node;
|
|
9437
|
+
}
|
|
9438
|
+
|
|
9276
9439
|
// Delimiter functions
|
|
9277
9440
|
function checkDelimiter(delim, context) {
|
|
9278
9441
|
const symDelim = checkSymbolNodeType(delim);
|
|
@@ -9396,10 +9559,8 @@ defineFunction({
|
|
|
9396
9559
|
|
|
9397
9560
|
// Calculate its height and depth
|
|
9398
9561
|
for (let i = 0; i < inner.length; i++) {
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
// TODO(ts)
|
|
9402
|
-
if (inner[i].isMiddle) {
|
|
9562
|
+
const node = inner[i];
|
|
9563
|
+
if (isMiddleDelimNode(node)) {
|
|
9403
9564
|
hadMiddle = true;
|
|
9404
9565
|
} else {
|
|
9405
9566
|
innerHeight = Math.max(inner[i].height, innerHeight);
|
|
@@ -9428,11 +9589,8 @@ defineFunction({
|
|
|
9428
9589
|
if (hadMiddle) {
|
|
9429
9590
|
for (let i = 1; i < inner.length; i++) {
|
|
9430
9591
|
const middleDelim = inner[i];
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
// TODO(ts)
|
|
9434
|
-
const isMiddle = middleDelim.isMiddle;
|
|
9435
|
-
if (isMiddle) {
|
|
9592
|
+
if (isMiddleDelimNode(middleDelim)) {
|
|
9593
|
+
const isMiddle = middleDelim.isMiddle;
|
|
9436
9594
|
// Apply the options that were active when \middle was called
|
|
9437
9595
|
inner[i] = makeLeftRightDelim(isMiddle.delim, innerHeight, innerDepth, isMiddle.options, group.mode, []);
|
|
9438
9596
|
}
|
|
@@ -9493,16 +9651,15 @@ defineFunction({
|
|
|
9493
9651
|
middleDelim = makeNullDelimiter(options, []);
|
|
9494
9652
|
} else {
|
|
9495
9653
|
middleDelim = makeSizedDelim(group.delim, 1, options, group.mode, []);
|
|
9496
|
-
|
|
9654
|
+
|
|
9655
|
+
// Patch an ad-hoc property onto the node so the \left/\right
|
|
9656
|
+
// builder can reconstruct appropriately sized middle delimiters.
|
|
9657
|
+
// isMiddle is not part of HtmlDomNode; the read side uses
|
|
9658
|
+
// isMiddleDelimNode() to check before accessing.
|
|
9659
|
+
middleDelim.isMiddle = {
|
|
9497
9660
|
delim: group.delim,
|
|
9498
9661
|
options
|
|
9499
9662
|
};
|
|
9500
|
-
// Property `isMiddle` not defined on `span`. It is only used in
|
|
9501
|
-
// this file above.
|
|
9502
|
-
// TODO: Fix this violation of the `span` type and possibly rename
|
|
9503
|
-
// things since `isMiddle` sounds like a boolean, but is a struct.
|
|
9504
|
-
// TODO(ts)
|
|
9505
|
-
middleDelim.isMiddle = isMiddle;
|
|
9506
9663
|
}
|
|
9507
9664
|
return middleDelim;
|
|
9508
9665
|
},
|
|
@@ -9541,7 +9698,7 @@ const enclose_htmlBuilder = (group, options) => {
|
|
|
9541
9698
|
const label = group.label.slice(1);
|
|
9542
9699
|
let scale = options.sizeMultiplier;
|
|
9543
9700
|
let img;
|
|
9544
|
-
let imgShift
|
|
9701
|
+
let imgShift;
|
|
9545
9702
|
|
|
9546
9703
|
// In the LaTeX cancel package, line geometry is slightly different
|
|
9547
9704
|
// depending on whether the subject is wider than it is tall, or vice versa.
|
|
@@ -9597,8 +9754,8 @@ const enclose_htmlBuilder = (group, options) => {
|
|
|
9597
9754
|
}
|
|
9598
9755
|
|
|
9599
9756
|
// Add vertical padding
|
|
9600
|
-
let topPad
|
|
9601
|
-
let bottomPad
|
|
9757
|
+
let topPad;
|
|
9758
|
+
let bottomPad;
|
|
9602
9759
|
let ruleThickness = 0;
|
|
9603
9760
|
// ref: cancel package: \advance\totalheight2\p@ % "+2"
|
|
9604
9761
|
if (/box/.test(label)) {
|
|
@@ -9680,7 +9837,7 @@ const enclose_htmlBuilder = (group, options) => {
|
|
|
9680
9837
|
}
|
|
9681
9838
|
};
|
|
9682
9839
|
const enclose_mathmlBuilder = (group, options) => {
|
|
9683
|
-
let fboxsep
|
|
9840
|
+
let fboxsep;
|
|
9684
9841
|
const node = new MathNode(group.label.includes("colorbox") ? "mpadded" : "menclose", [buildMathML_buildGroup(group.body, options)]);
|
|
9685
9842
|
switch (group.label) {
|
|
9686
9843
|
case "\\cancel":
|
|
@@ -9733,7 +9890,7 @@ defineFunction({
|
|
|
9733
9890
|
props: {
|
|
9734
9891
|
numArgs: 2,
|
|
9735
9892
|
allowedInText: true,
|
|
9736
|
-
argTypes: ["color", "
|
|
9893
|
+
argTypes: ["color", "hbox"]
|
|
9737
9894
|
},
|
|
9738
9895
|
handler(_ref, args, optArgs) {
|
|
9739
9896
|
let {
|
|
@@ -9759,7 +9916,7 @@ defineFunction({
|
|
|
9759
9916
|
props: {
|
|
9760
9917
|
numArgs: 3,
|
|
9761
9918
|
allowedInText: true,
|
|
9762
|
-
argTypes: ["color", "color", "
|
|
9919
|
+
argTypes: ["color", "color", "hbox"]
|
|
9763
9920
|
},
|
|
9764
9921
|
handler(_ref2, args, optArgs) {
|
|
9765
9922
|
let {
|
|
@@ -9962,12 +10119,15 @@ function defineMacro(name, body) {
|
|
|
9962
10119
|
* This object is immutable.
|
|
9963
10120
|
*/
|
|
9964
10121
|
class SourceLocation {
|
|
9965
|
-
// The + prefix indicates that these fields aren't writeable
|
|
9966
|
-
// Lexer holding the input string.
|
|
9967
|
-
// Start offset, zero-based inclusive.
|
|
9968
10122
|
// End offset, zero-based exclusive.
|
|
9969
10123
|
|
|
9970
10124
|
constructor(lexer, start, end) {
|
|
10125
|
+
// The + prefix indicates that these fields aren't writeable
|
|
10126
|
+
this.lexer = void 0;
|
|
10127
|
+
// Lexer holding the input string.
|
|
10128
|
+
this.start = void 0;
|
|
10129
|
+
// Start offset, zero-based inclusive.
|
|
10130
|
+
this.end = void 0;
|
|
9971
10131
|
this.lexer = lexer;
|
|
9972
10132
|
this.start = start;
|
|
9973
10133
|
this.end = end;
|
|
@@ -10013,12 +10173,16 @@ class SourceLocation {
|
|
|
10013
10173
|
* lead to degraded error reporting, though.
|
|
10014
10174
|
*/
|
|
10015
10175
|
class Token {
|
|
10016
|
-
// don't expand the token
|
|
10017
10176
|
// used in \noexpand
|
|
10018
10177
|
|
|
10019
10178
|
constructor(text,
|
|
10020
10179
|
// the text of this token
|
|
10021
10180
|
loc) {
|
|
10181
|
+
this.text = void 0;
|
|
10182
|
+
this.loc = void 0;
|
|
10183
|
+
this.noexpand = void 0;
|
|
10184
|
+
// don't expand the token
|
|
10185
|
+
this.treatAsRelax = void 0;
|
|
10022
10186
|
this.text = text;
|
|
10023
10187
|
this.loc = loc;
|
|
10024
10188
|
}
|
|
@@ -10166,7 +10330,6 @@ function parseArray(parser, _ref, style) {
|
|
|
10166
10330
|
// Test for \hline at the top of the array.
|
|
10167
10331
|
hLinesBeforeRow.push(getHLines(parser));
|
|
10168
10332
|
while (true) {
|
|
10169
|
-
// eslint-disable-line no-constant-condition
|
|
10170
10333
|
// Parse each cell in its own group (namespace)
|
|
10171
10334
|
const cellBody = parser.parseExpression(false, singleRow ? "\\end" : "\\\\");
|
|
10172
10335
|
parser.gullet.endGroup();
|
|
@@ -10181,6 +10344,7 @@ function parseArray(parser, _ref, style) {
|
|
|
10181
10344
|
type: "styling",
|
|
10182
10345
|
mode: parser.mode,
|
|
10183
10346
|
style,
|
|
10347
|
+
resetFont: true,
|
|
10184
10348
|
body: [cell]
|
|
10185
10349
|
};
|
|
10186
10350
|
}
|
|
@@ -10324,7 +10488,12 @@ const array_htmlBuilder = function (group, options) {
|
|
|
10324
10488
|
if (nc < inrow.length) {
|
|
10325
10489
|
nc = inrow.length;
|
|
10326
10490
|
}
|
|
10327
|
-
const outrow =
|
|
10491
|
+
const outrow = {
|
|
10492
|
+
cells: new Array(inrow.length),
|
|
10493
|
+
height: 0,
|
|
10494
|
+
depth: 0,
|
|
10495
|
+
pos: 0
|
|
10496
|
+
};
|
|
10328
10497
|
for (c = 0; c < inrow.length; ++c) {
|
|
10329
10498
|
const elt = buildGroup(inrow[c], options);
|
|
10330
10499
|
if (depth < elt.depth) {
|
|
@@ -10333,7 +10502,7 @@ const array_htmlBuilder = function (group, options) {
|
|
|
10333
10502
|
if (height < elt.height) {
|
|
10334
10503
|
height = elt.height;
|
|
10335
10504
|
}
|
|
10336
|
-
outrow[c] = elt;
|
|
10505
|
+
outrow.cells[c] = elt;
|
|
10337
10506
|
}
|
|
10338
10507
|
const rowGap = group.rowGaps[r];
|
|
10339
10508
|
let gap = 0;
|
|
@@ -10449,7 +10618,7 @@ const array_htmlBuilder = function (group, options) {
|
|
|
10449
10618
|
const colElems = [];
|
|
10450
10619
|
for (r = 0; r < nr; ++r) {
|
|
10451
10620
|
const row = body[r];
|
|
10452
|
-
const elem = row[c];
|
|
10621
|
+
const elem = row.cells[c];
|
|
10453
10622
|
if (!elem) {
|
|
10454
10623
|
continue;
|
|
10455
10624
|
}
|
|
@@ -11081,7 +11250,6 @@ const environments = _environments;
|
|
|
11081
11250
|
|
|
11082
11251
|
|
|
11083
11252
|
|
|
11084
|
-
|
|
11085
11253
|
// Environment delimiters. HTML/MathML rendering is defined in the corresponding
|
|
11086
11254
|
// defineEnvironment definitions.
|
|
11087
11255
|
defineFunction({
|
|
@@ -11128,7 +11296,10 @@ defineFunction({
|
|
|
11128
11296
|
if (end.name !== envName) {
|
|
11129
11297
|
throw new src_ParseError("Mismatch: \\begin{" + envName + "} matched by \\end{" + end.name + "}", endNameToken);
|
|
11130
11298
|
}
|
|
11131
|
-
//
|
|
11299
|
+
// env.handler returns the specific node type (e.g. "array"),
|
|
11300
|
+
// not "environment". This cast is unavoidable: defineFunction
|
|
11301
|
+
// requires the handler to return ParseNode<"environment"> but
|
|
11302
|
+
// \begin delegates to environment handlers with different types.
|
|
11132
11303
|
return result;
|
|
11133
11304
|
}
|
|
11134
11305
|
return {
|
|
@@ -11160,8 +11331,7 @@ const font_mathmlBuilder = (group, options) => {
|
|
|
11160
11331
|
const fontAliases = {
|
|
11161
11332
|
"\\Bbb": "\\mathbb",
|
|
11162
11333
|
"\\bold": "\\mathbf",
|
|
11163
|
-
"\\frak": "\\mathfrak"
|
|
11164
|
-
"\\bm": "\\boldsymbol"
|
|
11334
|
+
"\\frak": "\\mathfrak"
|
|
11165
11335
|
};
|
|
11166
11336
|
defineFunction({
|
|
11167
11337
|
type: "font",
|
|
@@ -11242,11 +11412,10 @@ defineFunction({
|
|
|
11242
11412
|
mode
|
|
11243
11413
|
} = parser;
|
|
11244
11414
|
const body = parser.parseExpression(true, breakOnTokenText);
|
|
11245
|
-
const style = "math" + funcName.slice(1);
|
|
11246
11415
|
return {
|
|
11247
11416
|
type: "font",
|
|
11248
11417
|
mode: mode,
|
|
11249
|
-
font:
|
|
11418
|
+
font: "math" + funcName.slice(1),
|
|
11250
11419
|
body: {
|
|
11251
11420
|
type: "ordgroup",
|
|
11252
11421
|
mode: parser.mode,
|
|
@@ -11730,18 +11899,18 @@ const horizBrace_htmlBuilder = (grp, options) => {
|
|
|
11730
11899
|
size: 0.1
|
|
11731
11900
|
}, {
|
|
11732
11901
|
type: "elem",
|
|
11733
|
-
elem: braceBody
|
|
11902
|
+
elem: braceBody,
|
|
11903
|
+
wrapperClasses: ["svg-align"]
|
|
11734
11904
|
}]
|
|
11735
11905
|
}, options);
|
|
11736
|
-
// TODO(ts): Replace this with passing "svg-align" into makeVList.
|
|
11737
|
-
vlist.children[0].children[0].children[1].classes.push("svg-align");
|
|
11738
11906
|
} else {
|
|
11739
11907
|
vlist = makeVList({
|
|
11740
11908
|
positionType: "bottom",
|
|
11741
11909
|
positionData: body.depth + 0.1 + braceBody.height,
|
|
11742
11910
|
children: [{
|
|
11743
11911
|
type: "elem",
|
|
11744
|
-
elem: braceBody
|
|
11912
|
+
elem: braceBody,
|
|
11913
|
+
wrapperClasses: ["svg-align"]
|
|
11745
11914
|
}, {
|
|
11746
11915
|
type: "kern",
|
|
11747
11916
|
size: 0.1
|
|
@@ -11750,8 +11919,6 @@ const horizBrace_htmlBuilder = (grp, options) => {
|
|
|
11750
11919
|
elem: body
|
|
11751
11920
|
}]
|
|
11752
11921
|
}, options);
|
|
11753
|
-
// TODO(ts): Replace this with passing "svg-align" into makeVList.
|
|
11754
|
-
vlist.children[0].children[0].children[0].classes.push("svg-align");
|
|
11755
11922
|
}
|
|
11756
11923
|
if (supSubGroup) {
|
|
11757
11924
|
// To write the supsub, wrap the first vlist in another vlist:
|
|
@@ -11949,11 +12116,11 @@ defineFunction({
|
|
|
11949
12116
|
};
|
|
11950
12117
|
},
|
|
11951
12118
|
htmlBuilder(group, options) {
|
|
11952
|
-
const elements = buildExpression(group.body, options, false);
|
|
12119
|
+
const elements = buildExpression(group.body, options.withFont(''), false);
|
|
11953
12120
|
return makeFragment(elements);
|
|
11954
12121
|
},
|
|
11955
12122
|
mathmlBuilder(group, options) {
|
|
11956
|
-
return new MathNode("mrow", buildMathML_buildExpression(group.body, options));
|
|
12123
|
+
return new MathNode("mrow", buildMathML_buildExpression(group.body, options.withFont('')));
|
|
11957
12124
|
}
|
|
11958
12125
|
});
|
|
11959
12126
|
;// ./src/functions/html.ts
|
|
@@ -12393,6 +12560,7 @@ defineFunction({
|
|
|
12393
12560
|
type: "styling",
|
|
12394
12561
|
mode: parser.mode,
|
|
12395
12562
|
style: "text",
|
|
12563
|
+
resetFont: true,
|
|
12396
12564
|
body
|
|
12397
12565
|
};
|
|
12398
12566
|
}
|
|
@@ -12627,6 +12795,9 @@ const op_htmlBuilder = (grp, options) => {
|
|
|
12627
12795
|
large = true;
|
|
12628
12796
|
}
|
|
12629
12797
|
let base;
|
|
12798
|
+
// Italic correction from the symbol glyph, captured before the symbol
|
|
12799
|
+
// may be wrapped in a vlist (for \oiint/\oiiint). Stays 0 for non-symbol ops.
|
|
12800
|
+
let symbolItalic;
|
|
12630
12801
|
if (group.symbol) {
|
|
12631
12802
|
// If this is a symbol, create the symbol.
|
|
12632
12803
|
const fontName = large ? "Size2-Regular" : "Size1-Regular";
|
|
@@ -12638,10 +12809,10 @@ const op_htmlBuilder = (grp, options) => {
|
|
|
12638
12809
|
group.name = stash === "oiint" ? "\\iint" : "\\iiint";
|
|
12639
12810
|
}
|
|
12640
12811
|
base = makeSymbol(group.name, fontName, "math", options, ["mop", "op-symbol", large ? "large-op" : "small-op"]);
|
|
12812
|
+
symbolItalic = base.italic;
|
|
12641
12813
|
if (stash.length > 0) {
|
|
12642
12814
|
// We're in \oiint or \oiiint. Overlay the oval.
|
|
12643
12815
|
// TODO: When font glyphs are available, delete this code.
|
|
12644
|
-
const italic = base.italic;
|
|
12645
12816
|
const oval = staticSvg(stash + "Size" + (large ? "2" : "1"), options);
|
|
12646
12817
|
base = makeVList({
|
|
12647
12818
|
positionType: "individualShift",
|
|
@@ -12657,8 +12828,9 @@ const op_htmlBuilder = (grp, options) => {
|
|
|
12657
12828
|
}, options);
|
|
12658
12829
|
group.name = "\\" + stash;
|
|
12659
12830
|
base.classes.unshift("mop");
|
|
12660
|
-
//
|
|
12661
|
-
|
|
12831
|
+
// Carry the italic correction from the original symbol to the
|
|
12832
|
+
// vlist wrapper so supsub can use it for subscript positioning.
|
|
12833
|
+
base.italic = symbolItalic;
|
|
12662
12834
|
}
|
|
12663
12835
|
} else if (group.body) {
|
|
12664
12836
|
// If this is a list, compose that list.
|
|
@@ -12683,6 +12855,7 @@ const op_htmlBuilder = (grp, options) => {
|
|
|
12683
12855
|
let baseShift = 0;
|
|
12684
12856
|
let slant = 0;
|
|
12685
12857
|
if ((base instanceof SymbolNode || group.name === "\\oiint" || group.name === "\\oiiint") && !group.suppressBaseShift) {
|
|
12858
|
+
var _base$italic;
|
|
12686
12859
|
// We suppress the shift of the base of \overset and \underset. Otherwise,
|
|
12687
12860
|
// shift the symbol so its center lies on the axis (rule 13). It
|
|
12688
12861
|
// appears that our fonts have the centers of the symbols already
|
|
@@ -12692,8 +12865,9 @@ const op_htmlBuilder = (grp, options) => {
|
|
|
12692
12865
|
baseShift = (base.height - base.depth) / 2 - options.fontMetrics().axisHeight;
|
|
12693
12866
|
|
|
12694
12867
|
// The slant of the symbol is just its italic correction.
|
|
12695
|
-
//
|
|
12696
|
-
|
|
12868
|
+
// SymbolNode carries .italic natively; Span (for \oiint/\oiiint)
|
|
12869
|
+
// only has it set when nonzero, so default to 0.
|
|
12870
|
+
slant = (_base$italic = base.italic) != null ? _base$italic : 0;
|
|
12697
12871
|
}
|
|
12698
12872
|
if (hasLimits) {
|
|
12699
12873
|
return assembleSupSub(base, supGroup, subGroup, options, style, slant, baseShift);
|
|
@@ -13427,7 +13601,7 @@ defineFunction({
|
|
|
13427
13601
|
// Optional [tb] argument is engaged.
|
|
13428
13602
|
// ref: amsmath: \renewcommand{\smash}[1][tb]{%
|
|
13429
13603
|
// def\mb@t{\ht}\def\mb@b{\dp}\def\mb@tb{\ht\z@\z@\dp}%
|
|
13430
|
-
let letter
|
|
13604
|
+
let letter;
|
|
13431
13605
|
for (let i = 0; i < tbArg.body.length; ++i) {
|
|
13432
13606
|
const node = tbArg.body[i];
|
|
13433
13607
|
letter = assertSymbolNodeType(node).text;
|
|
@@ -13649,6 +13823,9 @@ const styling_styleMap = {
|
|
|
13649
13823
|
"script": src_Style.SCRIPT,
|
|
13650
13824
|
"scriptscript": src_Style.SCRIPTSCRIPT
|
|
13651
13825
|
};
|
|
13826
|
+
function isStyleStr(s) {
|
|
13827
|
+
return s in styling_styleMap;
|
|
13828
|
+
}
|
|
13652
13829
|
defineFunction({
|
|
13653
13830
|
type: "styling",
|
|
13654
13831
|
names: ["\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle"],
|
|
@@ -13668,8 +13845,10 @@ defineFunction({
|
|
|
13668
13845
|
|
|
13669
13846
|
// TODO: Refactor to avoid duplicating styleMap in multiple places (e.g.
|
|
13670
13847
|
// here and in buildHTML and de-dupe the enumeration of all the styles).
|
|
13671
|
-
// TODO(ts): The names above exactly match the styles.
|
|
13672
13848
|
const style = funcName.slice(1, funcName.length - 5);
|
|
13849
|
+
if (!isStyleStr(style)) {
|
|
13850
|
+
throw new Error("Unknown style: " + style);
|
|
13851
|
+
}
|
|
13673
13852
|
return {
|
|
13674
13853
|
type: "styling",
|
|
13675
13854
|
mode: parser.mode,
|
|
@@ -13682,13 +13861,19 @@ defineFunction({
|
|
|
13682
13861
|
htmlBuilder(group, options) {
|
|
13683
13862
|
// Style changes are handled in the TeXbook on pg. 442, Rule 3.
|
|
13684
13863
|
const newStyle = styling_styleMap[group.style];
|
|
13685
|
-
|
|
13864
|
+
let newOptions = options.havingStyle(newStyle);
|
|
13865
|
+
if (group.resetFont) {
|
|
13866
|
+
newOptions = newOptions.withFont('');
|
|
13867
|
+
}
|
|
13686
13868
|
return sizingGroup(group.body, newOptions, options);
|
|
13687
13869
|
},
|
|
13688
13870
|
mathmlBuilder(group, options) {
|
|
13689
13871
|
// Figure out what style we're changing to.
|
|
13690
13872
|
const newStyle = styling_styleMap[group.style];
|
|
13691
|
-
|
|
13873
|
+
let newOptions = options.havingStyle(newStyle);
|
|
13874
|
+
if (group.resetFont) {
|
|
13875
|
+
newOptions = newOptions.withFont('');
|
|
13876
|
+
}
|
|
13692
13877
|
const inner = buildMathML_buildExpression(group.body, newOptions);
|
|
13693
13878
|
const node = new MathNode("mstyle", inner);
|
|
13694
13879
|
const styleAttributes = {
|
|
@@ -13724,7 +13909,9 @@ defineFunction({
|
|
|
13724
13909
|
* its inner element should handle the superscripts and subscripts instead of
|
|
13725
13910
|
* handling them itself.
|
|
13726
13911
|
*/
|
|
13727
|
-
const htmlBuilderDelegate = function (group, options
|
|
13912
|
+
const htmlBuilderDelegate = function (group, options
|
|
13913
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13914
|
+
) {
|
|
13728
13915
|
const base = group.base;
|
|
13729
13916
|
if (!base) {
|
|
13730
13917
|
return null;
|
|
@@ -13810,8 +13997,10 @@ defineFunctionBuilders({
|
|
|
13810
13997
|
// amount. Note we only do this when the base is a single symbol.
|
|
13811
13998
|
const isOiint = group.base && group.base.type === "op" && group.base.name && (group.base.name === "\\oiint" || group.base.name === "\\oiiint");
|
|
13812
13999
|
if (base instanceof SymbolNode || isOiint) {
|
|
13813
|
-
|
|
13814
|
-
|
|
14000
|
+
var _italic;
|
|
14001
|
+
// SymbolNode has .italic natively; for \oiint/\oiiint the
|
|
14002
|
+
// op builder stores .italic on the wrapping Span.
|
|
14003
|
+
marginLeft = makeEm(-((_italic = base.italic) != null ? _italic : 0));
|
|
13815
14004
|
}
|
|
13816
14005
|
}
|
|
13817
14006
|
let supsub;
|
|
@@ -14286,7 +14475,9 @@ defineFunction({
|
|
|
14286
14475
|
// There is no way to do this in MathML.
|
|
14287
14476
|
// Write a class as a breadcrumb in case some post-processor wants
|
|
14288
14477
|
// to perform a vcenter adjustment.
|
|
14289
|
-
|
|
14478
|
+
// Wrap in mrow to ensure valid MathML when placed inside mo (e.g., \mathrel)
|
|
14479
|
+
const mpadded = new MathNode("mpadded", [buildMathML_buildGroup(group.body, options)], ["vcenter"]);
|
|
14480
|
+
return new MathNode("mrow", [mpadded]);
|
|
14290
14481
|
}
|
|
14291
14482
|
});
|
|
14292
14483
|
;// ./src/functions/verb.ts
|
|
@@ -14455,10 +14646,13 @@ combiningDiacriticalMarkString + "*") +
|
|
|
14455
14646
|
|
|
14456
14647
|
/** Main Lexer class */
|
|
14457
14648
|
class Lexer {
|
|
14458
|
-
// Category codes. The lexer only supports comment characters (14) for now.
|
|
14459
|
-
// MacroExpander additionally distinguishes active (13).
|
|
14460
|
-
|
|
14461
14649
|
constructor(input, settings) {
|
|
14650
|
+
this.input = void 0;
|
|
14651
|
+
this.settings = void 0;
|
|
14652
|
+
this.tokenRegex = void 0;
|
|
14653
|
+
// Category codes. The lexer only supports comment characters (14) for now.
|
|
14654
|
+
// MacroExpander additionally distinguishes active (13).
|
|
14655
|
+
this.catcodes = void 0;
|
|
14462
14656
|
// Separate accents from characters
|
|
14463
14657
|
this.input = input;
|
|
14464
14658
|
this.settings = settings;
|
|
@@ -14525,6 +14719,9 @@ class Namespace {
|
|
|
14525
14719
|
if (globalMacros === void 0) {
|
|
14526
14720
|
globalMacros = {};
|
|
14527
14721
|
}
|
|
14722
|
+
this.current = void 0;
|
|
14723
|
+
this.builtins = void 0;
|
|
14724
|
+
this.undefStack = void 0;
|
|
14528
14725
|
this.current = globalMacros;
|
|
14529
14726
|
this.builtins = builtins;
|
|
14530
14727
|
this.undefStack = [];
|
|
@@ -15628,6 +15825,12 @@ const implicitCommands = {
|
|
|
15628
15825
|
};
|
|
15629
15826
|
class MacroExpander {
|
|
15630
15827
|
constructor(input, settings, mode) {
|
|
15828
|
+
this.settings = void 0;
|
|
15829
|
+
this.expansionCount = void 0;
|
|
15830
|
+
this.lexer = void 0;
|
|
15831
|
+
this.macros = void 0;
|
|
15832
|
+
this.stack = void 0;
|
|
15833
|
+
this.mode = void 0;
|
|
15631
15834
|
this.settings = settings;
|
|
15632
15835
|
this.expansionCount = 0;
|
|
15633
15836
|
this.feed(input);
|
|
@@ -16174,6 +16377,7 @@ const uSubsAndSups = Object.freeze({
|
|
|
16174
16377
|
|
|
16175
16378
|
|
|
16176
16379
|
|
|
16380
|
+
|
|
16177
16381
|
// Pre-evaluate both modules as unicodeSymbols require String.normalize()
|
|
16178
16382
|
const unicodeAccents = {
|
|
16179
16383
|
"́": {
|
|
@@ -16601,6 +16805,11 @@ const unicodeSymbols = {
|
|
|
16601
16805
|
|
|
16602
16806
|
class Parser {
|
|
16603
16807
|
constructor(input, settings) {
|
|
16808
|
+
this.mode = void 0;
|
|
16809
|
+
this.gullet = void 0;
|
|
16810
|
+
this.settings = void 0;
|
|
16811
|
+
this.leftrightDepth = void 0;
|
|
16812
|
+
this.nextToken = void 0;
|
|
16604
16813
|
// Start in math mode
|
|
16605
16814
|
this.mode = "math";
|
|
16606
16815
|
// Create a new macro expander (gullet) and (indirectly via that) also a
|
|
@@ -17105,13 +17314,16 @@ class Parser {
|
|
|
17105
17314
|
case "hbox":
|
|
17106
17315
|
{
|
|
17107
17316
|
// hbox argument type wraps the argument in the equivalent of
|
|
17108
|
-
// \hbox, which is like \text but switching to \textstyle size
|
|
17317
|
+
// \hbox, which is like \text but switching to \textstyle size
|
|
17318
|
+
// and resetting math font.
|
|
17109
17319
|
const group = this.parseArgumentGroup(optional, "text");
|
|
17110
17320
|
return group != null ? {
|
|
17111
17321
|
type: "styling",
|
|
17112
17322
|
mode: group.mode,
|
|
17113
17323
|
body: [group],
|
|
17114
|
-
style: "text"
|
|
17324
|
+
style: "text",
|
|
17325
|
+
// simulate \textstyle
|
|
17326
|
+
resetFont: true
|
|
17115
17327
|
} : null;
|
|
17116
17328
|
}
|
|
17117
17329
|
case "raw":
|
|
@@ -17477,18 +17689,15 @@ class Parser {
|
|
|
17477
17689
|
const group = src_symbols[this.mode][text].group;
|
|
17478
17690
|
const loc = SourceLocation.range(nucleus);
|
|
17479
17691
|
let s;
|
|
17480
|
-
if (
|
|
17481
|
-
// TODO(ts)
|
|
17482
|
-
const family = group;
|
|
17692
|
+
if (isAtom(group)) {
|
|
17483
17693
|
s = {
|
|
17484
17694
|
type: "atom",
|
|
17485
17695
|
mode: this.mode,
|
|
17486
|
-
family,
|
|
17696
|
+
family: group,
|
|
17487
17697
|
loc,
|
|
17488
17698
|
text
|
|
17489
17699
|
};
|
|
17490
17700
|
} else {
|
|
17491
|
-
// TODO(ts)
|
|
17492
17701
|
s = {
|
|
17493
17702
|
type: group,
|
|
17494
17703
|
mode: this.mode,
|
|
@@ -17496,7 +17705,6 @@ class Parser {
|
|
|
17496
17705
|
text
|
|
17497
17706
|
};
|
|
17498
17707
|
}
|
|
17499
|
-
// TODO(ts)
|
|
17500
17708
|
symbol = s;
|
|
17501
17709
|
} else if (text.charCodeAt(0) >= 0x80) {
|
|
17502
17710
|
// no symbol for e.g. ^
|
|
@@ -17542,12 +17750,10 @@ class Parser {
|
|
|
17542
17750
|
label: command,
|
|
17543
17751
|
isStretchy: false,
|
|
17544
17752
|
isShifty: true,
|
|
17545
|
-
// TODO(ts)
|
|
17546
17753
|
base: symbol
|
|
17547
17754
|
};
|
|
17548
17755
|
}
|
|
17549
17756
|
}
|
|
17550
|
-
// TODO(ts)
|
|
17551
17757
|
return symbol;
|
|
17552
17758
|
}
|
|
17553
17759
|
}
|
|
@@ -17693,7 +17899,7 @@ const renderToHTMLTree = function (expression, options) {
|
|
|
17693
17899
|
return renderError(error, expression, settings);
|
|
17694
17900
|
}
|
|
17695
17901
|
};
|
|
17696
|
-
const version = "0.16.
|
|
17902
|
+
const version = "0.16.46";
|
|
17697
17903
|
const __domTree = {
|
|
17698
17904
|
Span: Span,
|
|
17699
17905
|
Anchor: Anchor,
|