From 13b87181219f5a96e499c6bda230f6bcd2ed3bc0 Mon Sep 17 00:00:00 2001 From: Ignat Beresnev Date: Thu, 17 Feb 2022 14:51:14 +0300 Subject: Custom doctag extension (#2343) * Add an extension point for rendering custom doc tags * Iterate over documentable sourcesets when building custom tags * Extract a nested custom tags brief block into a separate method * Filter out tag content providers and make since kotlin brief a one-liner * Add padding to "Since Kotlin" block in brief description --- .../DefaultDocumentableToPageTranslator.kt | 14 +++-- .../documentables/DefaultPageCreator.kt | 59 +++++++++++++++------- 2 files changed, 49 insertions(+), 24 deletions(-) (limited to 'plugins/base/src/main/kotlin/translators/documentables') diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultDocumentableToPageTranslator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultDocumentableToPageTranslator.kt index 18647207..a385e0e4 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/DefaultDocumentableToPageTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultDocumentableToPageTranslator.kt @@ -4,10 +4,7 @@ import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.DokkaBaseConfiguration import org.jetbrains.dokka.model.DModule import org.jetbrains.dokka.pages.ModulePageNode -import org.jetbrains.dokka.plugability.configuration -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle +import org.jetbrains.dokka.plugability.* import org.jetbrains.dokka.transformers.documentation.DocumentableToPageTranslator class DefaultDocumentableToPageTranslator( @@ -16,8 +13,15 @@ class DefaultDocumentableToPageTranslator( private val configuration = configuration(context) private val commentsToContentConverter = context.plugin().querySingle { commentsToContentConverter } private val signatureProvider = context.plugin().querySingle { signatureProvider } + private val customTagContentProviders = context.plugin().query { customTagContentProvider } private val logger = context.logger override fun invoke(module: DModule): ModulePageNode = - DefaultPageCreator(configuration, commentsToContentConverter, signatureProvider, logger).pageForModule(module) + DefaultPageCreator( + configuration, + commentsToContentConverter, + signatureProvider, + logger, + customTagContentProviders + ).pageForModule(module) } \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt index c16996a0..946d6416 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt @@ -19,6 +19,7 @@ import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.base.DokkaBaseConfiguration import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint import org.jetbrains.dokka.base.transformers.documentables.ClashingDriIdentifier +import org.jetbrains.dokka.base.transformers.pages.tags.CustomTagContentProvider private typealias GroupedTags = Map, List>> @@ -29,7 +30,8 @@ open class DefaultPageCreator( configuration: DokkaBaseConfiguration?, commentsToContentConverter: CommentsToContentConverter, signatureProvider: SignatureProvider, - val logger: DokkaLogger + val logger: DokkaLogger, + val customTagContentProviders: List = emptyList() ) { protected open val contentBuilder = PageContentBuilder(commentsToContentConverter, signatureProvider, logger) @@ -341,6 +343,23 @@ open class DefaultPageCreator( } } + val customTags = d.customTags + if (customTags.isNotEmpty()) { + group(styles = setOf(TextStyle.Block)) { + platforms.forEach { platform -> + customTags.forEach { (tagName, sourceSetTag) -> + sourceSetTag[platform]?.let { tag -> + customTagContentProviders.filter { it.isApplicable(tag) }.forEach { provider -> + with(provider) { + contentForDescription(platform, tag) + } + } + } + } + } + } + } + val unnamedTags = tags.filterNot { (k, _) -> k.isSubclassOf(NamedTagWrapper::class) || k in specialTags } .values.flatten().groupBy { it.first }.mapValues { it.value.map { it.second } } if (unnamedTags.isNotEmpty()) { @@ -357,8 +376,6 @@ open class DefaultPageCreator( } } } - - contentForSinceKotlin(d) }.children } @@ -560,21 +577,6 @@ open class DefaultPageCreator( } ?: firstParagraphComment(tag.root) } - protected open fun DocumentableContentBuilder.contentForSinceKotlin(documentable: Documentable) { - documentable.documentation.mapValues { - it.value.children.find { it is CustomTagWrapper && it.name == "Since Kotlin" } as CustomTagWrapper? - }.run { - documentable.sourceSets.forEach { sourceSet -> - this[sourceSet]?.also { tag -> - group(sourceSets = setOf(sourceSet), kind = ContentKind.Comment, styles = setOf(TextStyle.Block)) { - header(4, tag.name) - comment(tag.root) - } - } - } - } - } - protected open fun contentForFunction(f: DFunction) = contentForMember(f) protected open fun contentForProperty(p: DProperty) = contentForMember(p) @@ -681,7 +683,7 @@ open class DefaultPageCreator( } after(extra = PropertyContainer.empty()) { contentForBrief(it) - contentForSinceKotlin(it) + contentForCustomTagsBrief(it) } } } @@ -692,6 +694,22 @@ open class DefaultPageCreator( } } + private fun DocumentableContentBuilder.contentForCustomTagsBrief(documentable: Documentable) { + val customTags = documentable.customTags + if (customTags.isEmpty()) return + + documentable.sourceSets.forEach { sourceSet -> + customTags.forEach { (tagName, sourceSetTag) -> + sourceSetTag[sourceSet]?.let { tag -> + customTagContentProviders.filter { it.isApplicable(tag) }.forEach { provider -> + with(provider) { + contentForBrief(sourceSet, tag) + } + } + } + } + } + } protected open fun TagWrapper.toHeaderString() = this.javaClass.toGenericString().split('.').last() @@ -706,6 +724,9 @@ open class DefaultPageCreator( private val Documentable.descriptions: SourceSetDependent get() = groupedTags.withTypeUnnamed() + private val Documentable.customTags: Map> + get() = groupedTags.withTypeNamed() + private val Documentable.hasSeparatePage: Boolean get() = this !is DTypeAlias -- cgit