package org.jetbrains.dokka.base.renderers.html
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.model.DisplaySourceSet
import org.jetbrains.dokka.model.dfs
import org.jetbrains.dokka.pages.*
import java.util.concurrent.ConcurrentHashMap
data class SearchRecord(val name: String, val description: String? = null, val location: String, val searchKeys: List = listOf(name)) {
companion object { }
}
open class SearchbarDataInstaller {
private val mapper = jacksonObjectMapper()
private val pageList = ConcurrentHashMap>()
open fun generatePagesList(): String {
val pages = pageList.entries
.filter { it.key.isNotEmpty() }
.sortedWith(compareBy({ it.key }, { it.value.first }, { it.value.second }))
.groupBy { it.key.substringAfterLast(".") }
.entries
.flatMap { entry ->
entry.value.map { subentry ->
val name = subentry.value.first
createSearchRecord(
name = name,
description = subentry.key,
location = subentry.value.second,
searchKeys = listOf(entry.key, name)
)
}
}
return mapper.writeValueAsString(pages)
}
open fun createSearchRecord(name: String, description: String?, location: String, searchKeys: List): SearchRecord =
SearchRecord(name, description, location, searchKeys)
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 =
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 }
}
open 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 { id -> pageList.put(id, Pair(textNodes ?: page.name, link)) }
}
}
}