【Sphinx】blockdiag拡張を使用して図を挿入する

インターステラの阿形です。

最近仕様書を書くのにもSphinxを使っています。
reStructuredTextで文章を書くのはなかなかサクサク書けていいんですが、図は悩みどころ。
そこで簡単な図を挿入したいときに便利なblockdiag拡張を使ってみたので、その設定方法を書いていこうと思います。


blockdiagとは

blockdiagとは、テキストからブロック図などの画像を生成するツール群です。
対応している図の種類は以下のようなものがあります。
  • ブロック図(blockdiag)
  • シーケンス図(seqdiag)
  • アクティビティ図(actdiag)
  • 論理ネットワーク図(nwdiag)
  • ラック図(rackdiag)
  • パケットヘッダ図(packetdiag)
これらを以下のような記法で記述することができます。
blockdiag {
   A -> B -> C -> D;
   A -> E -> F -> G;
}
詳細はこちらをご覧ください。


インストール

Sphinxで使用する場合は、pipで各パッケージをインストールすることで使用することができます。
作成する図の種類ごとにそれぞれ対応するパッケージをインストールする必要があります。
ここでは面倒なので、全部インストールしてしまいます。
pip install sphinxcontrib-blockdiag sphinxcontrib-seqdiag sphinxcontrib-actdiag sphinxcontrib-nwdiag
不要なものは適宜省いてインストールすると良いと思います。

Sphinxの設定

Sphinxで使用するためにはSphinxのconf.pyに設定を追加する必要があります。
まず、conf.pyのextensionsにそれぞれ以下のように追加します。
extensions = [
    'sphinxcontrib.blockdiag',
    'sphinxcontrib.seqdiag',
    'sphinxcontrib.actdiag',
    'sphinxcontrib.nwdiag',
    'sphinxcontrib.rackdiag',
    'sphinxcontrib.packetdiag'
]
既存のextentionsの設定がある場合は、'sphinxcontrib.blockdiag'...以下を既存の設定の後に追加するようにします。
例えば、私の場合は当初以下のようになっていたので
extensions = [
    'sphinx.ext.autodoc',
]
以下のように変更しました。
extensions = [
    'sphinx.ext.autodoc',
    'sphinxcontrib.blockdiag',
    'sphinxcontrib.seqdiag',
    'sphinxcontrib.actdiag',
    'sphinxcontrib.nwdiag',
    'sphinxcontrib.rackdiag',
    'sphinxcontrib.packetdiag'
]
こちらも同様に適宜不要なものは省いて設定すると良いと思います。

さらに、出力形式の設定を行います。
Sphinxで使用する場合、私の場合はHTMLで出力して使用しているんですが、デフォルトのままだとあまり美しくないのでSVG出力するように変更します。
blockdiag_html_image_format = "SVG"
seqdiag_html_image_format = "SVG"
actdiag_html_image_format = "SVG"
nwdiag_html_image_format = "SVG"
rackdiag_html_image_format = "SVG"
packetdiag_html_image_format = "SVG"

こちらも同様に適宜不要なものは省いて設定すると良いと思います。
以上でconf.pyの修正は終了です。

記述方法

それではSphinxで実際に図を書いていってみましょう。
図を見てからどう書いているか見たほうがわかりやすいと思うので、図を示してからコードを掲載しています。
(なお、ブログエンジンの都合上、SVG出力したものを画面キャプチャしたものを貼り付けているので、実際の画像と若干異なる可能性があります。)

ブロック図


.. blockdiag::

   blockdiag {
      A -> B -> C;
   }
矢印の向きを変えたり、説明を記述することもできます。

.. blockdiag::
   :desctable:

   blockdiag {
      A -> B -> C;
      A [description = "browsers in each client"];
      B [description = "web server"];
      C [description = "database server"];
   }
記述方法の詳細はこちらを参照してください。
http://blockdiag.com/ja/blockdiag/sphinxcontrib.html#directive

 シーケンス図

