From c15e5c9e797032e041e14eff090f1e75baa1b40b Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Sat, 23 Mar 2024 19:49:22 +0300 Subject: [PATCH 1/3] Wip on additing support for kroki diagrams #162 Implemented: 1. kroki gem is loaded and can generate inlined diagrams 2. required configuration options defined for text2confl.yml file Todo: 1. blockmacro does not work so far (can't load file) 2. documentation updates --- convert/pom.xml | 6 ++ .../asciidoc/RenderingOfDiagramsTest.kt | 65 +++++++++++++++- .../text2confl/core/config/DirectoryConfig.kt | 24 +++++- .../core/config/DirectoryConfigTest.kt | 66 +++++++++++++++- core/src/test/resources/data/.text2confl.yml | 4 + docs/configuration-reference.md | 19 +++-- gem-kroki/pom.xml | 77 +++++++++++++++++++ pom.xml | 1 + renovate.json5 | 9 ++- 9 files changed, 258 insertions(+), 13 deletions(-) create mode 100644 gem-kroki/pom.xml diff --git a/convert/pom.xml b/convert/pom.xml index 111fedaa..79a2f932 100644 --- a/convert/pom.xml +++ b/convert/pom.xml @@ -99,6 +99,12 @@ ${asciidoctorj-diagram.version} runtime + + com.github.zeldigas.confluence + gem-kroki + 1.0.0 + runtime + diff --git a/convert/src/test/kotlin/com/github/zeldigas/text2confl/convert/asciidoc/RenderingOfDiagramsTest.kt b/convert/src/test/kotlin/com/github/zeldigas/text2confl/convert/asciidoc/RenderingOfDiagramsTest.kt index 2ee8981a..8cb237ad 100644 --- a/convert/src/test/kotlin/com/github/zeldigas/text2confl/convert/asciidoc/RenderingOfDiagramsTest.kt +++ b/convert/src/test/kotlin/com/github/zeldigas/text2confl/convert/asciidoc/RenderingOfDiagramsTest.kt @@ -1,7 +1,11 @@ package com.github.zeldigas.text2confl.convert.asciidoc +import assertk.all import assertk.assertThat +import assertk.assertions.endsWith +import assertk.assertions.hasSize import assertk.assertions.isEqualTo +import assertk.assertions.startsWith import com.github.zeldigas.text2confl.convert.Attachment import com.github.zeldigas.text2confl.convert.AttachmentCollector import com.github.zeldigas.text2confl.convert.AttachmentsRegistry @@ -16,7 +20,7 @@ import kotlin.io.path.div internal class RenderingOfDiagramsTest : RenderingTestBase() { @Test - fun `Code block is replaced with image for registered diagram generator`(@TempDir tempDir: Path) { + fun `Code block is replaced with image for registered asciidoc diagram generator`(@TempDir tempDir: Path) { val parser = AsciidocParser( AsciidoctorConfiguration( workdir = tempDir.resolve("out").also { it.createDirectories() }, @@ -66,4 +70,63 @@ internal class RenderingOfDiagramsTest : RenderingTestBase() { """.trimIndent() ) } + + @Test + fun `Code block is replaced with image for registered kroki diagram generator`(@TempDir tempDir: Path) { + val parser = AsciidocParser( + AsciidoctorConfiguration( + workdir = tempDir.resolve("out").also { it.createDirectories() }, + libsToLoad = listOf("asciidoctor-kroki"), + loadBundledMacros = false, + attributes = mapOf( + "kroki-fetch-diagram" to "true", + "outdir" to (tempDir / "out").toString(), + "imagesoutdir" to (tempDir / "out").toString() + ) + ) + ) + val registry = AttachmentsRegistry() + val result = toHtml( + """ + [plantuml,auth-protocol,png] + .... + Alice -> Bob: Authentication Request + Bob --> Alice: Authentication Response + + Alice -> Bob: Another authentication Request + Alice <-- Bob: another authentication Response + .... + """.trimIndent(), + attachmentsCollector = AsciidocAttachmentCollector( + tempDir / "test.adoc", AttachmentCollector( + ReferenceProvider.fromDocuments( + tempDir, mapOf( + tempDir / "test.adoc" to PageHeader("Test", emptyMap()) + ) + ), + registry + ), + tempDir / "out" + ), + parser = parser + ) + + println(result) + + assertThat(registry.collectedAttachments).hasSize(1) + + val (key, attachment) = registry.collectedAttachments.entries.first() + assertThat(key).all { + startsWith("auth-protocol") + endsWith(".png") + } + assertThat(attachment).isEqualTo( + Attachment.fromLink(key, tempDir / "out" / key) + ) + assertThat(result).isEqualToConfluenceFormat( + """ +

