PandocインストールとPlantUMLフィルター

# PandocでのPlantUMLフィルター

Markdown内にPlantUML形式で記載したUMLを、Pandocで変換する時に図として出力したい。この場合、Pandocで変換の際にフィルター処理をしてPlantUMLを図に変換しないといけない。

Windowsで簡単に使えるものがすぐに見つからなかった。なにやら、インストールするために色々環境を整えないといけなさそうなものばかりだった。Pandocのfilterでは、pythonが使えるみたいなので、自分の環境的にはPythonで動けばubuntu等でも使えるので一番良さそうでした。そこで、Pythonのpandocfiltersをインストールして、サンプルを動かしてみたけどうまく動かなかったので、改造して動くようにした。

# Pandocのインストール

Ubuntuリポジトリに標準登録されている、Pandocは古めなので新しいものをインストールして置いて下さい。

https://github.com/jgm/pandoc/releases
からそれぞれの環境に合わせたインストーラーをダウンロードしてインストールすればOK。インストール方法は、
https://github.com/jgm/pandoc/blob/master/INSTALL.md
を参考に。


## Ubuntuの場合

pandoc-X.X.X-X-amd64.deb 等をダウンロードしてきて、

``` bash
sudo dpkg -i pandoc-X.X.X-X-amd64.deb
```

すればインストールできます。


# pythonにpandocfiltersをインストール

今回は、python3系を前提で、pythonのインストールはすでされている前提で進めて行きます。

## Windows環境

管理者権限で開いたcmdもしくはpowershellで、以下のコマンドでインストール

``` powershell
pip install pandocfilters
```
する。

## Ubuntu環境

ターミナルで、以下のコマンドでインストール。

``` bash
sudo pip install pandocfilters
```

# PlantUMLの準備

## Javaのインストール

PlantUMLはjavaを使うのでインストールされていない場合は、インストールしておいて下さい。
インストール方法はここでは省きます。

## PlantUMLのダウンロード

http://plantuml.com/download
から plantuml.jar をダウンロードしておく。

# Pandocフィルターの修正

https://github.com/jgm/pandocfilters
の examples/plantuml.py を使える用に修正します。基本的には、python3用に書き換えただけです。


``` python:plantuml.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Pandoc filter to process code blocks with class "plantuml" into
plant-generated images.

Needs `plantuml.jar` from http://plantuml.com/.
"""

import os
import sys
import subprocess

from pandocfilters import toJSONFilter, Para, Image, get_filename4code, get_caption, get_extension


def plantuml(key, value, format, _):
    if key == 'CodeBlock':
        [[ident, classes, keyvals], code] = value

        if "plantuml" in classes or "puml" in classes:
            caption, typef, keyvals = get_caption(keyvals)

            filename = get_filename4code("plantuml", code)
            # HTML5を追加
            filetype = get_extension(format, "png", html5="svg", html="svg", latex="eps")

            src = filename + '.uml'
            dest = filename + '.' + filetype

            if not os.path.isfile(dest):
                # エンコード関連をコメントアウト
                # txt = code.encode(sys.getfilesystemencoding())
                # txt = str(code)
                txt = code

                if not txt.startswith("@start"):
                    txt = "@startuml\n" + txt + "\n@enduml\n"
                    
                with open(src, "w") as f:
                    f.write(txt)

                # フィルターと同じディレクトリにplantuml.jarをおいておく
                plantuml_jar = os.path.join(os.path.dirname(__file__) , "plantuml.jar")

                # subprosess.callから変更
                subprocess.run(["java", "-jar", plantuml_jar, "-t"+filetype, src])
                sys.stderr.write('Created image ' + dest + '\n')

            return Para([Image([ident, [], keyvals], caption, [dest, typef])])

if __name__ == "__main__":
    toJSONFilter(plantuml)
```

# フィルターの使い方

作成した plantuml.pyと同じディレクトリーにダウンロードした plantuml.jar を配置して下さい。

その上で、

``` bash
pandoc -i input.md -o output.xx --filter plantuml.py
```
とすれば、出力フォーマットに合わせた画像がplantuml-images以下に作成され、出力ファイルに画像が埋め込まれます。

# 参考

> https://qiita.com/i3vi3/items/205768ad10107d9f571f
> https://efcl.info/2014/0301/res3692/