Skip to content

AST Nodes

The Abstract Syntax Tree (AST) nodes are the building blocks of your Markdown document. The Node enum represents all possible elements in a CommonMark document.

Node Types

The Node enum includes various variants for different Markdown elements:

Block Elements

These elements form the structure of the document:

Node VariantDescriptionExample
DocumentRoot container for all contentThe entire Markdown document
HeadingSection heading (levels 1-6)# Heading
ParagraphText paragraphNormal text blocks
BlockQuoteQuoted content> Quoted text
CodeBlockBlock of code with optional language````rust`
ThematicBreakHorizontal rule---
OrderedListNumbered list1. Item
UnorderedListBullet list- Item
TableTabular dataA data table

Inline Elements

These elements appear within block elements:

Node VariantDescriptionExample
TextPlain text contentNormal text
EmphasisEmphasized text*italic*
StrongStrongly emphasized text**bold**
InlineCodeCode within text`code`
LinkHyperlink[text](url)
ImageImage reference![alt](src)
HardBreakHard line break\\ or two spaces
SoftBreakSoft line breakA simple newline
HtmlElementInline HTML<span>

GFM Extensions

When the gfm feature is enabled:

Node VariantDescriptionExample
StrikethroughCrossed-out text~~text~~
Table with alignmentsTable with column alignmentLeft/center/right aligned columns
Task list itemsCheckable items- [ ] or - [x]
ExtendedAutolinkAuto-detected linksURLs without angle brackets

Creating Nodes

You can create nodes in several ways:

Direct Enum Construction

rust
// Using enum variant directly
let heading = Node::Heading {
    level: 1,
    content: vec![Node::Text("Title".to_string())],
    heading_type: HeadingType::Atx,
};

Convenience Methods

rust
// Using convenience methods
let heading = Node::heading(1, vec![Node::Text("Title".to_string())]);

Building Complex Structures

Nodes can be nested to create complex documents:

rust
let document = Node::Document(vec![
    Node::heading(1, vec![Node::Text("Document Title".to_string())]),
    Node::Paragraph(vec![
        Node::Text("This is a paragraph with ".to_string()),
        Node::Strong(vec![Node::Text("bold".to_string())]),
        Node::Text(" and ".to_string()),
        Node::Emphasis(vec![Node::Text("italic".to_string())]),
        Node::Text(" text.".to_string()),
    ]),
    Node::UnorderedList(vec![
        ListItem::Unordered { 
            content: vec![Node::Paragraph(vec![Node::Text("Item 1".to_string())])] 
        },
        ListItem::Unordered { 
            content: vec![Node::Paragraph(vec![Node::Text("Item 2".to_string())])] 
        },
    ]),
]);

Working with List Items

List items have their own types to support different list styles:

rust
// Unordered list item
let unordered_item = ListItem::Unordered {
    content: vec![Node::Paragraph(vec![Node::Text("Bullet point".to_string())])],
};

// Ordered list item
let ordered_item = ListItem::Ordered {
    number: Some(1), // Optional explicit numbering
    content: vec![Node::Paragraph(vec![Node::Text("Numbered item".to_string())])],
};

// GFM task list item (with gfm feature)
#[cfg(feature = "gfm")]
let task_item = ListItem::Task {
    status: TaskListStatus::Unchecked,
    content: vec![Node::Paragraph(vec![Node::Text("Task to do".to_string())])],
};