Skip to content

Instantly share code, notes, and snippets.

@baole
Last active January 26, 2019 05:44
Show Gist options
  • Save baole/8cada2ca3e55fa42e6ea59b905b8a21b to your computer and use it in GitHub Desktop.
Save baole/8cada2ca3e55fa42e6ea59b905b8a21b to your computer and use it in GitHub Desktop.
package com.anttek.alice.util.markdown;
import org.commonmark.node.Node;
import org.commonmark.node.StrongEmphasis;
import org.commonmark.node.Text;
import org.commonmark.parser.delimiter.DelimiterProcessor;
import org.commonmark.parser.delimiter.DelimiterRun;
public class AliceAsteriskDelimiterProcessor implements DelimiterProcessor {
private final char delimiterChar;
public AliceAsteriskDelimiterProcessor() {
this.delimiterChar = '*';
}
@Override
public char getOpeningCharacter() {
return delimiterChar;
}
@Override
public char getClosingCharacter() {
return delimiterChar;
}
@Override
public int getMinLength() {
return 1;
}
@Override
public int getDelimiterUse(DelimiterRun opener, DelimiterRun closer) {
// "multiple of 3" rule for internal delimiter runs
if ((opener.canClose() || closer.canOpen()) && (opener.originalLength() + closer.originalLength()) % 3 == 0) {
return 0;
}
// calculate actual number of delimiters used from this closer
if (opener.length() >= 2 && closer.length() >= 2) {
return 2;
} else {
return 1;
}
}
@Override
public void process(Text opener, Text closer, int delimiterUse) {
Node emphasis = new StrongEmphasis();
Node tmp = opener.getNext();
while (tmp != null && tmp != closer) {
Node next = tmp.getNext();
emphasis.appendChild(tmp);
tmp = next;
}
opener.insertAfter(emphasis);
}
}
package com.anttek.alice.util.markdown;
import org.commonmark.node.Emphasis;
import org.commonmark.node.Paragraph;
import org.commonmark.node.StrongEmphasis;
import org.commonmark.renderer.html.CoreHtmlNodeRenderer;
import org.commonmark.renderer.html.HtmlNodeRendererContext;
import org.commonmark.renderer.html.HtmlWriter;
public class AliceHtmlNodeRender extends CoreHtmlNodeRenderer {
private final HtmlWriter html;
public AliceHtmlNodeRender(HtmlNodeRendererContext context) {
super(context);
this.html = context.getWriter();
}
@Override
public void visit(Paragraph paragraph) {
visitChildren(paragraph);
}
@Override
public void visit(StrongEmphasis strongEmphasis) {
html.tag("b");
visitChildren(strongEmphasis);
html.tag("/b");
}
@Override
public void visit(Emphasis emphasis) {
html.tag("i");
visitChildren(emphasis);
html.tag("/i");
}
}
package com.anttek.alice.util.markdown;
import org.commonmark.parser.delimiter.DelimiterProcessor;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
public class AliceInlineParser extends org.commonmark.internal.InlineParserImpl {
public AliceInlineParser(List<DelimiterProcessor> processorList) {
super(processorList);
try {
Field f = org.commonmark.internal.InlineParserImpl.class.getDeclaredField("delimiterProcessors");
f.setAccessible(true);
Map<Character, DelimiterProcessor> processors = (Map<Character, DelimiterProcessor>) f.get(this);
processors.put('*', new AliceAsteriskDelimiterProcessor());
} catch (Throwable e) {
e.printStackTrace();
}
}
}
package com.anttek.alice.util.markdown;
import org.commonmark.parser.InlineParser;
import org.commonmark.parser.InlineParserContext;
import org.commonmark.parser.InlineParserFactory;
public class AliceInlineParserFactory implements InlineParserFactory {
@Override
public InlineParser create(InlineParserContext inlineParserContext) {
return new AliceInlineParser(inlineParserContext.getCustomDelimiterProcessors());
}
}
package com.anttek.alice.utils
import com.anttek.alice.util.markdown.AliceHtmlNodeRender
import com.anttek.alice.util.markdown.AliceInlineParserFactory
import com.anttek.alice.util.markdown.StrikethroughDelimiterProcessor
import com.anttek.alice.util.markdown.StrikethroughExtension
import org.commonmark.parser.Parser
import org.commonmark.renderer.html.HtmlRenderer
import org.junit.Test
import org.commonmark.renderer.html.HtmlNodeRendererContext
import org.commonmark.renderer.NodeRenderer
import org.commonmark.renderer.html.HtmlWriter
import java.util.*
import org.commonmark.node.*
class MarkdownTest {
val sample = "This is *bold* and _italic_ and ~strikethought~ text"
@Test
fun customParser() {
val parser = Parser.builder()
.inlineParserFactory(AliceInlineParserFactory())
.extensions(mutableListOf(StrikethroughExtension.create()))
.build()
val renderer = HtmlRenderer.builder()
.nodeRendererFactory { AliceHtmlNodeRender(it) }
.extensions(mutableListOf(StrikethroughExtension.create()))
.build()
System.out.println(renderer.render(parser.parse(sample)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment