katex.ts 7.0 KB

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