かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

PlantUML の図を生成するモジュールを Asciidoctor Diagram → Kroki に変更する

Translate to English
https://translate.google.com/translate?sl=auto&tl=en&u=https%3A%2F%2Fksby.hatenablog.com%2Fentry%2F2021%2F01%2F26%2F234903

概要

記事一覧はこちらです。

Creating a Diagram には Asciidoctor Diagram が対応している Diagram Type が PlantUML 以外にも列挙されていますが、例えば mermaid のコードを adoc ファイル内に記述しても Failed to generate image: Could not find the 'mermaid' executable in PATH; と外部プログラムが見つからないというエラーが出て図が生成・表示されません。

f:id:ksby:20210124095809p:plain f:id:ksby:20210124095855p:plain

また plantuml-stdlib / C4-PlantUML というものを見つけたのですが、Asciidoctor Diagram はこの PlantUML で C4 model を記述する方法に対応していません。

Kroki を利用すれば外部プログラムを個別にインストールせずに PlantUML やそれ以外の diagram を生成したり、C4 model を PlantUML で記述したコードから図を生成したりできるようなので試してみます。

参照したサイト・書籍

  1. Kroki
    https://kroki.io/

  2. Kroki Documentation
    https://docs.kroki.io/kroki/

  3. 【12/24にGitLab対応!】テキストで自在に「描く」- KrokiではじめるDiagram as Code
    https://qiita.com/tomo_makes/items/7c42a736b30554e15c35

  4. Mermaid
    https://mermaid-js.github.io/mermaid/#/

  5. plantuml-stdlib / C4-PlantUML
    https://github.com/plantuml-stdlib/C4-PlantUML

  6. The C4 model for visualising software architecture
    https://c4model.com/

  7. asciidoctor-kroki
    https://rubygems.org/gems/asciidoctor-kroki/

  8. Mogztter / asciidoctor-kroki
    https://github.com/Mogztter/asciidoctor-kroki

  9. Ruby GEM support
    https://asciidoctor.github.io/asciidoctor-gradle-plugin/development-3.x/user-guide/#asciidoctorj-gems-plugin

  10. How can I configure the gradle asciidoctor 2.0 plugin to use pygments.rb as higlighter?
    https://github.com/asciidoctor/asciidoctor-gradle-plugin/issues/326

  11. Copy
    https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Copy.html

  12. Gradle - Delete files with certain extension
    https://stackoverflow.com/questions/27285885/gradle-delete-files-with-certain-extension

目次

  1. Ruby の gem の asciidoctor-kroki を使用して asciidoctor タスク実行時に Kroki で図を生成するよう build.gradle を変更する
  2. asciidoctor タスクを実行して動作確認する
  3. Kroki の Docker image を利用してローカルでサーバを起動し、画像ファイルがローカルに保存されるようにする
    1. docker-compose.yml を作成し、Kroki のコンテナを起動するための設定を記述する
    2. docker-compose up -d を実行して Kroki のコンテナを起動する
    3. AsciiDoc Plugin の Preview が Kroki を利用するよう設定を変更する
    4. asciidoctor タスク実行時にローカルで起動した Kroki のコンテナを利用するよう build.gradle を変更する
    5. index.adoc の plantuml の記述を変更する
    6. asciidoctorWithMoveDiagSvg タスクを実行して動作確認する

手順

Ruby の gem の asciidoctor-kroki を使用して asciidoctor タスク実行時に Kroki で図を生成するよう build.gradle を変更する

Asciidoctor+Gradle の環境で Kroki を利用するにはどうすればよいのか調べてみたところ、

  • Mogztter / asciidoctor-kroki が見つかりましたが、これは An extension for Asciidoctor.js とのこと。
  • 他にも探すと Ruby の gem である asciidoctor-kroki が見つかりました。このページ右上の GitHub のアイコンをクリックすると Mogztter / asciidoctor-kroki に遷移しますので同じ機能を持つモジュールのようです。
  • Asciidoctor Gradle Plugin のドキュメントを見ると Ruby GEM support の記述があり、Asciidoctor+Gradle の環境で Ruby の gem が利用できるとのこと。

ということで Ruby の gem の asciidoctor-kroki を利用するよう build.gradle を変更すれば Kroki を利用できるようです。

build.gradle を以下のように変更します。

plugins {
    id "org.asciidoctor.jvm.convert" version "3.3.0"
    id "org.asciidoctor.jvm.gems" version "3.3.0"
}

repositories {
    mavenCentral()
    ruby.gems()
}

dependencies {
    asciidoctorGems "rubygems:asciidoctor-kroki:0.3.0"
}

asciidoctor {
    dependsOn asciidoctorGemsPrepare
    sourceDir file("src/docs/asciidoc")
    baseDirFollowsSourceFile()
    sources {
        include "**/index.adoc"
    }
    resources {
        from("${sourceDir}") {
            include "**/*.png",
                    "**/*.js"
        }
    }
}

