かんがるーさんの日記

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

PlantUML 以外の diagram を AsciiDoc のドキュメントに埋め込んで見る(bpmn、bytefield 編)

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

概要

記事一覧はこちらです。

AsciiDoc のドキュメントには PlantUML 以外の diagram も埋め込めるので、いくつか興味を持ったものを試してみます。diagram の生成には Kroki のコンテナを使用します。

全部で bpmn、bytefield、ditaa、C4 model の4つ試します。今回は bpmn、bytefield の2つです。

参照したサイト・書籍

  1. gtudan / bpmn-js-cmd
    https://github.com/gtudan/bpmn-js-cmd

  2. bpmn-js
    https://bpmn.io/toolkit/bpmn-js/

  3. ABOUT THE BUSINESS PROCESS MODEL AND NOTATION SPECIFICATION VERSION 2.0.2
    https://www.omg.org/spec/BPMN

  4. Deep-Symmetry / bytefield-svg
    https://github.com/Deep-Symmetry/bytefield-svg

  5. Byte Field SVG Builder
    https://bytefield-svg.deepsymmetry.org/bytefield-svg/intro.html

  6. The Clojure Programming Language
    https://clojure.org/

目次

  1. bpmn の diagram を埋め込む
    1. https://demo.bpmn.io/ で BPMN のワークフローを描き XML ファイルを出力する
    2. AsciiDoc のドキュメントに出力した XML ファイルを include する
    3. asciidoctorWithMoveDiagSvg タスクを実行して動作確認する
  2. bytefield の diagram を埋め込む
    1. https://kroki.io/ の Bytefield のコードをファイルに保存する
    2. AsciiDoc のドキュメントに Bytefield のコードのファイルを include する
    3. asciidoctorWithMoveDiagSvg タスクを実行して動作確認する

手順

bpmn の diagram を埋め込む

https://demo.bpmn.io/ で BPMN のワークフローを描き XML ファイルを出力する

https://bpmn.io/toolkit/bpmn-js/ の「Try Online」のボタンをクリックすると

f:id:ksby:20210130210935p:plain

BPMN diagram のエディタのページが開くので create リンクをクリックします。

f:id:ksby:20210130211137p:plain

以下のページが表示されるので、

f:id:ksby:20210130211346p:plain

BPMN の diagram を作成して画面左下の「Download as BPMN 2.0 file」ボタンをクリックします。このエディタ、かなり使い勝手がいいです。BPMN でなくてもフローチャートのようなものを描きたい時にも使えそうです。

f:id:ksby:20210130211900p:plain

diagram.bpmn というファイルがダウンロードされるので、

f:id:ksby:20210130212101p:plain

