katex-rs 0.2.4

A Rust implementation of KaTeX - Fast math typesetting for anywhere, more than just the web.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
//! Core type definitions for KaTeX Rust implementation

mod class_list;
mod source_location;

use core::fmt;

use crate::define_environment::EnvSpec;
use crate::define_function::FunctionSpec;
use crate::namespace::KeyMap;
use crate::parser::parse_node::NodeType;
use crate::utils::escape_into;
use rapidhash::HashMapExt as _;
pub use source_location::{LexerInterface, SourceLocation};
use strum::AsRefStr;
use strum::Display;
use strum::EnumCount;
use strum::EnumIter;
use strum::EnumString;

/// Parse error type - imported from parse_error module
mod parse_error;
pub use parse_error::{ErrorLocationProvider, ParseError, ParseErrorKind};
use strum::FromRepr;

mod tokens;
pub use crate::symbols::Mode;
pub use class_list::ClassList;
pub use tokens::{Token, TokenText};

mod settings;
pub use settings::{
    OutputFormat, Settings, StrictFunction, StrictMode, StrictReturn, StrictSetting, TrustContext,
    TrustFunction, TrustSetting,
};

pub use source_location::SourceRangeRef;

/// Represents a set of standard CSS property names.
///
/// This enum is serialized in `kebab-case` (the standard CSS syntax) via
/// `strum`. It can be used for mapping strongly-typed property names to their
/// CSS strings and is especially useful when generating styles
/// programmatically.
#[derive(
    EnumIter,
    Debug,
    Copy,
    AsRefStr,
    PartialEq,
    Eq,
    Hash,
    Clone,
    Display,
    EnumCount,
    FromRepr,
    Ord,
    PartialOrd,
)]
#[strum(serialize_all = "kebab-case")]
#[repr(u8)]
pub enum CssProperty {
    /// Sets the background color of an element. See: <https://developer.mozilla.org/docs/Web/CSS/background-color>
    BackgroundColor,
    /// Sets the width of the bottom border of an element. See: <https://developer.mozilla.org/docs/Web/CSS/border-bottom-width>
    BorderBottomWidth,
    /// Sets the color of the border on all four sides of an element. See: <https://developer.mozilla.org/docs/Web/CSS/border-color>
    BorderColor,
    /// Sets the style of the right border. See: <https://developer.mozilla.org/docs/Web/CSS/border-right-style>
    BorderRightStyle,
    /// Sets the width of the right border of an element. See: <https://developer.mozilla.org/docs/Web/CSS/border-right-width>
    BorderRightWidth,
    /// Sets the width of the top border of an element. See: <https://developer.mozilla.org/docs/Web/CSS/border-top-width>
    BorderTopWidth,
    /// Sets the style of all four borders. See: <https://developer.mozilla.org/docs/Web/CSS/border-style>
    BorderStyle,
    /// Sets the width of all four borders. See: <https://developer.mozilla.org/docs/Web/CSS/border-width>
    BorderWidth,
    /// Specifies how far the bottom edge of an element is from the bottom edge of its containing block. See: <https://developer.mozilla.org/docs/Web/CSS/bottom>
    Bottom,
    /// Sets the color of the text content of an element. See: <https://developer.mozilla.org/docs/Web/CSS/color>
    Color,
    /// Specifies the height of an element. See: <https://developer.mozilla.org/docs/Web/CSS/height>
    Height,
    /// Specifies how far the left edge of an element is from the left edge of its containing block. See: <https://developer.mozilla.org/docs/Web/CSS/left>
    Left,
    /// Sets the margin area on all four sides of an element. See: <https://developer.mozilla.org/docs/Web/CSS/margin>
    Margin,
    /// Sets the margin area on the left side of an element. See: <https://developer.mozilla.org/docs/Web/CSS/margin-left>
    MarginLeft,
    /// Sets the margin area on the right side of an element. See: <https://developer.mozilla.org/docs/Web/CSS/margin-right>
    MarginRight,
    /// Sets the margin area on the top side of an element. See: <https://developer.mozilla.org/docs/Web/CSS/margin-top>
    MarginTop,
    /// Sets the minimum width of an element. See: <https://developer.mozilla.org/docs/Web/CSS/min-width>
    MinWidth,
    /// Sets the padding on the left side of an element. See: <https://developer.mozilla.org/docs/Web/CSS/padding-left>
    PaddingLeft,
    /// Specifies how an element is positioned in the document. See: <https://developer.mozilla.org/docs/Web/CSS/position>
    Position,
    /// Applies one or more shadows to text. See: <https://developer.mozilla.org/docs/Web/CSS/text-shadow>
    TextShadow,
    /// Specifies how far the top edge of an element is from the top edge of its containing block. See: <https://developer.mozilla.org/docs/Web/CSS/top>
    Top,
    /// Specifies the width of an element. See: <https://developer.mozilla.org/docs/Web/CSS/width>
    Width,
    /// Sets the vertical alignment of an inline or table-cell element. See: <https://developer.mozilla.org/docs/Web/CSS/vertical-align>
    VerticalAlign,
}

