package org.jetbrains.dokka 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.* class MarkdownNode(val node: ASTNode, val markdown: String) { val children: List 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 } } fun MarkdownNode.visit(action: (MarkdownNode, () -> Unit) -> Unit) { action(this) { for (child in children) { child.visit(action) } } } public fun MarkdownNode.toTestString(): String { val sb = StringBuilder() var level = 0 visit {(node, visitChildren) -> sb.append(" ".repeat(level * 2)) sb.append(node.type.toString()) sb.append(":" + node.text.replace("\n", "\u23CE")) sb.appendln() level++ visitChildren() level-- } return sb.toString() } public fun MarkdownNode.toHtml(): String { val sb = StringBuilder() visit {(node, processChildren) -> val nodeType = node.type val nodeText = node.text when (nodeType) { MarkdownElementTypes.UNORDERED_LIST -> { sb.appendln("") } MarkdownElementTypes.ORDERED_LIST -> { sb.appendln("
    ") processChildren() sb.appendln("
") } MarkdownElementTypes.LIST_ITEM -> { sb.append("
  • ") processChildren() sb.appendln("
  • ") } MarkdownElementTypes.EMPH -> { sb.append("") processChildren() sb.append("") } MarkdownElementTypes.STRONG -> { sb.append("") processChildren() sb.append("") } MarkdownElementTypes.ATX_1 -> { sb.append("

    ") processChildren() sb.append("

    ") } MarkdownElementTypes.ATX_2 -> { sb.append("

    ") processChildren() sb.append("

    ") } MarkdownElementTypes.ATX_3 -> { sb.append("

    ") processChildren() sb.append("

    ") } MarkdownElementTypes.ATX_4 -> { sb.append("

    ") processChildren() sb.append("

    ") } MarkdownElementTypes.ATX_5 -> { sb.append("
    ") processChildren() sb.append("
    ") } MarkdownElementTypes.ATX_6 -> { sb.append("
    ") processChildren() sb.append("
    ") } MarkdownElementTypes.BLOCK_QUOTE -> { sb.append("
    ") processChildren() sb.append("
    ") } MarkdownElementTypes.PARAGRAPH -> { sb.append("

    ") processChildren() sb.appendln("

    ") } MarkdownTokenTypes.CODE -> { sb.append("
    ")
                    sb.append(nodeText)
                    sb.append("
    ")
                }
                MarkdownTokenTypes.TEXT -> {
                    sb.append(nodeText)
                }
                else -> {
                    processChildren()
                }
            }
        }
        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 tree = MarkdownParser(CommonMarkMarkerProcessor()).buildMarkdownTreeFromString(markdown)
        val markdownTree = MarkdownNode(tree, markdown)
        val ast = markdownTree.toTestString()
        return markdownTree.toHtml()
    }