2011年10月26日水曜日

Sphinx 文書で HTML と reStructuredText コードを混在させる

SphinxHTMLコードを挿入する方法で、悩んでいたことが簡単に解決したので記事にします。Sphinx については、次のサイトを参照ください。

参考: Sphinx-Users.jp

Sphinxで文書を作成するのは簡単だし楽しい。ただ文書として表現できるのは、Sphinxが提供している機能の範囲に限られる。Sphinxの機能では表現できない、込み入った図や表を表現するのにはどうしたら良いのだろうか?。

図や表を画像にして文書に挿入するのが、最も簡単な解決方法だ。ただこの方法は例えば、表の中に複数のリンクを貼ったり、表の数字をコピー&ペーストで利用できるようにはできない。

これに対してSphinx文書にHTMLコードを挿入して図や表を表現すると、画像だけを使った方法で起こる問題を解決可能だ。SphinxにどのようにHTMLコードを挿入していくか、まず HTMLコードの挿入方法の説明から始める。

SphinxにHTMLコードを挿入する方法

SphinxにHTMLコードを挿入するには、rawディレクティブを使用する。HTMLコードに対しては、rawディレクティブのパラメータに html を指定する。

.. raw:: html

 (HTMLコードはここ)

次にサンプルを示してみる。

下の表は\ **HTMLコード**\ のテスト表示です。

.. raw:: html
 
    <table border="1" style="background-color: #33FFFF">
    <tr><th>項目1</th><th>項目2</th><th>項目3</th></tr>
    <tr><td>1000</td><td>2000</td><td>3000</td></tr>
    </table>

設定したサンプル1の表示は次のようになる。

HTMLコードは文書ファイル中にも記述できるが、HTMLコードだけを別ファイルにすることも可能だ。 その場合、HTMLコードファイルは :file: オプションで指定する。

.. raw:: html
   :file: test.html

test.html はHTMLコード記述した別ファイルの名前。

この他、インターネット上のURLを指定して、コードを取り込むことも可能だ。詳細は次のサイトを参照のこと。

参考: reStructuredText Directives - Raw Data Pass-Through

CSSコードの設置

HTMLコードで使用するCSSは、サンプル1のようにタグ中に style で設定してもよいが、コードの量が多いと対応できなくなる。このためCSSを次のように設置できる。

  1. Sphinxの _template フォルダに layout.html ファイルが無い場合、ファイルを作成する。
  2. layout.html ファイルをテキストエディタで開き、次の記述を追加する。
    {% block extrahead %}
    <style type="text/css"> 
    
    (ここにCSSコードを記述) 
    
    </style>
    {% endblock %}
    

layout.html に CSSを追加したくない時や、外部のCSSファイルを利用したい場合は、次のように設置する。

  1. 外部CSSファイルを作成し、どこかのサーバにアップロードする(例 Googleサイトなど)。
  2. layout.html ファイルをテキストエディタで開き、次の記述を追加する。
    {% block linktags %}
    <link rel="stylesheet" type="text/css" href="xxxxxx" />
    {% endblock %}
    
    xxxxxx にはCSSファイルのURLを記述する。

参考: Sphinx - テンプレート

HTMLコードに reStructuredText コードを記述する方法

ここまでで、Sphinx文書内にHTMLコードを記述できるようになった。これから少し難しい問題になるが、挿入するHTMLコード内に文書内リンクを記述するのにはどうしたらよいだろうか?。

文書外のリンクなら、アンカータグ(<a>)を利用して記述は可能だ。文書内のリンクでも予めURLがわかっているのなら、アンカータグで記述できる。しかしその場合、文書ファイル名を変更した時などはHTMLコードも変更する必要が出てくる。また、HTMLコード内に reStructuredTextreST) のコードを記述しても、Sphinxは変換してくれない。

このような時は、HTMLとreStructuredTextのコードの混在ファイルを作成し、HTMLコードを表示したい箇所に include ディレクティブで作成したファイルを挿入しておけばよい。手順をサンプルを使って説明する。

1. HTMLとreStructuredTextのコードの混在ファイルの作成
 
reStructuredTextコードを、HTMLコードで包むように記述している。作成したファイルは test.html という名前になる。
.. raw:: html
 
    <table border="1" style="background-color: #33FFFF">
    <tr><th>項目1</th><th>項目2</th><th>項目3</th></tr>
    <tr><td>1000</td><td>2000</td><td>3000</td></tr>
    <tr><td colspan="3">
 
:ref:`test_ref` 
 
.. raw:: html
 
    </td></tr>
    </table>
テーブル内に文書内ラベル(test_ref)へのリンクを記述している。  
 
2. HTMLコードを表示したい箇所に include ディレクティブで挿入する
 
include ディレクティブのパラメータに、先ほど作成した test.html を指定し文書に挿入する。
下の表は\ **HTMLコード**\ のテスト表示です。

.. include:: test.html

.. _test_ref:

テストリンク
^^^^^^^^^^^^

テストリンク先です。 
includeディレクティブでは test.html ファイルを挿入するように指定している。  
 

この設定によって、HTMLコード内に文書内リンクが含まれた状態で文書が生成できる。サンプル2の表示は次のようになる。

表内の「テストリンク」は、文書内のテストリンクというセクションのラベルにリンクしている。

設定してみると意外と簡単なのがわかる。サンプル2のようにHTMLコードを別ファイルに分離しなくてもよいが、文書とHTMLコードを一緒に記述すると見通しが悪くなるため避けたほうがよいだろう。分離したファイルを挿入する時に重要なのは、raw ディレクティブの :file: オプションを使用するのではなく、include ディレクティブを使用することである。

include ディレクティブは強力だ。例えば文書の一部分を取り込むなどといったことが可能である。使いこなせば、とても便利なディレクティブとなる。詳細は次のサイトを参照して欲しい。

参考: reStructuredText Directives - Including an External Document Fragment

最後に一つ注意点だが、サンプル2ではHTMLコードを記述するファイルの拡張子を .html にしている。include ディレクティブ はどんな拡張子でも取り込むことが可能だが、ここで .rst と拡張子をつけてしまうとSphinxのmake時に警告が表示されてしまう。警告は toctree に登録されていないファイルだとか、タイトルがないファイルがあるとかで実害はない。しかし警告を表示させないためには、.rst 以外の拡張子をつけたほうがよいだろう。

 

今回は文書内リンクをHTMLコードに挿入しましたが、同様に画像などの他の reStructuredText コードの挿入も可能です。これによって、Sphinxを使った文書の表現の幅が広がるのではないでしょうか。

参考 - 今回の方法で作成したSphinx文書の図です。