-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement a temporary Markdown-To-BBCode converter
- Loading branch information
Showing
5 changed files
with
307 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
renderer/src/main/java/me/hsgamer/mcreleaser/renderer/bbcode/MarkdownToBBCodeConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package me.hsgamer.mcreleaser.renderer.bbcode; | ||
|
||
import me.hsgamer.mcreleaser.renderer.bbcode.internal.BBCodeNodeRendererContext; | ||
import me.hsgamer.mcreleaser.renderer.bbcode.internal.BBCodeWriter; | ||
import me.hsgamer.mcreleaser.renderer.bbcode.internal.CodeBBCodeNodeRenderer; | ||
import org.commonmark.internal.util.Escaping; | ||
import org.commonmark.node.Node; | ||
import org.commonmark.parser.Parser; | ||
|
||
public class MarkdownToBBCodeConverter { | ||
private static final Parser parser = Parser.builder().build(); | ||
|
||
// TODO: Implement a dedicated library for BBCode rendering | ||
public static String convert(String markdown) { | ||
Node document = parser.parse(markdown); | ||
StringBuilder builder = new StringBuilder(); | ||
BBCodeNodeRendererContext context = new BBCodeNodeRendererContext() { | ||
@Override | ||
public String escapeUrl(String url) { | ||
return Escaping.escapeHtml(url); | ||
} | ||
|
||
@Override | ||
public BBCodeWriter getWriter() { | ||
return new BBCodeWriter(builder); | ||
} | ||
|
||
@Override | ||
public String getSoftBreak() { | ||
return "\n"; | ||
} | ||
}; | ||
document.accept(new CodeBBCodeNodeRenderer(context)); | ||
return builder.toString(); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
...c/main/java/me/hsgamer/mcreleaser/renderer/bbcode/internal/BBCodeNodeRendererContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package me.hsgamer.mcreleaser.renderer.bbcode.internal; | ||
|
||
public interface BBCodeNodeRendererContext { | ||
String escapeUrl(String url); | ||
|
||
BBCodeWriter getWriter(); | ||
|
||
String getSoftBreak(); | ||
} |
76 changes: 76 additions & 0 deletions
76
renderer/src/main/java/me/hsgamer/mcreleaser/renderer/bbcode/internal/BBCodeWriter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package me.hsgamer.mcreleaser.renderer.bbcode.internal; | ||
|
||
import org.commonmark.internal.util.Escaping; | ||
|
||
import java.io.IOException; | ||
import java.util.Map; | ||
|
||
public class BBCodeWriter { | ||
private static final Map<String, String> NO_ATTRIBUTES = Map.of(); | ||
|
||
private final Appendable appendable; | ||
private char lastChar = 0; | ||
|
||
public BBCodeWriter(Appendable appendable) { | ||
this.appendable = appendable; | ||
} | ||
|
||
public void raw(String s) { | ||
append(s); | ||
} | ||
|
||
public void text(String text) { | ||
append(Escaping.escapeHtml(text)); | ||
} | ||
|
||
public void tag(String name) { | ||
tag(name, null, NO_ATTRIBUTES, false); | ||
} | ||
|
||
public void tag(String name, String value) { | ||
tag(name, value, NO_ATTRIBUTES, false); | ||
} | ||
|
||
public void tag(String name, Map<String, String> attrs) { | ||
tag(name, null, attrs, false); | ||
} | ||
|
||
public void tag(String name, String value, Map<String, String> attrs, boolean voidElement) { | ||
append("["); | ||
append(name); | ||
if (value != null) { | ||
append("="); | ||
append(value); | ||
} | ||
if (attrs != null && !attrs.isEmpty()) { | ||
for (Map.Entry<String, String> entry : attrs.entrySet()) { | ||
append(" "); | ||
append(entry.getKey()); | ||
append("="); | ||
append(entry.getValue()); | ||
} | ||
} | ||
if (voidElement) { | ||
append("/"); | ||
} | ||
append("]"); | ||
} | ||
|
||
public void line() { | ||
if (lastChar != 0 && lastChar != '\n') { | ||
append("\n"); | ||
} | ||
} | ||
|
||
protected void append(String s) { | ||
try { | ||
appendable.append(s); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
int length = s.length(); | ||
if (length != 0) { | ||
lastChar = s.charAt(length - 1); | ||
} | ||
} | ||
} |
184 changes: 184 additions & 0 deletions
184
.../src/main/java/me/hsgamer/mcreleaser/renderer/bbcode/internal/CodeBBCodeNodeRenderer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
package me.hsgamer.mcreleaser.renderer.bbcode.internal; | ||
|
||
import org.commonmark.node.*; | ||
import org.commonmark.renderer.NodeRenderer; | ||
|
||
import java.util.Set; | ||
|
||
public class CodeBBCodeNodeRenderer extends AbstractVisitor implements NodeRenderer { | ||
private final BBCodeNodeRendererContext context; | ||
private final BBCodeWriter writer; | ||
|
||
public CodeBBCodeNodeRenderer(BBCodeNodeRendererContext context) { | ||
this.context = context; | ||
this.writer = context.getWriter(); | ||
} | ||
|
||
@Override | ||
public Set<Class<? extends Node>> getNodeTypes() { | ||
return Set.of( | ||
Document.class, | ||
Heading.class, | ||
Paragraph.class, | ||
BlockQuote.class, | ||
BulletList.class, | ||
FencedCodeBlock.class, | ||
HtmlBlock.class, | ||
ThematicBreak.class, | ||
IndentedCodeBlock.class, | ||
Link.class, | ||
ListItem.class, | ||
OrderedList.class, | ||
Image.class, | ||
Emphasis.class, | ||
StrongEmphasis.class, | ||
Text.class, | ||
Code.class, | ||
HtmlInline.class, | ||
SoftLineBreak.class, | ||
HardLineBreak.class | ||
); | ||
} | ||
|
||
@Override | ||
public void render(Node node) { | ||
node.accept(this); | ||
} | ||
|
||
@Override | ||
public void visit(Document document) { | ||
visitChildren(document); | ||
} | ||
|
||
@Override | ||
public void visit(Heading heading) { | ||
int size = Math.max(1, 8 - heading.getLevel()); | ||
writer.tag("b"); | ||
writer.tag("size", String.valueOf(size)); | ||
visitChildren(heading); | ||
writer.tag("/size"); | ||
writer.tag("/b"); | ||
writer.line(); | ||
} | ||
|
||
@Override | ||
public void visit(Paragraph paragraph) { | ||
visitChildren(paragraph); | ||
writer.line(); | ||
} | ||
|
||
@Override | ||
public void visit(BlockQuote blockQuote) { | ||
writer.tag("quote"); | ||
visitChildren(blockQuote); | ||
writer.tag("/quote"); | ||
writer.line(); | ||
} | ||
|
||
@Override | ||
public void visit(BulletList bulletList) { | ||
writer.tag("list"); | ||
visitChildren(bulletList); | ||
writer.tag("/list"); | ||
writer.line(); | ||
} | ||
|
||
@Override | ||
public void visit(FencedCodeBlock fencedCodeBlock) { | ||
writer.tag("code"); | ||
writer.text(fencedCodeBlock.getLiteral()); | ||
writer.tag("/code"); | ||
writer.line(); | ||
} | ||
|
||
@Override | ||
public void visit(HtmlBlock htmlBlock) { | ||
writer.text(htmlBlock.getLiteral()); | ||
writer.line(); | ||
} | ||
|
||
@Override | ||
public void visit(ThematicBreak thematicBreak) { | ||
writer.tag("hr"); | ||
writer.line(); | ||
} | ||
|
||
@Override | ||
public void visit(IndentedCodeBlock indentedCodeBlock) { | ||
writer.tag("code"); | ||
writer.text(indentedCodeBlock.getLiteral()); | ||
writer.tag("/code"); | ||
writer.line(); | ||
} | ||
|
||
@Override | ||
public void visit(Link link) { | ||
writer.tag("url", context.escapeUrl(link.getDestination())); | ||
visitChildren(link); | ||
writer.tag("/url"); | ||
} | ||
|
||
@Override | ||
public void visit(ListItem listItem) { | ||
writer.tag("*"); | ||
visitChildren(listItem); | ||
writer.line(); | ||
} | ||
|
||
@Override | ||
public void visit(OrderedList orderedList) { | ||
writer.tag("list", orderedList.getMarkerStartNumber() + ""); | ||
visitChildren(orderedList); | ||
writer.tag("/list"); | ||
writer.line(); | ||
} | ||
|
||
@Override | ||
public void visit(Image image) { | ||
writer.tag("img", context.escapeUrl(image.getDestination())); | ||
writer.tag("/img"); | ||
} | ||
|
||
@Override | ||
public void visit(Emphasis emphasis) { | ||
writer.tag("i"); | ||
visitChildren(emphasis); | ||
writer.tag("/i"); | ||
} | ||
|
||
@Override | ||
public void visit(StrongEmphasis strongEmphasis) { | ||
writer.tag("b"); | ||
writer.tag("i"); | ||
visitChildren(strongEmphasis); | ||
writer.tag("/i"); | ||
writer.tag("/b"); | ||
} | ||
|
||
@Override | ||
public void visit(Text text) { | ||
writer.text(text.getLiteral()); | ||
} | ||
|
||
@Override | ||
public void visit(Code code) { | ||
writer.tag("code"); | ||
writer.text(code.getLiteral()); | ||
writer.tag("/code"); | ||
} | ||
|
||
@Override | ||
public void visit(HtmlInline htmlInline) { | ||
writer.text(htmlInline.getLiteral()); | ||
} | ||
|
||
@Override | ||
public void visit(SoftLineBreak softLineBreak) { | ||
writer.raw(context.getSoftBreak()); | ||
} | ||
|
||
@Override | ||
public void visit(HardLineBreak hardLineBreak) { | ||
writer.line(); | ||
} | ||
} |