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
use crate::{helpers::safe_html_str, MathML};
use std::fmt::{Display, Formatter};

mod display;

/// The [`<mi>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mi) element indicates that the content should be rendered as an identifier such as function names, variables or symbolic constants.
///
/// You can also have arbitrary text in it to mark up terms.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MathIdentifier {
    identifier: String,
    variant: FontVariant,
}

// noinspection SpellCheckingInspection
/// The [`<mtext>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtext) element is used to display text in a math formula.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MathText {
    is_string: bool,
    text: String,
}

// noinspection SpellCheckingInspection
/// Font variant for [`<mi>`](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mi),
/// used as [`mathvariant`](https://developer.mozilla.org/en-US/docs/Web/MathML/Global_attributes/mathvariant) attribute.
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum FontVariant {
    /// <math><mi mathvariant="normal">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    Normal,
    /// <math><mi mathvariant="italic">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    Italic,
    /// <math><mi mathvariant="bold">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    Bold,
    /// <math><mi mathvariant="bold-italic">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    BoldItalic,
    /// <math><mi mathvariant="double-struck">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    DoubleStruck,
    /// <math><mi mathvariant="bold-fraktur">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    BoldFraktur,
    /// <math><mi mathvariant="script">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    Script,
    /// <math><mi mathvariant="bold-script">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    BoldScript,
    /// <math><mi mathvariant="fraktur">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    Fraktur,
    /// <math><mi mathvariant="sans-serif">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    SansSerif,
    /// <math><mi mathvariant="bold-sans-serif">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    BoldSansSerif,
    /// <math><mi mathvariant="sans-serif-italic">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    SansSerifItalic,
    /// <math><mi mathvariant="sans-serif-bold-italic">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    SansSerifBoldItalic,
    /// <math><mi mathvariant="monospace">ABCDEFGHIJKLMNOPQRSTUVWXYZ</mi></math>
    Monospace,
}

impl MathIdentifier {
    /// Creates a new [`MathIdentifier`] with the given [`FontVariant`].
    pub fn new<S>(text: S, variant: FontVariant) -> Self
    where
        S: ToString,
    {
        Self { identifier: text.to_string(), variant }
    }
    /// Creates a new [`MathIdentifier`] with the [`FontVariant::Normal`] variant.
    pub fn normal<S>(text: S) -> Self
    where
        S: ToString,
    {
        Self { identifier: text.to_string(), variant: FontVariant::Normal }
    }
    /// Creates a new [`MathIdentifier`] with the [`FontVariant::Italic`] variant.
    pub fn italic<S>(text: S) -> Self
    where
        S: ToString,
    {
        Self { identifier: text.to_string(), variant: FontVariant::Italic }
    }
    /// Gets the font variant of the identifier.
    pub fn get_variant(&self) -> FontVariant {
        self.variant
    }
    /// Gets the identifier of the identifier.
    pub fn get_identifier(&self) -> &str {
        &self.identifier
    }
}

impl MathText {
    /// Creates a new [`MathText`] with the given [`FontVariant`].
    pub fn text<S>(text: S) -> Self
    where
        S: ToString,
    {
        Self { text: text.to_string(), is_string: false }
    }
    /// Creates a new [`MathText`] with the [`FontVariant::Normal`] variant.
    pub fn string<S>(text: S) -> Self
    where
        S: ToString,
    {
        Self { text: text.to_string(), is_string: true }
    }
}

impl MathML {
    /// Creates a new [`MathIdentifier`] with the [`FontVariant::Italic`] variant.
    pub fn identifier<S>(text: S) -> Self
    where
        S: ToString,
    {
        MathIdentifier::italic(text).into()
    }
    /// Creates a new [`MathIdentifier`] with the [`FontVariant::Normal`] variant.
    pub fn text<S>(text: S) -> Self
    where
        S: ToString,
    {
        MathText::text(text).into()
    }
    /// Creates a new [`MathText`] with the [`FontVariant::Normal`] variant.
    pub fn string<S>(text: S) -> Self
    where
        S: ToString,
    {
        MathText::string(text).into()
    }
}