asciidoctorj {
    requires = [
            "asciidoctor-kroki"
    ]
    attributes "source-highlighter" : "rouge"
}
  • plugins block に以下の行を追加します。
    • id "org.asciidoctor.jvm.gems" version "3.3.0"
  • repositories block に以下の行を追加します。
    • ruby.gems()
  • dependencies { asciidoctorGems "rubygems:asciidoctor-kroki:0.3.0" } を追加します。
  • asciidoctor block に dependsOn asciidoctorGemsPrepare を追加します。この記述を追加することが最初分からず asciidoctor タスクを実行すると以下の画像のエラーが出たのですが、 f:id:ksby:20210124105428p:plain How can I configure the gradle asciidoctor 2.0 plugin to use pygments.rb as higlighter? の Issue に記述されているサンプルを見つけたのと、Asciidoctor Gradle Plugin のドキュメントにも asciidoctorGemsPrepare の記述があり、マネしてみたらうまく動きました。
  • asciidoctorj block の以下の点を変更します。
    • Asciidoctor Diagram の設定は不要になるので modules { diagram.use() diagram.version "2.1.0" } を削除します。
    • requires = [ "asciidoctor-kroki" ] を追加します。

asciidoctor タスクを実行して動作確認する

asciidoctor タスクを実行すると BUILD SUCCESSFUL が出力されますが、asciidoctor タスクの前に asciidoctorGemsPrepare タスクが実行されるようになり、また Java 11 を使っていることに伴う WARNING メッセージが出力されました。

f:id:ksby:20210124121432p:plain

WARNING メッセージが出力されないようにします。IntelliJ IDEA のメインメニューから「Run」-「Edit Configurations...」を選択して「Run/Debug Configurations」ダイアログを表示した後、「ksbysample-asciidoctor [asciidoctor]」 の Environment variables に "--add-opens=java.base/java.security=ALL-UNNAMED" を追加します。Environment variables にセットされている文字列は全体で JDK_JAVA_OPTIONS="--add-opens=java.base/java.lang=ALL-UNNAMED" "--add-opens=java.base/java.util=ALL-UNNAMED" "--add-opens=java.base/java.security=ALL-UNNAMED" "-Xverify:none" "-XX:TieredStopAtLevel=1" になります。

f:id:ksby:20210124122255p:plain

clean タスク実行 → asciidoctor タスク実行をすると今度は WARNING メッセージが出ませんでした。

f:id:ksby:20210124122426p:plain

build/docs/asciidoc/03_diagram/index.html が出力されており、それ以外に、

  • build/.asciidoctorGems というディレクトリが出来ていました。Ruby の gem はここにダウンロードされるようです。
  • build/docs/asciidoc/03_diagram の下に index.html は作成されていますが、example-sequence.svg、example-class.svg は作成されていませんでした。

f:id:ksby:20210124122611p:plain:w300

