LoginSignup
7
7

More than 5 years have passed since last update.

LaTeX数式をブラウザでお試しリアルタイム編集(簡易版)

Last updated at Posted at 2014-12-22

LaTeXの数式をちょこちょこっと編集してリアルタイムに出力結果を見たいという際にはDaum Equation Editorが非常に高機能で便利です。ただ、自分の職場はChrome Web AppもMacアプリも(LaTeXも!)インストールできないPC環境なので、極めて単純な数式リアルタイム編集機能だけではありますが、AngularJSとMathJaxで実装してみました。

デモ
ソースコード

実装手順
(1) JavaScriptライブラリ(AngularJSとMathJax)をページに読み込む。MathJaxは通常ページ読み込み完了時に自動的にTeXコマンドをレンダリングするが、ここではそれを止める必要があるため&delayStartupUntil=configuredをMathJaxのURLクエリパラメータ最後に追記。

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.27/angular.min.js"></script>
<script type="text/javascript"
src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML&delayStartupUntil=configured">
</script>

(2) MathJaxのページ読み込み時自動レンダリングを無効化するための設定(skipStartupTypeset: true)を追加。

<script>
  MathJax.Hub.Config({
    skipStartupTypeset: true,
    messageStyle: "none", 
    "HTML-CSS": {
      showMathMenu: false
    }
  });
  MathJax.Hub.Configured();
</script>

(3) bodyタグのng-app属性にモジュール名を追加、LaTeX入力用のtextareaにng-modelとしてexpressionを追加、数式出力用のp要素にはmathjax-bind属性を追加。

<!-- LaTeXコマンド入力用 -->
<textarea ng-model="expression"></textarea>

<!-- MathJaxレンダリング出力用 -->
<p mathjax-bind="expression"></p>

(4) AngularJSのディレクティブmathjax-bindを作成してtextareaを監視させ、expressionモデルに入っているLaTeXコマンドに変更がある都度、そのコマンドを出力用p要素に挿入するようにする。p要素内のLaTeXコマンドが更新されたら、MathJax.Hub.Queue(["Reprocess", MathJax.Hub, $element[0]]);で即座にMathJaxに再レンダリングさせる。

angular.module("myApp", [])
.directive("mathjaxBind", function () {
    return {
        restrict: "A",
        controller: ["$scope", "$element", "$attrs", function ($scope, $element, $attrs) {
            $scope.$watch($attrs.mathjaxBind, function (value) {
                var $script = angular.element("<script type='math/tex'>")
                .html(value == undefined ? "" : value);
                $element.html("");
                $element.append($script);
                MathJax.Hub.Queue(["Reprocess", MathJax.Hub, $element[0]]);
            });
        }]
    };
})

(5) アクセス時にLaTeX数式コマンドが全く入力されていないとなんとなく寂しいので、デフォルトの数式コマンドをいくつか挿入(JavaScript内ではLaTeXコマンドのバックスラッシュをエスケープするためにダブルバックスラッシュに置き換え)。

.controller("MyCtrl", ["$scope", "$element", function($scope, $element) {
    $scope.expression = "\\frac{5}{4} \\div \\frac{1}{6} \\\\ \n\n";
    $scope.expression += "d\\!f_n(t,T) = \\alpha_n(t,T) dt + \\tau_n(t,T) dW_n^P\\!(t) \\\\ \n\n";
    $scope.expression += "\\zeta(s) = \\sum_{n=1}^\\infty\\frac{1}{n^s} \\\\ \n\n";
    $scope.expression += "% You can define custom macro with 'newcommand': \n";
    $scope.expression += "\\newcommand\\C{{\\mathbb C}} \n\\newcommand\\np[2]{{#1}#2{#1}} \n\\C[y_1,\\ldots,y_n]\\to {\\mathcal A}, \\quad a\\mapsto\\np{:}{a}";
}]);

(6) おまけとしてBootstrapとjQueryで見た目をごまかす調整。

おしまい

参考
http://www.mathjax.org/demos/
https://github.com/mathjax/MathJax-docs/wiki/More-live-preview-examples
http://stackoverflow.com/questions/7925622/display-mathjax-output-in-realtime
http://genkuroki.web.fc2.com/MathJax/LivePreviewMathJax-jquery.html

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7