2017年06月16日

$\mathrm{\TeX}$→MathMLに変換し、構造なしの数式を検索 〜簡単なマシーン・ライクの数式の操作に踏み出そう〜

応援クリックを1日1回宜しくお願いいたします。




一昨昨日一昨日に引き続き、 MathJaxを利用して$\mathrm{\TeX}$からPresentation MathMLへ直接的に変換した後、構造なしの数式を検索するアプリケーションを作成しました。
↓↓↓
TeX→MathML→構造なしの数式を検索


本日は、2箇所に入力した$\mathrm{\TeX}$からMathMLへ変換して、一方の数式をもう一方の数式から検索します。

ただし、検索する数式が構造を含んでいても、構造以外の箇所を検索します。

構造とは、べき乗や分数やルートのことです。

構造以外の箇所の検索では、<mi>タグ、<mo>タグ、<mn>タグの値が検索対象の数式に含まれていればヒットと判定します。




・「query」は検索する$\mathrm{\TeX}$の数式コマンドが書かれている<textarea>タグのid属性の値です。
・「searchArea」は検索対象の$\mathrm{\TeX}$の数式コマンドが書かれている<textarea>タグのid属性の値です。
・検索対象には数式環境を複数書いてあることを想定しています。



JavaScriptのソースコードの説明

当ブログではドルマーク($)は文章中の数式としてレンダリングの対象となるため、下記のソースコードでは全角のドルマークまたはjQueryと表記しています。

// ページ内の数式を全て取得してelement jax objectに格納する
//(例としてページ内の最上部の数式を$\mathrm{\TeX}$としている)
var jax = MathJax.Hub.getAllJax();
// 検索する$\mathrm{\TeX}$の数式コマンドを取得して、jaxに設定する
jax[0].Text(jQuery("#query").val());
// Presentation MathMLに変換して、XMLとしてパースしてjQueryオブジェクトとして格納する
queryMML = jQuery( jQuery.parseXML(jax[0].root.toMathML("")) );

// 検索対象の$\mathrm{\TeX}$の数式コマンドを取得する
var searchArea = jQuery("#searchArea").val();
// 数式環境を分割する
while (searchArea.length != 0) {
var i = searchArea.length;
var eqType = 0;
// 1つ目の数式環境の最後の位置を探す
for (e = 0; e < 39; e++) {
// 数式環境の間の改行や、文章中の数式の$を考慮して、何文字目からか始める
var pos = searchArea.slice(3).indexOf(EquationEnvironment[e][1]) + 3;
if (pos > 2 && pos < i) {
i = pos;
eqType = e;
}
}
// 1つの数式環境をjaxに格納する
jax[0].Text(searchArea.substring(0, i + EquationEnvironment[eqType][1].length));
// MathMLに変換してパースしてjQueryオブジェクトにして検索関数を呼び出す
if ( searchEq(jQuery( jQuery.parseXML(jax[0].root.toMathML("")) )) ) {
// ヒットしたら検索結果に表示する
jQuery("#result").append(searchArea.substring(0, i + EquationEnvironment[eqType][1].length));
}
// 2つ目以降の数式環境を検索対象とする
searchArea = searchArea.slice(i + EquationEnvironment[eqType][1].length);
}

// jaxを元に戻す
jQuery("#jax").html("$\\mathrm{\\TeX}$");
// 数式レンダリングも施しておく
MathJax.Hub.Queue(["Typeset", MathJax.Hub, "jax"]);
}

function searchEq (xml) {
// その数式全体でのヒット判定
var hit = true;
// 検索対象xml:タグ、検索数式queryMML:タグ
// 各タグを対象に検索する
["mi", "mo", "mn"].forEach(function(t) {
// クエリに各タグが見つかったら、
queryMML.find(t).each(function () {
// そのタグの値を検索する
var query = jQuery(this).text();
// そのタグの値のヒット判定
var hit1 = false;
// 検索対象に各タグが見つかったら、
xml.find(t).each(function () {
// そのタグの値を調べる
if (query == $(this).text()) hit1 = true;
});
// 各タグの値が全て見つかったら、数式全体でヒットとする
hit = hit && hit1;
});
});
return hit;
}








このソースコードの特徴

本日分の方法では、クエリの数式の文字が検索対象の数式にバラバラでも含まれていれば、ヒットと判定しています。

そのため、構造を含む数式や文字・記号の順序を指定した検索ではありません。


TeX→MathML→構造なしの数式を検索


本日の分で検索できるのは、
    1. <mi>:文字($x$,$y$,$z$,$\sin$)
    1. <mo>:記号($+$,$-$,$\times$,$\div$,$\cdots$)
    1. <mn>:数字(0,1,2,3)
の3種類の文字となります。

MathMLでは上記のような細かな分類によるマークアップがされます。

$\mathrm{\TeX}$で「123」という数字を書くと、<mn>123</mn>と変換されるので、検索対象でもバラバラでない<mn>123</mn>を探します。

ただし、$\mathrm{\TeX}$で「1 2 3」と書くと、<mn>1</mn><mn>2</mn><mn>3</mn>となって、バラバラの1と2と3を検索します。



posted by Line Segment at 18:00 | Comment(0) | TrackBack(0) | ホームページ | このブログの読者になる | 更新情報をチェックする