From 23e270b603eb32472b8ef4a5f44c01af57fd049f Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Mon, 23 Nov 2015 18:53:18 +0100 Subject: Use Java 8 Path API to relativize paths instead of rolling a custom version. Fixes various IOExceptions thrown during generation. --- src/Locations/LocationService.kt | 2 +- src/Utilities/Path.kt | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) (limited to 'src') diff --git a/src/Locations/LocationService.kt b/src/Locations/LocationService.kt index 4f587361..15a4ebac 100644 --- a/src/Locations/LocationService.kt +++ b/src/Locations/LocationService.kt @@ -27,7 +27,7 @@ public data class FileLocation(val file: File): Location { return "." } val ownerFolder = file.parentFile!! - val relativePath = ownerFolder.getRelativePath(other.file).path + val relativePath = ownerFolder.toPath().relativize(other.file.toPath()).toString() return if (anchor == null) relativePath else relativePath + "#" + anchor } } diff --git a/src/Utilities/Path.kt b/src/Utilities/Path.kt index 36277d9f..05838499 100644 --- a/src/Utilities/Path.kt +++ b/src/Utilities/Path.kt @@ -1,19 +1,5 @@ package org.jetbrains.dokka import java.io.File -import java.io.IOException - -fun File.getRelativePath(name: File): File { - val parent = parentFile ?: throw IOException("No common directory") - - val basePath = canonicalPath + File.separator; - val targetPath = name.canonicalPath; - - if (targetPath.startsWith(basePath)) { - return File(targetPath.substring(basePath.length)) - } else { - return File(".." + File.separator + parent.getRelativePath(name)) - } -} fun File.appendExtension(extension: String) = if (extension.isEmpty()) this else File(path + "." + extension) -- cgit From 90cf2ebccd12073a55ff6f187e5a378a2e96e23b Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Mon, 23 Nov 2015 19:21:08 +0100 Subject: Copy style.css to the output directory when doing HTML and use relative paths. Fixes the code so that the relative path to root is always available, breaking the requirement to use a local web server. --- resources/dokka/styles/style.css | 280 +++++++++++++++++++++++++++ src/Formats/HtmlFormatService.kt | 7 +- src/Formats/HtmlTemplateService.kt | 9 +- src/Generation/FileGenerator.kt | 6 + src/Generation/Generator.kt | 2 + src/Locations/FoldersLocationService.kt | 8 +- src/Locations/LocationService.kt | 2 + src/Locations/SingleFolderLocationService.kt | 9 +- src/Utilities/DokkaModule.kt | 2 +- src/main.kt | 4 +- styles/style.css | 280 --------------------------- 11 files changed, 315 insertions(+), 294 deletions(-) create mode 100644 resources/dokka/styles/style.css delete mode 100644 styles/style.css (limited to 'src') diff --git a/resources/dokka/styles/style.css b/resources/dokka/styles/style.css new file mode 100644 index 00000000..09586237 --- /dev/null +++ b/resources/dokka/styles/style.css @@ -0,0 +1,280 @@ +@import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700); + +body, table { + padding:50px; + font:14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif; + color:#555; + font-weight:300; +} + +.keyword { + color:black; + font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + font-size:12px; +} + +.symbol { + font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + font-size:12px; +} + +.identifier { + color: darkblue; + font-size:12px; + font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; +} + +h1, h2, h3, h4, h5, h6 { + color:#222; + margin:0 0 20px; +} + +p, ul, ol, table, pre, dl { + margin:0 0 20px; +} + +h1, h2, h3 { + line-height:1.1; +} + +h1 { + font-size:28px; +} + +h2 { + color:#393939; +} + +h3, h4, h5, h6 { + color:#494949; +} + +a { + color:#258aaf; + font-weight:400; + text-decoration:none; +} + +a:hover { + color: inherit; + text-decoration:underline; +} + +a small { + font-size:11px; + color:#555; + margin-top:-0.6em; + display:block; +} + +.wrapper { + width:860px; + margin:0 auto; +} + +blockquote { + border-left:1px solid #e5e5e5; + margin:0; + padding:0 0 0 20px; + font-style:italic; +} + +code, pre { + font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + color:#333; + font-size:12px; +} + +pre { + display: block; +/* + padding:8px 8px; + background: #f8f8f8; + border-radius:5px; + border:1px solid #e5e5e5; +*/ + overflow-x: auto; +} + +table { + width:100%; + border-collapse:collapse; +} + +th, td { + text-align:left; + vertical-align: top; + padding:5px 10px; +} + +dt { + color:#444; + font-weight:700; +} + +th { + color:#444; +} + +img { + max-width:100%; +} + +header { + width:270px; + float:left; + position:fixed; +} + +header ul { + list-style:none; + height:40px; + + padding:0; + + background: #eee; + background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); + background: -webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); + background: -o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); + background: -ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); + background: linear-gradient(top, #f8f8f8 0%,#dddddd 100%); + + border-radius:5px; + border:1px solid #d2d2d2; + box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0; + width:270px; +} + +header li { + width:89px; + float:left; + border-right:1px solid #d2d2d2; + height:40px; +} + +header ul a { + line-height:1; + font-size:11px; + color:#999; + display:block; + text-align:center; + padding-top:6px; + height:40px; +} + +strong { + color:#222; + font-weight:700; +} + +header ul li + li { + width:88px; + border-left:1px solid #fff; +} + +header ul li + li + li { + border-right:none; + width:89px; +} + +header ul a strong { + font-size:14px; + display:block; + color:#222; +} + +section { + width:500px; + float:right; + padding-bottom:50px; +} + +small { + font-size:11px; +} + +hr { + border:0; + background:#e5e5e5; + height:1px; + margin:0 0 20px; +} + +footer { + width:270px; + float:left; + position:fixed; + bottom:50px; +} + +@media print, screen and (max-width: 960px) { + + div.wrapper { + width:auto; + margin:0; + } + + header, section, footer { + float:none; + position:static; + width:auto; + } + + header { + padding-right:320px; + } + + section { + border:1px solid #e5e5e5; + border-width:1px 0; + padding:20px 0; + margin:0 0 20px; + } + + header a small { + display:inline; + } + + header ul { + position:absolute; + right:50px; + top:52px; + } +} + +@media print, screen and (max-width: 720px) { + body { + word-wrap:break-word; + } + + header { + padding:0; + } + + header ul, header p.view { + position:static; + } + + pre, code { + word-wrap:normal; + } +} + +@media print, screen and (max-width: 480px) { + body { + padding:15px; + } + + header ul { + display:none; + } +} + +@media print { + body { + padding:0.4in; + font-size:12pt; + color:#444; + } +} diff --git a/src/Formats/HtmlFormatService.kt b/src/Formats/HtmlFormatService.kt index e810ef7f..2c461905 100644 --- a/src/Formats/HtmlFormatService.kt +++ b/src/Formats/HtmlFormatService.kt @@ -3,6 +3,7 @@ package org.jetbrains.dokka import com.google.inject.Inject import com.google.inject.name.Named import java.io.File +import java.nio.file.Paths public open class HtmlFormatService @Inject constructor(@Named("folders") locationService: LocationService, signatureGenerator: LanguageService, @@ -113,17 +114,19 @@ public open class HtmlFormatService @Inject constructor(@Named("folders") locati override fun appendNodes(location: Location, to: StringBuilder, nodes: Iterable) { - templateService.appendHeader(to, getPageTitle(nodes)) + templateService.appendHeader(to, getPageTitle(nodes), calcPathToRoot(location)) super.appendNodes(location, to, nodes) templateService.appendFooter(to) } override fun appendOutline(location: Location, to: StringBuilder, nodes: Iterable) { - templateService.appendHeader(to, "Module Contents") + templateService.appendHeader(to, "Module Contents", calcPathToRoot(location)) super.appendOutline(location, to, nodes) templateService.appendFooter(to) } + private fun calcPathToRoot(location: Location) = Paths.get(location.path).parent.relativize(Paths.get(locationService.root.path + '/')) + override fun getOutlineFileName(location: Location): File { return File("${location.path}-outline.html") } diff --git a/src/Formats/HtmlTemplateService.kt b/src/Formats/HtmlTemplateService.kt index b9900757..ae42a31b 100644 --- a/src/Formats/HtmlTemplateService.kt +++ b/src/Formats/HtmlTemplateService.kt @@ -1,7 +1,9 @@ package org.jetbrains.dokka +import java.nio.file.Path + public interface HtmlTemplateService { - fun appendHeader(to: StringBuilder, title: String?) + fun appendHeader(to: StringBuilder, title: String?, basePath: Path) fun appendFooter(to: StringBuilder) companion object { @@ -11,14 +13,15 @@ public interface HtmlTemplateService { to.appendln("") to.appendln("") } - override fun appendHeader(to: StringBuilder, title: String?) { + override fun appendHeader(to: StringBuilder, title: String?, basePath: Path) { to.appendln("") to.appendln("") if (title != null) { to.appendln("$title") } if (css != null) { - to.appendln("") + val cssPath = basePath.resolve(css) + to.appendln("") } to.appendln("") to.appendln("") diff --git a/src/Generation/FileGenerator.kt b/src/Generation/FileGenerator.kt index 810038fa..a762bae3 100644 --- a/src/Generation/FileGenerator.kt +++ b/src/Generation/FileGenerator.kt @@ -42,6 +42,12 @@ public class FileGenerator @Inject constructor(val locationService: FileLocation } } } + + override fun buildSupportFiles() { + FileOutputStream(locationService.location(listOf("style.css"), false).file).use { + javaClass.getResourceAsStream("/dokka/styles/style.css").copyTo(it) + } + } } private fun File.mkdirsOrFail() { diff --git a/src/Generation/Generator.kt b/src/Generation/Generator.kt index d7db1c52..ac10a6a5 100644 --- a/src/Generation/Generator.kt +++ b/src/Generation/Generator.kt @@ -3,11 +3,13 @@ package org.jetbrains.dokka public interface Generator { fun buildPages(nodes: Iterable) fun buildOutlines(nodes: Iterable) + fun buildSupportFiles() } fun Generator.buildAll(nodes: Iterable) { buildPages(nodes) buildOutlines(nodes) + buildSupportFiles() } fun Generator.buildPage(node: DocumentationNode): Unit = buildPages(listOf(node)) diff --git a/src/Locations/FoldersLocationService.kt b/src/Locations/FoldersLocationService.kt index 8a0cf6be..89b34ed1 100644 --- a/src/Locations/FoldersLocationService.kt +++ b/src/Locations/FoldersLocationService.kt @@ -5,14 +5,16 @@ 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 root: File, val extension: String) : FileLocationService { +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(root, newExtension) else this + return if (extension.isEmpty()) FoldersLocationService(rootFile, newExtension) else this } override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation { - return FileLocation(File(root, relativePathToNode(qualifiedName, hasMembers)).appendExtension(extension)) + return FileLocation(File(rootFile, relativePathToNode(qualifiedName, hasMembers)).appendExtension(extension)) } } diff --git a/src/Locations/LocationService.kt b/src/Locations/LocationService.kt index 15a4ebac..80bc0236 100644 --- a/src/Locations/LocationService.kt +++ b/src/Locations/LocationService.kt @@ -51,6 +51,8 @@ public interface LocationService { * @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 } diff --git a/src/Locations/SingleFolderLocationService.kt b/src/Locations/SingleFolderLocationService.kt index 049636c0..e313ac28 100644 --- a/src/Locations/SingleFolderLocationService.kt +++ b/src/Locations/SingleFolderLocationService.kt @@ -5,12 +5,15 @@ 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 root: File, val extension: String) : FileLocationService { +public class SingleFolderLocationService @Inject constructor(@Named("outputDir") val rootFile: File, val extension: String) : FileLocationService { override fun withExtension(newExtension: String): FileLocationService = - SingleFolderLocationService(root, newExtension) + SingleFolderLocationService(rootFile, newExtension) override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation { val filename = qualifiedName.map { identifierToFilename(it) }.joinToString("-") - return FileLocation(File(root, filename).appendExtension(extension)) + return FileLocation(File(rootFile, filename).appendExtension(extension)) } + + override val root: Location + get() = FileLocation(rootFile) } \ No newline at end of file diff --git a/src/Utilities/DokkaModule.kt b/src/Utilities/DokkaModule.kt index 3b2d26f1..1eb82313 100644 --- a/src/Utilities/DokkaModule.kt +++ b/src/Utilities/DokkaModule.kt @@ -26,7 +26,7 @@ class DokkaModule(val environment: AnalysisEnvironment, binder.bind(LanguageService::class.java).to(KotlinLanguageService::class.java) binder.bind(HtmlTemplateService::class.java).toProvider(object : Provider { - override fun get(): HtmlTemplateService = HtmlTemplateService.default("/dokka/styles/style.css") + override fun get(): HtmlTemplateService = HtmlTemplateService.default("style.css") }) binder.registerCategory("language") diff --git a/src/main.kt b/src/main.kt index ef694981..5a7514c4 100644 --- a/src/main.kt +++ b/src/main.kt @@ -93,7 +93,7 @@ public fun main(args: Array) { samples, includes, arguments.moduleName, - arguments.outputDir, + arguments.outputDir.let { if (it.endsWith('/')) it else it + '/' }, arguments.outputFormat, sourceLinks, arguments.nodeprecated) @@ -148,7 +148,7 @@ class DokkaGenerator(val logger: DokkaLogger, val environment = createAnalysisEnvironment() logger.info("Module: $moduleName") - logger.info("Output: ${File(outputDir).absolutePath}") + logger.info("Output: ${File(outputDir)}") logger.info("Sources: ${environment.sources.joinToString()}") logger.info("Classpath: ${environment.classpath.joinToString()}") diff --git a/styles/style.css b/styles/style.css deleted file mode 100644 index 09586237..00000000 --- a/styles/style.css +++ /dev/null @@ -1,280 +0,0 @@ -@import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700); - -body, table { - padding:50px; - font:14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif; - color:#555; - font-weight:300; -} - -.keyword { - color:black; - font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; - font-size:12px; -} - -.symbol { - font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; - font-size:12px; -} - -.identifier { - color: darkblue; - font-size:12px; - font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; -} - -h1, h2, h3, h4, h5, h6 { - color:#222; - margin:0 0 20px; -} - -p, ul, ol, table, pre, dl { - margin:0 0 20px; -} - -h1, h2, h3 { - line-height:1.1; -} - -h1 { - font-size:28px; -} - -h2 { - color:#393939; -} - -h3, h4, h5, h6 { - color:#494949; -} - -a { - color:#258aaf; - font-weight:400; - text-decoration:none; -} - -a:hover { - color: inherit; - text-decoration:underline; -} - -a small { - font-size:11px; - color:#555; - margin-top:-0.6em; - display:block; -} - -.wrapper { - width:860px; - margin:0 auto; -} - -blockquote { - border-left:1px solid #e5e5e5; - margin:0; - padding:0 0 0 20px; - font-style:italic; -} - -code, pre { - font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; - color:#333; - font-size:12px; -} - -pre { - display: block; -/* - padding:8px 8px; - background: #f8f8f8; - border-radius:5px; - border:1px solid #e5e5e5; -*/ - overflow-x: auto; -} - -table { - width:100%; - border-collapse:collapse; -} - -th, td { - text-align:left; - vertical-align: top; - padding:5px 10px; -} - -dt { - color:#444; - font-weight:700; -} - -th { - color:#444; -} - -img { - max-width:100%; -} - -header { - width:270px; - float:left; - position:fixed; -} - -header ul { - list-style:none; - height:40px; - - padding:0; - - background: #eee; - background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); - background: -webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); - background: -o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); - background: -ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); - background: linear-gradient(top, #f8f8f8 0%,#dddddd 100%); - - border-radius:5px; - border:1px solid #d2d2d2; - box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0; - width:270px; -} - -header li { - width:89px; - float:left; - border-right:1px solid #d2d2d2; - height:40px; -} - -header ul a { - line-height:1; - font-size:11px; - color:#999; - display:block; - text-align:center; - padding-top:6px; - height:40px; -} - -strong { - color:#222; - font-weight:700; -} - -header ul li + li { - width:88px; - border-left:1px solid #fff; -} - -header ul li + li + li { - border-right:none; - width:89px; -} - -header ul a strong { - font-size:14px; - display:block; - color:#222; -} - -section { - width:500px; - float:right; - padding-bottom:50px; -} - -small { - font-size:11px; -} - -hr { - border:0; - background:#e5e5e5; - height:1px; - margin:0 0 20px; -} - -footer { - width:270px; - float:left; - position:fixed; - bottom:50px; -} - -@media print, screen and (max-width: 960px) { - - div.wrapper { - width:auto; - margin:0; - } - - header, section, footer { - float:none; - position:static; - width:auto; - } - - header { - padding-right:320px; - } - - section { - border:1px solid #e5e5e5; - border-width:1px 0; - padding:20px 0; - margin:0 0 20px; - } - - header a small { - display:inline; - } - - header ul { - position:absolute; - right:50px; - top:52px; - } -} - -@media print, screen and (max-width: 720px) { - body { - word-wrap:break-word; - } - - header { - padding:0; - } - - header ul, header p.view { - position:static; - } - - pre, code { - word-wrap:normal; - } -} - -@media print, screen and (max-width: 480px) { - body { - padding:15px; - } - - header ul { - display:none; - } -} - -@media print { - body { - padding:0.4in; - font-size:12pt; - color:#444; - } -} -- cgit