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 を書いた。
これで PlantUML を実行してぬるぽになったら「こういうことが疑わしいよ?」というメッセージを付け加えることができるので、無駄にトラブルシュートに入ろうとしないんじゃないんかな。たぶん。