package org.jetbrains.dokka.base.renderers import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.links.parent import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.plugin import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.kotlin.utils.addToStdlib.safeAs class PackageListService(val context: DokkaContext) { fun formatPackageList(module: RootPageNode, format: String, linkExtension: String): String { val packages = mutableSetOf() val nonStandardLocations = mutableMapOf() val locationProvider = context.plugin().querySingle { locationProviderFactory }.getLocationProvider(module) fun visit(node: PageNode, parentDris: Set) { if (node is PackagePage) { node.name .takeUnless { name -> name.startsWith("[") && name.endsWith("]") } // Do not include the package name for declarations without one ?.let { packages.add(it) } } val contentPage = node.safeAs() contentPage?.dri?.forEach { if (parentDris.isNotEmpty() && it.parent !in parentDris) { locationProvider.resolve(node) ?.let { nodeLocation -> nonStandardLocations[it.toString()] = nodeLocation } ?: context.logger.error("Cannot resolve path for ${node.name}!") } } node.children.forEach { visit(it, contentPage?.dri ?: setOf()) } } visit(module, setOf()) return buildString { appendLine("$DOKKA_PARAM_PREFIX.format:${format}") appendLine("$DOKKA_PARAM_PREFIX.linkExtension:${linkExtension}") nonStandardLocations.map { (signature, location) -> "$DOKKA_PARAM_PREFIX.location:$signature\u001f$location" } .sorted().joinTo(this, separator = "\n", postfix = "\n") packages.sorted().joinTo(this, separator = "\n", postfix = "\n") } } companion object { const val DOKKA_PARAM_PREFIX = "\$dokka" } }