リリース報告エントリです。
「sphinx-new-tab-linkとはなんだろう」という方は、以下の記事をまずどうぞ!
目次
sphinx-new-tab-link 0.3.0
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の場合のみ適用
- ビルダーのTranslatorに指定されたクラスに、動的に
これにより、メソッド代入は不要になりました。
ハックを重ねて汚くしていた5ので改善です!
sphinx_new_tab_link
拡張を有効にする(conf.pyのextensions
に書く)だけでよくなっています6
なお、0.2.2 で無限の再帰エラーを発生させてしまった7ので、報告元のnjabリポジトリをcloneしてきて 0.3.0 でデグレていないことを確認しています
気づいたこと
システムは2度死ぬ
そーだいさんのスライドより
Unixの哲学にも「システムは2度死ぬ」と書いてある。
— そーだい@初代ALF (@soudai1025) 2023年3月14日
正しく小さく作って "すぐ捨てる" が大事だと古事記にも書いてある。
今回再実装をしたので、当初の実装は死んだ(一度目)のだと思います。
この先もう一回何かあるのかな?
解き放たれたsphinx-new-tab-link
ビルダーの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
)。
触ってみた感想や「こういうユースケースで使いたいんだけどサポートしてくれないか」といった要望、そしてリポジトリへのスターも、お待ちしています!
-
Sphinx拡張の肝は
setup()
関数です ↩ - 開発の中でdirhtmlをサポートしました ↩
- 「ビルダーオブジェクトが作成された時に発行されます」 ref: https://www.sphinx-doc.org/ja/master/extdev/appapi.html#event-builder-inited ここから、このイベントのタイミングではユーザがビルダーが指定済みと理解しました↩
- builderのformat属性 https://www.sphinx-doc.org/ja/master/usage/builders/index.html↩
- どうか私の罪をお許しください ↩
- 詳細が知りたい方はテストケースの実装をどうぞ https://github.com/ftnext/sphinx-new-tab-link/tree/v0.3.0/tests/roots/test-method-assignment↩
- 0.2.3 で修正済み ↩
- 設定例です ↩
- 実際の設定例:https://github.com/ftnext/2024-slides/blob/e1e90edc150928269134de5796d5beb56b3fe946/source/conf.py#L20-L26↩
- 実装を見て確認しました ↩
- 私のUnknown Box、開いちゃった! ↩