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

html-rendering.mddocs/

HTML Rendering

High-performance HTML rendering system with extensive customization options including URL sanitization, attribute providers, custom node renderers, and output formatting controls. The HTML renderer converts CommonMark AST nodes into clean, standards-compliant HTML output.

Capabilities

HTML Renderer

Main rendering class that converts AST nodes to HTML output.

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

Usage Examples:

import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import org.commonmark.node.Node;

// Basic HTML rendering
Parser parser = Parser.builder().build();
HtmlRenderer renderer = HtmlRenderer.builder().build();

Node document = parser.parse("# Hello\n\nThis is **bold** text.");
String html = renderer.render(document);
// Result: <h1>Hello</h1>\n<p>This is <strong>bold</strong> text.</p>\n

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

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

HTML Renderer Builder

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

/**
 * Builder for configuring an HtmlRenderer
 */
public static class HtmlRenderer.Builder {
    /**
     * Build the configured HtmlRenderer instance
     * @return the configured HtmlRenderer
     */
    public HtmlRenderer build();
    
    /**
     * The HTML to use for rendering a softbreak, defaults to "\n"
     * Set it to "<br>" to make them hard breaks
     * Set it to " " to ignore line wrapping in the source
     * @param softbreak HTML for softbreak
     * @return this builder
     */
    public Builder softbreak(String softbreak);
    
    /**
     * Whether HtmlInline and HtmlBlock should be escaped, defaults to false
     * @param escapeHtml true for escaping, false for preserving raw HTML
     * @return this builder
     */
    public Builder escapeHtml(boolean escapeHtml);
    
    /**
     * Whether Image src and Link href should be sanitized, defaults to false
     * @param sanitizeUrls true for sanitization, false for preserving raw attribute
     * @return this builder
     */
    public Builder sanitizeUrls(boolean sanitizeUrls);
    
    /**
     * UrlSanitizer used to filter URLs if sanitizeUrls is true
     * @param urlSanitizer Filterer used to filter Image src and Link href
     * @return this builder
     */
    public Builder urlSanitizer(UrlSanitizer urlSanitizer);
    
    /**
     * Whether URLs of link or images should be percent-encoded, defaults to false
     * @param percentEncodeUrls true to percent-encode, false for leaving as-is
     * @return this builder
     */
    public Builder percentEncodeUrls(boolean percentEncodeUrls);
    
    /**
     * Add a factory for an attribute provider for adding/changing HTML attributes to the rendered tags
     * @param attributeProviderFactory the attribute provider factory to add
     * @return this builder
     */
    public Builder attributeProviderFactory(AttributeProviderFactory attributeProviderFactory);
    
    /**
     * 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(HtmlNodeRendererFactory nodeRendererFactory);
    
    /**
     * Add extensions to use on this HTML renderer
     * @param extensions extensions to use on this HTML renderer
     * @return this builder
     */
    public Builder extensions(Iterable<? extends Extension> extensions);
}

Usage Examples:

import org.commonmark.renderer.html.HtmlRenderer;
import org.commonmark.renderer.html.AttributeProvider;

// Custom softbreak handling
HtmlRenderer brRenderer = HtmlRenderer.builder()
    .softbreak("<br>\n")
    .build();

// Escape HTML content
HtmlRenderer safeRenderer = HtmlRenderer.builder()
    .escapeHtml(true)
    .build();

// URL sanitization
HtmlRenderer sanitizedRenderer = HtmlRenderer.builder()
    .sanitizeUrls(true)
    .percentEncodeUrls(true)
    .build();

// Custom attribute provider
HtmlRenderer customRenderer = HtmlRenderer.builder()
    .attributeProviderFactory(context -> new AttributeProvider() {
        @Override
        public void setAttributes(Node node, String tagName, Map<String, String> attributes) {
            if (node instanceof Heading) {
                attributes.put("class", "heading-" + ((Heading) node).getLevel());
            }
        }
    })
    .build();

HTML Renderer Extension System

Extension interfaces and classes for customizing HTML rendering behavior.

/**
 * Extension interface for HTML renderer
 */
