mathml_core/helpers/
mod.rs

1#![allow(non_snake_case)]
2#![allow(unused_variables)]
3#![doc = include_str!("readme.md")]
4mod matrix;
5pub use self::matrix::*;
6use crate::{
7    blocks::MathStyle, LineThickness, MathElement, MathFenced, MathFraction, MathML, MathMultiScript, MathRow, MathTable,
8};
9
10/// Build a normal fraction.
11///
12/// # Input
13///
14/// ```tex
15/// \begin{vmatrix} a & b \\ c & d \end{vmatrix}
16/// ```
17///
18/// # Output
19#[doc = include_str!("isotope.xml")]
20pub fn frac<N, D>(numerator: N, denominator: D) -> MathML
21where
22    N: Into<MathML>,
23    D: Into<MathML>,
24{
25    MathML::fraction(numerator, denominator)
26}
27
28/// Renders a display style fraction.
29///
30/// # Input
31///
32/// ```tex
33/// \begin{vmatrix} a & b \\ c & d \end{vmatrix}
34/// ```
35///
36/// # Output
37#[doc = include_str!("isotope.xml")]
38pub fn dfrac<N, D>(numerator: N, denominator: D) -> MathML
39where
40    N: Into<MathML>,
41    D: Into<MathML>,
42{
43    MathStyle::display(frac(numerator, denominator)).into()
44}
45
46/// Renders a matrix with vertical bars.
47///
48/// # Input
49///
50/// ```tex
51/// \begin{vmatrix} a & b \\ c & d \end{vmatrix}
52/// ```
53///
54/// # Output
55#[doc = include_str!("isotope.xml")]
56pub fn cfrac(numerator: MathML, denominator: MathML) -> MathML {
57    todo!()
58}
59
60/// Renders binomial coefficient as `\binom{n}{k}`.
61///
62/// # Input
63///
64/// ```
65/// # use mathml_core::helpers::binom;
66/// binom('n', 'k');
67/// ```
68///
69/// # Output
70#[doc = include_str!("isotope.xml")]
71pub fn binom<N, D>(numerator: N, denominator: D) -> MathML
72where
73    N: Into<MathML>,
74    D: Into<MathML>,
75{
76    MathFraction::new(numerator.into(), denominator.into()).with_thickness(LineThickness::Length(0)).into()
77}
78
79/// Renders binomial coefficient as `C_{n}^{k}`.
80///
81/// # Input
82///
83/// ```
84/// # use mathml_core::helpers::cbinom;
85/// cbinom('n', 'k');
86/// ```
87///
88/// # Output
89#[doc = include_str!("isotope.xml")]
90pub fn cbinom<N, D>(numerator: N, denominator: D) -> MathML
91where
92    N: Into<MathML>,
93    D: Into<MathML>,
94{
95    MathMultiScript::sub_super_script(MathML::identifier("C"), numerator.into(), denominator.into()).into()
96}
97
98/// Renders a matrix with vertical bars.
99///
100/// # Input
101///
102/// ```no_run
103/// # use mathml_core::helpers::legendre_symbols;
104/// legendre_symbols('a', 'b');
105/// ```
106///
107/// # Output
108#[doc = include_str!("isotope.xml")]
109pub fn legendre_symbols<N, D>(numerator: N, denominator: D) -> MathFenced
110where
111    N: Into<MathML>,
112    D: Into<MathML>,
113{
114    MathFenced::new(vec![MathFraction::new(numerator.into(), denominator.into()).into()], '(', ')')
115}
116
117/// Build a isotopic symbol.
118///
119/// # Input
120///
121/// ```
122/// # use mathml_core::{helpers::isotope, MathFenced};
123/// MathFenced::parentheses(vec![
124///     isotope("H", 1, None).into(),
125///     isotope("H", 2, Some(2)).into(),
126///     isotope("H", 3, None).into(),
127/// ]);
128/// ```
129///
130/// # Output
131#[doc = include_str!("isotope.xml")]
132pub fn isotope(symbol: &str, mass_number: usize, atomic_number: Option<usize>) -> MathMultiScript {
133    let ld = match atomic_number {
134        Some(s) => vec![s.into()],
135        None => vec![],
136    };
137    MathMultiScript::new(MathML::identifier(symbol), vec![MathML::number(mass_number)], ld, vec![], vec![])
138}
139
140/// Build a isotopic symbol.
141#[inline(always)]
142pub fn safe_html_char<W>(writer: &mut W, c: char) -> std::fmt::Result
143where
144    W: std::fmt::Write,
145{
146    match c {
147        '<' => writer.write_str("&lt;"),
148        '>' => writer.write_str("&gt;"),
149        '&' => writer.write_str("&amp;"),
150        '"' => writer.write_str("&quot;"),
151        '\'' => writer.write_str("&apos;"),
152        _ => writer.write_char(c),
153    }
154}
155
156/// Build a isotopic symbol.
157#[inline(always)]
158pub fn safe_html_str<W>(writer: &mut W, s: &str) -> std::fmt::Result
159where
160    W: std::fmt::Write,
161{
162    for c in s.chars() {
163        safe_html_char(writer, c)?;
164    }
165    Ok(())
166}
167
168/// Assert that the MathML is equal to the target string, ignoring all whitespaces.
169#[track_caller]
170pub fn assert_no_ws(source: &MathML, target: &str) {
171    let text = source.to_string();
172    assert_eq!(remove_ws(&text), remove_ws(target));
173}
174
175/// remove all whitespaces from a string
176#[inline]
177fn remove_ws(string: &str) -> String {
178    let mut refined = String::with_capacity(string.len());
179    for char in string.chars() {
180        if char.is_whitespace() {
181            continue;
182        }
183        refined.push(char);
184    }
185    refined
186}