Sphinxをマークダウンで使うためのrecommonmarkをMySTへ移行した際のメモ

[趣味で書いているPythonライブラリ](https://github.com/simon-ritchie/apysc)のドキュメントはSphinx + マークダウン（recommonmark）を使っていたのですがいつのまにかrecommonmarkがdeprecatedとなっておりMySTへ移行したのでその際に発生した作業や引っかかった点などを記事にしておきます。

# recommonmarkの状況

過去のSphinx + マークダウン環境設定の記事などだと割とrecommonmark前提のものが多かった気がしますが、一方でrecommonmarkは現在以下のようにdeprecatedとされておりMySTへの移行が推奨されています。

> Warning: recommonmark is now deprecated. We recommend using MyST for a docutils bridge going forward. See this issue for background and discussion.

https://github.com/readthedocs/recommonmark

公式がサポートを停止した経緯ややりとりは以下で色々されています。

https://github.com/readthedocs/recommonmark/issues/221

今までサポートしてくださったことやSphinxでマークダウンを使うきっかけを作ってくれたことに多大な感謝をしつつ、今後色々とアップデートなどを受けていく場合にはrecommonmarkの皆さんが推奨しているMyST（もしくは他のライブラリ）へと移行する必要があります。

# MySTとは

どうやらマークダウンの方言の1つのようです。

基本的なマークダウンの記述は書けて、その他通常のマークダウンには無い機能なども使用できるようです。例えば以下の記事などを拝見していると、コードブロックで行番号の表示等も行えるようです。

https://qiita.com/Tachy_Pochy/items/53866eea43d0ad93ea1d

# 移行で必要になる作業

## MySTのパーサーのインストール

まずはMySTのパーサーのPythonライブラリのインストールが必要になります。本記事執筆時点では最新版であった0.18.0のバージョンを使用しています。pipでインストールが効きます。

```
$ pip install myst-parser==0.18.0
```

## conf.pyの調整

続いてSphinxの設定ファイルのconf.pyを調整していく必要があります。ライブラリでのコミットログを見直してみると以下のような修正になっています。

https://github.com/simon-ritchie/apysc/commit/6fc8a41ba4a10c3ff07305367f133cd6354e100e

まずはEXTENSIONSの設定です。`'recommonmark'`が指定されていたと思われますがそちらを消して`'myst_parser'`を加えます。

```py
EXTENSIONS: List[str] = [
    'myst_parser',
]
```

`source_parsers`の指定にも`'.md': CommonMarkParser,`といった記述が必要でしたが単純に要らなくなるので削除します。移行後は以下のように設定を空にしています。

```py
source_parsers: Final[Dict[str, type]] = {}
```

また、setupの関数内にrecommonmarkでのindex.mdなどからのtoctree自動生成のための設定で以下のような記述（プロジェクトごとによって細かい設定は異なるとは思います）があると思いますがこちらもrecommonmark特有の機能となるため削除します。

```py
from recommonmark.transform import AutoStructify

...

def setup(*, sphinx: Sphinx) -> None:

...

    sphinx.add_config_value(
        name='recommonmark_config',
        default={
            'auto_toc_tree_section': 'Table of contents',
        },
        rebuild=True)
    sphinx.add_transform(AutoStructify)

...
```

## toctreeとして扱うリンクを書き換える

今まではindex.md内での特定の節のリンクがrecommonmarkの機能で自動でtoctreeとして扱われていたりしていましたが、今後は以下のようにMyST用の独特な記述に差し替える必要があります。

````markdown
```{toctree}
:maxdepth: 1
int_and_number
int_and_number_arithmetic_operations
int_and_number_comparison_operations
string
string_comparison_operations
```
````

`{toctree}`を含んだコードブロックの箇所にはtoctreeで扱うための各ファイル名（場合によってはパスを含み、そして拡張子を除く）を記述する必要があります。例えば`string.md`というファイルが`index.md`のファイルと同じ階層にあれば`string`という行を`{toctree}`のコードブロック内に含める必要があります。

これらの記述はtoctree用として扱われるだけでなくドキュメントをビルドすると以下のようにリンクに差し変わります。リンクのラベルは`<h1>`相当の見出し相当（1つだけの`#`部分）の部分の文字列が使われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228778/b67cd187-41be-3328-ce71-c7523044e4b6.png)

また、`:maxdepth: 1`といった部分の指定はリンクとして何階層までの見出しをリンクで表示するかといった指定になります。1を指定すれば`<h1>`相当（1つだけの`#`部分）の見出しがリンクとして表示され、2を指定すれば`<h1>`と`<h2>`相当（2つの`#`部分まで）の見出しがリンクとしてindex.md内に表示されます（`{toctree}`部分のコードブロックが置換されます）。

# 移行してみてどうだったか

移行してみて感じたことを以降の節で少し触れておきます。

## ビルドはドキュメント全体対象にならなくなり快適になった

Sphinxでマークダウンを使用すると今まではビルドが全体的に実行されることが多かったように感じています。コマンドを調整したりしていたものの、英語版は問題なくともなんだか日本語版が全体的にビルドが走ったりしており「なんでだろう・・・？」と感じていました。
ドキュメント量が少ないうちは問題がありませんでしたがページ数が増えるにつれて全体的にビルドが走るのが処理時間が段々と気になってきていました。

この辺がMySTに移行したら改善し、想定通り更新したページのみビルドが走るようになりました。

この辺はもしかしたら以下の辺りが関係しているのかも？と思っていますが、英語版は普通に部分的なビルドになっていたので私の場合は別の要因だったかもしれません。

https://qiita.com/AngryMane/items/6c1a5c8847f62bad7897

## レイアウト崩れなどは今のところ発生していない

とりあえず現時点までに確認した限りではビルド結果でレイアウト崩れなどは発生していません。
使っていたSphinxテーマなどもそのまま動作しています。

この辺りは影響が少なくて良かったです。

## index.md内でのリンクで記号が使えるようになった

今まではrecommonmarkの目次設定（toctree）をindex.md内の指定した節のリンクから作成する（AutoStructify？）・・・という機能を使っていたのですが、その場合アンダースコアなどが含まれているとリンクの文字列が一部消えたりしていて特殊な制御が必要になっていました。

その辺が移行後はシンプルにリンクの文字列内に記号が使えるようになりました。

# 参考サイト・参考文献

https://myst-parser.readthedocs.io/en/latest/index.html

https://github.com/readthedocs/recommonmark

https://github.com/readthedocs/recommonmark/issues/221

https://qiita.com/AngryMane/items/6c1a5c8847f62bad7897

https://qiita.com/Tachy_Pochy/items/53866eea43d0ad93ea1d

https://qiita.com/AngryMane/items/6c1a5c8847f62bad7897

https://qiita.com/ousttrue/items/82650a13a3d488806984