aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/renderers/HtmlRenderer.kt
blob: adc3dd5af88ca45f674a8e553e9e748ee7dc84e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package org.jetbrains.dokka.renderers

import org.jetbrains.dokka.htmlEscape
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.resolvers.LocationProvider
import java.io.File

open class HtmlRenderer(fileWriter: FileWriter, locationProvider: LocationProvider) : DefaultRenderer(fileWriter, locationProvider) {

    override fun buildList(node: ContentList, pageContext: PageNode): String = if (node.ordered) {
        "<ol>${buildListItems(node.children, pageContext)}</ol>"
    } else {
        "<ul>${buildListItems(node.children, pageContext)}</ul>"
    }

    protected open fun buildListItems(items: List<ContentNode>, pageContext: PageNode) =
        "<li>\n${items.joinToString("\n</li>\n<li>\n") { it.build(pageContext) }}\n</li>"

    override fun buildResource(node: ContentEmbeddedResource, pageContext: PageNode): String { // TODO: extension point there
        val imageExtensions = setOf("png", "jpg", "jpeg", "gif", "bmp", "tif", "webp", "svg")
        return if (File(node.address).extension.toLowerCase() in imageExtensions) {
            val imgAttrs = node.extras.filterIsInstance<HTMLSimpleAttr>().joinAttr()
            """<img src="${node.address}" alt="${node.altText}" $imgAttrs>"""
        } else {
            println("Unrecognized resource type: $node")
            ""
        }
    }

    override fun buildTable(node: ContentTable, pageContext: PageNode): String {
        val tableHeader =
            """<thead>
                |<tr>
                |<th> ${node.header.joinToString("<th>\n</tr>\n<tr>\n<th>") { it.build(pageContext) }} </th>
                |</tr>
                |</thead>""".trimMargin()

        return """<table>```
            |$tableHeader
            |<tbody>
            |<tr>
            |<td>${node.children.joinToString("<td>\n</tr>\n<tr>\n<td>") { it.build(pageContext) }}</td>
            |</tr>
            |</tbody>
            |</table>""".trimMargin()
    }

    override fun buildHeader(level: Int, text: String): String = "<h$level>$text</h$level>\n"

    override fun buildNewLine(): String = "<br/>"

    override fun buildLink(text: String, address: String): String = "<a href=\"$address\">${text.htmlEscape()}</a>"

    override fun buildCode(code: List<ContentNode>, language: String, pageContext: PageNode): String = "<code>$code</code>"

    override fun buildText(textNode: ContentText): String = super.buildText(textNode).htmlEscape()

    override fun renderPage(page: PageNode) {
        val pageText = buildStartHtml(page) + buildPageContent(page) + buildEndHtml()
        fileWriter.write(locationProvider.resolve(page), pageText, "")
    }

    override fun buildSupportFiles() { // TODO copy file instead of reading
        fileWriter.write(
            "style.css",
            javaClass.getResourceAsStream("/dokka/styles/style.css").reader().readText()
        )
    }

    protected open fun buildStartHtml(page: PageNode) = """<!DOCTYPE html>
        |<html>
        |<head>
        |<title>${page.name}</title>
        |<link rel="stylesheet" href="${locationProvider.resolveRoot(page)}style.css" />
        |</head>
        |<body>
        |""".trimMargin()

    protected open fun buildEndHtml() =
        """
        |
        |</body>
        |</html>
    """.trimMargin()

    protected open fun List<HTMLMetadata>.joinAttr() = this.joinToString(" ") { it.key + "=" + it.value }
}