【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

KaTeXでTeXのソースを表示

KaTeX には MathJax のようにソースを取得する機能がなかったため実装してみました。

目次

概要

MathJax では数式を右クリックして Show Math As ▶ TeX Commands を選択すればソースが表示されます。

KaTeX にはこの機能がありませんが、DOM を調べると <annotation> タグにソースが格納されています。

  • <span class="katex" style="position: relative;">
    • <span class="katex-mathml">
      • <math>
        • <semantics>
          • <mrow>
          • <annotation encoding="application/x-tex">

この情報を使って、右クリックで TeX のソースが表示できるようにしてみました。

f:id:n7shi:20180806155724p:plain

既に選択状態になっているため [Ctrl]+[C] でコピーできます。ソースの枠はマウスを外に出すと消えます。

とりあえずの粗削りな実装で使い勝手はあまり良くありませんが、ソースが取得できないよりはましなので公開します。

テスト

$x+1$ の2乗は $x^ 2+2x+1$ です。

x=\frac{-b±\sqrt{b^2-4ac}}{2a}
f(x)=\frac1{\sqrt{2πσ^2}}\exp\left(-\frac{(x-μ)^2}{2σ^2}\right)
i\hbar\frac∂{∂t}ψ=\left(\frac{(-i\hbar∇)^2}{2m}+V\right)ψ
rC=\frac{∂C}{∂t}+\frac12σ^2S_t^2\frac{∂^2C}{∂S_t^2}+rS_t\frac{∂C}{∂S_t}

ソース

はてなブログでの KaTeX の導入方法は以下の記事を参照してください。

KaTeX を導入して数式が表示されていることを前提に、以下を追加します。

CSS

.math-tip {
    position: absolute;
    font-size: small;
    border: solid black 1px;
    background-color: lightyellow;
    white-space: pre-wrap;
    z-index: 9999;
}

JavaScript

function unescapeHTML(s) {
    return s
        .replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&")
        .replace(/&#x([0-9a-fA-F]+);/g, (_, p1) => String.fromCharCode(parseInt(p1, 16)));
}

function addSrcView(e) {
    if (typeof e.mathSrcView != "undefined") return;
    e.addEventListener("contextmenu", ev => {
        if (e.mathSrcView != null) return;
        let an = e.getElementsByTagName("annotation");
        if (an.length == 0) return;
        ev.preventDefault();
        e.style.position = "relative";
        let tip = document.createElement("textarea");
        tip.rows = 3;
        tip.readOnly = true;
        tip.className = "math-tip";
        tip.value = unescapeHTML(an[0].textContent.trim());
        e.appendChild(tip);
        let b1 = e.getBoundingClientRect();
        let b2 = e.parentElement.parentElement.getBoundingClientRect();
        tip.style.width = b2.width + "px ";
        tip.style.left = (b2.left - b1.left) + "px ";
        tip.style.top = (ev.clientY - b1.top - 2) + "px ";
        tip.focus();
        tip.select();
        e.mathSrcView = tip;
        tip.addEventListener("mouseout", () => {
            e.removeChild(tip);
            e.mathSrcView = null;
        });
    });
}

document.addEventListener("DOMContentLoaded", () => {
    let e3 = document.getElementsByClassName("katex");
    for (let i = 0; i < e3.length; ++i) {
        addSrcView(e3[i]);
    }
});

参考

今回は実用性と実装の簡単さの折り合いを付けるのに苦労しました。以下の記事がヒントになりました。

Wikipedia から TeX のソースを取得する方法は以下を参照してください。

数式の画像から TeX に変換するアプリがあります。

Word や PowerPoint で書いた数式を TeX に変換するツールを作りました。