LaTeX\LaTeX で書いたようにしか見えない HTML を作った話

まど
2021年12月5日
LaTeX\LaTeX で書いたようにしか見えない HTML を作った話

はじめに

要約

LaTeX 討伐のため、Markdown を LaTeX 風HTMLに変換するスクリプトを書いたが、LaTeX を倒すことはできなかった。しかし、頑張ればHTML/CSSでも LaTeX の代替となり得ることは分かった。

この変なHTMLは何?

これは、LaTeX で書いたようにしか見えない HTML です。

数式を表示することもできますし、

f(x)=limΔx0f(x+Δx)f(x)Δx{f}'{\left({x}\right)}=\lim_{{\Delta{x}\to{0}}}\frac{{{f{{\left({x}+\Delta{x}\right)}}}-{f{{\left({x}\right)}}}}}{{\Delta{x}}}

表も一応 LaTeX 風です。注釈もLaTeX風です。

表 1: AsciiMath と LaTeX の比較
AsciiMath LaTeX\LaTeX 表示
a/b \frac ab ab\frac{{a}}{{b}}
ab/c a\frac bc abc{a}\frac{{b}}{{c}}

このままでも十分な LaTeX ですが、ブラウザの印刷機能で PDF にすればもっと LaTeX になります。ブラウザは PC 版の Chrome か Firefox が良いです。

作った経緯

LaTeXにはファンが多いですが、私は LaTeX を書くのが苦手です。できることなら LaTeX を書きたくありません。今まで、どうしても LaTeX を使ってレポートを書く必要がある場合は、Markdown を Pandoc で LaTeX に変換する方法を使っていました。この方法では一旦 LaTeX を経由してから PDF にするため、LaTeX の全コマンドが使えるという大きなメリットがあり、大変お世話になりました。

しかし、この方法には次のような欠点がありました。

そこで、Markdown を LaTeX 風のデザインの HTML に変換するスクリプトを書きました。(LaTeX 風のデザインにしたのはその方が面白そうだったからです。別に LaTeX のデザインが好きだからというわけではないんだからね。)

HTML なので、CSS で自由にデザインの調節・変更ができます。

完成したもの

完成したスクリプトは、https://github.com/nanikamado/tex-html に置いておきました。

スクリプト自体は、Pandoc にコマンドライン引数を渡しているだけの簡単なものなのですが、依存しているコマンドが pandocpandoc-crossrefpandoc-asciimath-filterpandoc-katex と4つもあってインストールが大変なので、Homebrewのパッケージにまとめました。

Linux の方は、(Homebrew をインストールしていない場合は) 公式サイト にしたがって Homebrew をインストールしてから、

brew install nanikamado/tap/tex-html

でインストールできます。

Macは持っていないので試していませんが、多分同じ方法でインストールできると思います。WindowsでもWSLを使えば同じ方法でインストールできるかもしれませんが、詳しくないので分かりません。

とはいえ、このスクリプトを使ってレポートを書くのはおすすめしません。理由は後述します。

使い方

次のように実行してください。

tex-html Markdownのファイル名 -o HTMLのファイル名

もしくは、次のように標準入力・標準出力を使うこともできます。

tex-html <Markdownのファイル名 >HTMLのファイル名

書けるもの

普通の Markdown で書けるものに加えて、数式も書くことができます。

数式は、AsciiMath か LaTeX で書くことができるようにしました。AsciiMath というのは、書けることを数式に絞るとこで LaTeX を書きやすくしたような言語です。できることはLaTeXより少ないものの、LaTeX よりも簡潔に数式を書くことができます。AsciiMath の書き方は asciimath.org から見れます。

Markdown 内で次のように $$ を使うと LaTeX で数式が書けます。数式の表示には、KaTeX\KaTeX というライブラリを使っています。どのコマンドが使えるかは KaTeX のドキュメントで確認してください。

$$
f'\left(x\right)=\lim_{\Delta x\to0}\frac{f\left(x+\Delta x\right)-f\left(x\right)}{\Delta x}
$$

数式を AsciiMath で書きたいときは、次のように始めの $$ の後ろに :a を付けてください。

$$:a
f'(x)=lim_{Delta x->0}(f(x+Delta x)-f(x))/(Delta x)
$$

インラインの数式は、次のように、1つの$で囲んでください。

$\frac12$←これはLaTeXで、$:a 1/2$←これはAsciiMathです。

表示:

12\frac12←これはLaTeXで、12\frac{{1}}{{2}}←これはAsciiMathです。

また、コードブロック、表、画像にキャプションを付けたり、コードブロック、表、画像、数式に番号をふって文中から参照することもできます。

Paged.js

HTML で LaTeX を模倣する場合、各ページの上や下についているヘッダーや注釈、ページナンバーをどうやって表示するのかというのが問題になります。 HTML をブラウザで印刷すると、ブラウザがページの上や下にタイトルやページ番号などを付けてくれたりしますが、大体の場合そういうのは見た目が LaTeX っぽくありません。

LaTeX は、文章がページによって分割されることを前提に作られていますが、HTML/CSS はそうではありません。ここに大きな隔たりがあるのです。

そこで登場するのが、CSS Paged Media Module Level 3 というCSSの規格です。これは、文章が紙や PDF に印刷されて、ページによって分割されたとき、どのようにコンテンツが表示されるべきかを、CSSによって詳細に記述することができるようにするための規格です。これを使えば、LaTeX のページ番号やヘッダー・フッターを HTML/CSS で再現することができます。しかし、この規格はまだ標準化団体が案として考えている段階なので、Chrome などの各ブラウザには実装されていないません。

そこで、この機能を無理やり使えるようにしてくれる Paged.js という JavaScript ライブラリを利用しました。

Paged.js は、HTML が読み込んでいるすべての CSS をパースして、Paged Media 3 の機能が使われていたら、HTML 要素を追加したり CSS を書き換えたりしてその機能を使えるようにするという、なかなかに豪快な JavaScript ライブラリです。

この記事にページ番号が付いていたり、各ページの上にタイトルが表示されているのは Paged.js のおかげです。内容を各ページに分割することも Paged.js がやっています。本当は、Web ページとして表示するときはページで分割されていない普通の Web ページとして表示して、印刷するときだけページ分けするようにしてほしいのですが、そういうことはできないみたいです。

問題点

Pandoc と Paged.js によって Markdown から LaTeX 風の HTML を作ることには一応成功しましたが、以下のような問題点があります。

他にもいろいろ不具合があると思います。このスクリプトを使ってレポートを書くのをおすすめしないのはそのためです。レポートのデザインを CSS で調整する必要がないのであれば、Markdown を LaTeX に変換して PDF にする方法を使ったほうが良いと思います。その方が不具合が少ないですし、LaTeXのコマンドが使えるので便利です。

とはいえ、HTML/CSS が LaTeX の代わりとして使えるかもしれないということは分かって頂けたと思います。私はそれだけで満足です。あの忌々しいLaTeXを駆逐するため、共に闘いましょう。

補足