はじめに
Sphinx、全然理解せずに使ってたな… nikkieです。
ドキュメント変換ツールSphinx、私は執筆や発表資料作成でもヘビーユースしています。
シンタックスハイライトしたコードの表示はcode-block
ディレクティブ1やliteralinclude
ディレクティブを使ってきたのですが、このたびあと2つあることを知りました。
このエントリの流れとしては知った順に見ていきますが、「終わりに」に4つをまとめています。
目次
- はじめに
- 目次
- 前提
- すでに知っていたcode-blockディレクティブ
- すでに知っていたliteralincludeディレクティブ
- 存在を初めて知ったdoctest block
- 存在を初めて知ったliteral block
- highlightディレクティブというものがある!
- 終わりに
- P.S. parsed-literalディレクティブ
前提
Sphinxのドキュメントのユーザガイドの中に、reStructuredTextについてのページ2があります。
その中の「ディレクティブ」というドキュメントの「コードサンプルの表示」セクションを参照しました。
ここに4つ紹介されています
There are multiple ways to show syntax-highlighted literal code blocks in Sphinx:
動作環境
Sphinx 6.1.3で検証しました。
今回素振りしたreSTファイルはこちらにあります:
すでに知っていたcode-block
ディレクティブ
https://www.sphinx-doc.org/ja/master/usage/restructuredtext/directives.html#directive-code-block
これまでずっと、以下のような形でコードを書いていました3。
.. code-block:: python >>> print("spam") spam
このディレクティブはSphinxのディレクティブです。
ドキュメント中のoptions部分をぜひ見ていただきたいのですが、コードのスタイルをoptionできめ細かに指定できます。
行番号を表示したり、指定した行を強調したり、クロスリファレンスできるようにしたりといろいろできます。
すでに知っていたliteralinclude
ディレクティブ
https://www.sphinx-doc.org/ja/master/usage/restructuredtext/directives.html#directive-literalinclude
ドキュメントに含めたいソースコードがファイル中にある場合、literalinclude
ディレクティブを使っています。
example.pyのコードをドキュメントに含める例です:
.. literalinclude:: example.py
このディレクティブもSphinxのディレクティブです。
code-block
ディレクティブと同様のoptionに加えて、指定した行の範囲や関数のコードだけを含めることもできます!4
私の中では大変重宝しています。
この2つの私の中での使い分けですが、
- ファイルがあるなら
literalinclude
- 最初は手元にファイルがなかったとしても、コード量が多かったり何度も使ったりするならファイルにして
literalinclude
に指定します
- 最初は手元にファイルがなかったとしても、コード量が多かったり何度も使ったりするならファイルにして
- ファイルが必要なければ
code-block
に書く
としています。
存在を初めて知ったdoctest block
https://www.sphinx-doc.org/ja/master/usage/restructuredtext/basics.html#rst-doctest-blocks
なんとPython対話モードからreSTにコピー&ペーストするだけで、doctest blockとして扱われます!
- doctest blockはインデント不要
- シンタックスハイライトされる
>>> 1 + 1 2
いままで対話モードからcode-block
ディレクティブの中にコピペしていましたが、もっと少ない手順で済んだなんて!
これからは非常にお世話になりそうです。
doctest blockは(Sphinxが依存している)docutilsのディレクティブです。
https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#doctest-blocks
存在を初めて知ったliteral block
https://www.sphinx-doc.org/ja/master/usage/restructuredtext/basics.html#literal-blocks
2重のコロン(::
)で終えた行に続くインデントされた行がliteral blockです。
:: >>> 1 + 1 2 前の段落から続けることもできる:: >>> print("this is a Literal block") this is a Literal block
doctest blockに書けるのは対話モードのPythonだけですが、literal block(や他の2つのディレクティブ)にはPython以外のコードも書けます。
literal blockではコードのスタイルはきめ細かには指定できないため、きめ細かく指定したければcode-block
ディレクティブの出番ですね。
literal blockもdocutilsのディレクティブです。
https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#literal-blocks
highlight
ディレクティブというものがある!
https://www.sphinx-doc.org/ja/master/usage/restructuredtext/directives.html#directive-highlight
シンタックスハイライトに使う言語(正確にはPygmentsのlexer5)を指定するディレクティブです。
あるhighlightディレクティブの後は(次のhighlightディレクティブまで)指定した言語でシンタックスハイライトされます。
literal blockも言語指定をしないcode-blockも、highlightディレクティブでの指定が適用されました。
code-block
ディレクティブしか知らなかったので、毎回言語を指定してきましたが、highlight
ディレクティブを知ったおかげで解放されそうです。
また、highlight
ディレクティブのoption linenothreshold
は興味深いです。
「N行以上のコードには一律で行番号表示する」と指定できるoptionと理解しました。
私は行番号を頻繁に使うので、highlight
ディレクティブのおかげでますます楽ができそうです。
.. highlight:: rest :linenothreshold: 1 reSTのハイライトを指定(行番号付きで指定) :: Doctest blockの例 ==================== >>> 1 + 1 2 .. code-block:: Literal blockの例です:: ここがLiteral block
終わりに
シンタックスハイライトされたコードをSphinxで表示する方法を、ようやく完全に理解しました。
- Pythonの対話モードを貼り付けるだけで済む、doctest block
- 末尾
::
の行の後にインデントしてコードを書く、literal block code-block
ディレクティブに続けてコードを書く(きめ細かくスタイル指定できる)- ファイルに書いたコードを
literalinclude
ディレクティブで含める(code-block
同様きめ細かくスタイル指定できる)
手持ちの武器が増えた感覚です。
いままではcode-block
ディレクティブ一本槍で結構無茶をしていたんだな〜
今後作るSphinx製ドキュメントで使っていって、4つを使い分けられる状態を目指します。
よろしくね、私の味方!
P.S. parsed-literalディレクティブ
シンタックスハイライトはされないのですが、コード中にインラインマークアップやリンクを入れられると知りました6。
.. parsed-literal:: >>> # コメントの一部を **強調** >>> 1 + 1 2 >>> # `doctestのドキュメント <https://docs.python.org/ja/3/library/doctest.html>`__ >>> print("parsed-literalディレクティブの練習です") parsed-literalディレクティブの練習です
parsed-literal
ディレクティブというそうで、docutilsのディレクティブです。
https://docutils.sourceforge.io/docs/ref/rst/directives.html#parsed-literal
-
「ディレクティブ」は
.. <ディレクティブ>::
と書いて、インデントした行に内容を書くものというざっくり理解です(精緻にする伸びしろはあると思います)↩ - https://www.sphinx-doc.org/ja/master/usage/restructuredtext/index.html↩
- 先日のdoctestの記事でも使っています。 ↩
- literalincludeディレクティブについてだけで1エントリ書けそうな気がしますね(書けたら書きます)↩
- https://pygments.org/docs/lexers/↩
- 『Sphinxをはじめよう』付録A.30より。ドキュメントと見比べる中で気付きました↩