index.html をエディタで開いてみると、<img src="https://kroki.io/plantuml/svg/..." alt="example-sequence"> のような img タグが記述されていました。svg の画像は Kroki のサーバ(https://kroki.io/)上に生成されているようです。

f:id:ksby:20210124123008p:plain

index.html をブラウザで開くと PlantUML の図が表示されました。

f:id:ksby:20210124123306p:plain

Kroki の Docker image を利用してローカルでサーバを起動し、画像ファイルがローカルに保存されるようにする

画像ファイルはローカルに保存しておきたいのと、Kroki は Docker image が提供されていてローカルでサーバを起動できるので、Docker で Kroki のコンテナを起動して、生成した画像ファイルもローカルにダウンロードして保存するようにします。

docker-compose.yml を作成し、Kroki のコンテナを起動するための設定を記述する

プロジェクトのルートディレクトリ直下に docker-compose.yml を新規作成し、Install Kroki に記載されている docker-compose.yml の記述をそのままコピペします。

version: "3"
services:
  core:
    image: yuzutech/kroki
    environment:
      - KROKI_BLOCKDIAG_HOST=blockdiag
      - KROKI_MERMAID_HOST=mermaid
      - KROKI_BPMN_HOST=bpmn
    ports:
      - "8000:8000"
  blockdiag:
    image: yuzutech/kroki-blockdiag
    expose:
      - "8001"
  mermaid:
    image: yuzutech/kroki-mermaid
    expose:
      - "8002"
  bpmn:
    image: yuzutech/kroki-bpmn
    expose:
      - "8003"
  excalidraw:
    image: yuzutech/kroki-excalidraw
    expose:
      - "8004"

docker-compose up -d を実行して Kroki のコンテナを起動する

docker-compose up -d を実行して Kroki のコンテナを起動します。

f:id:ksby:20210124142828p:plain f:id:ksby:20210124142927p:plain

AsciiDoc Plugin の Preview が Kroki を利用するよう設定を変更する

AsciiDoc Plugin の Preview は Asciidoctor Diagram だけでなく Kroki にも対応しているので、ローカルで起動した Kroki のコンテナを利用するように設定を変更します。

IntelliJ IDEA の「Settings」ダイアログを開いてから画面左上の検索フィールドに Kroki と入力すると「Languages & Frameworks」-「AsciiDoc」が表示されるので選択します。その後画面左側の「Use Kroki to render diagrams instead of Asciidoctor Diagram」をチェックし、「URL of custom Kroki instance」に http://localhost:8000 を入力して「OK」ボタンをクリックします。

f:id:ksby:20210124143315p:plain

AsciiDoc Plugin の Preview で index.adoc を表示すると今度はクラス図も表示されるようになりました。

f:id:ksby:20210124143952p:plain

PlantUML integration Plugin には Kroki を利用する設定はないので、こちらは何もしません(何もしなくても C4 model を PlantUML で記述したコードから図を表示してくれました)。

asciidoctor タスク実行時にローカルで起動した Kroki のコンテナを利用するよう build.gradle を変更する

build.gradle を以下のように変更します。

..........

asciidoctorj {
    requires = [
            "asciidoctor-kroki"
    ]
    attributes "source-highlighter" : "rouge"
    attributes "kroki-server-url": "http://localhost:8000"
    attributes "kroki-fetch-diagram": "true"
}

// Kroki で生成してローカルにダウンロードした画像ファイルを asciidoctor.outputDir に移動する
task asciidoctorWithMoveDiagSvg(group: "documentation") {
    doLast {
        def moveFilePattern = "**/diag-*.svg"

        copy() {
            from(asciidoctor.sourceDir) {
                include moveFilePattern
            }
            into asciidoctor.outputDir
        }

        delete fileTree(asciidoctor.sourceDir) { include moveFilePattern }
    }
}
asciidoctorWithMoveDiagSvg.dependsOn asciidoctor
  • asciidoctorj block に以下の2行を追加します。
    • attributes "kroki-server-url": "http://localhost:8000"
    • attributes "kroki-fetch-diagram": "true"
  • task asciidoctorWithMoveDiagSvg(group: "documentation") { ... }asciidoctorWithMoveDiagSvg.dependsOn asciidoctor を追加します。

上の変更から asciidoctorWithMoveDiagSvg タスクがない状態で asciidoctor タスクを実行すると build/docs/asciidoc/03_diagram/index.html の img タグには以下のように出力されるのですが、

f:id:ksby:20210124153821p:plain

Kroki で生成された画像ファイルは build ディレクトリではなく src/docs/asciidoc/03_diagram の下にダウンロードされるため、index.html をブラウザで表示させた時に PlantUML の図が表示されません。

f:id:ksby:20210124154247p:plain:w300

src/docs/asciidoc/03_diagram/index.adoc の中で [plantuml,example-sequence,svg][plantuml,opts=inline] に変更すれば index.html の中に SVG のコードが出力されるので SVG のファイルを移動しなくてもよくなるのですが、今度は AsciiDoc Plugin の Preview に図が表示されません。

f:id:ksby:20210124154519p:plain

ブラウザの表示も AsciiDoc Plugin の Preview の表示もできるようにするために、asciidoctorWithMoveDiagSvg タスクを追加して asciidoctor タスク実行後に svg のファイルを移動することにしました。

Gradle Tool Window 左上の「Reload All Gradle Projects」ボタンをクリックして更新すると、documentation の下に asciidoctorWithMoveDiagSvg タスクが表示されます。

f:id:ksby:20210125235605p:plain

index.adoc の plantuml の記述を変更する

Kroki を利用する場合、画像ファイル名を指定できないので、src/docs/asciidoc/03_diagram/index.adoc の [plantuml] の記述から画像ファイル名と画像のタイプの指定を削除します。

= AsciiDoc 形式のドキュメントに PlantUML の図を埋め込む
Doc Writer <doc@example.com>
:lang: ja

== シーケンス図

[plantuml]
....
include::example-sequence.puml[]
....

== クラス図

[plantuml]
....
include::example-class.puml[]
....

asciidoctorWithMoveDiagSvg タスクを実行して動作確認する

asciidoctorWithMoveDiagSvg タスクを実行すると Java 11 を使っていることに伴う WARNING メッセージが出力されました。asciidoctor タスクでなくなったので当然ですね。。。

f:id:ksby:20210125235849p:plain

「Run/Debug Configurations」ダイアログを表示した後、asciidoctor タスクの Environment variables に設定していた文字列を asciidoctorWithMoveDiagSvg タスクにも設定します。

f:id:ksby:20210126000115p:plain

再度 asciidoctorWithMoveDiagSvg タスクを実行すると今度は WARNING メッセージが出力されませんでした。

f:id:ksby:20210126000327p:plain

画像ファイルは build/docs/asciidoc/03_diagram の下に移動しており、

f:id:ksby:20210126000504p:plain:w300

build/docs/asciidoc/03_diagram/index.html をブラウザで表示すると PlantUML の図も表示されました。

f:id:ksby:20210126000858p:plain

履歴

2021/01/26
初版発行。