/// A type alias representing CSS style properties for HTML nodes in KaTeX
/// rendering.
///
/// This `HashMap` maps CSS property names (as strings) to their corresponding
/// values, enabling dynamic styling of mathematical expressions rendered as
/// HTML. It is used throughout the KaTeX rendering pipeline to apply visual
/// styles such as colors, fonts, spacing, and positioning to generated HTML
/// elements.
///
/// # LaTeX/KaTeX Context
/// In mathematical typesetting, CSS styles are crucial for controlling the
/// visual appearance of rendered math, including font variants (e.g., italic
/// for variables), display styles (inline vs. block), and layout adjustments.
/// This type supports KaTeX's approach to generating accessible and visually
/// consistent math output.
///
/// # Cross-references
/// - Used in [`TrustContext`] for inline style validation.
/// - See [`Settings`] for global styling options.
/// - Related to [`FontVariant`] for font-specific styling.
#[derive(Clone, PartialEq, Eq, Default)]
pub struct CssStyle {
    map: KeyMap<CssProperty, String>,
}

impl fmt::Debug for CssStyle {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let mut ds = f.debug_struct("CssStyle");
        // Sort the keys for consistent output
        let mut entries: Vec<(&CssProperty, &String)> = self.map.iter().collect();
        entries.sort_by_key(|(k, _)| *k);
        for (key, value) in entries {
            ds.field(key.as_ref(), value);
        }
        ds.finish()
    }
}

impl fmt::Display for CssStyle {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.write_to(f)
    }
}

impl CssStyle {
    /// Creates one with given capacity
    #[inline]
    #[must_use]
    pub fn with_capacity(capacity: usize) -> Self {
        Self {
            map: KeyMap::with_capacity(capacity),
        }
    }

    /// Inserts or updates a CSS property with the given value.
    #[inline]
    pub fn insert<T>(&mut self, property: CssProperty, value: T)
    where
        T: Into<String>,
    {
        self.map.insert(property, value.into());
    }

    /// Checks if the style contains a specific CSS property.
    #[inline]
    #[must_use]
    pub fn contains_key(&self, property: CssProperty) -> bool {
        self.map.contains_key(&property)
    }

    /// Retrieves the value of a specific CSS property, if it exists.
    #[inline]
    #[must_use]
    pub fn get(&self, property: CssProperty) -> Option<&str> {
        self.map.get(&property).map(AsRef::as_ref)
    }

    /// Checks if the style is empty (contains no properties).
    #[inline]
    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.map.is_empty()
    }

    /// Writes the CSS style as a string to the provided formatter.
    #[inline]
    pub fn write_to<W: fmt::Write>(&self, writer: &mut W) -> fmt::Result {
        for (key, value) in &self.map {
            writer.write_str(key.as_ref())?;
            writer.write_char(':')?;
            escape_into(writer, value)?;
            writer.write_char(';')?;
        }
        Ok(())
    }
}

