aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin/renderers
diff options
context:
space:
mode:
authorIgnat Beresnev <ignat.beresnev@jetbrains.com>2023-11-10 11:46:54 +0100
committerGitHub <noreply@github.com>2023-11-10 11:46:54 +0100
commit8e5c63d035ef44a269b8c43430f43f5c8eebfb63 (patch)
tree1b915207b2b9f61951ddbf0ff2e687efd053d555 /plugins/base/src/main/kotlin/renderers
parenta44efd4ba0c2e4ab921ff75e0f53fc9335aa79db (diff)
downloaddokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.gz
dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.bz2
dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.zip
Restructure the project to utilize included builds (#3174)
* Refactor and simplify artifact publishing * Update Gradle to 8.4 * Refactor and simplify convention plugins and build scripts Fixes #3132 --------- Co-authored-by: Adam <897017+aSemy@users.noreply.github.com> Co-authored-by: Oleg Yukhnevich <whyoleg@gmail.com>
Diffstat (limited to 'plugins/base/src/main/kotlin/renderers')
-rw-r--r--plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt257
-rw-r--r--plugins/base/src/main/kotlin/renderers/FileWriter.kt109
-rw-r--r--plugins/base/src/main/kotlin/renderers/OutputWriter.kt11
-rw-r--r--plugins/base/src/main/kotlin/renderers/PackageListService.kt80
-rw-r--r--plugins/base/src/main/kotlin/renderers/TabSortingStrategy.kt11
-rw-r--r--plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt24
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/HtmlContent.kt18
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt1013
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/NavigationDataProvider.kt134
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/NavigationPage.kt129
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/SearchbarDataInstaller.kt128
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/Tags.kt82
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/command/consumers/ImmediateResolutionTagConsumer.kt37
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/command/consumers/PathToRootConsumer.kt26
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/command/consumers/ReplaceVersionsConsumer.kt29
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/command/consumers/ResolveLinkConsumer.kt34
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/htmlFormatingUtils.kt67
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt172
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/innerTemplating/DefaultTemplateModelFactory.kt234
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/innerTemplating/DefaultTemplateModelMerger.kt20
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/innerTemplating/HtmlTemplater.kt82
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/innerTemplating/TemplateModelFactory.kt19
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/innerTemplating/TemplateModelMerger.kt9
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/shouldRenderSourceSetBubbles.kt20
-rw-r--r--plugins/base/src/main/kotlin/renderers/pageId.kt31
-rw-r--r--plugins/base/src/main/kotlin/renderers/preprocessors.kt41
26 files changed, 0 insertions, 2817 deletions
diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
deleted file mode 100644
index eed7794e..00000000
--- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.renderers
-
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import org.jetbrains.dokka.DokkaException
-import org.jetbrains.dokka.base.DokkaBase
-import org.jetbrains.dokka.base.resolvers.local.LocationProvider
-import org.jetbrains.dokka.model.DisplaySourceSet
-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.dokka.renderers.Renderer
-import org.jetbrains.dokka.transformers.pages.PageTransformer
-
-public abstract class DefaultRenderer<T>(
- protected val context: DokkaContext
-) : Renderer {
-
- protected val outputWriter: OutputWriter = context.plugin<DokkaBase>().querySingle { outputWriter }
-
- protected lateinit var locationProvider: LocationProvider
- private set
-
- protected open val preprocessors: Iterable<PageTransformer> = emptyList()
-
- public abstract fun T.buildHeader(level: Int, node: ContentHeader, content: T.() -> Unit)
- public abstract fun T.buildLink(address: String, content: T.() -> Unit)
- public abstract fun T.buildList(
- node: ContentList,
- pageContext: ContentPage,
- sourceSetRestriction: Set<DisplaySourceSet>? = null
- )
-
- public abstract fun T.buildLineBreak()
- public open fun T.buildLineBreak(node: ContentBreakLine, pageContext: ContentPage) {
- buildLineBreak()
- }
-
- public abstract fun T.buildResource(node: ContentEmbeddedResource, pageContext: ContentPage)
- public abstract fun T.buildTable(
- node: ContentTable,
- pageContext: ContentPage,
- sourceSetRestriction: Set<DisplaySourceSet>? = null
- )
-
- public abstract fun T.buildText(textNode: ContentText)
- public abstract fun T.buildNavigation(page: PageNode)
-
- public abstract fun buildPage(page: ContentPage, content: (T, ContentPage) -> Unit): String
- public abstract fun buildError(node: ContentNode)
-
- public open fun T.buildPlatformDependent(
- content: PlatformHintedContent,
- pageContext: ContentPage,
- sourceSetRestriction: Set<DisplaySourceSet>?
- ) {
- buildContentNode(content.inner, pageContext)
- }
-
- public open fun T.buildGroup(
- node: ContentGroup,
- pageContext: ContentPage,
- sourceSetRestriction: Set<DisplaySourceSet>? = null
- ) {
- wrapGroup(node, pageContext) { node.children.forEach { it.build(this, pageContext, sourceSetRestriction) } }
- }
-
- public open fun T.buildDivergent(node: ContentDivergentGroup, pageContext: ContentPage) {
- node.children.forEach { it.build(this, pageContext) }
- }
-
- public open fun T.wrapGroup(node: ContentGroup, pageContext: ContentPage, childrenCallback: T.() -> Unit) {
- childrenCallback()
- }
-
- public open fun T.buildText(
- nodes: List<ContentNode>,
- pageContext: ContentPage,
- sourceSetRestriction: Set<DisplaySourceSet>? = null
- ) {
- nodes.forEach { it.build(this, pageContext, sourceSetRestriction) }
- }
-
- public open fun T.buildCodeBlock(code: ContentCodeBlock, pageContext: ContentPage) {
- code.children.forEach { it.build(this, pageContext) }
- }
-
- public open fun T.buildCodeInline(code: ContentCodeInline, pageContext: ContentPage) {
- code.children.forEach { it.build(this, pageContext) }
- }
-
- public open fun T.buildHeader(
- node: ContentHeader,
- pageContext: ContentPage,
- sourceSetRestriction: Set<DisplaySourceSet>? = null
- ) {
- buildHeader(node.level, node) { node.children.forEach { it.build(this, pageContext, sourceSetRestriction) } }
- }
-
- public open fun ContentNode.build(
- builder: T,
- pageContext: ContentPage,
- sourceSetRestriction: Set<DisplaySourceSet>? = null
- ) {
- builder.buildContentNode(this, pageContext, sourceSetRestriction)
- }
-
- public fun T.buildContentNode(
- node: ContentNode,
- pageContext: ContentPage,
- sourceSetRestriction: DisplaySourceSet
- ) {
- buildContentNode(node, pageContext, setOf(sourceSetRestriction))
- }
-
- public open fun T.buildContentNode(
- node: ContentNode,
- pageContext: ContentPage,
- sourceSetRestriction: Set<DisplaySourceSet>? = null
- ) {
- if (sourceSetRestriction.isNullOrEmpty() || node.sourceSets.any { it in sourceSetRestriction }) {
- when (node) {
- is ContentText -> buildText(node)
- is ContentHeader -> buildHeader(node, pageContext, sourceSetRestriction)
- is ContentCodeBlock -> buildCodeBlock(node, pageContext)
- is ContentCodeInline -> buildCodeInline(node, pageContext)
- is ContentDRILink -> buildDRILink(node, pageContext, sourceSetRestriction)
- is ContentResolvedLink -> buildResolvedLink(node, pageContext, sourceSetRestriction)
- is ContentEmbeddedResource -> buildResource(node, pageContext)
- is ContentList -> buildList(node, pageContext, sourceSetRestriction)
- is ContentTable -> buildTable(node, pageContext, sourceSetRestriction)
- is ContentGroup -> buildGroup(node, pageContext, sourceSetRestriction)
- is ContentBreakLine -> buildLineBreak(node, pageContext)
- is PlatformHintedContent -> buildPlatformDependent(node, pageContext, sourceSetRestriction)
- is ContentDivergentGroup -> buildDivergent(node, pageContext)
- is ContentDivergentInstance -> buildDivergentInstance(node, pageContext)
- else -> buildError(node)
- }
- }
- }
-
- public open fun T.buildDRILink(
- node: ContentDRILink,
- pageContext: ContentPage,
- sourceSetRestriction: Set<DisplaySourceSet>?
- ) {
- locationProvider.resolve(node.address, node.sourceSets, pageContext)?.let { address ->
- buildLink(address) {
- buildText(node.children, pageContext, sourceSetRestriction)
- }
- } ?: buildText(node.children, pageContext, sourceSetRestriction)
- }
-
- public open fun T.buildResolvedLink(
- node: ContentResolvedLink,
- pageContext: ContentPage,
- sourceSetRestriction: Set<DisplaySourceSet>?
- ) {
- buildLink(node.address) {
- buildText(node.children, pageContext, sourceSetRestriction)
- }
- }
-
- public open fun T.buildDivergentInstance(node: ContentDivergentInstance, pageContext: ContentPage) {
- node.before?.build(this, pageContext)
- node.divergent.build(this, pageContext)
- node.after?.build(this, pageContext)
- }
-
- public open fun buildPageContent(context: T, page: ContentPage) {
- context.buildNavigation(page)
- page.content.build(context, page)
- }
-
- public open suspend fun renderPage(page: PageNode) {
- val path by lazy {
- locationProvider.resolve(page, skipExtension = true)
- ?: throw DokkaException("Cannot resolve path for ${page.name}")
- }
- when (page) {
- is ContentPage -> outputWriter.write(path, buildPage(page) { c, p -> buildPageContent(c, p) }, ".html")
- is RendererSpecificPage -> when (val strategy = page.strategy) {
- is RenderingStrategy.Copy -> outputWriter.writeResources(strategy.from, path)
- is RenderingStrategy.Write -> outputWriter.write(path, strategy.text, "")
- is RenderingStrategy.Callback -> outputWriter.write(path, strategy.instructions(this, page), ".html")
- is RenderingStrategy.DriLocationResolvableWrite -> outputWriter.write(
- path,
- strategy.contentToResolve { dri, sourcesets ->
- locationProvider.resolve(dri, sourcesets)
- },
- ""
- )
- is RenderingStrategy.PageLocationResolvableWrite -> outputWriter.write(
- path,
- strategy.contentToResolve { pageToLocate, context ->
- locationProvider.resolve(pageToLocate, context)
- },
- ""
- )
- RenderingStrategy.DoNothing -> Unit
- }
- else -> throw AssertionError(
- "Page ${page.name} cannot be rendered by renderer as it is not renderer specific nor contains content"
- )
- }
- }
-
- private suspend fun renderPages(root: PageNode) {
- coroutineScope {
- renderPage(root)
-
- root.children.forEach {
- launch { renderPages(it) }
- }
- }
- }
-
- override fun render(root: RootPageNode) {
- val newRoot = preprocessors.fold(root) { acc, t -> t(acc) }
-
- locationProvider =
- context.plugin<DokkaBase>().querySingle { locationProviderFactory }.getLocationProvider(newRoot)
-
- runBlocking(Dispatchers.Default) {
- renderPages(newRoot)
- }
- }
-
- protected fun ContentDivergentGroup.groupDivergentInstances(
- pageContext: ContentPage,
- beforeTransformer: (ContentDivergentInstance, ContentPage, DisplaySourceSet) -> String,
- afterTransformer: (ContentDivergentInstance, ContentPage, DisplaySourceSet) -> String
- ): Map<SerializedBeforeAndAfter, List<InstanceWithSource>> =
- children.flatMap { instance ->
- instance.sourceSets.map { sourceSet ->
- Pair(instance, sourceSet) to Pair(
- beforeTransformer(instance, pageContext, sourceSet),
- afterTransformer(instance, pageContext, sourceSet)
- )
- }
- }.groupBy(
- Pair<InstanceWithSource, SerializedBeforeAndAfter>::second,
- Pair<InstanceWithSource, SerializedBeforeAndAfter>::first
- )
-}
-
-internal typealias SerializedBeforeAndAfter = Pair<String, String>
-internal typealias InstanceWithSource = Pair<ContentDivergentInstance, DisplaySourceSet>
-
-public fun ContentPage.sourceSets(): Set<DisplaySourceSet> = this.content.sourceSets
diff --git a/plugins/base/src/main/kotlin/renderers/FileWriter.kt b/plugins/base/src/main/kotlin/renderers/FileWriter.kt
deleted file mode 100644
index 1a1c3b42..00000000
--- a/plugins/base/src/main/kotlin/renderers/FileWriter.kt
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.renderers
-
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.sync.Mutex
-import kotlinx.coroutines.sync.withLock
-import kotlinx.coroutines.withContext
-import org.jetbrains.dokka.plugability.DokkaContext
-import java.io.File
-import java.io.IOException
-import java.net.URI
-import java.nio.file.*
-
-public class FileWriter(
- public val context: DokkaContext
-): OutputWriter {
- private val createdFiles: MutableSet<String> = mutableSetOf()
- private val createdFilesMutex = Mutex()
- private val jarUriPrefix = "jar:file:"
- private val root = context.configuration.outputDir
-
- override suspend fun write(path: String, text: String, ext: String) {
- if (checkFileCreated(path)) return
-
- try {
- val dir = Paths.get(root.absolutePath, path.dropLastWhile { it != '/' }).toFile()
- withContext(Dispatchers.IO) {
- dir.mkdirsOrFail()
- Files.write(Paths.get(root.absolutePath, "$path$ext"), text.lines())
- }
- } catch (e: Throwable) {
- context.logger.error("Failed to write $this. ${e.message}")
- e.printStackTrace()
- }
- }
-
- private suspend fun checkFileCreated(path: String): Boolean = createdFilesMutex.withLock {
- if (createdFiles.contains(path)) {
- context.logger.error("An attempt to write ${root}/$path several times!")
- return true
- }
- createdFiles.add(path)
- return false
- }
-
- override suspend fun writeResources(pathFrom: String, pathTo: String) {
- if (javaClass.getResource(pathFrom)?.toURI()?.toString()?.startsWith(jarUriPrefix) == true) {
- copyFromJar(pathFrom, pathTo)
- } else {
- copyFromDirectory(pathFrom, pathTo)
- }
- }
-
-
- private suspend fun copyFromDirectory(pathFrom: String, pathTo: String) {
- val dest = Paths.get(root.path, pathTo).toFile()
- val uri = javaClass.getResource(pathFrom)?.toURI()
- val file = uri?.let { File(it) } ?: File(pathFrom)
- withContext(Dispatchers.IO) {
- file.copyRecursively(dest, true)
- }
- }
-
- private suspend fun copyFromJar(pathFrom: String, pathTo: String) {
- val rebase = fun(path: String) =
- "$pathTo/${path.removePrefix(pathFrom)}"
- val dest = Paths.get(root.path, pathTo).toFile()
- if(dest.isDirectory){
- dest.mkdirsOrFail()
- } else {
- dest.parentFile.mkdirsOrFail()
- }
- val uri = javaClass.getResource(pathFrom).toURI()
- val fs = getFileSystemForURI(uri)
- val path = fs.getPath(pathFrom)
- for (file in Files.walk(path).iterator()) {
- if (Files.isDirectory(file)) {
- val dirPath = file.toAbsolutePath().toString()
- withContext(Dispatchers.IO) {
- Paths.get(root.path, rebase(dirPath)).toFile().mkdirsOrFail()
- }
- } else {
- val filePath = file.toAbsolutePath().toString()
- withContext(Dispatchers.IO) {
- Paths.get(root.path, rebase(filePath)).toFile().writeBytes(
- this@FileWriter.javaClass.getResourceAsStream(filePath).use { it?.readBytes() }
- ?: throw IllegalStateException("Can not get a resource from $filePath")
- )
- }
- }
- }
- }
-
- private fun File.mkdirsOrFail() {
- if (!mkdirs() && !exists()) {
- throw IOException("Failed to create directory $this")
- }
- }
-
- private fun getFileSystemForURI(uri: URI): FileSystem =
- try {
- FileSystems.newFileSystem(uri, emptyMap<String, Any>())
- } catch (e: FileSystemAlreadyExistsException) {
- FileSystems.getFileSystem(uri)
- }
-}
diff --git a/plugins/base/src/main/kotlin/renderers/OutputWriter.kt b/plugins/base/src/main/kotlin/renderers/OutputWriter.kt
deleted file mode 100644
index 3fdd1802..00000000
--- a/plugins/base/src/main/kotlin/renderers/OutputWriter.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.renderers
-
-public interface OutputWriter {
-
- public suspend fun write(path: String, text: String, ext: String)
- public suspend fun writeResources(pathFrom: String, pathTo: String)
-}
diff --git a/plugins/base/src/main/kotlin/renderers/PackageListService.kt b/plugins/base/src/main/kotlin/renderers/PackageListService.kt
deleted file mode 100644
index 3ed6cd21..00000000
--- a/plugins/base/src/main/kotlin/renderers/PackageListService.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.renderers
-
-import org.jetbrains.dokka.base.DokkaBase
-import org.jetbrains.dokka.base.resolvers.shared.LinkFormat
-import org.jetbrains.dokka.base.resolvers.shared.PackageList.Companion.DOKKA_PARAM_PREFIX
-import org.jetbrains.dokka.base.resolvers.shared.PackageList.Companion.MODULE_DELIMITER
-import org.jetbrains.dokka.base.resolvers.shared.PackageList.Companion.SINGLE_MODULE_NAME
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.pages.*
-import org.jetbrains.dokka.plugability.DokkaContext
-import org.jetbrains.dokka.plugability.plugin
-import org.jetbrains.dokka.plugability.querySingle
-
-public class PackageListService(
- public val context: DokkaContext,
- public val rootPage: RootPageNode
-) {
-
- public fun createPackageList(module: ModulePage, format: LinkFormat): String {
-
- val packages = mutableSetOf<String>()
- val nonStandardLocations = mutableMapOf<String, String>()
-
- val locationProvider =
- context.plugin<DokkaBase>().querySingle { locationProviderFactory }.getLocationProvider(rootPage)
-
- fun visit(node: PageNode) {
- 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 as? ContentPage
- contentPage?.dri?.forEach { dri ->
- val nodeLocation = locationProvider.resolve(node, context = module, skipExtension = true)
- ?: run { context.logger.error("Cannot resolve path for ${node.name}!"); null }
-
- if (dri != DRI.topLevel && locationProvider.expectedLocationForDri(dri) != nodeLocation) {
- nonStandardLocations[dri.toString()] = "$nodeLocation.${format.linkExtension}"
- }
- }
-
- node.children.forEach { visit(it) }
- }
-
- visit(module)
- return renderPackageList(
- nonStandardLocations = nonStandardLocations,
- modules = mapOf(SINGLE_MODULE_NAME to packages),
- format = format.formatName,
- linkExtension = format.linkExtension
- )
- }
-
- public companion object {
- public fun renderPackageList(
- nonStandardLocations: Map<String, String>,
- modules: Map<String, Set<String>>,
- format: String,
- linkExtension: String
- ): String = 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")
-
- modules.mapNotNull { (module, packages) ->
- ("$MODULE_DELIMITER$module\n".takeIf { module != SINGLE_MODULE_NAME }.orEmpty() +
- packages.filter(String::isNotBlank).sorted().joinToString(separator = "\n"))
- .takeIf { packages.isNotEmpty() }
- }.joinTo(this, separator = "\n", postfix = "\n")
- }
- }
-}
diff --git a/plugins/base/src/main/kotlin/renderers/TabSortingStrategy.kt b/plugins/base/src/main/kotlin/renderers/TabSortingStrategy.kt
deleted file mode 100644
index 665b6717..00000000
--- a/plugins/base/src/main/kotlin/renderers/TabSortingStrategy.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.renderers
-
-import org.jetbrains.dokka.pages.ContentNode
-
-public interface TabSortingStrategy {
- public fun <T: ContentNode> sort(tabs: Collection<T>) : List<T>
-}
diff --git a/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt b/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt
deleted file mode 100644
index 0fcb0efb..00000000
--- a/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.renderers
-
-import org.jetbrains.dokka.base.renderers.HtmlFileExtensions.imageExtensions
-import org.jetbrains.dokka.pages.ContentEmbeddedResource
-import java.io.File
-
-public fun ContentEmbeddedResource.isImage(): Boolean {
- return File(address).extension.toLowerCase() in imageExtensions
-}
-
-public val String.URIExtension: String
- get() = substringBefore('?').substringAfterLast('.')
-
-public fun String.isImage(): Boolean =
- URIExtension in imageExtensions
-
-public object HtmlFileExtensions {
- public val imageExtensions: Set<String> = setOf("png", "jpg", "jpeg", "gif", "bmp", "tif", "webp", "svg")
-}
-
diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlContent.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlContent.kt
deleted file mode 100644
index 1ef6e04c..00000000
--- a/plugins/base/src/main/kotlin/renderers/html/HtmlContent.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.renderers.html
-
-import org.jetbrains.dokka.pages.ContentBreakLine
-import org.jetbrains.dokka.pages.Style
-
-
-/**
- * Html-specific style that represents <hr> tag if used in conjunction with [ContentBreakLine]
- */
-internal object HorizontalBreakLineStyle : Style {
- // this exists as a simple internal solution to avoid introducing unnecessary public API on content level.
- // If you have the need to implement proper horizontal divider (i.e to support `---` markdown element),
- // consider removing this and providing proper API for all formats and levels
-}
diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
deleted file mode 100644
index 083876d5..00000000
--- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
+++ /dev/null
@@ -1,1013 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.renderers.html
-
-import kotlinx.html.*
-import kotlinx.html.stream.createHTML
-import org.jetbrains.dokka.DokkaSourceSetID
-import org.jetbrains.dokka.Platform
-import org.jetbrains.dokka.base.DokkaBase
-import org.jetbrains.dokka.base.renderers.*
-import org.jetbrains.dokka.base.renderers.html.command.consumers.ImmediateResolutionTagConsumer
-import org.jetbrains.dokka.base.renderers.html.innerTemplating.DefaultTemplateModelFactory
-import org.jetbrains.dokka.base.renderers.html.innerTemplating.DefaultTemplateModelMerger
-import org.jetbrains.dokka.base.renderers.html.innerTemplating.DokkaTemplateTypes
-import org.jetbrains.dokka.base.renderers.html.innerTemplating.HtmlTemplater
-import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint
-import org.jetbrains.dokka.base.resolvers.local.DokkaBaseLocationProvider
-import org.jetbrains.dokka.base.templating.*
-import org.jetbrains.dokka.base.transformers.documentables.CallableExtensions
-import org.jetbrains.dokka.base.translators.documentables.shouldDocumentConstructors
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.model.*
-import org.jetbrains.dokka.model.properties.PropertyContainer
-import org.jetbrains.dokka.model.properties.WithExtraProperties
-import org.jetbrains.dokka.pages.*
-import org.jetbrains.dokka.pages.HtmlContent
-import org.jetbrains.dokka.plugability.*
-import org.jetbrains.dokka.transformers.pages.PageTransformer
-import org.jetbrains.dokka.utilities.htmlEscape
-
-internal const val TEMPLATE_REPLACEMENT: String = "###"
-internal const val TOGGLEABLE_CONTENT_TYPE_ATTR = "data-togglable"
-
-public open class HtmlRenderer(
- context: DokkaContext
-) : DefaultRenderer<FlowContent>(context) {
- private val sourceSetDependencyMap: Map<DokkaSourceSetID, List<DokkaSourceSetID>> =
- context.configuration.sourceSets.associate { sourceSet ->
- sourceSet.sourceSetID to context.configuration.sourceSets
- .map { it.sourceSetID }
- .filter { it in sourceSet.dependentSourceSets }
- }
-
- private val templateModelFactories = listOf(DefaultTemplateModelFactory(context)) // TODO: Make extension point
- private val templateModelMerger = DefaultTemplateModelMerger()
- private val templater = HtmlTemplater(context).apply {
- setupSharedModel(templateModelMerger.invoke(templateModelFactories) { buildSharedModel() })
- }
-
- private var shouldRenderSourceSetTabs: Boolean = false
-
- override val preprocessors: List<PageTransformer> = context.plugin<DokkaBase>().query { htmlPreprocessors }
-
- /**
- * Tabs themselves are created in HTML plugin since, currently, only HTML format supports them.
- * [TabbedContentType] is used to mark content that should be inside tab content.
- * A tab can display multiple [TabbedContentType].
- * The content style [ContentStyle.TabbedContent] is used to determine where tabs will be generated.
- *
- * @see TabbedContentType
- * @see ContentStyle.TabbedContent
- */
- private fun createTabs(pageContext: ContentPage): List<ContentTab> {
- return when(pageContext) {
- is ClasslikePage -> createTabsForClasslikes(pageContext)
- is PackagePage -> createTabsForPackage(pageContext)
- else -> throw IllegalArgumentException("Page ${pageContext.name} cannot have tabs")
- }
- }
-
- private fun createTabsForClasslikes(page: ClasslikePage): List<ContentTab> {
- val documentables = page.documentables
- val csEnum = documentables.filterIsInstance<DEnum>()
- val csWithConstructor = documentables.filterIsInstance<WithConstructors>()
- val scopes = documentables.filterIsInstance<WithScope>()
- val constructorsToDocumented = csWithConstructor.flatMap { it.constructors }
-
- val containsRenderableConstructors = constructorsToDocumented.isNotEmpty() && documentables.shouldDocumentConstructors()
- val containsRenderableMembers =
- containsRenderableConstructors || scopes.any { it.classlikes.isNotEmpty() || it.functions.isNotEmpty() || it.properties.isNotEmpty() }
-
- @Suppress("UNCHECKED_CAST")
- val extensions = (documentables as List<WithExtraProperties<DClasslike>>).flatMap {
- it.extra[CallableExtensions]?.extensions
- ?.filterIsInstance<Documentable>().orEmpty()
- }
- .distinctBy { it.sourceSets to it.dri } // [Documentable] has expensive equals/hashCode at the moment, see #2620
- return listOfNotNull(
- if(!containsRenderableMembers) null else
- ContentTab(
- "Members",
- listOf(
- BasicTabbedContentType.CONSTRUCTOR,
- BasicTabbedContentType.TYPE,
- BasicTabbedContentType.PROPERTY,
- BasicTabbedContentType.FUNCTION
- )
- ),
- if (extensions.isEmpty()) null else ContentTab(
- "Members & Extensions",
- listOf(
- BasicTabbedContentType.CONSTRUCTOR,
- BasicTabbedContentType.TYPE,
- BasicTabbedContentType.PROPERTY,
- BasicTabbedContentType.FUNCTION,
- BasicTabbedContentType.EXTENSION_PROPERTY,
- BasicTabbedContentType.EXTENSION_FUNCTION
- )
- ),
- if(csEnum.isEmpty()) null else ContentTab(
- "Entries",
- listOf(
- BasicTabbedContentType.ENTRY
- )
- )
- )
- }
-
- private fun createTabsForPackage(page: PackagePage): List<ContentTab> {
- val p = page.documentables.single() as DPackage
- return listOfNotNull(
- if (p.typealiases.isEmpty() && p.classlikes.isEmpty()) null else ContentTab(
- "Types",
-