use comrak::nodes::{AstNode, NodeValue};
use crate::math::render_math;
pub fn transform_math<'a>(root: &'a AstNode<'a>) -> usize {
let mut count = 0;
transform(root, &mut count);
count
}
fn transform<'a>(node: &'a AstNode<'a>, count: &mut usize) {
let replacement = {
let data = node.data.borrow();
if let NodeValue::Math(m) = &data.value {
Some(render_math(&m.literal, m.display_math))
} else {
None
}
};
if let Some(html) = replacement {
node.data.borrow_mut().value = NodeValue::HtmlInline(html);
*count += 1;
}
for child in node.children() {
transform(child, count);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::markdown::{comrak_options, format_ast};
use comrak::{parse_document, Arena};
fn render(md: &str) -> String {
let arena = Arena::new();
let opts = comrak_options();
let root = parse_document(&arena, md, &opts);
let n = transform_math(root);
assert!(n >= 1, "expected at least one math node");
format_ast(root, &opts)
}
#[test]
fn inline_dollar_math_becomes_katex_html() {
let html = render("Euler: $e^{i\\pi}+1=0$ done\n");
assert!(html.contains("katex"));
assert!(!html.contains("$e^")); }
#[test]
fn display_math_becomes_katex_display() {
let html = render("$$\\sum_{i=1}^n i$$\n");
assert!(html.contains("katex-display"));
}
#[test]
fn no_math_leaves_document_untouched() {
let arena = Arena::new();
let opts = comrak_options();
let root = parse_document(&arena, "plain text only\n", &opts);
assert_eq!(transform_math(root), 0);
assert!(format_ast(root, &opts).contains("plain text only"));
}
}