diff options
| author | Kamil Doległo <kamilok1965@interia.pl> | 2019-10-31 12:10:10 +0100 |
|---|---|---|
| committer | Kamil Doległo <kamilok1965@interia.pl> | 2019-10-31 12:10:10 +0100 |
| commit | 7c30624e3d0868346823b15b5cea5e29a56357f2 (patch) | |
| tree | 5cc8175510c907d23f7bdcb5d5617ef03b587965 /core/src/main/kotlin/Formats | |
| parent | 57830827b9bc13aad7af6ab899f25b278b248ef7 (diff) | |
| download | dokka-7c30624e3d0868346823b15b5cea5e29a56357f2.tar.gz dokka-7c30624e3d0868346823b15b5cea5e29a56357f2.tar.bz2 dokka-7c30624e3d0868346823b15b5cea5e29a56357f2.zip | |
Remove all unnecessary files
Diffstat (limited to 'core/src/main/kotlin/Formats')
| -rw-r--r-- | core/src/main/kotlin/Formats/FormatService.kt | 32 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/GFMFormatService.kt | 61 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/HtmlFormatService.kt | 166 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/HtmlTemplateService.kt | 38 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlPackageListService.kt | 117 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt | 91 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/JekyllFormatService.kt | 44 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt | 264 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/MarkdownFormatService.kt | 250 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/OutlineService.kt | 29 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/PackageListService.kt | 66 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/StandardFormats.kt | 55 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/StructuredFormatService.kt | 1014 | ||||
| -rw-r--r-- | core/src/main/kotlin/Formats/YamlOutlineService.kt | 26 |
14 files changed, 0 insertions, 2253 deletions
diff --git a/core/src/main/kotlin/Formats/FormatService.kt b/core/src/main/kotlin/Formats/FormatService.kt deleted file mode 100644 index 8f4855e3..00000000 --- a/core/src/main/kotlin/Formats/FormatService.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.jetbrains.dokka - -/** - * Abstract representation of a formatting service used to output documentation in desired format - * - * Bundled Formatters: - * * [HtmlFormatService] – outputs documentation to HTML format - * * [MarkdownFormatService] – outputs documentation in Markdown format - */ -interface FormatService { - /** Returns extension for output files */ - val extension: String - - /** extension which will be used for internal and external linking */ - val linkExtension: String - get() = extension - - fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder - - fun enumerateSupportFiles(callback: (resource: String, targetPath: String) -> Unit) { - } -} - -interface FormattedOutputBuilder { - /** Appends formatted content */ - fun appendNodes(nodes: Iterable<DocumentationNode>) -} - -/** Format content to [String] using specified [location] */ -fun FormatService.format(location: Location, nodes: Iterable<DocumentationNode>): String = StringBuilder().apply { - createOutputBuilder(this, location).appendNodes(nodes) -}.toString() diff --git a/core/src/main/kotlin/Formats/GFMFormatService.kt b/core/src/main/kotlin/Formats/GFMFormatService.kt deleted file mode 100644 index 036ec856..00000000 --- a/core/src/main/kotlin/Formats/GFMFormatService.kt +++ /dev/null @@ -1,61 +0,0 @@ -package org.jetbrains.dokka - -import com.google.inject.Inject -import com.google.inject.name.Named -import org.jetbrains.dokka.Utilities.impliedPlatformsName - -open class GFMOutputBuilder( - to: StringBuilder, - location: Location, - generator: NodeLocationAwareGenerator, - languageService: LanguageService, - extension: String, - impliedPlatforms: List<String> -) : MarkdownOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) { - override fun appendTable(vararg columns: String, body: () -> Unit) { - to.appendln(columns.joinToString(" | ", "| ", " |")) - to.appendln("|" + "---|".repeat(columns.size)) - body() - } - - override fun appendUnorderedList(body: () -> Unit) { - if (inTableCell) { - wrapInTag("ul", body) - } else { - super.appendUnorderedList(body) - } - } - - override fun appendOrderedList(body: () -> Unit) { - if (inTableCell) { - wrapInTag("ol", body) - } else { - super.appendOrderedList(body) - } - } - - override fun appendListItem(body: () -> Unit) { - if (inTableCell) { - wrapInTag("li", body) - } else { - super.appendListItem(body) - } - } -} - -open class GFMFormatService( - generator: NodeLocationAwareGenerator, - signatureGenerator: LanguageService, - linkExtension: String, - impliedPlatforms: List<String> -) : MarkdownFormatService(generator, signatureGenerator, linkExtension, impliedPlatforms) { - - @Inject constructor( - generator: NodeLocationAwareGenerator, - signatureGenerator: LanguageService, - @Named(impliedPlatformsName) impliedPlatforms: List<String> - ) : this(generator, signatureGenerator, "md", impliedPlatforms) - - override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder = - GFMOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) -} diff --git a/core/src/main/kotlin/Formats/HtmlFormatService.kt b/core/src/main/kotlin/Formats/HtmlFormatService.kt deleted file mode 100644 index d36ea0a2..00000000 --- a/core/src/main/kotlin/Formats/HtmlFormatService.kt +++ /dev/null @@ -1,166 +0,0 @@ -package org.jetbrains.dokka - -import com.google.inject.Inject -import com.google.inject.name.Named -import org.jetbrains.dokka.Utilities.impliedPlatformsName -import java.io.File - -open class HtmlOutputBuilder(to: StringBuilder, - location: Location, - generator: NodeLocationAwareGenerator, - languageService: LanguageService, - extension: String, - impliedPlatforms: List<String>, - val templateService: HtmlTemplateService) - : StructuredOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) -{ - override fun appendText(text: String) { - to.append(text.htmlEscape()) - } - - override fun appendSymbol(text: String) { - to.append("<span class=\"symbol\">${text.htmlEscape()}</span>") - } - - override fun appendKeyword(text: String) { - to.append("<span class=\"keyword\">${text.htmlEscape()}</span>") - } - - override fun appendIdentifier(text: String, kind: IdentifierKind, signature: String?) { - val id = signature?.let { " id=\"$it\"" }.orEmpty() - to.append("<span class=\"identifier\"$id>${text.htmlEscape()}</span>") - } - - override fun appendBlockCode(language: String, body: () -> Unit) { - val openTags = if (language.isNotBlank()) - "<pre><code class=\"lang-$language\">" - else - "<pre><code>" - wrap(openTags, "</code></pre>", body) - } - - override fun appendHeader(level: Int, body: () -> Unit) = - wrapInTag("h$level", body, newlineBeforeOpen = true, newlineAfterClose = true) - override fun appendParagraph(body: () -> Unit) = - wrapInTag("p", body, newlineBeforeOpen = true, newlineAfterClose = true) - - override fun appendSoftParagraph(body: () -> Unit) = appendParagraph(body) - - override fun appendLine() { - to.appendln("<br/>") - } - - override fun appendAnchor(anchor: String) { - to.appendln("<a name=\"${anchor.htmlEscape()}\"></a>") - } - - override fun appendTable(vararg columns: String, body: () -> Unit) = - wrapInTag("table", body, newlineAfterOpen = true, newlineAfterClose = true) - override fun appendTableBody(body: () -> Unit) = - wrapInTag("tbody", body, newlineAfterOpen = true, newlineAfterClose = true) - override fun appendTableRow(body: () -> Unit) = - wrapInTag("tr", body, newlineAfterOpen = true, newlineAfterClose = true) - override fun appendTableCell(body: () -> Unit) = - wrapInTag("td", body, newlineAfterOpen = true, newlineAfterClose = true) - - override fun appendLink(href: String, body: () -> Unit) = wrap("<a href=\"$href\">", "</a>", body) - - override fun appendStrong(body: () -> Unit) = wrapInTag("strong", body) - override fun appendEmphasis(body: () -> Unit) = wrapInTag("em", body) - override fun appendStrikethrough(body: () -> Unit) = wrapInTag("s", body) - override fun appendCode(body: () -> Unit) = wrapInTag("code", body) - - override fun appendUnorderedList(body: () -> Unit) = wrapInTag("ul", body, newlineAfterClose = true) - override fun appendOrderedList(body: () -> Unit) = wrapInTag("ol", body, newlineAfterClose = true) - override fun appendListItem(body: () -> Unit) = wrapInTag("li", body, newlineAfterClose = true) - - override fun appendBreadcrumbSeparator() { - to.append(" / ") - } - - override fun appendNodes(nodes: Iterable<DocumentationNode>) { - templateService.appendHeader(to, getPageTitle(nodes), generator.relativePathToRoot(location)) - super.appendNodes(nodes) - templateService.appendFooter(to) - } - - override fun appendNonBreakingSpace() { - to.append(" ") - } - - override fun ensureParagraph() {} -} - -open class HtmlFormatService @Inject constructor(generator: NodeLocationAwareGenerator, - signatureGenerator: LanguageService, - val templateService: HtmlTemplateService, - @Named(impliedPlatformsName) val impliedPlatforms: List<String>) -: StructuredFormatService(generator, signatureGenerator, "html"), OutlineFormatService { - - override fun enumerateSupportFiles(callback: (String, String) -> Unit) { - callback("/dokka/styles/style.css", "style.css") - } - - override fun createOutputBuilder(to: StringBuilder, location: Location) = - HtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms, templateService) - - override fun appendOutline(location: Location, to: StringBuilder, nodes: Iterable<DocumentationNode>) { - templateService.appendHeader(to, "Module Contents", generator.relativePathToRoot(location)) - super.appendOutline(location, to, nodes) - templateService.appendFooter(to) - } - - override fun getOutlineFileName(location: Location): File { - return File("${location.path}-outline.html") - } - - override fun appendOutlineHeader(location: Location, node: DocumentationNode, to: StringBuilder) { - val link = ContentNodeDirectLink(node) - link.append(languageService.render(node, LanguageService.RenderMode.FULL)) - val tempBuilder = StringBuilder() - createOutputBuilder(tempBuilder, location).appendContent(link) - to.appendln("<a href=\"${location.path}\">$tempBuilder</a><br/>") - } - - override fun appendOutlineLevel(to: StringBuilder, body: () -> Unit) { - to.appendln("<ul>") - body() - to.appendln("</ul>") - } -} - -fun getPageTitle(nodes: Iterable<DocumentationNode>): String? { - val breakdownByLocation = nodes.groupBy { node -> formatPageTitle(node) } - return breakdownByLocation.keys.singleOrNull() -} - -fun formatPageTitle(node: DocumentationNode): String { - val path = node.path - val moduleName = path.first().name - if (path.size == 1) { - return moduleName - } - - val qName = qualifiedNameForPageTitle(node) - return "$qName - $moduleName" -} - -private fun qualifiedNameForPageTitle(node: DocumentationNode): String { - if (node.kind == NodeKind.Package) { - var packageName = node.qualifiedName() - if (packageName.isEmpty()) { - packageName = "root package" - } - return packageName - } - - val path = node.path - var pathFromToplevelMember = path.dropWhile { it.kind !in NodeKind.classLike } - if (pathFromToplevelMember.isEmpty()) { - pathFromToplevelMember = path.dropWhile { it.kind != NodeKind.Property && it.kind != NodeKind.Function } - } - if (pathFromToplevelMember.isNotEmpty()) { - return pathFromToplevelMember.map { it.name }.filter { it.length > 0 }.joinToString(".") - } - return node.qualifiedName() -} diff --git a/core/src/main/kotlin/Formats/HtmlTemplateService.kt b/core/src/main/kotlin/Formats/HtmlTemplateService.kt deleted file mode 100644 index a65a7b18..00000000 --- a/core/src/main/kotlin/Formats/HtmlTemplateService.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.jetbrains.dokka - -import java.io.File - -interface HtmlTemplateService { - fun appendHeader(to: StringBuilder, title: String?, basePath: File) - fun appendFooter(to: StringBuilder) - - companion object { - fun default(css: String? = null): HtmlTemplateService { - return object : HtmlTemplateService { - override fun appendFooter(to: StringBuilder) { - if (!to.endsWith('\n')) { - to.append('\n') - } - to.appendln("</BODY>") - to.appendln("</HTML>") - } - override fun appendHeader(to: StringBuilder, title: String?, basePath: File) { - to.appendln("<HTML>") - to.appendln("<HEAD>") - to.appendln("<meta charset=\"UTF-8\">") - if (title != null) { - to.appendln("<title>$title</title>") - } - if (css != null) { - val cssPath = basePath.resolve(css).toUnixString() - to.appendln("<link rel=\"stylesheet\" href=\"$cssPath\">") - } - to.appendln("</HEAD>") - to.appendln("<BODY>") - } - } - } - } -} - - diff --git a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlPackageListService.kt b/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlPackageListService.kt deleted file mode 100644 index 09bb2602..00000000 --- a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlPackageListService.kt +++ /dev/null @@ -1,117 +0,0 @@ -package org.jetbrains.dokka.Formats - -import org.jetbrains.dokka.* -import org.jetbrains.dokka.ExternalDocumentationLinkResolver.Companion.DOKKA_PARAM_PREFIX -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject -import org.jetbrains.kotlin.types.KotlinType - -class JavaLayoutHtmlPackageListService: PackageListService { - - private fun StringBuilder.appendParam(name: String, value: String) { - append(DOKKA_PARAM_PREFIX) - append(name) - append(":") - appendln(value) - } - - override fun formatPackageList(module: DocumentationModule): String { - val packages = module.members(NodeKind.Package).map { it.name } - - return buildString { - appendParam("format", "java-layout-html") - appendParam("mode", "kotlin") - for (p in packages) { - appendln(p) - } - } - } - -} - -class JavaLayoutHtmlInboundLinkResolutionService(private val paramMap: Map<String, List<String>>) : InboundExternalLinkResolutionService { - private fun getContainerPath(symbol: DeclarationDescriptor): String? { - return when (symbol) { - is PackageFragmentDescriptor -> symbol.fqName.asString().replace('.', '/') + "/" - is ClassifierDescriptor -> getContainerPath(symbol.findPackage()) + symbol.nameWithOuter() + ".html" - else -> null - } - } - - private fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor = - generateSequence(this) { it.containingDeclaration }.filterIsInstance<PackageFragmentDescriptor>().first() - - private fun ClassifierDescriptor.nameWithOuter(): String = - generateSequence(this) { it.containingDeclaration as? ClassifierDescriptor } - .toList().asReversed().joinToString(".") { it.name.asString() } - - private fun getPagePath(symbol: DeclarationDescriptor): String? { - return when (symbol) { - is PackageFragmentDescriptor -> getContainerPath(symbol) + "package-summary.html" - is EnumEntrySyntheticClassDescriptor -> getContainerPath(symbol.containingDeclaration) + "#" + symbol.signatureForAnchorUrlEncoded() - is ClassifierDescriptor -> getContainerPath(symbol) + "#" - is FunctionDescriptor, is PropertyDescriptor -> getContainerPath(symbol.containingDeclaration!!) + "#" + symbol.signatureForAnchorUrlEncoded() - else -> null - } - } - - private fun DeclarationDescriptor.signatureForAnchor(): String? { - - fun ReceiverParameterDescriptor.extractReceiverName(): String { - var receiverClass: DeclarationDescriptor = type.constructor.declarationDescriptor!! - if (receiverClass.isCompanionObject()) { - receiverClass = receiverClass.containingDeclaration!! - } else if (receiverClass is TypeParameterDescriptor) { - val upperBoundClass = receiverClass.upperBounds.singleOrNull()?.constructor?.declarationDescriptor - if (upperBoundClass != null) { - receiverClass = upperBoundClass - } - } - - return receiverClass.name.asString() - } - - fun KotlinType.qualifiedNameForSignature(): String { - val desc = constructor.declarationDescriptor - return desc?.fqNameUnsafe?.asString() ?: "<ERROR TYPE NAME>" - } - - fun StringBuilder.appendReceiverAndCompanion(desc: CallableDescriptor) { - if (desc.containingDeclaration.isCompanionObject()) { - append("Companion.") - } - desc.extensionReceiverParameter?.let { - append("(") - append(it.extractReceiverName()) - append(").") - } - } - - return when(this) { - is EnumEntrySyntheticClassDescriptor -> buildString { - append("ENUM_VALUE:") - append(name.asString()) - } - is FunctionDescriptor -> buildString { - appendReceiverAndCompanion(this@signatureForAnchor) - append(name.asString()) - valueParameters.joinTo(this, prefix = "(", postfix = ")") { - it.type.qualifiedNameForSignature() - } - } - is PropertyDescriptor -> buildString { - appendReceiverAndCompanion(this@signatureForAnchor) - append(name.asString()) - append(":") - append(returnType?.qualifiedNameForSignature()) - } - else -> null - } - } - - private fun DeclarationDescriptor.signatureForAnchorUrlEncoded(): String? = signatureForAnchor()?.urlEncoded() - - override fun getPath(symbol: DeclarationDescriptor) = getPagePath(symbol) -}
\ No newline at end of file diff --git a/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt b/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt deleted file mode 100644 index 885cdf6c..00000000 --- a/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt +++ /dev/null @@ -1,91 +0,0 @@ -package org.jetbrains.dokka.Formats - -import com.google.inject.Binder -import com.google.inject.Inject -import kotlinx.html.li -import kotlinx.html.stream.appendHTML -import kotlinx.html.ul -import org.jetbrains.dokka.* -import org.jetbrains.dokka.Samples.DefaultSampleProcessingService -import org.jetbrains.dokka.Utilities.bind -import org.jetbrains.dokka.Utilities.toType -import java.io.File - - -class JavaLayoutHtmlFormatDescriptor : FormatDescriptor, DefaultAnalysisComponent { - override val packageDocumentationBuilderClass = KotlinPackageDocumentationBuilder::class - override val javaDocumentationBuilderClass = KotlinJavaDocumentationBuilder::class - override val sampleProcessingService = DefaultSampleProcessingService::class - override val elementSignatureProvider = KotlinElementSignatureProvider::class - - override fun configureOutput(binder: Binder): Unit = with(binder) { - bind<Generator>() toType generatorServiceClass - } - - val formatServiceClass = JavaLayoutHtmlFormatService::class - val generatorServiceClass = JavaLayoutHtmlFormatGenerator::class -} - - -class JavaLayoutHtmlFormatService : FormatService { - override val extension: String - get() = TODO("not implemented") - - - override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder { - TODO("not implemented") - } -} - -class JavaLayoutHtmlFormatOutputBuilder : FormattedOutputBuilder { - override fun appendNodes(nodes: Iterable<DocumentationNode>) { - - } -} - - -class JavaLayoutHtmlFormatNavListBuilder @Inject constructor() : OutlineFormatService { - override fun getOutlineFileName(location: Location): File { - TODO() - } - - override fun appendOutlineHeader(location: Location, node: DocumentationNode, to: StringBuilder) { - with(to.appendHTML()) { - //a(href = ) - li { - when { - node.kind == NodeKind.Package -> appendOutline(location, to, node.members) - } - } - } - } - - override fun appendOutlineLevel(to: StringBuilder, body: () -> Unit) { - with(to.appendHTML()) { - ul { body() } - } - } - -} - -class JavaLayoutHtmlFormatGenerator @Inject constructor( - private val outlineFormatService: OutlineFormatService -) : Generator { - override fun buildPages(nodes: Iterable<DocumentationNode>) { - - } - - override fun buildOutlines(nodes: Iterable<DocumentationNode>) { - for (node in nodes) { - if (node.kind == NodeKind.Module) { - //outlineFormatService.formatOutline() - } - } - } - - override fun buildSupportFiles() {} - - override fun buildPackageList(nodes: Iterable<DocumentationNode>) { - - } -}
\ No newline at end of file diff --git a/core/src/main/kotlin/Formats/JekyllFormatService.kt b/core/src/main/kotlin/Formats/JekyllFormatService.kt deleted file mode 100644 index a948dfa9..00000000 --- a/core/src/main/kotlin/Formats/JekyllFormatService.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.jetbrains.dokka - -import com.google.inject.Inject -import com.google.inject.name.Named -import org.jetbrains.dokka.Utilities.impliedPlatformsName - -open class JekyllOutputBuilder(to: StringBuilder, - location: Location, - generator: NodeLocationAwareGenerator, - languageService: LanguageService, - extension: String, - impliedPlatforms: List<String>) - : MarkdownOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) { - override fun appendNodes(nodes: Iterable<DocumentationNode>) { - to.appendln("---") - appendFrontMatter(nodes, to) - to.appendln("---") - to.appendln("") - super.appendNodes(nodes) - } - - protected open fun appendFrontMatter(nodes: Iterable<DocumentationNode>, to: StringBuilder) { - to.appendln("title: ${getPageTitle(nodes)}") - } -} - - -open class JekyllFormatService( - generator: NodeLocationAwareGenerator, - signatureGenerator: LanguageService, - linkExtension: String, - impliedPlatforms: List<String> -) : MarkdownFormatService(generator, signatureGenerator, linkExtension, impliedPlatforms) { - - @Inject constructor( - generator: NodeLocationAwareGenerator, - signatureGenerator: LanguageService, - @Named(impliedPlatformsName) impliedPlatforms: List<String> - ) : this(generator, signatureGenerator, "html", impliedPlatforms) - - override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder = - JekyllOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) - -} diff --git a/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt b/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt deleted file mode 100644 index 3cdea156..00000000 --- a/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt +++ /dev/null @@ -1,264 +0,0 @@ -package org.jetbrains.dokka - -import com.google.inject.Inject -import com.google.inject.name.Named -import org.jetbrains.dokka.Utilities.impliedPlatformsName -import java.io.File - - -object EmptyHtmlTemplateService : HtmlTemplateService { - override fun appendFooter(to: StringBuilder) {} - - override fun appendHeader(to: StringBuilder, title: String?, basePath: File) {} -} - - -open class KotlinWebsiteHtmlOutputBuilder( - to: StringBuilder, - location: Location, - generator: NodeLocationAwareGenerator, - languageService: LanguageService, - extension: String, - val impliedPlatforms: List<String>, - templateService: HtmlTemplateService -) : HtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms, templateService) { - private var needHardLineBreaks = false - private var insideDiv = 0 - - override fun appendLine() {} - - override fun appendBreadcrumbs(path: Iterable<FormatLink>) { - if (path.count() > 1) { - to.append("<div class='api-docs-breadcrumbs'>") - super.appendBreadcrumbs(path) - to.append("</div>") - } - } - - override fun appendSinceKotlin(version: String) { - } - - override fun appendSinceKotlinWrapped(version: String) { - } - - override fun appendCode(body: () -> Unit) = wrapIfNotEmpty("<code>", "</code>", body) - - protected fun div(to: StringBuilder, cssClass: String, otherAttributes: String = "", block: () -> Unit) { - to.append("<div class=\"$cssClass\"$otherAttributes") - to.append(">") - insideDiv++ - block() - insideDiv-- - to.append("</div>\n") - } - - override fun appendAsSignature(node: ContentNode, block: () -> Unit) { - val contentLength = node.textLength - if (contentLength == 0) return - div(to, "signature") { - needHardLineBreaks = contentLength >= 62 - try { - block() - } finally { - needHardLineBreaks = false - } - } - } - - override fun appendAsOverloadGroup(to: StringBuilder, platforms: PlatformsData, block: () -> Unit) { - div(to, "overload-group", calculateDataAttributes(platforms)) { - block() - } - } - - override fun appendLink(href: String, body: () -> Unit) = wrap("<a href=\"$href\">", "</a>", body) - - override fun appendTable(vararg columns: String, body: () -> Unit) { - //to.appendln("<table class=\"api-docs-table\">") - div(to, "api-declarations-list") { - body() - } - //to.appendln("</table>") - } - - override fun appendTableBody(body: () -> Unit) { - //to.appendln("<tbody>") - body() - //to.appendln("</tbody>") - } - - override fun appendTableRow(body: () -> Unit) { - //to.appendln("<tr>") - body() - //to.appendln("</tr>") - } - - override fun appendTableCell(body: () -> Unit) { -// to.appendln("<td>") - body() -// to.appendln("\n</td>") - } - - override fun appendSymbol(text: String) { - to.append("<span class=\"symbol\">${text.htmlEscape()}</span>") - } - - override fun appendKeyword(text: String) { - to.append("<span class=\"keyword\">${text.htmlEscape()}</span>") - } - - override fun appendIdentifier(text: String, kind: IdentifierKind, signature: String?) { - val id = signature?.let { " id=\"$it\"" }.orEmpty() - to.append("<span class=\"${identifierClassName(kind)}\"$id>${text.htmlEscape()}</span>") - } - - override fun appendSoftLineBreak() { - if (needHardLineBreaks) - to.append("<br/>") - } - - override fun appendIndentedSoftLineBreak() { - if (needHardLineBreaks) { - to.append("<br/> ") - } - } - - private fun identifierClassName(kind: IdentifierKind) = when (kind) { - IdentifierKind.ParameterName -> "parameterName" - IdentifierKind.SummarizedTypeName -> "summarizedTypeName" - else -> "identifier" - } - - private data class PlatformsForElement( - val platformToVersion: Map<String, String> - ) - - private fun calculatePlatforms(platforms: PlatformsData): PlatformsForElement { - //val kotlinVersion = platforms.singleOrNull(String::isKotlinVersion)?.removePrefix("Kotlin ") - val jreVersion = platforms.keys.filter(String::isJREVersion).min()?.takeUnless { it.endsWith("6") } - val targetPlatforms = platforms.filterNot { it.key.isJREVersion() } + - listOfNotNull(jreVersion?.let { it to platforms[it]!! }) - - return PlatformsForElement( - targetPlatforms.mapValues { (_, nodes) -> effectiveSinceKotlinForNodes(nodes) } - ) - } - - private fun calculateDataAttributes(platforms: PlatformsData): String { - val platformToVersion = calculatePlatforms(platforms).platformToVersion - val (platformNames, versions) = platformToVersion.toList().unzip() - return "data-platform=\"${platformNames.joinToString()}\" "+ - "data-kotlin-version=\"${versions.joinToString()}\"" - } - - override fun appendIndexRow(platforms: PlatformsData, block: () -> Unit) { -// if (platforms.isNotEmpty()) -// wrap("<tr${calculateDataAttributes(platforms)}>", "</tr>", block) -// else -// appendTableRow(block) - div(to, "declarations", otherAttributes = " ${calculateDataAttributes(platforms)}") { - block() - } - } - - override fun appendPlatforms(platforms: PlatformsData) { - val platformToVersion = calculatePlatforms(platforms).platformToVersion - div(to, "tags") { - div(to, "spacer") {} - platformToVersion.entries.sortedBy { - platformSortWeight(it.key) - }.forEach { (platform, version) -> - div(to, "tags__tag platform tag-value-$platform", - otherAttributes = " data-tag-version=\"$version\"") { - to.append(platform) - } - } - div(to, "tags__tag kotlin-version") { - to.append(mergeVersions(platformToVersion.values.toList())) - } - } - } - - override fun appendAsNodeDescription(platforms: PlatformsData, block: () -> Unit) { - div(to, "node-page-main", otherAttributes = " ${calculateDataAttributes(platforms)}") { - block() - } - - } - - override fun appendBreadcrumbSeparator() { - to.append(" / ") - } - - override fun appendPlatformsAsText(platforms: PlatformsData) { - appendHeader(5) { - val filtered = platforms.keys.filterNot { it.isJREVersion() }.sortedBy { platformSortWeight(it) } - if (filtered.isNotEmpty()) { - to.append("For ") - filtered.joinTo(to) - } - } - } - - override fun appendSampleBlockCode(language: String, imports: () -> Unit, body: () -> Unit) { - div(to, "sample", otherAttributes = " data-min-compiler-version=\"1.3\"") { - appendBlockCode(language) { - imports() - wrap("\n\nfun main(args: Array<String>) {".htmlEscape(), "}") { - wrap("\n//sampleStart\n", "\n//sampleEnd\n", body) - } - } - } - } - - override fun appendSoftParagraph(body: () -> Unit) = appendParagraph(body) - - - override fun appendSectionWithTag(section: ContentSection) { - appendParagraph { - appendStrong { appendText(section.tag) } - appendText(" ") - appendContent(section) - } - } - - override fun appendAsPlatformDependentBlock(platforms: PlatformsData, block: (PlatformsData) -> Unit) { - if (platforms.isNotEmpty()) - wrap("<div ${calculateDataAttributes(platforms)}>", "</div>") { - block(platforms) - } - else - block(platforms) - } - - override fun appendAsSummaryGroup(platforms: PlatformsData, block: (PlatformsData) -> Unit) { - div(to, "summary-group", otherAttributes = " ${calculateDataAttributes(platforms)}") { - block(platforms) - } - } - - fun platformSortWeight(name: String) = when(name.toLowerCase()) { - "common" -> 0 - "jvm" -> 1 - "js" -> 3 - "native" -> 4 - else -> 2 // This is hack to support JRE/JUnit and so on - } -} - -class KotlinWebsiteHtmlFormatService @Inject constructor( - generator: NodeLocationAwareGenerator, - signatureGenerator: LanguageService, - @Named(impliedPlatformsName) impliedPlatforms: List<String>, - templateService: HtmlTemplateService -) : HtmlFormatService(generator, signatureGenerator, templateService, impliedPlatforms) { - - override fun enumerateSupportFiles(callback: (String, String) -> Unit) {} - - override fun createOutputBuilder(to: StringBuilder, location: Location) = - KotlinWebsiteHtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms, templateService) -} - - -private fun String.isKotlinVersion() = this.startsWith("Kotlin") -private fun String.isJREVersion() = this.startsWith("JRE", ignoreCase=true)
\ No newline at end of file diff --git a/core/src/main/kotlin/Formats/MarkdownFormatService.kt b/core/src/main/kotlin/Formats/MarkdownFormatService.kt deleted file mode 100644 index 216dd2ef..00000000 --- a/core/src/main/kotlin/Formats/MarkdownFormatService.kt +++ /dev/null @@ -1,250 +0,0 @@ -package org.jetbrains.dokka - -import com.google.inject.Inject -import com.google.inject.name.Named -import org.jetbrains.dokka.Utilities.impliedPlatformsName -import java.util.* - -enum class ListKind { - Ordered, - Unordered -} - -private class ListState(val kind: ListKind, var size: Int = 1) { - fun getTagAndIncrement() = when (kind) { - ListKind.Ordered -> "${size++}. " - else -> "* " - } -} - -private val TWO_LINE_BREAKS = System.lineSeparator() + System.lineSeparator() - -open class MarkdownOutputBuilder(to: StringBuilder, - location: Location, - generator: NodeLocationAwareGenerator, - languageService: LanguageService, - extension: String, - impliedPlatforms: List<String>) - : StructuredOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) -{ - private val listStack = ArrayDeque<ListState>() - protected var inTableCell = false - protected var inCodeBlock = false - private var lastTableCellStart = -1 - private var maxBackticksInCodeBlock = 0 - - private fun appendNewline() { - while (to.endsWith(' ')) { - to.setLength(to.length - 1) - } - to.appendln() - } - - private fun ensureNewline() { - if (inTableCell && listStack.isEmpty()) { - if (to.length != lastTableCellStart && !to.endsWith("<br>")) { - to.append("<br>") - } - } - else { - if (!endsWithNewline()) { - appendNewline() - } - } - } - - private fun endsWithNewline(): Boolean { - var index = to.length - 1 - while (index > 0) { - val c = to[index] - if (c != ' ') { - return c == '\n' - } - index-- - } - return false - } - - override fun ensureParagraph() { - if (!to.endsWith(TWO_LINE_BREAKS)) { - if (!to.endsWith('\n')) { - appendNewline() - } - appendNewline() - } - } - override fun appendBreadcrumbSeparator() { - to.append(" / ") - } - - private val backTickFindingRegex = """(`+)""".toRegex() - - override fun appendText(text: String) { - if (inCodeBlock) { - to.append(text) - val backTicks = backTickFindingRegex.findAll(text) - val longestBackTickRun = backTicks.map { it.value.length }.max() ?: 0 - maxBackticksInCodeBlock = maxBackticksInCodeBlock.coerceAtLeast(longestBackTickRun) - } - else { - if (text == "\n" && inTableCell) { - to.append(" ") - } else { - to.append(text.htmlEscape()) - } - } - } - - override fun appendCode(body: () -> Unit) { - inCodeBlock = true - val codeBlockStart = to.length - maxBackticksInCodeBlock = 0 - - wrapIfNotEmpty("`", "`", body, checkEndsWith = true) - - if (maxBackticksInCodeBlock > 0) { - val extraBackticks = "`".repeat(maxBackticksInCodeBlock) - to.insert(codeBlockStart, extraBackticks) - to.append(extraBackticks) - } - - inCodeBlock = false - } - - override fun appendUnorderedList(body: () -> Unit) { - listStack.push(ListState(ListKind.Unordered)) - body() - listStack.pop() - ensureNewline() - } - - override fun appendOrderedList(body: () -> Unit) { - listStack.push(ListState(ListKind.Ordered)) - body() - listStack.pop() - ensureNewline() - } - - override fun appendListItem(body: () -> Unit) { - ensureNewline() - to.append(listStack.peek()?.getTagAndIncrement()) - body() - ensureNewline() - } - - override fun appendStrong(body: () -> Unit) = wrap("**", "**", body) - override fun appendEmphasis(body: () -> Unit) = wrap("*", "*", body) - override fun appendStrikethrough(body: () -> Unit) = wrap("~~", "~~", body) - - override fun appendLink(href: String, body: () -> Unit) { - if (inCodeBlock) { - wrap("`[`", "`]($href)`", body) - } - else { - wrap("[", "]($href)", body) - } - } - - override fun appendLine() { - if (inTableCell) { - to.append("<br>") - } - else { - appendNewline() - } - } - - override fun appendAnchor(anchor: String) { - // no anchors in Markdown - } - - override fun appendParagraph(body: () -> Unit) { - when { - inTableCell -> { - ensureNewline() - body() - } - listStack.isNotEmpty() -> { - body() - ensureNewline() - } - else -> { - ensureParagraph() - body() - ensureParagraph() - } - } - } - - override fun appendHeader(level: Int, body: () -> Unit) { - when { - inTableCell -> { - body() - } - else -> { - ensureParagraph() - to.append("${"#".repeat(level)} ") - body() - ensureParagraph() - } - } - } - - override fun appendBlockCode(language: String, body: () -> Unit) { - inCodeBlock = true - ensureParagraph() - to.appendln(if (language.isEmpty()) "```" else "``` $language") - body() - ensureNewline() - to.appendln("```") - appendLine() - inCodeBlock = false - } - - override fun appendTable(vararg columns: String, body: () -> Unit) { - ensureParagraph() - body() - ensureParagraph() - } - - override fun appendTableBody(body: () -> Unit) { - body() - } - - override fun appendTableRow(body: () -> Unit) { - to.append("|") - body() - appendNewline() - } - - override fun appendTableCell(body: () -> Unit) { - to.append(" ") - inTableCell = true - lastTableCellStart = to.length - body() - inTableCell = false - to.append(" |") - } - - override fun appendNonBreakingSpace() { - if (inCodeBlock) { - to.append(" ") - } - else { - to.append(" ") - } - } -} - -open class MarkdownFormatService(generator: NodeLocationAwareGenerator, - signatureGenerator: LanguageService, - linkExtension: String, - val impliedPlatforms: List<String>) -: StructuredFormatService(generator, signatureGenerator, "md", linkExtension) { - @Inject constructor(generator: NodeLocationAwareGenerator, - signatureGenerator: LanguageService, - @Named(impliedPlatformsName) impliedPlatforms: List<String>): this(generator, signatureGenerator, "md", impliedPlatforms) - - override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder = - MarkdownOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) -} diff --git a/core/src/main/kotlin/Formats/OutlineService.kt b/core/src/main/kotlin/Formats/OutlineService.kt deleted file mode 100644 index 958e93af..00000000 --- a/core/src/main/kotlin/Formats/OutlineService.kt +++ /dev/null @@ -1,29 +0,0 @@ -package org.jetbrains.dokka - -import java.io.File - -/** - * Service for building the outline of the package contents. - */ -interface OutlineFormatService { - fun getOutlineFileName(location: Location): File - - fun appendOutlineHeader(location: Location, node: DocumentationNode, to: StringBuilder) - fun appendOutlineLevel(to: StringBuilder, body: () -> Unit) - - /** Appends formatted outline to [StringBuilder](to) using specified [location] */ - fun appendOutline(location: Location, to: StringBuilder, nodes: Iterable<DocumentationNode>) { - for (node in nodes) { - appendOutlineHeader(location, node, to) - if (node.members.any()) { - val sortedMembers = node.members.sortedBy { it.name.toLowerCase() } - appendOutlineLevel(to) { - appendOutline(location, to, sortedMembers) - } - } - } - } - - fun formatOutline(location: Location, nodes: Iterable<DocumentationNode>): String = - StringBuilder().apply { appendOutline(location, this, nodes) }.toString() -} diff --git a/core/src/main/kotlin/Formats/PackageListService.kt b/core/src/main/kotlin/Formats/PackageListService.kt deleted file mode 100644 index e675d927..00000000 --- a/core/src/main/kotlin/Formats/PackageListService.kt +++ /dev/null @@ -1,66 +0,0 @@ -package org.jetbrains.dokka - -import com.google.inject.Inject - - -interface PackageListService { - fun formatPackageList(module: DocumentationModule): String -} - -class DefaultPackageListService @Inject constructor( - val generator: NodeLocationAwareGenerator, - val formatService: FormatService -) : PackageListService { - - override fun formatPackageList(module: DocumentationModule): String { - val packages = mutableSetOf<String>() - val nonStandardLocations = mutableMapOf<String, String>() - - fun visit(node: DocumentationNode, relocated: Boolean = false) { - val nodeKind = node.kind - - when (nodeKind) { - NodeKind.Package -> { - packages.add(node.qualifiedName()) - node.members.forEach { visit(it) } - } - NodeKind.Signature -> { - if (relocated) - nonStandardLocations[node.name] = generator.relativePathToLocation(module, node.owner!!) - } - NodeKind.ExternalClass -> { - node.members.forEach { visit(it, relocated = true) } - } - NodeKind.GroupNode -> { - if (node.members.isNotEmpty()) { - // Only nodes only has single file is need to be relocated - // TypeAliases for example - node.origins - .filter { it.members.isEmpty() } - .forEach { visit(it, relocated = true) } - } - } - else -> { - if (nodeKind in NodeKind.classLike || nodeKind in NodeKind.memberLike) { - node.details(NodeKind.Signature).forEach { visit(it, relocated) } - node.members.forEach { visit(it, relocated) } - } - } - } - } - - module.members.forEach { visit(it) } - - return buildString { - appendln("\$dokka.linkExtension:${formatService.linkExtension}") - - nonStandardLocations.map { (signature, location) -> "\$dokka.location:$signature\u001f$location" } - .sorted().joinTo(this, separator = "\n", postfix = "\n") - - packages.sorted().joinTo(this, separator = "\n", postfix = "\n") - } - - } - -} - diff --git a/core/src/main/kotlin/Formats/StandardFormats.kt b/core/src/main/kotlin/Formats/StandardFormats.kt deleted file mode 100644 index 86f70a37..00000000 --- a/core/src/main/kotlin/Formats/StandardFormats.kt +++ /dev/null @@ -1,55 +0,0 @@ -package org.jetbrains.dokka.Formats - -import com.google.inject.Binder -import org.jetbrains.dokka.* -import org.jetbrains.dokka.Samples.KotlinWebsiteSampleProcessingService -import org.jetbrains.dokka.Utilities.bind -import kotlin.reflect.KClass - -abstract class KotlinFormatDescriptorBase - : FileGeneratorBasedFormatDescriptor(), - DefaultAnalysisComponent, - DefaultAnalysisComponentServices by KotlinAsKotlin { - override val generatorServiceClass = FileGenerator::class - override val outlineServiceClass: KClass<out OutlineFormatService>? = null - override val packageListServiceClass: KClass<out PackageListService>? = DefaultPackageListService::class -} - -abstract class HtmlFormatDescriptorBase : FileGeneratorBasedFormatDescriptor(), DefaultAnalysisComponent { - override val formatServiceClass = HtmlFormatService::class - override val outlineServiceClass = HtmlFormatService::class - override val generatorServiceClass = FileGenerator::class - override val packageListServiceClass = DefaultPackageListService::class - - override fun configureOutput(binder: Binder): Unit = with(binder) { - super.configureOutput(binder) - bind<HtmlTemplateService>().toProvider { HtmlTemplateService.default("style.css") } - } -} - -class HtmlFormatDescriptor : HtmlFormatDescriptorBase(), DefaultAnalysisComponentServices by KotlinAsKotlin - -class HtmlAsJavaFormatDescriptor : HtmlFormatDescriptorBase(), DefaultAnalysisComponentServices by KotlinAsJava - -class KotlinWebsiteHtmlFormatDescriptor : KotlinFormatDescriptorBase() { - override val formatServiceClass = KotlinWebsiteHtmlFormatService::class - override val sampleProcessingService = KotlinWebsiteSampleProcessingService::class - override val outlineServiceClass = YamlOutlineService::class - - override fun configureOutput(binder: Binder) = with(binder) { - super.configureOutput(binder) - bind<HtmlTemplateService>().toInstance(EmptyHtmlTemplateService) - } -} - -class JekyllFormatDescriptor : KotlinFormatDescriptorBase() { - override val formatServiceClass = JekyllFormatService::class -} - -class MarkdownFormatDescriptor : KotlinFormatDescriptorBase() { - override val formatServiceClass = MarkdownFormatService::class -} - -class GFMFormatDescriptor : KotlinFormatDescriptorBase() { - override val formatServiceClass = GFMFormatService::class -} diff --git a/core/src/main/kotlin/Formats/StructuredFormatService.kt b/core/src/main/kotlin/Formats/StructuredFormatService.kt deleted file mode 100644 index 76f9366f..00000000 --- a/core/src/main/kotlin/Formats/StructuredFormatService.kt +++ /dev/null @@ -1,1014 +0,0 @@ -package org.jetbrains.dokka - -import org.jetbrains.dokka.LanguageService.RenderMode -import org.jetbrains.kotlin.utils.keysToMap -import java.util.* - -data class FormatLink(val text: String, val href: String) - -private data class Summarized( - val data: List<SummarizedBySummary> -) { - - constructor(data: Map<ContentNode, Map<ContentNode, List<DocumentationNode>>>) : this( - data.entries.map { (summary, signatureToMember) -> - SummarizedBySummary( - summary, - signatureToMember.map { (signature, nodes) -> - SummarizedNodes(signature, nodes) - } - ) - } - ) - - data class SummarizedNodes(val content: ContentNode, val nodes: List<DocumentationNode>) { - val platforms = effectivePlatformsForMembers(nodes) - } - data class SummarizedBySummary(val content: ContentNode, val signatures: List<SummarizedNodes>) { - val platforms = effectivePlatformsForMembers(signatures.flatMap { it.nodes }) - val platformsOnSignature = !samePlatforms(signatures.map { it.platforms }) - } - - - fun computePlatformLevel(): PlatformPlacement { - if (data.any { it.platformsOnSignature }) { - return PlatformPlacement.Signature - } - if (samePlatforms(data.map { it.platforms })) { - return PlatformPlacement.Row - } - return PlatformPlacement.Summary - } - val platformPlacement: PlatformPlacement = computePlatformLevel() - val platforms = effectivePlatformsForMembers(data.flatMap { it.signatures.flatMap { it.nodes } }) - - - enum class PlatformPlacement { - Row, Summary, Signature - } -} - -abstract class StructuredOutputBuilder(val to: StringBuilder, - val location: Location, - val generator: NodeLocationAwareGenerator, - val languageService: LanguageService, - val extension: String, - impliedPlatforms: List<String>) : FormattedOutputBuilder { - - protected fun wrap(prefix: String, suffix: String, body: () -> Unit) { - to.append(prefix) - body() - to.append(suffix) - } - - protected fun wrapIfNotEmpty(prefix: String, suffix: String, body: () -> Unit, checkEndsWith: Boolean = false) { - val startLength = to.length - to.append(prefix) - body() - if (checkEndsWith && to.endsWith(suffix)) { - to.setLength(to.length - suffix.length) - } else if (to.length > startLength + prefix.length) { - to.append(suffix) - } else { - to.setLength(startLength) - } - } - - protected fun wrapInTag(tag: String, - body: () -> Unit, - newlineBeforeOpen: Boolean = false, - newlineAfterOpen: Boolean = false, - newlineAfterClose: Boolean = false) { - if (newlineBeforeOpen && !to.endsWith('\n')) to.appendln() - to.append("<$tag>") - if (newlineAfterOpen) to.appendln() - body() - to.append("</$tag>") - if (newlineAfterClose) to.appendln() - } - - protected abstract fun ensureParagraph() - - open fun appendSampleBlockCode(language: String, imports: () -> Unit, body: () -> Unit) = appendBlockCode(language, body) - abstract fun appendBlockCode(language: String, body: () -> Unit) - abstract fun appendHeader(level: Int = 1, body: () -> Unit) - abstract fun appendParagraph(body: () -> Unit) - - open fun appendSoftParagraph(body: () -> Unit) { - ensureParagraph() - body() - } - - abstract fun appendLine() - abstract fun appendAnchor(anchor: String) - - abstract fun appendTable(vararg columns: String, body: () -> Unit) - abstract fun appendTableBody(body: () -> Unit) - abstract fun appendTableRow(body: () -> Unit) - abstract fun appendTableCell(body: () -> Unit) - - abstract fun appendText(text: String) - - open fun appendSinceKotlin(version: String) { - appendText("Since: ") - appendCode { appendText(version) } - } - - open fun appendSinceKotlinWrapped(version: String) { - wrap(" (", ")") { - appendSinceKotlin(version) - } - } - - open fun appendSectionWithTag(section: ContentSection) { - appendParagraph { - appendStrong { appendText(section.tag) } - appendLine() - appendContent(section) - } - } - - open fun appendAsPlatformDependentBlock(platforms: PlatformsData, block: (PlatformsData) -> Unit) { - block(platforms) - } - - open fun appendAsSummaryGroup(platforms: PlatformsData, block: (PlatformsData) -> Unit) { - appendAsPlatformDependentBlock(platforms, block) - } - - open fun appendSymbol(text: String) { - appendText(text) - } - - open fun appendKeyword(text: String) { - appendText(text) - } - - open fun appendIdentifier(text: String, kind: IdentifierKind, signature: String?) { - appendText(text) - } - - open fun appendAsNodeDescription(platforms: PlatformsData, block: () -> Unit) { - block() - } - - fun appendEntity(text: String) { - to.append(text) - } - - abstract fun appendLink(href: String, body: () -> Unit) - - open fun appendLink(link: FormatLink) { - appendLink(link.href) { appendText(link.text) } - } - - abstract fun appendStrong(body: () -> Unit) - abstract fun appendStrikethrough(body: () -> Unit) - abstract fun appendEmphasis(body: () -> Unit) - abstract fun appendCode(body: () -> Unit) - abstract fun appendUnorderedList(body: () -> Unit) - abstract fun appendOrderedList(body: () -> Unit) - abstract fun appendListItem(body: () -> Unit) - - abstract fun appendBreadcrumbSeparator() - abstract fun appendNonBreakingSpace() - open fun appendSoftLineBreak() { - } - - open fun appendIndentedSoftLineBreak() { - } - - fun appendContent(content: List<ContentNode>) { - for (contentNode in content) { - appendContent(contentNode) - } - } - - open fun appendContent(content: ContentNode) { - when (content) { - is ContentText -> appendText(content.text) - is ContentSymbol -> appendSymbol(content.text) - is ContentKeyword -> appendKeyword(content.text) - is ContentIdentifier -> appendIdentifier(content.text, content.kind, content.signature) - is ContentNonBreakingSpace -> appendNonBreakingSpace() - is ContentSoftLineBreak -> appendSoftLineBreak() - is ContentIndentedSoftLineBreak -> appendIndentedSoftLineBreak() - is ContentEntity -> appendEntity(content.text) - is ContentStrong -> appendStrong { appendContent(content.children) } - is ContentStrikethrough -> appendStrikethrough { appendContent(content.children) } - is ContentCode -> appendCode { appendContent(content.children) } - is ContentEmphasis -> appendEmphasis { appendContent(content.children) } - is ContentUnorderedList -> appendUnorderedList { appendContent(content.children) } - is ContentOrderedList -> appendOrderedList { appendContent(content.children) } - is ContentListItem -> appendListItem { - val child = content.children.singleOrNull() - if (child is ContentParagraph) { - appendContent(child.children) - } else { - appendContent(content.children) - } - } - - is NodeRenderContent -> { - val node = content.node - appendContent(languageService.render(node, content.mode)) - } - is ContentNodeLink -> { - val node = content.node - val linkTo = if (node != null) locationHref(location, node, generator) else "#" - appendLinkIfNotThisPage(linkTo, content) - } - is ContentExternalLink -> appendLinkIfNotThisPage(content.href, content) - - is ContentParagraph -> { - if (!content.isEmpty()) { - appendParagraph { appendContent(content.children) } - } - } - - is ContentBlockSampleCode, is ContentBlockCode -> { - content as ContentBlockCode - fun ContentBlockCode.appendBlockCodeContent() { - children - .dropWhile { it is ContentText && it.text.isBlank() } - .forEach { appendContent(it) } - } - when (content) { - is ContentBlockSampleCode -> - appendSampleBlockCode(content.language, content.importsBlock::appendBlockCodeContent) { content.appendBlockCodeContent() } - is ContentBlockCode -> - appendBlockCode(content.language) { content.appendBlockCodeContent() } - } - } - is ContentHeading -> appendHeader(content.level) { appendContent(content.children) } - is ContentBlock -> appendContent(content.children) - } - } - - private fun appendLinkIfNotThisPage(href: String, content: ContentBlock) { - if (href == ".") { - appendContent(content.children) - } else { - appendLink(href) { appendContent(content.children) } - } - } - - open fun link( - from: DocumentationNode, - to: DocumentationNode, - name: (DocumentationNode) -> String = DocumentationNode::name - ): FormatLink = link(from, to, extension, name) - - open fun link( - from: DocumentationNode, - to: DocumentationNode, - extension: String, - name: (DocumentationNode) -> String = DocumentationNode::name - ): FormatLink = - FormatLink(name(to), generator.relativePathToLocation(from, to)) - - private fun DocumentationNode.isModuleOrPackage(): Boolean = - kind == NodeKind.Module || kind == NodeKind.Package - - protected open fun appendAsSignature(node: ContentNode, block: () -> Unit) { - block() - } - - protected open fun appendAsOverloadGroup(to: StringBuilder, platforms: PlatformsData, block: () -> Unit) { - block() - } - - protected open fun appendIndexRow(platforms: PlatformsData, block: () -> Unit) { - appendTableRow(block) - } - - protected open fun appendPlatformsAsText(platforms: PlatformsData) { - appendPlatforms(platforms) - } - - protected open fun appendPlatforms(platforms: PlatformsData) { - if (platforms.isNotEmpty()) { - appendText(platforms.keys.joinToString(prefix = "(", postfix = ") ")) - } - } - - protected open fun appendBreadcrumbs(path: Iterable<FormatLink>) { - for ((index, item) in path.withIndex()) { - if (index > 0) { - appendBreadcrumbSeparator() - } - appendLink(item) - } - } - - fun Content.getSectionsWithSubjects(): Map<String, List<ContentSection>> = - sections.filter { it.subjectName != null }.groupBy { it.tag } - - private fun ContentNode.appendSignature() { - if (this is ContentBlock && this.isEmpty()) { - return - } - - val signatureAsCode = ContentCode() - signatureAsCode.append(this) - appendContent(signatureAsCode) - } - - open inner class PageBuilder(val nodes: Iterable<DocumentationNode>, val noHeader: Boolean = false) { - open fun build() { - val breakdownByLocation = nodes.groupBy { node -> - node.path.filterNot { it.name.isEmpty() }.map { link(node, it) }.distinct() - } - - for ((path, nodes) in breakdownByLocation) { - if (!noHeader && path.isNotEmpty()) { - appendBreadcrumbs(path) - appendLine() - appendLine() - } - appendLocation(nodes.filter { it.kind != NodeKind.ExternalClass }) - } - } - - private fun appendLocation(nodes: Iterable<DocumentationNode>) { - val singleNode = nodes.singleOrNull() - if (singleNode != null && singleNode.isModuleOrPackage()) { - if (singleNode.kind == NodeKind.Package) { - val packageName = if (singleNode.name.isEmpty()) "<root>" else singleNode.name - appendHeader(2) { appendText("Package $packageName") } - } - appendContent(singleNode.content) - } else { - val breakdownByName = nodes.groupBy { node -> node.name } - for ((name, items) in breakdownByName) { - if (!noHeader) - appendHeader { appendText(name) } - appendDocumentation(items, singleNode != null) - } - } - } - - private fun appendDocumentation(overloads: Iterable<DocumentationNode>, isSingleNode: Boolean) { - val breakdownBySummary = overloads.groupByTo(LinkedHashMap()) { node -> - when (node.kind) { - NodeKind.GroupNode -> node.origins.map { it.content } - else -> node.content - } - } - - if (breakdownBySummary.size == 1) { - val node = breakdownBySummary.values.single() - appendAsNodeDescription(effectivePlatformsForMembers(node)) { - formatOverloadGroup(node, isSingleNode) - } - } else { - for ((_, items) in breakdownBySummary) { - appendAsOverloadGroup(to, effectivePlatformsForMembers(items)) { - formatOverloadGroup(items) - } - } - } - } - - private fun formatOverloadGroup(items: List<DocumentationNode>, isSingleNode: Boolean = false) { - - val platformsPerGroup = samePlatforms( - items.flatMap { - if (it.kind == NodeKind.GroupNode) { - it.origins.groupBy { origin -> - languageService.render(origin) - }.values.map { origins -> effectivePlatformsForMembers(origins) } - } else { - listOf(effectivePlatformsForNode(it)) - } - } - ) - - if (platformsPerGroup) { - appendAsPlatformDependentBlock(effectivePlatformsForMembers(items)) { platforms -> - appendPlatforms(platforms) - } - } - for ((index, item) in items.withIndex()) { - if (index > 0) appendLine() - - if (item.kind == NodeKind.GroupNode) { - renderGroupNode(item, isSingleNode, !platformsPerGroup) - } else { - renderSimpleNode(item, isSingleNode, !platformsPerGroup) - } - - } - // All items have exactly the same documentation, so we can use any item to render it - val item = items.first() - // TODO: remove this block cause there is no one node with OverloadGroupNote detail - item.details(NodeKind.OverloadGroupNote).forEach { - appendContent(it.content) - } - - if (item.kind == NodeKind.GroupNode) { - val groupByContent = item.origins.groupBy { it.content } - if (groupByContent.count { !it.key.isEmpty() } > 1) { - if (groupByContent.size > 1) println("[mult] Found ov diff: ${generator.location(item).path}") - } - for ((content, origins) in groupByContent) { - if (content.isEmpty()) continue - appendAsPlatformDependentBlock(effectivePlatformsForMembers(origins)) { platforms -> - if (groupByContent.count { !it.key.isEmpty() } > 1) { - appendPlatformsAsText(platforms) - } - appendContent(content.summary) - content.appendDescription() - } - } - } else { - val platforms = effectivePlatformsForNode(item) - appendAsPlatformDependentBlock(platforms) { - appendContent(item.summary) - item.content.appendDescription() - } - } - } - - - fun renderSimpleNode(item: DocumentationNode, isSingleNode: Boolean, withPlatforms: Boolean = true) { - appendAsPlatformDependentBlock(effectivePlatformsForMembers(listOf(item))) { platforms -> - // TODO: use summarizesignatures - val rendered = languageService.render(item) - item.detailOrNull(NodeKind.Signature)?.let { - if (item.kind !in NodeKind.classLike || !isSingleNode) - appendAnchor(it.name) - } - if (withPlatforms) { - appendPlatforms(platforms) - } - appendAsSignature(rendered) { - appendCode { appendContent(rendered) } - item.appendSourceLink() - } - item.appendOverrides() - item.appendDeprecation() - } - } - - fun renderGroupNode(item: DocumentationNode, isSingleNode: Boolean, withPlatforms: Boolean = true) { - // TODO: use summarizesignatures - val groupBySignature = item.origins.groupBy { - languageService.render(it) - } - - for ((sign, nodes) in groupBySignature) { - appendAsPlatformDependentBlock(effectivePlatformsForMembers(nodes)) { platforms -> - val first = nodes.first() - first.detailOrNull(NodeKind.Signature)?.let { - if (item.kind !in NodeKind.classLike || !isSingleNode) - appendAnchor(it.name) - } - - if (withPlatforms) { - appendPlatforms(platforms) - } - - appendAsSignature(sign) { - appendCode { appendContent(sign) } - } - first.appendOverrides() - first.appendDeprecation() - } - - } - } - - private fun DocumentationNode.appendSourceLink() { - val sourceUrl = details(NodeKind.SourceUrl).firstOrNull() - if (sourceUrl != null) { - to.append(" ") - appendLink(sourceUrl.name) { to.append("(source)") } - } - } - - private fun DocumentationNode.appendOverrides() { - overrides.forEach { - appendParagraph { - to.append("Overrides ") - val location = generator.relativePathToLocation(this, it) - - appendLink(FormatLink(it.owner!!.name + "." + it.name, location)) - } - } - } - - private fun DocumentationNode.appendDeprecation() { - if (deprecation != null) { - val deprecationParameter = deprecation!!.details(NodeKind.Parameter).firstOrNull() - val deprecationValue = deprecationParameter?.details(NodeKind.Value)?.firstOrNull() - appendLine() - when { - deprecationValue != null -> { - appendStrong { to.append("Deprecated:") } - appendText(" " + deprecationValue.name.removeSurrounding("\"")) - appendLine() - appendLine() - } - deprecation?.content != Content.Empty -> { - appendStrong { to.append("Deprecated:") } - to.append(" ") - appendContent(deprecation!!.content) - } - else -> { - appendStrong { to.append("Deprecated") } - appendLine() - appendLine() - } - } - } - } - - -// protected fun platformsOfItems(items: List<DocumentationNode>): Set<String> { -// val platforms = items.asSequence().map { -// when (it.kind) { -// NodeKind.ExternalClass, NodeKind.Package, NodeKind.Module -> platformsOfItems(it.members) -// NodeKind.GroupNode -> platformsOfItems(it.origins) -// else -> it.platformsToShow.toSet() -// } -// } -// -// fun String.isKotlinVersion() = this.startsWith("Kotlin") -// -// if (platforms.count() == 0) return emptySet() -// -// // Calculating common platforms for items -// return platforms.reduce { result, platformsOfItem -> -// val otherKotlinVersion = result.find { it.isKotlinVersion() } -// val (kotlinVersions, otherPlatforms) = platformsOfItem.partition { it.isKotlinVersion() } -// -// // When no Kotlin version specified, it means that version is 1.0 -// if (otherKotlinVersion != null && kotlinVersions.isNotEmpty()) { -// result.intersect(platformsOfItem) + mergeVersions(otherKotlinVersion, kotlinVersions) -// } else { -// result.intersect(platformsOfItem) -// } -// } -// } -// -// protected fun unionPlatformsOfItems(items: List<DocumentationNode>): Set<String> { -// val platforms = items.asSequence().map { -// when (it.kind) { -// NodeKind.GroupNode -> unionPlatformsOfItems(it.origins) -// else -> it.platformsToShow.toSet() -// } -// } -// -// fun String.isKotlinVersion() = this.startsWith("Kotlin") -// -// if (platforms.count() == 0) return emptySet() -// -// // Calculating common platforms for items -// return platforms.reduce { result, platformsOfItem -> -// val otherKotlinVersion = result.find { it.isKotlinVersion() } -// val (kotlinVersions, otherPlatforms) = platformsOfItem.partition { it.isKotlinVersion() } -// -// // When no Kotlin version specified, it means that version is 1.0 -// if (otherKotlinVersion != null && kotlinVersions.isNotEmpty()) { -// result.union(otherPlatforms) + mergeVersions(otherKotlinVersion, kotlinVersions) -// } else { -// result.union(otherPlatforms) -// } -// } -// } - -// val DocumentationNode.platformsToShow: List<String> -// get() = platforms - - private fun Content.appendDescription() { - if (description != ContentEmpty) { - appendContent(description) - } - - - getSectionsWithSubjects().forEach { - appendSectionWithSubject(it.key, it.value) - } - - for (section in sections.filter { it.subjectName == null }) { - appendSectionWithTag(section) - } - } - - fun appendSectionWithSubject(title: String, subjectSections: List<ContentSection>) { - appendHeader(3) { appendText(title) } - subjectSections.forEach { - val subjectName = it.subjectName - if (subjectName != null) { - appendSoftParagraph { - appendAnchor(subjectName) - appendCode { to.append(subjectName) } - to.append(" - ") - appendContent(it) - } - } - } - } - - fun appendOriginsGroupByContent(node: DocumentationNode) { - require(node.kind == NodeKind.GroupNode) - val groupByContent = - node.origins.groupBy { it.content } - .mapValues { (_, origins) -> - effectivePlatformsForMembers(origins) - } - .filterNot { it.key.isEmpty() } - .toList() - .sortedByDescending { it.second.size } - - if (groupByContent.size > 1) println("[mult] Found diff: ${generator.location(node).path}") - for ((content, platforms) in groupByContent) { - appendAsPlatformDependentBlock(platforms) { - if (groupByContent.size > 1) { - appendPlatformsAsText(platforms) - } - appendContent(content.summary) - content.appendDescription() - } - } - } - } - - inner class SingleNodePageBuilder(val node: DocumentationNode, noHeader: Boolean = false) : - PageBuilder(listOf(node), noHeader) { - - override fun build() { - super.build() - SectionsBuilder(node).build() - } - } - - inner class GroupNodePageBuilder(val node: DocumentationNode) : PageBuilder(listOf(node)) { - - override fun build() { - val breakdownByLocation = node.path.filterNot { it.name.isEmpty() }.map { link(node, it) } - - appendBreadcrumbs(breakdownByLocation) - appendLine() - appendLine() - appendHeader { appendText(node.name) } - - appendAsNodeDescription(effectivePlatformsForNode(node)) { - renderGroupNode(node, true) - - appendOriginsGroupByContent(node) - } - - SectionsBuilder(node).build() - } - } -// -// private fun unionPlatformsOfItems(items: List<DocumentationNode>): Set<String> { -// val platforms = items.flatMapTo(mutableSetOf<String>()) { -// when (it.kind) { -// NodeKind.GroupNode -> unionPlatformsOfItems(it.origins) -// else -> it.platforms -// } -// } -// -// return platforms -// } - - - inner class SectionsBuilder(val node: DocumentationNode): PageBuilder(listOf(node)) { - override fun build() { - if (node.kind == NodeKind.ExternalClass) { - appendSection("Extensions for ${node.name}", node.members) - return - } - - fun DocumentationNode.membersOrGroupMembers(predicate: (DocumentationNode) -> Boolean): List<DocumentationNode> { - return members.filter(predicate) + members(NodeKind.GroupNode).filter{ it.origins.isNotEmpty() && predicate(it.origins.first()) } - } - - fun DocumentationNode.membersOrGroupMembers(kind: NodeKind): List<DocumentationNode> { - return membersOrGroupMembers { it.kind == kind } - } - - appendSection("Packages", node.members(NodeKind.Package), platformsBasedOnMembers = true) - appendSection("Types", node.membersOrGroupMembers { it.kind in NodeKind.classLike /*&& it.kind != NodeKind.TypeAlias*/ && it.kind != NodeKind.AnnotationClass && it.kind != NodeKind.Exception }) - appendSection("Annotations", node.membersOrGroupMembers(NodeKind.AnnotationClass)) - appendSection("Exceptions", node.membersOrGroupMembers(NodeKind.Exception)) - appendSection("Extensions for External Classes", node.members(NodeKind.ExternalClass)) - appendSection("Enum Values", node.membersOrGroupMembers(NodeKind.EnumItem), sortMembers = false, omitSamePlatforms = true) - appendSection("Constructors", node.membersOrGroupMembers(NodeKind.Constructor), omitSamePlatforms = true) - appendSection("Properties", node.membersOrGroupMembers(NodeKind.Property), omitSamePlatforms = true) - appendSection("Inherited Properties", node.inheritedMembers(NodeKind.Property)) - appendSection("Functions", node.membersOrGroupMembers(NodeKind.Function), omitSamePlatforms = true) - appendSection("Inherited Functions", node.inheritedMembers(NodeKind.Function)) - appendSection("Companion Object Properties", node.membersOrGroupMembers(NodeKind.CompanionObjectProperty), omitSamePlatforms = true) - appendSection("Inherited Companion Object Properties", node.inheritedCompanionObjectMembers(NodeKind.Property)) - appendSection("Companion Object Functions", node.membersOrGroupMembers(NodeKind.CompanionObjectFunction), omitSamePlatforms = true) - appendSection("Inherited Companion Object Functions", node.inheritedCompanionObjectMembers(NodeKind.Function)) - appendSection("Other members", node.members.filter { - it.kind !in setOf( - NodeKind.Class, - NodeKind.Interface, - NodeKind.Enum, - NodeKind.Object, - NodeKind.AnnotationClass, - NodeKind.Exception, - NodeKind.TypeAlias, - NodeKind.Constructor, - NodeKind.Property, - NodeKind.Package, - NodeKind.Function, - NodeKind.CompanionObjectProperty, - NodeKind.CompanionObjectFunction, - NodeKind.ExternalClass, - NodeKind.EnumItem, - NodeKind.AllTypes, - NodeKind.GroupNode - ) - }) - - val allExtensions = node.extensions - appendSection("Extension Properties", allExtensions.filter { it.kind == NodeKind.Property }) - appendSection("Extension Functions", allExtensions.filter { it.kind == NodeKind.Function }) - appendSection("Companion Object Extension Properties", allExtensions.filter { it.kind == NodeKind.CompanionObjectProperty }) - appendSection("Companion Object Extension Functions", allExtensions.filter { it.kind == NodeKind.CompanionObjectFunction }) - appendSection("Inheritors", - node.inheritors.filter { it.kind != NodeKind.EnumItem }) - - if (node.kind == NodeKind.Module) { - appendHeader(3) { to.append("Index") } - node.members(NodeKind.AllTypes).singleOrNull()?.let { allTypes -> - appendLink(link(node, allTypes) { "All Types" }) - } - } - } - - private fun appendSection(caption: String, members: List<DocumentationNode>, - sortMembers: Boolean = true, - omitSamePlatforms: Boolean = false, - platformsBasedOnMembers: Boolean = false) { - if (members.isEmpty()) return - - appendHeader(3) { appendText(caption) } - - val children = if (sortMembers) members.sortedBy { it.name.toLowerCase() } else members - val membersMap = children.groupBy { link(node, it) } - - - - appendTable("Name", "Summary") { - appendTableBody { - for ((memberLocation, membersList) in membersMap) { - val platforms = effectivePlatformsForMembers(membersList) -// val platforms = if (platformsBasedOnMembers) -// members.flatMapTo(mutableSetOf()) { platformsOfItems(it.members) } + elementPlatforms -// else -// elementPlatforms - - val summarized = computeSummarySignatures(membersList) - - appendIndexRow(platforms) { - appendTableCell { - if (summarized.platformPlacement == Summarized.PlatformPlacement.Row) { - appendPlatforms(platforms) - } - appendHeader(level = 4) { - // appendParagraph { - appendLink(memberLocation) - } - if (node.sinceKotlin != null) { - appendSinceKotlin(node.sinceKotlin.toString()) - } - - if (membersList.singleOrNull()?.sinceKotlin != null){ - appendSinceKotlinWrapped(membersList.single().sinceKotlin.toString()) - } -// } -// if (members.singleOrNull()?.kind != NodeKind.ExternalClass) { -// appendPlatforms(platforms) -// } -// } - } - appendTableCell { - appendSummarySignatures(summarized) - } - } - } - } - } - } - -// -// private fun platformsOfItems(items: List<DocumentationNode>, omitSamePlatforms: Boolean = true): Set<String> { -// if (items.all { it.kind != NodeKind.Package && it.kind != NodeKind.Module && it.kind != NodeKind.ExternalClass }) { -// return unionPlatformsOfItems(items) -// } -// -// val platforms = platformsOfItems(items) -// if (platforms.isNotEmpty() && (platforms != node.platformsToShow.toSet() || !omitSamePlatforms)) { -// return platforms -// } -// return emptySet() -// } - - - - private fun computeSummarySignatures(items: List<DocumentationNode>): Summarized = - Summarized(items.groupBy { it.summary }.mapValues { (_, nodes) -> - val nodesToAppend = nodes.flatMap { if(it.kind == NodeKind.GroupNode) it.origins else listOf(it) } - - val summarySignature = languageService.summarizeSignatures(nodesToAppend) - if (summarySignature != null) { - mapOf(summarySignature to nodesToAppend) - } else { - nodesToAppend.groupBy { - languageService.render(it, RenderMode.SUMMARY) - } - } - }) - - - private fun appendSummarySignatures( - summarized: Summarized - ) { - for(summary in summarized.data) { - - appendAsSummaryGroup(summary.platforms) { - if (summarized.platformPlacement == Summarized.PlatformPlacement.Summary) { - appendPlatforms(summary.platforms) - } - appendContent(summary.content) - summary.signatures.subList(0, summary.signatures.size - 1).forEach { - appendSignatures( - it, - summarized.platformPlacement == Summarized.PlatformPlacement.Signature - ) - appendLine() - } - appendSignatures( - summary.signatures.last(), - summarized.platformPlacement == Summarized.PlatformPlacement.Signature - ) - } - - } - } - - private fun appendSignatures( - signature: Summarized.SummarizedNodes, - withPlatforms: Boolean - ) { - -// val platforms = if (platformsBasedOnMembers) -// items.flatMapTo(mutableSetOf()) { platformsOfItems(it.members) } + elementPlatforms -// else -// elementPlatforms - - - appendAsPlatformDependentBlock(signature.platforms) { - if (withPlatforms) { - appendPlatforms(signature.platforms) - } - appendAsSignature(signature.content) { - signature.content.appendSignature() - } - appendSoftLineBreak() - } - } - } - - private fun DocumentationNode.isClassLikeGroupNode(): Boolean { - if (kind != NodeKind.GroupNode) { - return false - } - - return origins.all { it.kind in NodeKind.classLike } - } - - - inner class AllTypesNodeBuilder(val node: DocumentationNode) - : PageBuilder(listOf(node)) { - - override fun build() { - appendContent(node.owner!!.summary) - appendHeader(3) { to.append("All Types") } - - appendTable("Name", "Summary") { - appendTableBody { - for (type in node.members) { - val platforms = effectivePlatformsForNode(type) - appendIndexRow(platforms) { - appendPlatforms(platforms) - if (type.kind == NodeKind.ExternalClass) { - val packageName = type.owner?.name - if (packageName != null) { - appendText(" (extensions in package $packageName)") - } - } - appendHeader(level = 5) { - appendLink(link(node, type) { - if (it.kind == NodeKind.ExternalClass) it.name else it.qualifiedName() - }) - } - - appendContent(type.summary) - } - } - } - } - } - } - - override fun appendNodes(nodes: Iterable<DocumentationNode>) { - val singleNode = nodes.singleOrNull() - when (singleNode?.kind) { - NodeKind.AllTypes -> AllTypesNodeBuilder(singleNode).build() - NodeKind.GroupNode -> GroupNodePageBuilder(singleNode).build() - null -> PageBuilder(nodes).build() - else -> SingleNodePageBuilder(singleNode).build() - } - } -} - -abstract class StructuredFormatService(val generator: NodeLocationAwareGenerator, - val languageService: LanguageService, - override val extension: String, - override final val linkExtension: String = extension) : FormatService { - -} - -typealias PlatformsData = Map<String, Set<DocumentationNode>> - -fun memberPlatforms(node: DocumentationNode): PlatformsData { - val members = when { - node.kind == NodeKind.GroupNode -> node.origins - node.kind in NodeKind.classLike -> emptyList() - node.kind in NodeKind.memberLike -> emptyList() - else -> node.members - } - - return members.map(::effectivePlatformsForNode).fold(mapOf(), ::mergePlatforms) -} - -fun mergePlatforms(a: PlatformsData, b: PlatformsData): PlatformsData { - val mutable = a.toMutableMap() - b.forEach { (name, declarations) -> - mutable.merge(name, declarations) { a, b -> a.union(b) } - } - return mutable -} - -fun effectivePlatformsForNode(node: DocumentationNode): PlatformsData { - val platforms = node.platforms + memberPlatforms(node).keys - return platforms.keysToMap { setOf(node) } -} - -fun effectivePlatformsForMembers(nodes: Collection<DocumentationNode>): PlatformsData { - return nodes.map { effectivePlatformsForNode(it) }.reduce(::mergePlatforms) -} - -fun mergeVersions(kotlinVersions: List<String>): String { - return kotlinVersions.distinct().min().orEmpty() -} - -fun effectiveSinceKotlinForNode(node: DocumentationNode, baseVersion: String = "1.0"): String { - val members = when { - node.kind == NodeKind.GroupNode -> node.origins - node.kind in NodeKind.classLike -> emptyList() - node.kind in NodeKind.memberLike -> emptyList() - else -> node.members - } - val newBase = node.sinceKotlin ?: baseVersion - val memberVersion = if (members.isNotEmpty()) effectiveSinceKotlinForNodes(members, newBase) else newBase - - return node.sinceKotlin ?: memberVersion -} - -fun effectiveSinceKotlinForNodes(nodes: Collection<DocumentationNode>, baseVersion: String = "1.0"): String { - val map = nodes.map { effectiveSinceKotlinForNode(it, baseVersion) } - return mergeVersions(map) -} - -fun samePlatforms(platformsPerNode: Collection<PlatformsData>): Boolean { - - val first = platformsPerNode.firstOrNull()?.keys ?: return true - return platformsPerNode.all { it.keys == first } -} - -fun locationHref( - from: Location, - to: DocumentationNode, - generator: NodeLocationAwareGenerator, - pathOnly: Boolean = false -): String { - val topLevelPage = to.references(RefKind.TopLevelPage).singleOrNull()?.to - if (topLevelPage != null) { - val signature = to.detailOrNull(NodeKind.Signature) - return from.relativePathTo( - generator.location(topLevelPage), - (signature?.name ?: to.name).takeUnless { pathOnly } - ) - } - return from.relativePathTo(generator.location(to)) -}
\ No newline at end of file diff --git a/core/src/main/kotlin/Formats/YamlOutlineService.kt b/core/src/main/kotlin/Formats/YamlOutlineService.kt deleted file mode 100644 index 3c92d8ff..00000000 --- a/core/src/main/kotlin/Formats/YamlOutlineService.kt +++ /dev/null @@ -1,26 +0,0 @@ -package org.jetbrains.dokka - -import com.google.inject.Inject -import java.io.File - -class YamlOutlineService @Inject constructor( - val generator: NodeLocationAwareGenerator, - val languageService: LanguageService -) : OutlineFormatService { - override fun getOutlineFileName(location: Location): File = File("${location.path}.yml") - - var outlineLevel = 0 - override fun appendOutlineHeader(location: Location, node: DocumentationNode, to: StringBuilder) { - val indent = " ".repeat(outlineLevel) - to.appendln("$indent- title: ${languageService.renderName(node)}") - to.appendln("$indent url: ${generator.relativePathToLocation(node.path.first(), node)}") - } - - override fun appendOutlineLevel(to: StringBuilder, body: () -> Unit) { - val indent = " ".repeat(outlineLevel) - to.appendln("$indent content:") - outlineLevel++ - body() - outlineLevel-- - } -} |
