diff options
author | Ilya Ryzhenkov <orangy@jetbrains.com> | 2014-09-26 21:04:33 +0400 |
---|---|---|
committer | Ilya Ryzhenkov <orangy@jetbrains.com> | 2014-09-26 21:04:33 +0400 |
commit | 2e3dc238275073a5c7a2e5a14c79337d12492dad (patch) | |
tree | 53f54e03f0564500e72f7dede11baf7ae6871bb1 /src/Markdown | |
parent | 7b2e274afa45560796160308ba286651651d7099 (diff) | |
download | dokka-2e3dc238275073a5c7a2e5a14c79337d12492dad.tar.gz dokka-2e3dc238275073a5c7a2e5a14c79337d12492dad.tar.bz2 dokka-2e3dc238275073a5c7a2e5a14c79337d12492dad.zip |
Continue markdown processing
Diffstat (limited to 'src/Markdown')
-rw-r--r-- | src/Markdown/MarkdownProcessor.kt | 124 | ||||
-rw-r--r-- | src/Markdown/markdown.bnf | 24 |
2 files changed, 117 insertions, 31 deletions
diff --git a/src/Markdown/MarkdownProcessor.kt b/src/Markdown/MarkdownProcessor.kt index 4453e750..fe6e8436 100644 --- a/src/Markdown/MarkdownProcessor.kt +++ b/src/Markdown/MarkdownProcessor.kt @@ -26,31 +26,111 @@ public class MarkdownProcessor { } public class MarkdownTree(private val text: String, private val structure: FlyweightCapableTreeStructure<LighterASTNode>) { - public fun dump(): String { - val sb = StringBuilder() - visit(sb, "", structure.getRoot(), structure, text) - return sb.toString() + fun visit(action: (LighterASTNode, String, visitChildren: () -> Unit) -> Unit) { + visit(structure.getRoot(), action) + } + + fun visit(node: LighterASTNode, action: (LighterASTNode, String, visitChildren: () -> Unit) -> Unit) { + action(node, text) { + val ref = Ref.create<Array<LighterASTNode>?>() + val count = structure.getChildren(node, ref) + val children = ref.get() + if (children != null) { + for (index in 0..count - 1) { + val child = children[index] + visit(child, action) + } + } + } } -} -fun markdownToHtml(markdown : String) : String { - return MarkdownProcessor().parse(markdown).dump() } +public fun MarkdownTree.dump(): String { + val sb = StringBuilder() + var level = 0 + visit {(node, text, visitChildren) -> + val nodeText = text.substring(node.getStartOffset(), node.getEndOffset()) + sb.append(" ".repeat(level * 2)) + sb.append(node.getTokenType().toString()) + sb.append(":" + nodeText.replace("\n", "\u23CE")) + sb.appendln() + level++ + visitChildren() + level-- + } + return sb.toString() +} -fun visit(sb: StringBuilder, indent: String, node: LighterASTNode, structure: FlyweightCapableTreeStructure<LighterASTNode>, markdown: String) { - sb.append(indent) - sb.append(node.getTokenType().toString()) - val nodeText = markdown.substring(node.getStartOffset(), node.getEndOffset()) - sb.append(":" + nodeText.replace("\n","\u23CE")) - sb.appendln() - val ref = Ref.create<Array<LighterASTNode>?>() - val count = structure.getChildren(node, ref) - val children = ref.get() - if (children == null) - return - for (index in 0..count - 1) { - val child = children[index] - visit(sb, indent + " ", child, structure, markdown) +public fun MarkdownTree.toHtml(): String { + val sb = StringBuilder() + var level = 0 + visit {(node, text, processChildren) -> + val nodeType = node.getTokenType() + val nodeText = text.substring(node.getStartOffset(), node.getEndOffset()) + val indent = " ".repeat(level * 2) + when (nodeType) { + MarkdownElementTypes.BULLET_LIST -> { + sb.appendln("$indent<ul>") + level++ + processChildren() + level-- + sb.appendln("$indent</ul>") + } + MarkdownElementTypes.HORIZONTAL_RULE -> { + sb.appendln("$indent<hr/>") + } + MarkdownElementTypes.ORDERED_LIST -> { + sb.appendln("$indent<ol>") + processChildren() + sb.appendln("$indent</ol>") + } + MarkdownElementTypes.LIST_BLOCK -> { + sb.append("$indent<li>") + processChildren() + sb.appendln("</li>") + } + MarkdownElementTypes.EMPH -> { + sb.append("<em>") + processChildren() + sb.append("</em>") + } + MarkdownElementTypes.STRONG -> { + sb.append("<strong>") + processChildren() + sb.append("</strong>") + } + MarkdownElementTypes.PLAIN_TEXT -> { + sb.append(nodeText) + } + MarkdownElementTypes.END_LINE -> { + sb.appendln() + } + MarkdownElementTypes.BLANK_LINE -> { + sb.appendln() + } + MarkdownElementTypes.PARA -> { + sb.appendln("$indent<p>") + processChildren() + sb.appendln("$indent</p>") + } + MarkdownElementTypes.VERBATIM -> { + sb.appendln("$indent<pre><code>") + processChildren() + sb.appendln("$indent</code></pre>") + } + else -> { + processChildren() + } + } } -}
\ No newline at end of file + return sb.toString() +} + + +fun markdownToHtml(markdown: String): String { + val markdownTree = MarkdownProcessor().parse(markdown) + val ast = markdownTree.dump() + return markdownTree.toHtml() +} + diff --git a/src/Markdown/markdown.bnf b/src/Markdown/markdown.bnf index 71100a6f..ca254295 100644 --- a/src/Markdown/markdown.bnf +++ b/src/Markdown/markdown.bnf @@ -32,19 +32,24 @@ BlankLine ::= OptionalSpace Newline Whitespace ::= Spacechar | Newline EndLine ::= TerminalEndline | NormalEndline private NormalEndline ::= OptionalSpace Newline !BlankLine -private TerminalEndline ::= OptionalSpace Newline <<eof>> +private TerminalEndline ::= (OptionalSpace Newline <<eof>>) | (OptionalSpace <<eof>>) private Indent ::= "\t" | " " +NonblankIndentedLine ::= !BlankLine IndentedLine +IndentedLine ::= Indent PlainText // ---- BLOCKS ---- -Block ::= BlankLine* ( - Para - | Plain +private Block ::= BlankLine* ( + Para + | Verbatim | OrderedList | BulletList + | Inlines ) -Para ::= NonindentSpace Inlines (BlankLine+ | TerminalEndline) -private Plain ::= Inlines +Para ::= NonindentSpace Inlines (BlankLine | TerminalEndline) + +Verbatim ::= VerbatimItem+ +VerbatimItem ::= BlankLine* NonblankIndentedLine HorizontalRule ::= NonindentSpace ( '*' OptionalSpace '*' OptionalSpace '*' (OptionalSpace '*')* @@ -61,15 +66,16 @@ OrderedList ::= &Enumerator List private List ::= (ListItem BlankLine*)+ ListItem ::= (Bullet | Enumerator) ListBlock ( ListContinuationBlock )* -ListBlock ::= !BlankLine Plain ( ListBlockLine )* -ListBlockLine ::= !BlankLine !(Indent? (Bullet | Enumerator)) !HorizontalRule Indent? Plain +ListBlock ::= !BlankLine Inlines ( ListBlockLine )* +ListBlockLine ::= !BlankLine !(Indent? (Bullet | Enumerator)) !HorizontalRule Indent? Inlines ListContinuationBlock ::= BlankLine* (Indent ListBlock)+ // ---- INLINES ---- private Inlines ::= (!EndLine Inline | EndLine &Inline )+ EndLine? -Inline ::= String | Number | EndLine | Spacechar+ | Strong | Emph | Link +private Inline ::= Strong | Emph | Link | PlainText +PlainText ::= (String | Number | Spacechar)+ Emph ::= EmphStar | EmphUnderscore private EmphStar ::= '*' !Whitespace (!'*' Inline)+ '*' |