aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin/renderers/html/SearchbarDataInstaller.kt
blob: cd95013a309b5a322bca450da3ba562c1940350c (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
package org.jetbrains.dokka.base.renderers.html

import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.base.resolvers.local.LocationProvider
import org.jetbrains.dokka.model.DisplaySourceSet
import org.jetbrains.dokka.model.dfs
import org.jetbrains.dokka.pages.*

class SearchbarDataInstaller() {
    private val pageList = mutableMapOf<String, Pair<String, String>>()

    private fun String.escaped(): String = this.replace("'","\\'")

    fun generatePagesList(): String {
        return pageList.entries
            .filter { it.key.isNotEmpty() }
            .groupBy { it.key.substringAfterLast(".") }
            .entries
            .flatMapIndexed { topLevelIndex, entry ->
                entry.value.mapIndexed { index, subentry ->
                    "{\'name\': \'${subentry.value.first.escaped()}\', \'description\':\'${subentry.key.escaped()}\', \'location\':\'${subentry.value.second.escaped()}\', 'searchKey':'${entry.key.escaped()}'}"
                }
            }
            .joinToString(prefix = "[", separator = ",\n", postfix = "]")
    }


    private fun getSymbolSignature(page: ContentPage) = page.content.dfs { it.dci.kind == ContentKind.Symbol }

    private fun flattenToText(node: ContentNode): String {
        fun getContentTextNodes(node: ContentNode, sourceSetRestriction: DisplaySourceSet): List<ContentText> =
            when (node) {
                is ContentText -> listOf(node)
                is ContentComposite -> node.children
                    .filter { sourceSetRestriction in it.sourceSets }
                    .flatMap { getContentTextNodes(it, sourceSetRestriction) }
                    .takeIf { node.dci.kind != ContentKind.Annotations }
                    .orEmpty()
                else -> emptyList()
            }

        val sourceSetRestriction =
            node.sourceSets.find { it.platform == Platform.common } ?: node.sourceSets.first()
        return getContentTextNodes(node, sourceSetRestriction).joinToString("") { it.text }
    }

    fun processPage(page: ContentPage, link: String) {
        val signature = getSymbolSignature(page)
        val textNodes = signature?.let { flattenToText(it) }
        val documentable = page.documentable
        if (documentable != null) {
            listOf(
                documentable.dri.packageName,
                documentable.dri.classNames,
                documentable.dri.callable?.name
            )
                .filter { !it.isNullOrEmpty() }
                .takeIf { it.isNotEmpty() }
                ?.joinToString(".")
                ?.let {
                    pageList.put(it, Pair(textNodes ?: page.name, link))
                }

        }
    }


}