diff options
-rw-r--r-- | src/Formats/KotlinWebsiteFormatService.kt | 27 | ||||
-rw-r--r-- | src/Formats/StructuredFormatService.kt | 49 | ||||
-rw-r--r-- | src/Kotlin/KotlinLanguageService.kt | 6 | ||||
-rw-r--r-- | src/Model/Content.kt | 59 |
4 files changed, 104 insertions, 37 deletions
diff --git a/src/Formats/KotlinWebsiteFormatService.kt b/src/Formats/KotlinWebsiteFormatService.kt index 97419c58..b66fa1a7 100644 --- a/src/Formats/KotlinWebsiteFormatService.kt +++ b/src/Formats/KotlinWebsiteFormatService.kt @@ -3,6 +3,8 @@ package org.jetbrains.dokka public class KotlinWebsiteFormatService(locationService: LocationService, signatureGenerator: LanguageService) : JekyllFormatService(locationService, signatureGenerator) { + private var needHardLineBreaks = false + override fun appendFrontMatter(nodes: Iterable<DocumentationNode>, to: StringBuilder) { super.appendFrontMatter(nodes, to) to.appendln("layout: api") @@ -24,12 +26,17 @@ public class KotlinWebsiteFormatService(locationService: LocationService, override fun formatStrikethrough(text: String): String = "<s>$text</s>" - override fun appendAsSignature(to: StringBuilder, block: () -> Unit) { - val oldLength = to.length - block() - if (to.length > oldLength) { - to.append("<br/>") // since we've used HTML to format the signature, add an HTML line break following it + override fun appendAsSignature(to: StringBuilder, node: ContentNode, block: () -> Unit) { + val contentLength = node.textLength + if (contentLength == 0) return + to.append("<div class=\"signature\">") + needHardLineBreaks = contentLength >= 62 + try { + block() + } finally { + needHardLineBreaks = false } + to.append("</div>") } override fun formatLink(text: String, href: String): String { @@ -88,6 +95,16 @@ public class KotlinWebsiteFormatService(locationService: LocationService, return "<span class=\"${identifierClassName(kind)}\">${formatText(text)}</span>" } + override fun formatSoftLineBreak(): String = if (needHardLineBreaks) + "<br/>" + else + "" + + override fun formatIndentedSoftLineBreak(): String = if (needHardLineBreaks) + "<br/> " + else + "" + private fun identifierClassName(kind: IdentifierKind) = when(kind) { IdentifierKind.ParameterName -> "parameterName" IdentifierKind.SummarizedTypeName -> "summarizedTypeName" diff --git a/src/Formats/StructuredFormatService.kt b/src/Formats/StructuredFormatService.kt index 405a8b10..5a8109dc 100644 --- a/src/Formats/StructuredFormatService.kt +++ b/src/Formats/StructuredFormatService.kt @@ -44,6 +44,8 @@ public abstract class StructuredFormatService(locationService: LocationService, public abstract fun formatListItem(text: String, kind: ListKind): String public abstract fun formatBreadcrumbs(items: Iterable<FormatLink>): String public abstract fun formatNonBreakingSpace(): String + public open fun formatSoftLineBreak(): String = "" + public open fun formatIndentedSoftLineBreak(): String = "" open fun formatText(location: Location, nodes: Iterable<ContentNode>, listKind: ListKind = ListKind.Unordered): String { return nodes.map { formatText(location, it, listKind) }.joinToString("") @@ -57,6 +59,8 @@ public abstract class StructuredFormatService(locationService: LocationService, is ContentKeyword -> append(formatKeyword(content.text)) is ContentIdentifier -> append(formatIdentifier(content.text, content.kind)) is ContentNonBreakingSpace -> append(formatNonBreakingSpace()) + is ContentSoftLineBreak -> append(formatSoftLineBreak()) + is ContentIndentedSoftLineBreak -> append(formatIndentedSoftLineBreak()) is ContentEntity -> append(formatEntity(content.text)) is ContentStrong -> append(formatStrong(formatText(location, content.children))) is ContentStrikethrough -> append(formatStrikethrough(formatText(location, content.children))) @@ -111,8 +115,9 @@ public abstract class StructuredFormatService(locationService: LocationService, for ((summary, items) in breakdownBySummary) { items.forEach { - appendAsSignature(to) { - to.append(formatCode(formatText(location, languageService.render(it)))) + val rendered = languageService.render(it) + appendAsSignature(to, rendered) { + to.append(formatCode(formatText(location, rendered))) it.appendSourceLink(to) } it.appendOverrides(to) @@ -133,7 +138,7 @@ public abstract class StructuredFormatService(locationService: LocationService, private fun DocumentationNode.isModuleOrPackage(): Boolean = kind == DocumentationNode.Kind.Module || kind == DocumentationNode.Kind.Package - protected open fun appendAsSignature(to: StringBuilder, block: () -> Unit) { + protected open fun appendAsSignature(to: StringBuilder, node: ContentNode, block: () -> Unit) { block() } @@ -254,30 +259,32 @@ public abstract class StructuredFormatService(locationService: LocationService, private fun appendSummarySignatures(items: List<DocumentationNode>, location: Location, to: StringBuilder) { val summarySignature = languageService.summarizeSignatures(items) if (summarySignature != null) { - appendAsSignature(to) { - val signatureAsCode = ContentCode() - signatureAsCode.append(summarySignature) - to.append(formatText(location, signatureAsCode)) + val signatureAsCode = ContentCode() + signatureAsCode.append(summarySignature) + appendAsSignature(to, signatureAsCode) { + appendLine(to, signatureAsCode.signatureToText(location)) } return } - val signatureTexts = items.map { signature -> - val signatureText = languageService.render(signature, RenderMode.SUMMARY) - if (signatureText is ContentBlock && signatureText.isEmpty()) { - "" - } else { - val signatureAsCode = ContentCode() - signatureAsCode.append(signatureText) - formatText(location, signatureAsCode) + val renderedSignatures = items.map { languageService.render(it, RenderMode.SUMMARY) } + renderedSignatures.subList(0, renderedSignatures.size - 1).forEach { + appendAsSignature(to, it) { + appendLine(to, it.signatureToText(location)) } + appendLine(to) } - signatureTexts.subList(0, signatureTexts.size - 1).forEach { - appendAsSignature(to) { - appendLine(to, it) - } + appendAsSignature(to, renderedSignatures.last()) { + to.append(renderedSignatures.last().signatureToText(location)) } - appendAsSignature(to) { - to.append(signatureTexts.last()) + } + + private fun ContentNode.signatureToText(location: Location): String { + return if (this is ContentBlock && this.isEmpty()) { + "" + } else { + val signatureAsCode = ContentCode() + signatureAsCode.append(this) + formatText(location, signatureAsCode) } } diff --git a/src/Kotlin/KotlinLanguageService.kt b/src/Kotlin/KotlinLanguageService.kt index 1e7050ef..0d1d6b85 100644 --- a/src/Kotlin/KotlinLanguageService.kt +++ b/src/Kotlin/KotlinLanguageService.kt @@ -104,9 +104,7 @@ class KotlinLanguageService : LanguageService { private class SummarizingMapper(val kind: ReceiverKind, val typeParameterName: String): SignatureMapper { override fun renderReceiver(receiver: DocumentationNode, to: ContentBlock) { - val newReceiver = ContentEmphasis() - newReceiver.append(ContentIdentifier(kind.receiverName, IdentifierKind.SummarizedTypeName)) - to.append(newReceiver) + to.append(ContentIdentifier(kind.receiverName, IdentifierKind.SummarizedTypeName)) to.text("<$typeParameterName>") } } @@ -340,8 +338,10 @@ class KotlinLanguageService : LanguageService { symbol("(") renderList(node.details(DocumentationNode.Kind.Parameter)) { + indentedSoftLineBreak() renderParameter(it, renderMode) } + softLineBreak() symbol(")") if (needReturnType(node)) { symbol(": ") diff --git a/src/Model/Content.kt b/src/Model/Content.kt index 4dfd3606..e7dfc241 100644 --- a/src/Model/Content.kt +++ b/src/Model/Content.kt @@ -1,8 +1,12 @@ package org.jetbrains.dokka -public interface ContentNode +public interface ContentNode { + val textLength: Int +} -public object ContentEmpty : ContentNode +public object ContentEmpty : ContentNode { + override val textLength: Int get() = 0 +} public open class ContentBlock() : ContentNode { val children = arrayListOf<ContentNode>() @@ -18,6 +22,9 @@ public open class ContentBlock() : ContentNode { override fun hashCode(): Int = children.hashCode() + + override val textLength: Int + get() = children.sumBy { it.textLength } } enum class IdentifierKind { @@ -28,12 +35,45 @@ enum class IdentifierKind { Other } -public data class ContentText(val text: String) : ContentNode -public data class ContentKeyword(val text: String) : ContentNode -public data class ContentIdentifier(val text: String, val kind: IdentifierKind = IdentifierKind.Other) : ContentNode -public data class ContentSymbol(val text: String) : ContentNode -public data class ContentEntity(val text: String) : ContentNode -public object ContentNonBreakingSpace: ContentNode +public data class ContentText(val text: String) : ContentNode { + override val textLength: Int + get() = text.length +} + +public data class ContentKeyword(val text: String) : ContentNode { + override val textLength: Int + get() = text.length +} + +public data class ContentIdentifier(val text: String, val kind: IdentifierKind = IdentifierKind.Other) : ContentNode { + override val textLength: Int + get() = text.length +} + +public data class ContentSymbol(val text: String) : ContentNode { + override val textLength: Int + get() = text.length +} + +public data class ContentEntity(val text: String) : ContentNode { + override val textLength: Int + get() = text.length +} + +public object ContentNonBreakingSpace: ContentNode { + override val textLength: Int + get() = 1 +} + +public object ContentSoftLineBreak: ContentNode { + override val textLength: Int + get() = 0 +} + +public object ContentIndentedSoftLineBreak: ContentNode { + override val textLength: Int + get() = 0 +} public class ContentParagraph() : ContentBlock() public class ContentEmphasis() : ContentBlock() @@ -97,6 +137,9 @@ fun ContentBlock.keyword(value: String) = append(ContentKeyword(value)) fun ContentBlock.symbol(value: String) = append(ContentSymbol(value)) fun ContentBlock.identifier(value: String, kind: IdentifierKind = IdentifierKind.Other) = append(ContentIdentifier(value, kind)) fun ContentBlock.nbsp() = append(ContentNonBreakingSpace) +fun ContentBlock.softLineBreak() = append(ContentSoftLineBreak) +fun ContentBlock.indentedSoftLineBreak() = append(ContentIndentedSoftLineBreak) + fun ContentBlock.strong(body: ContentBlock.() -> Unit) { val strong = ContentStrong() strong.body() |