2024-06-08 ,

インポートとジェネレータ

el-easydraw(以下edraw)の最近の変更の中で比較的大きかったのはインポート機能でしょうか。

これは元々edrawが一部のSVGを正しく読み込むことが出来ないという問題を指摘されたことから開発に至った機能です。

元々edrawは膨大なSVG仕様の全てに対応する気はさらさら無く、edrawによって作成・出力したSVGのみが再編集可能です。edrawが出力したSVGには <g id="edraw-body">...</g> という形のグループ要素がありその中が唯一編集可能な領域になっています。idがedraw-bodyなグループ要素(つまりg#edraw-body)の中にはedrawが対応しているものしか入っていない前提で作られているため、無理矢理そこに何かを入れたとしても動作は保証されません(いや、まぁ、どのみち誰も何も保証しませんが)。とは言えその方は他のツールで作成したSVGを持ってきたかったらしく、そのための仕組みとして最終的にインポート機能を作ることになったわけです。

特にedraw-modeを使うと任意のSVGファイル(を開いたバッファ)で作図エディタを起動することが可能だったのですが、そんなことをしても当然そのSVGの中にあった図形を編集できるわけも無く、せいぜいその上に新しい図形を乗せていくことくらいしか出来ませんでした。

現在では、他で作った(g#edraw-bodyが存在しない)SVGでM-x edraw-modeを実行するとエラーが出て、諦めるか自己責任で M-x edraw-convert-buffer-to-edraw-svg-xml を実行して変換するよう勧めるメッセージが表示されます。実際に edraw-convert-buffer-to-edraw-svg-xml を使用すると、バッファ内のSVGがedrawが扱えそうな形に変換されます。対応していない要素は除去されたり警告が出たりします。そして再度 M-x edraw-mode を実行すると、運が良ければ編集できることでしょう。

作図エディタの中からでもメインメニューの「ドキュメント」→「ファイルからインポート...」を選択して任意のSVGファイルを選べばそれを変換・取りこむことができます。

試しにInkscapeで作成したSVGを読み込んでみましたが、まぁ、思ったよりは取りこめる感じでした。他にもGraphvizで作成したSVGを取りこんだりも出来ました(ただしグラフ構造を手軽に再編集できるようなものではありません)。その方はdvisvgmの出力を取りこみたかったようですが、それも最終的にはうまく取りこめるようになりました。

dvisvgmを使用すればlatexで生成したものをSVGに変換できます。つまり、例えば数式をSVGに変換することが可能です。そしてそれを取りこめるようになったわけです。

しかしこのままでは数式を図の中に取りこむには手間がかかりすぎます。まずlatexのソースを書いて、latexでdviを作成し、それをdvisvgmでsvgへ変換し、edrawでインポートしなければなりません。もっと効率よく出来る仕組みが必要です。

私も数式を図に取りこめたら良いだろうなと思ったことはあったので、そのための仕組みを作ることにしました。

「数式ツール」のようなものを作っても良かったのですが、それでは直接的すぎて面白くありません。そこで考えたのが「ジェネレータ」です。

ジェネレータは何らかの設定から図形を生成するような(図形として配置可能な)オブジェクトです。ジェネレータツール(生成ツール)で配置できます。

ジェネレータにはプロパティとして生成の元(ソース)となるような情報を指定出来ます。まず第一に生成タイプがあり、今のところlatexかgridが指定出来ます。次に生成ソースを指定するプロパティがあり、タイプがlatexの時はそこにLaTeXのソースコードを記述できます。最後に生成オプションがあり、これはタイプによって異なる追加のプロパティを色々設定できます。

そして生成ボタンを押すとそれらのソース情報を元に図形が生成されるという寸法です。latexの場合は、preamble部分(カスタマイズ変数で変更可能)などと合成されてlatex、dvisvgmコマンドが呼び出され、生成されたSVGがedraw用に変換されてジェネレータの子要素として挿入されます(もちろんlatexとdvisvgmが必要です。私はTeX Liveでインストールしましたが、MSYS2にPATHが通っていると色々ハマるのでご注意を)。

latexジェネレータで数式を生成したところ
図1: latexジェネレータで数式を生成したところ

生成タイプのgridは格子状の線を生成するものです。生成タイプがlatexだけでは格好が付かないので適当に作ってみました。線が太くて気に入らないという方は位置を0.5ピクセルずらしてみて下さい。「これもうソースコード要らないじゃん!」ということが発覚してちょっと後悔しています。

数式をSVGに入れるならMathMLを使うという手もあります。実際latexからMathMLに変換してforeignObject要素として取りこむような生成タイプを作ることもできるでしょう。しかし一番のネックはlibrsvgが対応していないのでEmacsの中で表示されないことでしょうね。

latexの中で(tikzで)グラフを生成することもできるみたいです。

latexの図を生成したところ
図2: latexの図を生成したところ

これらの機能で簡単に複雑な図を表現できるようになったのは良いところですが、反面データサイズが膨らみがちなことが困りそうなところでしょうか。特に [[edraw:data= 形式のリンクはデータがOrgファイル内(特に一行に)埋め込まれるので、あまり大きいと何か問題を引き起こすかもしれません。単純にインライン画像をoffにしたときに見栄えが悪いというのもあります(今更ですが)。そういう場合はインライン画像を右クリックして [[edraw:file= 形式へ変換して下さい。