nikkie-ftnextの日記

イベントレポートや読書メモを発信

Sphinx拡張が持つ静的ファイルをビルド結果のディレクトリに含める

はじめに

七尾百合子さん、お誕生日 19日目 おめでとうございます! nikkieです。

今回は、Sphinx拡張を開発する中で静的ファイルについて知ったことです。

目次

静的ファイルを持ったSphinx拡張

この記事の背景として、自作のsphinx-revealjs-copycodeに静的ファイルを持たせる変更を考えています。

  • これまで
    • 自作拡張でsphinx-revealjs側に静的ファイルを追加
    • sphinx-revealjsの実装に乗っかって、静的ファイルはビルド結果のディレクトリに含められる
  • 今回の取り組み
    • 自作拡張側に静的ファイルを持たせる
    • Q:この静的ファイルをビルド結果のディレクトリに含めるには、どのようにしたらよい?
sphinx_revealjs_copycode/
├── static/  # この下に配置する静的ファイルを、make revealjsでできるディレクトリに含めたい
└── __init__.py

結論:ビルド結果のディレクトリにコピーする

o3-mini deep researchで見つかったのが「Adding CSS and javascript files from extensions」というissue

続きのメーリングリストの中に、tk0miyaさんによる実装例が
https://groups.google.com/g/sphinx-users/c/Z-wcktOhIAc/m/Ug0_HhSNCQAJ

from sphinx.util.fileutil import copy_asset

def copy_asset_files(app, exc):
    asset_files = [...]
    if exc is None: # build succeeded
        for path in asset_files:
            copy_asset(path, os.path.join(app.outdir, '_static'))

def setup(app):
    app.connect('build-finished', copy_asset_files) 

コピーに使うのが、sphinx.util.fileutil.copy_asset

Copy asset files to destination recursively.

私のケースではテンプレートは使いませんが、テンプレート変数がある場合は展開されるそうです。

同様の方法はSphinxテーマのドキュメントにも記載されていました1
https://www.sphinx-doc.org/ja/master/development/html_themes/index.html#add-your-own-static-files-to-the-build-assets
copy_asset()に代えて、shutilでコピーする例です)

考えた案:html_static_path

最初はhtml_static_pathを使おうと考えていました。
https://www.sphinx-doc.org/ja/master/usage/configuration.html#confval-html_static_path

A list of paths that contain custom static files (such as style sheets or script files).

拡張の実装でapp.config.html_static_pathを変更してみたのですが、期待したようになかなか動かず、deep researchに踏み切りました。

取り上げたissueの中でこんな意見が
https://github.com/sphinx-doc/sphinx/issues/1379#issuecomment-439657133

IMO you should not modify app.config.html_static_path from extension.

sphinx-revealjsの実装はhtml_static_pathを使うよう2なのですが、私は見つけたtk0miyaさん案で、結果的にこの意見にも沿いました。

終わりに

Sphinx拡張が持つ静的ファイルをビルド結果のディレクトリに含める方法を知りました。

  • コアイベントのbuild-finished利用
  • 拡張が持つ静的ファイルをビルド結果のディレクトリにコピーする

Sphinx拡張が持つ静的ファイルをビルド結果にも含めたければ、自分でコピーするわけですね。
html_static_pathを拡張から変更すべきでないという意見も知りました。


  1. By default, Sphinx copies static files on the static/ directory of the template directory.」とありますが、これはテーマのテンプレートディレクトリの話(Sphinx拡張の静的ファイルとは別の話題)と理解しました
  2. https://github.com/attakei/sphinx-revealjs/blob/v3.2.0/sphinx_revealjs/builders.py#L70-L72