1use comrak::nodes::{AstNode, NodeValue};
11
12use crate::math::render_math;
13
14pub fn transform_math<'a>(root: &'a AstNode<'a>) -> usize {
19 let mut count = 0;
20 transform(root, &mut count);
21 count
22}
23
24fn transform<'a>(node: &'a AstNode<'a>, count: &mut usize) {
25 let replacement = {
27 let data = node.data.borrow();
28 if let NodeValue::Math(m) = &data.value {
29 Some(render_math(&m.literal, m.display_math))
30 } else {
31 None
32 }
33 };
34 if let Some(html) = replacement {
35 node.data.borrow_mut().value = NodeValue::HtmlInline(html);
36 *count += 1;
37 }
38 for child in node.children() {
39 transform(child, count);
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46 use crate::markdown::{comrak_options, format_ast};
47 use comrak::{parse_document, Arena};
48
49 fn render(md: &str) -> String {
50 let arena = Arena::new();
51 let opts = comrak_options();
52 let root = parse_document(&arena, md, &opts);
53 let n = transform_math(root);
54 assert!(n >= 1, "expected at least one math node");
55 format_ast(root, &opts)
56 }
57
58 #[test]
59 fn inline_dollar_math_becomes_katex_html() {
60 let html = render("Euler: $e^{i\\pi}+1=0$ done\n");
61 assert!(html.contains("katex"));
62 assert!(!html.contains("$e^")); }
64
65 #[test]
66 fn display_math_becomes_katex_display() {
67 let html = render("$$\\sum_{i=1}^n i$$\n");
68 assert!(html.contains("katex-display"));
69 }
70
71 #[test]
72 fn no_math_leaves_document_untouched() {
73 let arena = Arena::new();
74 let opts = comrak_options();
75 let root = parse_document(&arena, "plain text only\n", &opts);
76 assert_eq!(transform_math(root), 0);
77 assert!(format_ast(root, &opts).contains("plain text only"));
78 }
79}