flexmark-java
| Language | Java (11+ for 0.64) |
|---|---|
| License | BSD-2-Clause |
| Repository | github.com/vsch/flexmark-java |
| Documentation | wiki, usage examples |
| Depends on | flexmark-util; extensions bring their own (e.g. openhtmltopdf for PDF, docx4j for DOCX) |
| Read / write | parses CommonMark plus extensions; renders HTML, Markdown, DOCX, PDF; converts HTML to Markdown |
flexmark-java began as a fork of commonmark-java and added detailed source tracking, a large set of extensions (tables, task lists, footnotes, front matter, TOC, admonitions, abbreviations, attributes, emoji, wiki links, definition lists and more) and “parser emulation” to mimic other Markdown processors (Pegdown, Kramdown, MultiMarkdown, GitHub). The flexmark-html2md-converter module turns HTML back into Markdown, and flexmark-docx-converter and flexmark-pdf-converter produce Word and PDF files. JetBrains’ Markdown plugin was built on it.
Options are passed through a MutableDataSet. The last release, 0.64.8, is from 2023; the project still receives occasional commits. Use the flexmark-all artifact to get everything, or individual modules to keep dependencies small.
Installation#
Maven:
<dependency>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-all</artifactId>
<version>0.64.8</version>
</dependency>
Gradle: implementation("com.vladsch.flexmark:flexmark-all:0.64.8")
Basic usage: convert Markdown to HTML with GFM extensions#
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension;
import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension;
import com.vladsch.flexmark.ext.tables.TablesExtension;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.ast.Node;
import com.vladsch.flexmark.util.data.MutableDataSet;
import java.util.List;
public class MdToHtml {
public static void main(String[] args) {
MutableDataSet options = new MutableDataSet();
options.set(Parser.EXTENSIONS, List.of(
TablesExtension.create(),
StrikethroughExtension.create(),
TaskListExtension.create()));
Parser parser = Parser.builder(options).build();
HtmlRenderer renderer = HtmlRenderer.builder(options).build();
Node document = parser.parse("| a | b |\n|---|---|\n| 1 | 2 |\n\n- [x] ~~done~~\n");
System.out.println(renderer.render(document));
}
}
How to list headings and links#
import com.vladsch.flexmark.ast.Heading;
import com.vladsch.flexmark.ast.Link;
import com.vladsch.flexmark.util.ast.NodeVisitor;
import com.vladsch.flexmark.util.ast.VisitHandler;
NodeVisitor visitor = new NodeVisitor(
new VisitHandler<>(Heading.class, h -> System.out.println("h" + h.getLevel() + ": " + h.getText())),
new VisitHandler<>(Link.class, l -> System.out.println("link: " + l.getUrl()))
);
visitor.visit(document);
NodeVisitor visits children automatically when a handler doesn’t stop it.
How to convert HTML to Markdown#
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;
String md = FlexmarkHtmlConverter.builder().build()
.convert("<h1>Title</h1><p>Some <b>bold</b> text and <a href=\"https://example.com\">a link</a>.</p>");
// # Title
//
// Some **bold** text and [a link](https://example.com).
How to emulate GitHub’s dialect#
import com.vladsch.flexmark.parser.ParserEmulationProfile;
MutableDataSet options = new MutableDataSet();
options.setFrom(ParserEmulationProfile.GITHUB_DOC);
How to escape raw HTML#
options.set(HtmlRenderer.ESCAPE_HTML, true);
Tips#
- Pass the same
optionsto the parser and the renderer so extensions register on both. Node.getChars()returns the original source text of a node, with offsets, which is useful for editors and linters.- For new projects that only need CommonMark and GFM, commonmark-java is smaller and more actively released.