rst2pdf に手を入れる

※2209/05/29 01:52 GitHub - ralsina/rst2pdf: Use a text editor. Make a PDF. にて修正してもらいました。THX @ralsina !


また GitHub - ralsina/rst2pdf: Use a text editor. Make a PDF. の話。

rst2pdf のスタイル指定は -s オプションでスタイルシートファイル名を指定する。

$ rst2pdf mydoc.txt -s mystyles.txt

マニュアルによると、このスタイルファイルは次の順に検索される。

  • --stylesheet-path で指定した場所(コロン区切りでデフォルトは"")
  • コンフィグファイル(~/.rst2pdf/config)で指定した stylesheet_path
  • カレントフォルダ
  • ~/.rst2pdf/styles フォルダ
  • rst2pdf がインストールされた場所の sytles フォルダ

の、はずなんだけど、どうもカレントフォルダ以外のスタイルファイルを探してくれてない気がする。

$ rst2pdf mydoc.txt -s perldoc.json
[CRITICAL] styles.py:77 Error opening stylesheet "perldoc.json": [Errno 2] No such file or directory: 'perldoc.json'

てな感じ。

処理を追ってみる

ということで --stylesheet-path を未指定の場合の処理を追ってみる。
ちなみにソースはリリース版 0.10.1 です。

  1. createpdf.py の main 関数にて RstToPdf インスタンス生成。--stylesheet-path 未指定なので、引数として stylePath=[] を渡す。
  2. 同モジュールの RstToPdf クラスのコンストラクタで、stylePath はStyleSheet インスタンス生成に使用。
  3. styles.py の StyleSheet クラスのコンストラクタにおいて、stylePath が None の時だけ 上記サーチパスリストを stylePath に突っ込んでる。
  4. stylePath の各値を os.path.expanduser して StyleSearchPath インスタンス変数に突っ込む。
  5. -s オプションで指定された各スタイルシートファイルの絶対パスを得るために findStyle メソッド呼び出し。
  6. findStyle メソッドでは、StyleSearhPath にセットされた各パスの下に、指定のスタイルシートファイルが無いか、順番にチェック。あれば絶対パスとして返すし、無ければファイル名だけを返す。
  7. findStyle の返り値を open して… ここでエラー

コードの変更

ということで、上の3番目の処理で stylePath が None だろうがなんだろうが、サーチパスリストを追加するように変更してやればよさそうです。

ついでに、スタイルシートパスの指定では使えるのに、フォントフォルダの指定に "~" を使ったホームディレクトリ指定ができないのもなんかヤなので、FontSearchPath にも os.path.expanduser をカマしちゃいます。


※ 2009/05/28 fontPath, stylePath が None の場合に [] で初期化する処理を追加しました。

[yosuke@Trillian rst2pdf]$ diff styles.py.org styles.py
41,42c41,44
<         self.FontSearchPath = fontPath + [
<             '.', os.path.join(os.path.abspath(os.path.dirname(__file__)), 'fonts')]
---
>         if fontPath is None:
>             fontPath = []
>         fontPath += ['.', os.path.join(os.path.abspath(os.path.dirname(__file__)), 'fonts')]
>         self.FontSearchPath = map(os.path.expanduser, fontPath)
44,45c46,48
<             stylePath = ['.', os.path.join(os.path.abspath(os.path.dirname(__file__)),
<                 'styles'),'~/.rst2pdf/styles']
---
>             stylePath = []
>         stylePath += ['.', os.path.join(os.path.abspath(os.path.dirname(__file__)),
>                                         'styles'),'~/.rst2pdf/styles']

ほい。これでなんかスッキリした。