diff options
| author | Ignat Beresnev <ignat.beresnev@jetbrains.com> | 2023-08-04 18:59:28 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-04 18:59:28 +0200 |
| commit | f7bd2ce1a5ef194643b078bd11a90fdf9b389c2b (patch) | |
| tree | 2f26d61ed1f90f5a2c3405b70c651607f97506d7 | |
| parent | b559131ddda8efea3394a0ea641460c4189769db (diff) | |
| download | dokka-f7bd2ce1a5ef194643b078bd11a90fdf9b389c2b.tar.gz dokka-f7bd2ce1a5ef194643b078bd11a90fdf9b389c2b.tar.bz2 dokka-f7bd2ce1a5ef194643b078bd11a90fdf9b389c2b.zip | |
Update Developer Guides (#3088)
27 files changed, 646 insertions, 618 deletions
diff --git a/.github/workflows/gh-pages-deploy-mkdocs.yml b/.github/workflows/gh-pages-deploy-dev-docs.yml index b212f55b..9b4fdb52 100644 --- a/.github/workflows/gh-pages-deploy-mkdocs.yml +++ b/.github/workflows/gh-pages-deploy-dev-docs.yml @@ -1,11 +1,11 @@ -name: Deploy MkDocs to GitHub Pages +name: Deploy developer docs to GitHub Pages on: push: branches: - master paths: - - 'mkdocs/**' + - 'docs-developer/**' release: types: [ published ] @@ -25,7 +25,7 @@ jobs: - uses: gradle/gradle-build-action@v2 with: gradle-home-cache-cleanup: true - - name: Get current dokka version + - name: Get current Dokka version run: echo "DOKKA_VERSION=`./gradlew :properties | grep '^version:.*' | cut -d ' ' -f 2`" >> $GITHUB_ENV working-directory: ./dokka - name: Build docs @@ -35,6 +35,6 @@ jobs: uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./dokka/mkdocs/build/mkdocs + publish_dir: ./dokka/docs-developer/build/mkdocs keep_files: true full_commit_message: Publish ${{ env.DOKKA_VERSION }} documentation diff --git a/docs-developer/README.md b/docs-developer/README.md new file mode 100644 index 00000000..d415dbf7 --- /dev/null +++ b/docs-developer/README.md @@ -0,0 +1,43 @@ +# Developer documentation + +This module contains developer documentation which is published to GitHub pages: +[kotlin.github.io/dokka](https://kotlin.github.io/dokka/). + +It is built using the [gradle-mkdocs-plugin](https://github.com/xvik/gradle-mkdocs-plugin). + +## Building + +You can build the documentation locally: + +```Bash +./gradlew :docs-developer:mkdocsBuild +``` + +The output directory is `build/mkdocs`. + +### Docker + +Alternatively, you can use Docker: + +```bash +docker run --rm -it -p 8000:8000 -v ./docs-developer/src/doc:/docs squidfunk/mkdocs-material +``` + +This will build the docs and start a web server under [localhost:8000/Kotlin/dokka](http://localhost:8000/Kotlin/dokka/). + +### Livereload server + +Alternatively, you can run a livereload server that automatically rebuilds documentation on every change: + +```Bash +./gradlew :docs-developer:mkdocsServe +``` + +By default, it is run under [localhost:3001](http://localhost:3001/), but you can change it in +[mkdocs.yml](src/doc/mkdocs.yml) by setting the `dev_addr` option. + +## Publishing + +The documentation is published automatically for all changes in master and for every GitHub release. + +See [gh-pages.yml](../.github/workflows/gh-pages-deploy-dev-docs.yml) workflow configuration for more details. diff --git a/mkdocs/build.gradle.kts b/docs-developer/build.gradle.kts index b3c52a0a..e920c6f8 100644 --- a/mkdocs/build.gradle.kts +++ b/docs-developer/build.gradle.kts @@ -2,7 +2,7 @@ import org.jetbrains.dokkaVersionType import org.jetbrains.DokkaVersionType plugins { - id("ru.vyarus.mkdocs") version "2.3.0" + id("ru.vyarus.mkdocs") version "2.4.0" } if (dokkaVersionType != DokkaVersionType.RELEASE) { diff --git a/docs-developer/src/doc/docs/developer_guide/architecture/architecture_overview.md b/docs-developer/src/doc/docs/developer_guide/architecture/architecture_overview.md new file mode 100644 index 00000000..d72dda91 --- /dev/null +++ b/docs-developer/src/doc/docs/developer_guide/architecture/architecture_overview.md @@ -0,0 +1,123 @@ +# Architecture overview + +Normally, you would think that a tool like Dokka simply parses some programming language sources and generates +HTML pages for whatever it sees along the way, with little to no abstractions. That would be the simplest and +the most straightforward way to implement an API documentation engine. + +However, it was clear that Dokka may need to generate documentation from various sources (not only Kotlin), that users +might request additional output formats (like Markdown), that users might need additional features like supporting +custom KDoc tags or rendering [mermaid.js](https://mermaid.js.org/) diagrams - all these things would require changing +a lot of code inside Dokka itself if all solutions were hardcoded. + +For this reason, Dokka was built from the ground up to be easily extensible and customizable by adding several layers +of abstractions to the data model, and by providing pluggable extension points, giving you the ability to introduce +selective changes on a given level. + +## Overview of data model + +Generating API documentation begins with input source files (`.kt`, `.java`, etc) and ends with some output files +(`.html`/`.md`, etc). However, to allow for extensibility and customization, several input and output independent +abstractions have been added to the data model. + +Below you can find the general pipeline of processing data gathered from sources and the explanation for each stage. + +```mermaid +flowchart TD + Input --> Documentables --> Pages --> Output +``` + +* `Input` - generalization of sources, by default Kotlin / Java sources, but could be virtually anything +* [`Documentables`](data_model/documentable_model.md) - unified data model that represents _any_ parsed sources as a + tree, independent of the source language. Examples of a `Documentable`: class, function, package, property, etc +* [`Pages`](data_model/page_content.md) - universal model that represents output pages (e.g a function/property page) + and the content it's composed of (lists, text, code blocks) that the users needs to see. Not to be confused with + `.html` pages. Goes hand in hand with the so-called [Content model](data_model/page_content.md#content-model). +* `Output` - specific output formats like HTML / Markdown / Javadoc and so on. This is a mapping of the pages/content + model to a human-readable and visual representation. For instance: + * `PageNode` is mapped as + * `.html` file for the HTML format + * `.md` file for the Markdown format + * `ContentList` is mapped as + * `<li>` / `<ul>` for the HTML format + * `1.` / `*` for the Markdown format + * `ContentCodeBlock` is mapped as + * `<code>` or `<pre>` with some CSS styles in the HTML format + * Text wrapped in triple backticks for the Markdown format + + +You, as a Dokka developer or a plugin writer, can use extension points to introduce selective changes to the +model on one particular level without altering everything else. + +For instance, if you wanted to make an annotation / function / class invisible in the final documentation, you would only +need to modify the `Documentables` level by filtering undesirable declarations out. If you wanted to display all overloaded +methods on the same page instead of on separate ones, you would only need to modify the `Pages` layer by merging multiple +pages into one, and so on. + +For a deeper dive into Dokka's model with more examples and details, +see sections about [Documentables](data_model/documentable_model.md) and [Page/Content](data_model/page_content.md) + +For an overview of existing extension points that let you transform Dokka's models, see +[Core extension points](extension_points/core_extension_points.md) and [Base extensions](extension_points/base_plugin.md). + +## Overview of extension points + +An _extension point_ usually represents a pluggable interface that performs an action during one of the stages of +generating documentation. An _extension_ is, therefore, an implementation of the interface which is extending the +extension point. + +You can create extension points, provide your own implementations (extensions) and configure them. All of +this is possible with Dokka's plugin / extension point API. + +Here's a sneak peek of the DSL: + +```kotlin +// declare your own plugin +class MyPlugin : DokkaPlugin() { + // create an extension point for developers to use + val signatureProvider by extensionPoint<SignatureProvider>() + + // provide a default implementation + val defaultSignatureProvider by extending { + signatureProvider with KotlinSignatureProvider() + } + + // register our own extension in Dokka's Base plugin by overriding its default implementation + val dokkaBasePlugin by lazy { plugin<DokkaBase>() } + val multimoduleLocationProvider by extending { + (dokkaBasePlugin.locationProviderFactory + providing MultimoduleLocationProvider::Factory + override dokkaBasePlugin.locationProvider) + } +} + +class MyExtension(val context: DokkaContext) { + + // use an existing extension + val signatureProvider: SignatureProvider = context.plugin<MyPlugin>().querySingle { signatureProvider } + + fun doSomething() { + signatureProvider.signature(..) + } +} + +interface SignatureProvider { + fun signature(documentable: Documentable): List<ContentNode> +} + +class KotlinSignatureProvider : SignatureProvider { + override fun signature(documentable: Documentable): List<ContentNode> = listOf() +} +``` + +For a deeper dive into extensions and extension points, see [Introduction to Extensions](extension_points/extension_points.md). + +For an overview of existing extension points, see [Core extension points](extension_points/core_extension_points.md) and +[Base extensions](extension_points/base_plugin.md). + +## Historical context + +This is a second iteration of Dokka that was built from scratch. + +If you want to learn more about why Dokka was redesigned this way, watch this great talk by Paweł Marks: +[New Dokka - Designed for Fearless Creativity](https://www.youtube.com/watch?v=OvFoTRhqaKg). The general principles +and general architecture are the same, although it may be outdated in some areas, so please double-check. diff --git a/mkdocs/src/doc/docs/developer_guide/architecture/data_model/documentables.md b/docs-developer/src/doc/docs/developer_guide/architecture/data_model/documentable_model.md index 5264553d..b30780fc 100644 --- a/mkdocs/src/doc/docs/developer_guide/architecture/data_model/documentables.md +++ b/docs-developer/src/doc/docs/developer_guide/architecture/data_model/documentable_model.md @@ -1,18 +1,22 @@ -# Documentables Model +# Documentable Model -Documentables represent data that is parsed from sources. Think of this data model as of something that could be -seen or produced by a compiler frontend, it's not far off from the truth. +The Documentable model represents the data that is parsed from some programming language sources. Think of this data as +of something that could be seen or produced by a compiler frontend, it's not far off from the truth. -By default, documentables are parsed from `Descriptor` (for `Kotlin`) -and [Psi](https://plugins.jetbrains.com/docs/intellij/psi.html) -(for `Java`) models. Code-wise, you can have a look at following classes: +By default, the documentables are created from: -* `DefaultDescriptorToDocumentableTranslator` - responsible for `Kotlin` -> `Documentable` mapping -* `DefaultPsiToDocumentableTranslator` - responsible for `Java` -> `Documentable` mapping +* Descriptors (Kotlin's K1 compiler) +* Symbols (Kotlin's K2 compiler) +* [PSI](https://plugins.jetbrains.com/docs/intellij/psi.html) (Java's model). -Upon creation, it's a collection of trees, each with `DModule` as root. +Code-wise, you can have a look at following classes: -Take some arbitrary `Kotlin` source code that is located within the same module: +* `DefaultDescriptorToDocumentableTranslator` - responsible for Kotlin -> `Documentable` mapping +* `DefaultPsiToDocumentableTranslator` - responsible for Java -> `Documentable` mapping + +Upon creation, the documentable model represents a collection of trees, each with `DModule` as root. + +Take some arbitrary Kotlin source code that is located within the same module: ```kotlin // Package 1 @@ -28,7 +32,7 @@ enum class Enum { } val topLevelProperty: String ``` -This would be represented roughly as the following `Documentable` tree: +This would be represented roughly as the following Documentable tree: ```mermaid flowchart TD @@ -43,20 +47,23 @@ flowchart TD secondPackage --> secondPackageProperty[DProperty] ``` -At later stages of transformation, all trees are folded into one (by `DocumentableMerger`). +At later stages of transformation, all trees are folded into one by +[DocumentableMerger](../extension_points/core_extension_points.md#documentablemerger). ## Documentable -The main building block of documentables model is `Documentable` class. It's the base class for all more specific types -that represent elements of parsed sources with mostly self-explanatory names (`DFunction`, `DPackage`, `DProperty`, etc) -. -`DClasslike` is the base class for class-like documentables such as `DClass`, `DEnum`, `DAnnotation`, etc. +The main building block of the documentable model is the `Documentable` class. It is the base class for all more specific +types. All implementations represent elements of source code with mostly self-explanatory names: `DFunction`, +`DPackage`, `DProperty`, and so on. + +`DClasslike` is the base class for all class-like documentables, such as `DClass`, `DEnum`, `DAnnotation` and others. + +The contents of each documentable normally represent what you would see in the source code. -The contents of each documentable normally represent what you would see in source code. For instance, if you open -`DClass`, you should find that it contains references to functions, properties, companion object, constructors and so -on. -`DEnum` should have references to enum entries, and `DPackage` can have references to both classlikes and top-level -functions and properties (`Kotlin`-specific). +For example, if you open +`DClass`, you should find that it contains references to functions, properties, companion objects, constructors and so +on. `DEnum` should have references to its entries, and `DPackage` can have references to both classlikes and top-level +functions and properties (Kotlin-specific). Here's an example of a documentable: @@ -85,7 +92,7 @@ data class DClass( ___ -There are three non-documentable classes that important for this model: +There are three non-documentable classes that are important for this model: * `DRI` * `SourceSetDependent` @@ -94,9 +101,9 @@ There are three non-documentable classes that important for this model: ### DRI `DRI` stans for _Dokka Resource Identifier_ - a unique value that identifies a specific `Documentable`. -All references and relations between documentables (other than direct ownership) are described using `DRI`. +All references and relations between the documentables (other than direct ownership) are described using `DRI`. -For example, `DFunction` with a parameter of type `Foo` has only `Foo`'s `DRI`, not the actual reference +For example, `DFunction` with a parameter of type `Foo` only has `Foo`'s `DRI`, but not the actual reference to `Foo`'s `Documentable` object. #### Example @@ -146,11 +153,11 @@ kotlinx.coroutines/MainCoroutineDispatcher/limitedParallelism/#kotlin.Int/Pointi ### SourceSetDependent `SourceSetDependent` helps handling multiplatform data by associating platform-specific data (declared with either -`expect` or `actual` modifier) with particular +`expect` or `actual` modifiers) with particular [source sets](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets). -This comes in handy if `expect`/`actual` declarations differ. For instance, the default value for `actual` might differ -from that declared in `expect`, or code comments written for `expect` might be different from what's written +This comes in handy if the `expect` / `actual` declarations differ. For example, the default value for `actual` might +differ from that declared in `expect`, or code comments written for `expect` might be different from what's written for `actual`. Under the hood, it's a `typealias` to a `Map`: @@ -171,18 +178,18 @@ ___ ## Documentation model -Documentation model is used alongside Documentables to store data obtained by parsing -code comments (such as `KDoc`/`Javadoc`). +The Documentation model is used alongside documentables to store data obtained by parsing +code comments (such as KDocs / Javadocs). ### DocTag `DocTag` describes a specific documentation syntax element. -It's universal across source languages. For instance, DocTag `B` is the same for `**bold**` in `Kotlin` and -`<b>bold</b>` in `Java`. +It's universal across language sources. For example, the DocTag `B` is the same for `**bold**` in Kotlin and +`<b>bold</b>` in Java. -However, some `DocTag` elements are specific to a certain language, there are many such examples for `Java` -because it allows HTML tags inside `Javadoc` comments, some of which are simply not possible to reproduce with `Markdown`. +However, some DocTag elements are specific to one language. There are many such examples for Java, because it allows +HTML tags inside the Javadoc comments, some of which are simply not possible to reproduce with Markdown that KDocs use. `DocTag` elements can be deeply nested with other `DocTag` children elements. @@ -218,10 +225,9 @@ data class CodeBlock( ### TagWrapper -`TagWrapper` describes the whole comment description or a specific comment tag. -For example: `@see` / `@author` / `@return`. +`TagWrapper` describes the whole comment description or a specific comment tag. For example: `@see` / `@author` / `@return`. -Since each such section may contain formatted text inside of it, each `TagWrapper` has `DocTag` children. +Since each such section may contain formatted text inside it, each `TagWrapper` has `DocTag` children. ```kotlin /** diff --git a/mkdocs/src/doc/docs/developer_guide/architecture/data_model/extra.md b/docs-developer/src/doc/docs/developer_guide/architecture/data_model/extra.md index 0abbc70e..d7412e36 100644 --- a/mkdocs/src/doc/docs/developer_guide/architecture/data_model/extra.md +++ b/docs-developer/src/doc/docs/developer_guide/architecture/data_model/extra.md @@ -2,24 +2,13 @@ ## Introduction -`ExtraProperty` classes are used both by [Documentable](documentables.md) and [Content](page_content.md#content-model) -models. - -Source code for `ExtraProperty`: - -```kotlin -interface ExtraProperty<in C : Any> { - interface Key<in C : Any, T : Any> { - fun mergeStrategyFor(left: T, right: T): MergeStrategy<C> = MergeStrategy.Fail { - throw NotImplementedError("Property merging for $this is not implemented") - } - } +`ExtraProperty` is used to store any additional information that falls outside of the regular model. It is highly +recommended to use extras to provide any additional information when creating custom Dokka plugins. - val key: Key<C, *> -} -``` +`ExtraProperty` classes are available both in the [Documentable](documentable_model.md) and the [Content](page_content.md#content-model) +models. -To declare a new extra, you need to implement `ExtraProperty` interface. It is advised to use following pattern +To create a new extra, you need to implement the `ExtraProperty` interface. It is advised to use the following pattern when declaring new extras: ```kotlin @@ -32,14 +21,14 @@ data class CustomExtra( } ``` -Merge strategy (`mergeStrategyFor` method) for extras is invoked during -[merging](../extension_points/core_extensions.md#documentablemerger) if documentables from different -[source sets](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets) each -have their own `Extra` of the same type. +Merge strategy (the `mergeStrategyFor` method) for extras is invoked during the +[merging](../extension_points/core_extension_points.md#documentablemerger) of the documentables from different +[source sets](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets), when the documentables being +merged have their own `Extra` of the same type. ## PropertyContainer -All extras for `ContentNode` and `Documentable` classes are stored in `PropertyContainer<C : Any>` class instances. +All extras for `ContentNode` and `Documentable` classes are stored in the `PropertyContainer<C : Any>` class instances. ```kotlin data class DFunction( @@ -51,26 +40,29 @@ data class DFunction( `PropertyContainer` has a number of convenient functions for handling extras in a collection-like manner. -The `C` generic class parameter limits the type of properties that can be stored in the container - it must -match generic `C` class parameter from `ExtraProperty` interface. This allows creating extra properties +The generic class parameter `C` limits the types of properties that can be stored in the container - it must +match the generic `C` class parameter from the `ExtraProperty` interface. This allows creating extra properties which can only be stored in a specific `Documentable`. ## Usage example -In following example we will create a `DFunction`-only property, store it and then retrieve its value: +In following example we will create a `DFunction`-only extra property, store it and then retrieve its value: ```kotlin +// Extra that is applicable only to DFunction data class CustomExtra(val customExtraValue: String) : ExtraProperty<DFunction> { override val key: ExtraProperty.Key<Documentable, *> = CustomExtra companion object: ExtraProperty.Key<Documentable, CustomExtra> } +// Storing it inside the documentable fun DFunction.withCustomExtraProperty(data: String): DFunction { return this.copy( extra = extra + CustomExtra(data) ) } +// Retrieveing it from the documentable fun DFunction.getCustomExtraPropertyValue(): String? { return this.extra[CustomExtra]?.customExtraValue } diff --git a/docs-developer/src/doc/docs/developer_guide/architecture/data_model/page_content.md b/docs-developer/src/doc/docs/developer_guide/architecture/data_model/page_content.md new file mode 100644 index 00000000..eb85200f --- /dev/null +++ b/docs-developer/src/doc/docs/developer_guide/architecture/data_model/page_content.md @@ -0,0 +1,144 @@ +# Page / Content Model + +Even though the `Page` and `Content` models reside on the same level (under `Page`), it is easier to view them as two +different models altogether, even though `Content` is only used in conjunction with and inside the `Page` model only. + +## Page + +The Page model represents the structure of documentation pages to be generated. During rendering, each page +is processed separately, so one page corresponds to exactly one output file. + +The Page model is independent of the final output format. In other words, it's universal. Which file extension the pages +should be created as (`.html`, `.md`, etc), and how, is up to the +[Renderer](../extension_points/core_extension_points.md#renderer) extension. + +Subclasses of the `PageNode` class represent the different kinds of pages, such as `ModulePage`, `PackagePage`, +`ClasslikePage`, `MemberPage` and so on. + +The Page model can be represented as a tree, with `RootPageNode` at the root. + +Here's an example of how an arbitrary project's `Page` tree might look like, if the project consists of a module with +3 packages, one of which contains a top level function, a top level property and a class, inside which there's a function +and a property: + +```mermaid +flowchart TD + RootPageNode --> firstPackage[PackagePageNode] + RootPageNode --> secondPackage[PackagePageNode] + RootPageNode --> thirdPackage[PackagePageNode] + firstPackage --> firstPackageFirstMember[MemberPageNode - Function] + firstPackage --> firstPackageSecondMember[MemberPageNode - Property] + firstPackage ---> firstPackageClasslike[ClasslikePageNode - Class] + firstPackageClasslike --> firstPackageClasslikeFirstMember[MemberPageNode - Function] + firstPackageClasslike --> firstPackageClasslikeSecondMember[MemberPageNode - Property] + secondPackage --> etcOne[...] + thirdPackage --> etcTwo[...] +``` + +Almost all pages are derivatives of `ContentPage` - it's the type of a page that has user-visible content on it. + +## Content Model + +The Content model describes what the pages consist of. It is essentially a set of building blocks that you can put +together to represent some content. It is also output-format independent and universal. + +For an example, have a look at the subclasses of `ContentNode`: `ContentText`, `ContentList`, `ContentTable`, +`ContentCodeBlock`, `ContentHeader` and so on -- all self-explanatory. You can group chunks of content together with +`ContentGroup` - for example, to wrap all children with a style. + +```kotlin +// real example of composing content using the `DocumentableContentBuilder` DSL +orderedList { + item { + text("This list contains a nested table:") + table { + header { + text("Col1") + text("Col2") + } + row { + text("Text1") + text("Text2") + } + } + } + item { + group(styles = setOf(TextStyle.Bold)) { + text("This is bald") + text("This is also bald") + } + } +} +``` + +It is the responsibility of the `Renderer` (i.e a specific output format) to render it in a way the user can process it, +be it visually (html pages) or otherwise (json). + +For instance, `HtmlRenderer` might render `ContentCodeBlock` as `<code>text</code>`, but `CommonmarkRenderer` might +render it using backticks. + +### DCI + +Each node is identified by a unique `DCI`, which stands for _Dokka Content Identifier_. + +`DCI` aggregates `DRI`s of all documentables that are used by the given `ContentNode`. + +```kotlin +data class DCI(val dri: Set<DRI>, val kind: Kind) +``` + +All references to other nodes (other than direct ownership) are described using `DCI`. + +### ContentKind + +`ContentKind` represents a grouping of content of one kind that can be rendered as part of a composite +page, like a single one tab or a block within a class's page. + +For example, on the same page that describes a class you can have multiple sections (== `ContentKind`s). +One to describe functions, one to describe properties, another one to describe the constructors, and so on. + +### Styles + +Each `ContentNode` has a `styles` property in case you want to indicate to the `Renderer` that this content needs to be +rendered in a certain way. + +```kotlin +group(styles = setOf(TextStyle.Paragraph)) { + text("Text1", styles = setOf(TextStyle.Bold)) + text("Text2", styles = setOf(TextStyle.Italic)) +} +``` + +It is responsibility of the `Renderer` (i.e a specific output format) to render it in a way the user can process it. +For instance, `HtmlRenderer` might render `TextStyle.Bold` as `<b>text</b>`, but `CommonmarkRenderer` might render it +as `**text**`. + +There's a number of existing styles that you can use, most of them are supported by the `HtmlRenderer` extension out of +the box: + +```kotlin +// for code highlighting +enum class TokenStyle : Style { + Keyword, Punctuation, Function, Operator, Annotation, + Number, String, Boolean, Constant, Builtin, ... +} + +enum class TextStyle : Style { + Bold, Italic, Strong, Strikethrough, Paragraph, ... +} + +enum class ContentStyle : Style { + TabbedContent, RunnableSample, Wrapped, Indented, ... +} +``` + +### Extra + +`ExtraProperty` is used to store any additional information that falls outside of the regular model. + +It is highly recommended to use extras to provide any additional information when creating custom Dokka plugins. + +All `ExtraProperty` elements from the `Documentable` model are propagated into the `Content` model, and are available +in the `Renderer` extensions. + +This element is a bit complex, so you can read more about how to use it [in a separate section](extra.md). diff --git a/docs-developer/src/doc/docs/developer_guide/architecture/extension_points/base_plugin.md b/docs-developer/src/doc/docs/developer_guide/architecture/extension_points/base_plugin.md new file mode 100644 index 00000000..88579be7 --- /dev/null +++ b/docs-developer/src/doc/docs/developer_guide/architecture/extension_points/base_plugin.md @@ -0,0 +1,33 @@ +# Base plugin + +`DokkaBase` represents Dokka's _Base_ plugin, which provides a number of sensible default implementations for +`CoreExtensions`, as well as declares its own, more high-level abstractions and extension points to be used from other +plugins and output formats. + +If you want to develop a simple plugin that only changes a few details, it is very convenient to rely on +default implementations and use extension points defined in `DokkaBase`, as it reduces the scope of changes you need to make. + +`DokkaBase` is used extensively in Dokka's own output formats. + +You can learn how to add, use, override and configure extensions and extension points in +[Introduction to Extensions](extension_points.md) - all of that information is applicable to the `DokkaBase` plugin as well. + +## Extension points + +Some notable extension points defined in Dokka's Base plugin. + +### PreMergeDocumentableTransformer + +`PreMergeDocumentableTransformer` is very similar to the +[DocumentableTransformer](core_extension_points.md#documentabletransformer) core extension point, but it is used during +an earlier stage by the [Single module generation](generation_implementations.md#singlemodulegeneration). + +This extension point allows you to apply any transformations to the [Documentables model](../data_ |
