WordPressでプラグインなしでLatex数式を表示する方法 script対応

WordPress

基本的なMathJaxの使い方

基本的なMathJaxの使い方については、以下の記事で紹介しています。

上記の記事で紹介した方法で数式表示できますが、このままの設定では数式部分を、<script type="math/tex">タグで記述した場合には、うまく表示されません。
今回は<script type="math/tex">でも表示するための設定を紹介します。

MathJaxのスクリプトの編集

  1. WordPressダッシュボードにログインします。
  2. 左側のメニューから「外観」を選択し、「テーマエディター」をクリックします。
  3. 右側のファイルリストから「ヘッダー (header.php)」ファイルなどの<head>を編集できるファイルを選択します。
  4. <head>タグの中のスクリプトを以下のように設定します。
<script type="text/javascript" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>
<script type="text/javascript">
  window.MathJax = {
    tex: {
      inlineMath: [['$', '$'], ['\\(', '\\)']],
      displayMath: [['$$', '$$'], ['\\[', '\\]']],
      packages: ['base', 'ams']
    },
    options: {
      renderActions: {
        findScript: [10, function (doc) {
          for (const node of document.querySelectorAll('script[type^="math/tex"]')) {
            const display = !!node.type.match(/; *mode=display/);
            const math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display);
            const text = document.createTextNode('');
            const sibling = node.previousElementSibling;
            node.parentNode.replaceChild(text, node);
            math.start = { node: text, delim: '', n: 0 };
            math.end = { node: text, delim: '', n: 0 };
            doc.math.push(math);
            if (sibling && sibling.matches('script[type^="math/tex"]')) {
              sibling.after(node);
            }
          }
        }, '']
      }
    }
  };
</script>

通常の設定の場合、

<script type="text/javascript" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

の部分のみになります。

その後ろの以下スクリプトを追加することで、<script type="math/tex">で表示可能になります。

<script type="text/javascript">
  window.MathJax = {
    tex: {
      inlineMath: [['$', '$'], ['\\(', '\\)']],
      displayMath: [['$$', '$$'], ['\\[', '\\]']],
      packages: ['base', 'ams']
    },
    options: {
      renderActions: {
        findScript: [10, function (doc) {
          for (const node of document.querySelectorAll('script[type^="math/tex"]')) {
            const display = !!node.type.match(/; *mode=display/);
            const math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display);
            const text = document.createTextNode('');
            const sibling = node.previousElementSibling;
            node.parentNode.replaceChild(text, node);
            math.start = { node: text, delim: '', n: 0 };
            math.end = { node: text, delim: '', n: 0 };
            doc.math.push(math);
            if (sibling && sibling.matches('script[type^="math/tex"]')) {
              sibling.after(node);
            }
          }
        }, '']
      }
    }
  };
</script>

コード詳細

スクリプトの追加

<script type="text/javascript" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

この部分はMathJaxのスクリプトを非同期に読み込むためのコードです。src属性にはMathJaxのCDN(Content Delivery Network)から最新版のスクリプトを取得するURLを指定してます。

MathJaxの設定

<script type="text/javascript">
  window.MathJax = {
    tex: {
      inlineMath: [['$', '$'], ['\\(', '\\)']],
      displayMath: [['$$', '$$'], ['\\[', '\\]']],
      packages: ['base', 'ams']
    },
    options: {
      renderActions: {
        findScript: [10, function (doc) {
          for (const node of document.querySelectorAll('script[type^="math/tex"]')) {
            const display = !!node.type.match(/; *mode=display/);
            const math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display);
            const text = document.createTextNode('');
            const sibling = node.previousElementSibling;
            node.parentNode.replaceChild(text, node);
            math.start = { node: text, delim: '', n: 0 };
            math.end = { node: text, delim: '', n: 0 };
            doc.math.push(math);
            if (sibling && sibling.matches('script[type^="math/tex"]')) {
              sibling.after(node);
            }
          }
        }, '']
      }
    }
  };
</script>
  1. window.MathJaxオブジェクトの設定
    このオブジェクトはMathJaxの設定を行います。

  2. texオブジェクト

  • inlineMath:インライン数式の始まりと終わりの記号を指定します。[['$', '$'], ['\\(', '\\)']]は、$...$および\(...\)の形式をインライン数式として認識する設定です。
  • displayMath:ブロック数式の始まりと終わりの記号を指定します。[['$$', '$$'], ['\\[', '\\]']]は、$$...$$および\[...\]の形式をブロック数式として認識する設定です。
  • packages:MathJaxで使用するパッケージを指定します。['base', 'ams']は、基本的なTeXパッケージとAMS(American Mathematical Society)の拡張パッケージを使用する設定です。
  1. optionsオブジェクト
  • renderActions:MathJaxのレンダリングアクションを設定します。
    • findScript:MathJaxがページ内の<script type="math/tex">タグを探して処理するためのカスタムレンダリングアクションを定義しています。
  1. findScript関数
  • querySelectorAll<script type^="math/tex"]タグをすべて取得します。
  • node.type.match(/; *mode=display/)mode=displayが設定されているかどうかを確認します。
  • new doc.options.MathItem(node.textContent, doc.inputJax[0], display):MathJaxのMathItemオブジェクトを作成します。node.textContentは数式の内容を取得し、displayは数式がブロック表示かインライン表示かを示します。
  • document.createTextNode(”):空のテキストノードを作成し、元の<script>タグを置き換えます。
  • math.startおよびmath.end:数式の開始と終了を示すノードを設定します。
  • doc.math.push(math):作成したMathItemオブジェクトをMathJaxの数式リストに追加します。
  • sibling.after(node):連続する<script type="math/tex"]タグを正しく処理します。

この設定により、MathJaxが<script type="math/tex"]タグ内の数式を正しく認識し、レンダリングします。また、$...$$$...$$といった始まりと終わりの記号を使用する数式も正しく表示されます。

数式の記述

投稿やページに数式を埋め込む際に、以下のように記述します。

<p>インライン数式: \(100 \times (1 + r_1)(1 + r_2)(1 + r_3) + 100 \times (1 + r_2)(1 + r_3) + 100 \times (1 + r_3)\)</p>

<p>ブロック数式:</p>
$$
100 \times (1 + r_1)(1 + r_2)(1 + r_3) + 100 \times (1 + r_2)(1 + r_3) + 100 \times (1 + r_3)
$$

また、<script type="math/tex">タグを使って数式を記述することもできます。

<script type="math/tex">
100 \times (1 + r_1)(1 + r_2)(1 + r_3) + 100 \times (1 + r_2)(1 + r_3) + 100 \times (1 + r_3)
</script>
python-markdownを使って、マークダウンファイルをHTMLに変換するとデフォルトでは数式が`script type=”math/tex”`になるので、ぜひこの設定を試してみてください。
タイトルとURLをコピーしました