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}