aboutsummaryrefslogtreecommitdiff
path: root/src/Markdown/MarkdownProcessor.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/Markdown/MarkdownProcessor.kt')
-rw-r--r--src/Markdown/MarkdownProcessor.kt156
1 files changed, 74 insertions, 82 deletions
diff --git a/src/Markdown/MarkdownProcessor.kt b/src/Markdown/MarkdownProcessor.kt
index 040f2ad5..b5e18f92 100644
--- a/src/Markdown/MarkdownProcessor.kt
+++ b/src/Markdown/MarkdownProcessor.kt
@@ -1,80 +1,34 @@
package org.jetbrains.dokka
-import org.jetbrains.markdown.*
-import com.intellij.lang.impl.PsiBuilderImpl
-import com.intellij.psi.tree.TokenSet
-import com.intellij.lang.Language
-import com.intellij.psi.tree.IFileElementType
-import com.intellij.lang.LighterASTNode
-import com.intellij.util.diff.FlyweightCapableTreeStructure
-import com.intellij.openapi.util.Ref
-import org.jetbrains.markdown.lexer.MarkdownLexer
-import com.intellij.psi.tree.IElementType
+import net.nicoulaj.idea.markdown.lang.ast.*
+import net.nicoulaj.idea.markdown.lang.parser.dialects.commonmark.*
+import net.nicoulaj.idea.markdown.lang.parser.*
+import net.nicoulaj.idea.markdown.lang.*
-public object MarkdownProcessor {
- val EXPR_LANGUAGE = object : Language("MARKDOWN") {}
- val DOCUMENT = IFileElementType("DOCUMENT", EXPR_LANGUAGE);
-
- public fun parse(markdown: String): MarkdownTree {
- val parser = MarkdownParser()
- val builder = PsiBuilderImpl(null, null, TokenSet.EMPTY, TokenSet.EMPTY, MarkdownLexer(), null, markdown, null, null)
- parser.parse_only_(DOCUMENT, builder)
- val light = builder.getLightTree()!!
- return MarkdownTree(markdown, light)
- }
+class MarkdownNode(val node: ASTNode, val markdown: String) {
+ val children: List<MarkdownNode> get() = node.children.map { MarkdownNode(it, markdown) }
+ val endOffset: Int get() = node.endOffset
+ val startOffset: Int get() = node.startOffset
+ val type: IElementType get() = node.type
+ val text: String get() = markdown.substring(startOffset, endOffset)
+ fun child(type: IElementType): MarkdownNode? = children.firstOrNull { it.type == type }
}
-public class MarkdownTree(private val text: String, private val structure: FlyweightCapableTreeStructure<LighterASTNode>) {
- fun visit(action: (LighterASTNode, String, visitChildren: () -> Unit) -> Unit) {
- visit(structure.getRoot(), action)
- }
-
- fun findChildByType(node: LighterASTNode, findType: IElementType) : LighterASTNode? {
- val ref: Ref<Array<LighterASTNode>?> = 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]
- val nodeType = child.getTokenType()
- if (nodeType == findType)
- return child
- val nestedChild = findChildByType(child, findType)
- if (nestedChild != null)
- return nestedChild
- }
- }
- return null
- }
-
- fun getNodeText(node: LighterASTNode) : String {
- return text.substring(node.getStartOffset(), node.getEndOffset())
- }
-
- fun visit(node: LighterASTNode, action: (LighterASTNode, String, visitChildren: () -> Unit) -> Unit) {
- action(node, text) {
- val ref : Ref<Array<LighterASTNode>?> = 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 MarkdownNode.visit(action: (MarkdownNode, () -> Unit) -> Unit) {
+ action(this) {
+ for (child in children) {
+ child.visit(action)
}
}
-
}
-public fun MarkdownTree.toTestString(): String {
+public fun MarkdownNode.toTestString(): String {
val sb = StringBuilder()
var level = 0
- visit {(node, text, visitChildren) ->
- val nodeText = text.substring(node.getStartOffset(), node.getEndOffset())
+ visit {(node, visitChildren) ->
sb.append(" ".repeat(level * 2))
- sb.append(node.getTokenType().toString())
- sb.append(":" + nodeText.replace("\n", "\u23CE"))
+ sb.append(node.type.toString())
+ sb.append(":" + node.text.replace("\n", "\u23CE"))
sb.appendln()
level++
visitChildren()
@@ -83,26 +37,23 @@ public fun MarkdownTree.toTestString(): String {
return sb.toString()
}
-public fun MarkdownTree.toHtml(): String {
+public fun MarkdownNode.toHtml(): String {
val sb = StringBuilder()
- visit {(node, text, processChildren) ->
- val nodeType = node.getTokenType()
- val nodeText = text.substring(node.getStartOffset(), node.getEndOffset())
+ visit {(node, processChildren) ->
+ val nodeType = node.type
+ val nodeText = node.text
when (nodeType) {
- MarkdownElementTypes.BULLET_LIST -> {
+ MarkdownElementTypes.UNORDERED_LIST -> {
sb.appendln("<ul>")
processChildren()
sb.appendln("</ul>")
}
- MarkdownElementTypes.HORIZONTAL_RULE -> {
- sb.appendln("<hr/>")
- }
MarkdownElementTypes.ORDERED_LIST -> {
sb.appendln("<ol>")
processChildren()
sb.appendln("</ol>")
}
- MarkdownElementTypes.LIST_BLOCK -> {
+ MarkdownElementTypes.LIST_ITEM -> {
sb.append("<li>")
processChildren()
sb.appendln("</li>")
@@ -117,20 +68,54 @@ public fun MarkdownTree.toHtml(): String {
processChildren()
sb.append("</strong>")
}
- MarkdownElementTypes.PLAIN_TEXT -> {
- sb.append(nodeText)
+ MarkdownElementTypes.ATX_1 -> {
+ sb.append("<h1>")
+ processChildren()
+ sb.append("</h1>")
}
- MarkdownElementTypes.END_LINE -> {
- sb.appendln()
+ MarkdownElementTypes.ATX_2 -> {
+ sb.append("<h2>")
+ processChildren()
+ sb.append("</h2>")
}
- MarkdownElementTypes.BLANK_LINE -> {
- sb.appendln()
+ MarkdownElementTypes.ATX_3 -> {
+ sb.append("<h3>")
+ processChildren()
+ sb.append("</h3>")
+ }
+ MarkdownElementTypes.ATX_4 -> {
+ sb.append("<h4>")
+ processChildren()
+ sb.append("</h4>")
+ }
+ MarkdownElementTypes.ATX_5 -> {
+ sb.append("<h5>")
+ processChildren()
+ sb.append("</h5>")
+ }
+ MarkdownElementTypes.ATX_6 -> {
+ sb.append("<h6>")
+ processChildren()
+ sb.append("</h6>")
}
- MarkdownElementTypes.PARA -> {
+ MarkdownElementTypes.BLOCK_QUOTE -> {
+ sb.append("<blockquote>")
+ processChildren()
+ sb.append("</blockquote>")
+ }
+ MarkdownElementTypes.PARAGRAPH -> {
sb.append("<p>")
processChildren()
sb.appendln("</p>")
}
+ MarkdownTokenTypes.CODE -> {
+ sb.append("<pre><code>")
+ sb.append(nodeText)
+ sb.append("</code><pre>")
+ }
+ MarkdownTokenTypes.TEXT -> {
+ sb.append(nodeText)
+ }
else -> {
processChildren()
}
@@ -139,9 +124,16 @@ public fun MarkdownTree.toHtml(): String {
return sb.toString()
}
+fun parseMarkdown(markdown: String): MarkdownNode {
+ if (markdown.isEmpty())
+ return MarkdownNode(LeafASTNode(MarkdownElementTypes.MARKDOWN_FILE, 0, 0), markdown)
+ return MarkdownNode(MarkdownParser(CommonMarkMarkerProcessor()).buildMarkdownTreeFromString(markdown), markdown)
+}
fun markdownToHtml(markdown: String): String {
- val markdownTree = MarkdownProcessor.parse(markdown)
+
+ val tree = MarkdownParser(CommonMarkMarkerProcessor()).buildMarkdownTreeFromString(markdown)
+ val markdownTree = MarkdownNode(tree, markdown)
val ast = markdownTree.toTestString()
return markdownTree.toHtml()
}