public interface HtmlRenderer.HtmlRendererExtension extends Extension {
    /**
     * Extend the HTML renderer builder with custom functionality
     * @param rendererBuilder the builder to extend
     */
    void extend(HtmlRenderer.Builder rendererBuilder);
}

/**
 * Factory for HTML node renderers
 */
public interface HtmlNodeRendererFactory {
    /**
     * Create a node renderer with the given context
     * @param context the rendering context
     * @return a node renderer instance
     */
    NodeRenderer create(HtmlNodeRendererContext context);
}

/**
 * Context for HTML node rendering
 */
public interface HtmlNodeRendererContext {
    /**
     * Whether HTML should be escaped
     * @return true if HTML should be escaped
     */
    boolean shouldEscapeHtml();
    
    /**
     * Whether URLs should be sanitized
     * @return true if URLs should be sanitized
     */
    boolean shouldSanitizeUrls();
    
    /**
     * Get the URL sanitizer
     * @return the URL sanitizer
     */
    UrlSanitizer urlSanitizer();
    
    /**
     * Encode a URL if percent encoding is enabled
     * @param url the URL to encode
     * @return the encoded URL
     */
    String encodeUrl(String url);
    
    /**
     * Extend attributes for a node and tag
     * @param node the node being rendered
     * @param tagName the HTML tag name
     * @param attributes the current attributes
     * @return the extended attributes
     */
    Map<String, String> extendAttributes(Node node, String tagName, Map<String, String> attributes);
    
    /**
     * Get the HTML writer
     * @return the HTML writer
     */
    HtmlWriter getWriter();
    
    /**
     * Get the softbreak string
     * @return the softbreak HTML
     */
    String getSoftbreak();
    
    /**
     * Render a child node
     * @param node the node to render
     */
    void render(Node node);
}

Attribute Provider System

System for adding custom HTML attributes to rendered elements.

/**
 * Provides attributes for HTML elements
 */
public interface AttributeProvider {
    /**
     * Set attributes for the specified node and tag
     * @param node the node being rendered
     * @param tagName the HTML tag name
     * @param attributes the attributes map to modify
     */
    void setAttributes(Node node, String tagName, Map<String, String> attributes);
}

/**
 * Factory for attribute providers
 */
public interface AttributeProviderFactory {
    /**
     * Create an attribute provider with the given context
     * @param context the attribute provider context
     * @return an attribute provider instance
     */
    AttributeProvider create(AttributeProviderContext context);
}

/**
 * Context for attribute providers
 */
public interface AttributeProviderContext {
    // Context methods for attribute provision
}

Usage Examples:

import org.commonmark.renderer.html.AttributeProvider;
import org.commonmark.node.*;

// Add CSS classes to headings
AttributeProvider headingClassProvider = new AttributeProvider() {
    @Override
    public void setAttributes(Node node, String tagName, Map<String, String> attributes) {
        if (node instanceof Heading) {
            Heading heading = (Heading) node;
            attributes.put("class", "heading heading-" + heading.getLevel());
        }
    }
};

// Add target="_blank" to external links
AttributeProvider externalLinkProvider = new AttributeProvider() {
    @Override
    public void setAttributes(Node node, String tagName, Map<String, String> attributes) {
        if (node instanceof Link && tagName.equals("a")) {
            Link link = (Link) node;
            if (link.getDestination().startsWith("http")) {
                attributes.put("target", "_blank");
                attributes.put("rel", "noopener");
            }
        }
    }
};

// Use providers
HtmlRenderer renderer = HtmlRenderer.builder()
    .attributeProviderFactory(context -> headingClassProvider)
    .attributeProviderFactory(context -> externalLinkProvider)
    .build();

URL Sanitization

System for sanitizing URLs in links and images for security.

/**
 * Sanitizes URLs in links and images
 */
public interface UrlSanitizer {
    /**
     * Sanitize a link URL
     * @param url the URL to sanitize
     * @return the sanitized URL, or null to remove the URL
     */
    String sanitizeLinkUrl(String url);
    
    /**
     * Sanitize an image URL
     * @param url the URL to sanitize
     * @return the sanitized URL, or null to remove the URL
     */
    String sanitizeImageUrl(String url);
}

/**
 * Default URL sanitizer implementation
 */
