Daiji256

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による数式表示が可能です。

本文中やf(x)=ax+b、別行立てで、

f(x)=ax+bg(x)=cx2+dx+e

MathMLによる数式表示が可能です。


MathML

MathMLについて簡単に説明します。

MathML(Mathematical Markup Language)とはXML/HTML5で数式を記述するためのマークアップ言語です。Can I useによると、現在ではメジャーなブラウザがMathMLをサポートしているそうです。

Can I use MathML? Baseline 2023 Newly available across major browsers

ブラウザで数式を表示する方法として、MathMLの他に、MathJaxやKaTeXがあります。これらはJavaScriptの処理や画像の読み込み、HTMLの肥大化などによりパフォーマンスが優れないです。一方でMathMLは標準機能で数式を扱い非常に軽量です。さらに、MathMLは数式の表示だけでなく、そのコードに数式としての意味を持たせるため、スクリーンリーダーなどでも扱うことができます1。

しかし、MathMLはコンピューターが認識しやすいように設計されたものであり、人間が直接扱うのは難しいです。そのため、MathML専用のエディタなどを使うのが一般的です。

MathMLによる数式記述例

例えば二次方程式の解の公式

x=−b±b2−4ac2a

は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);

文献

  1. rehype-mathml(GitHub)
  2. rehype-mathml(npm)
  3. unified
  4. remark-math
  5. W3C Math Home
  6. “MathML” | Can I use

フラー株式会社 Advent Calendar 2024の8日目はいのりこさんの復職記 〜第二子〜です。

脚注

  1. rehype-mathmlではTeX数式をMathMLに変換するため、数式が持つ情報量はTeX数式までになります。そのため、MathMLほどの情報量はありません。 ↩