はじめに
Emacsを使って自分が考えていることを図で表現することについて,
plantumlを利用できないかと考えています。
ネットでplantumlに関する日本語情報を検索すると,
stdlibに関しては,ネットワーク構成図を描くような情報ばかりで,
汎用的な図の描画に利用する方法についてはあまり情報がないような気がします。
そこで,色々なアイコンが利用可能なGoogle Material Design
を利用できないかと色々調べてみました。
stdlibのgithubレポジトリはplantuml-stdlibです。
Material Designのアイコンはバージョン2系と
バージョン7系があるようなのですが,
バージョン7系について自分が利用しているEmacsで利用する方法について試してみました。
アイコンの検索は次のサイトが有効かと思います。
Material Design
Emacsのplantuml-modeの設定
Emacsでplantumlを利用するには,plantuml-modeをインストールするのがいいかと思います。
インストールする方法は省略します。
下の設定は,javaが実行できる(PATHが通っているところにjavaコマンドがある)前提での設定です。
init.el内相当のところに記入する感じです。
(require 'plantuml-mode)
(setq plantuml-jar-path "/home/ujimushi/.local/opt/plantuml.jar")
(setq plantuml-output-type "png")
(setq plantuml-default-exec-mode 'jar)
(setq plantuml-indent-level 2)
(setenv "PLANTUML_LIMIT_SIZE" "8192")
Emacsのauto-completeの設定
今ではもう化石と化しているEmacs補完パッケージauto-completeですが,
plantumlのようにわりと単純な補完だけでいいケースでは,
自分で制御しやすいauto-completeもわりと使い勝手がいい面もあります。
今回は今さらですが,auto-completeで編集環境を構築してみます。
auto-completeの辞書登録機能
元々,plantuml-modeはcapfやcompany-modeでのキーワード補完が可能なのですが,
auto-completeはcapf対応がそれほど良くないので,
個別に辞書に登録することにします。
Emacsのauto-completeでは,ac-dictionary-directoriesで設定されているフォルダに
モード名のファイルを作成してキーワード辞書を登録しておくと,
そのモード名に登録したキーワードを補完するようになります。
plantumlのキーワードの登録
Emacs上で*scratch*バッファ上で,
(print plantuml-kwdList)
と入力してctrl+jとすると,plantumlのキーワードのリストが表示されます。
2つ目の(とそれに対になる)の間をテキストファイルに保存します。
その後,そのテキストファイルに対して,Julia言語で次のような処理をして,
一行ーキーワードのテキストファイルを作成します。
open("plantuml-dict-example.txt", "w") do io
kwds = map(
replace(read("kwdlist.txt", String), " t " => "\n") |>
IOBuffer |> readlines
) do x
strip(x, ['\"'])
end
for s in kwds
println(io, "$s")
end
end
auto-completeだと直接Material Designのinclude補完は難しいので,
githubのmaterial7.4.47のフォルダ構造と同じ構造のダミーファイルを作成,
そのフォルダを自分がplantumlのファイルを置いているフォルダ内に
シンボリックリンクを作成して,auto-completeのファイルパスの補完機能を使って
補完させようと考えました。
using JSON
function make_plantuml_stdlib_materail7_dummy_files(srcdir, destdir)
categories = open(joinpath(srcdir, "all.json"), "r") do io
JSON.parse(io)
end
isdir(destdir) || mkdir(destdir)
mydict = Dict()
for category in categories
files = readdir(joinpath(srcdir, category))
mydict[category] = map(x -> first(splitext(x)), filter(x -> endswith(x, ".puml"), files))
end
for (key, values) in mydict
module_path = joinpath(destdir, key)
isdir(module_path) || mkdir(module_path)
for v in values
touch(joinpath(module_path, v))
end
end
nothing
end
の後,
plantuml-stdlibのレポジトリからソースをダウンロードして展開してから,
rootfolder = "/home/ujimushi/Downloads/plantuml-stdlib-master/stdlib/material7.4.47"
destfolder = "material7.4.47"
make_plantuml_stdlib_materail7_dummy_files(rootfolder, destfolder)
ぐらいでダミーのファイルを作成してから,作業フォルダ内から生成したダミーファイルを格納しているフォルダにシンボリックリンクを貼るといいでしょう。
最後に,スプライトのキーワードの登録を考えてみます。先ほどplantumlのstdlibのgithubのアーカイブのフォルダ
構成から生成をしてみます。次のような関数を作成します。
using JSON
function write_stdlib_mdi7_kwdfile(srcdir, destfile)
categories = open(joinpath(srcdir, "all.json"), "r") do io
JSON.parse(io)
end
tmpdict = Dict()
for category in categories
files = readdir(joinpath(rootfolder, category))
tmpdict[category] = map(x -> first(splitext(x)), filter(x -> endswith(x, ".puml"), files))
end
open(destfile, "w") do io
for (_, values) in tmpdict
for v in values
if v != "all"
println(io, "<\$mdi$(uppercasefirst(v))>")
end
end
end
end
end
から,
rootfolder = "/home/ujimushi/Downloads/plantuml-stdlib-master/stdlib/material7.4.47"
destfile = "plantuml-icon-keywords.txt"
make_plantuml_stdlib_materail7_dummy_files(rootfolder, destfolder)
を実行すると,できたテキストファイルの中身は次のような感じです。
<$mdiTooltipAccount>
<$mdiTooltipCellphone>
<$mdiTooltipCheck>
<$mdiTooltipCheckOutline>
<$mdiTooltipEdit>
<$mdiTooltipEditOutline>
<$mdiTooltipImage>
<$mdiTooltipImageOutline>
<$mdiTooltipMinus>
<$mdiTooltipMinusOutline>
<$mdiTooltipOutline>
<$mdiTooltipPlus>
...
これを先ほどのkwdlist.txtと結合して,plantuml-modeという拡張子なしのテキストファイルを用意しておきます。
auto-completeの設定
最後にauto-completeの設定をします。
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict")
(ac-config-default)
(add-hook 'auto-complete-mode-hook
(lambda ()
(setq ac-sources (remove 'ac-source-abbrev ac-sources))))
(setq ac-disable-faces nil)
(add-hook 'plantuml-mode-hook
(function (lambda ()
(setq ac-sources
'(ac-source-dictionary ac-source-filename ac-source-words-in-same-mode-buffers)))))
(add-to-list 'ac-modes 'plantuml-mode)
先ほど作成したplantuml-modeファイルを~/.emacs.d/ac-dictフォルダの中に保存します。
そして,作業用フォルダ内に先ほど作成したダミーファイル群のフォルダをターゲットに
シンボリックリンクを作成すると環境作成は完了です。
使用例とか
基本的にはplantumlのスプライトの利用方法を見ていただければと思います。
後は,配置図とかのヘルプが参考になるでしょうか。
ちょっとした利用例です。
!includeのところは個別にincludeするとコンパイルの時間も短くてすむかと思います。
@startuml
!include <material7/all>
card 自宅 [
自宅
<$mdiHome,color=orange>
]
card 会社 [
会社
<$mdiOfficeBuilding,color=blue>
]
card 駅1 [
家の最寄り駅
<$mdiTrain,color=red>
]
card 駅2 [
会社の最寄り駅
<$mdiTrain,color=green>
]
自宅 -> 駅1 : <$mdiBike,scale=0.4>自転車
駅1 -> 駅2 : <$mdiTrain,scale=0.4>電車
駅2 -> 会社 : <$mdiWalk,scale=0.4>徒歩
@enduml

まとめ
とりあえずEmacsでplantumlを利用しやすいように環境を構築してみました。
といっても,普通はcompany-mode等でセットアップすると思うので,
非常に古めかしい環境での構築となりました。(単に日本語の補完パッケージとの兼ね合いです。)
ただ,図を描くのはまだまだ勉強中でこれからといった感じです。