From 5081c9ea811efa30b21512b2700c4aa321879281 Mon Sep 17 00:00:00 2001 From: Giorgio Garofalo Date: Tue, 8 Oct 2024 22:10:05 +0200 Subject: [PATCH] Add `.container`'s border style customization --- .../ast/quarkdown/block/Container.kt | 33 +++++++++++++++++++ .../rendering/html/CssRepresentableVisitor.kt | 7 ++++ .../html/QuarkdownHtmlNodeRenderer.kt | 13 ++++++-- .../RenderRepresentableVisitor.kt | 3 ++ .../iamgio/quarkdown/HtmlNodeRendererTest.kt | 9 +++++ .../rendering/quarkdown/container.html | 13 ++++++++ .../eu/iamgio/quarkdown/stdlib/Layout.kt | 15 +++++---- 7 files changed, 84 insertions(+), 9 deletions(-) diff --git a/core/src/main/kotlin/eu/iamgio/quarkdown/ast/quarkdown/block/Container.kt b/core/src/main/kotlin/eu/iamgio/quarkdown/ast/quarkdown/block/Container.kt index 4428d916..fdabc653 100644 --- a/core/src/main/kotlin/eu/iamgio/quarkdown/ast/quarkdown/block/Container.kt +++ b/core/src/main/kotlin/eu/iamgio/quarkdown/ast/quarkdown/block/Container.kt @@ -4,6 +4,8 @@ import eu.iamgio.quarkdown.ast.NestableNode import eu.iamgio.quarkdown.ast.Node import eu.iamgio.quarkdown.document.size.Sizes import eu.iamgio.quarkdown.misc.color.Color +import eu.iamgio.quarkdown.rendering.representable.RenderRepresentable +import eu.iamgio.quarkdown.rendering.representable.RenderRepresentableVisitor import eu.iamgio.quarkdown.visitor.node.NodeVisitor /** @@ -12,6 +14,7 @@ import eu.iamgio.quarkdown.visitor.node.NodeVisitor * @param backgroundColor background color * @param borderColor border color * @param borderWidth border width + * @param borderStyle border style * @param padding whitespace around the content * @param cornerRadius border radius of the container */ @@ -20,9 +23,39 @@ data class Container( val backgroundColor: Color? = null, val borderColor: Color? = null, val borderWidth: Sizes? = null, + val borderStyle: BorderStyle? = null, val padding: Sizes? = null, val cornerRadius: Sizes? = null, override val children: List, ) : NestableNode { override fun accept(visitor: NodeVisitor): T = visitor.visit(this) + + /** + * Style of the border of a [Container]. + */ + enum class BorderStyle : RenderRepresentable { + /** + * Solid border. + */ + NORMAL, + + /** + * Dashed border. + */ + DASHED, + + /** + * Dotted border. + */ + DOTTED, + + /** + * Double border. + */ + DOUBLE, + + ; + + override fun accept(visitor: RenderRepresentableVisitor): T = visitor.visit(this) + } } diff --git a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/CssRepresentableVisitor.kt b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/CssRepresentableVisitor.kt index 85cb9fc2..438cd503 100644 --- a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/CssRepresentableVisitor.kt +++ b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/CssRepresentableVisitor.kt @@ -4,6 +4,7 @@ import eu.iamgio.quarkdown.ast.base.block.BlockQuote import eu.iamgio.quarkdown.ast.base.block.Table import eu.iamgio.quarkdown.ast.quarkdown.block.Box import eu.iamgio.quarkdown.ast.quarkdown.block.Clipped +import eu.iamgio.quarkdown.ast.quarkdown.block.Container import eu.iamgio.quarkdown.ast.quarkdown.block.SlidesFragment import eu.iamgio.quarkdown.ast.quarkdown.block.Stacked import eu.iamgio.quarkdown.ast.quarkdown.inline.TextTransformData @@ -34,6 +35,12 @@ class CssRepresentableVisitor : RenderRepresentableVisitor { override fun visit(alignment: Table.Alignment) = alignment.kebabCaseName + override fun visit(borderStyle: Container.BorderStyle) = + when (borderStyle) { + Container.BorderStyle.NORMAL -> "solid" + else -> borderStyle.kebabCaseName + } + override fun visit(stackLayout: Stacked.Layout) = when (stackLayout) { is Stacked.Column -> "column" diff --git a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/QuarkdownHtmlNodeRenderer.kt b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/QuarkdownHtmlNodeRenderer.kt index 11947fb3..86de9553 100644 --- a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/QuarkdownHtmlNodeRenderer.kt +++ b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/html/QuarkdownHtmlNodeRenderer.kt @@ -92,9 +92,15 @@ class QuarkdownHtmlNodeRenderer(context: Context) : BaseHtmlNodeRenderer(context "border-width" value node.borderWidth "border-radius" value node.cornerRadius - if (node.borderColor != null || node.borderWidth != null) { - "border-style" value "solid" - } + "border-style" value + when { + // If the border style is set, it is used. + node.borderStyle != null -> node.borderStyle + // If border properties are set, a normal (solid) border is used. + node.borderColor != null || node.borderWidth != null -> Container.BorderStyle.NORMAL + // No border style. + else -> null + } } } @@ -164,6 +170,7 @@ class QuarkdownHtmlNodeRenderer(context: Context) : BaseHtmlNodeRenderer(context node.width == null && node.height == null -> { buildTag("span", " ") } + else -> { buildTag("div") { style { diff --git a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/representable/RenderRepresentableVisitor.kt b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/representable/RenderRepresentableVisitor.kt index d3ded588..fc99c941 100644 --- a/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/representable/RenderRepresentableVisitor.kt +++ b/core/src/main/kotlin/eu/iamgio/quarkdown/rendering/representable/RenderRepresentableVisitor.kt @@ -4,6 +4,7 @@ import eu.iamgio.quarkdown.ast.base.block.BlockQuote import eu.iamgio.quarkdown.ast.base.block.Table import eu.iamgio.quarkdown.ast.quarkdown.block.Box import eu.iamgio.quarkdown.ast.quarkdown.block.Clipped +import eu.iamgio.quarkdown.ast.quarkdown.block.Container import eu.iamgio.quarkdown.ast.quarkdown.block.SlidesFragment import eu.iamgio.quarkdown.ast.quarkdown.block.Stacked import eu.iamgio.quarkdown.ast.quarkdown.inline.TextTransformData @@ -27,6 +28,8 @@ interface RenderRepresentableVisitor { fun visit(alignment: Table.Alignment): T + fun visit(borderStyle: Container.BorderStyle): T + fun visit(stackLayout: Stacked.Layout): T fun visit(alignment: Stacked.MainAxisAlignment): T diff --git a/core/src/test/kotlin/eu/iamgio/quarkdown/HtmlNodeRendererTest.kt b/core/src/test/kotlin/eu/iamgio/quarkdown/HtmlNodeRendererTest.kt index db79bf9e..bf9759e9 100644 --- a/core/src/test/kotlin/eu/iamgio/quarkdown/HtmlNodeRendererTest.kt +++ b/core/src/test/kotlin/eu/iamgio/quarkdown/HtmlNodeRendererTest.kt @@ -717,6 +717,15 @@ class HtmlNodeRendererTest { children = children, ).render(), ) + + assertEquals( + out.next(), + Container( + borderColor = Color(30, 20, 10), + borderStyle = Container.BorderStyle.DOTTED, + children = children, + ).render(), + ) } @Test diff --git a/core/src/test/resources/rendering/quarkdown/container.html b/core/src/test/resources/rendering/quarkdown/container.html index 5da5858e..2f247f3b 100644 --- a/core/src/test/resources/rendering/quarkdown/container.html +++ b/core/src/test/resources/rendering/quarkdown/container.html @@ -46,4 +46,17 @@ Baz

