From d08591dea709917553c0d6de024820bb29b328fb Mon Sep 17 00:00:00 2001 From: Paweł Marks Date: Tue, 3 Mar 2020 23:38:23 +0100 Subject: Platform dependent hints for renderer --- .../src/main/kotlin/renderers/DefaultRenderer.kt | 68 +++++++----- .../src/main/kotlin/renderers/html/HtmlRenderer.kt | 58 +++++++--- .../documentables/PageContentBuilder.kt | 14 +++ .../test/kotlin/renderers/RenderingOnlyTestBase.kt | 88 +++++++++++++++ .../kotlin/renderers/html/GroupWrappingTest.kt | 97 ++--------------- .../renderers/html/PlatformDependentHintTest.kt | 118 +++++++++++++++++++++ 6 files changed, 313 insertions(+), 130 deletions(-) create mode 100644 plugins/base/src/test/kotlin/renderers/RenderingOnlyTestBase.kt create mode 100644 plugins/base/src/test/kotlin/renderers/html/PlatformDependentHintTest.kt (limited to 'plugins/base') diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt index 960a39fd..33be5dfe 100644 --- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt @@ -22,54 +22,68 @@ abstract class DefaultRenderer( 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.buildList(node: ContentList, pageContext: ContentPage, platformRestriction: PlatformData? = null) abstract fun T.buildNewLine() abstract fun T.buildResource(node: ContentEmbeddedResource, pageContext: ContentPage) - abstract fun T.buildTable(node: ContentTable, pageContext: ContentPage) + abstract fun T.buildTable(node: ContentTable, pageContext: ContentPage, platformRestriction: PlatformData? = null) 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) = wrapGroup(node, pageContext) { - node.children.forEach { it.build(this, pageContext) } - } + open fun T.buildPlatformDependent(content: PlatformHintedContent, pageContext: ContentPage) = + buildContentNode(content.inner, pageContext) + + open fun T.buildGroup(node: ContentGroup, pageContext: ContentPage, platformRestriction: PlatformData? = null) = + wrapGroup(node, pageContext) { node.children.forEach { it.build(this, pageContext, platformRestriction) } } open fun T.wrapGroup(node: ContentGroup, pageContext: ContentPage, childrenCallback: T.() -> Unit) = childrenCallback() - open fun T.buildLinkText(nodes: List, pageContext: ContentPage) { - nodes.forEach { it.build(this, pageContext) } + open fun T.buildLinkText( + nodes: List, + pageContext: ContentPage, + platformRestriction: PlatformData? = null + ) { + nodes.forEach { it.build(this, pageContext, platformRestriction) } } open fun T.buildCode(code: List, 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 T.buildHeader(node: ContentHeader, pageContext: ContentPage, platformRestriction: PlatformData? = null) { + buildHeader(node.level) { node.children.forEach { it.build(this, pageContext, platformRestriction) } } } - 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) + open fun ContentNode.build(builder: T, pageContext: ContentPage, platformRestriction: PlatformData? = null) = + builder.buildContentNode(this, pageContext, platformRestriction) + + open fun T.buildContentNode( + node: ContentNode, + pageContext: ContentPage, + platformRestriction: PlatformData? = null + ) { + if (platformRestriction == null || platformRestriction in node.platforms) { + when (node) { + is ContentText -> buildText(node) + is ContentHeader -> buildHeader(node, pageContext, platformRestriction) + is ContentCode -> buildCode(node.children, node.language, pageContext) + is ContentDRILink -> + buildLink(locationProvider.resolve(node.address, node.platforms.toList(), pageContext)) { + buildLinkText(node.children, pageContext, platformRestriction) + } + is ContentResolvedLink -> buildLink(node.address) { + buildLinkText(node.children, pageContext, platformRestriction) + } + is ContentEmbeddedResource -> buildResource(node, pageContext) + is ContentList -> buildList(node, pageContext, platformRestriction) + is ContentTable -> buildTable(node, pageContext, platformRestriction) + is ContentGroup -> buildGroup(node, pageContext, platformRestriction) + is PlatformHintedContent -> buildPlatformDependent(node, pageContext) + else -> buildError(node) } - 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) } } diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index dcd65c21..0dd3b34b 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -33,24 +33,46 @@ open class HtmlRenderer( else -> childrenCallback() } - override fun FlowContent.buildList(node: ContentList, pageContext: ContentPage) = - if (node.ordered) ol { - buildListItems(node.children, pageContext) - } - else ul { - buildListItems(node.children, pageContext) - } + override fun FlowContent.buildPlatformDependent(content: PlatformHintedContent, pageContext: ContentPage) { + val distinct = content.platforms.map { + it to createHTML(prettyPrint = false).div { + buildContentNode(content.inner, pageContext, it) + }.drop(5).dropLast(6) // TODO: Find a way to do it without arbitrary trims + }.groupBy(Pair::second, Pair::first) + + if (distinct.size == 1) + consumer.onTagContentUnsafe { +distinct.keys.single() } + else + distinct.forEach { text, platforms -> + consumer.onTagContentUnsafe { +platforms.joinToString(prefix = "$text [", postfix = "]") { it.name } } + } + } + + override fun FlowContent.buildList( + node: ContentList, + pageContext: ContentPage, + platformRestriction: PlatformData? + ) = if (node.ordered) ol { buildListItems(node.children, pageContext, platformRestriction) } + else ul { buildListItems(node.children, pageContext, platformRestriction) } - open fun OL.buildListItems(items: List, pageContext: ContentPage) { + open fun OL.buildListItems( + items: List, + pageContext: ContentPage, + platformRestriction: PlatformData? = null + ) { items.forEach { if (it is ContentList) buildList(it, pageContext) else - li { it.build(this, pageContext) } + li { it.build(this, pageContext, platformRestriction) } } } - open fun UL.buildListItems(items: List, pageContext: ContentPage) { + open fun UL.buildListItems( + items: List, + pageContext: ContentPage, + platformRestriction: PlatformData? = null + ) { items.forEach { if (it is ContentList) buildList(it, pageContext) @@ -73,14 +95,18 @@ open class HtmlRenderer( } } - override fun FlowContent.buildTable(node: ContentTable, pageContext: ContentPage) { + override fun FlowContent.buildTable( + node: ContentTable, + pageContext: ContentPage, + platformRestriction: PlatformData? + ) { table { thead { node.header.forEach { tr { it.children.forEach { th { - it.build(this@table, pageContext) + it.build(this@table, pageContext, platformRestriction) } } } @@ -91,7 +117,7 @@ open class HtmlRenderer( tr { it.children.forEach { td { - it.build(this, pageContext) + it.build(this, pageContext, platformRestriction) } } } @@ -141,7 +167,11 @@ open class HtmlRenderer( override fun FlowContent.buildLink(address: String, content: FlowContent.() -> Unit) = a(href = address, block = content) - override fun FlowContent.buildCode(code: List, language: String, pageContext: ContentPage) { + override fun FlowContent.buildCode( + code: List, + language: String, + pageContext: ContentPage + ) { buildNewLine() code.forEach { +((it as? ContentText)?.text ?: run { context.logger.error("Cannot cast $it as ContentText!"); "" }) diff --git a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt index eb422920..0c08241f 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt @@ -232,6 +232,20 @@ open class PageContentBuilder( block: DocumentableContentBuilder.() -> Unit ): ContentGroup = contentFor(dri, platformData, kind, styles, extras, block) + fun platformDependentHint( + dri: DRI = mainDRI, + platformData: Set = mainPlatformData, + kind: Kind = ContentKind.Main, + styles: Set