こちらもブロック図と同様の記述で行うことができます。
.. seqdiag::
   :desctable:

   seqdiag {
      A -> B -> C;
      A [description = "browsers in each client"];
      B [description = "web server"];
      C [description = "database server"];
   }
記述方法の詳細はこちらを参照してください。
http://blockdiag.com/ja/seqdiag/sphinxcontrib.html#directive

アクティビティ図


こちらは若干複雑です。
actdiagで囲った中に、まず各ノードの接続を記述し、続いてレーンをlaneで指定します。
各レーンに属するノードをその中に記述する形です。

.. actdiag::

    actdiag {
        write -> convert -> image
        lane user {
            label = "User"
            write [label = "Writing reST"];
            image [label = "Get diagram IMAGE"];
        }
        lane actdiag {
            convert [label = "Convert reST to Image"];
        }
    }
記述方法の詳細はこちらを参照してください。
http://blockdiag.com/ja/actdiag/sphinxcontrib.html#directive

ネットワーク図


こちらはネットワークセグメントごとにnetwork{}を記述し、それぞれのノードの設定を記述する形です。
.. nwdiag::
   :desctable:

   nwdiag {
      network {
        A [address = 192.168.0.1, description = "web server01"];
        B [address = 192.168.0.2, description = "web server02"];
      }
      network {
        A [address = 172.0.0.1];
        C [address = 172.0.0.2, description = "database server"];
      }
   }

記述方法の詳細はこちらを参照してください。
http://blockdiag.com/ja/nwdiag/sphinxcontrib.html#directive

ラック図


ラックごとにrack{}でまとめるのはnetworkと同じです。 電源容量を入力したりもできます。便利。
.. nwdiag::
.. rackdiag::
    :desctable:

    rackdiag {
        rack {
            10U

            description = "Rack No. 001 Production";

            1: Switching HUB [0.5A,description="Cisco"]
            2: Web Server 01 [0.5A,description="HP"]
            3: Web Server 02 [0.5A,description="HP"]
            4: Application Server 01 [0.5A,description="HP"]
            5: Application Server 02 [0.5A,description="HP"]
            6: DB Server 01 [2U,1A,description="HP"]
            8: DB Server 02 [2U,1A,description="HP"]
            10: N/A
        }
        rack {
            10U

            description = "Rack No. 002 Test";

            1: Switching HUB [0.5A,description="Cisco"]
            2: Web Server [0.5A,description="HP"]
            3: Application Server [0.5A,description="HP"]
            4: DB Server [2U,1A,description="HP"]
            6: N/A [5U]
        }
    }
こちらは書き方の詳細がオフィシャルにないようなので、かなり手探りで書きました。 オプションは基本的にnwdiagと同じようです。

パケットヘッダ図


.. packetdiag::
    :desctable:

    {
        colwidth = 32
        node_height = 72

        0-15: Source Port
        16-31: Destination Port
        32-63: Sequence Number
        64-95: Acknowledgment Number
        96-99: Data Offset
        100-105: Reserved
        106: URG [rotate = 270]
        107: ACK [rotate = 270]
        108: PSH [rotate = 270]
        109: RST [rotate = 270]
        110: SYN [rotate = 270]
        111: FIN [rotate = 270]
        112-127: Window
        128-143: Checksum
        144-159: Urgent Pointer
        160-191: (Options and Padding)
        192-223: data [colheight = 3]
    }

こちらも書き方の詳細がオフィシャルにないようです。
ただ、面倒なパケットヘッダ図を簡潔に描くことができるので、これが一番おいしいかもしれません。(使用頻度は低そうですが)

まとめ

ざっと使ってみた感じ、複雑な図を書くにはなかなか面倒そうですが、ちょっとした図を挿入したいときには結構使えそうです。


このブログの人気の投稿

【AWS】IAMFullAccessを付与せずIAM Roleの作成とアタッチを行う方法

【AWS】EBSボリューム自動取得/削除 を Lambda で実行 (世代管理も)

【GCP】Compute EngineでVPNサーバーを立てるときの注意点