DOSEIの日記

技術メモ+日常ログ

HTML にスケーラブルな数式を SVG で埋め込む

Wikipedia のエンジンのように数式を PNG で埋めるのが現状一番実用的。しかし、ラスタ画像なので拡大縮小や印刷に耐えない。 MathML はレンダラがいまいちなものしかない。

つい最近、 dvisvgm がフォントのアウトライン化に対応したので (0.7.1 2009-03-09 版)、早速試す。

なお、以下の記事は Firefox 3 でしかちゃんとうごかないっぽい(ぉ

概要

dvisvgm に -n オプションをつけると、フォントをアウトラインパスに変換してくれる。デフォルトではバウンディングボックスが tight (矩形包) になる。
様々な数式を一定のベースラインにそろえて表示させるために、"x" だけの出力からx-height を割り出して、 SVG を編集し、ベースラインより下が 1ex 上が 3ex になるように変更する。

で、その SVGCSS で相対配置し、高さを 4ex に、下端を −1ex 移動させる。

HTML ソース
<object class="eq" data="equation.svg" type="image/svg+xml"></object>
CSS ソース
object.eq
{
  display: inline-block;
  position: relative;
  height: 4ex;
  bottom: -1ex;
}

作業例

sh スクリプト

#!/bin/bash

top="50.0833" # ex top - 2* ex height
height="17.2222" # 4 * ex height

if [ $# -ne 2 ]
then
  echo "Usage: $0 filename 'eqation'"
  exit 1
fi

echo -E \
  '\documentclass{article}' \
  '\usepackage{bm}' \
  '\pagestyle{empty}' \
  '\begin{document}' \
  "\$$2\$" \
  '\end{document}' > _$1.tex

latex --halt-on-error _$1
dvisvgm -n _$1

sed \
  -e "s/\(viewBox\='[0-9.]\+\)\ [0-9.]\+\ \([0-9.]\+\)\ [0-9.]\+/\1 ${top} \2 ${height}/" \
  -e "s/svg\ height\='[0-9.]\+'/svg height='${height}'/"  \
  _$1.svg > $1.svg

echo "$1.svg"

rm _$1.{log,dvi,tex,aux}