CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-commonmark--commonmark

Java library for parsing and rendering Markdown text according to the CommonMark specification

Pending
Overview
Eval results
Files

core-parsing.mddocs/

Core Parsing

Complete Markdown parsing functionality that converts text input into a structured Abstract Syntax Tree (AST). The parser supports all CommonMark specification features with extensive configuration options for customization and extensibility.

Capabilities

Parser

Main parsing class that converts CommonMark text to AST nodes.

/**
 * Parses input text to a tree of nodes.
 * Thread-safe parser that can be reused across multiple parsing operations.
 */
public class Parser {
    /**
     * Create a new builder for configuring a Parser
     * @return a builder instance
     */
    public static Builder builder();
    
    /**
     * Parse the specified input text into a tree of nodes.
     * This method is thread-safe (a new parser state is used for each invocation).
     * @param input the text to parse - must not be null
     * @return the root node (Document)
     */
    public Node parse(String input);
    
    /**
     * Parse the specified reader into a tree of nodes. The caller is responsible for closing the reader.
     * This method is thread-safe (a new parser state is used for each invocation).
     * @param input the reader to parse - must not be null
     * @return the root node (Document)  
     * @throws IOException when reading throws an exception
     */
    public Node parseReader(Reader input) throws IOException;
}

Usage Examples:

import org.commonmark.parser.Parser;
import org.commonmark.node.Node;

// Basic parsing
Parser parser = Parser.builder().build();
Node document = parser.parse("# Hello World\n\nThis is **bold** text.");

// Parse from file
try (FileReader reader = new FileReader("document.md")) {
    Node document = parser.parseReader(reader);
}

// Parse with custom configuration
Parser customParser = Parser.builder()
    .includeSourceSpans(IncludeSourceSpans.BLOCKS)
    .build();
Node documentWithSpans = customParser.parse("# Heading");

Parser Builder

Builder class for configuring Parser instances with custom options and extensions.

/**
 * Builder for configuring a Parser
 */
public static class Parser.Builder {
    /**
     * Build the configured Parser instance
     * @return the configured Parser
     */
    public Parser build();
    
    /**
     * Add extensions to use on this parser
     * @param extensions extensions to use on this parser
     * @return this builder
     */
    public Builder extensions(Iterable<? extends Extension> extensions);
    
    /**
     * Describe the list of markdown features the parser will recognize and parse.
     * By default, all CommonMark block types are enabled.
     * @param enabledBlockTypes A set of block nodes the parser will parse
     * @return this builder
     */
    public Builder enabledBlockTypes(Set<Class<? extends Block>> enabledBlockTypes);
    
    /**
     * Whether to calculate source spans for nodes
     * @param includeSourceSpans which kind of source spans should be included
     * @return this builder
     */
    public Builder includeSourceSpans(IncludeSourceSpans includeSourceSpans);
    
    /**
     * Add a custom block parser factory
     * @param blockParserFactory a block parser factory implementation
     * @return this builder
     */
    public Builder customBlockParserFactory(BlockParserFactory blockParserFactory);
    
    /**
     * Add a custom delimiter processor
     * @param delimiterProcessor a delimiter processor implementation  
     * @return this builder
     */
    public Builder customDelimiterProcessor(DelimiterProcessor delimiterProcessor);
    
    /**
     * Add a post processor that runs after parsing
     * @param postProcessor a post processor implementation
     * @return this builder
     */
    public Builder postProcessor(PostProcessor postProcessor);
    
    /**
     * Override the parser used for inline markdown processing
     * @param inlineParserFactory an inline parser factory implementation
     * @return this builder
     */
    public Builder inlineParserFactory(InlineParserFactory inlineParserFactory);
}

Usage Examples:

import org.commonmark.parser.Parser;
import org.commonmark.parser.IncludeSourceSpans;
import org.commonmark.node.*;

// Enable only specific block types
Set<Class<? extends Block>> enabledTypes = new HashSet<>(Arrays.asList(
    Heading.class, 
    Paragraph.class, 
    ListBlock.class
));
Parser restrictedParser = Parser.builder()
    .enabledBlockTypes(enabledTypes)
    .build();

// Include source span information
Parser spanParser = Parser.builder()
    .includeSourceSpans(IncludeSourceSpans.BLOCKS_AND_INLINES)
    .build();
Node document = spanParser.parse("# Title");
List<SourceSpan> spans = document.getSourceSpans();

// Add custom post-processor
Parser processedParser = Parser.builder()
    .postProcessor(new MyCustomPostProcessor())
    .build();

Parser Configuration

Configuration enums and interfaces for customizing parser behavior.

/**
 * Configuration for including source span information
 */
public enum IncludeSourceSpans {
    /** Do not include source spans */
    NONE,
    /** Include source spans on block nodes */
    BLOCKS,
    /** Include source spans on all nodes */
    BLOCKS_AND_INLINES
}

