Skip to main content

marco_core/parser/inlines/
math_inline_parser.rs

1//! Math inline parser - converts grammar output to InlineMath AST node
2//!
3//! Parses inline math delimited by `$...$` using KaTeX.
4
5use super::shared::{opt_span, GrammarSpan};
6use crate::grammar::inlines::inline_math;
7use crate::parser::ast::{Node, NodeKind};
8use nom::IResult;
9
10/// Parse an inline math expression `$...$` to an InlineMath AST node.
11///
12/// # Example
13/// ```ignore
14/// let input = GrammarSpan::new("$E = mc^2$ text");
15/// let (rest, node) = parse_inline_math(input).unwrap();
16/// // node.kind == NodeKind::InlineMath { content: "E = mc^2" }
17/// ```
18pub fn parse_inline_math(input: GrammarSpan) -> IResult<GrammarSpan, Node> {
19    let (rest, content_span) = inline_math(input)?;
20
21    let node = Node {
22        kind: NodeKind::InlineMath {
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_inline_math() {
38        let input = GrammarSpan::new("$E = mc^2$ text");
39        let result = parse_inline_math(input);
40        assert!(result.is_ok());
41
42        let (_, node) = result.unwrap();
43        match node.kind {
44            NodeKind::InlineMath { content } => {
45                assert_eq!(content, "E = mc^2");
46            }
47            _ => panic!("Expected InlineMath node"),
48        }
49    }
50}