7rikazhexde’s tech log

技術的な興味関心、備忘録、アウトプットなどを書いています。

PlantUMLでPDF出力できないのでInkscapeを使用して対応した話

はじめに

私はVSCode拡張機能PlantUMLを使用しています。

作成した.pumlファイルはPNGSVGにエクスポート(PlantUML: Export Current Diagram)できるため、プロジェクトではコードとセットでコミットしています。

大抵はPNGSVGをエクスポートできれば十分なのですが、PDFもエクスポートしたいことがありました。しかし、うまくいきませんでした。

これは後述しますが公式の仕様でした。解決方法もありましたが、結論から言えば解決方法ではPDFのエクスポートを有効にすることはできませんでした。

それで、結局はベクター画像を扱えるOSSベクターグラフィックエディタである、InkscapeでPDFファイルを作成することにしました。

本記事ではこれらの内容についてまとめたので紹介します。

PlantUMLのPDF出力エラーと解決方法

まず、実際に実行すると以下のエラーになりました。

ダイアグラム"packages_dlSubscanStakingRewardsHistory"にエラーが見つかりました
Warning: the font "Times" is not available, so "Lucida Bright" has been substituted, but may have unexpected appearance or behavor. Re-enable the "Times" font to remove this warning.
java.lang.ClassNotFoundException: org.apache.batik.apps.rasterizer.SVGConverter
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at net.sourceforge.plantuml.pdf.PdfConverter.convert(PdfConverter.java:59)
    at net.sourceforge.plantuml.UmlDiagram.exportDiagramInternalPdf(UmlDiagram.java:277)
    at net.sourceforge.plantuml.UmlDiagram.exportDiagramNow(UmlDiagram.java:132)
    at net.sourceforge.plantuml.AbstractPSystem.exportDiagram(AbstractPSystem.java:178)
    at net.sourceforge.plantuml.SourceStringReader.outputImage(SourceStringReader.java:172)
    at net.sourceforge.plantuml.Pipe.generateDiagram(Pipe.java:100)
    at net.sourceforge.plantuml.Pipe.managePipe(Pipe.java:92)
    at net.sourceforge.plantuml.Run.managePipe(Run.java:354)
    at net.sourceforge.plantuml.Run.main(Run.java:181)
Exception in thread "main" java.lang.UnsupportedOperationException
    at net.sourceforge.plantuml.pdf.PdfConverter.convert(PdfConverter.java:78)
    at net.sourceforge.plantuml.UmlDiagram.exportDiagramInternalPdf(UmlDiagram.java:277)
    at net.sourceforge.plantuml.UmlDiagram.exportDiagramNow(UmlDiagram.java:132)
    at net.sourceforge.plantuml.AbstractPSystem.exportDiagram(AbstractPSystem.java:178)
    at net.sourceforge.plantuml.SourceStringReader.outputImage(SourceStringReader.java:172)
    at net.sourceforge.plantuml.Pipe.generateDiagram(Pipe.java:100)
    at net.sourceforge.plantuml.Pipe.managePipe(Pipe.java:92)
    at net.sourceforge.plantuml.Run.managePipe(Run.java:354)
    at net.sourceforge.plantuml.Run.main(Run.java:181)

SVGをPDFにすればそれまでなのですが、何か納得がいかないので、解決方法がないのか?と思い調べることにしました。 すると、公式ページに以下の記載がありました。そもそも公式が簡単なことではないと言ってました。

ダイアグラムを直接PDF形式で出力する機能の要望が以前からありました。 しかし残念ながら、これは簡単なことではなく、いくつかの外部ライブラリ(BatikとFOP)も必要でした。
これは、plantuml.jarが大きくなりすぎないようにして、他の製品との統合を容易にしたいという要望に反するものです。

ただ、解決方法も記載されていました。

使用方法
デフォルト状態ではPDFの生成はできません。これでも、大多数のユーザのニーズを満たしているでしょう。

PDF機能を使いたい場合、以下のファイルをダウンロードする必要があります:
avalon-framework-4.2.0.jar
batik-all-1.7.jar
commons-io-1.3.1.jar
commons-logging-1.0.4.jar
fop.jar
xml-apis-ext-1.3.04.jar
xmlgraphics-commons-1.4.jar

これらのファイルをBatikとFOPのウェブサイトからダウンロードします。
テストを目的として、これらのファイルをまとめたzipがこちらにあります。
これらのファイルは、plantuml.jarと同じフォルダに配置する必要があります。
以上の準備を行うと、コマンドラインで-tpdfフラグが使えるようになります:

java -jar plantuml.jar -tpdf diagram.txt
もしくは、Antタスクでformat="pdf"が使えます:

<!-- task definition -->
<taskdef name="plantuml" classname="net.sourceforge.plantuml.ant.PlantUmlTask" classpath="plantuml.jar" />
<!-- process diagram.txt file -->
<target name="images">
<plantuml format="pdf">
<fileset file="diagram.txt" />
</plantuml>
</target>

よし、これでいけると思った矢先、zipのリンクをクリックしても一向にDLが開始されませんでした。 Chrome(F12)のConsoleを見ると以下のエラーが出てました。どうやらzipのリンクがHTTPでHTTPSではないのでエラーとしたというものでした。

Mixed Content: The site at 'https://plantuml.com/' was loaded over a secure connection, but the file at 'http://beta.plantuml.net/batikAndFop.zip' was loaded over an insecure connection. This file should be served over HTTPS. See https://blog.chromium.org/2020/02/protecting-users-from-insecure.html for more details.

ここまで来るとどうしようもないので、諦めて他の方法を考えました。

InkscapeSVGをPDF指定でエクスポートする

Inkscapeについては個人サイトのTips記事でまとめているので参照してください。(色々できるのでおすすめです。調べた機能については追記していく予定です。)

PDFを作成するには、PlantUML->Inkscapeとソフトを跨ぐ必要がありますが、Inkscape自体はCLIで実行できます。

Windowsでは未確認ですが、Macではbrewコマンド, Linux(WSL2)ではaptコマンドでインストールできます。

Mac

formulae.brew.sh

brew install --cask inkscape

Linux

inkscape.org

sudo apt-get install inkscape

SVGをPDF指定でエクスポートする方法

以下のコマンドで変換できます。

inkscape input.svg -o output.pdf

その他指定

以下のWIkiにまとめられています。

wiki.inkscape.org

まとめ

以下について紹介しました。

  • PlantUMLのPDL出力エラーと解決方法
  • InkscapeによるSVGからPDFへのエクスポート

上記方法は一度SVGのエクスポートが必要であり手間はあります。また、Inkscapeを使わなくてもSVGからPDFに変換するやり方は他にもあると思うので、それぞれの手段で最終的にPDFを保存できれば良いのかなと思います。

以上です。