sphinxでtsv-tableできなかった!(前編)
きっかけは sphinxでtsv-tableしたい! - think it over
結論から言うと、ディレクティブにコンテンツが渡ったときにはすでにタブはスペースに変換されておりました。。。
あきらめきれないので、そこまで行き着くまでの流れを備忘録的にまとめておきます。
長いので、前編、後編の2回に分けます。
csv-tableの実装はいずこ?
pythonのsite-package配下を探したところ、csv-tableの実装は
/usr/lib/python2.7/site-packages/docutils-0.10-py2.7.egg/docutils/parsers/rst/directives/tables.py
※Windows + Cygwin環境
にありました。
tables.pyには
- CSVTable (csv-tableディレクティブの実装)
- ListTable(list-tableディレクティブの実装)
等が含まれています。
ちなみに、罫線をrstに記述していく以下のタイプは一つ上の階層にあるtableparser.pyにその実装があります。
+------------------------+------------+----------+----------+ | Header row, column 1 | Header 2 | Header 3 | Header 4 | +========================+============+==========+==========+ | body row 1, column 1 | column 2 | column 3 | column 4 | +------------------------+------------+----------+----------+ | body row 2 | Cells may span columns. | +------------------------+------------+---------------------+ | body row 3 | Cells may | - Table cells | +------------------------+ span rows. | - contain | | body row 4 | | - body elements. | +------------------------+------------+---------------------+
csv-tableを継承してtsv-tableを作る
さて、CSVTableですが、ディレクティブのコンテンツであるCSVデータを解析する「parse_csv_data_into_rows」関数オブジェクトがあります。
CSVTableを継承したTSVTableを作ってparse_csv_data_into_rowsをオーバーラードしてタブ区切り用にカスタマイズすればOKじゃーん、やったね!
ってことで、tables.pyと同じ階層にtsvtable.pyを作成し、まずは継承のみしてみる
""" Directives for tsv-table elements. """ __docformat__ = 'reStructuredText' import sys import os.path import csv from StringIO import StringIO from docutils import io, nodes, statemachine, utils from docutils.utils.error_reporting import SafeString from docutils.utils import SystemMessagePropagation from docutils.parsers.rst import Directive from docutils.parsers.rst import directives from docutils.parsers.rst.directives.tables import CSVTable class TSVTable(CSVTable): def run(self): return CSVTable.run(self)
tsv-tableディレクティブの登録
ここまでで、csv-tableと同一機能のtsv-tableが出来上がり。
これで、できるのか?と疑問を抱きつつ、makeしてみると、案の定、、
ERROR: Unknown directive type "tsv-table".
あーーーん。。。
ディレクティブを登録しなければならないようです。
Creating reStructuredText Directives
公式ドキュメントによると、ディレクティブを登録する方法は2つ。
- docutilsのコアディレクティブとして使う場合
- __init__.pyの「_directive_registry」ディクショナリに追加してね
- アプリ固有のディレクティブとしえ使う場合
- 「register_directive」関数を使ってディレクティブを追加してね
後者で!!
むんむん唸りながら、結局、sphinxのconf.pyに
from docutils.parsers.rst import directives from docutils.parsers.rst.directives.tsvtable import TSVTable directives.register_directive('tsv-table', TSVTable)
と書くことでtsv-tableのディレクティブの登録が行われ、
.. tsv-table:: :header: "開始", "終了", "時間", "内容" :widths: 10, 10, 10, 200 08:00, 08:10, 00:10, メールチェック 08:10, 08:20, 00:10,
が正常にparseされるようになりました。
前編おわり!!