//! 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, /// Verbatim text after the opening `{{{`, trailing whitespace trimmed /// (e.g. `python` or `class="brush: python"`). vimwiki inserts this as /// raw attributes on the `
` tag, so we preserve it for byte-parity.
    pub attrs: String,
}

#[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,
}