/// Enumeration of LaTeX argument types used in KaTeX parsing and rendering.
///
/// This enum categorizes the different kinds of arguments that LaTeX commands
/// and functions can accept, enabling type-safe handling during mathematical
/// expression processing. Each variant represents a specific argument category
/// with distinct parsing and validation rules.
///
/// # LaTeX/KaTeX Context
/// In LaTeX, commands often require arguments of specific types (e.g., colors,
/// sizes, URLs). KaTeX extends this by providing structured argument types
/// that facilitate robust parsing and rendering of complex mathematical
/// expressions, including those with embedded URLs, custom styling, and
/// mode-specific content.
///
/// # Cross-references
/// - See [`Mode`] for mathematical rendering modes.
/// - Used in [`Settings`] for macro and command validation.
/// - Related to [`TrustContext`] for security validation of URLs and styles.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ArgType {
    /// Color specification argument (e.g., for `\color{red}`).
    ///
    /// Represents arguments that specify colors, such as named colors,
    /// hex values, or RGB specifications used in color commands.
    Color,
    /// Size specification argument (e.g., for `\fontsize{12pt}{14pt}`).
    ///
    /// Represents arguments that define sizes, including font sizes,
    /// spacing dimensions, and other length specifications.
    Size,
    /// URL string argument (e.g., for `\href{http://example.com}{text}`).
    ///
    /// Represents arguments containing URLs, subject to trust validation
    /// to prevent security vulnerabilities.
    Url,
    /// Raw string argument without special processing.
    ///
    /// Represents plain text arguments that should be used as-is,
    /// without LaTeX interpretation or escaping.
    Raw,
    /// Original mode type argument.
    ///
    /// Represents arguments that preserve the original parsing mode,
    /// useful for commands that need to maintain context.
    Original,
    /// Horizontal box argument (e.g., for `\hbox{content}`).
    ///
    /// Represents arguments that create horizontal boxes for layout control.
    Hbox,
    /// Primitive type argument.
    ///
    /// Represents low-level primitive arguments used in core LaTeX operations.
    Primitive,
    /// Mode-specific type argument.
    ///
    /// Represents arguments that are specific to a particular mathematical
    /// rendering mode (e.g., inline math vs. display math).
    ///
    /// # Parameters
    /// - `mode`: The specific [`Mode`] for this argument type.
    Mode(Mode),
}

/// Enumeration of style variants
#[derive(Debug, Clone, Copy, PartialEq, Eq, AsRefStr)]
#[strum(serialize_all = "lowercase")]
pub enum StyleVariant {
    /// Text style for inline mathematical expressions.
    ///
    /// Used for math embedded within text, with normal font size and spacing.
    /// Corresponds to LaTeX's `\textstyle`.
    Text,
    /// Display style for block mathematical expressions.
    ///
    /// Used for standalone equations, with larger font size and centered
    /// layout. Corresponds to LaTeX's `\displaystyle`.
    Display,
    /// Script style for first-level superscripts and subscripts.
    ///
    /// Used for exponents and indices, with reduced font size.
    /// Corresponds to LaTeX's `\scriptstyle`.
    Script,
    /// Scriptscript style for nested superscripts and subscripts.
    ///
    /// Used for exponents of exponents, with further reduced font size.
    /// Corresponds to LaTeX's `\scriptscriptstyle`.
    ScriptScript,
}

/// Enumeration of token types that can break or terminate parsing in KaTeX.
///
/// This enum represents special tokens that signal the end of a parsing
/// context, such as closing delimiters, command terminators, or end-of-input
/// markers. These tokens are crucial for maintaining proper parsing boundaries
/// in LaTeX mathematical expressions.
///
/// # LaTeX/KaTeX Context
/// In LaTeX parsing, certain tokens naturally terminate commands or groups.
/// KaTeX uses these break tokens to ensure correct parsing of nested
/// structures, preventing runaway parsing and ensuring proper error recovery.
///
///
/// # Cross-references
/// - See [`Token`] for general token representation.
/// - Used in `ParseError` for error location reporting.
/// - Related to parsing of groups and commands in the lexer.
#[derive(Debug, Clone, PartialEq, Eq, EnumString, AsRefStr)]
pub enum BreakToken {
    /// Right bracket token `]` - terminates bracket groups.
    #[strum(serialize = "]")]
    RightBracket,
    /// Right brace token `}` - terminates brace groups.
    #[strum(serialize = "}")]
    RightBrace,
    /// End group command `\endgroup` - terminates LaTeX groups.
    #[strum(serialize = "\\endgroup")]
    EndGroup,
    /// Dollar sign `$` - terminates inline math mode.
    #[strum(serialize = "$")]
    Dollar,
    /// Right parenthesis `\)` - terminates display math mode.
    #[strum(serialize = "\\)")]
    RightParen,
    /// Double backslash `\\` - terminates table rows.
    #[strum(serialize = "\\\\")]
    DoubleBackslash,
    /// End command `\end` - terminates environments.
    #[strum(serialize = "\\end")]
    End,
    /// End of file marker - terminates input stream.
    #[strum(serialize = "EOF")]
    Eof,
}