public class DefaultUrlSanitizer implements UrlSanitizer {
    /**
     * Sanitize a link URL - allows http, https, ftp, mailto
     * @param url the URL to sanitize
     * @return the sanitized URL, or null if not allowed
     */
    public String sanitizeLinkUrl(String url);
    
    /**
     * Sanitize an image URL - allows http, https, data
     * @param url the URL to sanitize
     * @return the sanitized URL, or null if not allowed
     */
    public String sanitizeImageUrl(String url);
}

Usage Examples:

import org.commonmark.renderer.html.UrlSanitizer;
import org.commonmark.renderer.html.DefaultUrlSanitizer;

// Custom URL sanitizer
UrlSanitizer strictSanitizer = new UrlSanitizer() {
    @Override
    public String sanitizeLinkUrl(String url) {
        // Only allow https URLs
        if (url.startsWith("https://")) {
            return url;
        }
        return null; // Remove unsafe URLs
    }
    
    @Override
    public String sanitizeImageUrl(String url) {
        // Only allow https images or data URLs
        if (url.startsWith("https://") || url.startsWith("data:image/")) {
            return url;
        }
        return null;
    }
};

HtmlRenderer renderer = HtmlRenderer.builder()
    .sanitizeUrls(true)
    .urlSanitizer(strictSanitizer)
    .build();

HTML Writer

Low-level HTML writing utility used by node renderers.

/**
 * Helper for writing HTML output
 */
public class HtmlWriter {
    /**
     * Create an HTML writer that writes to the given appendable
     * @param out the appendable to write to
     */
    public HtmlWriter(Appendable out);
    
    /**
     * Write raw HTML content (not escaped)
     * @param s the raw HTML to write
     */
    public void raw(String s);
    
    /**
     * Write text content (HTML-escaped)
     * @param text the text to write
     */
    public void text(String text);
    
    /**
     * Write an HTML tag with no attributes
     * @param name the tag name
     */
    public void tag(String name);
    
    /**
     * Write an HTML tag with attributes
     * @param name the tag name
     * @param attrs the attributes map
     */
    public void tag(String name, Map<String, String> attrs);
    
    /**
     * Write an HTML tag with attributes, specifying if it's a void element
     * @param name the tag name
     * @param attrs the attributes map
     * @param voidElement true if this is a void element (like <br>)
     */
    public void tag(String name, Map<String, String> attrs, boolean voidElement);
    
    /**
     * Write a line break
     */
    public void line();
}

Core HTML Node Renderer

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

/**
 * Core HTML renderer for built-in nodes
 */
public class CoreHtmlNodeRenderer extends AbstractVisitor implements NodeRenderer {
    /**
     * Create a core HTML node renderer with the given context
     * @param context the rendering context
     */
    public CoreHtmlNodeRenderer(HtmlNodeRendererContext 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)
}

Usage Examples:

import org.commonmark.renderer.html.HtmlWriter;
import org.commonmark.renderer.html.HtmlNodeRendererContext;
import org.commonmark.renderer.NodeRenderer;
import org.commonmark.node.CustomBlock;

// Custom node renderer example
public class CustomBlockRenderer implements NodeRenderer {
    private final HtmlNodeRendererContext context;
    private final HtmlWriter html;
    
    public CustomBlockRenderer(HtmlNodeRendererContext context) {
        this.context = context;
        this.html = context.getWriter();
    }
    
    @Override
    public Set<Class<? extends Node>> getNodeTypes() {
        return Collections.singleton(CustomBlock.class);
    }
    
    @Override
    public void render(Node node) {
        CustomBlock customBlock = (CustomBlock) node;
        
        Map<String, String> attrs = new HashMap<>();
        attrs.put("class", "custom-block");
        
        html.tag("div", context.extendAttributes(node, "div", attrs));
        renderChildren(customBlock);
        html.tag("/div");
    }
    
    private void renderChildren(Node parent) {
        Node child = parent.getFirstChild();
        while (child != null) {
            context.render(child);
            child = child.getNext();
        }
    }
}

// Register custom renderer
HtmlRenderer renderer = HtmlRenderer.builder()
    .nodeRendererFactory(context -> new CustomBlockRenderer(context))
    .build();

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