Skip to main content

marco_core/parser/inlines/
math_display_parser.rs

1//! Math display parser - converts grammar output to DisplayMath AST node
2//!
3//! Parses display math delimited by `$$...$$` using KaTeX.
4
5use super::shared::{opt_span, GrammarSpan};
6use crate::grammar::inlines::display_math;
7use crate::parser::ast::{Node, NodeKind};
8use nom::IResult;
9
10/// Parse a display math expression `$$...$$` to a DisplayMath AST node.
11///
12/// # Example
13/// ```ignore
14/// let input = GrammarSpan::new("$$\\int x^2 dx$$ text");
15/// let (rest, node) = parse_display_math(input).unwrap();
16/// // node.kind == NodeKind::DisplayMath { content: "\\int x^2 dx" }
17/// ```
18pub fn parse_display_math(input: GrammarSpan) -> IResult<GrammarSpan, Node> {
19    let (rest, content_span) = display_math(input)?;
20
21    let node = Node {
22        kind: NodeKind::DisplayMath {
23            content: content_span.fragment().to_string(),
24        },
25        span: opt_span(content_span),
26        children: Vec::new(),
27    };
28
29    Ok((rest, node))
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn smoke_test_parse_display_math() {
38        let input = GrammarSpan::new("$$x^2 + y^2 = r^2$$ text");
39        let result = parse_display_math(input);
40        assert!(result.is_ok());
41
42        let (_, node) = result.unwrap();
43        match node.kind {
44            NodeKind::DisplayMath { content } => {
45                assert_eq!(content, "x^2 + y^2 = r^2");
46            }
47            _ => panic!("Expected DisplayMath node"),
48        }
49    }
50}