//! Block-level AST nodes and their supporting types. use super::inline::InlineNode; use super::span::Span; #[derive(Debug, Clone, PartialEq, Eq)] pub enum BlockNode { Heading(HeadingNode), Paragraph(ParagraphNode), HorizontalRule(HorizontalRuleNode), Blockquote(BlockquoteNode), Preformatted(PreformattedNode), MathBlock(MathBlockNode), List(ListNode), DefinitionList(DefinitionListNode), Table(TableNode), Comment(CommentNode), /// Vimwiki tag line — `:tag1:tag2:`. The placement /// rule (file / heading / standalone) is captured in `TagScope` so /// LSP handlers and renderers can treat the three differently. Tag(TagNode), Error(ErrorNode), } #[derive(Debug, Clone, PartialEq, Eq)] pub struct HeadingNode { pub span: Span, /// 1..=6 — invariant enforced by the parser, not the type. pub level: u8, pub children: Vec, pub centered: bool, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ParagraphNode { pub span: Span, pub children: Vec, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct HorizontalRuleNode { pub span: Span, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct BlockquoteNode { pub span: Span, pub children: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct PreformattedNode { pub span: Span, pub content: String, pub language: Option, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct MathBlockNode { pub span: Span, pub content: String, pub environment: Option, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListNode { pub span: Span, pub ordered: bool, pub symbol: ListSymbol, pub items: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListItemNode { pub span: Span, pub symbol: ListSymbol, pub level: usize, pub checkbox: Option, pub children: Vec, pub sublist: Option, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ListSymbol { Dash, Star, Hash, Numeric, NumericParen, AlphaParen, AlphaUpperParen, RomanParen, RomanUpperParen, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum CheckboxState { Empty, Quarter, Half, ThreeQuarters, Done, Rejected, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DefinitionListNode { pub span: Span, pub items: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DefinitionItemNode { pub span: Span, pub term: Option>, pub definitions: Vec>, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum TableAlign { Default, Left, Right, Center, } impl Default for TableAlign { fn default() -> Self { Self::Default } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct TableNode { pub span: Span, pub rows: Vec, pub has_header: bool, /// One entry per column, taken from a Markdown-style header /// separator row (`|:--|--:|:--:|`). Empty when no alignment was /// specified; cells past the end inherit `Default`. pub alignments: Vec, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct TableRowNode { pub span: Span, pub cells: Vec, pub is_header: bool, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct TableCellNode { pub span: Span, pub children: Vec, pub col_span: bool, pub row_span: bool, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct CommentNode { pub span: Span, pub content: String, } /// Where a `TagNode` falls on the page, matching vimwiki's placement rules. /// /// - `File` — line 0 or 1 of the document; tags the entire page. /// - `Heading(i)` — within two lines below the i-th `HeadingNode` in the /// document's `children`; tags that heading. /// - `Standalone` — anywhere else; the tag is its own anchor on the source /// line. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum TagScope { File, Heading(usize), Standalone, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct TagNode { pub span: Span, pub tags: Vec, pub scope: TagScope, } /// Resilient parse-failure node — emitted instead of aborting the document. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ErrorNode { pub span: Span, pub raw: String, pub message: String, }