From 39631054c58df5841ea268b7002b820ec55f6e0a Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 3 Dec 2015 16:22:11 +0100 Subject: restructure Dokka build to use Gradle for everything except for the Maven plugin --- .../kotlin/Locations/FoldersLocationService.kt | 29 ++++++++ core/src/main/kotlin/Locations/LocationService.kt | 78 ++++++++++++++++++++++ .../Locations/SingleFolderLocationService.kt | 19 ++++++ 3 files changed, 126 insertions(+) create mode 100644 core/src/main/kotlin/Locations/FoldersLocationService.kt create mode 100644 core/src/main/kotlin/Locations/LocationService.kt create mode 100644 core/src/main/kotlin/Locations/SingleFolderLocationService.kt (limited to 'core/src/main/kotlin/Locations') diff --git a/core/src/main/kotlin/Locations/FoldersLocationService.kt b/core/src/main/kotlin/Locations/FoldersLocationService.kt new file mode 100644 index 00000000..89b34ed1 --- /dev/null +++ b/core/src/main/kotlin/Locations/FoldersLocationService.kt @@ -0,0 +1,29 @@ +package org.jetbrains.dokka + +import com.google.inject.Inject +import com.google.inject.name.Named +import java.io.File + +public fun FoldersLocationService(root: String): FoldersLocationService = FoldersLocationService(File(root), "") +public class FoldersLocationService @Inject constructor(@Named("outputDir") val rootFile: File, val extension: String) : FileLocationService { + override val root: Location + get() = FileLocation(rootFile) + + override fun withExtension(newExtension: String): FileLocationService { + return if (extension.isEmpty()) FoldersLocationService(rootFile, newExtension) else this + } + + override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation { + return FileLocation(File(rootFile, relativePathToNode(qualifiedName, hasMembers)).appendExtension(extension)) + } +} + +fun relativePathToNode(qualifiedName: List, hasMembers: Boolean): String { + val parts = qualifiedName.map { identifierToFilename(it) }.filterNot { it.isEmpty() } + return if (!hasMembers) { + // leaf node, use file in owner's folder + parts.joinToString("/") + } else { + parts.joinToString("/") + (if (parts.none()) "" else "/") + "index" + } +} diff --git a/core/src/main/kotlin/Locations/LocationService.kt b/core/src/main/kotlin/Locations/LocationService.kt new file mode 100644 index 00000000..80bc0236 --- /dev/null +++ b/core/src/main/kotlin/Locations/LocationService.kt @@ -0,0 +1,78 @@ +package org.jetbrains.dokka + +import java.io.File + +public interface Location { + val path: String get + fun relativePathTo(other: Location, anchor: String? = null): String +} + +/** + * Represents locations in the documentation in the form of [path](File). + * + * Locations are provided by [LocationService.location] function. + * + * $file: [File] for this location + * $path: [String] representing path of this location + */ +public data class FileLocation(val file: File): Location { + override val path : String + get() = file.path + + override fun relativePathTo(other: Location, anchor: String?): String { + if (other !is FileLocation) { + throw IllegalArgumentException("$other is not a FileLocation") + } + if (file.path.substringBeforeLast(".") == other.file.path.substringBeforeLast(".") && anchor == null) { + return "." + } + val ownerFolder = file.parentFile!! + val relativePath = ownerFolder.toPath().relativize(other.file.toPath()).toString() + return if (anchor == null) relativePath else relativePath + "#" + anchor + } +} + +/** + * Provides means of retrieving locations for [DocumentationNode](documentation nodes) + * + * `LocationService` determines where documentation for particular node should be generated + * + * * [FoldersLocationService] – represent packages and types as folders, members as files in those folders. + * * [SingleFolderLocationService] – all documentation is generated into single folder using fully qualified names + * for file names. + */ +public interface LocationService { + fun withExtension(newExtension: String) = this + + fun location(node: DocumentationNode): Location = location(node.path.map { it.name }, node.members.any()) + + /** + * Calculates a location corresponding to the specified [qualifiedName]. + * @param hasMembers if true, the node for which the location is calculated has member nodes. + */ + fun location(qualifiedName: List, hasMembers: Boolean): Location + + val root: Location +} + + +public interface FileLocationService: LocationService { + override fun withExtension(newExtension: String): FileLocationService = this + + override fun location(node: DocumentationNode): FileLocation = location(node.path.map { it.name }, node.members.any()) + override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation +} + + +public fun identifierToFilename(path: String): String { + val escaped = path.replace('<', '-').replace('>', '-') + val lowercase = escaped.replace("[A-Z]".toRegex()) { matchResult -> "-" + matchResult.value.toLowerCase() } + return if (lowercase == "index") "--index--" else lowercase +} + +/** + * Returns relative location between two nodes. Used for relative links in documentation. + */ +fun LocationService.relativePathToLocation(owner: DocumentationNode, node: DocumentationNode): String { + return location(owner).relativePathTo(location(node), null) +} diff --git a/core/src/main/kotlin/Locations/SingleFolderLocationService.kt b/core/src/main/kotlin/Locations/SingleFolderLocationService.kt new file mode 100644 index 00000000..e313ac28 --- /dev/null +++ b/core/src/main/kotlin/Locations/SingleFolderLocationService.kt @@ -0,0 +1,19 @@ +package org.jetbrains.dokka + +import com.google.inject.Inject +import com.google.inject.name.Named +import java.io.File + +public fun SingleFolderLocationService(root: String): SingleFolderLocationService = SingleFolderLocationService(File(root), "") +public class SingleFolderLocationService @Inject constructor(@Named("outputDir") val rootFile: File, val extension: String) : FileLocationService { + override fun withExtension(newExtension: String): FileLocationService = + SingleFolderLocationService(rootFile, newExtension) + + override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation { + val filename = qualifiedName.map { identifierToFilename(it) }.joinToString("-") + return FileLocation(File(rootFile, filename).appendExtension(extension)) + } + + override val root: Location + get() = FileLocation(rootFile) +} \ No newline at end of file -- cgit