Java library for parsing and rendering Markdown text according to the CommonMark specification
—
Comprehensive node hierarchy representing all CommonMark elements including blocks, inlines, and document structure. The AST (Abstract Syntax Tree) provides a structured representation of parsed Markdown documents with full support for tree traversal, manipulation, and the visitor pattern.
Core abstract classes that form the foundation of the AST hierarchy.
/**
* Base class for all CommonMark AST nodes
*/
public abstract class Node {
/**
* Accept a visitor (visitor pattern implementation)
* @param visitor the visitor to accept
*/
public abstract void accept(Visitor visitor);
/**
* Get the next sibling node
* @return the next sibling, or null if this is the last child
*/
public Node getNext();
/**
* Get the previous sibling node
* @return the previous sibling, or null if this is the first child
*/
public Node getPrevious();
/**
* Get the first child node
* @return the first child, or null if no children
*/
public Node getFirstChild();
/**
* Get the last child node
* @return the last child, or null if no children
*/
public Node getLastChild();
/**
* Get the parent node
* @return the parent node, or null if this is the root
*/
public Node getParent();
/**
* Append a child node to this node
* @param child the child node to append
*/
public void appendChild(Node child);
/**
* Prepend a child node to this node
* @param child the child node to prepend
*/
public void prependChild(Node child);
/**
* Remove this node from its parent
*/
public void unlink();
/**
* Insert this node after the specified sibling
* @param sibling the sibling to insert after
*/
public void insertAfter(Node sibling);
/**
* Insert this node before the specified sibling
* @param sibling the sibling to insert before
*/
public void insertBefore(Node sibling);
/**
* Get source spans for this node (available since 0.16.0)
* @return list of source spans, empty if not included by parser
*/
public List<SourceSpan> getSourceSpans();
/**
* Replace current source spans with provided list (available since 0.16.0)
* @param sourceSpans the new source spans to set
*/
public void setSourceSpans(List<SourceSpan> sourceSpans);
/**
* Add a source span to the end of the list (available since 0.16.0)
* @param sourceSpan the source span to add
*/
public void addSourceSpan(SourceSpan sourceSpan);
}
/**
* Base class for block-level nodes
*/
public abstract class Block extends Node {
/**
* Get the parent block (overridden for type safety)
* @return the parent block
*/
public Block getParent();
}Nodes representing the overall document structure and major organizational elements.
/**
* Root document node - the top level of any parsed document
*/
public class Document extends Block {
public void accept(Visitor visitor);
}
/**
* Heading nodes (# ## ### etc.)
*/
public class Heading extends Block {
/**
* Get the heading level (1-6)
* @return the heading level
*/
public int getLevel();
/**
* Set the heading level
* @param level the heading level (1-6)
*/
public void setLevel(int level);
public void accept(Visitor visitor);
}
/**
* Paragraph blocks
*/
public class Paragraph extends Block {
public void accept(Visitor visitor);
}
/**
* Block quotes (> text)
*/
public class BlockQuote extends Block {
public void accept(Visitor visitor);
}
/**
* Horizontal rules (---, ***, ___)
*/
public class ThematicBreak extends Block {
public void accept(Visitor visitor);
}Nodes representing different types of code blocks in Markdown.
/**
* Fenced code blocks (``` code ```)
*/
public class FencedCodeBlock extends Block {
/**
* Get the fence character (` or ~)
* @return the fence character
*/
public char getFenceChar();
/**
* Set the fence character
* @param fenceChar the fence character
*/
public void setFenceChar(char fenceChar);
/**
* Get the fence length (number of fence characters)
* @return the fence length
*/
public int getFenceLength();
/**
* Set the fence length
* @param fenceLength the fence length
*/
public void setFenceLength(int fenceLength);
/**
* Get the fence indentation
* @return the fence indentation
*/
public int getFenceIndent();
/**
* Set the fence indentation
* @param fenceIndent the fence indentation
*/
public void setFenceIndent(int fenceIndent);
/**
* Get the info string (language identifier)
* @return the info string, or null if not specified
*/
public String getInfo();
/**
* Set the info string
* @param info the info string
*/
public void setInfo(String info);
/**
* Get the literal code content
* @return the code content
*/
public String getLiteral();
/**
* Set the literal code content
* @param literal the code content
*/
public void setLiteral(String literal);
public void accept(Visitor visitor);
}
/**
* Indented code blocks (4+ spaces)
*/
public class IndentedCodeBlock extends Block {
/**
* Get the literal code content
* @return the code content
*/
public String getLiteral();
/**
* Set the literal code content
* @param literal the code content
*/
public void setLiteral(String literal);
public void accept(Visitor visitor);
}Nodes representing list structures and list items.
/**
* Base class for list blocks (ordered and unordered)
*/
public abstract class ListBlock extends Block {
// Base class for BulletList and OrderedList
}
/**
* Unordered lists (*, -, +)
*/
public class BulletList extends ListBlock {
/**
* Get the bullet marker character
* @return the bullet marker (*, -, or +)
*/
public char getBulletMarker();
/**
* Set the bullet marker character
* @param bulletMarker the bullet marker
*/
public void setBulletMarker(char bulletMarker);
public void accept(Visitor visitor);
}
/**
* Ordered lists (1. 2. 3.)
*/
public class OrderedList extends ListBlock {
/**
* Get the starting number
* @return the starting number
*/
public int getStartNumber();
/**
* Set the starting number
* @param startNumber the starting number
*/
public void setStartNumber(int startNumber);
/**
* Get the delimiter character (. or ))
* @return the delimiter character
*/
public char getDelimiter();
/**
* Set the delimiter character
* @param delimiter the delimiter character
*/
public void setDelimiter(char delimiter);
public void accept(Visitor visitor);
}
/**
* Individual list items
*/
public class ListItem extends Block {
public void accept(Visitor visitor);
}Nodes representing inline elements within blocks.
/**
* Plain text nodes
*/
public class Text extends Node {
/**
* Create an empty text node
*/
public Text();
/**
* Create a text node with the given literal content
* @param literal the text content
*/
public Text(String literal);
/**
* Get the literal text content
* @return the text content
*/
public String getLiteral();
/**
* Set the literal text content
* @param literal the text content
*/
public void setLiteral(String literal);
public void accept(Visitor visitor);
}
/**
* Inline code (`code`)
*/
public class Code extends Node {
/**
* Get the literal code content
* @return the code content
*/
public String getLiteral();
/**
* Set the literal code content
* @param literal the code content
*/
public void setLiteral(String literal);
public void accept(Visitor visitor);
}
/**
* Interface for nodes with delimiters (emphasis, strong emphasis)
*/
public interface Delimited {
/**
* Get the opening delimiter
* @return the opening delimiter string
*/
String getOpeningDelimiter();
/**
* Get the closing delimiter
* @return the closing delimiter string
*/
String getClosingDelimiter();
}
/**
* Italic text (*text* or _text_)
*/
public class Emphasis extends Node implements Delimited {
/**
* Create an empty emphasis node
*/
public Emphasis();
/**
* Create an emphasis node with the given delimiter
* @param delimiter the delimiter string (* or _)
*/
public Emphasis(String delimiter);
/**
* Get the opening delimiter
* @return the opening delimiter
*/
public String getOpeningDelimiter();
/**
* Get the closing delimiter
* @return the closing delimiter
*/
public String getClosingDelimiter();
/**
* Set the delimiter for both opening and closing
* @param delimiter the delimiter string
*/
public void setDelimiter(String delimiter);
public void accept(Visitor visitor);
}
/**
* Bold text (**text** or __text__)
*/
public class StrongEmphasis extends Node implements Delimited {
/**
* Create an empty strong emphasis node
*/
public StrongEmphasis();
/**
* Create a strong emphasis node with the given delimiter
* @param delimiter the delimiter string (** or __)
*/
public StrongEmphasis(String delimiter);
/**
* Get the opening delimiter
* @return the opening delimiter
*/
public String getOpeningDelimiter();
/**
* Get the closing delimiter
* @return the closing delimiter
*/
public String getClosingDelimiter();
/**
* Set the delimiter for both opening and closing
* @param delimiter the delimiter string
*/
public void setDelimiter(String delimiter);
public void accept(Visitor visitor);
}Nodes representing links and images with destinations and titles.
/**
* Links [text](url "title")
*/
public class Link extends Node {
/**
* Create an empty link
*/
public Link();
/**
* Create a link with destination and title
* @param destination the link destination
* @param title the link title (may be null)
*/
public Link(String destination, String title);
/**
* Get the link destination
* @return the destination URL
*/
public String getDestination();
/**
* Set the link destination
* @param destination the destination URL
*/
public void setDestination(String destination);
/**
* Get the link title
* @return the title, or null if not specified
*/
public String getTitle();
/**
* Set the link title
* @param title the title
*/
public void setTitle(String title);
public void accept(Visitor visitor);
}
/**
* Images 
*/
public class Image extends Node {
/**
* Create an empty image
*/
public Image();
/**
* Create an image with destination and title
* @param destination the image source
* @param title the image title (may be null)
*/
public Image(String destination, String title);
/**
* Get the image destination (src)
* @return the image source URL
*/
public String getDestination();
/**
* Set the image destination
* @param destination the image source URL
*/
public void setDestination(String destination);
/**
* Get the image title
* @return the title, or null if not specified
*/
public String getTitle();
/**
* Set the image title
* @param title the title
*/
public void setTitle(String title);
public void accept(Visitor visitor);
}
/**
* Link reference definitions [label]: url "title"
*/
public class LinkReferenceDefinition extends Node {
/**
* Get the reference label
* @return the label
*/
public String getLabel();
/**
* Set the reference label
* @param label the label
*/
public void setLabel(String label);
/**
* Get the destination URL
* @return the destination
*/
public String getDestination();
/**
* Set the destination URL
* @param destination the destination
*/
public void setDestination(String destination);
/**
* Get the title
* @return the title, or null if not specified
*/
public String getTitle();
/**
* Set the title
* @param title the title
*/
public void setTitle(String title);
public void accept(Visitor visitor);
}Nodes representing HTML content and line breaks.
/**
* HTML block elements
*/
public class HtmlBlock extends Block {
/**
* Get the literal HTML content
* @return the HTML content
*/
public String getLiteral();
/**
* Set the literal HTML content
* @param literal the HTML content
*/
public void setLiteral(String literal);
public void accept(Visitor visitor);
}
/**
* Inline HTML elements
*/
public class HtmlInline extends Node {
/**
* Get the literal HTML content
* @return the HTML content
*/
public String getLiteral();
/**
* Set the literal HTML content
* @param literal the HTML content
*/
public void setLiteral(String literal);
public void accept(Visitor visitor);
}
/**
* Soft line breaks (newlines in text)
*/
public class SoftLineBreak extends Node {
public void accept(Visitor visitor);
}
/**
* Hard line breaks ( \n or \)
*/
public class HardLineBreak extends Node {
public void accept(Visitor visitor);
}Interfaces and classes for traversing and processing AST nodes.
/**
* Visitor pattern interface for traversing AST nodes
*/
public interface Visitor {
void visit(Document document);
void visit(Heading heading);
void visit(Paragraph paragraph);
void visit(BlockQuote blockQuote);
void visit(BulletList bulletList);
void visit(OrderedList orderedList);
void visit(ListItem listItem);
void visit(FencedCodeBlock fencedCodeBlock);
void visit(IndentedCodeBlock indentedCodeBlock);
void visit(HtmlBlock htmlBlock);
void visit(ThematicBreak thematicBreak);
void visit(Text text);
void visit(Code code);
void visit(Emphasis emphasis);
void visit(StrongEmphasis strongEmphasis);
void visit(Link link);
void visit(Image image);
void visit(HtmlInline htmlInline);
void visit(SoftLineBreak softLineBreak);
void visit(HardLineBreak hardLineBreak);
void visit(LinkReferenceDefinition linkReferenceDefinition);
void visit(CustomBlock customBlock);
void visit(CustomNode customNode);
}
/**
* Abstract visitor that visits all children by default.
* Provides default implementations of all visit methods that call visitChildren.
* Override specific visit methods to customize behavior for particular node types.
*/
public abstract class AbstractVisitor implements Visitor {
/**
* Visit all children of the given parent node.
* This method is called by all default visit method implementations.
* Override specific visit methods and call visitChildren if you want to continue traversal.
*
* @param parent the parent node whose children to visit
*/
protected void visitChildren(Node parent);
// Default implementations for all visit methods in Visitor interface:
// public void visit(Document document) { visitChildren(document); }
// public void visit(Heading heading) { visitChildren(heading); }
// ... and so on for all node types
}Base classes for creating custom node types in extensions.
/**
* Base class for custom inline nodes
*/
public abstract class CustomNode extends Node {
// Base class for creating custom inline node types
}
/**
* Base class for custom block nodes
*/
public abstract class CustomBlock extends Block {
// Base class for creating custom block node types
}Helper classes for working with nodes and collections of nodes.
/**
* Utility class for working with multiple nodes
*/
public class Nodes {
/**
* Get all nodes between start and end (exclusive)
* @param start the starting node
* @param end the ending node
* @return iterable of nodes between start and end
*/
public static Iterable<Node> between(Node start, Node end);
}Usage Examples:
import org.commonmark.node.*;
import org.commonmark.parser.Parser;
// Parse and traverse AST
Parser parser = Parser.builder().build();
Node document = parser.parse("# Title\n\nHello **world**!");
// Using visitor pattern
document.accept(new AbstractVisitor() {
@Override
public void visit(Heading heading) {
System.out.println("Found heading level " + heading.getLevel());
super.visit(heading);
}
@Override
public void visit(StrongEmphasis strongEmphasis) {
System.out.println("Found bold text");
super.visit(strongEmphasis);
}
});
// Manual tree traversal
Node child = document.getFirstChild();
while (child != null) {
System.out.println("Child node: " + child.getClass().getSimpleName());
child = child.getNext();
}
// Modify AST - add a new paragraph
Paragraph newParagraph = new Paragraph();
Text text = new Text("This is a new paragraph.");
newParagraph.appendChild(text);
document.appendChild(newParagraph);
// Create links programmatically
Link link = new Link("https://example.com", "Example Site");
link.appendChild(new Text("Visit our site"));Install with Tessl CLI
npx tessl i tessl/maven-org-commonmark--commonmark