thumbnail

【超簡単】Next.js+WordPressで数式を記述する方法

Next.js+ヘッドレスCMSで、クラス名をつけるだけでLaTeXで数式の出力ができる方法を紹介します。この記事ではヘッドレスCMS化したWordPressを用い、文章のパースに「html-react-parser」を利用していますが、似たような技術スタックであれば同じことができると思います。

概要

前提となる技術スタック

前提として、ヘッドレスCMSからAPIで受け取った記事の内容を、Next.jsで整形して出力するようなスタイルにおける数式を表示する方法について説明します。そして、この方法はあくまでも一例です。

APIで記事を受け取り本文をNext.jsでパースするのに、ライブラリとして「html-react-parser」を用いている場合の方法を解説します。html-react-parser以外のライブラリでも、指定条件に応じたタグの変換ができるライブラリならば紹介する手法が可能となります。

私は記事をヘッドレス化したWordPressで記述しているので、WordPressでの編集の方法を解説しますが、別に他のCMSでも構わないと思います。

最終的な状態、ゴール

CMS側で記事を書く際、数式にmathというクラスをつけるだけで、LaTeXとして数式が展開される状態になります。

ゴールまでのステップ

大まかに、つぎの3ステップで数式の出力ができます。

ステップ

  1. react-katexのインストール
  2. CMSで数式を展開したい箇所にクラス名をつける
  3. 2で指定したクラス名の箇所をKaTeXのコンポーネントで置き換える

以下、詳しく説明します。

具体的な方法

必要なのものはreact-katexだけ

必要になるのは「react-katex」とその型のライブラリだけですので、次の2つをインストールしておきます。

yarn add react-katex
yarn add -D @types/react-katex

昔はブログで数式を載せるのにMathJaxを用いていましたが、現在はKaTeXが早い軽いで主流だそうです。

react-katexの簡単な説明

使い方は2パターンだけです。インライン展開したい数式なら<InlineMath>タグで囲み、ブロックレベルで展開したい数式は<BlockMath>タグで囲むだけです。

インラインで展開するかブロックで展開するかは、CMSで選択できるようにします。

ブロックレベルとは、次の数式のように、本文とは別の行に数式だけを出力するものです。

ΓFdΓ=S×FdS\oint_\Gamma\mathbf{F}d\Gamma=\iint_\mathbb{S}\nabla\times\mathbf{F}d\mathbb{S}

インラインはこのように、E=mc2E=mc^2と本文中に記述するスタイルです。

CMS側の準備

次のようなルールがあるテキストを、KaTeXとして展開するようにします。

  • pタグでclass名がmathのものは、ブロックレベルで数式を展開する。
  • strongタグでclass名がmathのものは、インラインレベルで数式を展開する、

このルールを実現するために、CMS側で行わなくてはならない作業は、LaTeXで数式を書いてクラス名をつけるだけです。

ブロックレベルの数式

WordPressならばデフォルトで改行すれば出てくる「段落」がpタグで出力される文字列となります。

ここに直にLaTeXで数式を記述します。

クラスをつけます。クラス名は何でもいいのですが、最初のルールで決めたmathにします。

WordPressでは右のエリアから簡単にクラス名をつけられるので、そこにmathと入力するだけです。

インラインレベルの数式

KaTeXで展開したい部分だけを太字(strongタグ)にし、そこだけにmathのクラス名をつけます。太字というのは一例で、他のインラインレベルのHTML要素でも構いません。

CMSでやることは以上です。続いて、Next.js側での準備について解説します。

Next.jsで実装しておくこと

先ほどのルールから、次のように出力タグを変換します。

  • pタグでclass名がmathのものは、<BlockMath>タグに置き換える。
  • strongタグでclass名がmathのものは、<InlineMath>タグに置き換える。
import 'katex/dist/katex.min.css'
import { BlockMath,InlineMath } from 'react-katex'

 const options: HTMLReactParserOptions = {
    replace: ({ name, attribs, children }) => {
    
     // 〜いくつかのコード〜
  
      // ブロックレベルの変換
      if (name === 'p') {
        const { class: clazz } = attribs
        if (clazz && clazz.includes('math')) {
          return <BlockMath>{domToReact(children, options)}</BlockMath>
        }
      }
      // インラインレベルの変換
      if (name === 'strong') {
        const { class: clazz } = attribs
        if (clazz && clazz.includes('math')) {
          return <InlineMath>{domToReact(children, options)}</InlineMath>
        }
      }
    },
  }

includesメソッドでmathクラスの判定を行なってしまっていますが、厳密に行いたいならばmatchとかのほうが良さそうです。あとは、このオプションでパースすれば数式が表示されます。

以上の準備で、クラス名をつけるだけでLaTeXの出力が可能になります。

まとめ

以上が、CMSでクラス名をつけるだけでLaTeXで数式が出力できる方法です。まとめますと、以下の3ステップからなります。

ステップ

  1. react-katexのインストール
  2. CMSで数式を展開したい箇所にクラス名をつける
  3. 2で指定したクラス名の箇所をKaTeXのコンポーネントで置き換える