+ + +--- + +
+

+ Foo bar +

+
+

+ Baz +

+
\ No newline at end of file diff --git a/stdlib/src/main/kotlin/eu/iamgio/quarkdown/stdlib/Layout.kt b/stdlib/src/main/kotlin/eu/iamgio/quarkdown/stdlib/Layout.kt index c453d9c7..e8814354 100644 --- a/stdlib/src/main/kotlin/eu/iamgio/quarkdown/stdlib/Layout.kt +++ b/stdlib/src/main/kotlin/eu/iamgio/quarkdown/stdlib/Layout.kt @@ -43,12 +43,13 @@ val Layout: Module = /** * A general-purpose container that groups content. * Any layout rules (e.g. from [align], [row], [column], [grid]) are ignored inside this container. - * @param foregroundColor text color - * @param backgroundColor background color - * @param borderColor border color - * @param borderWidth border width - * @param padding whitespace around the content - * @param cornerRadius corner (and border) radius + * @param foregroundColor text color. Default if unset + * @param backgroundColor background color. Transparent if unset + * @param borderColor border color. Default if unset and [borderWidth] is set + * @param borderWidth border width. Default if unset and [borderColor] is set + * @param borderStyle border style. Normal (solid) if unset and [borderColor] or [borderWidth] is set + * @param padding whitespace around the content. None if unset + * @param cornerRadius corner (and border) radius. None if unset * @param body content to group * @return the new container node */ @@ -57,6 +58,7 @@ fun container( @Name("background") backgroundColor: Color? = null, @Name("border") borderColor: Color? = null, @Name("borderwidth") borderWidth: Sizes? = null, + @Name("borderstyle") borderStyle: Container.BorderStyle? = null, @Name("padding") padding: Sizes? = null, @Name("radius") cornerRadius: Sizes? = null, body: MarkdownContent, @@ -65,6 +67,7 @@ fun container( backgroundColor, borderColor, borderWidth, + borderStyle, padding, cornerRadius, body.children,