diff options
| author | Błażej Kardyś <bkardys@virtuslab.com> | 2020-06-23 22:25:18 +0200 |
|---|---|---|
| committer | Paweł Marks <pmarks@virtuslab.com> | 2020-06-26 00:40:47 +0200 |
| commit | a1c316e829827ddb0e3e288e684ac287e8fd28ff (patch) | |
| tree | 0a421ff350f1018b6c57a0674142ec3da66d9c25 /plugins | |
| parent | fb9a5abfc24e93b918693f78a8f555da2c5a359f (diff) | |
| download | dokka-a1c316e829827ddb0e3e288e684ac287e8fd28ff.tar.gz dokka-a1c316e829827ddb0e3e288e684ac287e8fd28ff.tar.bz2 dokka-a1c316e829827ddb0e3e288e684ac287e8fd28ff.zip | |
Briefs raw rendering and basic url handling
Diffstat (limited to 'plugins')
15 files changed, 486 insertions, 426 deletions
diff --git a/plugins/base/.gitignore b/plugins/base/.gitignore index a259cd26..d68571db 100644 --- a/plugins/base/.gitignore +++ b/plugins/base/.gitignore @@ -1,2 +1,3 @@ src/main/resources/dokka/scripts/main.js -src/main/resources/dokka/scripts/main.js.map
\ No newline at end of file +src/main/resources/dokka/scripts/main.js.map +search-component/dist/
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt index 09d6cad1..4313f1e3 100644 --- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt @@ -104,7 +104,7 @@ abstract class DefaultRenderer<T>( is ContentHeader -> buildHeader(node, pageContext, sourceSetRestriction) is ContentCode -> buildCode(node, pageContext) is ContentDRILink -> - buildLink(locationProvider.resolve(node.address, node.sourceSets.toList(), pageContext)) { + buildLink(locationProvider.resolve(node.address, node.sourceSets, pageContext)) { buildLinkText(node.children, pageContext, sourceSetRestriction) } is ContentResolvedLink -> buildLink(node.address) { diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index d56ab50c..de892bb1 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -526,7 +526,7 @@ open class HtmlRenderer( platforms: List<DokkaSourceSet>, from: PageNode? = null, block: FlowContent.() -> Unit - ) = buildLink(locationProvider.resolve(to, platforms, from), block) + ) = buildLink(locationProvider.resolve(to, platforms.toSet(), from), block) override fun buildError(node: ContentNode) { context.logger.error("Unknown ContentNode type: $node") diff --git a/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt index 4d44fdef..6c4869d8 100644 --- a/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt +++ b/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt @@ -46,7 +46,7 @@ open class DefaultLocationProvider( override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean): String = pathTo(node, context) + if (!skipExtension) extension else "" - override fun resolve(dri: DRI, sourceSets: List<DokkaSourceSet>, context: PageNode?): String = + override fun resolve(dri: DRI, sourceSets: Set<DokkaSourceSet>, context: PageNode?): String = pagesIndex[dri]?.let { resolve(it, context) } ?: // Not found in PageGraph, that means it's an external link getLocation( diff --git a/plugins/base/src/main/kotlin/resolvers/local/LocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/LocationProvider.kt index d6d616f3..745636d0 100644 --- a/plugins/base/src/main/kotlin/resolvers/local/LocationProvider.kt +++ b/plugins/base/src/main/kotlin/resolvers/local/LocationProvider.kt @@ -6,7 +6,7 @@ import org.jetbrains.dokka.pages.PageNode import org.jetbrains.dokka.pages.RootPageNode interface LocationProvider { - fun resolve(dri: DRI, sourceSets: List<DokkaSourceSet>, context: PageNode? = null): String + fun resolve(dri: DRI, sourceSets: Set<DokkaSourceSet>, context: PageNode? = null): String fun resolve(node: PageNode, context: PageNode? = null, skipExtension: Boolean = false): String fun resolveRoot(node: PageNode): String fun ancestors(node: PageNode): List<PageNode> diff --git a/plugins/base/src/main/kotlin/resolvers/local/MultimoduleLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/MultimoduleLocationProvider.kt index 39b005a1..1d41bce0 100644 --- a/plugins/base/src/main/kotlin/resolvers/local/MultimoduleLocationProvider.kt +++ b/plugins/base/src/main/kotlin/resolvers/local/MultimoduleLocationProvider.kt @@ -14,7 +14,7 @@ class MultimoduleLocationProvider(private val root: RootPageNode, context: Dokka it.name to it.path }.toMap() - override fun resolve(dri: DRI, sourceSets: List<DokkaSourceSet>, context: PageNode?): String = + override fun resolve(dri: DRI, sourceSets: Set<DokkaSourceSet>, context: PageNode?): String = dri.takeIf { it.packageName == MULTIMODULE_PACKAGE_PLACEHOLDER }?.classNames?.let { paths[it] }?.let { "$it/${dri.classNames}/index.html" } ?: defaultLocationProvider.resolve(dri, sourceSets, context) diff --git a/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt b/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt index f8ecf868..d731ec5f 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt @@ -65,7 +65,7 @@ class JavadocLocationProvider(pageRoot: RootPageNode, private val context: Dokka private operator fun IdentityHashMap<PageNode, List<String>>.get(dri: DRI) = this[nodeIndex[dri]] - override fun resolve(dri: DRI, sourceSets: List<DokkaSourceSet>, context: PageNode?): String = + override fun resolve(dri: DRI, sourceSets: Set<DokkaSourceSet>, context: PageNode?): String = context?.let { resolve(it, skipExtension = false) } ?: nodeIndex[dri]?.let { resolve(it, skipExtension = true) } ?: with(externalLocationProvider!!) { diff --git a/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt b/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt index 3074a760..12c53ab7 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt @@ -39,19 +39,19 @@ open class JavadocPageCreator( ) fun pageForClasslike(c: DClasslike): JavadocClasslikePageNode? = - c.mostTopSourceSet?.let { jvm -> + c.highestJvmSourceSet?.let { jvm -> JavadocClasslikePageNode( name = c.name.orEmpty(), content = contentForClasslike(c), dri = setOf(c.dri), modifiers = listOfNotNull(c.visibility[jvm]?.name), - signature = signatureProvider.signature(c).jvmSignature(), + signature = signatureProvider.signature(c).nodeForJvm(jvm), description = c.descriptionToContentNodes(), constructors = c.safeAs<WithConstructors>()?.constructors?.map { it.toJavadocFunction(jvm) }.orEmpty(), methods = c.functions.map { it.toJavadocFunction(jvm) }, - entries = c.safeAs<DEnum>()?.entries?.map { JavadocEntryNode(signatureProvider.signature(it).jvmSignature(), it.descriptionToContentNodes(jvm)) }.orEmpty(), + entries = c.safeAs<DEnum>()?.entries?.map { JavadocEntryNode(signatureProvider.signature(it).nodeForJvm(jvm), it.descriptionToContentNodes(jvm)) }.orEmpty(), classlikes = c.classlikes.mapNotNull { pageForClasslike(it) }, - properties = c.properties.map { JavadocPropertyNode(signatureProvider.signature(it).jvmSignature(), it.descriptionToContentNodes(jvm)) }, + properties = c.properties.map { JavadocPropertyNode(signatureProvider.signature(it).nodeForJvm(jvm), it.descriptionToContentNodes(jvm)) }, documentable = c, extras = c.safeAs<WithExtraProperties<Documentable>>()?.extra ?: PropertyContainer.empty() ) @@ -129,7 +129,7 @@ open class JavadocPageCreator( private fun DFunction.toJavadocFunction(sourceSetData: DokkaSourceSet) = JavadocFunctionNode( name = name, - signature = signatureProvider.signature(this).jvmSignature(), + signature = signatureProvider.signature(this).nodeForJvm(sourceSetData), brief = brief(sourceSetData), parameters = parameters.map { JavadocParameterNode( @@ -141,21 +141,20 @@ open class JavadocPageCreator( extras = extra ) - // THIS MUST BE DISCUSSED private val Documentable.jvmSource get() = sourceSets.filter { it.analysisPlatform == Platform.jvm } - private val Documentable.mostTopSourceSet + private val Documentable.highestJvmSourceSet get() = jvmSource.let { sources -> sources.firstOrNull { it != expectPresentInSet } ?: sources.firstOrNull() } private val firstSentenceRegex = Regex("^((?:[^.?!]|[.!?](?!\\s))*[.!?])") - private inline fun <reified T: TagWrapper> Documentable.findNodeInDocumentation(sourceSetData: SourceSetData?): T? = + private inline fun <reified T: TagWrapper> Documentable.findNodeInDocumentation(sourceSetData: DokkaSourceSet?): T? = documentation[sourceSetData]?.firstChildOfType<T>() - private fun Documentable.descriptionToContentNodes(sourceSet: SourceSetData? = mostTopSourceSet) = findNodeInDocumentation<Description>(sourceSet)?.let { + private fun Documentable.descriptionToContentNodes(sourceSet: DokkaSourceSet? = highestJvmSourceSet) = findNodeInDocumentation<Description>(sourceSet)?.let { DocTagToContentConverter.buildContent( it.root, DCI(setOf(dri), JavadocContentKind.OverviewSummary), @@ -163,7 +162,10 @@ open class JavadocPageCreator( ) }.orEmpty() - private fun Documentable.brief(sourceSet: SourceSetData? = mostTopSourceSet): List<ContentNode> { + fun List<ContentNode>.nodeForJvm(jvm: DokkaSourceSet): ContentNode = + first { it.sourceSets.contains(jvm) } + + private fun Documentable.brief(sourceSet: DokkaSourceSet? = highestJvmSourceSet): List<ContentNode> { val description = descriptionToContentNodes(sourceSet) val contents = mutableListOf<ContentNode>() for (node in description) { diff --git a/plugins/javadoc/src/main/kotlin/javadoc/JavadocPlugin.kt b/plugins/javadoc/src/main/kotlin/javadoc/JavadocPlugin.kt index a90e46db..504eecfd 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/JavadocPlugin.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/JavadocPlugin.kt @@ -1,7 +1,7 @@ package org.jetbrains.dokka.javadoc import javadoc.JavadocDocumentableToPageTranslator -import javadoc.KorteJavadocRenderer +import javadoc.renderer.KorteJavadocRenderer import org.jetbrains.dokka.CoreExtensions import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.plugability.DokkaPlugin @@ -12,7 +12,11 @@ class JavadocPlugin : DokkaPlugin() { val dokkaJavadocPlugin by extending { val dokkaBasePlugin = plugin<DokkaBase>() CoreExtensions.renderer providing { ctx -> - KorteJavadocRenderer(dokkaBasePlugin.querySingle { outputWriter }, ctx, "views") + KorteJavadocRenderer( + dokkaBasePlugin.querySingle { outputWriter }, + ctx, + "views" + ) } applyIf { format == "javadoc" } } diff --git a/plugins/javadoc/src/main/kotlin/javadoc/KorteJavadocRenderer.kt b/plugins/javadoc/src/main/kotlin/javadoc/KorteJavadocRenderer.kt index cec5bbca..e69de29b 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/KorteJavadocRenderer.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/KorteJavadocRenderer.kt @@ -1,402 +0,0 @@ -package javadoc - -import com.soywiz.korte.* -import javadoc.pages.* -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.base.renderers.OutputWriter -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.links.sureClassNames -import org.jetbrains.dokka.model.ImplementedInterfaces -import org.jetbrains.dokka.model.InheritedFunction -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.pages.* -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.renderers.Renderer -import org.jetbrains.kotlin.utils.addToStdlib.safeAs -import java.nio.file.Path -import java.nio.file.Paths -import java.time.LocalDate - -typealias TemplateMap = Map<String, Any?> - -class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaContext, val resourceDir: String) : - Renderer { - private lateinit var locationProvider: JavadocLocationProvider - - override fun render(root: RootPageNode) = root.let { preprocessors.fold(root) { r, t -> t.invoke(r) } }.let { r -> - locationProvider = JavadocLocationProvider(r, context) - runBlocking(Dispatchers.IO) { - renderModulePageNode(r as JavadocModulePageNode) - } - } - - private fun templateForNode(node: JavadocPageNode) = when (node) { - is JavadocClasslikePageNode -> "class.korte" - is JavadocPackagePageNode -> "tabPage.korte" - is JavadocModulePageNode -> "tabPage.korte" - is AllClassesPage -> "listPage.korte" - is TreeViewPage -> "treePage.korte" - else -> "" - } - - private fun CoroutineScope.renderNode(node: PageNode, path: String = "") { - if (node is JavadocPageNode) { - renderJavadocNode(node) - } else if (node is RendererSpecificPage) { - renderSpecificPage(node, path) - } - } - - private fun CoroutineScope.renderModulePageNode(node: JavadocModulePageNode) { - val link = "." - val name = "index" - val pathToRoot = "" - - val contentMap = mapOf<String, Any?>( - "docName" to "docName", // todo docname - "pathToRoot" to pathToRoot, - "kind" to "main", - ) + ContentNodesRenderer(pathToRoot).renderJavadocContentNode(node.content) - - writeFromTemplate(outputWriter, "$link/$name".toNormalized(), "tabPage.korte", contentMap.toList()) - node.children.forEach { renderNode(it, link) } - } - - private fun CoroutineScope.renderJavadocNode(node: JavadocPageNode) { - val link = locationProvider.resolve(node, skipExtension = true) - val dir = Paths.get(link).parent?.let { it.toNormalized() }.orEmpty() - val pathToRoot = dir.split("/").filter { it.isNotEmpty() }.joinToString("/") { ".." }.let { - if (it.isNotEmpty()) "$it/" else it - } - - val contentMap = mapOf( - "docName" to "docName", // todo docname - "pathToRoot" to pathToRoot, - "dir" to dir - ) + ContentNodesRenderer(dir).renderContentNodes(node) - writeFromTemplate(outputWriter, link, templateForNode(node), contentMap.toList()) - node.children.forEach { renderNode(it, link.toNormalized()) } - } - - fun CoroutineScope.renderSpecificPage(node: RendererSpecificPage, path: String) = launch { - when (val strategy = node.strategy) { - is RenderingStrategy.Copy -> outputWriter.writeResources(strategy.from, "") - is RenderingStrategy.Write -> outputWriter.writeHtml(path, strategy.text) - is RenderingStrategy.Callback -> outputWriter.writeResources( - path, - strategy.instructions(this@KorteJavadocRenderer, node) - ) - RenderingStrategy.DoNothing -> Unit - } - } - - fun Pair<String, String>.pairToTag() = - "\n<th class=\"colFirst\" scope=\"row\">${first}</th>\n<td class=\"colLast\">${second}</td>" - - fun DRI.toLink(context: PageNode? = null) = locationProvider.resolve(this, emptyList(), context) - - fun createLinkTag(address: String, name: String) = - address.let { if (it.endsWith(".html")) it else "$it.html" }.let { - """<a href="$it">$name</a>""" - } - - private fun Path.toNormalized() = this.normalize().toFile().toString() - private fun String.toNormalized() = Paths.get(this).toNormalized() - private fun String.relativizePath(parent: String) = Paths.get(parent).relativize(Paths.get(this)).toNormalized() - - private suspend fun OutputWriter.writeHtml(path: String, text: String) = write(path, text, ".html") - private fun CoroutineScope.writeFromTemplate( - writer: OutputWriter, - path: String, - template: String, - args: List<Pair<String, *>> - ) = launch { - val tmp = templateRenderer.render(template, *(args.toTypedArray())) - writer.writeHtml(path, tmp) - } - - private fun htmlForContentNodes(content: List<ContentNode>, render: (ContentNode) -> String): String = - content.joinToString("") { render(it) } - - fun getTemplateConfig() = TemplateConfig().also { config -> - listOf( - TeFunction("curDate") { LocalDate.now() }, - TeFunction("jQueryVersion") { "3.1" }, - TeFunction("jQueryMigrateVersion") { "1.2.1" }, - TeFunction("rowColor") { args -> if ((args.first() as Int) % 2 == 0) "altColor" else "rowColor" }, - TeFunction("h1Title") { args -> if ((args.first() as? String) == "package") "title=\"Package\" " else "" }, - TeFunction("createTabRow") { args -> - val (link, doc) = args.first() as RowJavadocListEntry - val dir = args[1] as String? - val renderer = ContentNodesRenderer(dir) - (createLinkTag( - locationProvider.resolve(link, dir.orEmpty()), - link.name - ) to htmlForContentNodes(doc, renderer::htmlForContentNode)).pairToTag().trim() - }, - TeFunction("createListRow") { args -> - val link = args.first() as LinkJavadocListEntry - val dir = args[1] as String? - createLinkTag(locationProvider.resolve(link, dir.orEmpty()), link.name) - }, - TeFunction("createPackageHierarchy") { args -> - val list = args.first() as List<JavadocPackagePageNode> - list.mapIndexed { i, p -> - val content = if (i + 1 == list.size) "" else ", " - val name = p.name - "<li><a href=\"$name/package-tree.html\">$name</a>$content</li>" - }.joinToString("\n") - }, - TeFunction("renderInheritanceGraph") { args -> - val rootNodes = args.first() as List<TreeViewPage.InheritanceNode> - - fun drawRec(node: TreeViewPage.InheritanceNode): String { - val returnValue = "<li class=\"circle\">" + node.dri.let { dri -> - listOfNotNull( - dri.packageName, - dri.classNames - ).joinToString(".") + node.interfaces.takeUnless { node.isInterface || it.isEmpty() } - ?.let { - " implements " + it.joinToString(", ") { n -> - listOfNotNull( - n.packageName, - createLinkTag(n.toLink(), n.classNames.orEmpty()) - ).joinToString(".") - } - }.orEmpty() - } + node.children.filterNot { it.isInterface }.takeUnless { it.isEmpty() }?.let { - "<ul>" + it.joinToString("\n", transform = ::drawRec) + "</ul>" - }.orEmpty() + "</li>" - return returnValue - } - rootNodes.joinToString { drawRec(it) } - }, - Filter("length") { subject.dynamicLength() }, - TeFunction("hasAnyDescription") { args -> - args.first().safeAs<List<HashMap<String, String>>>() - ?.any { it["description"]?.trim()?.isNotEmpty() ?: false } - } - ).forEach { - when (it) { - is TeFunction -> config.register(it) - is Filter -> config.register(it) - is Tag -> config.register(it) - } - } - } - - val config = getTemplateConfig() - val templateRenderer = Templates(ResourceTemplateProvider(resourceDir), config = config, cache = true) - - class ResourceTemplateProvider(val basePath: String) : TemplateProvider { - override suspend fun get(template: String): String = - javaClass.classLoader.getResourceAsStream("$basePath/$template")?.bufferedReader()?.lines()?.toArray() - ?.joinToString("\n") ?: throw IllegalStateException("Template not found: $basePath/$template") - } - - private inner class ContentNodesRenderer(private val currentLocation: String?) { - fun renderContentNodes(node: JavadocPageNode): TemplateMap = - when (node) { - is JavadocClasslikePageNode -> renderClasslikeNode(node) - is JavadocFunctionNode -> renderFunctionNode(node) - is JavadocPackagePageNode -> renderPackagePageNode(node) - is TreeViewPage -> renderTreeViewPage(node) - is AllClassesPage -> renderAllClassesPage(node) - else -> emptyMap() - } - - - private fun renderAllClassesPage(node: AllClassesPage): TemplateMap { - return mapOf( - "title" to "All Classes", - "list" to node.classEntries - ) - } - - private fun renderTreeViewPage(node: TreeViewPage): TemplateMap { - return mapOf( - "title" to node.title, - "name" to node.name, - "kind" to node.kind, - "list" to node.packages.orEmpty() + node.classes.orEmpty(), - "classGraph" to node.classGraph, - "interfaceGraph" to node.interfaceGraph - ) - } - - private fun renderPackagePageNode(node: JavadocPackagePageNode): TemplateMap { - return mapOf( - "kind" to "package" - ) + renderJavadocContentNode(node.content) - } - - private fun renderFunctionNode(node: JavadocFunctionNode): TemplateMap { - val (modifiers, signature) = node.modifiersAndSignature - return mapOf( - "signature" to htmlForContentNode(node.signature), - "brief" to htmlForContentNodes(node.brief), - "parameters" to node.parameters.map { renderParameterNode(it) }, - "inlineParameters" to node.parameters.joinToString { "${it.type} ${it.name}" }, - "modifiers" to htmlForContentNode(modifiers), - "signatureWithoutModifiers" to htmlForContentNode(signature), - "name" to node.name - ) - } - - private fun renderParameterNode(node: JavadocParameterNode): TemplateMap = - mapOf( - "description" to htmlForContentNodes(node.description), - "name" to node.name, - "type" to node.type - ) - - private fun renderClasslikeNode(node: JavadocClasslikePageNode): TemplateMap = - mapOf( - "constructors" to node.constructors.map { renderContentNodes(it) }, - "signature" to htmlForContentNode(node.signature), - "methods" to renderClasslikeMethods(node.methods), - "classlikeDocumentation" to renderContentNodes(node.description), - "entries" to node.entries.map { renderEntryNode(it) }, - "properties" to node.properties.map { renderPropertyNode(it) }, - "classlikes" to node.classlikes.map { renderNestedClasslikeNode(it) }, - "implementedInterfaces" to renderImplementedInterfaces(node), - "kind" to node.kind, - "packageName" to node.packageName, - "name" to node.name - ) + renderJavadocContentNode(node.content) - - private fun renderImplementedInterfaces(node: JavadocClasslikePageNode) = - node.extras[ImplementedInterfaces]?.interfaces?.entries?.firstOrNull { it.key.analysisPlatform == Platform.jvm }?.value?.map { it.displayable() } // TODO: REMOVE HARDCODED JVM DEPENDENCY - .orEmpty() - - private fun renderClasslikeMethods(nodes: List<JavadocFunctionNode>): TemplateMap { - val (inherited, own) = nodes.partition { - val extra = it.extras[InheritedFunction] - extra?.inheritedFrom?.keys?.first { it.analysisPlatform == Platform.jvm }?.let { jvm -> - extra.isInherited(jvm) - } ?: false - } - return mapOf( - "own" to own.map { renderContentNodes(it) }, - "inherited" to inherited.map { renderInheritedMethod(it) } - .groupBy { it["inheritedFrom"] as String }.entries.map { - mapOf( - "inheritedFrom" to it.key, - "names" to it.value.map { it["name"] as String }.sorted().joinToString() - ) - } - ) - } - - private fun renderInheritedMethod(node: JavadocFunctionNode): TemplateMap { - val inheritedFrom = node.extras[InheritedFunction]?.inheritedFrom - return mapOf( - "inheritedFrom" to inheritedFrom?.entries?.firstOrNull { it.key.analysisPlatform == Platform.jvm }?.value?.displayable() // TODO: REMOVE HARDCODED JVM DEPENDENCY - .orEmpty(), - "name" to node.name - ) - } - - private fun renderNestedClasslikeNode(node: JavadocClasslikePageNode): TemplateMap { - return mapOf( - "modifiers" to (node.modifiers + "static" + node.kind).joinToString(separator = " "), - "signature" to node.name, - "description" to renderContentNodes(node.description) - ) - } - - private fun renderPropertyNode(node: JavadocPropertyNode): TemplateMap { - val (modifiers, signature) = node.modifiersAndSignature - return mapOf( - "modifiers" to htmlForContentNode(modifiers), - "signature" to htmlForContentNode(signature), - "description" to htmlForContentNodes(node.brief) - ) - } - - private fun renderEntryNode(node: JavadocEntryNode): TemplateMap { - return mapOf( - "signature" to htmlForContentNode(node.signature), - "brief" to node.brief - ) - } - - private fun renderContentNodes(nodes: List<ContentNode>): String = nodes.joinToString(separator = "") { htmlForContentNode(it) } - - fun htmlForContentNode(node: ContentNode): String = - when (node) { - is ContentGroup -> node.children.joinToString(separator = "") { htmlForContentNode(it) } - is ContentText -> node.text - is TextNode -> node.text - is ContentDRILink -> """<a href="${resolveLink( - node.address, - node.sourceSets - )}">${node.children.joinToString { htmlForContentNode(it) }} </a>""".trimMargin() - is ContentCode -> renderCode(node.children) - else -> "" - } - - private fun renderCode(code: List<ContentNode>) : String = code.map { element -> - when (element) { - is ContentText -> element.text - is ContentBreakLine -> "" - else -> run { context.logger.error("Cannot cast $element as ContentText!"); "" } - } - }.joinToString("<br>", "<span class=\"code\">", "</span>") { it } - - fun renderJavadocContentNode(node: JavadocContentNode): TemplateMap = when (node) { - is TitleNode -> renderTitleNode(node) - is JavadocContentGroup -> renderJavadocContentGroup(node) - is TextNode -> renderTextNode(node) - is ListNode -> renderListNode(node) - else -> emptyMap() - } - - private fun renderTitleNode(node: TitleNode): TemplateMap { - return mapOf( - "title" to node.title, - "subtitle" to htmlForContentNodes(node.subtitle), - "version" to node.version, - "packageName" to node.parent - ) - } - - private fun renderJavadocContentGroup(note: JavadocContentGroup): TemplateMap { - return note.children.fold(emptyMap<String, Any?>()) { map, child -> - map + renderJavadocContentNode(child) - } - } - - private fun renderTextNode(node: TextNode): TemplateMap { - return mapOf("text" to node.text) - } - - private fun renderListNode(node: ListNode): TemplateMap { - return mapOf( - "tabTitle" to node.tabTitle, - "colTitle" to node.colTitle, - "list" to node.children - ) - } - - private fun resolveLink(address: DRI, sourceSets: Set<DokkaSourceSet>) = - locationProvider.resolve(address, sourceSets.toList()).let { - val afterFormattingToHtml = formatToEndWithHtml(it) - if (currentLocation != null) afterFormattingToHtml.relativizePath(currentLocation) - else afterFormattingToHtml - } - - private fun formatToEndWithHtml(address: String) = - if (address.endsWith(".html")) { - address - } else { - "$address.html" - } - - private fun DRI.displayable(): String = "${packageName}.${sureClassNames}" - } -}
\ No newline at end of file diff --git a/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToHtmlTranslator.kt b/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToHtmlTranslator.kt new file mode 100644 index 00000000..5f628626 --- /dev/null +++ b/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToHtmlTranslator.kt @@ -0,0 +1,66 @@ +package javadoc.renderer + +import javadoc.pages.TextNode +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.base.resolvers.local.LocationProvider +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.pages.* +import org.jetbrains.dokka.plugability.DokkaContext +import java.nio.file.Path +import java.nio.file.Paths + +internal class JavadocContentToHtmlTranslator( + private val locationProvider: LocationProvider, + private val context: DokkaContext +) { + + fun <T> htmlForContentNode(node: ContentNode, relative: T?, locate: ContentDRILink.(T?) -> String): String = + when (node) { + is ContentGroup -> htmlForContentNodes(node.children, relative, locate) + is ContentText -> node.text + is TextNode -> node.text + is ContentDRILink -> buildLink( + node.locate(relative), + htmlForContentNodes(node.children, relative, locate) + ) + is ContentResolvedLink -> buildLink(node.address, htmlForContentNodes(node.children, relative, locate)) + is ContentCode -> htmlForCode(node.children) + else -> "" + } + + fun <T> htmlForContentNodes(list: List<ContentNode>, relative: T?, locate: ContentDRILink.(T?) -> String) = + list.joinToString(separator = "") { htmlForContentNode(it, relative, locate) } + + private fun locate(link: ContentDRILink, relativePath: String?) = + resolveLink(link.address, link.sourceSets, relativePath) + + fun htmlForContentNodes(list: List<ContentNode>, relative: String?) = + htmlForContentNodes(list, relative, ::locate) + + private fun htmlForCode(code: List<ContentNode>): String = code.map { element -> + when (element) { + is ContentText -> element.text + is ContentBreakLine -> "" + else -> run { context.logger.error("Cannot cast $element as ContentText!"); "" } + } + }.joinToString("<br>", """<span class="code">""", "</span>") { it } + + private fun resolveLink(address: DRI, sourceSets: Set<DokkaConfiguration.DokkaSourceSet>, relativePath: String?) = + locationProvider.resolve(address, sourceSets).let { + val afterFormattingToHtml = it.formatToEndWithHtml() + if (relativePath != null) afterFormattingToHtml.relativizePath(relativePath) + else afterFormattingToHtml + } + + private fun String.relativizePath(parent: String) = + Paths.get(parent).relativize(Paths.get(this)).normalize().toFile().toString() + + companion object { + + fun buildLink(address: String, content: String) = + """<a href=${address.formatToEndWithHtml()}>$content</a>""" + + private fun String.formatToEndWithHtml() = + if (endsWith(".html")) this else "$this.html" + } +}
\ No newline at end of file diff --git a/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt b/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt new file mode 100644 index 00000000..4d1ccca5 --- /dev/null +++ b/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt @@ -0,0 +1,203 @@ +package javadoc.renderer + +import javadoc.pages.* +import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.base.resolvers.local.LocationProvider |
