ブログの記事は reST (reStructuredText) で書いて HTML に変換していますが、 パソコンを買い替えたので環境を移行しなければなりません。 ということで、メモを書いておきます。
docutils のインストール
まずは Docutils モジュールをインストールします。 Sphinx をインストールすれば依存関係でインストールされていますが、 そうでない場合は個別にインストールします。
$ site=blog-site $ virtualenv --distribute $site $ cd $site $ . bin/activate $ pip install docutils
docutils には rst から始まる Python スクリプトがいくつか付属しています。
$ ls bin/rst*.py bin/rst2html.py bin/rst2latex.py bin/rst2man.py bin/rst2odt.py bin/rst2odt_prepstyles.py bin/rst2pseudoxml.py bin/rst2s5.py bin/rst2xetex.py bin/rst2xml.py bin/rstpep2html.py
rst2html.py を使うと、 reST で記述されたファイルを HTML に変換できます。 たとえば、 article.rst というファイルを HTML に変換する場合には次のように実行します。
$ rst2html.py article.rst >article.html
ブログ記事に使う
プレビュー用と投稿用の HTML を生成できるようにします。 ブログ投稿用のアプリケーションを使えばそんなものは必要ないかもしれませんが、 HTML をベタ書きできた方が何かと都合が良いこともありそうなので、 この方法にしています。
プレビュー用の HTML は先ほどのコマンドで生成できます。 しかし、投稿用には HTML の <head> タグなどは不要ですので、 これを取り除くことにします。
2種類のアプローチが考えられますが、ここでは後者を採用します。
- 生成された HTML をパースして、 <body> の中を抽出する。
- そもそも HTML の <body> だけを生成させる。
rst2html.py のオプション
rst2html.py に --help オプションをつけて実行すると、 たくさんのオプションが利用できることが分かります。 なんとなくメモしておくものだけを抜粋して日本語にしておきます。
--strip-comments | |
コメント要素を除去します。 | |
--leave-comments | |
コメント要素を残しておきます。 (default) | |
--input-encoding=<name[:handler]>, -i <name[:handler]> | |
入力テキストのエンコーディングと、オプションで エラーハンドラーを設定します。 Default: <locale-dependent>:strict. | |
--input-encoding-error-handler=INPUT_ENCODING_ERROR_HANDLER | |
デコードできない文字に対するエラーハンドラーを設定します。 Choices: "strict" (default), "ignore", and "replace". | |
--output-encoding=<name[:handler]>, -o <name[:handler]> | |
出力テキストのエンコーディングと、オプションで エラーハンドラーを設定します。 Default: UTF-8:strict. | |
--output-encoding-error-handler=OUTPUT_ENCODING_ERROR_HANDLER | |
デコードできない文字に対するエラーハンドラーを設定します。 "strict" (default), "ignore", "replace", "xmlcharrefreplace", "backslashreplace". | |
--language=<name>, -l <name> | |
言語を設定します。 (BCP 47 言語表記). Default: en. | |
--no-file-insertion | |
外部ファイルのコンテンツを挿入するディレクティブを無効にします。 ディレクティブは "include" と "raw" です。 | |
--file-insertion-enabled | |
外部ファイルのコンテンツを挿入するディレクティブを有効にします。 ディレクティブは "include" と "raw" です。 Enabled by default. | |
--no-raw | |
"raw" ディレクティブを無効にします。 | |
--raw-enabled | |
"raw" ディレクティブを有効にします。 Enabled by default. | |
--template=<file> | |
テンプレートファイルを指定します。 テンプレートファイルは UTF-8 でエンコードされていなければなりません。 Default is "lib/python2.7/site-packages/docutils/writers/html4css1/template.txt". | |
--stylesheet=<URL> | |
スタイルシートの URL をカンマ区切りで指定します。 --stylesheet と --stylesheet-path の設定を上書きます。 | |
--stylesheet-path=<file> | |
スタイルシートのパスをカンマ区切りで指定します。 --link-stylesheet があると、出力する HTML の相対パスとしてパスは上書きされます。 Default: "lib/python2.7/site-packages/docutils/writers/html4css1/html4css1.css" | |
--embed-stylesheet | |
出力する HTML にスタイルシートを埋め込みます。 スタイルシートファイルは、処理中にアクセスできなければなりません。 This is the default. | |
--link-stylesheet | |
出力する HTML にスタイルシートをリンクさせます。 Default: embed stylesheets. |
この中に、 --template オプションがあります。 ヘルプメッセージに表示されるデフォルトのテンプレートは次のようになっています。
%(head_prefix)s %(head)s %(stylesheet)s %(body_prefix)s %(body_pre_docinfo)s %(docinfo)s %(body)s %(body_suffix)s
見た目のままですが、 $(body)s だけにすると、文章部分だけを出力できます。 つまり、次のように実行できます。
$ rst2html.py --template=blog-template.txt article.rst >article-body.html
これでも目的は達成できますが、出力ファイル名をいちいち入力するのは面倒ですから、 Python スクリプトにまとめることにします。
Python スクリプトで使う
rst2html.py は単なるラッパースクリプトで、内部的には docutils.core.publish_cmdline() を呼び出しています。 つまり、 subprocess.call() で rst2html.py を呼び出すこともできますし、 docutils.core.publish_cmdline() を使うこともできます。
docutils のモジュールを使う場合は、次のようなスクリプトにまとめられます。
スクリプト
__doc__ = """ python %prog {manuscript} Parse a reST manuscript and write out it in two way HTML formats. A file whose suffix is ".html" is for preview, and a file whose suffix is ".txt" is for blogger's article. """ import optparse import os import tempfile from docutils.core import publish_cmdline # see: lib/python2.7/site-packages/docutils/writers/html4css1/template.txt RST_TEMPLATE_SOURCE = ''' %(body)s ''' def parse_args(): parser = optparse.OptionParser(__doc__) opts, args = parser.parse_args() if not args: parser.error("no arguments found.") return args def publish_restructured_text(manuscript): fname = tempfile.mktemp() with open(fname, 'w') as temp: temp.write(RST_TEMPLATE_SOURCE) basic_option = ['--strip-comments'] basename, _ = os.path.splitext(os.path.basename(manuscript)) source = '%s.txt' % (basename,) preview = '%s.html' % (basename,) argv = ['--template=%s' % (fname,), manuscript, source] publish_cmdline(writer_name='html', argv=basic_option+argv) argv = [manuscript, preview] publish_cmdline(writer_name='html', argv=basic_option+argv) os.unlink(fname) print "Write as single HTML page and only body element." print " single page : %s (%dbytes)" % (preview, os.path.getsize(preview)) print " only body : %s (%dbytes)" % (source, os.path.getsize(source)) def main(): manuscripts = parse_args() for manuscript in manuscripts: if os.path.exists(manuscript): publish_restructured_text(manuscript) else: print "%s is not found." % (manuscript,)
終わりに
Mac を買い替えたので環境を移行する必要がありました。 整理がてら記事にしましたが、必ずしも docutils で頑張る必要もなく、 Sphinx でラップした方が良いかもしれません。 ともあれ、まずは愚直に移行することにしました。
その他、テキストファイルで原稿を書いてブログで公開するソフトウェアはいくつかあります。
- プログラマ向けのテキストファイル変換型のブログエンジン「Octopress」 - MOON GIFT
- jekyll (jekyll 日本語説明)
Web サービスを使えない状況や、単一のドキュメントを整形する場合には、 このような方法も便利かもしれませんね。
0 件のコメント:
コメントを投稿