パスワードを忘れた? アカウント作成
210064 journal

taggaの日記: 使えずとも使ってしまえ MathML 的 JavaScript

日記 by tagga

前の日記の magnon さんのコメントを参考にして書いた、 MathML を強引に使ってしまうためのええかげんな JavaScript。 MathML の方も少し手直しが必要で、役に立つのは非常に限定的な場合。 考え方としては、 どうせ TeX から変換するのだから元の TeX を注釈に入れておけば、 だめなときは Google Chart で画像にできるじゃないかということ。 数式の下に画像に変換するためのボタンが現われる。 Firefox 3.6.3, Opera 10.10 (Linux 2.6.28 Ubuntu 9.04) で動作確認。IE 用のコードも入っているけど、その部分は未確認。

次のような感じに MathML を作ってもらう。

<math xmlns="http://www.w3.org/1998/Math/MathML" display='block'>
<semantics>
<mrow><mi>E</mi><mo>=</mo>
<mi>m</mi><mo>⁢</mo><msup><mrow><mi>c</mi></mrow><mrow><mn>2</mn></mrow></msup></mrow>
<annotation encoding="TeX">E = mc^2</annotation>
</semantics>
</math>

あとは、文書をロードするときに cheatMathML.prepareAll を呼び出せばいい。 cheatMathML.prepareOnLoad はイベントに結びつけるための関数。 inline のときもボタンが出てくるのは邪魔かもしれない。

// cheatMathML.js
// (c) copyright 2010 tagga
// 実質、パブリックドメインということで、改変、再配布は自由。
//
// MathML の annotation をもとに Google Chart で数式を画像化する、手抜きスクリプト
//
// 使い方:
// head の中に下のように書いておくと、数式の下にボタンが追加され、
// ボタンを押すと数式が画像に変換される。
//
// <script src="cheatMathML.js"></script>
// <script>cheatMathML.prepareOnLoad()</script>
//
// 注意点:
// (1) mstyle タグではなく display 属性で block を指定すること。
// (2) semantics タグと annotation タグを使うこと。annotation タグでは
//     encoding 属性に TeX を指定して、中身に TeX の式を入れておくこと。
// [例]
// <math xmlns="http://www.w3.org/1998/Math/MathML" display='block'>
// <semantics>
// <mrow><mi>E</mi><mo>=</mo>
// <mi>m</mi><mo>&InvisibleTimes;</mo><msup><mrow><mi>c</mi></mrow><mrow><mn>2</mn></mrow></msup></mrow>
// <annotation encoding="TeX">E = mc^2</annotation>
// </semantics>
// </math>
//
// (3) 挿入するボタン、画像には、class 属性として cheatMathML を設定してあるので、
//     画面用以外の CSS スタイルシートでは、非表示にすること。
// (4) semantics タグを使うと、式が一回り小さく表示されることがある。

var cheatMathML;
if (!cheatMathML)
    cheatMathML = {};

// ***Google Chart の URI***
if (!cheatMathML.googleURI)
    cheatMathML.googleURI = "http://chart.apis.google.com/chart?cht=tx&chl=";

// ***ボタンの文字列***
if (!cheatMathML.fixMeMessage)
    cheatMathML.fixMeMessage = "数式を直す"; //"Fix Me";
if (!cheatMathML.removeButtonsMessage)
    cheatMathML.removeButtonsMessage = "ボタンを消す"; //"Remove Buttons";

// *** エラーメセージ ***
if (!cheatMathML.noTexError)
    cheatMathML.noTexError = "TeX で注釈されていません"; // "This mathematical expression is not annotated with TeX";

// img ノードを作る。
cheatMathML.createTexImg = function (tex) {
    var imgNode = document.createElement("img");
    imgNode.setAttribute("src", cheatMathML.googleURI + encodeURI(tex));
    imgNode.setAttribute("alt", tex);
    imgNode.className = "cheatMathML";
    return imgNode;
};

// TeX 表現から前後の空白をとって、<> を元にもどす。
cheatMathML.scrubTexString = function (tex) {
    var str;
    str = tex.replace(/^\s+/, "").replace(/\s+$/, "");
    return str.replace(/\&gt;/g, ">").replace(/\&lt;/g, "<");
};

// 引数の数式に TeX の注釈があれば画像に変換する。
cheatMathML.fixMe = function (mathNode) {
    var nodes = mathNode.getElementsByTagName("annotation");
    var texNode = false;
    for (var i = 0; i < nodes.length; i++) {
    if (nodes[i].getAttribute("encoding") == "TeX") {
        texNode = nodes[i];
        break;
    }
    }
    if (texNode) {
    var tex = cheatMathML.scrubTexString(texNode.innerText || texNode.textContent);
    for (var i = mathNode.childNodes.length - 1; i >= 0; i--) {
        mathNode.removeChild(mathNode.childNodes[i]);
    }
    mathNode.appendChild(cheatMathML.createTexImg(tex));
    } else {
    alert(cheatMathML.noTexError);
    }
}

// 引数の数式にボタンを追加する。
cheatMathML.prepareOne = function (mathNode) {
    var formNode = document.createElement("form");
    formNode.className = "cheatMathML";
    var inputNode = document.createElement("input");
    inputNode.setAttribute("type", "button");
    inputNode.setAttribute("value", cheatMathML.fixMeMessage);
    inputNode.onclick = function () {cheatMathML.fixMe(mathNode)};
    formNode.appendChild(inputNode);
    inputNode = document.createElement("input");
    inputNode.setAttribute("type", "button");
    inputNode.setAttribute("value", cheatMathML.removeButtonsMessage);
    inputNode.onclick = function () {cheatMathML.removeButtons(mathNode)};
    formNode.appendChild(inputNode);
    mathNode.appendChild(formNode);
};

// 引数の数式からフォームを消す。
cheatMathML.removeButtons = function (mathNode) {
    var formNodes = mathNode.getElementsByTagName("form");
    for (var i = formNodes.length - 1; i >= 0; i--) {
    if (formNodes[i].tagName == "form")
        mathNode.removeChild(formNodes[i]);
    }
};

// ***全ての数式にボタンを追加する。***
cheatMathML.prepareAll = function () {
    var mathNodes = document.getElementsByTagName("math");
    for (var i = 0; i < mathNodes.length; i++) {
    cheatMathML.prepareOne(mathNodes[i]);
    }
};

// ***ロード時にボタンを追加してしまう。***
cheatMathML.prepareOnLoad = function () {
    if (window.attachEvent) {
    window.attachEvent("onload", cheatMathML.prepareAll);
    } else {
    window.addEventListener("load", cheatMathML.prepareAll, false);
    }
};

// ***全ての TeX の注釈つき数式を画像に変換する。***
cheatMathML.fixAll = function () {
    var mathNodes = document.getElementsByTagName("math");
    for (var i = 0; i < mathNodes.length; i++) {
    cheatMathML.fixMe(mathNodes[i]);
    }
};
// cheatMathML.js おしまい。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

「毎々お世話になっております。仕様書を頂きたく。」「拝承」 -- ある会社の日常

読み込み中...