数式#
数式の執筆はオプトインです。サイトが変換をオンにするまで、普通の $ はリテラルのままです。
import { oxContent } from "@ox-content/vite-plugin";
export default {
plugins: [
oxContent({
math: true,
}),
],
};
true と {} はどちらも既定でオンです。オプションを省略するか false を渡すと、$ と $$ はそのままです。
プラグイン本体は KaTeX に依存しません。数式を使わないサイトは入れなくて大丈夫です。オンにすると、ネイティブ変換が $…$ / $$…$$ を見つけ、入っている場合だけ KaTeX がビルド時に静的 HTML へ組版します。読者側にクライアント JS は不要です。
区切り#
| 形 | ソース | 結果 |
|---|---|---|
| インライン | $E=mc^2$ |
<span class="ox-math ox-math-inline">… |
| ディスプレイ | $$E = mc^2$$ |
<div class="ox-math ox-math-block">… |
| インライン | Before $$x$$ after |
<span class="ox-math ox-math-inline">… |
ディスプレイ区切りがブロックになるのは、段落全体を占めるときだけです。周りに文字がある $$…$$ はインラインのままなので、Markdown が <p> の中に <div> を出しません。
閉じていない $ や $$ はリテラルのままで、ファイルの残りを飲み込みません。数式がオンで、リテラルのドル記号が必要なときは \$ と書きます。フェンスコード、インデントコード、インラインコードは書き換えません。$5 や $5.00 のような金額もリテラルのままです。
描画例#
インライン: 恒等式は です。
ディスプレイ:
ガウス密度:
Inline: the identity is $E=mc^2$.
$$
\int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}
$$
TeX が解析できないとき#
$…$ の検出はヒューリスティックです。文中の ${score}、$vuetify、$10 から $20 はそのまま残しますが、$…$ を引用して説明するような数式構文そのものを扱うページは、まさに誤って拾ってしまう対象です。そのとき KaTeX は渡されたものを拒否します。読者に何を見せるかは onError が決めます。
oxContent({
math: { onError: "literal" },
});
onError |
結果 |
|---|---|
'literal' |
区切りも含めて書いたとおりに戻し、警告を出します。 |
'error' |
KaTeX が拒否した最初の箇所でビルドを失敗させます。 |
'render' |
KaTeX 自身の赤いエラー表示をページに書き込みます。 |
既定は 'literal' です。$ に触れているだけの文は文のまま読め、警告がファイル名と TeX を示すので、数式の本当の間違いも見逃しません。すべての $…$ が数式であるはずのサイトでは 'error' を、KaTeX のメッセージをその場で見たいときは 'render' を使ってください。
要件#
組版はビルド時の KaTeX なので、数式をオンにするサイトだけ入れてください。
vp install -D katexpnpm add -D katexbun add -D katexnpm install -D katexyarn add -D katexkatex が見つからなくてもビルドは失敗しません。エスケープした TeX プレースホルダがページに残り、警告を一度だけ出します。区切りの検出だけ欲しいサイトや、追加パッケージのない CI イメージでも動き続け、組版の依存を足すかどうかを後から決められます。
出力されるアセット#
KaTeX のスタイルシートとフォントは出力ディレクトリの __ox_katex__/ に置かれ、リンクするのは数式を描画したページだけです。math をオンにしても数式を1つも書いていないサイトには何も出力しません。少なくとも1ページが必要としたときに出力します。
フォントは woff2 だけを出力します。.ttf と .woff はフォントのバイト数の4分の3を占めますが、サイトの他の部分が動くブラウザならどれも必要としません。@font-face は woff2 を先に並べ、対応している最初の形式で止まるからです。本当に必要な環境向けには全部出力できます。
oxContent({
math: { fontFormats: "all" },
});