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

text-rendering.mddocs/

Text Content Rendering

Plain text rendering system for converting CommonMark documents back to text format with optional newline stripping and custom formatting. The text renderer extracts textual content from AST nodes while preserving document structure and readability.

Capabilities

Text Content Renderer

Main rendering class that converts AST nodes to plain text output.

/**
 * Renders a tree of nodes to plain text.
 * Thread-safe renderer that can be reused across multiple rendering operations.
 */
public class TextContentRenderer implements Renderer {
    /**
     * Create a new builder for configuring a TextContentRenderer
     * @return a builder instance
     */
    public static Builder builder();
    
    /**
     * Render the node to text and return as string
     * @param node the node to render - must not be null
     * @return the rendered text as a string
     */
    public String render(Node node);
    
    /**
     * Render the node to text and append to the given output
     * @param node the node to render - must not be null
     * @param output the appendable to write text to
     */
    public void render(Node node, Appendable output);
}

Usage Examples:

import org.commonmark.parser.Parser;
import org.commonmark.renderer.text.TextContentRenderer;
import org.commonmark.node.Node;

// Basic text rendering
Parser parser = Parser.builder().build();
TextContentRenderer renderer = TextContentRenderer.builder().build();

Node document = parser.parse("# Hello\n\nThis is **bold** text with a [link](url).");
String text = renderer.render(document);
// Result: "Hello\n\nThis is bold text with a link."

// Render to StringBuilder
StringBuilder sb = new StringBuilder();
renderer.render(document, sb);

// Render to file
try (FileWriter writer = new FileWriter("output.txt")) {
    renderer.render(document, writer);
}

Text Content Renderer Builder

Builder class for configuring text renderer instances with custom options and extensions.

/**
 * Builder for configuring a TextContentRenderer
 */
public static class TextContentRenderer.Builder {
    /**
     * Build the configured TextContentRenderer instance
     * @return the configured TextContentRenderer
     */
    public TextContentRenderer build();
    
    /**
     * Whether to strip newlines and render everything on one line, defaults to false
     * @param stripNewlines true to strip newlines, false to preserve line structure
     * @return this builder
     */
    public Builder stripNewlines(boolean stripNewlines);
    
    /**
     * Add a factory for instantiating a node renderer (done when rendering)
     * @param nodeRendererFactory the factory for creating a node renderer
     * @return this builder
     */
    public Builder nodeRendererFactory(TextContentNodeRendererFactory nodeRendererFactory);
    
    /**
     * Add extensions to use on this text renderer
     * @param extensions extensions to use on this text renderer
     * @return this builder
     */
    public Builder extensions(Iterable<? extends Extension> extensions);
}

Usage Examples:

import org.commonmark.renderer.text.TextContentRenderer;

// Strip newlines for single-line output
TextContentRenderer singleLineRenderer = TextContentRenderer.builder()
    .stripNewlines(true)
    .build();

Node document = parser.parse("# Title\n\nParagraph one.\n\nParagraph two.");
String singleLine = singleLineRenderer.render(document);
// Result: "Title Paragraph one. Paragraph two."

// Preserve line structure (default)
TextContentRenderer structuredRenderer = TextContentRenderer.builder()
    .stripNewlines(false)
    .build();

String structured = structuredRenderer.render(document);
// Result: "Title\n\nParagraph one.\n\nParagraph two."

Text Content Renderer Extension System

Extension interfaces and classes for customizing text rendering behavior.

/**
 * Extension interface for text content renderer
 */
public interface TextContentRenderer.TextContentRendererExtension extends Extension {
    /**
     * Extend the text content renderer builder with custom functionality
     * @param rendererBuilder the builder to extend
     */
    void extend(TextContentRenderer.Builder rendererBuilder);
}

/**
 * Factory for text content node renderers
 */
public interface TextContentNodeRendererFactory {
    /**
     * Create a node renderer with the given context
     * @param context the rendering context
     * @return a node renderer instance
     */
    NodeRenderer create(TextContentNodeRendererContext context);
}

/**
 * Context for text content node rendering
 */
public interface TextContentNodeRendererContext {
    /**
     * Whether newlines should be stripped
     * @return true if newlines should be stripped
     */
    boolean stripNewlines();
    
    /**
     * Get the text content writer
     * @return the text content writer
     */
    TextContentWriter getWriter();
    
    /**
     * Render a child node
     * @param node the node to render
     */
    void render(Node node);
}

Text Content Writer

Low-level text writing utility used by node renderers.

/**
 * Helper for writing text content
 */
public class TextContentWriter {
    /**
     * Create a text content writer that writes to the given appendable
     * @param out the appendable to write to
     */
    public TextContentWriter(Appendable out);
    
    /**
     * Write whitespace (space character)
     */
    public void whitespace();
    
    /**
     * Write a colon character
     */
    public void colon();
    
    /**
     * Write a line break
     */
    public void line();
    
    /**
     * Write text content, stripping newlines if configured
     * @param s the text to write
     */
    public void writeStripped(String s);
    
