Xy-picとdvisvgm


LaTeXで図式を書くのに、Xy-picというパッケージがある。このパッケージで書いた図式を、dvisvgmコマンドでSVG形式に変換しようという話。

大まかな流れ:

  1. Xy-picで作った図式を含むLaTeXソースをコンパイルしてDVIファイルを作る。
  2. DVIファイルをdvisvgmコマンドでSVG形式に変換する。

今回ハマったポイント(結論):

  • Xy-picにはPostScriptやPDFなどのバックエンド(ドライバー)を指定しよう。
  • dvisvgmに--no-fontsを指定することでSVGファイルの文字を正しく表示できるようになる。

以下、結論に至るまでの過程:

今回の実験に使うLaTeXソースは、以下のような何の変哲もないものにする。

\documentclass[preview=true]{standalone}
\usepackage[all]{xy}
\begin{document}
\[
\xymatrix{
& c \ar[ld]_f \ar[rd]^g \ar@{..>}[d] & \\
a & a\times b \ar[l]^{p_1} \ar[r]_{p_2} & b
}
\]
\end{document}

上のLaTeXソースを product.tex という名前で保存し、以下のようにコマンドを実行する。

$ latex product.tex
(略)
Output written on product.dvi (1 page, 2952 bytes).
Transcript written on product.log.
$ dvisvgm product.dvi
processing of PostScript specials is disabled (Ghostscript not found)
pre-processing DVI file (format 2)
processing page 1
  WARNING: 7 PostScript specials ignored. The resulting SVG might look wrong.
  page size: 91.3612pt x 45.201pt (32.1098mm x 15.8863mm)
  page written to product.svg
1 of 1 page converted in 0.276253 seconds

dvisvgmのところで、Ghostscriptが見つからないとかいう警告が出る。TeX LiveにGhostscriptって含まれてないのか?dvisvgm --helpによると、--libgsオプションによってGhostscriptの位置を指定してやればよさそうなので、MacPortsで入れたGhostscriptを指定してみる。

$ dvisvgm  --libgs=/opt/local/lib/libgs.dylib product.dvi
pre-processing DVI file (format 2)
processing page 1
  applying bounding box set by preview package (version 11.88)
  width=345pt, height=65.9166pt, depth=0pt
  page size: 345pt x 65.9166pt (121.254mm x 23.167mm)
  page written to product.svg
1 of 1 page converted in 0.346314 seconds

今度は警告が出ない。うまくいった。早速、できたSVGファイルをFirefoxで開いてみよう。

xypic-svg-1

…!??

文字化け…?

いや、文字化けはまだわかる(?)が、斜めの線が文字になっている!?

どうやら、Xy-picは、デフォルトでは斜めの線の描画にグリフを使うようだ。それが、フォントの指定がうまくいかないせいで化けてしまったのだろう。

(っていうか、Xy-picで描いた斜線がなんか不自然にカクカクしていたのはそういうことだったのかー!今更)

xypic-glyph-backend

Xy-picでバックエンドを指定しないで作った出力では、斜めの線が微妙にカクカクしている

TeXのDVIファイルで斜線を扱えないのかとかそういう話は筆者はよく知らないのだが、少なくとも、PostScriptやPDFでの出力を前提とすれば、本物の斜線を使えるはずだ。Xy-picで本物の斜線を使わせるには、バックエンドやドライバー(dvips, dvipdfm, pdftex)を指定してやれば良いらしい。この数年間Xy-picを使ってきたが、初めて知った。このあたりの話は、今回の件でxyrefer.pdf(末尾の参考リンクを参照)を読んでいるときに知ったが、改めてxyguide.pdfを読んだらそういう話もさらっと書いてあった。

さて、dvisvgmに渡す上で、どのバックエンド(PostScript, PDF, …)を使えばいいかだが、さっきGhostscriptも指定したことだし、多分PostScriptならなんかうまいこと扱ってくれるだろう!と思ったので、documentclassにdvipsを指定する。

\documentclass[dvips,preview=true]{standalone}
\usepackage[all]{xy}
\begin{document}
(以下同じ)

あるいは、\usepackageで指定したり、

\documentclass[preview=true]{standalone}
\usepackage[dvips,all]{xy}
\begin{document}
(以下同じ)

後から\xyoptionで指定することもできるようだ。

\documentclass[dvips,preview=true]{standalone}
\usepackage[all]{xy}
\xyoption{ps}
\xyoption{dvips}
\begin{document}
(以下同じ)

これをさっきと同様にコンパイルする。すると、

xypic-svg-2

…まあ、少なくとも、斜線は正常に表示されるようになった。あとはフォントだ。

適当にググった結果(&出力されたSVGファイルを調べた結果)、dvisvgmが出力するSVGファイルは、デフォルトではSVG Fontsという死んだテクノロジー(参考:MDNのSVG Fontsの記事)を使うらしい。dvisvgmでSVG Fontsを使わないようにするには、--no-fontsオプションを指定するらしい。

というわけで、

$ dvisvgm --libgs=/opt/local/lib/libgs.dylib --no-fonts product.dvi

によってSVGファイルを生成した結果。

xypic-svg-3

うん。美しい。しかし、文字がアウトライン化されて、ブラウザからコピペとかができなくなってしまった。つまり画像化だ。

こういう、文字の情報を失う「画像化」ではなく、ブラウザから文字のコピペができて、かつ見た目もちゃんとしているようなものを得る方法はあるのだろうか。冒険はまだ終わらない。(完)

参考リンク(Xy-picのマニュアル):

Xy-picとdvisvgm」への2件のフィードバック

  1. ピンバック: dvisvgmとSTIXフォント | 雑記帳

  2. ピンバック: dvisvgm 2.1.3 を試す | 雑記帳

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です