From 0494c462442ff0e7e1977d07df65e39548395ef0 Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 5 Aug 2020 15:54:08 +0200 Subject: [PATCH] Add more literal mappings --- Cargo.toml | 3 +- src/format/mathml.rs | 188 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 189 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0d58a2d..9887a2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,5 @@ license-file = "LICENSE" [dependencies] charred = "0.3.0" maplit = "1.0.2" -lazy_static = "1.4.0" \ No newline at end of file +lazy_static = "1.4.0" +htmlescape = "0.3.1" \ No newline at end of file diff --git a/src/format/mathml.rs b/src/format/mathml.rs index 9051e4c..6f4af23 100644 --- a/src/format/mathml.rs +++ b/src/format/mathml.rs @@ -1,4 +1,6 @@ -use crate::tokens::Greek; +use crate::elements::literal::{Number, PlainText, Symbol}; +use crate::tokens::{Arrow, FontCommand, Function, Greek, Logical, Misc, Relation}; +use htmlescape::encode_minimal; pub trait ToMathML { fn to_mathml(&self) -> String; @@ -48,3 +50,187 @@ impl ToMathML for Greek { format!("{}", inner) } } + +impl ToMathML for PlainText { + fn to_mathml(&self) -> String { + if let Some(formatting) = &self.formatting { + format!( + "{}", + formatting.to_mathml(), + encode_minimal(self.text.as_str()) + ) + } else { + format!("{}", encode_minimal(self.text.as_str())) + } + } +} + +impl ToMathML for FontCommand { + fn to_mathml(&self) -> String { + match self { + FontCommand::Big => "bold".to_string(), + FontCommand::BigOutline => "double-struck", + FontCommand::Cursive => "italic", + FontCommand::TText => "script", + FontCommand::Fr => "bold-fraktur", + FontCommand::SansSerif => "sans-serif", + } + } +} + +impl ToMathML for Symbol { + fn to_mathml(&self) -> String { + format!("{}", encode_minimal(self.symbol.as_str())) + } +} + +impl ToMathML for Number { + fn to_mathml(&self) -> String { + format!("{}", encode_minimal(self.number.as_str())) + } +} + +impl ToMathML for Relation { + fn to_mathml(&self) -> String { + let inner = match self { + Relation::Eq => "=", + Relation::Ne => "≠", + Relation::Lt => "<", + Relation::Gt => ">", + Relation::Le => "≤", + Relation::Ge => "≥", + Relation::Prec => "≺", + Relation::Succ => "≻", + Relation::PrecEq => "≼", + Relation::SuccEq => "≽", + Relation::In => "∈", + Relation::NotIn => "∉", + Relation::SubSet => "⊂", + Relation::SupSet => "⊃", + Relation::SubSetEq => "⊆", + Relation::SupSetEq => "⊇", + Relation::Equiv => "≡", + Relation::Cong => "≅", + Relation::Approx => "≈", + Relation::PropTo => "∝", + }; + + format!("{}", inner) + } +} + +impl ToMathML for Function { + fn to_mathml(&self) -> String { + let inner = match self { + Function::Exp => "exp", + Function::Sin => "sin", + Function::Max => "max", + Function::Min => "min", + Function::Glb => "glb", + Function::G => "g", + Function::Lub => "lub", + Function::Lcm => "lcm", + Function::Gcd => "gcd", + Function::Mod => "mod", + Function::Dim => "dim", + Function::Det => "det", + Function::Ln => "ln", + Function::Log => "log", + Function::Cot => "cot", + Function::Csc => "csc", + Function::Sech => "sech", + Function::Tanh => "tanh", + Function::Cosh => "cosh", + Function::ArcSin => "arcsin", + Function::ArcCos => "arccos", + Function::ArcTan => "arctan", + Function::Tan => "tan", + Function::Cos => "cos", + Function::F => "f", + Function::Sec => "sec", + Function::Sinh => "sinh", + Function::Csch => "csch", + Function::Coth => "coth", + }; + format!("{}", inner) + } +} + +impl ToMathML for Logical { + fn to_mathml(&self) -> String { + let inner = match self { + Logical::And => "and", + Logical::Or => "or", + Logical::Not => "¬", + Logical::Implies => "⇒", + Logical::If => "if", + Logical::Iff => "⇔", + Logical::ForAll => "∀", + Logical::Exists => "exists;", + Logical::Bot => "⊥", + Logical::Top => "⊤", + Logical::VDash => "⊢", + Logical::Models => "⊨", + }; + format!("{}", inner) + } +} + +impl ToMathML for Arrow { + fn to_mathml(&self) -> String { + let inner = match self { + Arrow::UpArrow => "↑", + Arrow::DownArrow => "↓", + Arrow::RightArrow => "→", + Arrow::To => "→", + Arrow::RightArrowTail => "↣", + Arrow::TwoHeadRightArrow => "↠", + Arrow::TwoHeadRightArrowTail => "⤖", + Arrow::MapsTo => "↦", + Arrow::LeftArrow => "←", + Arrow::LeftRightArrow => "⟷", + Arrow::BigRightArrow => "⇨", + Arrow::BigLeftArrow => "⇦", + Arrow::BigLeftRightArrow => "⬄", + }; + format!("{}", inner) + } +} + +impl ToMathML for Misc { + fn to_mathml(&self) -> String { + let inner = match self { + Misc::Del => "∂", + Misc::Grad => "∇", + Misc::PlusMinus => "±", + Misc::EmptySet => "∅", + Misc::Infty => "∞", + Misc::Aleph => "ℵ", + Misc::Therefore => "∴", + Misc::Because => "∵", + Misc::PLDots => "|…|", + Misc::PCDots => "|···|", + Misc::VDots => "︙", + Misc::DDots => "⋱", + Misc::EPipes => "||", + Misc::EQuad => "| |", + Misc::Angle => "∠", + Misc::Frown => "⌢", + Misc::Triangle => "△", + Misc::Diamond => "⋄", + Misc::Square => "□", + Misc::LFloor => "⌊", + Misc::RFloor => "⌋", + Misc::LCeiling => "⌈", + Misc::RCeiling => "⌉", + Misc::Complex => "ℂ", + Misc::Natural => "ℕ", + Misc::Rational => "ℚ", + Misc::Real => "ℝ", + Misc::Integer => "ℤ", + _ => "", + }; + + format!("{}", inner) + } +}