diff options
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> |
