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
use super::*;

impl Display for DisplayStyle {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            DisplayStyle::Block => write!(f, "block"),
            DisplayStyle::Inline => write!(f, "inline"),
        }
    }
}

impl Display for MathML {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            MathML::Root(v) => Display::fmt(v, f),
            MathML::Number(v) => Display::fmt(v, f),
            MathML::Letter(v) => Display::fmt(v, f),
            MathML::Operator(v) => Display::fmt(v, f),
            MathML::Sub(v) => Display::fmt(v, f),
            MathML::Sup(v) => Display::fmt(v, f),
            MathML::SubSup(v) => Display::fmt(v, f),
            MathML::Function(fun, arg) => match arg {
                Some(arg) => write!(f, "<mi>{}</mi><mo>&#x2061;</mo>{}", fun, arg),
                None => write!(f, "<mi>{}</mi>", fun),
            },
            MathML::Space(space) => write!(f, r#"<mspace width="{}em"/>"#, space),
            MathML::OverOp(op, acc, target) => write!(f, r#"<mover>{}<mo accent="{}">{}</mo></mover>"#, target, acc, op),
            MathML::UnderOp(op, acc, target) => write!(f, r#"<munder>{}<mo accent="{}">{}</mo></munder>"#, target, acc, op),
            MathML::Overset { over, target } => write!(f, r#"<mover>{}{}</mover>"#, target, over),
            MathML::Underset { under, target } => write!(f, r#"<munder>{}{}</munder>"#, target, under),
            MathML::Under(target, under) => write!(f, r#"<munder>{}{}</munder>"#, target, under),
            MathML::UnderOver { target, under, over } => write!(f, r#"<munderover>{}{}{}</munderover>"#, target, under, over),
            MathML::Sqrt(degree, content) => match degree {
                Some(deg) => write!(f, "<mroot>{}{}</mroot>", content, deg),
                None => write!(f, "<msqrt>{}</msqrt>", content),
            },
            MathML::Frac(v) => Display::fmt(v, f),
            MathML::Row(vec) => write!(f, "<mrow>{}</mrow>", vec.iter().map(|node| format!("{}", node)).collect::<String>()),
            MathML::Phantom(v) => Display::fmt(v, f),
            MathML::Fenced { open, close, content } => {
                write!(
                    f,
                    r#"<mrow><mo stretchy="true" form="prefix">{}</mo>{}<mo stretchy="true" form="postfix">{}</mo></mrow>"#,
                    open, content, close
                )
            }
            MathML::StrechedOp(stretchy, op) => write!(f, r#"<mo stretchy="{}">{}</mo>"#, stretchy, op),
            MathML::OtherOperator(op) => write!(f, "<mo>{}</mo>", op),
            MathML::SizedParen { size, paren } => {
                write!(f, r#"<mrow><mo maxsize="{0}" minsize="{0}">{1}</mro></mrow>"#, size, paren)
            }
            MathML::Slashed(node) => match &**node {
                // force set math-variant here
                MathML::Letter(mi) => {
                    write!(f, "{:}", mi)
                }
                MathML::Operator(x) => write!(f, "<mo>{}&#x0338;</mo>", x),
                n => write!(f, "{}", n),
            },
            MathML::Matrix(content, columnalign) => {
                let mut mathml = format!("<mtable{}><mtr><mtd>", columnalign);
                for (i, node) in content.iter().enumerate() {
                    match node {
                        MathML::NewLine => {
                            mathml.push_str("</mtd></mtr>");
                            if i < content.len() {
                                mathml.push_str("<mtr><mtd>")
                            }
                        }
                        MathML::Ampersand => {
                            mathml.push_str("</mtd>");
                            if i < content.len() {
                                mathml.push_str("<mtd>")
                            }
                        }
                        node => {
                            mathml = format!("{}{}", mathml, node);
                        }
                    }
                }
                mathml.push_str("</mtd></mtr></mtable>");

                write!(f, "{}", mathml)
            }
            MathML::Text(text) => write!(f, "<mtext>{}</mtext>", text),
            MathML::Style(display, content) => match display {
                Some(DisplayStyle::Block) => write!(f, r#"<mstyle displaystyle="true">{}</mstyle>"#, content),
                Some(DisplayStyle::Inline) => write!(f, r#"<mstyle displaystyle="false">{}</mstyle>"#, content),
                None => write!(f, "<mstyle>{}</mstyle>", content),
            },
            MathML::Ampersand => {
                todo!()
            }
            MathML::NewLine => {
                todo!()
            }
            MathML::Undefined(_) => {
                todo!()
            }
        }
    }
}