Python
Markdown
Pandoc
plantuml

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 等をダウンロードしてきて、

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用に書き換えただけです。


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 を配置して下さい。

その上で、

pandoc -i input.md -o output.xx --filter plantuml.py

とすれば、出力フォーマットに合わせた画像がplantuml-images以下に作成され、出力ファイルに画像が埋め込まれます。


参考


https://qiita.com/i3vi3/items/205768ad10107d9f571f

https://efcl.info/2014/0301/res3692/