aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin/parsers/HtmlParser.kt
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/base/src/main/kotlin/parsers/HtmlParser.kt')
-rw-r--r--plugins/base/src/main/kotlin/parsers/HtmlParser.kt89
1 files changed, 89 insertions, 0 deletions
diff --git a/plugins/base/src/main/kotlin/parsers/HtmlParser.kt b/plugins/base/src/main/kotlin/parsers/HtmlParser.kt
new file mode 100644
index 00000000..ece3cf24
--- /dev/null
+++ b/plugins/base/src/main/kotlin/parsers/HtmlParser.kt
@@ -0,0 +1,89 @@
+package org.jetbrains.dokka.base.parsers
+
+import org.jetbrains.dokka.model.doc.*
+import org.jetbrains.dokka.base.parsers.factories.DocTagsFromStringFactory
+import org.jsoup.Jsoup
+import org.jsoup.nodes.Node
+import org.jsoup.select.NodeFilter
+import org.jsoup.select.NodeTraversor
+
+class HtmlParser : Parser() {
+
+ inner class NodeFilterImpl : NodeFilter {
+
+ private val nodesCache: MutableMap<Int, MutableList<DocTag>> = mutableMapOf()
+ private var currentDepth = 0
+
+ fun collect(): DocTag = nodesCache[currentDepth]!![0]
+
+ override fun tail(node: Node?, depth: Int): NodeFilter.FilterResult {
+ val nodeName = node!!.nodeName()
+ val nodeAttributes = node.attributes()
+
+ if(nodeName in listOf("#document", "html", "head"))
+ return NodeFilter.FilterResult.CONTINUE
+
+ val body: String
+ val params: Map<String, String>
+
+
+ if(nodeName != "#text") {
+ body = ""
+ params = nodeAttributes.map { it.key to it.value }.toMap()
+ } else {
+ body = nodeAttributes["#text"]
+ params = emptyMap()
+ }
+
+ val docNode = if(depth < currentDepth) {
+ DocTagsFromStringFactory.getInstance(nodeName, nodesCache.getOrDefault(currentDepth, mutableListOf()).toList(), params, body).also {
+ nodesCache[currentDepth] = mutableListOf()
+ currentDepth = depth
+ }
+ } else {
+ DocTagsFromStringFactory.getInstance(nodeName, emptyList(), params, body)
+ }
+
+ nodesCache.getOrDefault(depth, mutableListOf()) += docNode
+ return NodeFilter.FilterResult.CONTINUE
+ }
+
+ override fun head(node: Node?, depth: Int): NodeFilter.FilterResult {
+
+ val nodeName = node!!.nodeName()
+
+ if(currentDepth < depth) {
+ currentDepth = depth
+ nodesCache[currentDepth] = mutableListOf()
+ }
+
+ if(nodeName in listOf("#document", "html", "head"))
+ return NodeFilter.FilterResult.CONTINUE
+
+ return NodeFilter.FilterResult.CONTINUE
+ }
+ }
+
+
+ private fun htmlToDocNode(string: String): DocTag {
+ val document = Jsoup.parse(string)
+ val nodeFilterImpl = NodeFilterImpl()
+ NodeTraversor.filter(nodeFilterImpl, document.root())
+ return nodeFilterImpl.collect()
+ }
+
+ private fun replaceLinksWithHrefs(javadoc: String): String = Regex("\\{@link .*?}").replace(javadoc) {
+ val split = it.value.dropLast(1).split(" ")
+ if(split.size !in listOf(2, 3))
+ return@replace it.value
+ if(split.size == 3)
+ return@replace "<documentationlink href=\"${split[1]}\">${split[2]}</documentationlink>"
+ else
+ return@replace "<documentationlink href=\"${split[1]}\">${split[1]}</documentationlink>"
+ }
+
+ override fun parseStringToDocNode(extractedString: String) = htmlToDocNode(extractedString)
+ override fun preparse(text: String) = replaceLinksWithHrefs(text)
+}
+
+