背景
- Sphinxで作成するHTMLドキュメントをわかりやすくするために、アニメーションGIFを使いたい。
- Sphinx標準でも、アニメーションGIFを単純にimageファイルとして挿入することはできる。
- しかし、これだとアニメが自動で動き始め、テキストを読む進捗と同期せず読み勝手が悪い。
- アニメの開始・停止を読み手が制御できるようにしたい。
調べてわかったこと
アニメーションGIFに開始・停止ボタンを追加するのは、gifffer を使うとできる。
具体的には、Sphinxで出力されるHTMLが以下のようになればよい。
-
HTMLに次のタグを追加する
<script src="https://cdn.rawgit.com/krasimir/gifffer/c5044af8/build/gifffer.min.js"></script>
-
<img>
タグの属性src
をdata-gifffer
に置換する置換前:<img src="_images/hello_world.gif" /> 置換後:<img data-gifffer="_images/hello_world.gif"/>
-
HTMLに次のタグを追加する
<script>jQuery(window).on("load", function(){Gifffer();});</script>
実現方法
これを実現するために、Sphinxを以下のように拡張・設定する。
-
_static/js/init.js
を作成する_static/js/init.jsjQuery(window).on("load", function(){Gifffer();});
-
conf.py
の最後に以下を追加するconf.pyimport posixpath from sphinx.writers.html import HTMLTranslator class GiffferTranslator(HTMLTranslator): def visit_image(self, node): olduri = node['uri'] if olduri in self.builder.images: node['uri'] = posixpath.join(self.builder.imgpath, self.builder.images[olduri]) uri = node['uri'] if uri.lower().endswith(('gif')): atts = {'data-gifffer': uri} if 'width' in node: atts['data-gifffer-width'] = node['width'] if 'height' in node: atts['data-gifffer-height'] = node['height'] atts['data-gifffer-alt'] = node.get('alt', uri) self.body.append(self.emptytag(node, 'img', '', **atts)) return HTMLTranslator.visit_image(self, node) def setup(app): app.require_sphinx("1.3") app.add_javascript('https://cdn.rawgit.com/krasimir/gifffer/c5044af8/build/gifffer.min.js') app.add_javascript('js/init.js') app.set_translator('html', GiffferTranslator)
まとめ
これで画像ファイルが .gif
の時に gifffer
が適用されるようになった。
.. image:: ../images/hello_world.gif
- 出来上がったページはこれ
- Sphinx 1.7.2で動作確認した (1.3b1 より前は、
set_translator
がないので動かない) - SphinxのHTMLTranslator#visit_image を参考にして作成
- アニメじゃないGIFかどうか判定していないが、アニメじゃない画像にはPNGを使うようにしているので実用上問題はない。