katex 0.10.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +141 -0
- package/LICENSE +1 -1
- package/README.md +6 -6
- package/cli.js +0 -0
- package/contrib/auto-render/auto-render.js +12 -3
- package/contrib/copy-tex/README.md +3 -5
- package/contrib/mathtex-script-type/README.md +12 -14
- package/contrib/mhchem/README.md +3 -1
- package/contrib/render-a11y-string/render-a11y-string.js +712 -0
- package/contrib/render-a11y-string/test/render-a11y-string-spec.js +526 -0
- package/dist/README.md +6 -6
- package/dist/contrib/auto-render.js +14 -3
- package/dist/contrib/auto-render.min.js +1 -1
- package/dist/contrib/auto-render.mjs +14 -3
- package/dist/contrib/mhchem.min.js +1 -1
- package/dist/contrib/render-a11y-string.js +870 -0
- package/dist/contrib/render-a11y-string.min.js +1 -0
- package/dist/contrib/render-a11y-string.mjs +753 -0
- package/dist/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Italic.woff +0 -0
- package/dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_Math-Italic.woff +0 -0
- package/dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Script-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dist/katex.css +34 -10
- package/dist/katex.js +2906 -2115
- package/dist/katex.min.css +1 -1
- package/dist/katex.min.js +1 -1
- package/dist/katex.mjs +2809 -2020
- package/package.json +12 -11
- package/src/Lexer.js +1 -0
- package/src/MacroExpander.js +39 -10
- package/src/Options.js +15 -75
- package/src/Parser.js +152 -115
- package/src/Settings.js +70 -7
- package/src/Token.js +2 -0
- package/src/buildCommon.js +24 -90
- package/src/buildHTML.js +31 -31
- package/src/buildMathML.js +52 -9
- package/src/buildTree.js +13 -6
- package/src/defineFunction.js +7 -22
- package/src/delimiter.js +66 -27
- package/src/domTree.js +71 -4
- package/src/environments/array.js +235 -25
- package/src/fontMetrics.js +11 -2
- package/src/functions/accent.js +9 -9
- package/src/functions/accentunder.js +2 -2
- package/src/functions/arrow.js +15 -5
- package/src/functions/color.js +9 -38
- package/src/functions/def.js +184 -0
- package/src/functions/delimsizing.js +32 -8
- package/src/functions/enclose.js +33 -6
- package/src/functions/font.js +4 -1
- package/src/functions/genfrac.js +39 -27
- package/src/functions/horizBrace.js +6 -7
- package/src/functions/href.js +16 -0
- package/src/functions/html.js +102 -0
- package/src/functions/includegraphics.js +153 -0
- package/src/functions/lap.js +4 -7
- package/src/functions/math.js +1 -5
- package/src/functions/mclass.js +41 -2
- package/src/functions/op.js +27 -111
- package/src/functions/operatorname.js +136 -92
- package/src/functions/ordgroup.js +1 -1
- package/src/functions/overline.js +3 -2
- package/src/functions/phantom.js +5 -2
- package/src/functions/raisebox.js +4 -16
- package/src/functions/rule.js +20 -9
- package/src/functions/styling.js +0 -9
- package/src/functions/supsub.js +27 -7
- package/src/functions/symbolsOp.js +4 -0
- package/src/functions/tag.js +20 -4
- package/src/functions/text.js +4 -3
- package/src/functions/underline.js +3 -2
- package/src/functions/utils/assembleSupSub.js +110 -0
- package/src/functions.js +3 -0
- package/src/katex.less +45 -9
- package/src/macros.js +259 -98
- package/src/mathMLTree.js +6 -4
- package/src/parseNode.js +37 -57
- package/src/stretchy.js +3 -1
- package/src/svgGeometry.js +136 -44
- package/src/symbols.js +52 -69
- package/src/tree.js +2 -2
- package/src/types.js +2 -1
- package/src/unicodeAccents.js +3 -1
- package/src/unicodeSymbols.js +30 -321
- package/src/utils.js +10 -0
- package/src/wide-character.js +2 -2
- package/src/unicodeMake.js +0 -70
package/src/Settings.js
CHANGED
|
@@ -16,18 +16,57 @@ export type StrictFunction =
|
|
|
16
16
|
(errorCode: string, errorMsg: string, token?: Token | AnyParseNode) =>
|
|
17
17
|
?(boolean | string);
|
|
18
18
|
|
|
19
|
+
export type TrustContextTypes = {
|
|
20
|
+
"\\href": {|
|
|
21
|
+
command: "\\href",
|
|
22
|
+
url: string,
|
|
23
|
+
protocol?: string,
|
|
24
|
+
|},
|
|
25
|
+
"\\includegraphics": {|
|
|
26
|
+
command: "\\includegraphics",
|
|
27
|
+
url: string,
|
|
28
|
+
protocol?: string,
|
|
29
|
+
|},
|
|
30
|
+
"\\url": {|
|
|
31
|
+
command: "\\url",
|
|
32
|
+
url: string,
|
|
33
|
+
protocol?: string,
|
|
34
|
+
|},
|
|
35
|
+
"\\htmlClass": {|
|
|
36
|
+
command: "\\htmlClass",
|
|
37
|
+
class: string,
|
|
38
|
+
|},
|
|
39
|
+
"\\htmlId": {|
|
|
40
|
+
command: "\\htmlId",
|
|
41
|
+
id: string,
|
|
42
|
+
|},
|
|
43
|
+
"\\htmlStyle": {|
|
|
44
|
+
command: "\\htmlStyle",
|
|
45
|
+
style: string,
|
|
46
|
+
|},
|
|
47
|
+
"\\htmlData": {|
|
|
48
|
+
command: "\\htmlData",
|
|
49
|
+
attributes: {[string]: string},
|
|
50
|
+
|},
|
|
51
|
+
};
|
|
52
|
+
export type AnyTrustContext = $Values<TrustContextTypes>;
|
|
53
|
+
export type TrustFunction = (context: AnyTrustContext) => ?boolean;
|
|
54
|
+
|
|
19
55
|
export type SettingsOptions = {
|
|
20
56
|
displayMode?: boolean;
|
|
57
|
+
output?: "html" | "mathml" | "htmlAndMathml";
|
|
21
58
|
leqno?: boolean;
|
|
22
59
|
fleqn?: boolean;
|
|
23
60
|
throwOnError?: boolean;
|
|
24
61
|
errorColor?: string;
|
|
25
62
|
macros?: MacroMap;
|
|
63
|
+
minRuleThickness?: number;
|
|
26
64
|
colorIsTextColor?: boolean;
|
|
27
65
|
strict?: boolean | "ignore" | "warn" | "error" | StrictFunction;
|
|
66
|
+
trust?: boolean | TrustFunction;
|
|
28
67
|
maxSize?: number;
|
|
29
68
|
maxExpand?: number;
|
|
30
|
-
|
|
69
|
+
globalGroup?: boolean;
|
|
31
70
|
};
|
|
32
71
|
|
|
33
72
|
/**
|
|
@@ -40,34 +79,42 @@ export type SettingsOptions = {
|
|
|
40
79
|
* math (true), meaning that the math starts in \displaystyle
|
|
41
80
|
* and is placed in a block with vertical margin.
|
|
42
81
|
*/
|
|
43
|
-
class Settings {
|
|
82
|
+
export default class Settings {
|
|
44
83
|
displayMode: boolean;
|
|
84
|
+
output: "html" | "mathml" | "htmlAndMathml";
|
|
45
85
|
leqno: boolean;
|
|
46
86
|
fleqn: boolean;
|
|
47
87
|
throwOnError: boolean;
|
|
48
88
|
errorColor: string;
|
|
49
89
|
macros: MacroMap;
|
|
90
|
+
minRuleThickness: number;
|
|
50
91
|
colorIsTextColor: boolean;
|
|
51
92
|
strict: boolean | "ignore" | "warn" | "error" | StrictFunction;
|
|
93
|
+
trust: boolean | TrustFunction;
|
|
52
94
|
maxSize: number;
|
|
53
95
|
maxExpand: number;
|
|
54
|
-
|
|
96
|
+
globalGroup: boolean;
|
|
55
97
|
|
|
56
98
|
constructor(options: SettingsOptions) {
|
|
57
99
|
// allow null options
|
|
58
100
|
options = options || {};
|
|
59
101
|
this.displayMode = utils.deflt(options.displayMode, false);
|
|
102
|
+
this.output = utils.deflt(options.output, "htmlAndMathml");
|
|
60
103
|
this.leqno = utils.deflt(options.leqno, false);
|
|
61
104
|
this.fleqn = utils.deflt(options.fleqn, false);
|
|
62
105
|
this.throwOnError = utils.deflt(options.throwOnError, true);
|
|
63
106
|
this.errorColor = utils.deflt(options.errorColor, "#cc0000");
|
|
64
107
|
this.macros = options.macros || {};
|
|
108
|
+
this.minRuleThickness = Math.max(
|
|
109
|
+
0,
|
|
110
|
+
utils.deflt(options.minRuleThickness, 0)
|
|
111
|
+
);
|
|
65
112
|
this.colorIsTextColor = utils.deflt(options.colorIsTextColor, false);
|
|
66
113
|
this.strict = utils.deflt(options.strict, "warn");
|
|
114
|
+
this.trust = utils.deflt(options.trust, false);
|
|
67
115
|
this.maxSize = Math.max(0, utils.deflt(options.maxSize, Infinity));
|
|
68
116
|
this.maxExpand = Math.max(0, utils.deflt(options.maxExpand, 1000));
|
|
69
|
-
this.
|
|
70
|
-
["http", "https", "mailto", "_relative"]);
|
|
117
|
+
this.globalGroup = utils.deflt(options.globalGroup, false);
|
|
71
118
|
}
|
|
72
119
|
|
|
73
120
|
/**
|
|
@@ -137,6 +184,22 @@ class Settings {
|
|
|
137
184
|
return false;
|
|
138
185
|
}
|
|
139
186
|
}
|
|
140
|
-
}
|
|
141
187
|
|
|
142
|
-
|
|
188
|
+
/**
|
|
189
|
+
* Check whether to test potentially dangerous input, and return
|
|
190
|
+
* `true` (trusted) or `false` (untrusted). The sole argument `context`
|
|
191
|
+
* should be an object with `command` field specifying the relevant LaTeX
|
|
192
|
+
* command (as a string starting with `\`), and any other arguments, etc.
|
|
193
|
+
* If `context` has a `url` field, a `protocol` field will automatically
|
|
194
|
+
* get added by this function (changing the specified object).
|
|
195
|
+
*/
|
|
196
|
+
isTrusted(context: AnyTrustContext) {
|
|
197
|
+
if (context.url && !context.protocol) {
|
|
198
|
+
context.protocol = utils.protocolFromUrl(context.url);
|
|
199
|
+
}
|
|
200
|
+
const trust = typeof this.trust === "function"
|
|
201
|
+
? this.trust(context)
|
|
202
|
+
: this.trust;
|
|
203
|
+
return Boolean(trust);
|
|
204
|
+
}
|
|
205
|
+
}
|
package/src/Token.js
CHANGED
|
@@ -23,6 +23,8 @@ export interface LexerInterface {input: string, tokenRegex: RegExp}
|
|
|
23
23
|
export class Token {
|
|
24
24
|
text: string;
|
|
25
25
|
loc: ?SourceLocation;
|
|
26
|
+
noexpand: ?boolean; // don't expand the token
|
|
27
|
+
treatAsRelax: ?boolean; // used in \noexpand
|
|
26
28
|
|
|
27
29
|
constructor(
|
|
28
30
|
text: string, // the text of this token
|
package/src/buildCommon.js
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
import {SymbolNode, Anchor, Span, PathNode, SvgNode, createClass} from "./domTree";
|
|
9
9
|
import {getCharacterMetrics} from "./fontMetrics";
|
|
10
10
|
import symbols, {ligatures} from "./symbols";
|
|
11
|
-
import utils from "./utils";
|
|
12
11
|
import {wideCharacterFont} from "./wide-character";
|
|
13
12
|
import {calculateSize} from "./units";
|
|
14
13
|
import {DocumentFragment} from "./tree";
|
|
@@ -21,13 +20,6 @@ import type {documentFragment as HtmlDocumentFragment} from "./domTree";
|
|
|
21
20
|
import type {HtmlDomNode, DomSpan, SvgSpan, CssStyle} from "./domTree";
|
|
22
21
|
import type {Measurement} from "./units";
|
|
23
22
|
|
|
24
|
-
// The following have to be loaded from Main-Italic font, using class mathit
|
|
25
|
-
const mathitLetters = [
|
|
26
|
-
"\\imath", "ı", // dotless i
|
|
27
|
-
"\\jmath", "ȷ", // dotless j
|
|
28
|
-
"\\pounds", "\\mathsterling", "\\textsterling", "£", // pounds symbol
|
|
29
|
-
];
|
|
30
|
-
|
|
31
23
|
/**
|
|
32
24
|
* Looks up the given symbol in fontMetrics, after applying any symbol
|
|
33
25
|
* replacements defined in symbol.js
|
|
@@ -80,9 +72,8 @@ const makeSymbol = function(
|
|
|
80
72
|
metrics.width, classes);
|
|
81
73
|
} else {
|
|
82
74
|
// TODO(emily): Figure out a good way to only print this in development
|
|
83
|
-
typeof console !== "undefined" && console.warn(
|
|
84
|
-
|
|
85
|
-
fontName + "'");
|
|
75
|
+
typeof console !== "undefined" && console.warn("No character metrics " +
|
|
76
|
+
`for '${value}' in style '${fontName}' and mode '${mode}'`);
|
|
86
77
|
symbolNode = new SymbolNode(value, 0, 0, 0, 0, 0, classes);
|
|
87
78
|
}
|
|
88
79
|
|
|
@@ -103,13 +94,11 @@ const makeSymbol = function(
|
|
|
103
94
|
/**
|
|
104
95
|
* Makes a symbol in Main-Regular or AMS-Regular.
|
|
105
96
|
* Used for rel, bin, open, close, inner, and punct.
|
|
106
|
-
*
|
|
107
|
-
* TODO(#953): Make `options` mandatory and always pass it in.
|
|
108
97
|
*/
|
|
109
98
|
const mathsym = function(
|
|
110
99
|
value: string,
|
|
111
100
|
mode: Mode,
|
|
112
|
-
options
|
|
101
|
+
options: Options,
|
|
113
102
|
classes?: string[] = [],
|
|
114
103
|
): SymbolNode {
|
|
115
104
|
// Decide what font to render the symbol in by its entry in the symbols
|
|
@@ -119,7 +108,7 @@ const mathsym = function(
|
|
|
119
108
|
// text ordinal and is therefore not present as a symbol in the symbols
|
|
120
109
|
// table for text, as well as a special case for boldsymbol because it
|
|
121
110
|
// can be used for bold + and -
|
|
122
|
-
if (
|
|
111
|
+
if (options.font === "boldsymbol" &&
|
|
123
112
|
lookupSymbol(value, "Main-Bold", mode).metrics) {
|
|
124
113
|
return makeSymbol(value, "Main-Bold", mode, options,
|
|
125
114
|
classes.concat(["mathbf"]));
|
|
@@ -131,63 +120,6 @@ const mathsym = function(
|
|
|
131
120
|
}
|
|
132
121
|
};
|
|
133
122
|
|
|
134
|
-
/**
|
|
135
|
-
* Determines which of the two font names (Main-Italic and Math-Italic) and
|
|
136
|
-
* corresponding style tags (maindefault or mathit) to use for default math font,
|
|
137
|
-
* depending on the symbol.
|
|
138
|
-
*/
|
|
139
|
-
const mathdefault = function(
|
|
140
|
-
value: string,
|
|
141
|
-
mode: Mode,
|
|
142
|
-
options: Options,
|
|
143
|
-
classes: string[],
|
|
144
|
-
): {| fontName: string, fontClass: string |} {
|
|
145
|
-
if (/[0-9]/.test(value.charAt(0)) ||
|
|
146
|
-
// glyphs for \imath and \jmath do not exist in Math-Italic so we
|
|
147
|
-
// need to use Main-Italic instead
|
|
148
|
-
utils.contains(mathitLetters, value)) {
|
|
149
|
-
return {
|
|
150
|
-
fontName: "Main-Italic",
|
|
151
|
-
fontClass: "mathit",
|
|
152
|
-
};
|
|
153
|
-
} else {
|
|
154
|
-
return {
|
|
155
|
-
fontName: "Math-Italic",
|
|
156
|
-
fontClass: "mathdefault",
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Determines which of the font names (Main-Italic, Math-Italic, and Caligraphic)
|
|
163
|
-
* and corresponding style tags (mathit, mathdefault, or mathcal) to use for font
|
|
164
|
-
* "mathnormal", depending on the symbol. Use this function instead of fontMap for
|
|
165
|
-
* font "mathnormal".
|
|
166
|
-
*/
|
|
167
|
-
const mathnormal = function(
|
|
168
|
-
value: string,
|
|
169
|
-
mode: Mode,
|
|
170
|
-
options: Options,
|
|
171
|
-
classes: string[],
|
|
172
|
-
): {| fontName: string, fontClass: string |} {
|
|
173
|
-
if (utils.contains(mathitLetters, value)) {
|
|
174
|
-
return {
|
|
175
|
-
fontName: "Main-Italic",
|
|
176
|
-
fontClass: "mathit",
|
|
177
|
-
};
|
|
178
|
-
} else if (/[0-9]/.test(value.charAt(0))) {
|
|
179
|
-
return {
|
|
180
|
-
fontName: "Caligraphic-Regular",
|
|
181
|
-
fontClass: "mathcal",
|
|
182
|
-
};
|
|
183
|
-
} else {
|
|
184
|
-
return {
|
|
185
|
-
fontName: "Math-Italic",
|
|
186
|
-
fontClass: "mathdefault",
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
|
|
191
123
|
/**
|
|
192
124
|
* Determines which of the two font names (Main-Bold and Math-BoldItalic) and
|
|
193
125
|
* corresponding style tags (mathbf or boldsymbol) to use for font "boldsymbol",
|
|
@@ -199,8 +131,10 @@ const boldsymbol = function(
|
|
|
199
131
|
mode: Mode,
|
|
200
132
|
options: Options,
|
|
201
133
|
classes: string[],
|
|
134
|
+
type: "mathord" | "textord",
|
|
202
135
|
): {| fontName: string, fontClass: string |} {
|
|
203
|
-
if (
|
|
136
|
+
if (type !== "textord" &&
|
|
137
|
+
lookupSymbol(value, "Math-BoldItalic", mode).metrics) {
|
|
204
138
|
return {
|
|
205
139
|
fontName: "Math-BoldItalic",
|
|
206
140
|
fontClass: "boldsymbol",
|
|
@@ -239,15 +173,10 @@ const makeOrd = function<NODETYPE: "spacing" | "mathord" | "textord">(
|
|
|
239
173
|
} else if (fontOrFamily) {
|
|
240
174
|
let fontName;
|
|
241
175
|
let fontClasses;
|
|
242
|
-
if (fontOrFamily === "boldsymbol"
|
|
243
|
-
const fontData =
|
|
244
|
-
? boldsymbol(text, mode, options, classes)
|
|
245
|
-
: mathnormal(text, mode, options, classes);
|
|
176
|
+
if (fontOrFamily === "boldsymbol") {
|
|
177
|
+
const fontData = boldsymbol(text, mode, options, classes, type);
|
|
246
178
|
fontName = fontData.fontName;
|
|
247
179
|
fontClasses = [fontData.fontClass];
|
|
248
|
-
} else if (utils.contains(mathitLetters, text)) {
|
|
249
|
-
fontName = "Main-Italic";
|
|
250
|
-
fontClasses = ["mathit"];
|
|
251
180
|
} else if (isFont) {
|
|
252
181
|
fontName = fontMap[fontOrFamily].fontName;
|
|
253
182
|
fontClasses = [fontOrFamily];
|
|
@@ -274,9 +203,8 @@ const makeOrd = function<NODETYPE: "spacing" | "mathord" | "textord">(
|
|
|
274
203
|
|
|
275
204
|
// Makes a symbol in the default font for mathords and textords.
|
|
276
205
|
if (type === "mathord") {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
classes.concat([fontLookup.fontClass]));
|
|
206
|
+
return makeSymbol(text, "Math-Italic", mode, options,
|
|
207
|
+
classes.concat(["mathnormal"]));
|
|
280
208
|
} else if (type === "textord") {
|
|
281
209
|
const font = symbols[mode][text] && symbols[mode][text].font;
|
|
282
210
|
if (font === "ams") {
|
|
@@ -423,7 +351,10 @@ const makeLineSpan = function(
|
|
|
423
351
|
thickness?: number,
|
|
424
352
|
) {
|
|
425
353
|
const line = makeSpan([className], [], options);
|
|
426
|
-
line.height =
|
|
354
|
+
line.height = Math.max(
|
|
355
|
+
thickness || options.fontMetrics().defaultRuleThickness,
|
|
356
|
+
options.minRuleThickness,
|
|
357
|
+
);
|
|
427
358
|
line.style.borderBottomWidth = line.height + "em";
|
|
428
359
|
line.maxFontSize = 1.0;
|
|
429
360
|
return line;
|
|
@@ -752,13 +683,14 @@ const fontMap: {[string]: {| variant: FontVariant, fontName: string |}} = {
|
|
|
752
683
|
variant: "italic",
|
|
753
684
|
fontName: "Main-Italic",
|
|
754
685
|
},
|
|
686
|
+
"mathnormal": {
|
|
687
|
+
variant: "italic",
|
|
688
|
+
fontName: "Math-Italic",
|
|
689
|
+
},
|
|
755
690
|
|
|
756
|
-
//
|
|
757
|
-
//
|
|
758
|
-
//
|
|
759
|
-
// Math-BoldItalic and Main-Bold for "boldsymbol". This is handled by a
|
|
760
|
-
// special case in makeOrd which ends up calling mathdefault, mathnormal,
|
|
761
|
-
// and boldsymbol.
|
|
691
|
+
// "boldsymbol" is missing because they require the use of multiple fonts:
|
|
692
|
+
// Math-BoldItalic and Main-Bold. This is handled by a special case in
|
|
693
|
+
// makeOrd which ends up calling boldsymbol.
|
|
762
694
|
|
|
763
695
|
// families
|
|
764
696
|
"mathbb": {
|
|
@@ -796,6 +728,8 @@ const svgData: {
|
|
|
796
728
|
oiintSize2: ["oiintSize2", 1.472, 0.659],
|
|
797
729
|
oiiintSize1: ["oiiintSize1", 1.304, 0.499],
|
|
798
730
|
oiiintSize2: ["oiiintSize2", 1.98, 0.659],
|
|
731
|
+
leftParenInner: ["leftParenInner", 0.875, 0.3],
|
|
732
|
+
rightParenInner: ["rightParenInner", 0.875, 0.3],
|
|
799
733
|
};
|
|
800
734
|
|
|
801
735
|
const staticSvg = function(value: string, options: Options): SvgSpan {
|
package/src/buildHTML.js
CHANGED
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
import ParseError from "./ParseError";
|
|
10
10
|
import Style from "./Style";
|
|
11
11
|
import buildCommon from "./buildCommon";
|
|
12
|
-
import {Anchor} from "./domTree";
|
|
12
|
+
import {Span, Anchor} from "./domTree";
|
|
13
13
|
import utils from "./utils";
|
|
14
|
-
import {checkNodeType} from "./parseNode";
|
|
15
14
|
import {spacings, tightSpacings} from "./spacingData";
|
|
16
15
|
import {_htmlGroupBuilders as groupBuilders} from "./defineFunction";
|
|
17
16
|
import {DocumentFragment} from "./tree";
|
|
@@ -60,7 +59,7 @@ type DomType = $Keys<typeof DomEnum>;
|
|
|
60
59
|
export const buildExpression = function(
|
|
61
60
|
expression: AnyParseNode[],
|
|
62
61
|
options: Options,
|
|
63
|
-
isRealGroup: boolean,
|
|
62
|
+
isRealGroup: boolean | "root",
|
|
64
63
|
surrounding: [?DomType, ?DomType] = [null, null],
|
|
65
64
|
): HtmlDomNode[] {
|
|
66
65
|
// Parse expressions into `groups`.
|
|
@@ -68,7 +67,7 @@ export const buildExpression = function(
|
|
|
68
67
|
for (let i = 0; i < expression.length; i++) {
|
|
69
68
|
const output = buildGroup(expression[i], options);
|
|
70
69
|
if (output instanceof DocumentFragment) {
|
|
71
|
-
const children: HtmlDomNode
|
|
70
|
+
const children: $ReadOnlyArray<HtmlDomNode> = output.children;
|
|
72
71
|
groups.push(...children);
|
|
73
72
|
} else {
|
|
74
73
|
groups.push(output);
|
|
@@ -83,11 +82,8 @@ export const buildExpression = function(
|
|
|
83
82
|
|
|
84
83
|
let glueOptions = options;
|
|
85
84
|
if (expression.length === 1) {
|
|
86
|
-
const node =
|
|
87
|
-
|
|
88
|
-
if (!node) {
|
|
89
|
-
// No match.
|
|
90
|
-
} else if (node.type === "sizing") {
|
|
85
|
+
const node = expression[0];
|
|
86
|
+
if (node.type === "sizing") {
|
|
91
87
|
glueOptions = options.havingSize(node.size);
|
|
92
88
|
} else if (node.type === "styling") {
|
|
93
89
|
glueOptions = options.havingStyle(styleMap[node.style]);
|
|
@@ -106,6 +102,7 @@ export const buildExpression = function(
|
|
|
106
102
|
|
|
107
103
|
// Before determining what spaces to insert, perform bin cancellation.
|
|
108
104
|
// Binary operators change to ordinary symbols in some contexts.
|
|
105
|
+
const isRoot = (isRealGroup === "root");
|
|
109
106
|
traverseNonSpaceNodes(groups, (node, prev) => {
|
|
110
107
|
const prevType = prev.classes[0];
|
|
111
108
|
const type = node.classes[0];
|
|
@@ -114,7 +111,7 @@ export const buildExpression = function(
|
|
|
114
111
|
} else if (type === "mbin" && utils.contains(binLeftCanceller, prevType)) {
|
|
115
112
|
node.classes[0] = "mord";
|
|
116
113
|
}
|
|
117
|
-
}, {node: dummyPrev}, dummyNext);
|
|
114
|
+
}, {node: dummyPrev}, dummyNext, isRoot);
|
|
118
115
|
|
|
119
116
|
traverseNonSpaceNodes(groups, (node, prev) => {
|
|
120
117
|
const prevType = getTypeOfDomTree(prev);
|
|
@@ -127,7 +124,7 @@ export const buildExpression = function(
|
|
|
127
124
|
if (space) { // Insert glue (spacing) after the `prev`.
|
|
128
125
|
return buildCommon.makeGlue(space, glueOptions);
|
|
129
126
|
}
|
|
130
|
-
}, {node: dummyPrev}, dummyNext);
|
|
127
|
+
}, {node: dummyPrev}, dummyNext, isRoot);
|
|
131
128
|
|
|
132
129
|
return groups;
|
|
133
130
|
};
|
|
@@ -145,6 +142,7 @@ const traverseNonSpaceNodes = function(
|
|
|
145
142
|
insertAfter?: HtmlDomNode => void,
|
|
146
143
|
|},
|
|
147
144
|
next: ?HtmlDomNode,
|
|
145
|
+
isRoot: boolean,
|
|
148
146
|
) {
|
|
149
147
|
if (next) { // temporarily append the right node, if exists
|
|
150
148
|
nodes.push(next);
|
|
@@ -154,27 +152,32 @@ const traverseNonSpaceNodes = function(
|
|
|
154
152
|
const node = nodes[i];
|
|
155
153
|
const partialGroup = checkPartialGroup(node);
|
|
156
154
|
if (partialGroup) { // Recursive DFS
|
|
157
|
-
|
|
155
|
+
// $FlowFixMe: make nodes a $ReadOnlyArray by returning a new array
|
|
156
|
+
traverseNonSpaceNodes(partialGroup.children,
|
|
157
|
+
callback, prev, null, isRoot);
|
|
158
158
|
continue;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
// Ignore explicit spaces (e.g., \;, \,) when determining what implicit
|
|
162
162
|
// spacing should go between atoms of different classes
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
i++;
|
|
163
|
+
const nonspace = !node.hasClass("mspace");
|
|
164
|
+
if (nonspace) {
|
|
165
|
+
const result = callback(node, prev.node);
|
|
166
|
+
if (result) {
|
|
167
|
+
if (prev.insertAfter) {
|
|
168
|
+
prev.insertAfter(result);
|
|
169
|
+
} else { // insert at front
|
|
170
|
+
nodes.unshift(result);
|
|
171
|
+
i++;
|
|
172
|
+
}
|
|
174
173
|
}
|
|
175
174
|
}
|
|
176
175
|
|
|
177
|
-
|
|
176
|
+
if (nonspace) {
|
|
177
|
+
prev.node = node;
|
|
178
|
+
} else if (isRoot && node.hasClass("newline")) {
|
|
179
|
+
prev.node = makeSpan(["leftmost"]); // treat like beginning of line
|
|
180
|
+
}
|
|
178
181
|
prev.insertAfter = (index => n => {
|
|
179
182
|
nodes.splice(index + 1, 0, n);
|
|
180
183
|
i++;
|
|
@@ -188,8 +191,9 @@ const traverseNonSpaceNodes = function(
|
|
|
188
191
|
// Check if given node is a partial group, i.e., does not affect spacing around.
|
|
189
192
|
const checkPartialGroup = function(
|
|
190
193
|
node: HtmlDomNode,
|
|
191
|
-
): ?(DocumentFragment<HtmlDomNode> | Anchor) {
|
|
192
|
-
if (node instanceof DocumentFragment || node instanceof Anchor
|
|
194
|
+
): ?(DocumentFragment<HtmlDomNode> | Anchor | DomSpan) {
|
|
195
|
+
if (node instanceof DocumentFragment || node instanceof Anchor
|
|
196
|
+
|| (node instanceof Span && node.hasClass("enclosing"))) {
|
|
193
197
|
return node;
|
|
194
198
|
}
|
|
195
199
|
return null;
|
|
@@ -291,10 +295,6 @@ function buildHTMLUnbreakable(children, options) {
|
|
|
291
295
|
// Add strut, which ensures that the top of the HTML element falls at
|
|
292
296
|
// the height of the expression, and the bottom of the HTML element
|
|
293
297
|
// falls at the depth of the expression.
|
|
294
|
-
// We used to have separate top and bottom struts, where the bottom strut
|
|
295
|
-
// would like to use `vertical-align: top`, but in IE 9 this lowers the
|
|
296
|
-
// baseline of the box to the bottom of this strut (instead of staying in
|
|
297
|
-
// the normal place) so we use an absolute value for vertical-align instead.
|
|
298
298
|
const strut = makeSpan(["strut"]);
|
|
299
299
|
strut.style.height = (body.height + body.depth) + "em";
|
|
300
300
|
strut.style.verticalAlign = -body.depth + "em";
|
|
@@ -316,7 +316,7 @@ export default function buildHTML(tree: AnyParseNode[], options: Options): DomSp
|
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
// Build the expression contained in the tree
|
|
319
|
-
const expression = buildExpression(tree, options,
|
|
319
|
+
const expression = buildExpression(tree, options, "root");
|
|
320
320
|
|
|
321
321
|
const children = [];
|
|
322
322
|
|
package/src/buildMathML.js
CHANGED
|
@@ -44,7 +44,7 @@ export const makeText = function(
|
|
|
44
44
|
* Wrap the given array of nodes in an <mrow> node if needed, i.e.,
|
|
45
45
|
* unless the array has length 1. Always returns a single node.
|
|
46
46
|
*/
|
|
47
|
-
export const makeRow = function(body: MathDomNode
|
|
47
|
+
export const makeRow = function(body: $ReadOnlyArray<MathDomNode>): MathDomNode {
|
|
48
48
|
if (body.length === 1) {
|
|
49
49
|
return body[0];
|
|
50
50
|
} else {
|
|
@@ -93,7 +93,20 @@ export const getVariant = function(
|
|
|
93
93
|
if (font === "mathit") {
|
|
94
94
|
return "italic";
|
|
95
95
|
} else if (font === "boldsymbol") {
|
|
96
|
-
return "bold-italic";
|
|
96
|
+
return group.type === "textord" ? "bold" : "bold-italic";
|
|
97
|
+
} else if (font === "mathbf") {
|
|
98
|
+
return "bold";
|
|
99
|
+
} else if (font === "mathbb") {
|
|
100
|
+
return "double-struck";
|
|
101
|
+
} else if (font === "mathfrak") {
|
|
102
|
+
return "fraktur";
|
|
103
|
+
} else if (font === "mathscr" || font === "mathcal") {
|
|
104
|
+
// MathML makes no distinction between script and caligrahpic
|
|
105
|
+
return "script";
|
|
106
|
+
} else if (font === "mathsf") {
|
|
107
|
+
return "sans-serif";
|
|
108
|
+
} else if (font === "mathtt") {
|
|
109
|
+
return "monospace";
|
|
97
110
|
}
|
|
98
111
|
|
|
99
112
|
let text = group.text;
|
|
@@ -121,7 +134,19 @@ export const getVariant = function(
|
|
|
121
134
|
export const buildExpression = function(
|
|
122
135
|
expression: AnyParseNode[],
|
|
123
136
|
options: Options,
|
|
124
|
-
|
|
137
|
+
isOrdgroup?: boolean,
|
|
138
|
+
): MathNode[] {
|
|
139
|
+
if (expression.length === 1) {
|
|
140
|
+
const group = buildGroup(expression[0], options);
|
|
141
|
+
if (isOrdgroup && group instanceof MathNode && group.type === "mo") {
|
|
142
|
+
// When TeX writers want to suppress spacing on an operator,
|
|
143
|
+
// they often put the operator by itself inside braces.
|
|
144
|
+
group.setAttribute("lspace", "0em");
|
|
145
|
+
group.setAttribute("rspace", "0em");
|
|
146
|
+
}
|
|
147
|
+
return [group];
|
|
148
|
+
}
|
|
149
|
+
|
|
125
150
|
const groups = [];
|
|
126
151
|
let lastGroup;
|
|
127
152
|
for (let i = 0; i < expression.length; i++) {
|
|
@@ -145,14 +170,24 @@ export const buildExpression = function(
|
|
|
145
170
|
lastGroup.children.push(...group.children);
|
|
146
171
|
continue;
|
|
147
172
|
}
|
|
173
|
+
} else if (lastGroup.type === 'mi' && lastGroup.children.length === 1) {
|
|
174
|
+
const lastChild = lastGroup.children[0];
|
|
175
|
+
if (lastChild instanceof TextNode && lastChild.text === '\u0338' &&
|
|
176
|
+
(group.type === 'mo' || group.type === 'mi' ||
|
|
177
|
+
group.type === 'mn')) {
|
|
178
|
+
const child = group.children[0];
|
|
179
|
+
if (child instanceof TextNode && child.text.length > 0) {
|
|
180
|
+
// Overlay with combining character long solidus
|
|
181
|
+
child.text = child.text.slice(0, 1) + "\u0338" +
|
|
182
|
+
child.text.slice(1);
|
|
183
|
+
groups.pop();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
148
186
|
}
|
|
149
187
|
}
|
|
150
188
|
groups.push(group);
|
|
151
189
|
lastGroup = group;
|
|
152
190
|
}
|
|
153
|
-
|
|
154
|
-
// TODO(kevinb): combine \\not with mrels and mords
|
|
155
|
-
|
|
156
191
|
return groups;
|
|
157
192
|
};
|
|
158
193
|
|
|
@@ -163,8 +198,9 @@ export const buildExpression = function(
|
|
|
163
198
|
export const buildExpressionRow = function(
|
|
164
199
|
expression: AnyParseNode[],
|
|
165
200
|
options: Options,
|
|
201
|
+
isOrdgroup?: boolean,
|
|
166
202
|
): MathDomNode {
|
|
167
|
-
return makeRow(buildExpression(expression, options));
|
|
203
|
+
return makeRow(buildExpression(expression, options, isOrdgroup));
|
|
168
204
|
};
|
|
169
205
|
|
|
170
206
|
/**
|
|
@@ -174,7 +210,7 @@ export const buildExpressionRow = function(
|
|
|
174
210
|
export const buildGroup = function(
|
|
175
211
|
group: ?AnyParseNode,
|
|
176
212
|
options: Options,
|
|
177
|
-
):
|
|
213
|
+
): MathNode {
|
|
178
214
|
if (!group) {
|
|
179
215
|
return new mathMLTree.MathNode("mrow");
|
|
180
216
|
}
|
|
@@ -202,6 +238,8 @@ export default function buildMathML(
|
|
|
202
238
|
tree: AnyParseNode[],
|
|
203
239
|
texExpression: string,
|
|
204
240
|
options: Options,
|
|
241
|
+
isDisplayMode: boolean,
|
|
242
|
+
forMathmlOnly: boolean,
|
|
205
243
|
): DomSpan {
|
|
206
244
|
const expression = buildExpression(tree, options);
|
|
207
245
|
|
|
@@ -225,11 +263,16 @@ export default function buildMathML(
|
|
|
225
263
|
"semantics", [wrapper, annotation]);
|
|
226
264
|
|
|
227
265
|
const math = new mathMLTree.MathNode("math", [semantics]);
|
|
266
|
+
math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML");
|
|
267
|
+
if (isDisplayMode) {
|
|
268
|
+
math.setAttribute("display", "block");
|
|
269
|
+
}
|
|
228
270
|
|
|
229
271
|
// You can't style <math> nodes, so we wrap the node in a span.
|
|
230
272
|
// NOTE: The span class is not typed to have <math> nodes as children, and
|
|
231
273
|
// we don't want to make the children type more generic since the children
|
|
232
274
|
// of span are expected to have more fields in `buildHtml` contexts.
|
|
275
|
+
const wrapperClass = forMathmlOnly ? "katex" : "katex-mathml";
|
|
233
276
|
// $FlowFixMe
|
|
234
|
-
return buildCommon.makeSpan([
|
|
277
|
+
return buildCommon.makeSpan([wrapperClass], [math]);
|
|
235
278
|
}
|
package/src/buildTree.js
CHANGED
|
@@ -13,6 +13,7 @@ const optionsFromSettings = function(settings: Settings) {
|
|
|
13
13
|
return new Options({
|
|
14
14
|
style: (settings.displayMode ? Style.DISPLAY : Style.TEXT),
|
|
15
15
|
maxSize: settings.maxSize,
|
|
16
|
+
minRuleThickness: settings.minRuleThickness,
|
|
16
17
|
});
|
|
17
18
|
};
|
|
18
19
|
|
|
@@ -36,12 +37,18 @@ export const buildTree = function(
|
|
|
36
37
|
settings: Settings,
|
|
37
38
|
): DomSpan {
|
|
38
39
|
const options = optionsFromSettings(settings);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
let katexNode;
|
|
41
|
+
if (settings.output === "mathml") {
|
|
42
|
+
return buildMathML(tree, expression, options, settings.displayMode, true);
|
|
43
|
+
} else if (settings.output === "html") {
|
|
44
|
+
const htmlNode = buildHTML(tree, options);
|
|
45
|
+
katexNode = buildCommon.makeSpan(["katex"], [htmlNode]);
|
|
46
|
+
} else {
|
|
47
|
+
const mathMLNode = buildMathML(tree, expression, options,
|
|
48
|
+
settings.displayMode, false);
|
|
49
|
+
const htmlNode = buildHTML(tree, options);
|
|
50
|
+
katexNode = buildCommon.makeSpan(["katex"], [mathMLNode, htmlNode]);
|
|
51
|
+
}
|
|
45
52
|
|
|
46
53
|
return displayWrap(katexNode, settings);
|
|
47
54
|
};
|