NuxtjsとMathJaxで数式エディタの簡単なサンプルを作成しました。
MathJaxについて
MathJaxはすべてのブラウザで動作する数学用のJavaScript描画エンジンです。
MathJax.jsをCDNで読み込むとHTML内の文章からTeX形式の文を変換します。
<h4>The Lorenz Equations</h4>
<p>
\begin{align}
\dot{x} & = \sigma(y-x) \\
\dot{y} & = \rho x - y - xz \\
\dot{z} & = -\beta z + xy
\end{align}
</p>
<h4>A Cross Product Formula</h4>
<p>\[
\mathbf{V}_1 \times \mathbf{V}_2 =
\begin{vmatrix}
\mathbf{i} & \mathbf{j} & \mathbf{k} \\
\frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\
\frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0 \\
\end{vmatrix}
\]</p>
こんな感じのHTMLを書いておき、MathJax.jsを読み込むと下のように数式に変換してくれます。
数式右クリックするとメニューが開きTeXを確認できる。
今回のようにエディタとして使う場合は、入力からTeXを変換して描画する必要があります。
Vueでエディタを作るサンプルは見つかるのですが、自分の環境で実行できなかった。
幾つか試してnpmのvue-mathjax
を使う方法でできました。
MathJaxをCDNから利用する
NuxtにMathJaxを導入します。
このブログに専用のページを作ってそこで動作するようにしました。npmで導入する方法が分からなかったのでCDNから導入します。クエリパラメータのconfig=TeX-AMS-MML_SVG
は出力を指定しています。この例ではSVGに変換します。
export default {
head() {
return {
script: [
{
src: "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS-MML_SVG"
}
],
};
},
また、コンフィグを設定する場合はcreated()
の中で設定する。
MathJax.Hub.Config({..});
と設定しようとMathJax is not defined
が出るため、if (process.browser) {}
の中で宣言すると可能。(参考:【Nuxt.js】ReferenceError: window is not defined ってエラーが出た)
export default {
...,
created() {
if (process.browser) {
window.MathJax.Hub.Config({
// MathJaxの設定
extensions: ["tex2jax.js"],
jax: ["input/TeX", "output/HTML-CSS"],
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
processEscapes: true
},
"HTML-CSS": { fonts: ["TeX"] }
});
}
},
これでHTML内のTeXを変換してくれます。
TeXエディタを作る
まず、npmのvue-mathjaxをインストールする。 これを使うと数式をリアルタイムで編集できます。
npmのデモの様子。
# install
$ npm install --save vue-mathjax
単体では動かず、Mathjax.jsのインストールも忘れないように。今回はCDNを上述のように取り込んでます。
作成したエディタのコードを載せます。 CSSフレームワークとしてBulmaを利用している。
<template>
<article class="section body">
<div class="field is-horizontal">
<div class="field-label">
<label class="label">LaTeXを入力</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<!-- TeXの入力フォーム -->
<textarea
class="textarea"
v-model="formula"
placeholder="e.g. $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$"
></textarea>
</div>
<p class="help">
TeX形式は
<code>$...$</code> または
<code>$$...$$</code> と区切り文字で囲って下さい。
(さらに
<code>\(...\)</code>と
<code>\[...\]</code>も対応しています )
</p>
</div>
</div>
</div>
</article>
<article class="section body">
<div class="field is-horizontal">
<div class="field-label">
<label class="label">変換結果</label>
</div>
<div class="field-body">
<div class="field is-narrow">
<div class="control">
<!-- 数式の出力先 -->
<vue-mathjax :formula="formula"></vue-mathjax>
</div>
</div>
</div>
</div>
</article>
</template>
<script>
import { VueMathjax } from "vue-mathjax";
export default {
components: {
"vue-mathjax": VueMathjax
},
head() {
return {
script: [
{
src:
"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS-MML_SVG"
}
]
};
},
created() {
MathJax;
if (process.browser) {
window.MathJax.Hub.Config({
// MathJaxの設定
extensions: ["tex2jax.js"],
jax: ["input/TeX", "output/HTML-CSS"],
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
processEscapes: true
},
"HTML-CSS": { fonts: ["TeX"] }
});
}
},
data() {
return {
formula: `When $a \\ne 0$, there are two solutions to $$ax^2 + bx + c = 0$$ and they are
$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$
};
}
};
</script>
これでデモのように実行できました。
おわりに
TeX形式の数式をブラウザで表示するプラグインは、MathJaxの他にKaTeXがあります。
- KaTeXはHTML形式で表現しており、数式のレンダリングがかなり早い特徴を持っています。
- MathJaxはレンダリング速度ではKaTeXにかないませんが、右クリックのメニューからTeXのソースを表示やSVGで出力できると機能が豊富です。
個人的にはKaTeXが使いやすい印象ですが、今後、比較してまとめたいと考えてます。