/**
 * Post-processes nodes after parsing
 */
public interface PostProcessor {
    /**
     * Process the document node after parsing is complete
     * @param node the document node to process
     * @return the processed node (may be the same or a new node)
     */
    Node process(Node node);
}

/**
 * Factory for creating inline parsers
 */
public interface InlineParserFactory {
    /**
     * Create an inline parser with the given context
     * @param inlineParserContext the context for inline parsing
     * @return an inline parser instance
     */
    InlineParser create(InlineParserContext inlineParserContext);
}

/**
 * Parser factory for a block node for determining when a block starts.
 * Implementations should subclass AbstractBlockParserFactory instead of implementing this directly.
 */
public interface BlockParserFactory {
    /**
     * Try to start parsing a block at the current position
     * @param state the current parser state
     * @param matchedBlockParser the matched block parser
     * @return a BlockStart if this factory can start a block, null otherwise
     */
    BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser);
}

/**
 * Custom delimiter processor for additional delimiters besides underscore and asterisk.
 * Implementations must be thread-safe as the same instance may be used by multiple parsers.
 */
public interface DelimiterProcessor {
    /**
     * Get the character that marks the beginning of a delimited node
     * @return the opening character, must not clash with built-in special characters
     */
    char getOpeningCharacter();
    
    /**
     * Get the character that marks the ending of a delimited node
     * @return the closing character, must not clash with built-in special characters
     */
    char getClosingCharacter();
    
    /**
     * Minimum number of delimiter characters needed to activate this processor
     * @return the minimum length, must be at least 1
     */
    int getMinLength();
    
    /**
     * Process the delimiter runs
     * @param openingRun the opening delimiter run
     * @param closingRun the closing delimiter run
     * @return how many delimiters were used; must not be greater than length of either opener or closer
     */
    int process(DelimiterRun openingRun, DelimiterRun closingRun);
}

Source Management

Classes for handling source input and tracking source positions.

/**
 * Represents a line from source input
 */
public class SourceLine {
    /**
     * Get the content of this source line
     * @return the line content
     */
    public CharSequence getContent();
    
    /**
     * Get the line number (0-based)
     * @return the line number
     */
    public int getLineIndex();
}

/**
 * Set of source lines
 */
public class SourceLines {
    /**
     * Create an empty SourceLines
     * @return empty SourceLines instance
     */
    public static SourceLines empty();
    
    /**
     * Create SourceLines from a single line
     * @param sourceLine the source line
     * @return SourceLines containing the single line
     */
    public static SourceLines of(SourceLine sourceLine);
    
    /**
     * Add a line to this SourceLines
     * @param sourceLine the line to add
     */
    public void addLine(SourceLine sourceLine);
    
    /**
     * Get all lines
     * @return list of source lines
     */
    public List<SourceLine> getLines();
    
    /**
     * Check if this SourceLines is empty
     * @return true if empty
     */
    public boolean isEmpty();
    
    /**
     * Get the combined content of all lines
     * @return the content as a string
     */
    public String getContent();
}

/**
 * References a snippet of text from source input
 */
public class SourceSpan {
    /**
     * Create a source span
     * @param lineIndex the line index (0-based)
     * @param columnIndex the column index (0-based)
     * @param length the length of the span
     * @return the source span
     */
    public static SourceSpan of(int lineIndex, int columnIndex, int length);
    
    /**
     * Get the line index
     * @return the line index (0-based)
     */
    public int getLineIndex();
    
    /**
     * Get the column index
     * @return the column index (0-based)
     */
    public int getColumnIndex();
    
    /**
     * Get the length of the span
     * @return the length
     */
    public int getLength();
}

Usage Examples:

import org.commonmark.parser.SourceLine;
import org.commonmark.parser.SourceLines;
import org.commonmark.node.SourceSpan;

// Working with source spans
Parser parser = Parser.builder()
    .includeSourceSpans(IncludeSourceSpans.BLOCKS_AND_INLINES)
    .build();

Node document = parser.parse("# Heading\n\nParagraph with *emphasis*");
List<SourceSpan> documentSpans = document.getSourceSpans();

// Find all heading nodes and their source positions
document.accept(new AbstractVisitor() {
    @Override
    public void visit(Heading heading) {
        List<SourceSpan> spans = heading.getSourceSpans();
        for (SourceSpan span : spans) {
            System.out.println("Heading at line " + span.getLineIndex() + 
                             ", column " + span.getColumnIndex());
        }
        super.visit(heading);
    }
});

Install with Tessl CLI

npx tessl i tessl/maven-org-commonmark--commonmark

docs

ast-nodes.md

core-parsing.md

extensions.md

html-rendering.md

index.md

text-rendering.md

tile.json