nikkie-ftnextの日記

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

sphinx-new-tab-link 0.3.0 をリリースしました🦋 フォーマットがHTMLの任意のビルダーと(おそらく)一緒に使えます!

リリース報告エントリです。
sphinx-new-tab-linkとはなんだろう」という方は、以下の記事をまずどうぞ!

目次

pydata-sphinx-themeの実装を参考に、再実装しました。
https://github.com/ftnext/sphinx-new-tab-link/releases/tag/v0.3.0

動的にクラスを生成して、Translatorに指定する

pydata-sphinx-themeは、動的に生成したTranslatorクラスをビルダーに指定するという見事な実装をしています。

これを丸パクリしました。

これまでの実装

  • Sphinxが提供するHTMLTranslatorを継承したNewTabLinkHTMLTranslator
  • setup()関数1の中で、html・dirhtml・singlehtmlの各ビルダーに指定2

今回の再実装

  • NewTabLinkHTMLTranslatorMixinを定義(HTMLTranslatorは継承しない)
  • builder-initedイベント3を契機に、ビルダーのTranslatorを置き換える
    • ビルダーのTranslatorに指定されたクラスに、動的にNewTabLinkHTMLTranslatorMixinを継承して置き換え
    • このロジックはビルダーの出力フォーマット4がHTMLの場合のみ適用

これにより、メソッド代入は不要になりました。
ハックを重ねて汚くしていた5ので改善です!
sphinx_new_tab_link拡張を有効にする(conf.pyのextensionsに書く)だけでよくなっています6

なお、0.2.2 で無限の再帰エラーを発生させてしまった7ので、報告元のnjabリポジトリをcloneしてきて 0.3.0 でデグレていないことを確認しています

気づいたこと

システムは2度死ぬ

そーだいさんのスライドより

今回再実装をしたので、当初の実装は死んだ(一度目)のだと思います。
この先もう一回何かあるのかな?

ビルダーのTranslatorにMixinを動的に継承して置き換えるという実装にしたことで、sphinx-new-tab-linkはフォーマットがHTMLのビルダー全てと合わせて使えるようになったと思われます。
(すべてのパターンは確認しきれないので、私の見落としにお気づきの際はバグ報告ください!)

その一例が、発表資料づくりでお世話になっているsphinx-revealjs8
conf.py に以下のように書くだけで、Reveal.js製スライド中の外部リンクがブラウザの別タブで開くようにできます9!🙌

extensions = [
    "sphinx_revealjs",
    "sphinx_new_tab_link",
]

これまでのsphinx-new-tab-linkはサポートしているビルダーが3つ(html・dirhtml・singlehtml)だけでした。
sphinx-revealjsはrevealjsビルダーを追加しています。

revealjsビルダーはフォーマットがHTMLと過去に分かっています10
そのためsphinx-new-tab-linkの再実装により、組合せて使えるようになりました。
sphinx-revealjs-new-tab-linkのようなものを作る必要があるのかなと思いながら動けていなかったのですが、今回pydata-sphinx-themeをパクったことで実現できました!
ありがとう、pydata-sphinx-theme

終わりに

sphinx-new-tab-link 0.3.0のリリース報告をしました。
pydata-sphinx-themeのソースで知った、ビルダーのTranslatorにMixinを動的に継承して置き換える実装に変更しています。
これにより、フォーマットがHTMLのビルダーと簡単に組合せられるようになりました!(一例がsphinx-revealjs)

pydata-sphinx-themeの実装は見事だったので真似したわけなのですが、これにより思ってもみなかった視界の開け方をしました11
sphinx-new-tab-linkは、フォーマットがHTMLの任意のビルダーと一緒に使えるんです!
よさそうな実装を見つけたから試しただけなんですが、至った実装(v0.3.0)はめちゃくちゃ可能性を秘めていると思います。

sphinx-new-tab-linkという蛹から蝶が羽化しました。
それはそれは美しい羽を持った蝶で、その羽で私の考えが及ばないところまで飛んでいけるでしょう。
この蝶の進路を妨げるものは何もないように見えていて、遠くへ飛び去っていってしまうことを予感させます(親心から来る若干の寂しさ)


SphinxでビルドしたHTMLの中の外部リンクをブラウザの新しいタブで開きたい」方はよろしければお試しください(pip install sphinx-new-tab-link)。
触ってみた感想や「こういうユースケースで使いたいんだけどサポートしてくれないか」といった要望、そしてリポジトリへのスターも、お待ちしています!

応援ください


  1. Sphinx拡張の肝はsetup()関数です
  2. 開発の中でdirhtmlをサポートしました
  3. ビルダーオブジェクトが作成された時に発行されます」 ref: https://www.sphinx-doc.org/ja/master/extdev/appapi.html#event-builder-inited ここから、このイベントのタイミングではユーザがビルダーが指定済みと理解しました
  4. builderのformat属性 https://www.sphinx-doc.org/ja/master/usage/builders/index.html
  5. どうか私の罪をお許しください
  6. 詳細が知りたい方はテストケースの実装をどうぞ https://github.com/ftnext/sphinx-new-tab-link/tree/v0.3.0/tests/roots/test-method-assignment
  7. 0.2.3 で修正済み
  8. 設定例です
  9. 実際の設定例:https://github.com/ftnext/2024-slides/blob/e1e90edc150928269134de5796d5beb56b3fe946/source/conf.py#L20-L26
  10. 実装を見て確認しました
  11. 私のUnknown Box、開いちゃった!