UNPKG

5.62 kBJavaScriptView Raw
1// @flow
2/* eslint no-console:0 */
3/**
4 * This is a module for storing settings passed into KaTeX. It correctly handles
5 * default settings.
6 */
7
8import utils from "./utils";
9import ParseError from "./ParseError";
10import {Token} from "./Token";
11
12import type {AnyParseNode} from "./parseNode";
13import type {MacroMap} from "./macros";
14
15export type StrictFunction =
16 (errorCode: string, errorMsg: string, token?: Token | AnyParseNode) =>
17 ?(boolean | string);
18
19export type SettingsOptions = {
20 displayMode?: boolean;
21 leqno?: boolean;
22 fleqn?: boolean;
23 throwOnError?: boolean;
24 errorColor?: string;
25 macros?: MacroMap;
26 colorIsTextColor?: boolean;
27 strict?: boolean | "ignore" | "warn" | "error" | StrictFunction;
28 maxSize?: number;
29 maxExpand?: number;
30 allowedProtocols?: string[];
31};
32
33/**
34 * The main Settings object
35 *
36 * The current options stored are:
37 * - displayMode: Whether the expression should be typeset as inline math
38 * (false, the default), meaning that the math starts in
39 * \textstyle and is placed in an inline-block); or as display
40 * math (true), meaning that the math starts in \displaystyle
41 * and is placed in a block with vertical margin.
42 */
43class Settings {
44 displayMode: boolean;
45 leqno: boolean;
46 fleqn: boolean;
47 throwOnError: boolean;
48 errorColor: string;
49 macros: MacroMap;
50 colorIsTextColor: boolean;
51 strict: boolean | "ignore" | "warn" | "error" | StrictFunction;
52 maxSize: number;
53 maxExpand: number;
54 allowedProtocols: string[];
55
56 constructor(options: SettingsOptions) {
57 // allow null options
58 options = options || {};
59 this.displayMode = utils.deflt(options.displayMode, false);
60 this.leqno = utils.deflt(options.leqno, false);
61 this.fleqn = utils.deflt(options.fleqn, false);
62 this.throwOnError = utils.deflt(options.throwOnError, true);
63 this.errorColor = utils.deflt(options.errorColor, "#cc0000");
64 this.macros = options.macros || {};
65 this.colorIsTextColor = utils.deflt(options.colorIsTextColor, false);
66 this.strict = utils.deflt(options.strict, "warn");
67 this.maxSize = Math.max(0, utils.deflt(options.maxSize, Infinity));
68 this.maxExpand = Math.max(0, utils.deflt(options.maxExpand, 1000));
69 this.allowedProtocols = utils.deflt(options.allowedProtocols,
70 ["http", "https", "mailto", "_relative"]);
71 }
72
73 /**
74 * Report nonstrict (non-LaTeX-compatible) input.
75 * Can safely not be called if `this.strict` is false in JavaScript.
76 */
77 reportNonstrict(errorCode: string, errorMsg: string,
78 token?: Token | AnyParseNode) {
79 let strict = this.strict;
80 if (typeof strict === "function") {
81 // Allow return value of strict function to be boolean or string
82 // (or null/undefined, meaning no further processing).
83 strict = strict(errorCode, errorMsg, token);
84 }
85 if (!strict || strict === "ignore") {
86 return;
87 } else if (strict === true || strict === "error") {
88 throw new ParseError(
89 "LaTeX-incompatible input and strict mode is set to 'error': " +
90 `${errorMsg} [${errorCode}]`, token);
91 } else if (strict === "warn") {
92 typeof console !== "undefined" && console.warn(
93 "LaTeX-incompatible input and strict mode is set to 'warn': " +
94 `${errorMsg} [${errorCode}]`);
95 } else { // won't happen in type-safe code
96 typeof console !== "undefined" && console.warn(
97 "LaTeX-incompatible input and strict mode is set to " +
98 `unrecognized '${strict}': ${errorMsg} [${errorCode}]`);
99 }
100 }
101
102 /**
103 * Check whether to apply strict (LaTeX-adhering) behavior for unusual
104 * input (like `\\`). Unlike `nonstrict`, will not throw an error;
105 * instead, "error" translates to a return value of `true`, while "ignore"
106 * translates to a return value of `false`. May still print a warning:
107 * "warn" prints a warning and returns `false`.
108 * This is for the second category of `errorCode`s listed in the README.
109 */
110 useStrictBehavior(errorCode: string, errorMsg: string,
111 token?: Token | AnyParseNode) {
112 let strict = this.strict;
113 if (typeof strict === "function") {
114 // Allow return value of strict function to be boolean or string
115 // (or null/undefined, meaning no further processing).
116 // But catch any exceptions thrown by function, treating them
117 // like "error".
118 try {
119 strict = strict(errorCode, errorMsg, token);
120 } catch (error) {
121 strict = "error";
122 }
123 }
124 if (!strict || strict === "ignore") {
125 return false;
126 } else if (strict === true || strict === "error") {
127 return true;
128 } else if (strict === "warn") {
129 typeof console !== "undefined" && console.warn(
130 "LaTeX-incompatible input and strict mode is set to 'warn': " +
131 `${errorMsg} [${errorCode}]`);
132 return false;
133 } else { // won't happen in type-safe code
134 typeof console !== "undefined" && console.warn(
135 "LaTeX-incompatible input and strict mode is set to " +
136 `unrecognized '${strict}': ${errorMsg} [${errorCode}]`);
137 return false;
138 }
139 }
140}
141
142export default Settings;