rehype-mathml
: TeX数式をMathMLにするrehypeプラグイン
この記事は、フラー株式会社 Advent Calendar 2024の7日目の記事です。6日目はsu8のサポート終了間近 しがない30代エンジニアの本棚(2024年版)でした。
はじめに
unified(remark、rehype)を使ってMarkdownをHTMLへ変換する人は多いでしょう。unifiedはGatsbyやNuxt.js、Astroなど、多くのフレームワークで利用されています。
unifiedで数式を扱う場合、Markdown中の$f(x)=ax+b$
のようなTeX(LaTeX)数式をremark-math
で見つけ、rehype-mathjax
やrehype-katex
でMathJaxやKaTeXにより表示できる形式に変換するのが一般的です。
ブラウザで数式を表示するために、HTMLにMathMLを記述する方法があります。KaTeXは数式表示のためのHTMLに変換するだけでなく、MathMLへの変換もサポートしています。しかし、KaTeXは少しTeX数式のカバレッジが低く、純粋なMathML以外も出力されるなど、いくつかの不満がありました。
そんなとき、カバレッジが優れ、軽量なMathMLを出力するTemmlというライブラリを見つけました。Temmlを使ってMathMLに変換したいと思い、@daiji256/rehype-mathml
を作成しました。
rehype-mathml
で出来ること
このようなMarkdownからMathMLを含むHTMLに変換できます。
本文中や$f(x)=ax+b$、別行立てで、
$$
\begin{align}
f(x) &= ax + b\\
g(x) &= cx^{2} + dx + e
\end{align}
$$
MathMLによる数式表示が可能です。
本文中や、別行立てで、
MathMLによる数式表示が可能です。
MathML
MathMLについて簡単に説明します。
MathML(Mathematical Markup Language)とはXML/HTML5で数式を記述するためのマークアップ言語です。Can I useによると、現在ではメジャーなブラウザがMathMLをサポートしているそうです。
ブラウザで数式を表示する方法として、MathMLの他に、MathJaxやKaTeXがあります。これらはJavaScriptの処理や画像の読み込み、HTMLの肥大化などによりパフォーマンスが優れないです。一方でMathMLは標準機能で数式を扱い非常に軽量です。さらに、MathMLは数式の表示だけでなく、そのコードに数式としての意味を持たせるため、スクリーンリーダーなどでも扱うことができます1。
しかし、MathMLはコンピューターが認識しやすいように設計されたものであり、人間が直接扱うのは難しいです。そのため、MathML専用のエディタなどを使うのが一般的です。
MathMLによる数式記述例
例えば二次方程式の解の公式
はMathMLで記述すると次のようになる。
<math>
<mrow>
<mi>x</mi>
<mo>=</mo>
<mfrac>
<mrow>
<mo>−</mo>
<mi>b</mi>
<mo>±</mo>
<msqrt>
<mrow>
<msup>
<mi>b</mi>
<mn>2</mn>
</msup>
<mo>−</mo>
<mn>4</mn>
<mi>a</mi>
<mi>c</mi>
</mrow>
</msqrt>
</mrow>
<mrow>
<mn>2</mn>
<mi>a</mi>
</mrow>
</mfrac>
</mrow>
</math>
rehype-mathml
の使い方
rehype-mathjax
やrehype-katex
をすでに使っている場合、その部分を@daiji256/rehype-mathml
に置き換えるだけで完了します。詳しくはrehype-mathml/README.mdに書いてあります。
インストール
npmの場合、
npm install @daiji256/rehype-mathml
でインストールできます。
remark-math
— rehype-mathml
remark-math
とrehype-mathml
を以下のようにして使うことができます。
import { unified } from 'unified';
import rehypeParse from 'rehype-parse';
import rehypeStringify from 'rehype-stringify';
import remarkRehype from 'remark-rehype';
import remarkMath from 'remark-math';
import rehypeMathML from '@daiji256/rehype-mathml';
import { read, write } from 'to-vfile';
const file = await unified()
.use(remarkParse)
.use(remarkMath)
.use(remarkRehype)
.use(rehypeMathML)
.use(rehypeStringify)
.process(await read('input.html'));
file.basename = 'output.html';
await write(file);
文献
フラー株式会社 Advent Calendar 2024の8日目はいのりこさんの復職記 〜第二子〜です。
脚注
-
rehype-mathml
ではTeX数式をMathMLに変換するため、数式が持つ情報量はTeX数式までになります。そのため、MathMLほどの情報量はありません。 ↩