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 等をダウンロードしてきて、
sudo dpkg -i pandoc-X.X.X-X-amd64.deb
すればインストールできます。
pythonにpandocfiltersをインストール
今回は、python3系を前提で、pythonのインストールはすでされている前提で進めて行きます。
Windows環境
管理者権限で開いたcmdもしくはpowershellで、以下のコマンドでインストール
pip install pandocfilters
する。
Ubuntu環境
ターミナルで、以下のコマンドでインストール。
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用に書き換えただけです。
#!/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 を配置して下さい。
その上で、
pandoc -i input.md -o output.xx --filter plantuml.py
とすれば、出力フォーマットに合わせた画像がplantuml-images以下に作成され、出力ファイルに画像が埋め込まれます。
参考
https://qiita.com/i3vi3/items/205768ad10107d9f571f
https://efcl.info/2014/0301/res3692/