cmark_writer/
ast.rs

1//! Abstract Syntax Tree for CommonMark document structure.
2//!
3//! This module defines various node types for representing CommonMark documents,
4//! including headings, paragraphs, lists, code blocks, etc.
5
6/// Main node type, representing an element in a CommonMark document
7#[derive(Debug, Clone, PartialEq)]
8pub enum Node {
9    /// Block-level node
10    Block(BlockNode),
11    /// Inline node
12    Inline(InlineNode),
13}
14
15/// Block-level node type, representing content blocks that can exist independently
16#[derive(Debug, Clone, PartialEq)]
17pub enum BlockNode {
18    /// Root document node, contains child block nodes
19    Document(Vec<BlockNode>),
20
21    /// Heading, contains level (1-6) and inline content
22    Heading {
23        /// Heading level, 1-6
24        level: u8,
25        /// Heading content, containing inline elements
26        content: Vec<InlineNode>,
27    },
28
29    /// Paragraph node, containing inline elements
30    Paragraph(Vec<InlineNode>),
31
32    /// Block quote, containing any block-level elements
33    BlockQuote(Vec<BlockNode>),
34
35    /// Code block, containing optional language identifier and content
36    CodeBlock {
37        /// Optional language identifier
38        language: Option<String>,
39        /// Code content
40        content: String,
41    },
42
43    /// Unordered list, containing list items
44    UnorderedList(Vec<ListItem>),
45
46    /// Ordered list, containing starting number and list items
47    OrderedList {
48        /// List starting number
49        start: u32,
50        /// List items
51        items: Vec<ListItem>,
52    },
53
54    /// Thematic break (horizontal rule)
55    ThematicBreak,
56
57    /// Table
58    Table {
59        /// Header cells
60        headers: Vec<InlineNode>,
61        /// Table rows, each row containing multiple cells
62        rows: Vec<Vec<InlineNode>>,
63        /// Column alignments
64        alignments: Vec<Alignment>,
65    },
66
67    /// HTML block
68    HtmlBlock(String),
69}
70
71/// Inline node type, representing inline elements used within block-level elements
72#[derive(Debug, Clone, PartialEq)]
73pub enum InlineNode {
74    /// Plain text
75    Text(String),
76
77    /// Emphasis (italic)
78    Emphasis(Vec<InlineNode>),
79
80    /// Strong emphasis (bold)
81    Strong(Vec<InlineNode>),
82
83    /// Strikethrough
84    Strike(Vec<InlineNode>),
85
86    /// Inline code
87    InlineCode(String),
88
89    /// Link
90    Link {
91        /// Link URL
92        url: String,
93        /// Optional link title
94        title: Option<String>,
95        /// Link text
96        content: Vec<InlineNode>,
97    },
98
99    /// Image
100    Image {
101        /// Image URL
102        url: String,
103        /// Optional image title
104        title: Option<String>,
105        /// Alternative text
106        alt: String,
107    },
108
109    /// Inline element collection, without formatting and line breaks
110    InlineContainer(Vec<InlineNode>),
111
112    /// HTML inline element
113    HtmlElement(HtmlElement),
114
115    /// Soft break (single line break)
116    SoftBreak,
117
118    /// Hard break (two spaces followed by a line break, or backslash followed by a line break)
119    HardBreak,
120}
121
122/// List item type
123#[derive(Debug, Clone, PartialEq)]
124pub enum ListItem {
125    /// Regular list item
126    Regular {
127        /// List item content, containing one or more block-level elements
128        content: Vec<BlockNode>,
129    },
130    /// Task list item
131    Task {
132        /// Whether the task is completed
133        completed: bool,
134        /// Task content
135        content: Vec<BlockNode>,
136    },
137}
138
139/// Table column alignment
140#[derive(Debug, Clone, Copy, PartialEq)]
141pub enum Alignment {
142    /// No specific alignment
143    None,
144    /// Left alignment
145    Left,
146    /// Center alignment
147    Center,
148    /// Right alignment
149    Right,
150}
151
152/// Represents an HTML attribute, containing name and value
153#[derive(Debug, Clone, PartialEq)]
154pub struct HtmlAttribute {
155    /// Attribute name
156    pub name: String,
157    /// Attribute value
158    pub value: String,
159}
160
161/// Represents an HTML element, containing tag name, attributes, and child nodes
162#[derive(Debug, Clone, PartialEq)]
163pub struct HtmlElement {
164    /// Element tag name
165    pub tag: String,
166    /// Element attributes
167    pub attributes: Vec<HtmlAttribute>,
168    /// Element child nodes (can only contain inline nodes)
169    pub children: Vec<InlineNode>,
170    /// Whether it's a self-closing tag (e.g. <img />)
171    pub self_closing: bool,
172}
173
174// Provides backward compatibility conversion functions and trait implementations
175impl BlockNode {
176    /// Converts a BlockNode to Node
177    pub fn into_node(self) -> Node {
178        Node::Block(self)
179    }
180}
181
182impl InlineNode {
183    /// Converts an InlineNode to Node
184    pub fn into_node(self) -> Node {
185        Node::Inline(self)
186    }
187}