blob: 2a144c57b8049b7c6d255b2baf4d157ab438f21e [file] [log] [blame]
package eu.mulk.mulkcms2.common.markdown;
import com.vladsch.flexmark.ext.abbreviation.AbbreviationExtension;
import com.vladsch.flexmark.ext.autolink.AutolinkExtension;
import com.vladsch.flexmark.ext.definition.DefinitionExtension;
import com.vladsch.flexmark.ext.footnotes.FootnoteExtension;
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension;
import com.vladsch.flexmark.ext.tables.TablesExtension;
import com.vladsch.flexmark.ext.typographic.TypographicExtension;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.data.MutableDataSet;
import java.util.Arrays;
import org.jsoup.Jsoup;
import org.jsoup.safety.Cleaner;
import org.jsoup.safety.Safelist;
public class MarkdownConverter {
public enum Mode {
POST,
COMMENT,
}
private final Parser parser;
private final HtmlRenderer renderer;
private final Mode mode;
public MarkdownConverter(Mode mode) {
var options = new MutableDataSet();
options.set(
Parser.EXTENSIONS,
Arrays.asList(
TablesExtension.create(),
StrikethroughExtension.create(),
AbbreviationExtension.create(),
AutolinkExtension.create(),
DefinitionExtension.create(),
TypographicExtension.create(),
FootnoteExtension.create(),
AbbreviationExtension.create()));
options.set(Parser.FENCED_CODE_BLOCK_PARSER, true);
options.set(HtmlRenderer.SOFT_BREAK, "\n");
options.set(HtmlRenderer.HARD_BREAK, "<br />\n");
options.set(TypographicExtension.ENABLE_SMARTS, true);
options.set(TypographicExtension.ENABLE_QUOTES, true);
options.set(FootnoteExtension.FOOTNOTE_BACK_REF_STRING, "");
this.mode = mode;
this.parser = Parser.builder(options).build();
this.renderer = HtmlRenderer.builder(options).build();
}
public String htmlify(String markdown) {
var parsedDocument = parser.parse(markdown);
var uncleanHtml = renderer.render(parsedDocument);
var cleaner = makeCleaner();
var cleanedDocument = cleaner.clean(Jsoup.parseBodyFragment(uncleanHtml));
cleanedDocument.select("table").addClass("pure-table").addClass("pure-table-horizontal");
return cleanedDocument.body().html();
}
private Cleaner makeCleaner() {
var safelist =
switch (mode) {
case POST -> Safelist.relaxed()
.addTags("abbr", "acronym")
.addAttributes("abbr", "title")
.addAttributes("acronym", "title");
case COMMENT -> Safelist.simpleText()
.addTags(
"p",
"blockquote",
"cite",
"code",
"pre",
"dd",
"dl",
"dt",
"s",
"sub",
"sup",
"ol",
"ul",
"li",
"abbr",
"acronym",
"ins",
"del")
.addAttributes("abbr", "title")
.addAttributes("acronym", "title");
};
return new Cleaner(safelist);
}
}