各 index.html へのリンクが不親切
MkDocs は以前記事で触れた通りとても便利な Markdown で文書を生成するツールなのだが、MkDocs で複数の Markdown ドキュメントをリンクする形 ([xxx](yyy)
形式での .md
ファイル間のリンク) にするとリンクが意図通り作成されない。
具体的には <a href="hoge/index.html">
のようになってほしいところが <a href="hoge/">
のように生成されてしまう。
生成された HTML ドキュメントを Web サーバ上に配置した場合は hoge/
形式でも正しく表示されるのだが、ローカルに置いた形でブラウザを起動してみる (つまり file:///C:/Users/fuga/hoge/...
のような形式の URL) だと例えば hoge/
を開くとその直下の index.html
が暗黙的に呼び出されるのではなく hoge/
ディレクトリ以下のファイル一覧が表示されてしまう。
この挙動に関しては MkDocs でマテリアルデザインな Markdown ドキュメントサイトを作ろうにも以下のように書いてある:
Webサーバに載せることが前提
>MkDocsで生成した静的サイト用ファイルは、ローカルでindex.html
を開く使い方は想定されていません。 開くことと表示することはできますが、リンクから他の記事に遷移することができません。 これはMarkdownファイルへのリンクが./TheTitle/
のように張られており、ファイルプロトコル上では これが./TheTitle/index.html
と解釈されず、正しく表示できません。
理屈はわかるが、HTML ドキュメントを生成したからといって Web サーバを立てて使うとは限らない。 何とかローカルで見たい。
index.html を正しく補ってやる
というわけで対象となるリンクを正しく置き換える Python スクリプトを書いた:
import glob, os, re
# MkDocs がビルドした HTML が置かれているディレクトリ
SITE_PATH = 'C:/Users/fuga/hoge/site'
# ルート index.html と各フォルダに分かれている index.html を対象とする
files = glob.glob(os.path.join(SITE_PATH, 'index.html')) + glob.glob(os.path.join(SITE_PATH, '*', 'index.html'))
for file in files:
# HTML 読込
with open(file, 'r', encoding='utf-8') as fp:
html = fp.read()
# index.html を付与
html2 = re.sub(r'href="(.*?)/"', 'href="\\1/index.html"', html)
# . と .. というリンクもあるのでそれも index.html を付加する...
html3 = html2.replace('href=".."', 'href="../index.html"').replace('href="."', 'html="./index.html"')
# HTML 書込
with open(file, 'w', encoding='utf-8') as fp2:
fp2.write(html3)
これを適当な名前で保存 (例えば mkdocs_converter.py
) し、ソース内の SITE_PATH
を MkDocs の site ディレクトリに書き換え python3 mkdocs_converter
のように実行すれば変換される。
2020/07/30 追記: 設定一発で解決できる
実は設定一発で解決できた。 拙記事を参照されたい。