ishii-akihiro’s blog

いろいろ試したことやバグ対応の作業履歴を残していきます。

動的にMathJaxを適用する

概要

ユーザが画面に入力したパラメータに応じた数式を表示し、
表示する数式にはMathJaxを適用してTeXっぽくします。

動的に変化させる数式はJavaScriptを利用して作成しますが、
うまくMathJax が適用されずハマったのでメモ。

環境

作成するページのイメージ

題材はフィボナッチ数列です。
---------- ここからイメージ ----------

説明

フィボナッチ数列の一般項は以下の式で表されます。

\begin{align} F_k = \frac{1}{\sqrt{5}} \left\{ \left( \frac{1+\sqrt{5}}{2} \right)^k - \left( \frac{1-\sqrt{5}}{2} \right)^k \right\} \end{align}

フィボナッチ数列の第0項から第n項までの和を計算します。

nに1〜10の整数を入力し、「表示」ボタンを押してください。

\( n = \)

出力結果

---------- ここまでイメージ ----------

ソースコード

ポイントは、JavaScriptMathJax.Hub.Queue を適用することです。
これを適用しないと、上記イメージ「出力結果」の数式が
MathJaxで変換されません。

index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>動的にMathJaxを適用する</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.0.4/math.min.js"></script>
    <script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
    <script src="main.js"></script>
  </head>
  <body>
    <h3>説明</h3>
    <div>
      <p>フィボナッチ数列の一般項は以下の式で表されます。</p>
      <div>
        \begin{align}
          F_k = \frac{1}{\sqrt{5}} \left\{ \left( \frac{1+\sqrt{5}}{2} \right)^k
                      - \left( \frac{1-\sqrt{5}}{2} \right)^k \right\}
        \end{align}
      </div>
      <p>フィボナッチ数列の第0項から第n項までの和を計算します。</p>
      <p>nに1〜10の整数を入力し、「表示」ボタンを押してください。</p>

      \( n = \) <input type="text" id="para_n" size="3" maxlength="2" value=2>
      <button type="button" id="display_button">表示</button>
    </div>

    <h3>出力結果</h3>
    <div id=result></div>
  </body>
</html>

main.js

$(function() {
  
  // 表示ボタン押下時
  $("#display_button").on('click', function() {
    
      var str_formula = "";  // 展開式を格納する変数
      var str_values = "";   // 項ごとに計算した展開式を格納する変数
      
      // 入力パラメータ n を取得して数値に変換
      var n = Number($("#para_n").val());
  
      // n < 1 または n > 10 の場合は警告メッセージを表示して処理終了
      if ( n < 1 | n > 10 ) {
        alert("nは1〜10の整数を設定してください");
        exit;
      }
  
      // 級数和の展開式を作成し、各項の値を加算
      var Fk = 0;       // フィボナッチ数列の第k項(初項を第0項とする)
      var sum = 0;      // k項までの和

      for ( var k = 0; k <= n; k++ ) {
        // 第k項の値を計算
        Fk = (1/Math.sqrt(5)) * ( ( (1 + Math.sqrt(5)) / 2)**k - ( (1 - Math.sqrt(5)) / 2)**k );
        
        // 初項から第k項までの和
        sum += Fk;
  
        // 展開式に第k項を追加
        str_formula += "\\frac{1}{\\sqrt{5}} \\left\\{ \\left( \\frac{1+\\sqrt{5}}{2} \\right)^{" + k + "}"
                      + " - \\left( \\frac{1-\\sqrt{5}}{2} \\right)^{" + k + "} \\right\\} \\newline + ";
                      
        // 展開式(項ごとに計算した値)に第k項の値を追加
        str_values += Fk.toString() + " + ";
      }
      
      // slice(0, -2)で展開式末尾の"+ "を削除
      str_formula = str_formula.slice(0, -2);
      str_values = str_values.slice(0, -2);
      
      // id=result のdiv要素内に、第n項までの和の展開式と答えを追加
      $("#result").html("\\begin\{align\} \n");
      $("#result").append("\\sum_{k=0}^{n=" + n + "} F_k = " + str_formula + "\n");
      $("#result").append(" = " + str_values + "\n");
      $("#result").append(" = " + sum + "\n");
      $("#result").append("\\end\{align\}");
      
      // id=result の要素をMathJaxで変換 ※ここが重要!!!
      MathJax.Hub.Queue(["Typeset",MathJax.Hub,"result"]);
  });
});

まとめ

軽い気持ちでフィボナッチ数列を題材にしましたが、
10年くらいTeXを触っていなかったため余計なところで苦労しました。。

でもTeXライクな数式だと見やすくていいですね!
掲示板で見る数式は、どうもスッと頭に入りません。。

参考

MathJaxの基本からリアルタイムプレビューまで | Coma's Tech Blog

フィボナッチ数 - Wikipedia