gatsby-plugin-mdxでKaTeXを使えるようにする

2022/03/09

最近マークダウンのレンダラをgatsby-transformer-remarkからgatsby-plugin-mdxに変えた。

当初はどうせマークダウンで書くなら独自仕様を避けたプレーンな形式にしておけば後から簡単にObsidianに移行したりも出来るからなるべくそうしようと思ってたんだけど、よく考えたらブログ記事をObsidianに移行することって多分永遠にないよね🤔?笑

そう考えるとPlotlyのグラフとかもサクッと書いて記事に埋め込めるようになって素敵だしもういっそのことMDXにしよう、みたいな。

実行環境の制約はあれどMDX自体もポータブルなのは変わらないしね。

MDXすごいよね、最初知った時はマークダウンにJSXが直接書けるって何事!?って思って超びびったよ。笑

文章書いてる流れのままJSXコンポーネントも挟めるってマジで革命的だと思う。

万が一記事中に突然クリックカウンターを表示したくなった時だってMDXならこの通り…!!

KaTeXだけ動かない問題

レンダラの移行自体は思ったより全然手間取ることなくサクッと出来た。

  • gatsby-transformer-remarkgatsby-plugin-mdxに差し替える
    • これまで書いてきた.mdも読み込むようにextensions['.md', '.mdx']に指定する
  • remarkのpluginsに入れてたやつらをmdxのgatsbyRemarkPluginsに引っ越す
  • プロパティ名変わるところ変える
    • allMarkdownRemarksallMdx
    • markdownRemarkmdx
    • post.bodypost.html

ほぼほぼこれだけ。

ただ1点だけ、数式の表示に使っていたgatsby-remark-katexだけはどうしてもmdxと一緒に動かすことができず。

でもちょっと調べて工夫したらいけたので備忘録がてらにメモ。

対象のバージョン

gatsby@4.9.3 gatsby-plugin-mdx@3.9.1

先に結論

gatsby-remark-katexを使うのをやめてremark-mathrehype-katexを使うと上手くいく。

現時点ではremark-mathは4系, rehype-katexは6系が最新なんだけど、ポイントは1つ古いメジャーバージョンのremark-math@3.0.1rehype-katex@5.0.0を使うこと。

そうすることで依存関係の不具合が解消されて動くようになる。

ちなみに肝心のkatexrehype-katexのdependencyとして一緒にくっついてくるのでgatsby-remark-katexの時みたいに明示的にインストールしなくても大丈夫。

やり方

npm install remark-math@3.0.1 rehype-katex@5.0.0
gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: 'gatsby-plugin-mdx',
      options: {
        remarkPlugins: [
          require('remark-math'),
        ],
        rehypePlugins: [
          require('rehype-katex'),
          // オプションを渡したい時はタプル形式で
          // [require('rehype-katex'), { strict: 'ignore' }],
        ],
      }
    }
  ]
}
gatsby-browser.js
import 'katex/dist/katex.min.css'

これでMDX環境でもKaTeX\Large \KaTeXが書ける。やったね!

もうちょっと細かい説明

gatsby-remark-katexが動かない理由

そもそもremark系のプラグインのほとんどがgatsby-plugin-mdxでも動作するんだからgatsby-remark-katexもしれっと動いてほしいところだよね。

この書き方で上手くいってほしい!けど動かない😇

gatsby-config.js
/* 動かないパターン */
module.exports = {
  plugins: [
    {
      resolve: 'gatsby-plugin-mdx',
      options: {
        gatsbyRemarkPlugins: [
          'gatsby-remark-katex',
        ],
      }
    }
  ]
}

原因はgatsby-plugin-mdxで利用している@mdx-js/mdxの1系で使われてるremarkが1つ前の12系だから。

よく見るとGatsbyのログの中でもバージョン上げないと動かないよって言ってくれてるね。

Gatsbyのログ
warn [remark-math] Warning: please upgrade to remark 13 to use this plugin

remark-mathというのはgatsby-remark-katexの中で使われているモジュールなんだけど、これが4系だとremarkの方は13系以上の必要があるみたい。

だから逆にgatsby-remark-katexを使わずに12系に対応したremark-mathのバージョンを直接使うようにすればとりあえずいけるってわけね。

@mdx-js/mdxのissue見た感じだとv2からはremarkも13系にアップデートされてるみたいだからgatsby-plugin-mdxが対応し次第自然に解消されるはず…なんだけど少し時間がかかるかもね。

MDX v2: ☂️ Umbrella issue #1041

ってゆーかremarkの13系以上を前提にしてるプラグインをMDX環境で使おうとすると全部同様の問題にぶつかる可能性があるってことかな?覚えておこう。

remark-mathrehype-katexなに

↓こういうことみたい。

  • remark-math
    • md→html変換の際に$でくくられた部分をLaTeX表記のブロックに変換する
    • 例) $\frac{1}{N}$<span class="math math-inline">\frac{1}{N}</span>
  • rehype-katex
    • 変換されたhtmlを受け取ってLaTeX表記の部分にKaTeXのスタイルを当てる
    • 例) <span class="math math-inline">\frac{1}{N}</span>1N\Large \frac{1}{N}

mdから変換したhtmlに対して色々する系の処理をremarkではrehypeって言うみたいだね。これも覚えとこ。