GitLabで数式もプレビュー可なMarkdownブログ環境(続)

前回(👇)の続き。さらに改善。

blog.sgry.jp

実現したいこと(前回の内容)

以下の要件を満たすような GitLab で数式もプレビューできる Markdown 文書執筆環境…もといブログ環境を実現したい。

  1. ブログ原稿を Markdown で書ける
  2. 原稿ファイル一式は git で管理できる
  3. 静的サイトジェネレータを使い、サーバーサイドプログラム・データベースを不要とする(GitLab Pages で公開したい)
  4. 記事中のプログラムコードをシンタックスハイライトできる
  5. 記事中の数式を MathJax または KaTeX でレンダリングできる
  6. ローカル環境で原稿の Markdown ファイル編集中に、リアルタイムで記事中のプログラムコード、数式、画像がレンダリングされた形でプレビューできる
  7. 数式の記述にあたり TeX 命令をエスケープせず素直に書ける(Markdown の書式との兼ね合いで \left\{\left\\{ と書かなくてはならなかったりするのは嫌)

要件 1、2、3 についてはブログ作成に使える静的サイトジェネレータを採用すれば良く、 要件 4 と 5 についても、そういう機能が(プラグイン等を含め)備わったものを選べば良いだけなので簡単だ。 しかし要件 6 と 7 を満たそうとすると、急に難しくなってくる。 最初に使っていたのは Hugo で、色々試したけれど 7 を実現できず、断念した。 続いて試したのは Nikola で、markdown_katex を併用することで要件をすべて満たすことができた。 なお Pelican も試したけれど基本的に Nikola と同様で、ただし <!-- more --> を使おうとすると面倒があり、 Nikola の方が良いなと思った次第。

さあ、これで万事解決…と思っていたのだけれど…。

数式関連の対応

少し使ってみたところ、markdown_katex の動作が重さが目立ち始め、数式が増えるにつれて苦痛を感じるようになった。 数式を多用した投稿のレンダリングに十数秒といったレベルの待ちが発生していたため(数式が無ければミリ秒単位で終わる)、 Nikola を採用したばかりでテーマなどのカスタマイズを試行錯誤していた自分にとっては強いストレスになった。 気になったので v202009.1026 のソースを読んでみたところ、どうやら埋め込まれた数式一つ一つに対して node.js のプロセスを起動して KaTeX のレンダリング処理を走らせているようだった。しかも、出力をパイプで処理せず一時ファイルに出力し、 その内容を読み出して Markdown のレンダリング処理に戻している。 Nikola は文書を並列処理しないようだから、これを全文書全数式に対してシーケンシャルに実行してくわけだ。 …そりゃあ遅いのは当然だね。

この状況を解決したかったので、markdown_katex の代わりとなる 「markdown_math_escape」 を勢いで書いて公開した。 個人的には数式をサーバーサイドでレンダリングしたいとは思っていなかったため、 この拡張機能は GitLab スタイルで書かれた数式が書いたとおり HTML に出力されるよう保護するだけのものとした (通常、Markdown の書式と TeX の書式は一部衝突するので特殊なエスケープ記法が必要になる)。 そんな処理内容なので、処理時間についても有効化しているかどうか気付けない程度には速い。

なお、ブログは原稿を push するたびに GitLab CI で GitLab Pages にデプロイしたかったので pip install できるよう PyPI に登録済み。

画像関連の対策

Visual Studio Code、GitLab、Nikola のいずれも ![説明](URL) という書式を使えば Markdown 中の画像ファイルを表示してくれる。 ただ、ブログの記事でこれをやると「ただ画像が表示されるだけ」となる。 Nikola の shortcode などを使えば大きな画像の縮小表示なども実現できるのだけれど、 そういう特殊な命令を使ってしまうと VSCode や GitLab でプレビューできなくなる。 両立できないかな、と考えた結果、最終的に今回は画面ロード直後に表示サイズ上限の適用や画像ファイル自体へのリンクを自動挿入するような JavaScript を書いてテーマの一部としてロードさせるようにした。 ページを開いた直後は一瞬だけ大きな画像が表示されてしまうので改善の余地が多々あるのだけれど、 まあ取り急ぎは良いかなと思っている。

実現した環境

まとめると、最初に書いた 7 要件は Nikola + markdown_math_escape, VSCode + Markdown+Math, GitLab の組み合わせでもって解決できた:

  1. ブログ原稿を Markdown で書ける
    • Nikola の採用で解決
  2. 原稿ファイル一式は git で管理できる
    • GitLab に、Nikola のプロジェクトファイル群一式を普通に登録・管理して解決
  3. 静的サイトジェネレータを使い、サーバーサイドプログラム・データベースを不要とする(GitLab Pages で公開したい)
    • Nikola の採用で解決
  4. 記事中のプログラムコードをシンタックスハイライトできる
    • Nikola の標準機能で、プログラムコードを Pygments で事前レンダリングして解決
  5. 記事中の数式を MathJax または KaTeX でレンダリングできる
    • Nikola の標準機能で、KaTeX 連携を有効化して解決(CDN からのダウンロード+自動実行のタグを挿入)
  6. ローカル環境で原稿の Markdown ファイル編集中に、リアルタイムで記事中のプログラムコード、数式、画像がレンダリングされた形でプレビューできる
    • VSCode に、拡張機能 Markdown+Math を入れて使うことで解決(設定値 mdmath.delimitersgitlab にする)
  7. 数式の記述にあたり TeX 命令をエスケープせず素直に書ける
    • 拙作の Python-Markdown 拡張機能 markdown_math_escape で解決(設定値 delimitersgitlab にする)

最後に

結局のところ、こういうモノは使い続けないと分からないことが多い。 なので、またしばらく使ってみようと思う。 本当に使い心地が良いようなら、そちらに引っ越しかなぁ。