aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/renderers
diff options
context:
space:
mode:
authorPaweł Marks <pmarks@virtuslab.com>2020-02-17 09:32:35 +0100
committerPaweł Marks <Kordyjan@users.noreply.github.com>2020-02-18 13:28:23 +0100
commitf625cef495d625d81ee22e950083f57cc4fab875 (patch)
treed4587be659154a3000ee58fe2297e55604e418e8 /core/src/main/kotlin/renderers
parent3b200cf10e0c50c2eee4b9da3f7039d678fa4aad (diff)
downloaddokka-f625cef495d625d81ee22e950083f57cc4fab875.tar.gz
dokka-f625cef495d625d81ee22e950083f57cc4fab875.tar.bz2
dokka-f625cef495d625d81ee22e950083f57cc4fab875.zip
Moves PsiToDocumentablesTranslator to the base plugin
Diffstat (limited to 'core/src/main/kotlin/renderers')
-rw-r--r--core/src/main/kotlin/renderers/DefaultRenderer.kt124
-rw-r--r--core/src/main/kotlin/renderers/html/HtmlRenderer.kt217
-rw-r--r--core/src/main/kotlin/renderers/html/NavigationPage.kt50
-rw-r--r--core/src/main/kotlin/renderers/html/htmlPreprocessors.kt68
4 files changed, 0 insertions, 459 deletions
diff --git a/core/src/main/kotlin/renderers/DefaultRenderer.kt b/core/src/main/kotlin/renderers/DefaultRenderer.kt
deleted file mode 100644
index d09d9ded..00000000
--- a/core/src/main/kotlin/renderers/DefaultRenderer.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-package org.jetbrains.dokka.renderers
-
-import org.jetbrains.dokka.CoreExtensions
-import org.jetbrains.dokka.pages.*
-import org.jetbrains.dokka.plugability.DokkaContext
-import org.jetbrains.dokka.resolvers.LocationProvider
-import org.jetbrains.dokka.transformers.pages.PageNodeTransformer
-
-abstract class DefaultRenderer<T>(
- protected val outputWriter: OutputWriter,
- protected val context: DokkaContext
-) : Renderer {
-
- protected lateinit var locationProvider: LocationProvider
- private set
-
- protected open val preprocessors: Iterable<PageNodeTransformer> = emptyList()
-
- abstract fun T.buildHeader(level: Int, content: T.() -> Unit)
- abstract fun T.buildLink(address: String, content: T.() -> Unit)
- abstract fun T.buildList(node: ContentList, pageContext: ContentPage)
- abstract fun T.buildNewLine()
- abstract fun T.buildResource(node: ContentEmbeddedResource, pageContext: ContentPage)
- abstract fun T.buildTable(node: ContentTable, pageContext: ContentPage)
- abstract fun T.buildText(textNode: ContentText)
- abstract fun T.buildNavigation(page: PageNode)
-
- abstract fun buildPage(page: ContentPage, content: (T, ContentPage) -> Unit): String
- abstract fun buildError(node: ContentNode)
-
- open fun T.buildGroup(node: ContentGroup, pageContext: ContentPage) {
- node.children.forEach { it.build(this, pageContext) }
- }
-
- open fun T.buildLinkText(nodes: List<ContentNode>, pageContext: ContentPage) {
- nodes.forEach { it.build(this, pageContext) }
- }
-
- open fun T.buildCode(code: List<ContentNode>, language: String, pageContext: ContentPage) {
- code.forEach { it.build(this, pageContext) }
- }
-
- open fun T.buildHeader(node: ContentHeader, pageContext: ContentPage) {
- buildHeader(node.level) { node.children.forEach { it.build(this, pageContext) } }
- }
-
- open fun ContentNode.build(builder: T, pageContext: ContentPage) =
- builder.buildContentNode(this, pageContext)
-
- open fun T.buildContentNode(node: ContentNode, pageContext: ContentPage) {
- when (node) {
- is ContentText -> buildText(node)
- is ContentHeader -> buildHeader(node, pageContext)
- is ContentCode -> buildCode(node.children, node.language, pageContext)
- is ContentDRILink -> buildLink(
- locationProvider.resolve(node.address, node.platforms.toList(), pageContext)
- ) {
- buildLinkText(node.children, pageContext)
- }
- is ContentResolvedLink -> buildLink(node.address) { buildLinkText(node.children, pageContext) }
- is ContentEmbeddedResource -> buildResource(node, pageContext)
- is ContentList -> buildList(node, pageContext)
- is ContentTable -> buildTable(node, pageContext)
- is ContentGroup -> buildGroup(node, pageContext)
- else -> buildError(node)
- }
- }
-
- open fun buildPageContent(context: T, page: ContentPage) {
- context.buildNavigation(page)
- page.content.build(context, page)
- }
-
- open fun renderPage(page: PageNode) {
- val path by lazy { locationProvider.resolve(page, skipExtension = true) }
- when (page) {
- is ContentPage -> outputWriter.write(path, buildPage(page) { c, p -> buildPageContent(c, p) }, ".html")
- is RendererSpecificPage -> when (val strategy = page.strategy) {
- is RenderingStrategy.Copy -> outputWriter.writeResources(strategy.from, path)
- is RenderingStrategy.Write -> outputWriter.write(path, strategy.text, "")
- is RenderingStrategy.Callback -> outputWriter.write(path, strategy.instructions(this, page), ".html")
- RenderingStrategy.DoNothing -> Unit
- }
- else -> throw AssertionError(
- "Page ${page.name} cannot be rendered by renderer as it is not renderer specific nor contains content"
- )
- }
- }
-
- open fun renderPages(root: PageNode) {
- renderPage(root)
- root.children.forEach { renderPages(it) }
- }
-
- // reimplement this as preprocessor
- open fun renderPackageList(root: ContentPage) =
- getPackageNamesAndPlatforms(root)
- .keys
- .joinToString("\n")
- .also { outputWriter.write("${root.name}/package-list", it, "") }
-
- open fun getPackageNamesAndPlatforms(root: PageNode): Map<String, List<PlatformData>> =
- root.children
- .map(::getPackageNamesAndPlatforms)
- .fold(emptyMap<String, List<PlatformData>>()) { e, acc -> acc + e } +
- if (root is PackagePageNode) {
- mapOf(root.name to root.platforms())
- } else {
- emptyMap()
- }
-
- override fun render(root: RootPageNode) {
- val newRoot = preprocessors.fold(root) { acc, t -> t(acc) }
-
- locationProvider =
- context.single(CoreExtensions.locationProviderFactory).getLocationProvider(newRoot)
-
- root.children<ModulePageNode>().forEach { renderPackageList(it) }
-
- renderPages(newRoot)
- }
-}
-
-fun ContentPage.platforms() = this.content.platforms.toList() \ No newline at end of file
diff --git a/core/src/main/kotlin/renderers/html/HtmlRenderer.kt b/core/src/main/kotlin/renderers/html/HtmlRenderer.kt
deleted file mode 100644
index 376ce5c8..00000000
--- a/core/src/main/kotlin/renderers/html/HtmlRenderer.kt
+++ /dev/null
@@ -1,217 +0,0 @@
-package org.jetbrains.dokka.renderers.html
-
-import kotlinx.html.*
-import kotlinx.html.stream.createHTML
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.model.Function
-import org.jetbrains.dokka.pages.*
-import org.jetbrains.dokka.plugability.DokkaContext
-import org.jetbrains.dokka.renderers.DefaultRenderer
-import org.jetbrains.dokka.renderers.OutputWriter
-import java.io.File
-
-open class HtmlRenderer(
- outputWriter: OutputWriter,
- context: DokkaContext
-) : DefaultRenderer<FlowContent>(outputWriter, context) {
-
- private val pageList = mutableListOf<String>()
-
- override val preprocessors = listOf(
- RootCreator,
- SearchPageInstaller,
- ResourceInstaller,
- NavigationPageInstaller,
- StyleAndScriptsAppender
- )
-
- override fun FlowContent.buildList(node: ContentList, pageContext: ContentPage) =
- if (node.ordered) ol {
- buildListItems(node.children, pageContext)
- }
- else ul {
- buildListItems(node.children, pageContext)
- }
-
- open fun OL.buildListItems(items: List<ContentNode>, pageContext: ContentPage) {
- items.forEach {
- if (it is ContentList)
- buildList(it, pageContext)
- else
- li { it.build(this, pageContext) }
- }
- }
-
- open fun UL.buildListItems(items: List<ContentNode>, pageContext: ContentPage) {
- items.forEach {
- if (it is ContentList)
- buildList(it, pageContext)
- else
- li { it.build(this, pageContext) }
- }
- }
-
- override fun FlowContent.buildResource(
- node: ContentEmbeddedResource,
- pageContext: ContentPage
- ) { // TODO: extension point there
- val imageExtensions = setOf("png", "jpg", "jpeg", "gif", "bmp", "tif", "webp", "svg")
- return if (File(node.address).extension.toLowerCase() in imageExtensions) {
- //TODO: add imgAttrs parsing
- val imgAttrs = node.extras.filterIsInstance<HTMLSimpleAttr>().joinAttr()
- img(src = node.address, alt = node.altText)
- } else {
- println("Unrecognized resource type: $node")
- }
- }
-
- override fun FlowContent.buildTable(node: ContentTable, pageContext: ContentPage) {
- table {
- thead {
- node.header.forEach {
- tr {
- it.children.forEach {
- th {
- it.build(this@table, pageContext)
- }
- }
- }
- }
- }
- tbody {
- node.children.forEach {
- tr {
- it.children.forEach {
- td {
- it.build(this, pageContext)
- }
- }
- }
- }
- }
- }
- }
-
- override fun FlowContent.buildHeader(level: Int, content: FlowContent.() -> Unit) {
- when (level) {
- 1 -> h1(block = content)
- 2 -> h2(block = content)
- 3 -> h3(block = content)
- 4 -> h4(block = content)
- 5 -> h5(block = content)
- else -> h6(block = content)
- }
- }
-
- override fun FlowContent.buildNavigation(page: PageNode) =
- locationProvider.ancestors(page).asReversed().forEach { node ->
- text("/")
- if (node.isNavigable) buildLink(node, page)
- else text(node.name)
- }
-
- private fun FlowContent.buildLink(to: PageNode, from: PageNode) =
- buildLink(locationProvider.resolve(to, from)) {
- text(to.name)
- }
-
- fun FlowContent.buildLink(
- to: DRI,
- platforms: List<PlatformData>,
- from: PageNode? = null,
- block: FlowContent.() -> Unit
- ) = buildLink(locationProvider.resolve(to, platforms, from), block)
-
- override fun buildError(node: ContentNode) {
- context.logger.error("Unknown ContentNode type: $node")
- }
-
- override fun FlowContent.buildNewLine() {
- br()
- }
-
- override fun FlowContent.buildLink(address: String, content: FlowContent.() -> Unit) =
- a(href = address, block = content)
-
- override fun FlowContent.buildCode(code: List<ContentNode>, language: String, pageContext: ContentPage) {
- buildNewLine()
- code.forEach {
- +((it as? ContentText)?.text ?: run { context.logger.error("Cannot cast $it as ContentText!"); "" })
- buildNewLine()
- }
- }
-
- override fun renderPage(page: PageNode) {
- super.renderPage(page)
- if (page is ContentPage) {
- pageList.add(
- """{ "name": "${page.name}", ${if (page is ClasslikePageNode) "\"class\": \"${page.name}\"," else ""} "location": "${locationProvider.resolve(
- page
- )}" }"""
- )
- }
- }
-
- override fun FlowContent.buildText(textNode: ContentText) {
- text(textNode.text)
- }
-
- override fun render(root: RootPageNode) {
- super.render(root)
- outputWriter.write("scripts/pages", "var pages = [\n${pageList.joinToString(",\n")}\n]", ".js")
- }
-
- private fun PageNode.root(path: String) = locationProvider.resolveRoot(this) + path
-
- override fun buildPage(page: ContentPage, content: (FlowContent, ContentPage) -> Unit): String =
- buildHtml(page, page.embeddedResources) { content(this, page) }
-
- open fun buildHtml(page: PageNode, resources: List<String>, content: FlowContent.() -> Unit) =
- createHTML().html {
- head {
- title(page.name)
- with(resources) {
- filter { it.substringBefore('?').substringAfterLast('.') == "css" }
- .forEach { link(rel = LinkRel.stylesheet, href = page.root(it)) }
- filter { it.substringBefore('?').substringAfterLast('.') == "js" }
- .forEach { script(type = ScriptType.textJavaScript, src = page.root(it)) { async = true } }
- }
- script { unsafe { +"""var pathToRoot = "${locationProvider.resolveRoot(page)}";""" } }
- }
- body {
- div {
- id = "navigation"
- div {
- id = "searchBar"
- form(action = page.root("-search.html"), method = FormMethod.get) {
- id = "searchForm"
- input(type = InputType.search, name = "query")
- input(type = InputType.submit) { value = "Search" }
- }
- }
- div {
- id = "sideMenu"
- }
- }
- div {
- id = "content"
- content()
- }
- }
- }
-}
-
-fun List<HTMLMetadata>.joinAttr() = joinToString(" ") { it.key + "=" + it.value }
-
-private fun PageNode.pageKind() = when (this) {
- is PackagePageNode -> "package"
- is ClasslikePageNode -> "class"
- is MemberPageNode -> when (this.documentable) {
- is Function -> "function"
- else -> "other"
- }
- else -> "other"
-}
-
-private val PageNode.isNavigable: Boolean
- get() = this !is RendererSpecificPage || strategy != RenderingStrategy.DoNothing \ No newline at end of file
diff --git a/core/src/main/kotlin/renderers/html/NavigationPage.kt b/core/src/main/kotlin/renderers/html/NavigationPage.kt
deleted file mode 100644
index 4a2fb40d..00000000
--- a/core/src/main/kotlin/renderers/html/NavigationPage.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.jetbrains.dokka.renderers.html
-
-import kotlinx.html.*
-import kotlinx.html.stream.createHTML
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.pages.PageNode
-import org.jetbrains.dokka.pages.PlatformData
-import org.jetbrains.dokka.pages.RendererSpecificPage
-import org.jetbrains.dokka.pages.RenderingStrategy
-
-class NavigationPage(val root: NavigationNode) : RendererSpecificPage {
- override val name = "navigation"
-
- override val children = emptyList<PageNode>()
-
- override fun modified(name: String, children: List<PageNode>) = this
-
- override val strategy = RenderingStrategy<HtmlRenderer> {
- createHTML().visit(root, "nav-submenu", this)
- }
-
- private fun <R> TagConsumer<R>.visit(node: NavigationNode, navId: String, renderer: HtmlRenderer): R =
- with(renderer) {
- div("sideMenuPart") {
- id = navId
- div("overview") {
- buildLink(node.dri, node.platforms) { +node.name }
- if (node.children.isNotEmpty()) {
- span("navButton") {
- onClick = """document.getElementById("$navId").classList.toggle("hidden");"""
- span("navButtonContent")
- }
- }
- }
- node.children.withIndex().forEach { (n, p) -> visit(p, "$navId-$n", renderer) }
- }
- }
-}
-
-class NavigationNode(
- val name: String,
- val dri: DRI,
- val platforms: List<PlatformData>,
- val children: List<NavigationNode>
-)
-
-fun NavigationPage.transform(block: (NavigationNode) -> NavigationNode) = NavigationPage(root.transform(block))
-
-fun NavigationNode.transform(block: (NavigationNode) -> NavigationNode) =
- run(block).let { NavigationNode(it.name, it.dri, it.platforms, it.children.map(block)) }
diff --git a/core/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/core/src/main/kotlin/renderers/html/htmlPreprocessors.kt
deleted file mode 100644
index 4ee67448..00000000
--- a/core/src/main/kotlin/renderers/html/htmlPreprocessors.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.jetbrains.dokka.renderers.html
-
-import kotlinx.html.h1
-import kotlinx.html.id
-import kotlinx.html.table
-import kotlinx.html.tbody
-import org.jetbrains.dokka.pages.*
-import org.jetbrains.dokka.renderers.platforms
-import org.jetbrains.dokka.transformers.pages.PageNodeTransformer
-
-object RootCreator : PageNodeTransformer {
- override fun invoke(input: RootPageNode) =
- RendererSpecificRootPage("", listOf(input), RenderingStrategy.DoNothing)
-}
-
-object SearchPageInstaller : PageNodeTransformer {
- override fun invoke(input: RootPageNode) = input.modified(children = input.children + searchPage)
-
- private val searchPage = RendererSpecificResourcePage(
- name = "Search",
- children = emptyList(),
- strategy = RenderingStrategy<HtmlRenderer> {
- buildHtml(it, listOf("styles/style.css", "scripts/pages.js")) {
- h1 {
- id = "searchTitle"
- text("Search results for ")
- }
- table {
- tbody {
- id = "searchTable"
- }
- }
- }
- })
-}
-
-object NavigationPageInstaller : PageNodeTransformer {
- override fun invoke(input: RootPageNode) = input.modified(
- children = input.children + NavigationPage(
- input.children.filterIsInstance<ContentPage>().single().let(::visit)
- )
- )
-
- private fun visit(page: ContentPage): NavigationNode = NavigationNode(
- page.name,
- page.dri.first(),
- page.platforms(),
- page.children.filterIsInstance<ContentPage>().map { visit(it) })
-}
-
-object ResourceInstaller : PageNodeTransformer {
- override fun invoke(input: RootPageNode) = input.modified(children = input.children + resourcePages)
-
- private val resourcePages = listOf("styles", "scripts", "images").map {
- RendererSpecificResourcePage(it, emptyList(), RenderingStrategy.Copy("/dokka/$it"))
- }
-}
-
-object StyleAndScriptsAppender : PageNodeTransformer {
- override fun invoke(input: RootPageNode) = input.transformContentPagesTree {
- it.modified(
- embeddedResources = it.embeddedResources + listOf(
- "styles/style.css",
- "scripts/navigationLoader.js"
- )
- )
- }
-}