MarkdownRenderService.java
package info.textgrid.rep.markdown;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;
import org.commonmark.Extension;
import org.commonmark.ext.gfm.tables.TablesExtension;
import org.commonmark.ext.heading.anchor.HeadingAnchorExtension;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class MarkdownRenderService {
// renderer and parser are meant to be threadsafe
// https://github.com/atlassian/commonmark-java#thread-safety
private static Parser parser;
private static HtmlRenderer renderer;
public MarkdownRenderService() {
List<Extension> extensions = Arrays.asList(
HeadingAnchorExtension.create(),
TablesExtension.create());
parser = Parser.builder()
.extensions(extensions).build();
renderer = HtmlRenderer.builder()
.extensions(extensions).build();
}
/**
* Render html from provided markdown
*
* @param in
* @return
* @throws IOException
*/
public String renderHtml(InputStream in) throws IOException {
// remove UTF8-BOM
BOMInputStream bomIn = BOMInputStream.builder().setInputStream(in).get();
InputStreamReader reader = new InputStreamReader(bomIn);
Node document = parser.parseReader(reader);
return renderer.render(document);
}
/**
* Render html from provided markdown
*
* @param in
* @return
* @throws IOException
*/
public String renderHtml(String markdown) throws IOException {
InputStream in = IOUtils.toInputStream(markdown, "UTF-8");
return renderHtml(in);
}
/**
* Render full html and also the toc for provided markdown
* This method reuses already parsed node for rendering both outputs in one record.
*
* @param in
* @return
* @throws IOException
*/
public HtmlAndToc renderHtmlAndToc(InputStream in) throws IOException {
// remove UTF8-BOM
BOMInputStream bomIn = BOMInputStream.builder().setInputStream(in).get();
InputStreamReader reader = new InputStreamReader(bomIn);
Node document = parser.parseReader(reader);
String markdown = renderer.render(document);
String toc = new TocRenderer().renderTocFromNode(document);
return new HtmlAndToc(markdown, toc);
}
/**
* Render full html and also the toc for provided markdown
* This method reuses already parsed node for rendering both outputs in one record.
*
* @param in
* @return
* @throws IOException
*/
public HtmlAndToc renderHtmlAndToc(String markdown) throws IOException {
InputStream in = IOUtils.toInputStream(markdown, "UTF-8");
return renderHtmlAndToc(in);
}
}