aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.idea/codeStyles/Project.xml17
-rw-r--r--core/build.gradle.kts1
-rw-r--r--core/src/main/kotlin/configuration.kt15
-rw-r--r--core/src/main/kotlin/defaultConfiguration.kt8
-rw-r--r--core/src/main/kotlin/plugability/DokkaPlugin.kt42
-rw-r--r--core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt2
-rw-r--r--docs/src/doc/docs/user_guide/base-specific/frontend.md29
-rw-r--r--docs/src/doc/docs/user_guide/cli/usage.md1
-rw-r--r--docs/src/doc/docs/user_guide/gradle/usage.md19
-rw-r--r--docs/src/doc/docs/user_guide/maven/usage.md23
-rw-r--r--integration-tests/gradle/build.gradle.kts2
-rw-r--r--integration-tests/gradle/projects/it-basic-groovy/build.gradle1
-rw-r--r--integration-tests/gradle/projects/it-basic/build.gradle.kts9
-rw-r--r--integration-tests/gradle/projects/it-basic/customResources/custom-resource.svg3
-rw-r--r--integration-tests/gradle/projects/it-basic/customResources/custom-style-to-add.css1
-rw-r--r--integration-tests/gradle/projects/it-basic/customResources/logo-styles.css3
-rw-r--r--integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt13
-rw-r--r--integration-tests/maven/projects/it-maven/customResources/custom-resource.svg3
-rw-r--r--integration-tests/maven/projects/it-maven/customResources/custom-style-to-add.css1
-rw-r--r--integration-tests/maven/projects/it-maven/customResources/logo-styles.css3
-rw-r--r--integration-tests/maven/projects/it-maven/pom.xml11
-rw-r--r--integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt15
-rw-r--r--plugins/base/src/main/kotlin/DokkaBase.kt12
-rw-r--r--plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt14
-rw-r--r--plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt8
-rw-r--r--plugins/base/src/main/kotlin/renderers/FileWriter.kt13
-rw-r--r--plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt16
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt2
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt103
-rwxr-xr-xplugins/base/src/main/resources/dokka/images/logo-text.svg6
-rw-r--r--plugins/base/src/main/resources/dokka/scripts/navigation-loader.js (renamed from plugins/base/src/main/resources/dokka/scripts/navigationLoader.js)0
-rw-r--r--plugins/base/src/main/resources/dokka/scripts/platform-content-handler.js (renamed from plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js)0
-rw-r--r--plugins/base/src/main/resources/dokka/scripts/search.js7
-rw-r--r--plugins/base/src/main/resources/dokka/styles/logo-styles.css3
-rw-r--r--plugins/base/src/main/resources/dokka/styles/style.css1
-rw-r--r--runners/cli/src/main/kotlin/cli/main.kt24
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt39
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt1
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt3
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt11
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt1
-rw-r--r--runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt4
-rw-r--r--runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt5
-rw-r--r--runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTaskTest.kt8
-rw-r--r--runners/maven-plugin/src/main/kotlin/DokkaMojo.kt15
45 files changed, 373 insertions, 145 deletions
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index f063496e..31d977a0 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -3,9 +3,18 @@
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
- <package name="java.util" withSubpackages="false" static="false" />
- <package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
- <package name="io.ktor" withSubpackages="true" static="false" />
+ <package name="java.util" alias="false" withSubpackages="false" />
+ <package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
+ <package name="io.ktor" alias="false" withSubpackages="true" />
+ </value>
+ </option>
+ <option name="PACKAGES_IMPORT_LAYOUT">
+ <value>
+ <package name="" alias="false" withSubpackages="true" />
+ <package name="java" alias="false" withSubpackages="true" />
+ <package name="javax" alias="false" withSubpackages="true" />
+ <package name="kotlin" alias="false" withSubpackages="true" />
+ <package name="" alias="true" withSubpackages="true" />
</value>
</option>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
@@ -14,4 +23,4 @@
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
-</component>
+</component> \ No newline at end of file
diff --git a/core/build.gradle.kts b/core/build.gradle.kts
index 971f08f4..b1c1dbb9 100644
--- a/core/build.gradle.kts
+++ b/core/build.gradle.kts
@@ -11,6 +11,7 @@ dependencies {
implementation(kotlin("reflect"))
implementation("org.jsoup:jsoup:1.12.1")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.11.1")
+ implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.11.1")
val coroutines_version: String by project
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
diff --git a/core/src/main/kotlin/configuration.kt b/core/src/main/kotlin/configuration.kt
index f5b2254a..bc097ae4 100644
--- a/core/src/main/kotlin/configuration.kt
+++ b/core/src/main/kotlin/configuration.kt
@@ -2,6 +2,7 @@
package org.jetbrains.dokka
+import org.jetbrains.dokka.plugability.ConfigurableBlock
import org.jetbrains.dokka.utilities.parseJson
import org.jetbrains.dokka.utilities.toJsonString
import java.io.File
@@ -29,6 +30,7 @@ object DokkaDefaults {
const val sourceSetDisplayName = "JVM"
const val sourceSetName = "main"
val moduleVersion: String? = null
+ val pluginsConfiguration = mutableListOf<PluginConfigurationImpl>()
}
enum class Platform(val key: String) {
@@ -81,6 +83,7 @@ data class DokkaSourceSetID(
fun DokkaConfigurationImpl(json: String): DokkaConfigurationImpl = parseJson(json)
fun DokkaConfiguration.toJsonString(): String = toJsonString(this)
+fun <T : ConfigurableBlock> T.toJsonString(): String = toJsonString(this)
interface DokkaConfiguration : Serializable {
val moduleName: String
@@ -92,7 +95,17 @@ interface DokkaConfiguration : Serializable {
val sourceSets: List<DokkaSourceSet>
val modules: List<DokkaModuleDescription>
val pluginsClasspath: List<File>
- val pluginsConfiguration: Map<String, String>
+ val pluginsConfiguration: List<PluginConfiguration>
+
+ enum class SerializationFormat : Serializable {
+ JSON, XML
+ }
+
+ interface PluginConfiguration : Serializable {
+ val fqPluginName: String
+ val serializationFormat: SerializationFormat
+ val values: String
+ }
interface DokkaSourceSet : Serializable {
val sourceSetID: DokkaSourceSetID
diff --git a/core/src/main/kotlin/defaultConfiguration.kt b/core/src/main/kotlin/defaultConfiguration.kt
index 45bf904d..a28df152 100644
--- a/core/src/main/kotlin/defaultConfiguration.kt
+++ b/core/src/main/kotlin/defaultConfiguration.kt
@@ -12,11 +12,17 @@ data class DokkaConfigurationImpl(
override val offlineMode: Boolean = DokkaDefaults.offlineMode,
override val sourceSets: List<DokkaSourceSetImpl> = emptyList(),
override val pluginsClasspath: List<File> = emptyList(),
- override val pluginsConfiguration: Map<String, String> = emptyMap(),
+ override val pluginsConfiguration: List<PluginConfigurationImpl> = DokkaDefaults.pluginsConfiguration,
override val modules: List<DokkaModuleDescriptionImpl> = emptyList(),
override val failOnWarning: Boolean = DokkaDefaults.failOnWarning
) : DokkaConfiguration
+data class PluginConfigurationImpl(
+ override val fqPluginName: String,
+ override val serializationFormat: DokkaConfiguration.SerializationFormat,
+ override val values: String
+) : DokkaConfiguration.PluginConfiguration
+
data class DokkaSourceSetImpl(
override val displayName: String = DokkaDefaults.sourceSetDisplayName,
diff --git a/core/src/main/kotlin/plugability/DokkaPlugin.kt b/core/src/main/kotlin/plugability/DokkaPlugin.kt
index 13f59f6e..625a34e2 100644
--- a/core/src/main/kotlin/plugability/DokkaPlugin.kt
+++ b/core/src/main/kotlin/plugability/DokkaPlugin.kt
@@ -1,12 +1,13 @@
package org.jetbrains.dokka.plugability
+import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule
+import com.fasterxml.jackson.dataformat.xml.XmlMapper
+import com.fasterxml.jackson.module.kotlin.readValue
import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.utilities.parseJson
-import org.jetbrains.dokka.utilities.toJsonString
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty1
-import kotlin.reflect.full.createInstance
abstract class DokkaPlugin {
private val extensionDelegates = mutableListOf<KProperty<*>>()
@@ -40,12 +41,12 @@ abstract class DokkaPlugin {
internal fun internalInstall(ctx: DokkaContextConfiguration, configuration: DokkaConfiguration) {
val extensionsToInstall = extensionDelegates.asSequence()
.filterIsInstance<KProperty1<DokkaPlugin, Extension<*, *, *>>>() // should be always true
- .map { it.get(this) } + unsafePlugins.map{ it.value }
+ .map { it.get(this) } + unsafePlugins.map { it.value }
extensionsToInstall.forEach { if (configuration.(it.condition)()) ctx.installExtension(it) }
}
- protected fun <T: Any> unsafeInstall(ext: Lazy<Extension<T, *, *>>){
- unsafePlugins.add(ext)
+ protected fun <T : Any> unsafeInstall(ext: Lazy<Extension<T, *, *>>) {
+ unsafePlugins.add(ext)
}
}
@@ -53,19 +54,8 @@ interface WithUnsafeExtensionSuppression {
val extensionsSuppressed: List<Extension<*, *, *>>
}
-interface Configurable {
- val pluginsConfiguration: Map<String, String>
-}
-
interface ConfigurableBlock
-inline fun <reified P : DokkaPlugin, reified T : ConfigurableBlock> Configurable.pluginConfiguration(block: T.() -> Unit) {
- val instance = T::class.createInstance().apply(block)
-
- val mutablePluginsConfiguration = pluginsConfiguration as MutableMap<String, String>
- mutablePluginsConfiguration[P::class.qualifiedName!!] = toJsonString(instance)
-}
-
inline fun <reified P : DokkaPlugin, reified E : Any> P.query(extension: P.() -> ExtensionPoint<E>): List<E> =
context?.let { it[extension()] } ?: throwIllegalQuery()
@@ -75,11 +65,15 @@ inline fun <reified P : DokkaPlugin, reified E : Any> P.querySingle(extension: P
fun throwIllegalQuery(): Nothing =
throw IllegalStateException("Querying about plugins is only possible with dokka context initialised")
-inline fun <reified T : DokkaPlugin, reified R : ConfigurableBlock> configuration(context: DokkaContext): ReadOnlyProperty<Any?, R> {
- return ReadOnlyProperty { _, _ ->
- val configuration = context.configuration.pluginsConfiguration[
- T::class.qualifiedName ?: throw AssertionError("Plugin must be named class")
- ]
- parseJson(checkNotNull(configuration))
- }
-}
+inline fun <reified T : DokkaPlugin, reified R : ConfigurableBlock> configuration(context: DokkaContext): R? =
+ context.configuration.pluginsConfiguration.firstOrNull { it.fqPluginName == T::class.qualifiedName }
+ ?.let { configuration ->
+ when (configuration.serializationFormat) {
+ DokkaConfiguration.SerializationFormat.JSON -> parseJson(configuration.values)
+ DokkaConfiguration.SerializationFormat.XML -> XmlMapper(JacksonXmlModule().apply {
+ setDefaultUseWrapper(
+ true
+ )
+ }).readValue<R>(configuration.values)
+ }
+ }
diff --git a/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt b/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt
index 45656a43..cba13f2a 100644
--- a/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt
+++ b/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt
@@ -31,7 +31,7 @@ class TestDokkaConfigurationBuilder {
var offlineMode: Boolean = false
var cacheRoot: String? = null
var pluginsClasspath: List<File> = emptyList()
- var pluginsConfigurations: Map<String, String> = emptyMap()
+ var pluginsConfigurations: MutableList<PluginConfigurationImpl> = mutableListOf()
var failOnWarning: Boolean = false
private val lazySourceSets = mutableListOf<Lazy<DokkaSourceSetImpl>>()
diff --git a/docs/src/doc/docs/user_guide/base-specific/frontend.md b/docs/src/doc/docs/user_guide/base-specific/frontend.md
new file mode 100644
index 00000000..adeb38ad
--- /dev/null
+++ b/docs/src/doc/docs/user_guide/base-specific/frontend.md
@@ -0,0 +1,29 @@
+# Configuration specific to HTML format
+
+## Modifying assets
+
+It is possible to change static assets that are used to generate dokka's HTML.
+Currently, user can modify:
+ * customAssets
+ * customStyleSheets
+
+Every file provided in those values will be applied to **every** page.
+
+Dokka uses 3 stylesheets:
+* `style.css` - main css file responsible for styling the page
+* `jetbrains-mono.css` - fonts used across dokka
+* `logo-styles.css` - logo styling
+
+User can choose to add or override those files.
+Resources will be overridden when in `pluginConfiguration` block there is a resource with the same name.
+
+### Examples
+In order to override a logo and style it accordingly a simple css file named `logo-styles.css` is needed:
+```css
+#logo {
+ background-image: url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg');
+ /* other styles required to make your page pretty */
+}
+```
+
+For build system specific instructions please visit dedicated pages: [gradle](../gradle/usage.md#Applying plugins), [maven](../maven/usage.md#Applying plugins) and [cli](../cli/usage.md#Configuration options) \ No newline at end of file
diff --git a/docs/src/doc/docs/user_guide/cli/usage.md b/docs/src/doc/docs/user_guide/cli/usage.md
index 9c73f8d3..e6bedf5e 100644
--- a/docs/src/doc/docs/user_guide/cli/usage.md
+++ b/docs/src/doc/docs/user_guide/cli/usage.md
@@ -14,6 +14,7 @@ Dokka supports the following command line arguments:
* `-moduleName` - (required) - module name used as a part of source set ID when declaring dependent source sets
* `-cacheRoot` - cache directory to enable package-list caching
* `-pluginsClasspath` - artifacts with Dokka plugins, separated by `;`. At least `dokka-base` and all its dependencies must be added there
+ * `-pluginsConfiguration` - configuration for plugins in format fqPluginName=json^^fqPluginName=json...
* `-offlineMode` - do not resolve package-lists online
* `-failOnWarning` - throw an exception instead of a warning
* `-globalPackageOptions` - per package options added to all source sets
diff --git a/docs/src/doc/docs/user_guide/gradle/usage.md b/docs/src/doc/docs/user_guide/gradle/usage.md
index 987bc4c0..e0f84e96 100644
--- a/docs/src/doc/docs/user_guide/gradle/usage.md
+++ b/docs/src/doc/docs/user_guide/gradle/usage.md
@@ -182,6 +182,10 @@ dokkaHtml {
suppress.set(true)
}
}
+ // Configures a plugin separately from the global configuration
+ pluginConfiguration<PluginClass, ConfigurationClass>{
+ // values
+ }
}
}
```
@@ -249,6 +253,21 @@ To generate the documentation, use the appropriate `dokka${format}` Gradle task:
./gradlew dokkaHtml
```
+Some plugins can be configured separately using a plugin class and configuration class. For example:
+
+```kotlin
+pluginConfiguration<DokkaBase, DokkaBaseConfiguration> {
+ customAssets = listOf(file("<path to asset>"))
+ customStyleSheets = listOf(file("<path to custom stylesheet>"))
+}
+```
+
+Keep in mind, that this only works when using a buildscript (with the configured plugin on classpath) since it is not possible to import plugin's class without it.
+
+If you don't want to use a buildscript or use Kotlin version lower than 1.3.50 you can achieve the same behaviour manually:
+```kotlin
+pluginsMapConfiguration.set(mapOf("<fully qualified plugin's name>" to """<json configuration>"""))
+```
## Android
!!! important
diff --git a/docs/src/doc/docs/user_guide/maven/usage.md b/docs/src/doc/docs/user_guide/maven/usage.md
index a95b6629..812737fa 100644
--- a/docs/src/doc/docs/user_guide/maven/usage.md
+++ b/docs/src/doc/docs/user_guide/maven/usage.md
@@ -160,6 +160,14 @@ The available configuration options are shown below:
<version>${dokka.version}</version>
</plugin>
</dokkaPlugins>
+
+ <!-- Configures a plugin separately -->
+ <pluginsConfiguration>
+ <fullyQualifiedPluginName>
+ <!-- Configuration -->
+ </fullyQualifiedPluginName>
+ </pluginsConfiguration>
+
</configuration>
</plugin>
```
@@ -192,6 +200,21 @@ You can add plugins inside the `dokkaPlugins` block:
</plugin>
```
+Some plugins can be configured separately using plugin's fully qualified name. For example:
+
+```xml
+<pluginsConfiguration>
+ <org.jetbrains.dokka.base.DokkaBase>
+ <customStyleSheets>
+ <customStyleSheet><!-- path to custom stylesheet --></customStyleSheet>
+ </customStyleSheets>
+ <customAssets>
+ <customAsset><!-- path to custom asset --></customAsset>
+ </customAssets>
+ </org.jetbrains.dokka.base.DokkaBase>
+</pluginsConfiguration>
+```
+
## Example project
Please see the [Dokka Maven example project](https://github.com/JetBrains/kotlin-examples/tree/master/maven/dokka-maven-example) for an example.
diff --git a/integration-tests/gradle/build.gradle.kts b/integration-tests/gradle/build.gradle.kts
index 3da416bb..8d3e8247 100644
--- a/integration-tests/gradle/build.gradle.kts
+++ b/integration-tests/gradle/build.gradle.kts
@@ -7,6 +7,8 @@ dependencies {
}
tasks.integrationTest {
+ val dokka_version: String by project
+ environment("DOKKA_VERSION", dokka_version)
inputs.dir(file("projects"))
dependsOnMavenLocalPublication()
}
diff --git a/integration-tests/gradle/projects/it-basic-groovy/build.gradle b/integration-tests/gradle/projects/it-basic-groovy/build.gradle
index df2e8624..dc469bba 100644
--- a/integration-tests/gradle/projects/it-basic-groovy/build.gradle
+++ b/integration-tests/gradle/projects/it-basic-groovy/build.gradle
@@ -11,7 +11,6 @@ dependencies {
dokkaHtml {
outputDirectory = new File(buildDir, "/dokka/customHtml")
- pluginsConfiguration.put("pluginA", "configA")
failOnWarning = false
dokkaSourceSets {
customSourceSet {
diff --git a/integration-tests/gradle/projects/it-basic/build.gradle.kts b/integration-tests/gradle/projects/it-basic/build.gradle.kts
index a155d9d7..6246bf93 100644
--- a/integration-tests/gradle/projects/it-basic/build.gradle.kts
+++ b/integration-tests/gradle/projects/it-basic/build.gradle.kts
@@ -1,5 +1,7 @@
import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.dokka.gradle.kotlinSourceSet
+import org.jetbrains.dokka.base.DokkaBase
+import org.jetbrains.dokka.base.DokkaBaseConfiguration
import java.net.URL
plugins {
@@ -7,6 +9,12 @@ plugins {
id("org.jetbrains.dokka")
}
+buildscript {
+ dependencies {
+ classpath("org.jetbrains.dokka:dokka-base:${System.getenv("DOKKA_VERSION")}")
+ }
+}
+
version = "1.5-SNAPSHOT"
apply(from = "../template.root.gradle.kts")
@@ -40,4 +48,5 @@ tasks.withType<DokkaTask> {
kotlinSourceSet(kotlin.sourceSets["test"])
}
}
+ pluginsMapConfiguration.set(mapOf(DokkaBase::class.qualifiedName to """{ "customStyleSheets": ["${file("customResources/logo-styles.css")}", "${file("customResources/custom-style-to-add.css")}"], "customAssets" : ["${file("customResources/custom-resource.svg")}"] }"""))
}
diff --git a/integration-tests/gradle/projects/it-basic/customResources/custom-resource.svg b/integration-tests/gradle/projects/it-basic/customResources/custom-resource.svg
new file mode 100644
index 00000000..1865f739
--- /dev/null
+++ b/integration-tests/gradle/projects/it-basic/customResources/custom-resource.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M18 9C18 14 14 18 9 18C4 18 0 14 0 9C0 4 4 0 9 0C14 0 18 4 18 9ZM14.2 6.2L12.8 4.8L7.5 10.1L5.3 7.8L3.8 9.2L7.5 13L14.2 6.2Z" fill="#4DBB5F"/>
+</svg> \ No newline at end of file
diff --git a/integration-tests/gradle/projects/it-basic/customResources/custom-style-to-add.css b/integration-tests/gradle/projects/it-basic/customResources/custom-style-to-add.css
new file mode 100644
index 00000000..408c210e
--- /dev/null
+++ b/integration-tests/gradle/projects/it-basic/customResources/custom-style-to-add.css
@@ -0,0 +1 @@
+/* custom stylesheet */ \ No newline at end of file
diff --git a/integration-tests/gradle/projects/it-basic/customResources/logo-styles.css b/integration-tests/gradle/projects/it-basic/customResources/logo-styles.css
new file mode 100644
index 00000000..2ac57218
--- /dev/null
+++ b/integration-tests/gradle/projects/it-basic/customResources/logo-styles.css
@@ -0,0 +1,3 @@
+#logo {
+ background-image: url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg');
+} \ No newline at end of file
diff --git a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt
index 46306078..9da67fc3 100644
--- a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt
+++ b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt
@@ -25,6 +25,8 @@ class BasicGradleIntegrationTest(override val versions: BuildVersions) : Abstrac
.forEach { topLevelFile -> topLevelFile.copyTo(File(projectDir, topLevelFile.name)) }
File(templateProjectDir, "src").copyRecursively(File(projectDir, "src"))
+ val customResourcesDir = File(templateProjectDir, "customResources")
+ if(customResourcesDir.exists() && customResourcesDir.isDirectory) customResourcesDir.copyRecursively(File(projectDir, "customResources"))
}
@Test
@@ -116,6 +118,17 @@ class BasicGradleIntegrationTest(override val versions: BuildVersions) : Abstrac
},
"Anchors should not have hashes inside"
)
+
+ assertEquals(
+ """#logo{background-image:url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg');}""",
+ stylesDir.resolve("logo-styles.css").readText().replace("\\s".toRegex(), ""),
+ )
+ assertTrue(stylesDir.resolve("custom-style-to-add.css").isFile)
+ assertEquals("""/* custom stylesheet */""", stylesDir.resolve("custom-style-to-add.css").readText())
+ allHtmlFiles().forEach { file ->
+ if(file.name != "navigation.html") assertTrue("custom-style-to-add.css" in file.readText(), "custom styles not added to html file ${file.name}")
+ }
+ assertTrue(imagesDir.resolve("custom-resource.svg").isFile)
}
private fun File.assertJavadocOutputDir() {
diff --git a/integration-tests/maven/projects/it-maven/customResources/custom-resource.svg b/integration-tests/maven/projects/it-maven/customResources/custom-resource.svg
new file mode 100644
index 00000000..1865f739
--- /dev/null
+++ b/integration-tests/maven/projects/it-maven/customResources/custom-resource.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M18 9C18 14 14 18 9 18C4 18 0 14 0 9C0 4 4 0 9 0C14 0 18 4 18 9ZM14.2 6.2L12.8 4.8L7.5 10.1L5.3 7.8L3.8 9.2L7.5 13L14.2 6.2Z" fill="#4DBB5F"/>
+</svg> \ No newline at end of file
diff --git a/integration-tests/maven/projects/it-maven/customResources/custom-style-to-add.css b/integration-tests/maven/projects/it-maven/customResources/custom-style-to-add.css
new file mode 100644
index 00000000..408c210e
--- /dev/null
+++ b/integration-tests/maven/projects/it-maven/customResources/custom-style-to-add.css
@@ -0,0 +1 @@
+/* custom stylesheet */ \ No newline at end of file
diff --git a/integration-tests/maven/projects/it-maven/customResources/logo-styles.css b/integration-tests/maven/projects/it-maven/customResources/logo-styles.css
new file mode 100644
index 00000000..2ac57218
--- /dev/null
+++ b/integration-tests/maven/projects/it-maven/customResources/logo-styles.css
@@ -0,0 +1,3 @@
+#logo {
+ background-image: url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg');
+} \ No newline at end of file
diff --git a/integration-tests/maven/projects/it-maven/pom.xml b/integration-tests/maven/projects/it-maven/pom.xml
index 80620c82..8bd5d956 100644
--- a/integration-tests/maven/projects/it-maven/pom.xml
+++ b/integration-tests/maven/projects/it-maven/pom.xml
@@ -137,6 +137,17 @@
<includeNonPublic>false</includeNonPublic>
</packageOptions>
</perPackageOptions>
+ <pluginsConfiguration>
+ <org.jetbrains.dokka.base.DokkaBase>
+ <customAssets>
+ <customAsset>${project.basedir}/customResources/custom-resource.svg</customAsset>
+ </customAssets>
+ <customStyleSheets>
+ <customStyleSheet>${project.basedir}/customResources/logo-styles.css</customStyleSheet>
+ <customStyleSheet>${project.basedir}/customResources/custom-style-to-add.css</customStyleSheet>
+ </customStyleSheets>
+ </org.jetbrains.dokka.base.DokkaBase>
+ </pluginsConfiguration>
</configuration>
</plugin>
</plugins>
diff --git a/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt b/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt
index 88fdc207..be70fdb4 100644
--- a/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt
+++ b/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt
@@ -24,6 +24,10 @@ class MavenIntegrationTest : AbstractIntegrationTest() {
pomXml.apply {
writeText(readText().replace("\$dokka_version", currentDokkaVersion))
}
+ val customResourcesDir = File(templateProjectDir, "customResources")
+ if(customResourcesDir.exists() && customResourcesDir.isDirectory) {
+ customResourcesDir.copyRecursively(File(projectDir, "customResources"), overwrite = true)
+ }
}
@Test
@@ -54,6 +58,17 @@ class MavenIntegrationTest : AbstractIntegrationTest() {
assertNoEmptyLinks(file)
assertNoEmptySpans(file)
}
+
+ assertEquals(
+ """#logo{background-image:url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg');}""",
+ stylesDir.resolve("logo-styles.css").readText().replace("\\s".toRegex(), ""),
+ )
+ assertTrue(stylesDir.resolve("custom-style-to-add.css").isFile)
+ projectDir.allHtmlFiles().forEach { file ->
+ if(file.name != "navigation.html") assertTrue("custom-style-to-add.css" in file.readText(), "custom styles not added to html file ${file.name}")
+ }
+ assertEquals("""/* custom stylesheet */""", stylesDir.resolve("custom-style-to-add.css").readText())
+ assertTrue(imagesDir.resolve("custom-resource.svg").isFile)
}
@Test
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt
index be3c09b9..e709b48b 100644
--- a/plugins/base/src/main/kotlin/DokkaBase.kt
+++ b/plugins/base/src/main/kotlin/DokkaBase.kt
@@ -198,10 +198,6 @@ class DokkaBase : DokkaPlugin() {
htmlPreprocessors with NavigationPageInstaller order { after(rootCreator) }
}
- val searchPageInstaller by extending {
- htmlPreprocessors with SearchPageInstaller order { after(rootCreator) }
- }
-
val scriptsInstaller by extending {
htmlPreprocessors with ScriptsInstaller order { after(rootCreator) }
}
@@ -214,6 +210,14 @@ class DokkaBase : DokkaPlugin() {
htmlPreprocessors with AssetsInstaller order { after(rootCreator) }
}
+ val customResourceInstaller by extending {
+ htmlPreprocessors providing { ctx -> CustomResourceInstaller(ctx) } order {
+ after(stylesInstaller)
+ after(scriptsInstaller)
+ after(assetsInstaller)
+ }
+ }
+
val packageListCreator by extending {
htmlPreprocessors providing {
PackageListCreator(it, RecognizedLinkFormat.DokkaHtml)
diff --git a/plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt b/plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt
new file mode 100644
index 00000000..c18b3446
--- /dev/null
+++ b/plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt
@@ -0,0 +1,14 @@
+package org.jetbrains.dokka.base
+
+import org.jetbrains.dokka.plugability.ConfigurableBlock
+import java.io.File
+
+data class DokkaBaseConfiguration(
+ var customStyleSheets: List<File> = defaultCustomStyleSheets,
+ var customAssets: List<File> = defaultCustomAssets
+): ConfigurableBlock {
+ companion object {
+ val defaultCustomStyleSheets: List<File> = emptyList()
+ val defaultCustomAssets: List<File> = emptyList()
+ }
+} \ 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 5c0f54d8..f393c0fa 100644
--- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
@@ -15,7 +15,6 @@ 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
-import java.io.File
abstract class DefaultRenderer<T>(
protected val context: DokkaContext
@@ -223,9 +222,4 @@ abstract class DefaultRenderer<T>(
internal typealias SerializedBeforeAndAfter = Pair<String, String>
internal typealias InstanceWithSource = Pair<ContentDivergentInstance, DisplaySourceSet>
-fun ContentPage.sourceSets() = this.content.sourceSets
-
-fun ContentEmbeddedResource.isImage(): Boolean {
- val imageExtensions = setOf("png", "jpg", "jpeg", "gif", "bmp", "tif", "webp", "svg")
- return File(address).extension.toLowerCase() in imageExtensions
-}
+fun ContentPage.sourceSets() = this.content.sourceSets \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/renderers/FileWriter.kt b/plugins/base/src/main/kotlin/renderers/FileWriter.kt
index cd38f1b9..f8c0e882 100644
--- a/plugins/base/src/main/kotlin/renderers/FileWriter.kt
+++ b/plugins/base/src/main/kotlin/renderers/FileWriter.kt
@@ -33,7 +33,7 @@ class FileWriter(val context: DokkaContext): OutputWriter {
}
override suspend fun writeResources(pathFrom: String, pathTo: String) =
- if (javaClass.getResource(pathFrom).toURI().toString().startsWith(jarUriPrefix)) {
+ if (javaClass.getResource(pathFrom)?.toURI()?.toString()?.startsWith(jarUriPrefix) == true) {
copyFromJar(pathFrom, pathTo)
} else {
copyFromDirectory(pathFrom, pathTo)
@@ -42,9 +42,10 @@ class FileWriter(val context: DokkaContext): OutputWriter {
private suspend fun copyFromDirectory(pathFrom: String, pathTo: String) {
val dest = Paths.get(root.path, pathTo).toFile()
- val uri = javaClass.getResource(pathFrom).toURI()
+ val uri = javaClass.getResource(pathFrom)?.toURI()
+ val file = uri?.let { File(it) } ?: File(pathFrom)
withContext(Dispatchers.IO) {
- File(uri).copyRecursively(dest, true)
+ file.copyRecursively(dest, true)
}
}
@@ -52,7 +53,11 @@ class FileWriter(val context: DokkaContext): OutputWriter {
val rebase = fun(path: String) =
"$pathTo/${path.removePrefix(pathFrom)}"
val dest = Paths.get(root.path, pathTo).toFile()
- dest.mkdirsOrFail()
+ if(dest.isDirectory){
+ dest.mkdirsOrFail()
+ } else {
+ dest.parentFile.mkdirsOrFail()
+ }
val uri = javaClass.getResource(pathFrom).toURI()
val fs = getFileSystemForURI(uri)
val path = fs.getPath(pathFrom)
diff --git a/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt b/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt
new file mode 100644
index 00000000..4619bc53
--- /dev/null
+++ b/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt
@@ -0,0 +1,16 @@
+package org.jetbrains.dokka.base.renderers
+
+import org.jetbrains.dokka.base.renderers.HtmlFileExtensions.imageExtensions
+import org.jetbrains.dokka.pages.ContentEmbeddedResource
+import java.io.File
+
+fun ContentEmbeddedResource.isImage(): Boolean {
+ return File(address).extension.toLowerCase() in imageExtensions
+}
+
+fun String.isImage(): Boolean =
+ substringBefore('?').substringAfterLast('.') in imageExtensions
+
+object HtmlFileExtensions {
+ val imageExtensions = setOf("png", "jpg", "jpeg", "gif", "bmp", "tif", "webp", "svg")
+} \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
index 6bdeae62..7a047d3c 100644
--- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
@@ -679,10 +679,10 @@ open class HtmlRenderer(
) {
async = true
}
+ it.isImage() -> link(href = page.root(it))
else -> unsafe { +it }
}
}
- link(rel = LinkRel.stylesheet, href = page.root("styles/main.css")) {}
script { unsafe { +"""var pathToRoot = "${locationProvider.pathToRoot(page)}";""" } }
}
body {
diff --git a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
index a5fca92f..a87254ce 100644
--- a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
@@ -7,6 +7,9 @@ import kotlinx.html.h1
import kotlinx.html.id
import kotlinx.html.table
import kotlinx.html.tbody
+import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.base.DokkaBase
+import org.jetbrains.dokka.base.DokkaBaseConfiguration
import org.jetbrains.dokka.base.renderers.sourceSets
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.DEnum
@@ -14,30 +17,9 @@ import org.jetbrains.dokka.model.DEnumEntry
import org.jetbrains.dokka.model.withDescendants
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.configuration
import org.jetbrains.dokka.transformers.pages.PageTransformer
-
-object SearchPageInstaller : PageTransformer {
- override fun invoke(input: RootPageNode) = input.modified(children = input.children + searchPage)
-
- private val searchPage = RendererSpecificResourcePage(
- name = "Search",
- children = emptyList(),
- strategy = RenderingStrategy<HtmlRenderer> {
- buildHtml(it, listOf("styles/style.css", "scripts/pages.js", "scripts/search.js")) {
- h1 {
- id = "searchTitle"
- text("Search results for ")
- }
- table {
- tbody {
- id = "searchTable"
- }
- }
- }
- })
-}
-
object NavigationPageInstaller : PageTransformer {
private val mapper = jacksonObjectMapper()
@@ -89,56 +71,79 @@ object NavigationPageInstaller : PageTransformer {
}.sortedBy { it.name.toLowerCase() }
}
+class CustomResourceInstaller(val dokkaContext: DokkaContext) : PageTransformer {
+ private val configuration = configuration<DokkaBase, DokkaBaseConfiguration>(dokkaContext)
+
+ private val customAssets = configuration?.customAssets?.map {
+ RendererSpecificResourcePage("images/${it.name}", emptyList(), RenderingStrategy.Copy(it.absolutePath))
+ }.orEmpty()
+
+ private val customStylesheets = configuration?.customStyleSheets?.map {
+ RendererSpecificResourcePage("styles/${it.name}", emptyList(), RenderingStrategy.Copy(it.absolutePath))
+ }.orEmpty()
+
+ override fun invoke(input: RootPageNode): RootPageNode {
+ val customResourcesPaths = (customAssets + customStylesheets).map { it.name }.toSet()
+ val withEmbeddedResources = input.transformContentPagesTree { it.modified(embeddedResources = it.embeddedResources + customResourcesPaths) }
+ val (currentResources, otherPages) = withEmbeddedResources.children.partition { it is RendererSpecificResourcePage }
+ return input.modified(children = otherPages + currentResources.filterNot { it.name in customResourcesPaths } + customAssets + customStylesheets)
+ }
+}
+
object ScriptsInstaller : PageTransformer {
+ private val scriptsPages = listOf(
+ "scripts/clipboard.js",
+ "scripts/navigation-loader.js",
+ "scripts/platform-content-handler.js",
+ "scripts/main.js"
+ )
+
override fun invoke(input: RootPageNode): RootPageNode {
return input.modified(
- children = input.children + RendererSpecificResourcePage(
- "scripts",
- emptyList(),
- RenderingStrategy.Copy("/dokka/scripts")
- )
+ children = input.children + scriptsPages.toRenderSpecificResourcePage()
).transformContentPagesTree {
it.modified(
- embeddedResources = it.embeddedResources + listOf(
- "scripts/navigationLoader.js",
- "scripts/platformContentHandler.js",
- "scripts/sourceset_dependencies.js",
- "scripts/clipboard.js",
- )
+ embeddedResources = it.embeddedResources + scriptsPages
)
}
}
}
object StylesInstaller : PageTransformer {
+ private val stylesPages = listOf(
+ "styles/style.css",
+ "styles/logo-styles.css",
+ "styles/jetbrains-mono.css",
+ "styles/main.css"
+ )
+
override fun invoke(input: RootPageNode): RootPageNode =
input.modified(
- children = input.children + RendererSpecificResourcePage(
- "styles",
- emptyList(),
- RenderingStrategy.Copy("/dokka/styles")
- )
+ children = input.children + stylesPages.toRenderSpecificResourcePage()
).transformContentPagesTree {
it.modified(
- embeddedResources = it.embeddedResources + listOf(
- "styles/style.css",
- "styles/jetbrains-mono.css"
- )
+ embeddedResources = it.embeddedResources + stylesPages
)
}
}
object AssetsInstaller : PageTransformer {
+ private val imagesPages = listOf(
+ "images/arrow_down.svg",
+ "images/docs_logo.svg",
+ "images/logo-icon.svg"
+ )
+
override fun invoke(input: RootPageNode) = input.modified(
- children = input.children + RendererSpecificResourcePage(
- "images",
- emptyList(),
- RenderingStrategy.Copy("/dokka/images")
- )
+ children = input.children + imagesPages.toRenderSpecificResourcePage()
)
}
+private fun List<String>.toRenderSpecificResourcePage(): List<RendererSpecificResourcePage> =
+ map { RendererSpecificResourcePage(it, emptyList(), RenderingStrategy.Copy("/dokka/$it")) }
+
class SourcesetDependencyAppender(val context: DokkaContext) : PageTransformer {
+ private val name = "scripts/sourceset_dependencies.js"
override fun invoke(input: RootPageNode): RootPageNode {
val dependenciesMap = context.configuration.sourceSets.map {
it.sourceSetID to it.dependentSourceSets
@@ -155,14 +160,14 @@ class SourcesetDependencyAppender(val context: DokkaContext) : PageTransformer {
}}'"
val deps = RendererSpecificResourcePage(
- name = "scripts/sourceset_dependencies.js",
+ name = name,
children = emptyList(),
strategy = RenderingStrategy.Write(createDependenciesJson())
)
return input.modified(
children = input.children + deps
- )
+ ).transformContentPagesTree { it.modified(embeddedResources = it.embeddedResources + name) }
}
}
diff --git a/plugins/base/src/main/resources/dokka/images/logo-text.svg b/plugins/base/src/main/resources/dokka/images/logo-text.svg
deleted file mode 100755
index 7bf3e6c5..00000000
--- a/plugins/base/src/main/resources/dokka/images/logo-text.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg width="83" height="27" viewBox="0 0 83 27" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M47.1611 7.6297V25.6345V25.6867H61.8428V21.8039H51.3589V10.3852H61.8428V6.50244H47.1611V7.6297Z" fill="#27282C"/>
-<path d="M82.9891 21.8039L72.778 10.3852H82.9051V6.50244H67.0586V10.3852L77.4585 21.8039H67.0586V25.6867H82.9996V21.8039H82.9891Z" fill="#27282C"/>
-<path d="M16.2978 7.76556C14.5872 6.46086 12.4463 5.67804 10.1271 5.67804C4.53357 5.67804 0 10.1871 0 15.7503C0 21.3135 4.53357 25.8226 10.1271 25.8226C12.4463 25.8226 14.5872 25.0502 16.2978 23.735V25.7182H20.4955V0H16.2978V7.76556ZM10.1271 21.8041C6.75838 21.8041 4.02984 19.0903 4.02984 15.7399C4.02984 12.3894 6.75838 9.67563 10.1271 9.67563C13.4958 9.67563 16.2243 12.3894 16.2243 15.7399C16.2138 19.0903 13.4853 21.8041 10.1271 21.8041Z" fill="#27282C"/>
-<path d="M33.9703 5.86566C28.3768 5.86566 23.8433 10.3747 23.8433 15.9379C23.8433 21.5011 28.3768 26.0102 33.9703 26.0102C39.5638 26.0102 44.0974 21.5011 44.0974 15.9379C44.0974 10.3747 39.5638 5.86566 33.9703 5.86566ZM33.9703 21.9917C30.6016 21.9917 27.8731 19.2779 27.8731 15.9275C27.8731 12.577 30.6016 9.86325 33.9703 9.86325C37.339 9.86325 40.0676 12.577 40.0676 15.9275C40.0676 19.2779 37.339 21.9917 33.9703 21.9917Z" fill="#27282C"/>
-</svg>
diff --git a/plugins/base/src/main/resources/dokka/scripts/navigationLoader.js b/plugins/base/src/main/resources/dokka/scripts/navigation-loader.js
index c2f60ec5..c2f60ec5 100644
--- a/plugins/base/src/main/resources/dokka/scripts/navigationLoader.js
+++ b/plugins/base/src/main/resources/dokka/scripts/navigation-loader.js
diff --git a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js b/plugins/base/src/main/resources/dokka/scripts/platform-content-handler.js
index 022aca4f..022aca4f 100644
--- a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js
+++ b/plugins/base/src/main/resources/dokka/scripts/platform-content-handler.js
diff --git a/plugins/base/src/main/resources/dokka/scripts/search.js b/plugins/base/src/main/resources/dokka/scripts/search.js
deleted file mode 100644
index 04d88ab5..00000000
--- a/plugins/base/src/main/resources/dokka/scripts/search.js
+++ /dev/null
@@ -1,7 +0,0 @@
-let query = new URLSearchParams(window.location.search).get("query");
-document.getElementById("searchTitle").innerHTML += '"' + query + '":';
-document.getElementById("searchTable").innerHTML = pages
- .filter(el => el.name.toLowerCase().startsWith(query.toLowerCase()))
- .reduce((acc, element) => {
- return acc + '<tr><td><a href="' + element.location + '">' + element.name + '</a></td></tr>'
- }, ""); \ No newline at end of file
diff --git a/plugins/base/src/main/resources/dokka/styles/logo-styles.css b/plugins/base/src/main/resources/dokka/styles/logo-styles.css
new file mode 100644
index 00000000..a3a07d75
--- /dev/null
+++ b/plugins/base/src/main/resources/dokka/styles/logo-styles.css
@@ -0,0 +1,3 @@
+#logo {
+ background-image: url(../images/docs_logo.svg);
+} \ No newline at end of file
diff --git a/plugins/base/src/main/resources/dokka/styles/style.css b/plugins/base/src/main/resources/dokka/styles/style.css
index 24fd8fa3..7c1b2803 100644
--- a/plugins/base/src/main/resources/dokka/styles/style.css
+++ b/plugins/base/src/main/resources/dokka/styles/style.css
@@ -191,7 +191,6 @@
background-size: 125px 26px;
border-bottom: 1px solid #DADFE6;
background-repeat: no-repeat;
- background-image: url(../images/docs_logo.svg);
background-origin: content-box;
padding-left: 24px;
padding-top: 24px;
diff --git a/runners/cli/src/main/kotlin/cli/main.kt b/runners/cli/src/main/kotlin/cli/main.kt
index a1139e65..681ebfa6 100644
--- a/runners/cli/src/main/kotlin/cli/main.kt
+++ b/runners/cli/src/main/kotlin/cli/main.kt
@@ -46,7 +46,7 @@ class GlobalArguments(args: Array<String>) : DokkaConfiguration {
override val pluginsConfiguration by parser.option(
ArgTypePlugin,
description = "Configuration for plugins in format fqPluginName=json^^fqPluginName=json..."
- ).default(emptyMap())
+ ).delimiter("^^")
override val pluginsClasspath by parser.option(
ArgTypeFile,
@@ -254,16 +254,22 @@ object ArgTypeFile : ArgType<File>(true) {
object ArgTypePlatform : ArgType<Platform>(true) {
override fun convert(value: kotlin.String, name: kotlin.String): Platform = Platform.fromString(value)
override val description: kotlin.String
- get() = "{ String thar represents paltform }"
+ get() = "{ String that represents platform }"
}
-object ArgTypePlugin : ArgType<Map<String, String>>(true) {
- override fun convert(value: kotlin.String, name: kotlin.String): Map<kotlin.String, kotlin.String> =
- value.split("^^").map {
- it.split("=").let {
- it[0] to it[1]
- }
- }.toMap()
+object ArgTypePlugin : ArgType<DokkaConfiguration.PluginConfiguration>(true) {
+ override fun convert(
+ value: kotlin.String,
+ name: kotlin.String
+ ): DokkaConfiguration.PluginConfiguration {
+ return value.split("=").let {
+ PluginConfigurationImpl(
+ fqPluginName = it[0],
+ serializationFormat = DokkaConfiguration.SerializationFormat.JSON,
+ values = it[1]
+ )
+ }
+ }
override val description: kotlin.String
get() = "{ String fqName=json, remember to escape `\"` inside json }"
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt
index 9dab1f04..77b4b2e1 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt
@@ -8,17 +8,19 @@ import org.gradle.api.DefaultTask
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.plugins.JavaBasePlugin
+import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
+import org.gradle.kotlin.dsl.listProperty
import org.gradle.kotlin.dsl.mapProperty
-import org.jetbrains.dokka.DokkaBootstrap
-import org.jetbrains.dokka.DokkaConfigurationImpl
-import org.jetbrains.dokka.DokkaDefaults
-import org.jetbrains.dokka.toJsonString
+import org.jetbrains.dokka.*
+import org.jetbrains.dokka.plugability.ConfigurableBlock
+import org.jetbrains.dokka.plugability.DokkaPlugin
import java.io.File
import java.util.function.BiConsumer
import kotlin.reflect.KClass
+import kotlin.reflect.full.createInstance
abstract class AbstractDokkaTask(
private val bootstrapClass: KClass<out DokkaBootstrap> = DokkaBootstrap::class
@@ -49,7 +51,23 @@ abstract class AbstractDokkaTask(
.safeConvention(DokkaDefaults.offlineMode)
@Input
- val pluginsConfiguration: MapProperty<String, String> = project.objects.mapProperty()
+ val pluginsConfiguration: ListProperty<in DokkaConfiguration.PluginConfiguration> = project.objects.listProperty()
+
+ /**
+ * Used to keep compatibility with gradle using Kotlin lower than 1.3.50
+ */
+ @Input
+ val pluginsMapConfiguration: MapProperty<String, String> = project.objects.mapProperty()
+
+ inline fun <reified P : DokkaPlugin, reified T : ConfigurableBlock> pluginConfiguration(block: T.() -> Unit) {
+ val instance = T::class.createInstance().apply(block)
+ val pluginConfiguration = PluginConfigurationImpl(
+ fqPluginName = P::class.qualifiedName!!,
+ serializationFormat = DokkaConfiguration.SerializationFormat.JSON,
+ values = instance.toJsonString()
+ )
+ pluginsConfiguration.add(pluginConfiguration)
+ }
@Classpath
val plugins: Configuration = project.maybeCreateDokkaPluginConfiguration(name)
@@ -84,4 +102,15 @@ abstract class AbstractDokkaTask(
init {
group = JavaBasePlugin.DOCUMENTATION_GROUP
}
+
+ internal fun buildPluginsConfiguration(): List<PluginConfigurationImpl> {
+ val manuallyConfigured = pluginsMapConfiguration.getSafe().entries.map { entry ->
+ PluginConfigurationImpl(
+ entry.key,
+ DokkaConfiguration.SerializationFormat.JSON,
+ entry.value
+ )
+ }
+ return pluginsConfiguration.getSafe().mapNotNull { it as? PluginConfigurationImpl } + manuallyConfigured
+ }
}
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt
index cd53398a..b0fc5f22 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt
@@ -17,6 +17,7 @@ abstract class DokkaCollectorTask : AbstractDokkaParentTask() {
failOnWarning = failOnWarning.getSafe(),
offlineMode = offlineMode.getSafe(),
pluginsClasspath = plugins.resolve().toList(),
+ pluginsConfiguration = buildPluginsConfiguration()
)
val subprojectDokkaConfigurations = childDokkaTasks.map { dokkaTask -> dokkaTask.buildDokkaConfiguration() }
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt
index 92560c94..03e0b4d7 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt
@@ -6,6 +6,7 @@ import org.gradle.api.tasks.*
import org.jetbrains.dokka.DokkaConfigurationImpl
import org.jetbrains.dokka.DokkaModuleDescriptionImpl
import org.jetbrains.dokka.DokkaMultimoduleBootstrapImpl
+import org.jetbrains.dokka.PluginConfigurationImpl
import java.io.File
@Suppress("unused") // Shall provide source compatibility if possible
@@ -49,7 +50,7 @@ abstract class DokkaMultiModuleTask : AbstractDokkaParentTask(DokkaMultimoduleBo
moduleName = moduleName.getSafe(),
outputDir = outputDirectory.getSafe(),
cacheRoot = cacheRoot.getSafe(),
- pluginsConfiguration = pluginsConfiguration.getSafe(),
+ pluginsConfiguration = buildPluginsConfiguration(),
failOnWarning = failOnWarning.getSafe(),
offlineMode = offlineMode.getSafe(),
pluginsClasspath = plugins.resolve().toList(),
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt
index ed3989af..9944bacb 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt
@@ -4,9 +4,7 @@ import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.internal.plugins.DslObject
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Nested
-import org.jetbrains.dokka.DokkaBootstrapImpl
-import org.jetbrains.dokka.DokkaConfigurationImpl
-import org.jetbrains.dokka.build
+import org.jetbrains.dokka.*
abstract class DokkaTask : AbstractDokkaTask(DokkaBootstrapImpl::class) {
@@ -34,8 +32,8 @@ abstract class DokkaTask : AbstractDokkaTask(DokkaBootstrapImpl::class) {
.also(::checkSourceSetDependencies)
.filterNot { it.suppress.getSafe() }
- override fun buildDokkaConfiguration(): DokkaConfigurationImpl {
- return DokkaConfigurationImpl(
+ override fun buildDokkaConfiguration(): DokkaConfigurationImpl =
+ DokkaConfigurationImpl(
moduleName = moduleName.getSafe(),
moduleVersion = moduleVersion.orNull,
outputDir = outputDirectory.getSafe(),
@@ -43,8 +41,7 @@ abstract class DokkaTask : AbstractDokkaTask(DokkaBootstrapImpl::class) {
offlineMode = offlineMode.getSafe(),
failOnWarning = failOnWarning.getSafe(),
sourceSets = unsuppressedSourceSets.build(),
- pluginsConfiguration = pluginsConfiguration.getSafe(),
+ pluginsConfiguration = buildPluginsConfiguration(),
pluginsClasspath = plugins.resolve().toList()
)
- }
}
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt
index 14b2a045..1c0c8080 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt
@@ -7,7 +7,6 @@ import org.gradle.api.provider.HasMultipleValues
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.util.Path
-import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt
index d1bfb0e1..68506876 100644
--- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt
+++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt
@@ -25,8 +25,8 @@ class DokkaConfigurationJsonTest {
this.offlineMode by true
this.outputDirectory by File("customOutputDir")
this.cacheRoot by File("customCacheRoot")
- this.pluginsConfiguration.put("0", "a")
- this.pluginsConfiguration.put("1", "b")
+ this.pluginsConfiguration.add(PluginConfigurationImpl("A", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value1" } """))
+ this.pluginsConfiguration.add(PluginConfigurationImpl("B", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value2" } """))
this.dokkaSourceSets.create("main") { sourceSet ->
sourceSet.displayName by "customSourceSetDisplayName"
sourceSet.reportUndocumented by true
diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt
index 99fca12d..2887f957 100644
--- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt
+++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt
@@ -3,6 +3,7 @@ package org.jetbrains.dokka.gradle
import org.gradle.kotlin.dsl.withType
import org.gradle.testfixtures.ProjectBuilder
import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.PluginConfigurationImpl
import org.jetbrains.dokka.toJsonString
import org.junit.Rule
import org.junit.rules.TemporaryFolder
@@ -32,8 +33,8 @@ class DokkaConfigurationSerializableTest {
this.offlineMode by true
this.outputDirectory by File("customOutputDir")
this.cacheRoot by File("customCacheRoot")
- this.pluginsConfiguration.put("0", "a")
- this.pluginsConfiguration.put("1", "b")
+ this.pluginsConfiguration.add(PluginConfigurationImpl("A", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value1" } """))
+ this.pluginsConfiguration.add(PluginConfigurationImpl("B", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value2" } """))
this.dokkaSourceSets.create("main") { sourceSet ->
sourceSet.displayName by "customSourceSetDisplayName"
sourceSet.reportUndocumented by true
diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTaskTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTaskTest.kt
index bea80f1e..fd449346 100644
--- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTaskTest.kt
+++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTaskTest.kt
@@ -4,9 +4,7 @@ package org.jetbrains.dokka.gradle
import org.gradle.kotlin.dsl.*
import org.gradle.testfixtures.ProjectBuilder
-import org.jetbrains.dokka.DokkaConfigurationImpl
-import org.jetbrains.dokka.DokkaException
-import org.jetbrains.dokka.DokkaModuleDescriptionImpl
+import org.jetbrains.dokka.*
import java.io.File
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -68,7 +66,7 @@ class DokkaMultiModuleTaskTest {
moduleName by "custom Module Name"
outputDirectory by project.buildDir.resolve("customOutputDirectory")
cacheRoot by File("customCacheRoot")
- pluginsConfiguration.put("pluginA", "configA")
+ pluginsConfiguration.add(PluginConfigurationImpl("pluginA", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value2" } """))
failOnWarning by true
offlineMode by true
}
@@ -79,7 +77,7 @@ class DokkaMultiModuleTaskTest {
moduleName = "custom Module Name",
outputDir = multiModuleTask.project.buildDir.resolve("customOutputDirectory"),
cacheRoot = File("customCacheRoot"),
- pluginsConfiguration = mapOf("pluginA" to "configA"),
+ pluginsConfiguration = mutableListOf(PluginConfigurationImpl("pluginA", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value2" } """)),
pluginsClasspath = emptyList(),
failOnWarning = true,
offlineMode = true,
diff --git a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt
index 89928b4c..b03d2811 100644
--- a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt
+++ b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt
@@ -12,6 +12,7 @@ import org.apache.maven.project.MavenProjectHelper
import org.apache.maven.repository.internal.MavenRepositorySystemUtils
import org.codehaus.plexus.archiver.Archiver
import org.codehaus.plexus.archiver.jar.JarArchiver
+import org.codehaus.plexus.util.xml.Xpp3Dom
import org.eclipse.aether.DefaultRepositorySystemSession
import org.eclipse.aether.RepositorySystem
import org.eclipse.aether.RepositorySystemSession
@@ -224,6 +225,16 @@ abstract class AbstractDokkaMojo(private val defaultDokkaPlugins: List<Dependenc
val logger = MavenDokkaLogger(log)
+ val pluginsConfiguration =
+ (mavenProject?.getPlugin("org.jetbrains.dokka:dokka-maven-plugin")?.configuration as? Xpp3Dom)
+ ?.getChild("pluginsConfiguration")?.children?.map {
+ PluginConfigurationImpl(
+ it.name,
+ DokkaConfiguration.SerializationFormat.XML,
+ it.toString()
+ )
+ }.orEmpty()
+
val configuration = DokkaConfigurationImpl(
moduleName = moduleName,
outputDir = File(getOutDir()),
@@ -233,9 +244,9 @@ abstract class AbstractDokkaMojo(private val defaultDokkaPlugins: List<Dependenc
pluginsClasspath = getArtifactByAether("org.jetbrains.dokka", "dokka-base", dokkaVersion) +
dokkaPlugins.map { getArtifactByAether(it.groupId, it.artifactId, it.version ?: dokkaVersion) }
.flatten(),
- pluginsConfiguration = mutableMapOf(), //TODO implement as it is in Gradle
+ pluginsConfiguration = pluginsConfiguration.toMutableList(),
modules = emptyList(),
- failOnWarning = failOnWarning
+ failOnWarning = failOnWarning,
)
val gen = DokkaGenerator(configuration, logger)