LaTeX の数式を PNG と SVG に変換する

似たような話題は検索すればいくらでも見つかる.が,イマイチなのが多い(ような気がする).ここでは日本語とかも出力できる方法を解説する.かなり力技なので環境依存性が強いかも.


環境:

用意するツール(コマンド):

  • platex (tex を dvi に変換できればなんでもOK)
  • dvipdfmx
  • gs (ghostscript)
  • pstoedit
  • sed
  • convert (imagemagick)

step 1. PDF をフォント埋め込みで生成できるようにする

とりあえず, platex などで, hoge.dvi が生成できているとする.この dvi から pdf を「フォント埋め込み」で生成する.(普通にできる人はこのステップを飛ばして下さい)

ポイントは,フォントマップファイル: pdffonts.map を用意すること.例えば,

pdffonts.map*1 :

rml    H   KozMinProVI-Regular.otf
rmlv   V   KozMinProVI-Regular.otf
gbm    H   KozGoProVI-Medium.otf
gbmv   V   KozGoProVI-Medium.otf

のような感じ.ただし KozMinProVI-Regular.otf とかを持っていることが前提.
パスが通っていないフォルダにこれらのファイルがある場合は, dvipdfmx を実行するフォルダにこれらのリンクを作成しておく必要があるようだ.
ほかのケースについては, [id:pyopyopyo:20080106] を参照.

次に,

dvipdfmx -f pdffonts.map -o hoge.pdf hoge.dvi

のようにして pdf を生成する. acroread とかで確認すると,フォントが埋め込まれていることが確認される.

step 2. SVG を生成する

gs を使って pdf をいったん eps に変換し,それから pstoedit で svg に変換するという流れ.

gs -q -r20480 -sDEVICE=epswrite -sOutputFile=hoge.eps \
  -dNOPAUSE -dBATCH -dSAFER -dEPSCrop -dEPSFitPage -dUseCropBox \
  hoge.pdf

このようなコマンドを実行すると hoge.eps が生成される(オプションの意味はちゃんと理解してません).次に,

pstoedit -f plot-svg -dt -ssp -sclip hoge.eps | \
  sed 's/<rect[^<>]\+id=\"background\"[^<>]*>//g' > hoge.svg

のようにして, hoge.svg に変換する.ここで sed を通しているのは, pstoedit の出力のままだと白い背景が残ってしまって邪魔だからだ.

FIXME:

  • ページサイズをぴったりにできない
  • 日本語の句読点(,.)が出力されない

step 3. PNG を生成する

gs で直接 pdf から png を生成し, convert でトリミングする.

gs -q -sDEVICE=pngalpha -sOutputFile=hoge.png -r150 \
  -dNOPAUSE -dBATCH -dSAFER -dEPSCrop -dGraphicsAlphaBits=4
  -dTextAlphaBits=4 -dMaxBitmap=50000000 hoge.pdf

これでとりあえず png が生成できる.解像度は -r150 で指定(大きい程画像がでかい).背景は透過. -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -dMaxBitmap=50000000 は,アンチエイリアス (antialiasing) のためのオプション.かなりきれいになる.
最後に,

convert -trim +repage hoge.png hoge.png

のようにしてトリミングすれば終り.


これは解像度 -r80 で作ったPNG.ブログに貼るために小さくしたが,実際はもう少し大きい方がいいかも.

まとめ

すべての作業を bash スクリプトでまとめておく(オプションとか作って使いやすくして下さい → LaTeX の数式を PNG と SVG に変換するスクリプト).

#!/bin/bash -x
ifile=latex-eq  # 入力ファイル (${ifile}.tex)
fontsmap=pdffonts.map  # フォントマップ
pngres=150  # PNG の解像度

error=1
if platex -halt-on-error ${ifile}.tex; then
  if platex -halt-on-error ${ifile}.tex; then
    if dvipdfmx -f ${fontsmap} -o ${ifile}.pdf ${ifile}.dvi; then
      error=0
    fi
  fi
fi

gs -q -r20480 -sDEVICE=epswrite -sOutputFile=${ifile}.eps -dNOPAUSE -dBATCH -dSAFER -dEPSCrop -dEPSFitPage -dUseCropBox ${ifile}.pdf

pstoedit -f plot-svg -dt -ssp -sclip ${ifile}.eps | \
  sed 's/<rect[^<>]\+id=\"background\"[^<>]*>//g' > ${ifile}.svg

gs -q -sDEVICE=pngalpha -sOutputFile=${ifile}.png -r${pngres} -dNOPAUSE -dBATCH -dSAFER -dEPSCrop -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -dMaxBitmap=50000000 ${ifile}.pdf
convert -trim +repage ${ifile}.png ${ifile}.png

*1:gbm,gbmvが間違っていたので修正した@Nov.12,2008.