PlantUMLの-pipeモードとEmacsのplantuml-mode
Emacsのplantuml-modeが謎のぬるぽ
なんだろうなぁと思っていた。一部の PlantUML ファイルについて Emacs の plantuml-mode で正しく preview できずに Java のレベルで異常終了してしまう。VS Code の PlantUML extension では特に問題ない。
違いとしては
- VS Code 側は画像を出力している
- Emacs 側は txt で出力している
あとなんとなくだけど
- Emacs 側は stdio で PlantUML の出力を受け取っているんじゃないか
と予測できる。ファイルを渡すのではなく選択範囲(region)の内容を渡して preview することが可能なので。
plantuml-modeの動作
まず plantuml に与えられる引数をチェック。
$ plantuml -h
すると
-p[ipe] To use stdin for PlantUML source and stdout for PNG/SVG/EPS generation
というオプションを見つける。実にそれっぽい。確かに plantuml コマンドでファイルを直接渡した場合と違って plantuml-mode の中から実行している場合と同様に落ちる。ビンゴか。
Emacs Lisp の方を調べると以下のような関数がある。
(defun plantuml-jar-start-process (buf)
"Run PlantUML as an Emacs process and puts the output into the given buffer (a\
s BUF)."
(let ((java-args (if (<= 8 (plantuml-jar-java-version))
(remove "--illegal-access=deny" plantuml-java-args)
plantuml-java-args)))
(apply #'start-process
"PLANTUML" buf plantuml-java-command
`(,@java-args
,(expand-file-name plantuml-jar-path)
,(plantuml-jar-output-type-opt plantuml-output-type)
,@plantuml-jar-args
"-p"))))
(defun plantuml-executable-start-process (buf)
"Run PlantUML as an Emacs process and puts the output into the given buffer (a\
s BUF)."
(apply #'start-process
"PLANTUML" buf plantuml-executable-path
`(,@plantuml-executable-args
,(plantuml-jar-output-type-opt plantuml-output-type)
"-p")))
jar を与えて Java を起動する方法でもコマンドを起動する方法でも -pipe で与えていることが分かる。
なぜか放置されている問題
理由は分からないが、
- PlantUML は -pipe で渡されたデータの中に複数の diagram が含まれていると処理できず NullPointerException が発生する。どうもファイルに出力することが基本的な前提のようだ。
加えて、これはある程度仕方ないとは思うが、
- -Ttxt で表現しきれない diagram でも同様に NullPointerException になってしまう。
まぁ無理なのは分かるけど、
さすがに NullPointerException を放置するのではなく、意味の分かるエラーメッセージにしてほしい
と思う。
さすがに何が起きてるか分かるようにしたい
ということで wrapper script を書いた。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/bash | |
set -o pipefail | |
OUTPUT=$(plantuml "$@" 2>&1) | |
printf "%s" "$OUTPUT" | |
if printf "%s" "$OUTPUT" | grep -q 'java\.lang\.'; then | |
cat <<EOD >&2 | |
Did you write multiple diagrams in single file ? | |
PlantUML with -pipe option cannot accept multiple images ... | |
Or something wrong about some diagrams with txt type ... | |
EOD | |
fi | |
exit 0 |
これで PlantUML を実行してぬるぽになったら「こういうことが疑わしいよ?」というメッセージを付け加えることができるので、無駄にトラブルシュートに入ろうとしないんじゃないんかな。たぶん。