/// Enumeration of font variants used in mathematical expression rendering.
///
/// This enum defines the various font styles available for rendering math
/// symbols and text in KaTeX. Each variant corresponds to a specific typeface
/// or style that can be applied to mathematical content for proper
/// typographical presentation.
///
/// # LaTeX/KaTeX Context
/// LaTeX provides extensive font support for mathematical typesetting,
/// including special symbol fonts (e.g., Blackboard Bold for sets, Fraktur for
/// certain notations). KaTeX implements these variants to ensure accurate
/// reproduction of mathematical documents with correct symbol rendering.
///
/// # Cross-references
/// - See [`CssStyle`] for CSS-based font styling.
/// - Related to [`StyleVariant`] for size and positioning adjustments.
/// - Used in symbol lookup and font metric calculations.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FontVariant {
    /// Bold font variant for emphasized mathematical symbols.
    Bold,
    /// Bold italic font variant for bold mathematical variables.
    BoldItalic,
    /// Bold sans-serif font variant for UI elements in math.
    BoldSansSerif,
    /// Double-struck (Blackboard Bold) font variant for sets (e.g., ℝ, ℕ).
    DoubleStruck,
    /// Fraktur font variant for special mathematical notation.
    Fraktur,
    /// Italic font variant for mathematical variables and functions.
    Italic,
    /// Monospace font variant for code and typewriter text in math.
    Monospace,
    /// Normal (roman) font variant for regular mathematical text.
    Normal,
    /// Sans-serif font variant for clean, modern mathematical text.
    SansSerif,
    /// Sans-serif bold italic font variant for emphasized sans-serif text.
    SansSerifBoldItalic,
    /// Sans-serif italic font variant for italic sans-serif text.
    SansSerifItalic,
    /// Script font variant for calligraphic mathematical symbols.
    Script,
}

/// General trait for Spec types, for arguments and properties
pub trait Spec {
    /// Returns the number of arguments required.
    fn num_args(&self) -> usize;
    /// Returns the number of optional arguments.
    fn num_optional_args(&self) -> usize;
    /// Returns the argument types if specified.
    fn arg_types(&self) -> Option<&Vec<ArgType>>;
    /// Returns true if the spec is primitive.
    fn primitive(&self) -> bool;
    /// Returns the node type if specified.
    fn node_type(&self) -> Option<&NodeType>;
}

impl Spec for FunctionSpec {
    fn num_args(&self) -> usize {
        self.num_args
    }
    fn num_optional_args(&self) -> usize {
        self.num_optional_args
    }
    fn arg_types(&self) -> Option<&Vec<ArgType>> {
        self.arg_types.as_ref()
    }
    fn primitive(&self) -> bool {
        self.primitive
    }
    fn node_type(&self) -> Option<&NodeType> {
        self.node_type.as_ref()
    }
}

impl Spec for EnvSpec {
    fn num_args(&self) -> usize {
        self.num_args
    }
    fn num_optional_args(&self) -> usize {
        self.num_optional_args
    }
    fn arg_types(&self) -> Option<&Vec<ArgType>> {
        self.arg_types.as_ref()
    }
    fn primitive(&self) -> bool {
        false
    }
    fn node_type(&self) -> Option<&NodeType> {
        Some(&self.node_type)
    }
}