use super::*;
impl MathElement for MathOperator {
fn tag_name(&self) -> &'static str {
"mo"
}
fn get_attributes(&self) -> &BTreeMap<String, String> {
&self.attributes
}
fn mut_attributes(&mut self) -> &mut BTreeMap<String, String> {
&mut self.attributes
}
}
impl MathOperator {
pub fn new<S>(text: S) -> Self
where
S: ToString,
{
Self { operator: text.to_string(), attributes: Default::default() }
}
pub fn mark_fence(self) -> Self {
self.with_attribute("fence", true)
}
pub fn mark_separator(self) -> Self {
self.with_attribute("separator", true)
}
pub fn mark_large_operator(self) -> Self {
self.with_attribute("largeop", true)
}
pub fn mark_stretchy(self) -> Self {
self.with_attribute("stretchy", true)
}
pub fn mark_symmetric(self) -> Self {
self.mark_stretchy().with_attribute("symmetric", true)
}
pub fn with_space(self, lhs: f32, rhs: f32) -> Self {
self.with_attribute("lspace", lhs).with_attribute("rspace", rhs)
}
pub fn with_size(self, min: f32, max: f32) -> Self {
self.mark_stretchy().with_attribute("minsize", min).with_attribute("maxsize", max)
}
}
impl Default for MathSpace {
fn default() -> Self {
MathSpace::new(1.0)
}
}
impl MathElement for MathSpace {
fn tag_name(&self) -> &'static str {
"mspace"
}
fn get_attributes(&self) -> &BTreeMap<String, String> {
&self.attributes
}
fn mut_attributes(&mut self) -> &mut BTreeMap<String, String> {
&mut self.attributes
}
}
impl MathSpace {
pub fn new(width: f32) -> Self {
let mut attributes = BTreeMap::new();
attributes.insert("width".to_string(), format!("{}rem", width));
Self { attributes }
}
}
impl MathElement for MathSqrt {
fn tag_name(&self) -> &'static str {
if self.surd.is_none() { "msqrt" } else { "mroot" }
}
fn get_attributes(&self) -> &BTreeMap<String, String> {
todo!()
}
fn mut_attributes(&mut self) -> &mut BTreeMap<String, String> {
todo!()
}
}
impl MathSqrt {
pub fn sqrt(base: MathML) -> Self {
Self { base, surd: None }
}
pub fn surd(base: MathML, power: MathML) -> Self {
Self { base, surd: Some(power) }
}
}
impl MathElement for MathMultiScript {
fn tag_name(&self) -> &'static str {
if self.is_sub_super_script() {
"msubsup"
}
else if self.is_sub_script() {
"msub"
}
else if self.is_super_script() {
"msup"
}
else {
"mmultiscripts"
}
}
fn get_attributes(&self) -> &BTreeMap<String, String> {
&self.attributes
}
fn mut_attributes(&mut self) -> &mut BTreeMap<String, String> {
&mut self.attributes
}
}
impl MathMultiScript {
pub fn new(base: MathML, lu: Vec<MathML>, ld: Vec<MathML>, ru: Vec<MathML>, rd: Vec<MathML>) -> Self {
Self { base, ru, rd, lu, ld, attributes: BTreeMap::new() }
}
pub fn sub_script(base: MathML, sub: MathML) -> Self {
MathMultiScript::new(base, vec![], vec![], vec![], vec![sub])
}
pub fn is_sub_script(&self) -> bool {
self.lu.is_empty() && self.ld.is_empty() && self.ru.is_empty() && self.rd.len() == 1
}
pub fn super_script(base: MathML, sup: MathML) -> Self {
MathMultiScript::new(base, vec![], vec![], vec![sup], vec![])
}
pub fn is_super_script(&self) -> bool {
self.lu.is_empty() && self.ld.is_empty() && self.ru.len() == 1 && self.rd.is_empty()
}
pub fn sub_super_script(base: MathML, sub: MathML, sup: MathML) -> Self {
MathMultiScript::new(base, vec![], vec![], vec![sup], vec![sub])
}
pub fn is_sub_super_script(&self) -> bool {
self.lu.is_empty() && self.ld.is_empty() && self.ru.len() == 1 && self.rd.len() == 1
}
}
impl MathFenced {
pub fn new<I>(base: I, lhs: char, rhs: char) -> Self
where
I: IntoIterator<Item = MathML>,
{
Self { base: base.into_iter().collect(), open: lhs, close: rhs, separators: String::new() }
}
pub fn parentheses<I>(base: I) -> Self
where
I: IntoIterator<Item = MathML>,
{
Self::new(base, '(', ')')
}
pub fn brackets<I>(base: I) -> Self
where
I: IntoIterator<Item = MathML>,
{
Self::new(base, '[', ']')
}
pub fn curly<I>(base: I) -> Self
where
I: IntoIterator<Item = MathML>,
{
Self::new(base, '{', '}')
}
pub fn with_separators<S>(mut self, separators: S) -> Self
where
S: ToString,
{
self.separators = separators.to_string();
self
}
}
impl MathElement for MathUnderOver {
fn tag_name(&self) -> &'static str {
match (&self.under, &self.over) {
(Some(_), Some(_)) => "munderover",
(Some(_), None) => "munder",
(None, Some(_)) => "mover",
(None, None) => unreachable!("MathUnderOver must have at least one of under or over"),
}
}
fn get_attributes(&self) -> &BTreeMap<String, String> {
&self.attributes
}
fn mut_attributes(&mut self) -> &mut BTreeMap<String, String> {
&mut self.attributes
}
}
impl MathUnderOver {
pub fn under(base: MathML, under: MathML) -> Self {
Self { base, under: Some(under), over: None, attributes: BTreeMap::new() }
}
pub fn over(base: MathML, over: MathML) -> Self {
Self { base, under: None, over: Some(over), attributes: BTreeMap::new() }
}
pub fn under_over(base: MathML, under: MathML, over: MathML) -> Self {
Self { base, under: Some(under), over: Some(over), attributes: BTreeMap::new() }
}
pub fn with_accent_over(self) -> Self {
self.with_attribute("accent", true)
}
pub fn with_accent_under(self) -> Self {
self.with_attribute("accentunder", true)
}
}
impl MathML {
pub fn operation<S>(text: S) -> Self
where
S: ToString,
{
MathOperator::new(text).into()
}
}