+ """.trimIndent() + ) + } } \ No newline at end of file diff --git a/core/src/main/kotlin/com/github/zeldigas/text2confl/core/config/DirectoryConfig.kt b/core/src/main/kotlin/com/github/zeldigas/text2confl/core/config/DirectoryConfig.kt index 225f0db6..2fb0e7be 100644 --- a/core/src/main/kotlin/com/github/zeldigas/text2confl/core/config/DirectoryConfig.kt +++ b/core/src/main/kotlin/com/github/zeldigas/text2confl/core/config/DirectoryConfig.kt @@ -4,6 +4,7 @@ import com.github.zeldigas.text2confl.convert.EditorVersion import com.github.zeldigas.text2confl.convert.asciidoc.AsciidoctorConfiguration import com.github.zeldigas.text2confl.convert.markdown.* import com.github.zeldigas.text2confl.core.upload.ChangeDetector +import java.net.URI import java.nio.file.Path import kotlin.io.path.Path import kotlin.io.path.createTempDirectory @@ -95,23 +96,42 @@ data class AsciidocParams( val attributes: Map = emptyMap(), val tempDir: Boolean = false, val baseDir: String = ".asciidoc", + val kroki: KrokiDiagramsParameters = KrokiDiagramsParameters() ) { fun toConfig(docsDir: Path): AsciidoctorConfiguration { val baseDir = if (tempDir) createTempDirectory() else docsDir / baseDir + return AsciidoctorConfiguration( libsToLoad = gems + diagrams.let { when (it) { AsciidocDiagrams.None -> emptyList() AsciidocDiagrams.Diagrams -> listOf("asciidoctor-diagram") + AsciidocDiagrams.Kroki -> listOf("asciidoctor-kroki") } }, loadBundledMacros = bundledMacros, - attributes = attributes, + attributes = diagramAttributes(diagrams) + attributes, workdir = baseDir ) } + + private fun diagramAttributes(diagrams: AsciidocDiagrams): Map { + if (diagrams != AsciidocDiagrams.Kroki) return emptyMap() + + return buildMap { + kroki.server?.let { put("kroki-server-url", it.toString()) } + kroki.defaultFormat?.let { put("kroki-default-format", it) } + put("kroki-fetch-diagram", "${kroki.fetch}") + } + } } enum class AsciidocDiagrams { - None, Diagrams + None, Diagrams, Kroki } + +data class KrokiDiagramsParameters( + val server: URI? = null, + val fetch: Boolean = true, + val defaultFormat: String? = null +) \ No newline at end of file diff --git a/core/src/test/kotlin/com/github/zeldigas/text2confl/core/config/DirectoryConfigTest.kt b/core/src/test/kotlin/com/github/zeldigas/text2confl/core/config/DirectoryConfigTest.kt index 20951fb9..6649835c 100644 --- a/core/src/test/kotlin/com/github/zeldigas/text2confl/core/config/DirectoryConfigTest.kt +++ b/core/src/test/kotlin/com/github/zeldigas/text2confl/core/config/DirectoryConfigTest.kt @@ -3,12 +3,14 @@ package com.github.zeldigas.text2confl.core.config import assertk.assertThat import assertk.assertions.isEqualTo import com.github.zeldigas.text2confl.convert.EditorVersion +import com.github.zeldigas.text2confl.convert.asciidoc.AsciidoctorConfiguration import com.github.zeldigas.text2confl.convert.markdown.* import com.github.zeldigas.text2confl.core.upload.ChangeDetector import org.junit.jupiter.api.Test import org.junit.jupiter.api.io.TempDir import java.net.URI import java.nio.file.Path +import kotlin.io.path.Path import kotlin.io.path.writeText class DirectoryConfigTest { @@ -77,9 +79,71 @@ class DirectoryConfigTest { bundledMacros = false, attributes = mapOf("toclevels" to 5), tempDir = true, - baseDir = "b" + baseDir = "b", + kroki = KrokiDiagramsParameters( + server = URI.create("https://example.org"), + fetch = false, + defaultFormat = "png" + ) ) ) ) } + + @Test + fun `Conversion of directory inputs to asciidoctor parameters for asciidoctor diagrams`() { + val dirAsciidoc = AsciidocParams( + gems = listOf("extra"), + diagrams = AsciidocDiagrams.Diagrams, + bundledMacros = true, + attributes = mapOf("toclevels" to 5), + tempDir = false, + baseDir = "test", + kroki = KrokiDiagramsParameters( + server = URI.create("https://example.org"), + fetch = true, + defaultFormat = "png" + ) + ) + + val baseDir = Path(".") + assertThat(dirAsciidoc.toConfig(baseDir)).isEqualTo(AsciidoctorConfiguration( + libsToLoad = listOf("extra", "asciidoctor-diagram"), + loadBundledMacros = true, + attributes = mapOf( + "toclevels" to 5 + ), + workdir = baseDir.resolve(Path("test")) + )) + } + + @Test + fun `Conversion of directory inputs to asciidoctor parameters for kroki diagrams`() { + val dirAsciidoc = AsciidocParams( + gems = listOf("extra"), + diagrams = AsciidocDiagrams.Kroki, + bundledMacros = true, + attributes = mapOf("toclevels" to 5), + tempDir = false, + baseDir = "test", + kroki = KrokiDiagramsParameters( + server = URI.create("https://example.org"), + fetch = true, + defaultFormat = "png" + ) + ) + + val baseDir = Path(".") + assertThat(dirAsciidoc.toConfig(baseDir)).isEqualTo(AsciidoctorConfiguration( + libsToLoad = listOf("extra", "asciidoctor-kroki"), + loadBundledMacros = true, + attributes = mapOf( + "kroki-server-url" to "https://example.org", + "kroki-default-format" to "png", + "kroki-fetch-diagram" to "true", + "toclevels" to 5 + ), + workdir = baseDir.resolve(Path("test")) + )) + } } \ No newline at end of file diff --git a/core/src/test/resources/data/.text2confl.yml b/core/src/test/resources/data/.text2confl.yml index 4229c9f0..e988fbe1 100644 --- a/core/src/test/resources/data/.text2confl.yml +++ b/core/src/test/resources/data/.text2confl.yml @@ -55,3 +55,7 @@ asciidoc: toclevels: 5 temp-dir: true base-dir: b + kroki: + server: https://example.org + fetch: false + default-format: png diff --git a/docs/configuration-reference.md b/docs/configuration-reference.md index fd3a3925..34f18ee6 100644 --- a/docs/configuration-reference.md +++ b/docs/configuration-reference.md @@ -84,14 +84,17 @@ asciidoc: plantuml-format: png ``` -| Parameter | Default value | Description | -|----------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------| -| diagrams | `Diagrams` | How to generate diagrams. The only option now is `Diagrams` that activates `asciidoctor-diagrams` | -| bundled-macros | `true` | Enables [asciidoctor macros for Confluence](./storage-formats/asciidoc/confluence-specific.adoc) | -| attributes | emtpy map | Section where you can specify key-value pairs. All provided pairs will be passed to Asciidoc as attributes. | -| gems | empty list | Additional ruby gems to _require_. Mentioned gems must be on classpath, packaged as jar files (like `asciidoctor-diagram`) | -| temp-dir | false | If temporary directory should be used to store all generated content | -| base-dir | `.asciidoc` | Working directory where all generated content is stored if `temp-dir` option is not enabled. Directory is resolved relative to document root | +| Parameter | Default value | Description | +|----------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------| +| diagrams | `Diagrams` | How to generate diagrams. You can use `Diagrams` that activates `asciidoctor-diagrams` or `Kroki` to rely on `asciidoctor-kroki` | +| kroki.server | not specified | Sets url of kroki server to use via `kroki-server-url` | +| kroki.fetch | `true` | If Kroki-generated diagrams should be attached as files to page. This sets `kroki-fetch-diagram` attribute | +| kroki.default-format | not specified | Sets `kroki-default-format` variable. | +| bundled-macros | `true` | Enables [asciidoctor macros for Confluence](./storage-formats/asciidoc/confluence-specific.adoc) | +| attributes | emtpy map | Section where you can specify key-value pairs. All provided pairs will be passed to Asciidoc as attributes. | +| gems | empty list | Additional ruby gems to _require_. Mentioned gems must be on classpath, packaged as jar files (like `asciidoctor-diagram`) | +| temp-dir | false | If temporary directory should be used to store all generated content | +| base-dir | `.asciidoc` | Working directory where all generated content is stored if `temp-dir` option is not enabled. Directory is resolved relative to document root | ### Modifications check strategies diff --git a/gem-kroki/pom.xml b/gem-kroki/pom.xml new file mode 100644 index 00000000..d5464903 --- /dev/null +++ b/gem-kroki/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + + + parent + com.github.zeldigas.confluence + 1.0.0-SNAPSHOT + + + gem-kroki + 1.0.0 + + Module that provides asciidoctor-kroki gem as jar dependency, just like we have for + asciidoctor-diagram + + + + 0.10.0 + 11 + 11 + UTF-8 + + + + + rubygems + asciidoctor-kroki + ${kroki.version} + gem + runtime + + + rubygems + asciidoctor + + + + + + + + + org.jruby.maven + gem-maven-plugin + 3.0.2 + + true + + + + + initialize + + + + + + + + org.jruby.maven + mavengem-wagon + 2.0.0 + + + + + + + mavengems + mavengem:https://rubygems.org + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index e60ff660..81b03291 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,7 @@ confluence-client core cli + gem-kroki diff --git a/renovate.json5 b/renovate.json5 index 31b2b39e..937834ea 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -10,12 +10,19 @@ "enabled": false } ], - "regexManagers": [ + "customManagers": [ { + "customType": "regex", "fileMatch": ["(^|/)Dockerfile$"], "matchStrings": ["ARG PLANTUML=\"(?.*?)\""], "depNameTemplate": "homebrew/plantuml", "datasourceTemplate": "repology" + }, + { + "customType": "regex", + "fileMatch": ["(^|/)gem-kroki/pom.xml"], + "matchStrings": [">(?.*?)"], + "datasourceTemplate": "rubygems" } ] } From 77ab760fab840f979102e505a095aada4c91bcae Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Sun, 24 Mar 2024 17:34:37 +0300 Subject: [PATCH 2/3] Documented usage of Kroki diagrams extension Fixes #162 --- docs/storage-formats/asciidoc/diagrams.adoc | 75 +++++++++++++++++++-- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/docs/storage-formats/asciidoc/diagrams.adoc b/docs/storage-formats/asciidoc/diagrams.adoc index 6e87f6c2..9d423aad 100644 --- a/docs/storage-formats/asciidoc/diagrams.adoc +++ b/docs/storage-formats/asciidoc/diagrams.adoc @@ -1,19 +1,74 @@ = AsciiDoc - diagrams -:keywords: supported-format,markdown +:keywords: supported-format,asciidoc :toc: preamble -For AsciiDoc *text2confl* relies on native diagrams support provided by link:https://docs.asciidoctor.org/diagram-extension/latest/[`asciidoctor-diagram` extension]. +*text2confl* supports two asciidoc-native diagrams extensions: + +. link:https://docs.asciidoctor.org/diagram-extension/latest/[`asciidoctor-diagram` extension]. +. link:https://github.com/asciidoctor/asciidoctor-kroki[`asciidoctor-kroki` extension]. + +Approach for diagrams generation is controlled by + +[source,yaml] +---- +asciidoc: + diagrams: Diagrams / Kroki / None +---- + +== Using `asciidoctor-diagram` + +`asciidoctor-diagram` support is enabled by default. That means that you have access to dozens of diagram formats as long as tools that can generate them is available on machine where *text2confl* works. NOTE: *text2confl* Docker image by default contains only `plantuml`. If you need any other diagram type, you can create derivative image with it. +List of supported diagrams and macro names: https://docs.asciidoctor.org/diagram-extension/latest/diagram_types/a2s/ + Generated diagrams are attached to page like a regular files. +== Using `asciidoctor-kroki` + +`asciidoctor-kroki` support can be enabled by explicitly setting diagram provider via `.text2confl.yml` file: + +[source,yaml] +---- +asciidoc: + diagrams: Kroki + kroki: + server: ... # <1> + format: png # <2> + fetch: true/false # <3> +---- + +<1> `server` specifies custom Kroki server +<2> `format` set's default format for generated diagrams +<3> `fetch` setting to `false` will put a links to Kroki server instead of attaching diagram files to page + +Generated diagrams are attached to page like a regular files or put as an image links to Kroki server. + +You can find details about available options in xref:../../configuration-reference.md#asciidoc-configuration-options[configuration reference] + +List of supported diagrams and macro names: https://github.com/asciidoctor/asciidoctor-kroki/?tab=readme-ov-file#supported-diagram-types + +=== Additional customizations for Kroki + +You can customize kroki extension via `asciidoc.attributes` section in config with all link:https://github.com/asciidoctor/asciidoctor-kroki/?tab=readme-ov-file#configuration[supported attributes]: + +[source,yaml] +---- +asciidoc: + attributes: +---- + +== Disabling diagram extensions + +If you want + == Adding diagrams to page -As link:https://docs.asciidoctor.org/diagram-extension/latest/blocks/[official AsciiDoc documentations] says, diagrams can be either put inline similar to code block or included from file using per diagram type macro. +With both link:https://docs.asciidoctor.org/diagram-extension/latest/blocks/[asciidoctor-diagram] and link:https://github.com/asciidoctor/asciidoctor-kroki/?tab=readme-ov-file#usage[asciidoctor-kroki], diagrams can be either put inline similar to code block or included from file using per diagram type macro. With block or macro attributes, you can control name of generated file, file format and diagram-specific features. @@ -38,10 +93,18 @@ include::_assets/example.adoc[tag=diagram] |=== | AsciiDoc | Confluence -|`+plantuml::_assets/test.puml[format=png]+` -| plantuml::_assets/test.puml[format=png] +|`+plantuml::_assets/test.puml[target=test,format=png]+` +| plantuml::{docdir}/_assets/test.puml[target=test,format=png] |=== +[WARNING] +.asciidoctor-kroki file imports +==== +Until link:https://github.com/asciidoctor/asciidoctor-kroki/issues/446[file resolution issue] is not fixed, Kroki extension will fail to resolve files properly when you use relative paths. + +There is a workaround for this - add `+{docdir}+` to macro target: `+plantuml::{docdir}/_assets/test.puml[target=test,format=png]+` +==== + == Location where diagrams are generated By default, generated diagrams are saved in `.asciidoc` directory under documents root. @@ -52,7 +115,7 @@ This is configurable with the following parameters in `.text2confl.yml` file ---- asciidoc: attributes: - plantuml-format: png + baseDir: .asciidoc ---- You can find details about available options in xref:../../configuration-reference.md#asciidoc-configuration-options[configuration reference] \ No newline at end of file From 3bce3627ee0e1be51940cfd22ee5989b60095d37 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Sun, 24 Mar 2024 17:36:54 +0300 Subject: [PATCH 3/3] Updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8277496..ab793bf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Added - Check for conflict of published page with pages parent (#142) +- Support for Kroki in asciidoc files via `kroki-extension` (#162) ### Changed