1 | // @flow
|
2 | /* eslint no-console:0 */
|
3 | /**
|
4 | * This is the main entry point for KaTeX. Here, we expose functions for
|
5 | * rendering expressions either to DOM nodes or to markup strings.
|
6 | *
|
7 | * We also expose the ParseError class to check if errors thrown from KaTeX are
|
8 | * errors in the expression, or errors in javascript handling.
|
9 | */
|
10 |
|
11 | import ParseError from "./src/ParseError";
|
12 | import Settings from "./src/Settings";
|
13 |
|
14 | import {buildTree, buildHTMLTree} from "./src/buildTree";
|
15 | import parseTree from "./src/parseTree";
|
16 | import buildCommon from "./src/buildCommon";
|
17 | import {
|
18 | Span,
|
19 | Anchor,
|
20 | SymbolNode,
|
21 | SvgNode,
|
22 | PathNode,
|
23 | LineNode,
|
24 | } from "./src/domTree";
|
25 |
|
26 | import type {SettingsOptions} from "./src/Settings";
|
27 | import type {AnyParseNode} from "./src/parseNode";
|
28 | import type {DomSpan} from "./src/domTree";
|
29 |
|
30 | import {defineSymbol} from './src/symbols';
|
31 | import {defineMacro} from './src/macros';
|
32 | import {setFontMetrics} from './src/fontMetrics';
|
33 |
|
34 | declare var __VERSION__: string;
|
35 |
|
36 | /**
|
37 | * Parse and build an expression, and place that expression in the DOM node
|
38 | * given.
|
39 | */
|
40 | let render: (string, Node, SettingsOptions) => void = function(
|
41 | expression: string,
|
42 | baseNode: Node,
|
43 | options: SettingsOptions,
|
44 | ) {
|
45 | baseNode.textContent = "";
|
46 | const node = renderToDomTree(expression, options).toNode();
|
47 | baseNode.appendChild(node);
|
48 | };
|
49 |
|
50 | // KaTeX's styles don't work properly in quirks mode. Print out an error, and
|
51 | // disable rendering.
|
52 | if (typeof document !== "undefined") {
|
53 | if (document.compatMode !== "CSS1Compat") {
|
54 | typeof console !== "undefined" && console.warn(
|
55 | "Warning: KaTeX doesn't work in quirks mode. Make sure your " +
|
56 | "website has a suitable doctype.");
|
57 |
|
58 | render = function() {
|
59 | throw new ParseError("KaTeX doesn't work in quirks mode.");
|
60 | };
|
61 | }
|
62 | }
|
63 |
|
64 | /**
|
65 | * Parse and build an expression, and return the markup for that.
|
66 | */
|
67 | const renderToString = function(
|
68 | expression: string,
|
69 | options: SettingsOptions,
|
70 | ): string {
|
71 | const markup = renderToDomTree(expression, options).toMarkup();
|
72 | return markup;
|
73 | };
|
74 |
|
75 | /**
|
76 | * Parse an expression and return the parse tree.
|
77 | */
|
78 | const generateParseTree = function(
|
79 | expression: string,
|
80 | options: SettingsOptions,
|
81 | ): AnyParseNode[] {
|
82 | const settings = new Settings(options);
|
83 | return parseTree(expression, settings);
|
84 | };
|
85 |
|
86 | /**
|
87 | * If the given error is a KaTeX ParseError and options.throwOnError is false,
|
88 | * renders the invalid LaTeX as a span with hover title giving the KaTeX
|
89 | * error message. Otherwise, simply throws the error.
|
90 | */
|
91 | const renderError = function(
|
92 | error,
|
93 | expression: string,
|
94 | options: Settings,
|
95 | ) {
|
96 | if (options.throwOnError || !(error instanceof ParseError)) {
|
97 | throw error;
|
98 | }
|
99 | const node = buildCommon.makeSpan(["katex-error"],
|
100 | [new SymbolNode(expression)]);
|
101 | node.setAttribute("title", error.toString());
|
102 | node.setAttribute("style", `color:${options.errorColor}`);
|
103 | return node;
|
104 | };
|
105 |
|
106 | /**
|
107 | * Generates and returns the katex build tree. This is used for advanced
|
108 | * use cases (like rendering to custom output).
|
109 | */
|
110 | const renderToDomTree = function(
|
111 | expression: string,
|
112 | options: SettingsOptions,
|
113 | ): DomSpan {
|
114 | const settings = new Settings(options);
|
115 | try {
|
116 | const tree = parseTree(expression, settings);
|
117 | return buildTree(tree, expression, settings);
|
118 | } catch (error) {
|
119 | return renderError(error, expression, settings);
|
120 | }
|
121 | };
|
122 |
|
123 | /**
|
124 | * Generates and returns the katex build tree, with just HTML (no MathML).
|
125 | * This is used for advanced use cases (like rendering to custom output).
|
126 | */
|
127 | const renderToHTMLTree = function(
|
128 | expression: string,
|
129 | options: SettingsOptions,
|
130 | ): DomSpan {
|
131 | const settings = new Settings(options);
|
132 | try {
|
133 | const tree = parseTree(expression, settings);
|
134 | return buildHTMLTree(tree, expression, settings);
|
135 | } catch (error) {
|
136 | return renderError(error, expression, settings);
|
137 | }
|
138 | };
|
139 |
|
140 | export default {
|
141 | /**
|
142 | * Current KaTeX version
|
143 | */
|
144 | version: __VERSION__,
|
145 | /**
|
146 | * Renders the given LaTeX into an HTML+MathML combination, and adds
|
147 | * it as a child to the specified DOM node.
|
148 | */
|
149 | render,
|
150 | /**
|
151 | * Renders the given LaTeX into an HTML+MathML combination string,
|
152 | * for sending to the client.
|
153 | */
|
154 | renderToString,
|
155 | /**
|
156 | * KaTeX error, usually during parsing.
|
157 | */
|
158 | ParseError,
|
159 | /**
|
160 | * Parses the given LaTeX into KaTeX's internal parse tree structure,
|
161 | * without rendering to HTML or MathML.
|
162 | *
|
163 | * NOTE: This method is not currently recommended for public use.
|
164 | * The internal tree representation is unstable and is very likely
|
165 | * to change. Use at your own risk.
|
166 | */
|
167 | __parse: generateParseTree,
|
168 | /**
|
169 | * Renders the given LaTeX into an HTML+MathML internal DOM tree
|
170 | * representation, without flattening that representation to a string.
|
171 | *
|
172 | * NOTE: This method is not currently recommended for public use.
|
173 | * The internal tree representation is unstable and is very likely
|
174 | * to change. Use at your own risk.
|
175 | */
|
176 | __renderToDomTree: renderToDomTree,
|
177 | /**
|
178 | * Renders the given LaTeX into an HTML internal DOM tree representation,
|
179 | * without MathML and without flattening that representation to a string.
|
180 | *
|
181 | * NOTE: This method is not currently recommended for public use.
|
182 | * The internal tree representation is unstable and is very likely
|
183 | * to change. Use at your own risk.
|
184 | */
|
185 | __renderToHTMLTree: renderToHTMLTree,
|
186 | /**
|
187 | * extends internal font metrics object with a new object
|
188 | * each key in the new object represents a font name
|
189 | */
|
190 | __setFontMetrics: setFontMetrics,
|
191 | /**
|
192 | * adds a new symbol to builtin symbols table
|
193 | */
|
194 | __defineSymbol: defineSymbol,
|
195 | /**
|
196 | * adds a new macro to builtin macro list
|
197 | */
|
198 | __defineMacro: defineMacro,
|
199 | /**
|
200 | * Expose the dom tree node types, which can be useful for type checking nodes.
|
201 | *
|
202 | * NOTE: This method is not currently recommended for public use.
|
203 | * The internal tree representation is unstable and is very likely
|
204 | * to change. Use at your own risk.
|
205 | */
|
206 | __domTree: {
|
207 | Span,
|
208 | Anchor,
|
209 | SymbolNode,
|
210 | SvgNode,
|
211 | PathNode,
|
212 | LineNode,
|
213 | },
|
214 | };
|