Skip to main content

marco_core/intelligence/markdown/
ast.rs

1//! Canonical markdown AST re-exports for intelligence subsystems.
2
3pub use crate::parser::{Document, Node, NodeKind, Position, Span};
4
5/// Alias types used by the intelligence boundary.
6pub type MarkdownDocument = Document;
7/// Alias for a Markdown AST node used by intelligence helpers.
8pub type MarkdownNode = Node;
9/// Alias for Markdown AST node kinds used by intelligence helpers.
10pub type MarkdownNodeKind = NodeKind;
11
12/// Return this node's span if available.
13pub fn node_span(node: &Node) -> Option<Span> {
14    node.span
15}
16
17/// True when the node kind is considered block-level.
18pub fn is_block_kind(kind: &NodeKind) -> bool {
19    matches!(
20        kind,
21        NodeKind::Heading { .. }
22            | NodeKind::Paragraph
23            | NodeKind::CodeBlock { .. }
24            | NodeKind::ThematicBreak
25            | NodeKind::List { .. }
26            | NodeKind::ListItem
27            | NodeKind::DefinitionList
28            | NodeKind::DefinitionTerm
29            | NodeKind::DefinitionDescription
30            | NodeKind::TaskCheckbox { .. }
31            | NodeKind::Blockquote
32            | NodeKind::Admonition { .. }
33            | NodeKind::TabGroup
34            | NodeKind::TabItem { .. }
35            | NodeKind::SliderDeck { .. }
36            | NodeKind::Slide { .. }
37            | NodeKind::Table { .. }
38            | NodeKind::TableRow { .. }
39            | NodeKind::TableCell { .. }
40            | NodeKind::HtmlBlock { .. }
41            | NodeKind::FootnoteDefinition { .. }
42            | NodeKind::MermaidDiagram { .. }
43    )
44}
45
46/// True when the node kind is considered inline-level.
47pub fn is_inline_kind(kind: &NodeKind) -> bool {
48    matches!(
49        kind,
50        NodeKind::Text(_)
51            | NodeKind::TaskCheckboxInline { .. }
52            | NodeKind::Emphasis
53            | NodeKind::Strong
54            | NodeKind::StrongEmphasis
55            | NodeKind::Strikethrough
56            | NodeKind::Mark
57            | NodeKind::Superscript
58            | NodeKind::Subscript
59            | NodeKind::Link { .. }
60            | NodeKind::LinkReference { .. }
61            | NodeKind::FootnoteReference { .. }
62            | NodeKind::Image { .. }
63            | NodeKind::CodeSpan(_)
64            | NodeKind::InlineHtml(_)
65            | NodeKind::HardBreak
66            | NodeKind::SoftBreak
67            | NodeKind::PlatformMention { .. }
68            | NodeKind::InlineMath { .. }
69            | NodeKind::DisplayMath { .. }
70    )
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn smoke_test_block_and_inline_classification() {
79        assert!(is_block_kind(&NodeKind::Paragraph));
80        assert!(is_block_kind(&NodeKind::CodeBlock {
81            language: None,
82            code: "x".to_string()
83        }));
84        assert!(!is_block_kind(&NodeKind::Text("x".to_string())));
85
86        assert!(is_inline_kind(&NodeKind::Text("x".to_string())));
87        assert!(is_inline_kind(&NodeKind::Link {
88            url: "https://example.com".to_string(),
89            title: None
90        }));
91        assert!(!is_inline_kind(&NodeKind::Paragraph));
92    }
93}