ファイル名を example-bpmn.xml に変更してから src/docs/asciidoc/03_diagram の下にコピーします。ファイルには以下の内容が出力されていました。

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1v0204h" targetNamespace="http://bpmn.io/schema/bpmn" exporter="bpmn-js (https://demo.bpmn.io)" exporterVersion="8.2.0">
  <bpmn:collaboration id="Collaboration_0esz28g">
    <bpmn:participant id="Participant_1wt0hx7" name="担当" processRef="Process_1yvf2u7" />
    <bpmn:participant id="Participant_1ekcrhk" name="顧客" processRef="Process_0y1378r" />
    <bpmn:messageFlow id="Flow_0sr1ydc" sourceRef="Participant_1ekcrhk" targetRef="Event_0bfbply" />
  </bpmn:collaboration>
  <bpmn:process id="Process_1yvf2u7">
    <bpmn:startEvent id="Event_0bfbply" name="開始">
      <bpmn:outgoing>Flow_1bjdsif</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:exclusiveGateway id="Gateway_0z7l85o" name="何か判断する">
      <bpmn:incoming>Flow_0awhuxb</bpmn:incoming>
      <bpmn:outgoing>Flow_1valj6w</bpmn:outgoing>
      <bpmn:outgoing>Flow_0zc3okk</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:intermediateThrowEvent id="Event_1jvqnpo" name="終了">
      <bpmn:incoming>Flow_0txzrxj</bpmn:incoming>
      <bpmn:incoming>Flow_00oerl8</bpmn:incoming>
    </bpmn:intermediateThrowEvent>
    <bpmn:userTask id="Activity_0qztpf7" name="タスク1">
      <bpmn:incoming>Flow_1bjdsif</bpmn:incoming>
      <bpmn:outgoing>Flow_0awhuxb</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:userTask id="Activity_1vn6vl3" name="タスク2">
      <bpmn:incoming>Flow_1valj6w</bpmn:incoming>
      <bpmn:outgoing>Flow_0ads6v6</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:userTask id="Activity_1um5mkv" name="タスク3">
      <bpmn:incoming>Flow_0ads6v6</bpmn:incoming>
      <bpmn:outgoing>Flow_0txzrxj</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:serviceTask id="Activity_0p4qw7j" name="サービス1">
      <bpmn:incoming>Flow_0zc3okk</bpmn:incoming>
      <bpmn:outgoing>Flow_00oerl8</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sequenceFlow id="Flow_1bjdsif" sourceRef="Event_0bfbply" targetRef="Activity_0qztpf7" />
    <bpmn:sequenceFlow id="Flow_0awhuxb" sourceRef="Activity_0qztpf7" targetRef="Gateway_0z7l85o" />
    <bpmn:sequenceFlow id="Flow_1valj6w" sourceRef="Gateway_0z7l85o" targetRef="Activity_1vn6vl3" />
    <bpmn:sequenceFlow id="Flow_0ads6v6" sourceRef="Activity_1vn6vl3" targetRef="Activity_1um5mkv" />
    <bpmn:sequenceFlow id="Flow_0txzrxj" sourceRef="Activity_1um5mkv" targetRef="Event_1jvqnpo" />
    <bpmn:sequenceFlow id="Flow_0zc3okk" sourceRef="Gateway_0z7l85o" targetRef="Activity_0p4qw7j" />
    <bpmn:sequenceFlow id="Flow_00oerl8" sourceRef="Activity_0p4qw7j" targetRef="Event_1jvqnpo" />
  </bpmn:process>
  <bpmn:process id="Process_0y1378r" />
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_0esz28g">
      <bpmndi:BPMNShape id="Participant_1wt0hx7_di" bpmnElement="Participant_1wt0hx7" isHorizontal="true">
        <dc:Bounds x="160" y="200" width="780" height="250" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="Flow_1bjdsif_di" bpmnElement="Flow_1bjdsif">
        <di:waypoint x="248" y="260" />
        <di:waypoint x="300" y="260" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0awhuxb_di" bpmnElement="Flow_0awhuxb">
        <di:waypoint x="400" y="260" />
        <di:waypoint x="455" y="260" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1valj6w_di" bpmnElement="Flow_1valj6w">
        <di:waypoint x="505" y="260" />
        <di:waypoint x="560" y="260" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0ads6v6_di" bpmnElement="Flow_0ads6v6">
        <di:waypoint x="660" y="260" />
        <di:waypoint x="720" y="260" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0txzrxj_di" bpmnElement="Flow_0txzrxj">
        <di:waypoint x="820" y="260" />
        <di:waypoint x="882" y="260" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0zc3okk_di" bpmnElement="Flow_0zc3okk">
        <di:waypoint x="480" y="285" />
        <di:waypoint x="480" y="370" />
        <di:waypoint x="560" y="370" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_00oerl8_di" bpmnElement="Flow_00oerl8">
        <di:waypoint x="660" y="370" />
        <di:waypoint x="850" y="370" />
        <di:waypoint x="850" y="260" />
        <di:waypoint x="882" y="260" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="Event_0bfbply_di" bpmnElement="Event_0bfbply">
        <dc:Bounds x="212" y="242" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="219" y="285" width="23" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Gateway_0z7l85o_di" bpmnElement="Gateway_0z7l85o" isMarkerVisible="true">
        <dc:Bounds x="455" y="235" width="50" height="50" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="447" y="205" width="66" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_1jvqnpo_di" bpmnElement="Event_1jvqnpo">
        <dc:Bounds x="882" y="242" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="889" y="285" width="23" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_104sj26_di" bpmnElement="Activity_0qztpf7">
        <dc:Bounds x="300" y="220" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_0sjnmyp_di" bpmnElement="Activity_1vn6vl3">
        <dc:Bounds x="560" y="220" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_079ttch_di" bpmnElement="Activity_1um5mkv">
        <dc:Bounds x="720" y="220" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_0mul251_di" bpmnElement="Activity_0p4qw7j">
        <dc:Bounds x="560" y="330" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Participant_1ekcrhk_di" bpmnElement="Participant_1ekcrhk" isHorizontal="true">
        <dc:Bounds x="160" y="80" width="300" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="Flow_0sr1ydc_di" bpmnElement="Flow_0sr1ydc">
        <di:waypoint x="230" y="153" />
        <di:waypoint x="230" y="242" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

AsciiDoc のドキュメントに出力した XML ファイルを include する

src/docs/asciidoc/03_diagram/index.adoc に example-bpmn.xml を include します。

..........

== クラス図

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

== BPMN

[bpmn]
....
include::example-bpmn.xml[]
....

AsciiDoc Plugin の preview にも Kroki のコンテナで生成された diagram が表示されます。

f:id:ksby:20210130213740p:plain

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

asciidoctorWithMoveDiagSvg タスクを実行すると BUILD SUCCESSFUL が表示されて、

f:id:ksby:20210130214217p:plain

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

f:id:ksby:20210130214457p:plain

bytefield の diagram を埋め込む

https://kroki.io/ の Bytefield のコードをファイルに保存する

こちらは https://kroki.io/ で Bytefield を選択して表示されたコードをコピーすることにします。Deep-Symmetry / bytefield-svg によると Clojure ベースの DSL とのことなので、src/docs/asciidoc/03_diagram の下に example-bytefield.clj というファイルを作成してコピペします。

拡張子 .clj のファイルに保存すると Clojure のコードと識別されて IntelliJ IDEA のエディタ上でシンタックスハイライトされます。

f:id:ksby:20210131174109p:plain

AsciiDoc のドキュメントに Bytefield のコードのファイルを include する

src/docs/asciidoc/03_diagram/index.adoc に example-bytefield.clj を include します。

..........

== BPMN

[bpmn]
....
include::example-bpmn.xml[]
....

== bytefield

[bytefield]
....
include::example-bytefield.clj[]
....

AsciiDoc Plugin の preview にも Kroki のコンテナで生成された diagram が表示されます。

f:id:ksby:20210131174449p:plain

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

asciidoctorWithMoveDiagSvg タスクを実行すると BUILD SUCCESSFUL が表示されて、

f:id:ksby:20210131174754p:plain

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

f:id:ksby:20210131174945p:plain

履歴

2021/01/31
初版発行。