aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorBłażej Kardyś <bkardys@virtuslab.com>2020-11-16 19:46:31 +0100
committerBłażej Kardyś <bkardys@virtuslab.com>2020-11-27 03:15:02 +0100
commit076a5f421c5e4621539efd814be612f43fef33f5 (patch)
tree90b399c459cccbd1e3010778320d49b7b806b1fb /plugins
parentc203be9fb65ee221875b4e1c865bcd289a85e69c (diff)
downloaddokka-076a5f421c5e4621539efd814be612f43fef33f5.tar.gz
dokka-076a5f421c5e4621539efd814be612f43fef33f5.tar.bz2
dokka-076a5f421c5e4621539efd814be612f43fef33f5.zip
Adding inter-module link resolving template strategy for Gfm
Diffstat (limited to 'plugins')
-rw-r--r--plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt13
-rw-r--r--plugins/all-module-page/src/main/kotlin/MultimoduleLocationProvider.kt7
-rw-r--r--plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt10
-rw-r--r--plugins/all-module-page/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt54
-rw-r--r--plugins/all-module-page/src/main/kotlin/templates/ExternalModuleLinkResolver.kt49
-rw-r--r--plugins/all-module-page/src/main/kotlin/templates/FallbackTemplateProcessingStrategy.kt18
-rw-r--r--plugins/all-module-page/src/main/kotlin/templates/TemplateProcessor.kt14
-rw-r--r--plugins/base/src/main/kotlin/DokkaBase.kt3
-rw-r--r--plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt2
-rw-r--r--plugins/base/src/main/kotlin/templating/ResolveLinkCommand.kt1
-rw-r--r--plugins/gfm/build.gradle.kts1
-rw-r--r--plugins/gfm/gfm-all-module-page/build.gradle.kts3
-rw-r--r--plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmAllModulesPagaPlugin.kt8
-rw-r--r--plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmMultimoduleLocationProvider.kt30
-rw-r--r--plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmTemplateProcessingStrategy.kt45
-rw-r--r--plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/gfmTemplating.kt19
-rw-r--r--plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/renderer/CommonmarkRenderer.kt15
17 files changed, 199 insertions, 93 deletions
diff --git a/plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt b/plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt
index a65c0c58..bcc43043 100644
--- a/plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt
+++ b/plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt
@@ -10,6 +10,7 @@ import org.jetbrains.dokka.transformers.pages.PageTransformer
class AllModulesPagePlugin : DokkaPlugin() {
val templateProcessor by extensionPoint<TemplateProcessor>()
+ val templateProcessingStrategy by extensionPoint<TemplateProcessingStrategy>()
val allModulePageCreator by extensionPoint<PageCreator>()
val allModulePageTransformer by extensionPoint<PageTransformer>()
@@ -33,7 +34,17 @@ class AllModulesPagePlugin : DokkaPlugin() {
}
val defaultTemplateProcessor by extending {
- templateProcessor providing { DefaultTemplateProcessor(it, DirectiveBasedTemplateProcessingStrategy(it)) }
+ templateProcessor providing ::DefaultTemplateProcessor
+ }
+
+ val directiveBasedHtmlTemplateProcessingStrategy by extending {
+ templateProcessingStrategy providing ::DirectiveBasedHtmlTemplateProcessingStrategy order {
+ before(fallbackProcessingStrategy)
+ }
+ }
+
+ val fallbackProcessingStrategy by extending {
+ templateProcessingStrategy providing ::FallbackTemplateProcessingStrategy
}
val pathToRootSubstitutor by extending {
diff --git a/plugins/all-module-page/src/main/kotlin/MultimoduleLocationProvider.kt b/plugins/all-module-page/src/main/kotlin/MultimoduleLocationProvider.kt
index 1e7fb60c..cb1eca7b 100644
--- a/plugins/all-module-page/src/main/kotlin/MultimoduleLocationProvider.kt
+++ b/plugins/all-module-page/src/main/kotlin/MultimoduleLocationProvider.kt
@@ -10,17 +10,16 @@ import org.jetbrains.dokka.pages.PageNode
import org.jetbrains.dokka.pages.RootPageNode
import org.jetbrains.dokka.plugability.DokkaContext
-class MultimoduleLocationProvider(private val root: RootPageNode, context: DokkaContext) : DokkaBaseLocationProvider(root, context, ".html") {
-
- private val defaultLocationProvider = DokkaLocationProvider(root, context)
+open class MultimoduleLocationProvider(private val root: RootPageNode, val context: DokkaContext, private val fileExtension: String = ".html") : DokkaBaseLocationProvider(root, context, fileExtension) {
+ protected open val defaultLocationProvider = DokkaLocationProvider(root, context)
val paths = context.configuration.modules.map {
it.name to it.relativePathToOutputDirectory
}.toMap()
override fun resolve(dri: DRI, sourceSets: Set<DisplaySourceSet>, context: PageNode?) =
dri.takeIf { it.packageName == MULTIMODULE_PACKAGE_PLACEHOLDER }?.classNames?.let { paths[it] }?.let {
- "$it/${identifierToFilename(dri.classNames.orEmpty())}/index.html"
+ "$it/${identifierToFilename(dri.classNames.orEmpty())}/index$fileExtension"
} ?: defaultLocationProvider.resolve(dri, sourceSets, context)
override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean) =
diff --git a/plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt b/plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt
index 46c8bf82..123dee2b 100644
--- a/plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt
+++ b/plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt
@@ -18,6 +18,7 @@ import org.jetbrains.dokka.model.doc.P
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.dokka.transformers.pages.PageCreator
import org.jetbrains.dokka.utilities.DokkaLogger
@@ -27,14 +28,11 @@ class MultimodulePageCreator(
) : PageCreator {
private val logger: DokkaLogger = context.logger
+ private val commentsConverter by lazy { context.plugin<DokkaBase>().querySingle { commentsToContentConverter } }
+ private val signatureProvider by lazy { context.plugin<DokkaBase>().querySingle { signatureProvider } }
+
override fun invoke(): RootPageNode {
val modules = context.configuration.modules
-
- val commentsConverter = context.plugin(DokkaBase::class)?.querySingle { commentsToContentConverter }
- val signatureProvider = context.plugin(DokkaBase::class)?.querySingle { signatureProvider }
- if (commentsConverter == null || signatureProvider == null)
- throw IllegalStateException("Both comments converter and signature provider must not be null")
-
val sourceSetData = emptySet<DokkaSourceSet>()
val builder = PageContentBuilder(commentsConverter, signatureProvider, context.logger)
val contentNode = builder.contentFor(
diff --git a/plugins/all-module-page/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt b/plugins/all-module-page/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt
index 92f39779..feba2d4e 100644
--- a/plugins/all-module-page/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt
+++ b/plugins/all-module-page/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt
@@ -5,9 +5,6 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jetbrains.dokka.allModulesPage.AllModulesPagePlugin
-import org.jetbrains.dokka.base.DokkaBase
-import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation
-import org.jetbrains.dokka.base.resolvers.shared.PackageList
import org.jetbrains.dokka.base.templating.*
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
@@ -16,16 +13,16 @@ import org.jsoup.Jsoup
import org.jsoup.nodes.*
import org.jsoup.parser.Tag
import java.io.File
-import java.net.URL
import java.nio.file.Files
import java.util.concurrent.ConcurrentHashMap
-class DirectiveBasedTemplateProcessingStrategy(private val context: DokkaContext) : TemplateProcessingStrategy {
+class DirectiveBasedHtmlTemplateProcessingStrategy(private val context: DokkaContext) : TemplateProcessingStrategy {
private val navigationFragments = ConcurrentHashMap<String, Element>()
private val substitutors = context.plugin<AllModulesPagePlugin>().query { substitutor }
+ private val externalModuleLinkResolver = ExternalModuleLinkResolver(context)
- override suspend fun process(input: File, output: File): Unit = coroutineScope {
+ override suspend fun process(input: File, output: File): Boolean = coroutineScope {
if (input.extension == "html") {
launch {
val document = withContext(IO) { Jsoup.parse(input, "UTF-8") }
@@ -40,11 +37,8 @@ class DirectiveBasedTemplateProcessingStrategy(private val context: DokkaContext
}
withContext(IO) { Files.write(output.toPath(), listOf(document.outerHtml())) }
}
- } else {
- launch(IO) {
- Files.copy(input.toPath(), output.toPath())
- }
- }
+ true
+ } else false
}
private fun substitute(element: Element, commandContext: TemplatingContext<SubstitutionCommand>) {
@@ -118,32 +112,9 @@ class DirectiveBasedTemplateProcessingStrategy(private val context: DokkaContext
}
private fun resolveLink(it: Element, command: ResolveLinkCommand, fileContext: File) {
- val elpFactory = context.plugin<DokkaBase>().query { externalLocationProviderFactory }
-
- val packageLists =
- context.configuration.modules.map { it.sourceOutputDirectory.resolve(it.relativePathToOutputDirectory) }
- .map { module ->
- module to PackageList.load(
- URL("file:" + module.resolve("package-list").path),
- 8,
- true
- )
- }.toMap()
-
- val externalDocumentations =
- packageLists.map { (module, pckgList) ->
- ExternalDocumentation(
- URL("file:/${module.name}/${module.name}"),
- pckgList!!
- )
- }
- val elps = elpFactory
- .flatMap { externalDocumentations.map { ed -> it.getExternalLocationProvider(ed) } }
- .filterNotNull()
-
- val absoluteLink = elps.mapNotNull { it.resolve(command.dri) }.firstOrNull()
- if (absoluteLink == null) {
+ val link = externalModuleLinkResolver.resolve(command.dri, fileContext)
+ if (link == null) {
val children = it.childNodes().toList()
val attributes = Attributes().apply {
put("data-unresolved-link", command.dri.toString())
@@ -155,17 +126,6 @@ class DirectiveBasedTemplateProcessingStrategy(private val context: DokkaContext
return
}
- val modulePath = context.configuration.outputDir.absolutePath.split(File.separator)
- val contextPath = fileContext.absolutePath.split(File.separator)
- val commonPathElements = modulePath.zip(contextPath)
- .takeWhile { (a, b) -> a == b }.count()
-
- // -1 here to not drop the last directory
- val link =
- (List(contextPath.size - commonPathElements - 1) { ".." } + modulePath.drop(commonPathElements)).joinToString(
- "/"
- ) + absoluteLink.removePrefix("file:")
-
val attributes = Attributes().apply {
put("href", link) // TODO: resolve
}
diff --git a/plugins/all-module-page/src/main/kotlin/templates/ExternalModuleLinkResolver.kt b/plugins/all-module-page/src/main/kotlin/templates/ExternalModuleLinkResolver.kt
new file mode 100644
index 00000000..5a3d3d33
--- /dev/null
+++ b/plugins/all-module-page/src/main/kotlin/templates/ExternalModuleLinkResolver.kt
@@ -0,0 +1,49 @@
+package org.jetbrains.dokka.allModulesPage.templates
+
+import org.jetbrains.dokka.base.DokkaBase
+import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation
+import org.jetbrains.dokka.base.resolvers.shared.PackageList
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.plugin
+import org.jetbrains.dokka.plugability.query
+import java.net.URL
+import java.io.File
+
+class ExternalModuleLinkResolver(val context: DokkaContext) {
+ private val elpFactory = context.plugin<DokkaBase>().query { externalLocationProviderFactory }
+ private val externalDocumentations by lazy(::setupExternalDocumentations)
+ private val elps by lazy {
+ elpFactory.flatMap { externalDocumentations.map { ed -> it.getExternalLocationProvider(ed) } }.filterNotNull()
+ }
+
+ private fun setupExternalDocumentations(): List<ExternalDocumentation> {
+ val packageLists =
+ context.configuration.modules.map { it.sourceOutputDirectory.resolve(it.relativePathToOutputDirectory) }
+ .map { module ->
+ module to PackageList.load(
+ URL("file:" + module.resolve("package-list").path),
+ 8,
+ true
+ )
+ }.toMap()
+ return packageLists.map { (module, pckgList) ->
+ ExternalDocumentation(
+ URL("file:/${module.name}/${module.name}"),
+ pckgList!!
+ )
+ }
+ }
+
+ fun resolve(dri: DRI, fileContext: File): String? {
+ val absoluteLink = elps.mapNotNull { it.resolve(dri) }.firstOrNull() ?: return null
+ val modulePath = context.configuration.outputDir.absolutePath.split(File.separator)
+ val contextPath = fileContext.absolutePath.split(File.separator)
+ val commonPathElements = modulePath.zip(contextPath)
+ .takeWhile { (a, b) -> a == b }.count()
+
+ return (List(contextPath.size - commonPathElements - 1) { ".." } + modulePath.drop(commonPathElements)).joinToString(
+ "/"
+ ) + absoluteLink.removePrefix("file:")
+ }
+} \ No newline at end of file
diff --git a/plugins/all-module-page/src/main/kotlin/templates/FallbackTemplateProcessingStrategy.kt b/plugins/all-module-page/src/main/kotlin/templates/FallbackTemplateProcessingStrategy.kt
new file mode 100644
index 00000000..9b5251ac
--- /dev/null
+++ b/plugins/all-module-page/src/main/kotlin/templates/FallbackTemplateProcessingStrategy.kt
@@ -0,0 +1,18 @@
+package org.jetbrains.dokka.allModulesPage.templates
+
+import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
+import org.jetbrains.dokka.plugability.DokkaContext
+import java.io.File
+import java.nio.file.Files
+
+class FallbackTemplateProcessingStrategy(dokkaContext: DokkaContext) : TemplateProcessingStrategy {
+
+ override suspend fun process(input: File, output: File): Boolean = coroutineScope {
+ launch(IO) {
+ Files.copy(input.toPath(), output.toPath())
+ }
+ true
+ }
+} \ No newline at end of file
diff --git a/plugins/all-module-page/src/main/kotlin/templates/TemplateProcessor.kt b/plugins/all-module-page/src/main/kotlin/templates/TemplateProcessor.kt
index eafc3669..18d63df0 100644
--- a/plugins/all-module-page/src/main/kotlin/templates/TemplateProcessor.kt
+++ b/plugins/all-module-page/src/main/kotlin/templates/TemplateProcessor.kt
@@ -1,8 +1,11 @@
package org.jetbrains.dokka.allModulesPage.templates
import kotlinx.coroutines.*
+import org.jetbrains.dokka.allModulesPage.AllModulesPagePlugin
import org.jetbrains.dokka.base.templating.Command
import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.plugin
+import org.jetbrains.dokka.plugability.query
import org.jsoup.nodes.Element
import java.io.File
import java.nio.file.Files
@@ -14,14 +17,16 @@ interface TemplateProcessor {
}
interface TemplateProcessingStrategy {
- suspend fun process(input: File, output: File)
+ suspend fun process(input: File, output: File): Boolean
suspend fun finish(output: File) {}
}
class DefaultTemplateProcessor(
private val context: DokkaContext,
- private val strategy: TemplateProcessingStrategy
): TemplateProcessor {
+
+ private val strategies: List<TemplateProcessingStrategy> = context.plugin<AllModulesPagePlugin>().query { templateProcessingStrategy }
+
override fun process() = runBlocking(Dispatchers.Default) {
coroutineScope {
context.configuration.modules.forEach {
@@ -30,7 +35,8 @@ class DefaultTemplateProcessor(
}
}
}
- strategy.finish(context.configuration.outputDir)
+ strategies.map { it.finish(context.configuration.outputDir) }
+ Unit
}
private suspend fun File.visit(target: File): Unit = coroutineScope {
@@ -41,7 +47,7 @@ class DefaultTemplateProcessor(
launch { source.resolve(it).visit(target.resolve(it)) }
}
} else {
- strategy.process(source, target)
+ strategies.asSequence().first { it.process(source, target) }
}
}
}
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt
index ac070ab4..c4dacdcd 100644
--- a/plugins/base/src/main/kotlin/DokkaBase.kt
+++ b/plugins/base/src/main/kotlin/DokkaBase.kt
@@ -32,7 +32,8 @@ import org.jetbrains.dokka.plugability.DokkaPlugin
import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer
import org.jetbrains.dokka.transformers.pages.PageTransformer
-class DokkaBase : DokkaPlugin() {
+class
+DokkaBase : DokkaPlugin() {
val preMergeDocumentableTransformer by extensionPoint<PreMergeDocumentableTransformer>()
val pageMergerStrategy by extensionPoint<PageMergerStrategy>()
diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
index 182ecbc6..d76ba597 100644
--- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt
@@ -104,7 +104,7 @@ abstract class DefaultRenderer<T>(
pageContext: ContentPage,
sourceSetRestriction: Set<DisplaySourceSet>? = null
) {
- if (sourceSetRestriction == null || node.sourceSets.any { it in sourceSetRestriction }) {
+ if (sourceSetRestriction.isNullOrEmpty() || node.sourceSets.any { it in sourceSetRestriction }) {
when (node) {
is ContentText -> buildText(node)
is ContentHeader -> buildHeader(node, pageContext, sourceSetRestriction)
diff --git a/plugins/base/src/main/kotlin/templating/ResolveLinkCommand.kt b/plugins/base/src/main/kotlin/templating/ResolveLinkCommand.kt
index 83b7e0d8..1cc3e773 100644
--- a/plugins/base/src/main/kotlin/templating/ResolveLinkCommand.kt
+++ b/plugins/base/src/main/kotlin/templating/ResolveLinkCommand.kt
@@ -1,6 +1,5 @@
package org.jetbrains.dokka.base.templating
-import com.fasterxml.jackson.annotation.JsonTypeInfo
import org.jetbrains.dokka.links.DRI
class ResolveLinkCommand(val dri: DRI): Command
diff --git a/plugins/gfm/build.gradle.kts b/plugins/gfm/build.gradle.kts
index 33917cdf..6400dba1 100644
--- a/plugins/gfm/build.gradle.kts
+++ b/plugins/gfm/build.gradle.kts
@@ -4,6 +4,7 @@ dependencies {
implementation(project(":plugins:base"))
testImplementation(project(":plugins:base"))
testImplementation(project(":plugins:base:base-test-utils"))
+ implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.11.1")
}
registerDokkaArtifactPublication("gfmPlugin") {
diff --git a/plugins/gfm/gfm-all-module-page/build.gradle.kts b/plugins/gfm/gfm-all-module-page/build.gradle.kts
index 66deb291..85f83587 100644
--- a/plugins/gfm/gfm-all-module-page/build.gradle.kts
+++ b/plugins/gfm/gfm-all-module-page/build.gradle.kts
@@ -4,6 +4,9 @@ dependencies {
implementation(project(":plugins:base"))
implementation(project(":plugins:gfm"))
implementation(project(":plugins:all-module-page"))
+
+ val coroutines_version: String by project
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
}
registerDokkaArtifactPublication("dokkaGfmAllModulePage") {
diff --git a/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmAllModulesPagaPlugin.kt b/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmAllModulesPagaPlugin.kt
index 8052a762..eb5e7e45 100644
--- a/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmAllModulesPagaPlugin.kt
+++ b/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmAllModulesPagaPlugin.kt
@@ -1,6 +1,7 @@
package org.jetbrains.dokka.gfm.allModulesPage
import org.jetbrains.dokka.allModulesPage.AllModulesPagePlugin
+import org.jetbrains.dokka.allModulesPage.templates.DefaultTemplateProcessor
import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.gfm.GfmPlugin
import org.jetbrains.dokka.plugability.DokkaPlugin
@@ -17,4 +18,11 @@ class GfmAllModulesPagePlugin : DokkaPlugin() {
(dokkaBase.locationProviderFactory providing GfmMultimoduleLocationProvider::Factory
override listOf(allModulesPagePlugin.multimoduleLocationProvider, gfmPlugin.locationProvider))
}
+
+ val defaultTemplateProcessor by extending {
+ (allModulesPagePlugin.templateProcessingStrategy
+ providing ::GfmTemplateProcessingStrategy
+ override allModulesPagePlugin.directiveBasedHtmlTemplateProcessingStrategy
+ order { before(allModulesPagePlugin.fallbackProcessingStrategy) })
+ }
} \ No newline at end of file
diff --git a/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmMultimoduleLocationProvider.kt b/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmMultimoduleLocationProvider.kt
index d49be426..9f2ee140 100644
--- a/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmMultimoduleLocationProvider.kt
+++ b/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmMultimoduleLocationProvider.kt
@@ -1,38 +1,14 @@
package org.jetbrains.dokka.gfm.allModulesPage
-import org.jetbrains.dokka.base.resolvers.local.DokkaBaseLocationProvider
-import org.jetbrains.dokka.base.resolvers.local.DokkaLocationProvider
+import org.jetbrains.dokka.allModulesPage.MultimoduleLocationProvider
import org.jetbrains.dokka.base.resolvers.local.LocationProviderFactory
import org.jetbrains.dokka.gfm.location.MarkdownLocationProvider
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.model.DisplaySourceSet
-import org.jetbrains.dokka.pages.PageNode
import org.jetbrains.dokka.pages.RootPageNode
import org.jetbrains.dokka.plugability.DokkaContext
-class GfmMultimoduleLocationProvider(private val root: RootPageNode, context: DokkaContext) : DokkaBaseLocationProvider(root, context, ".md") {
+class GfmMultimoduleLocationProvider(root: RootPageNode, context: DokkaContext) : MultimoduleLocationProvider(root, context, ".md") {
- private val defaultLocationProvider = MarkdownLocationProvider(root, context)
-
- val paths = context.configuration.modules.map {
- it.name to it.relativePathToOutputDirectory
- }.toMap()
-
- override fun resolve(dri: DRI, sourceSets: Set<DisplaySourceSet>, context: PageNode?) =
- dri.takeIf { it.packageName == MULTIMODULE_PACKAGE_PLACEHOLDER }?.classNames?.let { paths[it] }?.let {
- "$it/${DokkaLocationProvider.identifierToFilename(dri.classNames.orEmpty())}/index.md"
- } ?: defaultLocationProvider.resolve(dri, sourceSets, context)
-
- override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean) =
- defaultLocationProvider.resolve(node, context, skipExtension)
-
- override fun pathToRoot(from: PageNode): String = defaultLocationProvider.pathToRoot(from)
-
- override fun ancestors(node: PageNode): List<PageNode> = listOf(root)
-
- companion object {
- const val MULTIMODULE_PACKAGE_PLACEHOLDER = ".ext"
- }
+ override val defaultLocationProvider = MarkdownLocationProvider(root, context)
class Factory(private val context: DokkaContext): LocationProviderFactory {
override fun getLocationProvider(pageNode: RootPageNode) =
diff --git a/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmTemplateProcessingStrategy.kt b/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmTemplateProcessingStrategy.kt
new file mode 100644
index 00000000..37226d1e
--- /dev/null
+++ b/plugins/gfm/gfm-all-module-page/src/main/kotlin/org/jetbrains/dokka/gfm/allModulesPage/GfmTemplateProcessingStrategy.kt
@@ -0,0 +1,45 @@
+package org.jetbrains.dokka.gfm.allModulesPage
+
+import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
+import org.jetbrains.dokka.allModulesPage.templates.ExternalModuleLinkResolver
+import org.jetbrains.dokka.allModulesPage.templates.TemplateProcessingStrategy
+import org.jetbrains.dokka.base.templating.parseJson
+import org.jetbrains.dokka.gfm.GfmCommand
+import org.jetbrains.dokka.gfm.GfmCommand.Companion.templateCommandRegex
+import org.jetbrains.dokka.gfm.ResolveLinkGfmCommand
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.plugability.DokkaContext
+import java.io.File
+
+class GfmTemplateProcessingStrategy(val context: DokkaContext) : TemplateProcessingStrategy {
+
+ private val externalModuleLinkResolver = ExternalModuleLinkResolver(context)
+
+ override suspend fun process(input: File, output: File): Boolean = coroutineScope {
+ if (input.extension == "md") {
+ launch(IO) {
+ val reader = input.bufferedReader()
+ val writer = output.bufferedWriter()
+ do {
+ val line = reader.readLine()
+ if (line != null) {
+ writer.write(line.replace(templateCommandRegex) {
+ when (val command = parseJson<GfmCommand>(it.groupValues.last())) {
+ is ResolveLinkGfmCommand -> resolveLink(output, command.dri)
+ }
+ })
+ writer.newLine()
+ }
+ } while (line != null)
+ reader.close()
+ writer.close()
+ }
+ true
+ } else false
+ }
+
+ private fun resolveLink(fileContext: File, dri: DRI): String =
+ externalModuleLinkResolver.resolve(dri, fileContext) ?: ""
+} \ No newline at end of file
diff --git a/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/gfmTemplating.kt b/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/gfmTemplating.kt
new file mode 100644
index 00000000..1473ceee
--- /dev/null
+++ b/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/gfmTemplating.kt
@@ -0,0 +1,19 @@
+package org.jetbrains.dokka.gfm
+
+import org.jetbrains.dokka.base.templating.toJsonString
+import org.jetbrains.dokka.links.DRI
+import com.fasterxml.jackson.annotation.JsonTypeInfo
+import com.fasterxml.jackson.annotation.JsonTypeInfo.Id.CLASS
+
+@JsonTypeInfo(use = CLASS)
+sealed class GfmCommand {
+ companion object {
+ private const val delimiter = "\u1680"
+ fun templateCommand(command: GfmCommand): String = "$delimiter GfmCommand ${toJsonString(command)}$delimiter"
+ val templateCommandRegex: Regex = Regex("$delimiter GfmCommand ([^$delimiter ]*)$delimiter")
+ }
+}
+
+class ResolveLinkGfmCommand(val dri: DRI): GfmCommand()
+
+
diff --git a/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/renderer/CommonmarkRenderer.kt b/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/renderer/CommonmarkRenderer.kt
index 0655ce20..25b24f0c 100644
--- a/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/renderer/CommonmarkRenderer.kt
+++ b/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/renderer/CommonmarkRenderer.kt
@@ -3,7 +3,9 @@ package org.jetbrains.dokka.gfm.renderer
import org.jetbrains.dokka.DokkaException
import org.jetbrains.dokka.base.renderers.DefaultRenderer
import org.jetbrains.dokka.base.renderers.isImage
+import org.jetbrains.dokka.gfm.GfmCommand.Companion.templateCommand
import org.jetbrains.dokka.gfm.GfmPlugin
+import org.jetbrains.dokka.gfm.ResolveLinkGfmCommand
import org.jetbrains.dokka.model.DisplaySourceSet
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.plugability.DokkaContext
@@ -80,6 +82,17 @@ open class CommonmarkRenderer(
}
}
+ override fun StringBuilder.buildDRILink(
+ node: ContentDRILink,
+ pageContext: ContentPage,
+ sourceSetRestriction: Set<DisplaySourceSet>?
+ ) {
+ val address = locationProvider.resolve(node.address, node.sourceSets, pageContext)
+ buildLink(address ?: templateCommand(ResolveLinkGfmCommand(node.address))) {
+ buildText(node.children, pageContext, sourceSetRestriction)
+ }
+ }
+
override fun StringBuilder.buildNewLine() {
append(" \n")
}
@@ -118,7 +131,7 @@ open class CommonmarkRenderer(
}
override fun StringBuilder.buildResource(node: ContentEmbeddedResource, pageContext: ContentPage) {
- if(node.isImage()){
+ if (node.isImage()) {
append("!")
}
append("[${node.altText}](${node.address})")