Skip to main content

katex/types/
settings.rs

1use core::cell::RefCell;
2use core::fmt;
3
4use alloc::sync::Arc;
5use bon::bon;
6
7use crate::macro_expander::MacroMap;
8use crate::namespace::KeyMap;
9
10use crate::types::{ErrorLocationProvider, ParseError, ParseErrorKind};
11use crate::utils::protocol_from_url;
12
13#[cfg(feature = "wasm")]
14use wasm_bindgen::prelude::wasm_bindgen;
15
16/// Output format options for KaTeX mathematical expression rendering.
17///
18/// This enum specifies the format of the rendered output, controlling whether
19/// KaTeX generates HTML, MathML, or both. The choice affects browser
20/// compatibility, accessibility, and styling capabilities.
21///
22/// # LaTeX/KaTeX Context
23/// Different output formats serve different purposes in mathematical
24/// publishing:
25/// - HTML provides broad browser support and styling flexibility
26/// - MathML offers semantic markup and screen reader accessibility
27/// - Combined output balances compatibility with advanced features
28///
29/// # Cross-references
30/// - See [`Settings::output`] for configuring the output format.
31/// - Related to browser compatibility and accessibility requirements.
32/// - Affects CSS styling and semantic markup generation.
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum OutputFormat {
35    /// Generate both HTML and MathML markup.
36    ///
37    /// This is the default format, providing the best balance of compatibility,
38    /// accessibility, and styling. HTML is used for visual rendering, while
39    /// MathML provides semantic information for screen readers and other tools.
40    HtmlAndMathml,
41    /// Generate HTML markup only.
42    ///
43    /// Produces clean HTML output with CSS styling. Best for web pages where
44    /// MathML support is not required or desired. More predictable rendering
45    /// across different browsers.
46    Html,
47    /// Generate MathML markup only.
48    ///
49    /// Produces semantic MathML output optimized for accessibility and
50    /// mathematical software. Best for applications requiring precise
51    /// mathematical semantics over visual presentation.
52    Mathml,
53}
54
55/// Levels of strictness for LaTeX compatibility checking in KaTeX.
56///
57/// This enum defines how KaTeX responds to input that deviates from standard
58/// LaTeX syntax or behavior. It provides a spectrum from permissive to strict
59/// enforcement of LaTeX standards.
60///
61/// # LaTeX/KaTeX Context
62/// LaTeX has evolved over decades with various extensions and non-standard
63/// usages. Strict mode helps maintain compatibility and catch potential issues
64/// by controlling how KaTeX handles non-standard constructs.
65///
66/// # Cross-references
67/// - See [`Settings::report_nonstrict`] for how strictness is enforced.
68/// - Used in [`StrictSetting`] and [`StrictReturn`] for configuration.
69/// - Related to error reporting and LaTeX compatibility.
70#[derive(Debug, Clone, Copy, PartialEq, Eq)]
71pub enum StrictMode {
72    /// Ignore non-standard LaTeX input silently.
73    ///
74    /// Allows all input to be processed, even if it deviates from LaTeX
75    /// standards. Best for maximum compatibility when strictness is not
76    /// required.
77    Ignore,
78    /// Warn about non-standard LaTeX input but continue processing.
79    ///
80    /// Logs warnings for non-standard constructs but does not fail rendering.
81    /// Useful for development and debugging while maintaining functionality.
82    Warn,
83    /// Error on non-standard LaTeX input and halt processing.
84    ///
85    /// Rejects any input that doesn't conform to LaTeX standards, throwing
86    /// errors for strict compatibility. Best for production environments
87    /// requiring LaTeX compliance.
88    Error,
89}
90
91/// Core settings structure for KaTeX rendering configuration.
92///
93/// This struct contains all resolved configuration options that control
94/// KaTeX's behavior during mathematical expression parsing and rendering.
95/// Unlike the builder inputs, all fields have concrete values with no options.
96///
97/// # LaTeX/KaTeX Context
98/// These settings correspond to LaTeX document and package options that affect
99/// mathematical typesetting. KaTeX uses this structure to maintain consistent
100/// rendering behavior across different expressions and contexts.
101///
102/// # Cross-references
103/// - See [`Settings::builder`] for ergonomic construction of settings.
104/// - Related to [`OutputFormat`], [`StrictSetting`], and [`TrustSetting`].
105/// - Methods provide validation and utility functions.
106#[cfg_attr(feature = "wasm", wasm_bindgen)]
107#[derive(Debug, Clone)]
108pub struct Settings {
109    /// Whether mathematical expressions are rendered in display (block) mode.
110    ///
111    /// When `true`, equations are centered and displayed on separate lines
112    /// with larger fonts. When `false`, equations are rendered inline.
113    pub display_mode: bool,
114    /// The output format for rendered mathematical expressions.
115    ///
116    /// Determines the markup format (HTML, MathML, or both) of the output.
117    #[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
118    pub output: OutputFormat,
119    /// Whether equation numbers are placed on the left side.
120    ///
121    /// Controls the positioning of equation numbers in numbered environments.
122    pub leqno: bool,
123    /// Whether equations are flushed to the left margin.
124    ///
125    /// When `true`, equations are left-aligned instead of centered.
126    pub fleqn: bool,
127    /// Whether parsing/rendering errors should throw exceptions.
128    ///
129    /// When `true`, errors cause panics. When `false`, errors are rendered
130    /// as colored text in the output.
131    pub throw_on_error: bool,
132    /// CSS color value used for rendering error messages.
133    ///
134    /// Applied to error text when `throw_on_error` is `false`.
135    #[cfg_attr(feature = "wasm", wasm_bindgen(getter_with_clone))]
136    pub error_color: String,
137    /// Map of custom macro definitions.
138    ///
139    /// Contains user-defined LaTeX macros for extending functionality.
140    /// Keys are macro names, values are their LaTeX definitions.
141    #[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
142    pub macros: RefCell<MacroMap>,
143    /// Minimum thickness for rendered rules (lines).
144    ///
145    /// Prevents lines from becoming too thin to be visible. In points.
146    pub min_rule_thickness: f64,
147    /// Whether `\color` commands affect surrounding text color.
148    ///
149    /// When `true`, color commands modify text color. When `false`,
150    /// they only affect mathematical content.
151    pub color_is_text_color: bool,
152    /// Configuration for strict LaTeX compatibility checking.
153    ///
154    /// Controls how KaTeX handles non-standard LaTeX input.
155    #[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
156    pub strict: StrictSetting,
157    /// Configuration for trust validation of dangerous content.
158    ///
159    /// Controls validation of URLs, styles, and other potentially unsafe
160    /// inputs.
161    #[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
162    pub trust: TrustSetting,
163    /// Maximum allowed size for rendered expressions.
164    ///
165    /// Prevents excessive memory usage from very large expressions. In points.
166    pub max_size: f64,
167    /// Maximum limit for macro expansion iterations.
168    ///
169    /// Prevents infinite loops in macro expansion.
170    pub max_expand: usize,
171    /// Whether settings persist globally across render calls.
172    ///
173    /// When `true`, settings remain active for subsequent expressions.
174    pub global_group: bool,
175    /// Size multiplier for scaling rendered expressions.
176    ///
177    /// Controls the overall size scaling factor for mathematical expressions.
178    pub size_multiplier: f64,
179    /// Color value for mathematical content.
180    ///
181    /// CSS color value used for rendering mathematical expressions.
182    #[cfg_attr(feature = "wasm", wasm_bindgen(getter_with_clone))]
183    pub color: Option<String>,
184}
185
186#[bon]
187impl Settings {
188    /// Creates a new [`Settings`] instance from optional configuration values.
189    ///
190    /// This constructor applies default values for any `None` options in the
191    /// provided builder inputs, ensuring all settings have concrete
192    /// values.
193    ///
194    /// # Parameters
195    /// - `options`: Configuration options with optional values.
196    ///
197    /// # Returns
198    /// A fully configured [`Settings`] instance with all fields set to concrete
199    /// values.
200    ///
201    /// # Default Values
202    /// - `display_mode`: `false` (inline mode)
203    /// - `output`: [`OutputFormat::HtmlAndMathml`]
204    /// - `leqno`: `false` (right-side numbering)
205    /// - `fleqn`: `false` (centered equations)
206    /// - `throw_on_error`: `true` (throw on errors)
207    /// - `error_color`: `"#cc0000"` (red)
208    /// - `macros`: Empty map
209    /// - `min_rule_thickness`: `0.0`
210    /// - `color_is_text_color`: `false`
211    /// - `strict`: StrictSetting::Mode(StrictMode::Ignore)
212    /// - `trust`: TrustSetting::Bool(false)
213    /// - `max_size`: `f64::INFINITY`
214    /// - `max_expand`: `1000`
215    /// - `global_group`: `false`
216    #[must_use]
217    #[builder]
218    pub fn new(
219        /// Display mode (true for block, false for inline).
220        display_mode: Option<bool>,
221        /// Output format (HTML, MathML, or both).
222        output: Option<OutputFormat>,
223        /// Left equation numbers (true for left, false for right).
224        leqno: Option<bool>,
225        /// Left-aligned equations (true for left, false for centered).
226        fleqn: Option<bool>,
227        /// Throw errors (true) or render them (false).
228        /// Default is true (throw on errors).
229        throw_on_error: Option<bool>,
230        /// CSS color for rendering errors.
231        error_color: Option<String>,
232        /// Custom macro definitions.
233        macros: Option<MacroMap>,
234        /// Minimum rule thickness in points.
235        min_rule_thickness: Option<f64>,
236        /// Whether `\color` affects surrounding text color.
237        color_is_text_color: Option<bool>,
238        /// Strict mode configuration.
239        strict: Option<StrictSetting>,
240        /// Trust configuration for dangerous content.
241        trust: Option<TrustSetting>,
242        /// Maximum allowed size in points.
243        max_size: Option<f64>,
244        /// Maximum macro expansion iterations.
245        max_expand: Option<usize>,
246        /// Whether settings persist globally across render calls.
247        global_group: Option<bool>,
248        /// Size multiplier for rendering (scaling factor).
249        size_multiplier: Option<f64>,
250        /// Color for mathematical content.
251        color: Option<String>,
252    ) -> Self {
253        Self {
254            display_mode: display_mode.unwrap_or(false),
255            output: output.unwrap_or(OutputFormat::HtmlAndMathml),
256            leqno: leqno.unwrap_or(false),
257            fleqn: fleqn.unwrap_or(false),
258            throw_on_error: throw_on_error.unwrap_or(true),
259            error_color: error_color.unwrap_or_else(|| "#cc0000".to_owned()),
260            macros: RefCell::from(macros.unwrap_or_default()),
261            min_rule_thickness: min_rule_thickness.unwrap_or(0.0),
262            color_is_text_color: color_is_text_color.unwrap_or(false),
263            strict: strict.unwrap_or_default(),
264            trust: trust.unwrap_or_default(),
265            max_size: max_size.unwrap_or(f64::INFINITY).max(0.0),
266            max_expand: max_expand.unwrap_or(1000),
267            global_group: global_group.unwrap_or(false),
268            size_multiplier: size_multiplier.unwrap_or(1.0),
269            color,
270        }
271    }
272
273    /// Reports non-standard LaTeX input according to the current strict
274    /// settings.
275    ///
276    /// This method handles non-LaTeX-compatible input based on the configured
277    /// strictness level. It may ignore the input, log a warning, or return an
278    /// error.
279    ///
280    /// # Parameters
281    /// - `error_code`: A string identifier for the type of strict violation.
282    /// - `error_msg`: A human-readable description of the issue.
283    /// - `token`: Optional location information for error reporting.
284    ///
285    /// # Returns
286    /// - `Ok(())` if the input is accepted (ignore or warn modes).
287    /// - `Err(ParseError)` if the input is rejected (error mode).
288    ///
289    /// # Behavior by Strict Mode
290    /// - [`StrictMode::Ignore`]: Silently accepts the input.
291    /// - [`StrictMode::Warn`]: Logs a warning and accepts the input.
292    /// - [`StrictMode::Error`]: Returns an error rejecting the input.
293    ///
294    /// # Error Handling
295    /// Errors include the error code and message, with optional location
296    /// information from the token for precise error reporting.
297    #[expect(clippy::print_stderr)]
298    pub fn report_nonstrict(
299        &self,
300        error_code: &str,
301        error_msg: &str,
302        token: Option<&dyn ErrorLocationProvider>,
303    ) -> Result<(), ParseError> {
304        match self.resolve_strict(error_code, error_msg, token) {
305            StrictMode::Ignore => Ok(()),
306            StrictMode::Error => {
307                let kind = ParseErrorKind::StrictModeError {
308                    message: error_msg.to_owned(),
309                    code: error_code.to_owned(),
310                };
311                if let Some(t) = token {
312                    Err(ParseError::with_token(kind, t))
313                } else {
314                    Err(ParseError::new(kind))
315                }
316            }
317            StrictMode::Warn => {
318                eprintln!(
319                    "LaTeX-incompatible input and strict mode is set to 'warn': {error_msg} [{error_code}]"
320                );
321                Ok(())
322            }
323        }
324    }
325
326    /// Determines whether strict (LaTeX-adhering) behavior should be enforced.
327    ///
328    /// This method checks if the given input should trigger strict error
329    /// handling based on the current strict settings. Unlike
330    /// report_nonstrict, this method only returns a boolean without
331    /// performing any actions.
332    ///
333    /// # Parameters
334    /// - `error_code`: A string identifier for the type of strict violation.
335    /// - `error_msg`: A human-readable description of the issue.
336    /// - `token`: Optional location information for error reporting.
337    ///
338    /// # Returns
339    /// - `true` if strict behavior should be enforced (error mode).
340    /// - `false` if the input should be accepted (ignore or warn modes).
341    ///
342    /// # Notes
343    /// In warn mode, this method logs the warning but returns `false` to
344    /// indicate that processing should continue rather than fail.
345    #[must_use]
346    #[expect(clippy::print_stderr)]
347    pub fn use_strict_behavior(
348        &self,
349        error_code: &str,
350        error_msg: &str,
351        token: Option<&dyn ErrorLocationProvider>,
352    ) -> bool {
353        match self.resolve_strict_catch(error_code, error_msg, token) {
354            StrictMode::Ignore => false,
355            StrictMode::Error => true,
356            StrictMode::Warn => {
357                eprintln!(
358                    "LaTeX-incompatible input and strict mode is set to 'warn': {error_msg} [{error_code}]"
359                );
360                false
361            }
362        }
363    }
364
365    /// Evaluates whether potentially dangerous input should be trusted.
366    ///
367    /// This method validates potentially unsafe content (such as URLs in
368    /// `\href` commands) according to the current trust settings. It
369    /// automatically infers protocols from URLs when possible.
370    ///
371    /// # Parameters
372    /// - `context`: A [`TrustContext`] containing details about the potentially
373    ///   dangerous content, including the command, URL, styles, etc.
374    ///
375    /// # Returns
376    /// - `true` if the content should be trusted and rendered.
377    /// - `false` if the content should be rejected as unsafe.
378    ///
379    /// # Protocol Inference
380    /// If `context.url` is provided but `context.protocol` is `None`, this
381    /// method attempts to infer the protocol from the URL. If the URL is
382    /// malformed or has an invalid protocol, it returns `false`
383    /// immediately.
384    ///
385    /// # Security Considerations
386    /// This method is critical for preventing XSS attacks and other security
387    /// vulnerabilities. Trust functions should carefully validate all aspects
388    /// of the context before granting trust.
389    pub fn is_trusted(&self, context: &mut TrustContext) -> bool {
390        if context.protocol.is_none()
391            && let Some(url) = &context.url
392        {
393            if let Some(protocol) = protocol_from_url(url) {
394                context.protocol = Some(protocol);
395            } else {
396                return false;
397            }
398        }
399
400        match &self.trust {
401            TrustSetting::Bool(b) => *b,
402            TrustSetting::Function(f) => f(context).unwrap_or(false),
403        }
404    }
405
406    /// Helper: resolve strict setting into a concrete mode. Any boolean true
407    /// maps to Error, boolean false maps to Ignore.
408    fn resolve_strict(
409        &self,
410        error_code: &str,
411        error_msg: &str,
412        token: Option<&dyn ErrorLocationProvider>,
413    ) -> StrictMode {
414        match &self.strict {
415            StrictSetting::Mode(m) => *m,
416            StrictSetting::Bool(b) => {
417                if *b {
418                    StrictMode::Error
419                } else {
420                    StrictMode::Ignore
421                }
422            }
423            StrictSetting::Function(f) => match f(error_code, error_msg, token) {
424                Some(StrictReturn::Mode(m)) => m,
425                Some(StrictReturn::Bool(b)) => {
426                    if b {
427                        StrictMode::Error
428                    } else {
429                        StrictMode::Ignore
430                    }
431                }
432                None => StrictMode::Ignore,
433            },
434        }
435    }
436
437    /// Helper variant for use_strict_behavior: if the function errors, treat as
438    /// Error.
439    fn resolve_strict_catch(
440        &self,
441        error_code: &str,
442        error_msg: &str,
443        token: Option<&dyn ErrorLocationProvider>,
444    ) -> StrictMode {
445        match &self.strict {
446            StrictSetting::Mode(m) => *m,
447            StrictSetting::Bool(b) => {
448                if *b {
449                    StrictMode::Error
450                } else {
451                    StrictMode::Ignore
452                }
453            }
454            StrictSetting::Function(func) => {
455                // Mimic JS semantics: if function panics, treat as "error".
456                let f = Arc::clone(func);
457                let error_code = error_code.to_owned();
458                let error_msg = error_msg.to_owned();
459                let token_ref = token;
460                let res = f(&error_code, &error_msg, token_ref);
461                match res {
462                    Some(StrictReturn::Mode(m)) => m,
463                    Some(StrictReturn::Bool(b)) => {
464                        if b {
465                            StrictMode::Error
466                        } else {
467                            StrictMode::Ignore
468                        }
469                    }
470                    None => StrictMode::Ignore,
471                }
472            }
473        }
474    }
475}
476
477impl Default for Settings {
478    fn default() -> Self {
479        Self::builder().build()
480    }
481}
482
483/// Return type for strict validation functions in KaTeX.
484///
485/// This enum represents the possible return values from strict mode functions,
486/// which determine how KaTeX handles non-standard LaTeX input. It mirrors
487/// JavaScript's strict function return types, allowing flexible strictness
488/// configuration through function callbacks.
489///
490/// # LaTeX/KaTeX Context
491/// Strict mode in KaTeX controls how strictly the parser adheres to LaTeX
492/// standards. Functions can return different strictness levels based on
493/// the specific input being validated, enabling fine-grained control over
494/// error handling and warnings.
495///
496/// # Cross-references
497/// - See [`StrictMode`] for the different strictness levels.
498/// - Used in [`StrictSetting`] for configuring strict behavior.
499/// - Related to [`Settings::report_nonstrict`] for error reporting.
500#[derive(Debug, Clone, Copy, PartialEq, Eq)]
501pub enum StrictReturn {
502    /// Boolean return value for simple strict/non-strict decisions.
503    ///
504    /// - `true` corresponds to [`StrictMode::Error`] (strict behavior).
505    /// - `false` corresponds to [`StrictMode::Ignore`] (non-strict behavior).
506    Bool(bool),
507    /// Explicit strict mode return value for precise control.
508    ///
509    /// Allows returning any [`StrictMode`] variant for detailed strictness
510    /// control.
511    Mode(StrictMode),
512}
513
514/// Function signature for custom strict mode evaluation in KaTeX.
515pub type StrictFunction =
516    dyn Fn(&str, &str, Option<&dyn ErrorLocationProvider>) -> Option<StrictReturn> + Send + Sync;
517
518/// Configuration for strict mode behavior in KaTeX parsing and rendering.
519///
520/// This enum allows flexible configuration of how KaTeX handles non-standard
521/// LaTeX input. It can be set to a fixed strictness level, a simple boolean,
522/// or a custom function for dynamic strictness decisions based on context.
523///
524/// # LaTeX/KaTeX Context
525/// Strict mode controls KaTeX's adherence to LaTeX standards. When enabled,
526/// KaTeX will report or reject input that deviates from standard LaTeX syntax,
527/// helping catch errors and ensure compatibility. The function variant allows
528/// fine-grained control over which inputs are considered strict violations.
529///
530/// # Cross-references
531/// - See [`StrictMode`] for available strictness levels.
532/// - Used in [`Settings`] for global strict configuration.
533/// - Related to [`StrictReturn`] for function return values.
534#[derive(Clone)]
535pub enum StrictSetting {
536    /// Fixed strict mode level applied to all inputs.
537    ///
538    /// Uses the specified [`StrictMode`] for all parsing decisions.
539    Mode(StrictMode),
540    /// Boolean strict setting for simple on/off control.
541    ///
542    /// - `true` maps to [`StrictMode::Error`] (strict).
543    /// - `false` maps to [`StrictMode::Ignore`] (non-strict).
544    Bool(bool),
545    /// Custom function for dynamic strictness evaluation.
546    ///
547    /// The function receives error code, message, and optional location,
548    /// returning an optional [`StrictReturn`] to determine behavior.
549    ///
550    /// # Function Parameters
551    /// - `error_code`: String identifier for the type of strict violation.
552    /// - `error_msg`: Human-readable description of the issue.
553    /// - `token`: Optional location information for error reporting.
554    ///
555    /// # Function Return
556    /// - `Some(StrictReturn)` to specify strictness behavior.
557    /// - `None` to fall back to default behavior.
558    Function(Arc<StrictFunction>),
559}
560
561impl fmt::Debug for StrictSetting {
562    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
563        match self {
564            Self::Mode(m) => write!(f, "StrictSetting::Mode({m:?})"),
565            Self::Bool(b) => write!(f, "StrictSetting::Bool({b})"),
566            Self::Function(_) => write!(f, "StrictSetting::Function(<fn>)"),
567        }
568    }
569}
570
571impl Default for StrictSetting {
572    fn default() -> Self {
573        Self::Mode(StrictMode::Ignore)
574    }
575}
576
577/// Context structure for validating potentially dangerous inputs in KaTeX
578/// rendering.
579///
580/// This struct encapsulates information about potentially unsafe content (such
581/// as URLs, styles, or attributes) that requires trust validation before
582/// rendering. It provides a comprehensive context for security decisions,
583/// allowing fine-grained control over what content is permitted in mathematical
584/// expressions.
585///
586/// # LaTeX/KaTeX Context
587/// LaTeX commands like `\href`, `\htmlClass`, and `\htmlStyle` can introduce
588/// security risks if not properly validated. KaTeX uses trust contexts to
589/// implement security policies that prevent XSS attacks and other
590/// vulnerabilities while maintaining functionality for legitimate use cases.
591///
592/// # Cross-references
593/// - See [`Settings::is_trusted`] for trust validation logic.
594/// - Related to [`TrustSetting`] for configuring trust policies.
595/// - Used with [`crate::types::CssStyle`] for style validation.
596#[derive(Debug, Clone, Default)]
597pub struct TrustContext {
598    /// The LaTeX command name that triggered the trust check (e.g., "\\href",
599    /// "\\htmlClass").
600    ///
601    /// This identifies the specific command requiring validation, allowing
602    /// command-specific trust policies.
603    pub command: String,
604    /// Optional URL string involved in the trust decision.
605    ///
606    /// Present for URL-related commands like `\href`. The URL's protocol
607    /// is automatically inferred and stored in the `protocol` field.
608    pub url: Option<String>,
609    /// The protocol inferred from the URL (e.g., "http", "https", "mailto").
610    ///
611    /// Automatically populated when `url` is provided. Used to enforce
612    /// protocol-specific security policies.
613    pub protocol: Option<String>,
614    /// Optional CSS class name for HTML class attributes.
615    ///
616    /// Used with commands like `\htmlClass` to specify CSS classes
617    /// for generated HTML elements.
618    pub class: Option<String>,
619    /// Optional HTML id attribute value.
620    ///
621    /// Used with commands like `\htmlId` to assign unique identifiers
622    /// to rendered HTML elements.
623    pub id: Option<String>,
624    /// Optional inline CSS style string.
625    ///
626    /// Contains CSS style declarations for commands like `\htmlStyle`.
627    /// Subject to validation to prevent malicious style injection.
628    pub style: Option<String>,
629    /// Optional map of HTML attributes for data attributes.
630    ///
631    /// Used with commands like `\htmlData` to add custom data attributes
632    /// to rendered HTML elements.
633    pub attributes: Option<KeyMap<String, String>>,
634}
635
636/// Function signature for custom trust evaluation in KaTeX.
637pub type TrustFunction = dyn Fn(&mut TrustContext) -> Option<bool> + Send + Sync;
638
639/// Configuration for trust validation of potentially dangerous content in
640/// KaTeX.
641///
642/// This enum controls how KaTeX validates and permits potentially unsafe
643/// content such as URLs, styles, and HTML attributes. It can be set to a simple
644/// boolean for blanket trust decisions or a custom function for context-aware
645/// validation.
646///
647/// # LaTeX/KaTeX Context
648/// Certain LaTeX commands can introduce security risks (e.g., `\href` with
649/// malicious URLs, `\htmlStyle` with XSS payloads). Trust settings allow
650/// administrators to control which content is permitted, balancing
651/// functionality with security.
652///
653/// # Cross-references
654/// - See [`TrustContext`] for the context passed to trust functions.
655/// - Used in [`Settings`] for global trust configuration.
656/// - Related to [`Settings::is_trusted`] for validation logic.
657#[derive(Clone)]
658pub enum TrustSetting {
659    /// Fixed boolean trust setting for simple allow/deny decisions.
660    ///
661    /// - `true` trusts all potentially dangerous content.
662    /// - `false` rejects all potentially dangerous content.
663    Bool(bool),
664    /// Custom function for dynamic trust evaluation based on context.
665    ///
666    /// The function receives a mutable [`TrustContext`] and returns an optional
667    /// boolean indicating whether the content should be trusted.
668    ///
669    /// # Function Parameters
670    /// - `context`: Mutable reference to [`TrustContext`] containing details
671    ///   about the potentially dangerous content (command, URL, style, etc.).
672    ///
673    /// # Function Return
674    /// - `Some(true)` to trust the content.
675    /// - `Some(false)` to reject the content.
676    /// - `None` to fall back to default behavior.
677    ///
678    /// # Security Considerations
679    /// Trust functions should carefully validate all aspects of the context
680    /// to prevent security vulnerabilities.
681    Function(Arc<TrustFunction>),
682}
683
684impl fmt::Debug for TrustSetting {
685    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
686        match self {
687            Self::Bool(b) => write!(f, "TrustSetting::Bool({b})"),
688            Self::Function(_) => write!(f, "TrustSetting::Function(<fn>)"),
689        }
690    }
691}
692
693impl Default for TrustSetting {
694    fn default() -> Self {
695        Self::Bool(false)
696    }
697}