pulldown_latex/config.rs
1//! Configuration options for the renderer.
2//!
3//! The configuration of the `mathml` renderer is done through the [`RenderConfig`] struct.
4use std::fmt::Display;
5
6/// Configuration for the `mathml` renderer.
7///
8/// The default value is: [`RenderConfig::default`].
9#[derive(Debug, Clone, Copy, PartialEq)]
10pub struct RenderConfig<'a> {
11 /// See [`DisplayMode`].
12 pub display_mode: DisplayMode,
13 /// If Some, the `mathml` generated includes an `<annotation>` element that contains the
14 /// provided string. It is commonly used to include the LaTeX source code in the generated `mathml`.
15 pub annotation: Option<&'a str>,
16 /// A RGB color. This option determines the color in which errors and invalid LaTeX commands are rendered in.
17 pub error_color: (u8, u8, u8),
18 /// If true, a `xml` namespace (`xmlns="http://www.w3.org/1998/Math/MathML"`) will be written
19 /// into the `<math>` element.
20 ///
21 /// This namespace is unnecessary for modern browsers but can be helpful for other user agents,
22 /// such as Microsoft Word.
23 pub xml: bool,
24 /// See [`MathStyle`].
25 pub math_style: MathStyle,
26}
27
28impl<'a> RenderConfig<'a> {
29 /// Create a new `RenderConfig` with the provided annotation, and default values for other fields.
30 pub fn with_annotation(annotation: &'a str) -> Self {
31 Self {
32 annotation: Some(annotation),
33 ..Self::default()
34 }
35 }
36}
37
38impl<'a> Default for RenderConfig<'a> {
39 /// # Default Value
40 /// ```rust
41 /// # use pulldown_latex::config::{RenderConfig, DisplayMode, MathStyle};
42 /// const DEFAULT: RenderConfig = RenderConfig {
43 /// display_mode: DisplayMode::Inline,
44 /// annotation: None,
45 /// error_color: (178, 34, 34),
46 /// xml: false,
47 /// math_style: MathStyle::TeX,
48 /// };
49 /// assert_eq!(RenderConfig::default(), DEFAULT);
50 /// ```
51 fn default() -> Self {
52 Self {
53 display_mode: DisplayMode::Inline,
54 annotation: None,
55 error_color: (178, 34, 34),
56 xml: false,
57 math_style: MathStyle::TeX,
58 }
59 }
60}
61
62/// The way in which math variables are displayed.
63///
64/// This is used to determine how single-letter variables are displayed. This affects lowercase and
65/// uppercase latin letters (__a-z__ and __A-Z__), and uppercase and lowercase greek letters
66/// (__α-ω__ and __Α-Ω__). Style differences are shown in the table below.
67///
68/// ## Math Styles
69///
70/// | Style | Low. Latin | Upp. Latin | Low. Greek | Upp. Greek |
71/// | ----- | ---------- | ---------- | ---------- | ---------- |
72/// | `TeX` | _italic_ | _italic_ | _italic_ | upright |
73/// | `ISO` | _italic_ | _italic_ | _italic_ | _italic_ |
74/// | `French` | _italic_ | upright | upright | upright |
75/// | `Upright` | upright | upright | upright | upright |
76#[derive(Debug, Default, Clone, Copy, PartialEq)]
77pub enum MathStyle {
78 /// The default style used in TeX.
79 ///
80 /// Makes everything italic except for uppercase greek letters.
81 ///
82 /// __This is the default value.__
83 #[default]
84 TeX,
85 /// The style used in `ISO 80000-2:2019`.
86 ///
87 /// Makes everything italic.
88 ISO,
89 /// The style used in French typography.
90 ///
91 /// Makes everything upright except for lowercase latin letters.
92 French,
93 /// Makes everything upright.
94 Upright,
95}
96
97impl MathStyle {
98 /// Whether or not the style should __manually__ be set to upright for the given character.
99 ///
100 /// The mathml spec states that the default style for math variables is italic for all
101 /// characters, following the ISO 80000-2:2019 standard. If the style is set to something other
102 /// than `TeX`, then the style should be set to upright for some characters. This function
103 /// returns `true` if the style should be set to upright for the given character.
104 pub(crate) fn should_be_upright(self, c: char) -> bool {
105 match self {
106 MathStyle::TeX => c.is_uppercase() && !c.is_ascii_uppercase(),
107 MathStyle::ISO => false,
108 MathStyle::French => !c.is_ascii_lowercase(),
109 MathStyle::Upright => true,
110 }
111 }
112}
113
114/// How the math is displayed.
115///
116/// Semantically, this affects the [`display`] attribute of the [`<math>`] tag in the mathml
117/// output. The attribute will be set to `block` or `inline` depending on the value of this enum.
118///
119/// [`<math>`]: https://developer.mozilla.org/en-US/docs/Web/MathML/Element/math
120/// [`display`]: https://developer.mozilla.org/en-US/docs/Web/MathML/Element/math#display
121#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
122pub enum DisplayMode {
123 /// The math is rendered inline.
124 ///
125 /// The equation is displayed inline within a sentence or paragraph, and elements such as
126 /// `\int` and `\sum` are minimized to fit within the line.
127 ///
128 /// __This is the default value.__
129 #[default]
130 Inline,
131 /// The math is rendered in display/block mode (`displaystyle` in LaTeX).
132 ///
133 /// The equation is centered on its own line
134 /// and elements such as`\int` and `\sum` are displayed bigger.
135 Block,
136}
137
138impl Display for DisplayMode {
139 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
140 match self {
141 DisplayMode::Inline => f.write_str("inline"),
142 DisplayMode::Block => f.write_str("block"),
143 }
144 }
145}