Sphinxドキュメントを例にした静的ファイルの変換¶
XDV クイックスタート ではHTTP-Proxy機能を用いてサイトの変換を行いましたが、 このサンプルではクイックスタートの環境に手を加えて、静的なHTMLを変換する 例を紹介します。クイックスタートでは、変換した結果をWSGIサーバープログラムを 動かしながらブラウザで確認していましたが、ここではさらに静的HTMLファイルの 出力も行います。
ここで用いるパッケージはクイックスタートで使用したものの他に、 Sphinx を利用します。
- xdv:
ルールコンパイラ
- dv.xdvserver:
WSGIフィルタ
- Paster:
WSGIサーバー, Proxy
- Sphinx:
ドキュメンテーションビルダー
SphinxのHTML出力を用意¶
コンテンツ となる静的HTMLを用意します。 どのようなHTMLファイルでも良いのですが、複数のページにまたがって 統一的なレイアウトフォーマットになっているとxdvのルールをシンプルに記載 することが出来るため、チュートリアルとして Sphinx が出力した HTMLファイルを利用することにします。今回はSphinxの標準テンプレート に手を加えずに出来る範囲でデザインの変換を行ってみたいと思います。
ここでは、Sphinx-1.0を用い、Sphinxのデフォルトのテーマ (xdvのテーマHTMLではありません)としてbasicを選択します。
テーマHTMLファイルを用意¶
新しく適用したいデザインを テーマHTML として用意するわけですが、 チュートリアルのためには手軽にデザインを用意したいところです。そこで、 OSWD - Open Source Web Design で公開されている デザインをダウンロードして テーマHTML として利用してみましょう。
テーマHTMLは通常の場合、 xdvで適用しやすいようなHTML構造とidやclassなどを 備えていることが望ましい のですが、今回はチュートリアルですので、 OSWDからダウンロードしたテーマHTMLをうまくつかうようにしてみましょう。
ここでは、デザインとして silverglow を利用します。 ただし、OSWDで公開されているHTMLのデザインはともかく、HTML的にはなかなか 気になるところが多くあります。また、ほとんどのデザインが固定幅で作成 されているため、liquidデザインを採用したい場合はがんばって探すか、 自分でliquidになるようカスタマイズする必要があります。
IE以外では表示がちょっと崩れるので今回使うためにstyle.cssの末尾に以下の行を 追加しました。
div.header h1 {
float:left;
}
環境の構成¶
wsgi.iniの変更とコンテンツHTMLの配置¶
XDV クイックスタート ではWSGIでProxyを設定して外のサイトからコンテンツを 取得していましたが、今回はPCのDISKからHTMLを読み込みます。このため、 wsgi.iniファイルを以下のように変更します。
--- C:/Project/xdv/src/quickstart/wsgi.ini Sat Aug 21 17:29:15 2010
+++ C:/Project/xdv/src/ex-sphinx/wsgi.ini Sat Aug 28 22:51:23 2010
@@ -16,15 +16,16 @@
pipeline = egg:Paste#cgitb
egg:Paste#httpexceptions
xdv.theme
- proxy
+ sphinx.static
[filter:xdv.theme]
use = egg:dv.xdvserver#xdv
theme = %(here)s/static/theme.html
rules = %(here)s/static/rule.xml
live = true
+absolute_prefix = /static/
-[app:proxy]
-use = egg:Paste#proxy
-address = http://www.ruby-lang.org/
+[app:sphinx.static]
+use = egg:Paste#static
+document_root = %(here)s/../../docs/build/html
変更点は3つ。
proxy という名前が適切でないので sphinx.static に変更した。
テーマHTMLの中でcssや画像ファイル等への相対パスが含まれているので、 absolute_prefix = /static/ という指定を追加し、テーマHTMLが 正しく関連リソースを読み込めるようにした。
[app:proxy] を [app:sphinx.static] とし、コンテンツHTMLを置いている パスを記載した。
詳しくは説明しませんが、だいたい理解できると思います。
テーマHTMLの配置¶
テーマHTMLにはsilverglowを利用しますが、クイックスタートでの設定に合わせて index.htmlをtheme.htmlに変更しています。ファイルの置き場所はwsgi.iniの 記載通り、実行環境のstaticディレクトリ以下です。
theme = %(here)s/static/theme.html
rules = %(here)s/static/rule.xml
silverglowをstaticに配置すると、以下のようなファイル構成になると思います:
static/
+---images/
| +-- xxx.jpg
| +-- yyy.gif
|
+- rule.xml
+- style.css
+- theme.html
ルールの作成と確認¶
これから ルール定義 を作成していきますが、まずは空のrule.xmlを 用意します。
<rules xmlns="http://namespaces.plone.org/xdv"
xmlns:css="http://namespaces.plone.org/xdv+css">
</rules>
つぎは確認用にWSGIサーバーを起動しましょう。
デザイン確認用にWSGIサーバーを起動¶
python bootstrap
や bin/buildout
を実行して環境を構築しておいて
ください。カレントディレクトリはサンプルコードを置いている ex-sphinx
ディレクトリを想定しています。
WSGIサーバーを起動するには以下のコマンドを実行します (これもクイックスタートと同じ手順です)。
$ bin/paster wsgi.ini
ブラウザで http://localhost:8000/ にアクセスしてください。ただし、 まだルール定義が空なので、ブラウザでアクセスしても単にテーマHTMLの内容が 表示されるはずです。
ここから先は、ブラウザをリロードしながらrule.xmlを編集してデザインを 適用していきます。
デザイン適用の進め方の例¶
課題
後で書く
課題
本来cssはrule.xmlに書くのではなくテーマHTMLのcssに書くべきです
最終的な画面とrule.xmlの例¶
ここまでの作業で最終的にこのような画面になりました。
この画面を表示するためのrule.xmlは以下の内容です。
<rules xmlns="http://namespaces.plone.org/xdv"
xmlns:css="http://namespaces.plone.org/xdv+css">
<append theme="/html/head" css:content="head > *"/>
<replace theme="//head/title" content="//head/title"/>
<append theme="/html/head">
<style type="text/css">
body { background-color: #fff; font-size: 11pt; }
div.body h2 { background-position: 5px 10px; padding-left: 30px; }
div.body h3 { font-size: 120%; }
div.body h2, div.body h3 { text-transform: none; }
div.navigation { float: none; }
div.related { background-color: transparent; color: #006699;}
div.related a { color: #006699;}
div.footer { color: black; font-size: 100%; }
div.footer a { color: #006699; }
</style>
</append>
<drop css:theme="div.header h1" />
<copy css:theme="div.block_right" content="//h1/text()"/>
<replace css:theme="div.right_content" css:content="div.body"/>
<drop content="//h1"/>
<drop css:theme=".left_content" />
<copy css:theme="div.navigation" content="//div[@class='related'][1]" />
<replace css:theme="div.footer" css:content="div.footer" />
</rules>
静的HTMLの出力¶
ここまではWSGIサーバーを起動して表示を確認しながらデザインを適用してきました。 しかしSphinxであれば最終成果物は静的HTMLとして出力してほしいところです。
標準では全てのHTMLファイルにテーマを適用して出力する仕組みは、残念ながら 用意されていませんが、複数のコマンドを組み合わせることでhtmlの出力はできます。
xdvcompiler でrule.xmlとtheme.htmlからtheme.xsltを出力する
xdvrun でtheme.xsltと コンテンツ から変換後の HTMLを出力する
上記手順の2を全てのファイルに対して実行すれば、静的HTMLすべてを変換する ことができます。
これを自動的に行う簡単なスクリプトを作成してみました。外部コマンドとして xdvcompiler 等を呼び出しているためあまり効率は良くありませんが、 一応うまく動作しているようです。
# -*- coding: utf-8 -*-
import os
import sys
import tempfile
import shutil
j = lambda *p:os.path.normpath(os.path.join(*p))
def main(compiler_path, linker_path, static_path, static_prefix,
theme_path, rule_path, content_path, output_path):
# clean-up
if os.path.exists(output_path):
shutil.rmtree(output_path)
os.mkdir(output_path)
fd, xslt_path = tempfile.mkstemp('.xsl', 'theme-')
os.close(fd)
# create xslt file by compile
cmd = [compiler_path,
'-r', rule_path,
'-t', theme_path,
'-o', xslt_path,
'-a', static_prefix,
'-p']
cmd = ' '.join(cmd)
print cmd
os.system(cmd)
# copy theme files
shutil.copytree(static_path, j(output_path, os.path.basename(static_path)))
# copy content file or apply theme
for dirpath, dirnames, filenames in os.walk(content_path):
target_path = dirpath[len(content_path)+1:]
if not os.path.exists(j(output_path, target_path)):
os.mkdir(j(output_path, target_path))
for filename in filenames:
from_file = j(dirpath, filename)
to_file = j(output_path, target_path, filename)
if os.path.splitext(filename)[1] in ('.htm', '.html'):
# apply theme
cmd = [linker_path,
'--xsl', xslt_path,
'-o', to_file,
from_file,
]
cmd = ' '.join(cmd)
print cmd
os.system(cmd)
else:
# copy only
print 'copy', from_file, to_file
shutil.copy(from_file, to_file)
if __name__ == '__main__':
cwd = '.'
compiler_path = j(cwd, 'bin/xdvcompiler')
linker_path = j(cwd, 'bin/xdvrun')
static_path = j(cwd, 'static')
static_prefix = 'static'
theme_path = j(cwd, 'static/theme.html')
rule_path = j(cwd, 'static/rule.xml')
content_path = j(cwd, '../../docs/build/html')
output_path = j(cwd, 'output')
main(compiler_path, linker_path, static_path, static_prefix,
theme_path, rule_path, content_path, output_path)
実行は以下のように行います。ディレクトリ等は決め打ちで実装しているため、 他のディレクトリでは動作しません。
$ cd /path/to/ex-sphinx
$ bin/py convert.py
うまく動作すれば、outputというディレクトリに変換されたHTMLファイル等が 出力されます。