use super::prelude::*;
use cfg_if::cfg_if;
use std::num::NonZeroUsize;
cfg_if! {
if #[cfg(feature = "mathml")] {
use latex2mathml::{latex_to_mathml, DisplayStyle};
} else {
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum DisplayStyle {
Block,
Inline,
}
}
}
pub fn render_math_block(ctx: &mut HtmlContext, name: Option<&str>, latex_source: &str) {
debug!(
"Rendering math block (name '{}', source '{}')",
name.unwrap_or("<none>"),
latex_source,
);
let index = ctx.next_equation_index();
render_latex(ctx, name, Some(index), latex_source, DisplayStyle::Block);
}
pub fn render_math_inline(ctx: &mut HtmlContext, latex_source: &str) {
debug!("Rendering math inline (source '{latex_source}'");
render_latex(ctx, None, None, latex_source, DisplayStyle::Inline);
}
fn render_latex(
ctx: &mut HtmlContext,
name: Option<&str>,
index: Option<NonZeroUsize>,
latex_source: &str,
display: DisplayStyle,
) {
let (html_tag, wj_type, _error_type) = match display {
DisplayStyle::Block => ("div", "wj-math-block", "wj-error-block"),
DisplayStyle::Inline => ("span", "wj-math-inline", "wj-error-inline"),
};
ctx.html()
.tag(html_tag)
.attr(attr!(
"class" => "wj-math " wj_type,
"data-name" => name.unwrap_or(""); if name.is_some(),
))
.inner(|ctx| {
if let Some(index) = index {
ctx.html()
.span()
.attr(attr!("class" => "wj-equation-number"))
.inner(|ctx| {
ctx.html()
.span()
.attr(attr!(
"class" => "wj-equation-paren wj-equation-paren-open",
))
.contents("(");
str_write!(ctx, "{index}");
ctx.html()
.span()
.attr(attr!(
"class" => "wj-equation-paren wj-equation-paren-close",
))
.contents(")");
});
}
ctx.html()
.code()
.attr(attr!(
"class" => "wj-math-source wj-hidden",
"aria-hidden" => "true",
))
.contents(latex_source);
cfg_if! {
if #[cfg(feature = "mathml")] {
match latex_to_mathml(latex_source, display) {
Ok(mathml) => {
debug!("Processed LaTeX -> MathML");
ctx.html()
.element("wj-math-ml")
.attr(attr!("class" => "wj-math-ml"))
.inner(|ctx| ctx.push_raw_str(&mathml));
}
Err(error) => {
warn!("Error processing LaTeX -> MathML: {error}");
let error = str!(error);
ctx.html()
.span()
.attr(attr!("class" => _error_type))
.contents(error);
}
}
}
}
});
}
pub fn render_equation_reference(ctx: &mut HtmlContext, name: &str) {
debug!("Rendering equation reference (name '{name}')");
ctx.html()
.span()
.attr(attr!("class" => "wj-equation-ref"))
.inner(|ctx| {
ctx.html()
.element("wj-equation-ref-marker")
.attr(attr!(
"class" => "wj-equation-ref-marker",
"type" => "button",
"data-name" => name,
))
.contents(name);
ctx.html().span().attr(attr!(
"class" => "wj-equation-ref-tooltip",
"aria-hidden" => "true",
));
});
}