aboutsummaryrefslogtreecommitdiff
path: root/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt
diff options
context:
space:
mode:
authorVadim Mishenev <vad-mishenev@yandex.ru>2022-02-22 12:56:41 +0300
committerGitHub <noreply@github.com>2022-02-22 12:56:41 +0300
commitb9b1b588fad604c0cfc3e481f48338437dcaba5f (patch)
tree7c6a04d95f0f9b0c931b25dca91f1cf411f01105 /plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt
parentc44bf5487bd32f90a4576859548f1db0e9355a07 (diff)
downloaddokka-b9b1b588fad604c0cfc3e481f48338437dcaba5f.tar.gz
dokka-b9b1b588fad604c0cfc3e481f48338437dcaba5f.tar.bz2
dokka-b9b1b588fad604c0cfc3e481f48338437dcaba5f.zip
Fix HTML head and favicon in multi-module projects (#2365)
Diffstat (limited to 'plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt')
-rw-r--r--plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt60
1 files changed, 57 insertions, 3 deletions
diff --git a/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt b/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt
index 2b4951a1..7ef4cb10 100644
--- a/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt
+++ b/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt
@@ -1,13 +1,19 @@
package org.jetbrains.dokka.templates
import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.base.renderers.html.TEMPLATE_COMMAND_BEGIN_BORDER
+import org.jetbrains.dokka.base.renderers.html.TEMPLATE_COMMAND_END_BORDER
+import org.jetbrains.dokka.base.renderers.html.TEMPLATE_COMMAND_SEPARATOR
import org.jetbrains.dokka.base.templating.Command
import org.jetbrains.dokka.base.templating.parseJson
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.query
import org.jsoup.Jsoup
+import org.jsoup.nodes.Comment
import org.jsoup.nodes.Element
+import org.jsoup.nodes.Node
+import org.jsoup.nodes.TextNode
import java.io.File
import java.nio.file.Files
@@ -20,20 +26,68 @@ class DirectiveBasedHtmlTemplateProcessingStrategy(private val context: DokkaCon
if (input.isFile && input.extension == "html") {
val document = Jsoup.parse(input, "UTF-8")
document.outputSettings().indentAmount(0).prettyPrint(false)
+
document.select("dokka-template-command").forEach {
- handleCommand(it, parseJson(it.attr("data")), input, output)
+ handleCommandAsTag(it, parseJson(it.attr("data")), input, output)
+ }
+ extractCommandsFromComments(document) { command, body ->
+ val bodyTrimed =
+ body.dropWhile { node -> (node is TextNode && node.isBlank).also { if (it) node.remove() } }
+ .dropLastWhile { node -> (node is TextNode && node.isBlank).also { if (it) node.remove() } }
+ handleCommandAsComment(command, bodyTrimed, input, output)
}
+
Files.write(output.toPath(), listOf(document.outerHtml()))
true
} else false
- fun handleCommand(element: Element, command: Command, input: File, output: File) {
+ fun handleCommandAsTag(element: Element, command: Command, input: File, output: File) {
+ traverseHandlers(command) { handleCommandAsTag(command, element, input, output) }
+ }
+
+ fun handleCommandAsComment(command: Command, body: List<Node>, input: File, output: File) {
+ traverseHandlers(command) { handleCommandAsComment(command, body, input, output) }
+ }
+
+ private fun traverseHandlers(command: Command, action: CommandHandler.() -> Unit) {
val handlers = directiveBasedCommandHandlers.filter { it.canHandle(command) }
if (handlers.isEmpty())
context.logger.warn("Unknown templating command $command")
else
- handlers.forEach { it.handleCommand(element, command, input, output) }
+ handlers.forEach(action)
+ }
+ private fun extractCommandsFromComments(
+ node: Node,
+ startFrom: Int = 0,
+ handler: (command: Command, body: List<Node>) -> Unit
+ ) {
+ val nodes: MutableList<Node> = mutableListOf()
+ var lastStartBorder: Comment? = null
+ var firstStartBorder: Comment? = null
+ for (index in startFrom until node.childNodeSize()) {
+ when (val currentChild = node.childNode(index)) {
+ is Comment -> if (currentChild.data?.startsWith(TEMPLATE_COMMAND_BEGIN_BORDER) == true) {
+ lastStartBorder = currentChild
+ firstStartBorder = firstStartBorder ?: currentChild
+ nodes.clear()
+ } else if (lastStartBorder != null && currentChild.data?.startsWith(TEMPLATE_COMMAND_END_BORDER) == true) {
+ lastStartBorder.remove()
+ val cmd: Command? =
+ lastStartBorder.data?.removePrefix("$TEMPLATE_COMMAND_BEGIN_BORDER$TEMPLATE_COMMAND_SEPARATOR")?.let { parseJson(it) }
+ cmd?.let { handler(it, nodes) }
+ currentChild.remove()
+ extractCommandsFromComments(node, firstStartBorder?.siblingIndex() ?: 0, handler)
+ return
+ } else {
+ if (lastStartBorder != null) nodes.add(currentChild)
+ }
+ else -> {
+ extractCommandsFromComments(currentChild, handler = handler)
+ if (lastStartBorder != null) nodes.add(currentChild)
+ }
+ }
+ }
}
override fun finish(output: File) {