remarkdown を巡る冒険 (原題: remarkdown versus Sphinx)
docutils はある形式の文書を別の形式に変換するフレームワークです。
このフレームワークを利用して rst2html や rst2latex などが提供されています。
しかし、docutils が標準で対応している入力形式は reST 形式に限られているので、
実際には reST 変換用のライブラリとして捉えられていました。
markdown 黄金時代
docutils や Sphinx の周囲では reST を中心としてドキュメントが記述されていますが、
2014年現在、軽量マークアップ言語の主流の座は markdown であると言っても過言ではないでしょう。
flavor が乱立していたり、拡張性に乏しかったり、困ったら HTML で書き下してあったりと、
記述能力が十分とはいえない markdown ですが、github を初めてとして様々な場所で用いられています。
4月1日はすでに過ぎたというのに Internet Draft になっているほどの人気ぶりです。
Sphinx に興味を持った人も、Sphinx と markdown の組み合わせを実現するために様々な試行錯誤を繰り返しています。
remarkdown の到来
そんな流れの中、remarkdown という docutils 拡張が発見されます。
remarkdown は docutils の拡張として動作し、reST のかわりに markdown を docutils の入力に使うことができます。
docutils は html や latex, Open Document (.odt) などの出力に対応しているので、
組み合わせることで markdown から様々なフォーマットへ出力することができるようになります。
remarkdown のインストール
remarkdown は PyPI にパッケージがアップロードされていないため、簡単にインストールする方法がありません。
そのため、次の方法でインストールを行います。
まず、pip を用いて github のアーカイブ経由でパッケージをインストールします。
$ pip install https://github.com/sgenoud/remarkdown/archive/master.zip
なお、setup.py に不備があるので*1、ファイルをひとつ手動でダウンロードする必要があります(パスは各自適当な場所に読み替えてください)。
$ curl -LO https://raw.githubusercontent.com/sgenoud/remarkdown/master/remarkdown/markdown.parsley $ mv markdown.parslay lib/python2.7/site-packages/remarkdown
remarkdown を使ってみる
remarkdown をインストールすると、一緒に md2html, md2latex, md2xml などのコマンドも一緒にインストールされます。
これらのスクリプトは markdown を入力として docutils を呼び出しています。
$ md2html test.md > test.html
Sphinx meets remarkdown
さて、ここからが本題です。
docutils と remarkdown の組み合わせができることを確認したところで、
今度は Sphinx と remarkdown を組み合わせてみることにします。
Sphinx を書き換える
Sphinx は docutils を利用して文書の変換を行っているのですが、
内部では reST 以外を想定していない作りになっています。
具体的には sphinx/environment.py の BuildEnvironment#read_doc() の中にこんな記述があります。
pub = Publisher(reader=SphinxStandaloneReader(), writer=SphinxDummyWriter(), source_class=SphinxSourceClass, destination_class=NullOutput) pub.set_components(None, 'restructuredtext', None)
Publisher のコンポーネントとして 'restructuredtext' を固定値で指定していますね。
入力フォーマット(パーサ)もここで決定しているので、markdown を入力として利用するには Sphinx を書き換える必要があります。
また、remarkdown は section ノードに必要な属性(ids, names)を正しくセットしていないので、
Sphinx を書き換える際についでに補正します。
Sphinx を書き換える、と言っても本体のソースコードを書き換えてしまうと、他の環境で使えなくなってしまうので、
conf.py の中から次のように書き換えを行います。
from docutils.core import Publisher class MarkdownPublisher(Publisher): def __init__(self, *args, **kwargs): Publisher.__init__(self, *args, **kwargs) # replace parser FORCELY from remarkdown.parser import MarkdownParser self.reader.parser = MarkdownParser() def publish(self): Publisher.publish(self) # set names and ids attribute to section node from docutils import nodes for section in self.document.traverse(nodes.section): titlenode = section[0] name = nodes.fully_normalize_name(titlenode.astext()) section['names'].append(name) self.document.note_implicit_target(section, section) # replace Publisher import sphinx.environment sphinx.environment.Publisher = MarkdownPublisher
また、conf.py を編集する際、ソースの拡張子の設定もついでに書き換えておくとよいでしょう。
source_suffix = '.md'
まとめ
remarkdown を使って docutils を拡張したり、Sphinx を拡張したりしてみました。
実験する範囲ではそれっぽく動くものの、ちゃんとドキュメントをつくり上げることを考えると
乗り越え無くてはならない課題はまだいくつか残っているようです。
僕は markdown があまり好きではないのでここで筆を置きますが、
興味がある人は続きにトライしてみてはいかがでしょうか。
*1:記事で紹介している markdown.parsley が入らない問題の他、entry_points がうまく定義出来ていないおかげで setup.py install を実行しても md2* コマンド群がインストールされない問題などがあります。
flake8 の NOQA コメントは無敵ではない
flake8 のドキュメントを読むと、
警告を抑止する NOQA コメントについて
lines that contain a # noqa comment at the end will not issue warnings.
(訳: 末尾に # noqa というコメントがある行は警告されません)
と説明されています。
しかし、実際にはすべての警告を抑止できるわけではありません。
例えば、インデントのスペースの数を数える警告(E111)は NOQA コメントの効果がありません。
$ cat test.py name = 'Taro' if name: print 'Hello,', name # noqa else: print 'Hello world' # noqa $ flake8 test.py test.py:3:3: E111 indentation is not a multiple of four test.py:5:3: E111 indentation is not a multiple of four
では、具体的にどういったケースで NOQA コメントが有効で、どういうケースには効かないのでしょうか。
答えは pep8 パッケージのリファレンスにありました*1。
Error codesの備考のところに次のように記載があります。
(^) These checks can be disabled at the line level using the # noqa special comment. This possibility should be reserved for special cases.
(訳: (^) マークのついている警告は # noqa スペシャルコメントにより行レベルでのチェックが無効になります。この機能は特殊なケースのために予約されています。)
エラーコード一覧を見ていくと (^) マークが付いている項目は pep8 が検出する警告の半分以下です。
じゃあどうするのさ
PEP8 守れ。以上。
困っていること
こういうデータを記述した時に、見やすさを維持しつつ flake8 に怒られない方法を知りたいです。
data = [('Tokyo', 5), # noqa ('Kanagawa', 10), # noqa ('Saitama', 8), # noqa ('India', 20)] # noqa
まとめ
NOQA コメントが万能じゃないことがわかりました。
オチはない。
*1:flake8 は pep8 パッケージを利用して pep8 のチェックをしています
Re: Re: SphinxのLaTeXのフォーマットをいじる
先日、Re: SphinxのLaTeXのフォーマットをいじる の記事を書いた直後に、
sphinx-users ML に独自のclsファイルを使用する方法がポストされました。
前回の記事では conf.py でプリアンブル部にゴリゴリ定義を突っ込んでいましたが、
- Python の文字列として記述するため、エスケープを気にする必要がある
- ファイル内にPython のコードと LaTeX マクロがミックスされるため、読み書きしづらい
- エディタのサポートが得られない
などの問題があるので、今回はこの「独自の cls ファイルを使用する」方法を使ってみることにします。
自分だけの最強の cls を作る
とは言え、いちからドキュメントクラスを書き下すことは難しいので、
既存のドキュメントクラスをベースにカスタマイズしていくことにします。
まずは jsarticle をベースにすることにします。
これまでは conf.py の latex_docclass と latex_documents を使ってクラスを選択していましたが、
独自に cls ファイルを定義する場合は \LoadClass マクロを使います。
\LoadClass{jsarticle}
例えば、行間を広げるようなドキュメントクラスを作ってみます。
次の内容のファイルを myjsarticle.cls というファイル名で保存します。
\LoadClass{jsarticle} \renewcommand{\baselinestretch}{2.0}
そして、conf.py に次のように記述します。
latex_additional_files = ['myjsarticle.cls'] latex_documents = [ ('index', 'test.tex', u'test Documentation', u'test', 'myjsarticle'), ]
sphinxhowto, sphinxmanual をベースにする
前回の記事では sphinxhowto と jsarticle を組み合わせて、必要な箇所だけ書き換えるようにしていたので
今度は sphinxhowto をベースにしてみましょう。
sphinxhowto (sphinxmanual) はちょっと変わった形をしたドキュメントクラスです。
- ベースになるのは article や manual などの基本のドキュメントクラス
- ベースのドキュメントクラスの定義を一部差し替えている
- ベースのドキュメントクラスは差し替えしやすいよう、\sphinxdocclass という変数名経由で指定
そのため、sphinxhowto (sphinxmanual) を \LoadClass する前に \sphinxdocclass という変数を定義します*1。
今回は jsarticle を指定します。
\def\sphinxdocclass{jsarticle} \LoadClass{sphinxhowto} \renewcommand{\baselinestretch}{2.0}
そして、次に conf.py を書き換えます。
latex_additional_files = ['myjsarticle.cls'] latex_documents = [ ('index', 'test.tex', u'test Documentation', u'test', 'myjsarticle'), ]
まとめ
pandoc + sphinx + transifex で既存ドキュメントの翻訳を行う
この間の Sphinx+翻訳 Hack-a-thon で話題に上がった件について調査してみた。
お題は以下のとおり。
- 元の文書は markdown で記述されている
- Sphinx を使って翻訳してみようと思っている
- 元の文書が更新された時に差分管理できるとよい
その場で出た案はタイトルの通りで、
- pandoc で reST 形式に変換して
- Sphinx を使って gettext 化して
- sphinx-intl を使って transifex にアップロードして
- transifex で翻訳をすると良さそう
というもの。
gettext 化を挟むことで、翻訳しやすく、また原文の変化を追いかけやすいそうな。
というわけで、実際に試してみました。
環境を作る
お題は redis-doc。
まずはワークスペースを作る。
$ mkdir redis-doc $ cd redis-doc $ git init $ virtualenv . $ . bin/activate $ pip install --pre sphinx sphinx-intl transifex-client $ pip freeze > requirements.txt $ rehash $ git submodule add https://github.com/antirez/redis-doc
virutalenv で環境を作って、その中に Sphinx, sphinx-intl, transifex-client を入れてます*1。
そして、翻訳対象の文書を git の submodule として管理します。
Sphinx 環境を作る
つづいて Sphinx 環境を作ります。
translated ディレクトリ以下にプロジェクトを作ります。
$ sphinx-quickstart translated $ vi translated/source/conf.py language = 'ja' locale_dirs = ['locale/'] gettext_compact = False $ vi Makefile html: tx pull -l ja sphinx-intl build --pot-dir build/locale --locale-dir source/locale $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html $ cat > .gitignore bin/ include/ lib/ translated/build ^D $ git add . $ git commit -m 'Initial commit'
conf.py では language, locale_dirs, gettext_compact の設定をしています。翻訳する上で必要最低限の設定です*2。
また、Makefile の html ターゲットには tx pull と sphinx-intl build の実行を追加しています。
make html する際に transifex から最新の翻訳カタログを取ってくるようにするものです。
しばらく時間を開けるとコマンドを忘れてしまいがちなので、忘れないように記述を追加しておきます。
pandoc, transifex を使うための準備
続いて transifex 上に(アカウントと)プロジェクトを作成します。
サイトにアクセスすると大体わかると思うので説明は省略します。
そして、transifex-client(txコマンド)を使って transifex にアップロードする準備をします。
$ cd translated $ tx init $ echo 'type = PO' >> .tx/config $ cd ..
transifex ディレクトリにて tx init を実行して、設定ファイルを生成しておきます。
また、0.11系では .tx/config ファイルに type オプションが指定されていないので、書き加えておきます。
最後に markdown ファイルを pandoc で reST に変換して、transifex にアップロードするためのスクリプトを用意します。
#!/bin/bash TRANSIFEX_PROJECT_NAME=redis-doc mkdir -p translated/source/commands mkdir -p translated/source/topics cd redis-doc find . -name "*.md" -print0 | while read -r -d '' md; do CONVERTED="../translated/source/${md%.*}.rst" echo -n "Translating $md ... " if [ "$md" -nt "$CONVERTED" ]; then pandoc "$md" -o "$CONVERTED" touch -r "$CONVERTED" "$md" echo "done." else echo "skipped." fi done find . \( -name "*.jpg" -or -name "*.png" -or -name "*.gif" \) -print0 | while read -r -d '' img; do COPIED="../translated/source/$img" echo -n "Copying $img ... " if [ "$img" -nt "$COPIED" ]; then cp -a "$img" "$COPIED" echo "done." else echo "skipped." fi done cd ../translated make html sphinx-intl update --locale-dir source/locale --pot-dir build/locale sphinx-intl update-txconfig-resources --transifex-project-name=$TRANSIFEX_PROJECT_NAME --locale-dir source/locale --pot-dir build/locale tx push -s
このスクリプトを実行すると、
- pandoc を使って markdown ファイルを reST 形式に変換して translated/ ディレクトリに配置
- 画像類も適当にコピー
- Sphinx を使って gettext 化を実施
- sphinx-intl を使ってリソース登録
- transifex-client (txコマンド) を使って、翻訳カタログを transifex に転送
という一連の手順を実行します。
transifex で翻訳する
ひたすら翻訳してください。
HTML に変換する
transifex で翻訳が一息ついたら HTML に変換してみましょう。
変換する前に、目次となる index.rst を作っておきます。:glob: オプションを使って簡易的に並べています。
Redis Documentation (Japanese) =============================== .. toctree:: :glob: README topics/* commands/*
準備段階で Makefile をいじっているので make html を実行するだけで ok です。
$ cd translated
$ make html
元の文章が新しくなった場合は submodule を更新し、スクリプトを再実行すれば ok です。
この方法の問題点
この方法を試したところ、いくつか問題がありました。
- pandoc で適切に変換できない文章がある
- HTML から変換する際など、うまく変換できないことがありました
- redis-doc では見出しのないファイルがあるため、HTML に変換するときに toctree に含まれないという問題がありました
- sphinx-intl はファイル名に空白を含んでいるとうまく扱えない
- あとで pull request 送ります…
Re: SphinxのLaTeXのフォーマットをいじる
卒論とか修論は TeX で書いていた割には、TeX マクロが苦手な @tk0miya です。
先輩から秘伝のタレ的?なスタイルファイルを頂いたのでそれで済ませてました。
Sphinx で PDF 出力するときは TeX を介して出力することが多いのですが、
未だに TeX マクロをちゃんと理解していないのでまったくいじらず、素のままで使っていました。
そんな折、
SphinxのLaTeXのフォーマットをいじる という記事を見かけました。
この記事では Sphinx 本体や付属のマクロをいじっているのですが、Sphinx は設定でアプローチできるようになっているので、
同じことを conf.py の記述だけで実現してみようと思います。
用紙サイズを a4 に変更する
latex_elements['papersize'] 経由で変更できます。
latex_elements = { 'papersize': 'a4paper', }
latex_paper_size という変数もあるので、こっちで指定してもよいみたい。こっちは page と size のあいだにアンダースコアが入る。
その場合は paper を付けずに指定する模様。
latex_paper_size = 'a4'
article クラスを利用する
latex_documents の末尾の要素を書き換えます。デフォルトでは report 系を意味する 'howto' が指定されています。
latex_documents = [ ('index', 'test.tex', u'test Documentation', u'test', 'howto'), ]
行間を狭くする
BEGIN_DOC の内容はいじれませんが、マクロの差し替えをするだけであれば latex_elements['preamble'] を使います。
latex_elements = { 'preamble': ''' \\renewcommand{\\baselinestretch}{0.8} ''' }
default_elements を書き換える
conf.py の latex_elements を設定しておくと、上書きされます。
記事と同じ内容に揃えるのであればこうすると良いみたい。
latex_elements = { 'papersize': 'a4paper', 'fontpkg': '', 'fncychap': '', }
ちなみに、fncychap は language = 'ja' の設定をしていると、自動的に空になるようです。
TeX のドキュメントクラスに jsarticle, jsbook を使いたい
これは LaTeX 経由での PDF 出力の設定でもお馴染みですね。latex_docclass を定義します。
普段は jsbook しか設定していませんが、ちゃんと jsarticle も使えるようにしておきます。
latex_docclass = { 'howto': 'jsarticle', 'manual': 'jsbook', }
ページ番号を表示する
これもプリアンブル部に定義すると良いので、latex_elements['preamble'] に書き加えます。
latex_elements = { 'preamble': ''' \\pagestyle{plain} \\thispagestyle{plain} ''' }
ここでは \thispagestyle{empty} を無効にするために、再度 \thispagestyle を呼んでページスタイルを上書きしています。
ページ番号の深さを変更する
これもやっぱりプリアンブル部です。
latex_elements = { 'preamble': ''' \\setcounter{secnumdepth}{3} ''' }
タイトルを変更する
ちょっと量が多いので悩んだのですが、これもプリアンブル部に突っ込みます。
TeX のエラーで悩まされたので \makeatletter, \makeatother で囲んで調整しています。
latex_elements = { 'preamble': ''' \\makeatletter \\renewcommand{\maketitle}{ \\ifsphinxpdfoutput \\begingroup \\def\\\\{, } \\def\\and{and } \\pdfinfo{ /Author (\\@author) /Title (\\@title) } \\endgroup \\fi \\begin{center} \\sphinxlogo% {\\Large \\@title} \\par \\end{center} \\begin{flushright} \\@date \\hspace{3zw} \\@author \\par \\py@authoraddress \\par \\end{flushright} \\@thanks \\setcounter{footnote}{0} \\let\\thanks\\relax\\let\\maketitle\\relax } \\makeatother ''' }
目次を変更する
これもやっぱりプリアンブル部。
latex_elements = { 'preamble': ''' \\let\\pyOldTableofcontents=\\tableofcontents \\renewcommand{\\tableofcontents}{ \\begingroup \\parskip = 0mm \\pyOldTableofcontents \\endgroup \\vspace{12pt} } ''' }
元の定義だと \py@OldTableofcontents って変数名なんだけど、なぜかエラーになったので @ を取ってしまいました。
原因がよく分からないけど、動いたので深追いせず。
まとめ
プリアンブル部をいじりまくってるので、最終的にどうなったのかを貼っつけて終わりにします。
language = 'ja' latex_elements = { 'papersize': 'a4paper', 'fontpkg': '', 'fncychap': '', 'preamble': ''' \\renewcommand{\\baselinestretch}{0.8} \\pagestyle{plain} \\thispagestyle{plain} \\setcounter{secnumdepth}{3} \\makeatletter \\renewcommand{\maketitle}{ \\ifsphinxpdfoutput \\begingroup \\def\\\\{, } \\def\\and{and } \\pdfinfo{ /Author (\\@author) /Title (\\@title) } \\endgroup \\fi \\begin{center} \\sphinxlogo% {\\Large \\@title} \\par \\end{center} \\begin{flushright} \\@date \\hspace{3zw} \\@author \\par \\py@authoraddress \\par \\end{flushright} \\@thanks \\setcounter{footnote}{0} \\let\\thanks\\relax\\let\\maketitle\\relax } \\makeatother \\let\\pyOldTableofcontents=\\tableofcontents \\renewcommand{\\tableofcontents}{ \\begingroup \\parskip = 0mm \\pyOldTableofcontents \\endgroup \\vspace{12pt} } ''', } latex_docclass = { 'howto': 'jsarticle', 'manual': 'jsbook', } latex_documents = [ ('index', 'test.tex', u'test Documentation', u'test', 'howto'), ]
勉強になりました。
Pillow の ImageDraw#textsize() が間違った値を返している件
Pillow 2.2.0 以降には ImageDraw#textsize() にバグがあり、TrueType フォントを指定していると正しい高さが返りません。
どういう問題なのか
テキストとそれを囲む四角を描画する次のコードを実行してみます。
from PIL import Image, ImageDraw, ImageFont image = Image.new('RGB', (512, 256), (255, 255, 255)) drawer = ImageDraw.Draw(image) font = ImageFont.truetype('/Library/Fonts/Osaka.ttf', 32) # drawing text STRING = 'Hello, python language!' drawer.text((10, 10), STRING, fill='black', font=font) # drawing rectangle surrounding text size = drawer.textsize(STRING, font=font) drawer.rectangle((10, 10, 10 + size[0], 10 + size[1]), outline='black') image.save('example.png', 'PNG')
すると次のような図が出力されます。
カンマや y, g と言った文字の下辺が枠の外から飛び出しています。
この問題は TrueType フォントを表す PIL.ImageFont.FreeTypeFont クラスが文字の大きさを返す際に
offset 値を含めないサイズを返してしまっているために発生しています。
この問題はすでに github 上では修正されているのですが、
現在リリースされている Pillow-2.5.1 ではこの問題は解決されていません。
回避策
Pillow-2.2.0 以降には FreeTypeFont クラスに getoffset() というメソッドがあるので、この値を用いて補正します。
どのバージョンの Pillow でも動くようにするには以下のようなコードを書きます*1。
from PIL import PILLOW_VERSION from PIL.ImageFont import FreeTypeFont def textsize(drawer, text, font=None): size = drawer.textsize(text, font) # Avoid offset problem in Pillow (>= 2.2.0, < 2.6.0) if isinstance(font, FreeTypeFont) and "2.2.0" <= PILLOW_VERSION < "2.6.0": offset = font.getoffset(text) size = (size[0] + offset[0], size[1] + offset[1]) return size
まとめ
しばらくはバグったままなので、adhoc なコードを使って回避して生きていきましょう。
懺悔
このバグは日本語フォントが欠ける問題を直したところに、他の人が offset 値の調整を加えることで発生しているので
僕は(間接的ではあるものの)バグの生みの親ということになります。
大変申し訳無いです。
*1:まだ 2.6.0 はリリースされていませんが、次のリリースで直る想定で書かれています
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 ブロックができるため、どう使うと良いのかというのが難しい指定です。
このオプション、どういう時に使うと便利なんですかねえ。
まとめ
使ったことのないオプションが多い割に、互換性を保とうとすると面倒なことが多くて辛いです。