HEARTBEATS

Sphinxのテーマを継承して体裁をカスタマイズしよう

   

斎藤です。こんにちは。

今日は、SphinxでHTMLのドキュメントを生成する際、ドキュメント全体に対して体裁の変更を行えるよう、テーマを継承する方法をお話しします。本記事では、「継承する理由」「組み方」そして「注意点」の3点についてまとめました。

※検証したソフトウェアのバージョンば、Sphinxは1.1.3sphinxjp-latex、Pythonは2.6.6 (CentOS 6.4標準rpm)です。

継承する理由

Sphinxとは、Pythonで動作し、reStructuredText(以下、reST)で記述するドキュメント生成エンジンです。出力は、HTMLばかりでなく、LaTeX(PDF)やmanなど多様な形式をサポートしています。また、HTML出力の際、テーマを利用して容易に体裁を変更する事ができます。

さて、既存のSphinxのテーマを変更したくなる時とは、どのような場合でしょうか。例えば、ヘッダ・フッタの変更、JavaScriptの組み込みが該当します。変更にあたって、元のテーマを書き換えれば良いと考える事もできるのですが、それではテーマがバージョンアップした時等に、メンテナンスしづらい状態となります。また、全部書き換えとなると、相応の時間と手間がかかります。

では、"raw:: html"を使って直接HTMLを書けば良いのではないか、との意見もあるかと思います。しかし、直接HTMLで書いてしまうと、reSTでの記述のみで多様な出力形式をサポートしているSphinxの良さが低減してしまいます。

そこで、既に存在するテーマを継承することで、元のテーマを活かしつつ個々の状況に応じた体裁のカスタマイズを両立できるようにします。次の節で、bizstyleを継承する簡単な例を示しながら組み方を紹介します。

組み方

ファイル構成

テーマを継承するにあたり、ファイル・ディレクトリの作成例を示します。私の場合、継承したテーマのファイル・ディレクトリは、テーマを利用するSphinxドキュメントのソースディレクトリ配下に作成しています。

.
├── Makefile
├── build/
├── make.bat
└── source/
    ├── _static/
    │   ├── (JavaScriptファイル: 説明では OPTIONALFILE.js と仮に定義)
    │   └── (CSSファイル: 説明では OPTIONALFILE.css と仮に定義)
    ├── conf.py
    ├── THEME_NAME/ ← ※カスタマイズしたテーマの保存先※
    │   ├── layout.html
    │   ├── static/
    │   │   ├── (JavaScriptファイル: 説明では SOMEFILE.js と仮に定義)
    │   │   └── (CSSファイル: 説明では SOMEFILE.css と仮に定義)
    │   └── theme.conf
    ├── images/
    │   └── (個々のドキュメント用の画像ファイルを保存)
    ├── (ドキュメントファイル *.rst)
    └── index.rst

ファイル内容

テーマに関するファイルが保存してある"source/THEME_NAME/"配下について説明します。

  • layout.html

テーマ本体です。基本的な設定と、オーバーライドしたい内容について記述します。

{% extends "bizstyle/layout.html" %}

{% set script_files = script_files + [ "_static/SOMEFILE.js" ] %}
{% set css_files    = css_files    + [ "_static/SOMEFILE.css" ] %}

{%- block extrahead %}
    <meta name="viewport" content="width=device-width; initial-scale=1.0">
{%- endblock %}

1行目の extends は、元となるテーマの layout.html を継承する事を示します。

3,5行目は、追加するJavaScript, CSSファイルを指定しています。追加が不要な場合は記載する必要はありません。

以降は、オーバーライドする項目についてのHTMLを、Jinjaのテンプレートの書式に従って記述します。ここでは、HTMLのHEADタグ内に追加するMETAタグを記載しています。なお、blockの項目についての詳細は、Sphinxドキュメントの「Templating」の節を参照してください。

  • static/

CSSやJavaScriptファイル等、静的な外部ファイルを保存するディレクトリです。必須ではありません。

  • theme.conf

テーマの動作を決める設定ファイルです。以下は、bizstyleを継承する事、そしてCSSもbizstyleのものを利用する事を記述しています。

[theme]
inherit = bizstyle
stylesheet = bizstyle.css

もし、配色を変更したい場合は、継承元のCSSファイルを参考に、新しいCSSファイルを"static/"ディレクトリに保存し、そのファイル名を"stylesheet"欄に書きます。

conf.pyの修正

継承したテーマを利用するには、ドキュメントの"conf.py"の設定を最低2カ所操作します。今回は、ドキュメントのソースディレクトリに継承したテーマを保存した前提で記述します。

  • html_theme = '(テーマを保存したディレクトリ名)'
  • html_theme_path = [ "." ]

設定の変更が終わったら、"make clean html"を実行し、正しくビルドできるかを確かめます。

注意点

元のテーマのCSSの引き継ぎは自動ではない

継承するテーマの名前を指定しただけでは、CSSが引き継がれず体裁が崩れてしまいます。そのため、事前に継承元のテーマが利用しているCSSファイル名を調べておき、"theme.conf"に記述して下さい。

CSSやJavaScriptファイルのみの追加ならもっと簡素にできる

HTMLの書式の変更が無く、CSSやJavaScriptファイルの追加のみであれば、新しいテーマを作る必要はありません。"conf.py"の設定と、ソースファイルを収めたディレクトリの"_static"ディレクトリにファイルを収めるのみで適用可能です。

"_static"ディレクトリにファイルを収めた後、"conf.py"の末尾に次の記述を追記します。

def setup(app):
    app.add_stylesheet('OPTIONALFILE.css')
    app.add_javascript('OPTIONALFILE.js')

おわりに

ここまで、Sphinxのテーマを継承し体裁を変更する方法を、「継承する理由」「組み方」そして「注意点」の3点にまとめて述べました。HTMLやCSSを記述する知識さえあれば、テーマそのものをゼロから起こす事無く、既存のテーマの良さを活かしながら体裁を変更できる事がわかるかと思います。

また、注意点の2点目に、CSSやJavaScriptファイルのみの追加であれば、テーマを起こす必要がなく設定の追記のみで可能である事もお話ししました。

なお、私自身はテーマを継承してどのような事をしているかと申しますと...

  • 出力するHTMLのクラスを変更
  • JavaScriptを用いて出力したHTMLのテーブルにフィルタを実装

などを行っています。上記をテーマ側で実装する事で、HTML出力のカスタマイズをしつつ、LaTeXなどの他のフォーマットで出力する際の影響を最小限にできています。参考になれば幸いです。

それでは皆様、ごきげんよう。

参考文献

株式会社ハートビーツの技術情報やイベント情報などをお届けする公式ブログです。



ハートビーツをフォロー

  • Twitter:HEARTBEATS
  • Facebook:HEARTBEATS
  • HATENA:HEARTBEATS
  • RSS:HEARTBEATS

殿堂入り記事