    /**
     * Write text content as-is
     * @param s the text to write
     */
    public void write(String s);
    
    /**
     * Write a single character
     * @param c the character to write
     */
    public void write(char c);
}

Usage Examples:

import org.commonmark.renderer.text.TextContentWriter;

// Custom text writer usage
StringBuilder output = new StringBuilder();
TextContentWriter writer = new TextContentWriter(output);

writer.write("Hello");
writer.whitespace();
writer.write("world");
writer.line();
writer.writeStripped("Text with\nnewlines"); // May strip newlines based on configuration

Core Text Content Node Renderer

The built-in renderer that handles all core CommonMark nodes for text output.

/**
 * Core text content renderer for built-in nodes
 */
public class CoreTextContentNodeRenderer extends AbstractVisitor implements NodeRenderer {
    /**
     * Create a core text content node renderer with the given context
     * @param context the rendering context
     */
    public CoreTextContentNodeRenderer(TextContentNodeRendererContext context);
    
    /**
     * Get the node types this renderer handles
     * @return set of node types
     */
    public Set<Class<? extends Node>> getNodeTypes();
    
    /**
     * Render the specified node
     * @param node the node to render
     */
    public void render(Node node);
    
    // Visit methods for all core node types (inherited from AbstractVisitor)
}

Text Rendering Behavior

The text content renderer handles different node types with specific text extraction logic:

Block Elements

  • Document: Renders all child blocks with appropriate spacing
  • Heading: Renders heading text followed by double newline
  • Paragraph: Renders paragraph text followed by double newline
  • BlockQuote: Renders quoted text with standard spacing
  • Code Blocks: Renders code content with appropriate line breaks
  • Lists: Renders list items with appropriate spacing and structure
  • Thematic Break: Renders as empty (no text content)
  • HTML Blocks: Renders as empty (HTML content stripped)

Inline Elements

  • Text: Renders literal text content
  • Code: Renders code content without backticks
  • Emphasis/Strong: Renders emphasized text without formatting markers
  • Link: Renders link text content (URL is ignored)
  • Image: Renders alt text content
  • Line Breaks: Renders as space or newline depending on type
  • HTML Inline: Renders as empty (HTML content stripped)

Usage Examples:

import org.commonmark.renderer.text.TextContentRenderer;
import org.commonmark.renderer.text.TextContentNodeRendererFactory;
import org.commonmark.renderer.text.TextContentNodeRendererContext;
import org.commonmark.renderer.NodeRenderer;
import org.commonmark.node.CustomNode;

// Custom text node renderer
public class CustomTextRenderer implements NodeRenderer {
    private final TextContentNodeRendererContext context;
    private final TextContentWriter writer;
    
    public CustomTextRenderer(TextContentNodeRendererContext context) {
        this.context = context;
        this.writer = context.getWriter();
    }
    
    @Override
    public Set<Class<? extends Node>> getNodeTypes() {
        return Collections.singleton(CustomNode.class);
    }
    
    @Override
    public void render(Node node) {
        CustomNode customNode = (CustomNode) node;
        
        writer.write("[CUSTOM: ");
        renderChildren(customNode);
        writer.write("]");
    }
    
    private void renderChildren(Node parent) {
        Node child = parent.getFirstChild();
        while (child != null) {
            context.render(child);
            child = child.getNext();
        }
    }
}

// Register custom text renderer
TextContentRenderer renderer = TextContentRenderer.builder()
    .nodeRendererFactory(context -> new CustomTextRenderer(context))
    .build();

// Demonstrate different rendering modes
Parser parser = Parser.builder().build();
Node document = parser.parse(
    "# Title\n\n" +
    "This is a paragraph with **bold** text and a [link](url).\n\n" +
    "- List item 1\n" +
    "- List item 2\n\n" +
    "```java\n" +
    "System.out.println(\"code\");\n" +
    "```"
);

// Default text rendering (preserves structure)
TextContentRenderer defaultRenderer = TextContentRenderer.builder().build();
String structured = defaultRenderer.render(document);
System.out.println("Structured:\n" + structured);

// Single-line text rendering
TextContentRenderer singleLineRenderer = TextContentRenderer.builder()
    .stripNewlines(true)
    .build();
String singleLine = singleLineRenderer.render(document);
System.out.println("Single line: " + singleLine);

Common Use Cases

Extract Plain Text from Markdown

// Convert Markdown to plain text for search indexing
String markdown = "# Article Title\n\nThis **article** discusses [CommonMark](url).";
Node document = parser.parse(markdown);
String plainText = textRenderer.render(document);
// Use plainText for full-text search, previews, etc.

Generate Text Summaries

// Generate single-line summary
TextContentRenderer summaryRenderer = TextContentRenderer.builder()
    .stripNewlines(true)
    .build();
String summary = summaryRenderer.render(document);
// Use summary for meta descriptions, previews, etc.

Extract Headings for Table of Contents

// Custom renderer to extract only headings
public class HeadingExtractor implements NodeRenderer {
    // Implementation that only renders heading text
}

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