Files
nuwiki/crates/nuwiki-core/src/ast/block.rs
T

195 lines
4.5 KiB
Rust
Raw Normal View History

2026-05-10 16:25:24 +00:00
//! Block-level AST nodes and their supporting types.
//!
//! See SPEC.md §6.4.
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:`. Phase 12 (v1.1). The placement
/// rule (file / heading / standalone) is captured in `TagScope` so
/// LSP handlers and renderers can treat the three differently.
Tag(TagNode),
2026-05-10 16:25:24 +00:00
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<InlineNode>,
pub centered: bool,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParagraphNode {
pub span: Span,
pub children: Vec<InlineNode>,
}
#[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<BlockNode>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PreformattedNode {
pub span: Span,
pub content: String,
pub language: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MathBlockNode {
pub span: Span,
pub content: String,
pub environment: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ListNode {
pub span: Span,
pub ordered: bool,
pub symbol: ListSymbol,
pub items: Vec<ListItemNode>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ListItemNode {
pub span: Span,
pub symbol: ListSymbol,
pub level: usize,
pub checkbox: Option<CheckboxState>,
pub children: Vec<InlineNode>,
pub sublist: Option<ListNode>,
}
#[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<DefinitionItemNode>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DefinitionItemNode {
pub span: Span,
pub term: Option<Vec<InlineNode>>,
pub definitions: Vec<Vec<InlineNode>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TableAlign {
Default,
Left,
Right,
Center,
}
impl Default for TableAlign {
fn default() -> Self {
Self::Default
}
}
2026-05-10 16:25:24 +00:00
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TableNode {
pub span: Span,
pub rows: Vec<TableRowNode>,
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<TableAlign>,
2026-05-10 16:25:24 +00:00
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TableRowNode {
pub span: Span,
pub cells: Vec<TableCellNode>,
pub is_header: bool,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TableCellNode {
pub span: Span,
pub children: Vec<InlineNode>,
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<String>,
pub scope: TagScope,
}
2026-05-10 16:25:24 +00:00
/// 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,
}