image/figure ディレクティブのオプションまとめ

最近、Sphinx や docutils の blockdiag ディレクティブのオプションを見なおし、
reST 標準の image/figure ディレクティブと同じオプションを受け取るようにしました。
:width: や :height:、:scale: などのオプションが使えるようになっています。

その際にみつけた image ディレクティブのオプションの分かりづらい動作についてまとめてみます。

:width:, :height:, :scale: の関係

:width:, :height: そして :scale: は 3つでひとそろいのオプション群です。
ほとんどのケースではどれかひとつだけを使うようですが、
これらのオプションは組み合わせ使うととても分かりづらい動きをします。

:width: のみ 横幅を指定。縦幅はアスペクト比から算出。
:height: のみ 縦幅を指定。横幅はアスペクト比から算出。
:scale: のみ 拡大率を指定。縦幅、縦幅は元画像の大きさから計算。
:width: + :height: 縦幅、横幅を指定。アスペクト比は維持されない。
:width: + :scale: 横幅は width 値 x scale (拡大率)となる。縦幅はアスペクト比から算出。
:height: + :scale: 縦幅は height 値 x scale (拡大率)となる。横幅はアスペクト比から算出。
:width: + :height: + :scale: width 値 x scale、height 値 x scale の大きさになる。アスペクト比は維持されない。

例えば

.. image:: logo.png
   :width: 200px
   :scale: 50%

という指定では横幅は 200px * 50% = 100px となり、縦幅はアスペクト比から算出されます。

自分でも実装してみたものの、組み合わせてどう使うのかイマイチ分からないですね。

HTML と LaTeX で異なる :width: オプションの指定の仕方

Sphinx は "one source, multiple output format" みたいなところがあるので、
reST で書いておけばいろんなフォーマットに使えると考えがちですが、
:width: オプションはその例外のひとつです。

例えば

.. image:: logo.png
   :width: 200px

と指定した場合、HTML では 200px に縮小(拡大)して画像が表示されますが、
LaTeX では原寸のまま画像が埋め込まれます。

これは HTML と LaTeX で長さの単位が異なるために起きるもので、
LaTeX では px での width, height 指定は無視されます。
LaTeX では width の単位として cm や pt、em を利用します*1が、こちらは HTML でも利用できます。

HTML LaTeX
(単位なし) ×
px ×
% ×
pt
cm
in
em

というわけで、:width: や :height: を指定するときは単位を意識しておくと幸せになれるかもしれません。

訂正 (7/11 11:55): LaTeX では % 指定は無効でした。

image と figure で align の取る値が異なる

image ディレクティブでは left, center, right, top, middle, bottom の 6種類が指定できるのに対して、
figure ディレクティブでは left, center, right の 3種類だけ受け付けています。

:figwidth: オプションの image の謎

figure ディレクティブには :figwidth: オプションというオプションがあります。
figure ブロックの幅を指定するためのオプションです*2

この :figwidth: オプションは :width: オプションと同様に幅をしていするのですが、
特別なオプションとして image を指定することができます。

この リファレンスでは次のように説明されています。

A special value of "image" is allowed, in which case the included image's actual width is used (requires the Python Imaging Library).

画像の幅を計測して、その値を使うという指定です。

このオプションはあまり使われていないのか、実際に呼び出してみるとうまく動かないというバグが有ります(trunk では直っています)。

しかし、このオプション "image's actual width" と書いてあるとおり、
画像の実寸を使っているので :width: オプションや :scale: オプションと組み合わせると
やたらと大きい(小さい) figure ブロックができるため、どう使うと良いのかというのが難しい指定です。

このオプション、どういう時に使うと便利なんですかねえ。

まとめ

使ったことのないオプションが多い割に、互換性を保とうとすると面倒なことが多くて辛いです。

*1:em は 幅の単位なので、height には指定できません。詳しくは TeX の記述を調べてみてください。

*2:figure ブロックについては リファレンス の図示がわかりやすいです