-
-
Save karino2/1899613 to your computer and use it in GitHub Desktop.
EquationPad
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<style type="text/css"> | |
.selectedTarget { background-color: red} | |
</style> | |
</head> | |
<body onload="onload()"> | |
test. | |
<script language="javascript"> | |
var g_VERVOSE = false; | |
function assertFail(msg) { | |
if(g_VERVOSE) | |
alert("fail! "+ msg); | |
throw msg; | |
} | |
function assertEq(exp, act) { | |
if(exp != act) | |
assertFail("not equal [" + exp + "] and [" + act + "]"); | |
} | |
function assertNeq(exp, act) { | |
if(exp == act) | |
assertFail("not equal [" + exp + "] and [" + act + "]"); | |
} | |
function $(id) { | |
return document.getElementById(id); | |
} | |
var g_id = 1; | |
function IdGen() { | |
return g_id++; | |
} | |
function Mo(id, val) { | |
return "<mo id=\"" + id + "\">" + val + "</mo>"; | |
} | |
function Mi(id, val) { | |
return "<mi id=\"" + id + "\">" + val + "</mi>"; | |
} | |
function MnOrMi(term) { | |
if(term instanceof Number){ | |
return "<mn id=\"" + term.objId + "\">" + term + "</mn>"; | |
} | |
if(term instanceof String){ | |
if(term[0] == '&') { | |
return Mi(term.objId, term); | |
} | |
return Mi(term.objId, term); | |
} | |
throw "Unknow terminal"; | |
} | |
function EvalTerm(builder, term){ | |
if(term instanceof Array){ | |
builder.push("<mfenced id=\""); | |
builder.push(term.objId); | |
builder.push("\"><mrow>"); | |
builder.push(JsonToMathML(term)); | |
builder.push("</mrow></mfenced>"); | |
}else{ | |
builder.push(MnOrMi(term)); | |
} | |
} | |
function PushMo(builder, tagName) { | |
builder.push("<mo>"); | |
builder.push(tagName); | |
builder.push("</mo>"); | |
} | |
function IsMinus(term) { | |
return term instanceof Array && term[0] == "-"; | |
} | |
function PushMinusTerm(builder, term) { | |
assertEq(true, IsMinus(term)); | |
PushMo(builder, "-"); | |
EvalTerm(builder,term[1]); | |
} | |
function EvalPlus(json) { | |
var builder = []; | |
var len = json.length; | |
if(IsMinus(json[1])){ | |
PushMinusTerm(builder, json[1]); | |
} | |
else | |
EvalTerm(builder, json[1]); | |
for(var i = 2; i < len; i++) { | |
if(IsMinus(json[i])){ | |
PushMinusTerm(builder, json[i]); | |
} | |
else { | |
PushMo(builder, "+"); | |
EvalTerm(builder,json[i]); | |
} | |
} | |
return builder.join(""); | |
} | |
function EvalTimes(json) { | |
var builder = []; | |
var len = json.length; | |
EvalTerm(builder, json[1]); | |
for(var i = 2; i < len; i++) { | |
PushMo(builder, json[0]); | |
EvalTerm(builder,json[i]); | |
} | |
return builder.join(""); | |
} | |
function EvalEqual(json) { | |
var builder = []; | |
EvalTerm(builder, json[1]); | |
builder.push(Mo(json[0].objId, "=")); | |
EvalTerm(builder,json[2]); | |
return builder.join(""); | |
} | |
function EvalPower(json) { | |
var builder = []; | |
builder.push("<msup>"); | |
builder.push("<mrow>"); | |
EvalTerm(builder, json[1]); | |
builder.push("</mrow>"); | |
builder.push("<mrow>"); | |
EvalTerm(builder, json[2]); | |
builder.push("</mrow>"); | |
builder.push("</msup>"); | |
return builder.join(""); | |
} | |
function EvalDotOver(json) { | |
var builder = []; | |
builder.push("<mover>"); | |
EvalTerm(builder, json[1]); | |
builder.push("<mo>.</mo>"); | |
builder.push("</mover>"); | |
return builder.join(""); | |
} | |
function EvalIntegral(json) { | |
var builder = []; | |
if(json.length == 3) { | |
builder.push(Mo(json[0].objId, "∫")); | |
EvalTerm(builder, json[1]); | |
// currently, json[2] does'nt support ρ, etc. | |
builder.push(Mi(json[2].objId, "d" + json[2] )); | |
} else if(json.length == 5) { | |
builder.push("<msubsup>"); | |
builder.push(Mo(json[0].objId, "∫")); | |
EvalTerm(builder, json[3]); | |
EvalTerm(builder, json[4]); | |
builder.push("</msubsup>"); | |
EvalTerm(builder, json[1]); | |
// currently, json[2] does'nt support ρ, etc. | |
builder.push(Mi(json[2].objId, "d" + json[2] )); | |
} else { | |
throw "unknown arg number of integral. ( " + json.length + ")"; | |
} | |
return builder.join(""); | |
} | |
function JsonToMathML(json) { | |
var tag = json[0]; | |
if(tag == "-") | |
{ | |
var builder = []; | |
PushMinusTerm(builder, json); | |
return builder.join(""); | |
} | |
if(tag == "+") | |
{ | |
return EvalPlus(json); | |
} | |
if(tag == "*") | |
{ | |
return EvalTimes(json); | |
} | |
if(tag == "pow") | |
{ | |
return EvalPower(json); | |
} | |
if(tag == "dotover") | |
{ | |
return EvalDotOver(json); | |
} | |
if(tag == "int") | |
{ | |
return EvalIntegral(json); | |
} | |
if(tag == "=") | |
{ | |
return EvalEqual(json); | |
} | |
throw "unknown tag"; | |
} | |
function dp(st) { | |
var con = $("console"); | |
con.value += st + "\n"; | |
} | |
function showMath(str) { | |
var header ="<math id=\"mathcanvas\" display=\"block\" xmlns=\"http://www.w3.org/1998/Math/MathML\">" | |
var footer ="</math>" | |
var math = $("mathcanvas"); | |
math.innerHTML = header + str + footer; | |
} | |
function onClear() { | |
var con = $("console"); | |
con.value = ''; | |
} | |
var g_hash = {}; | |
function JsonParser(str) { | |
var sexp = eval(str); | |
var res = []; | |
res.objId = IdGen(); | |
g_hash[res.objId] = res; | |
for(var i = 0; i < sexp.length; i++) { | |
var obj; | |
if(typeof(sexp[i]) == "number") | |
obj = new Number(sexp[i]); | |
else if(typeof(sexp[i]) == "string") | |
obj = new String(sexp[i]); | |
else if(sexp[i] instanceof Array) | |
obj = JsonParser(sexp[i]); | |
else | |
obj = sexp[i]; | |
obj.objId = IdGen(); | |
g_hash[obj.objId] = obj; | |
res.push(obj); | |
obj.parent = res; | |
} | |
assertNeq(res, sexp); | |
return res; | |
} | |
var g_sexp; | |
function clicked() { | |
var inp = $("input"); | |
g_sexp = JsonParser(inp.value); | |
var result = JsonToMathML(g_sexp); | |
dp(result); | |
showMath(result); | |
// alert(inp.value); | |
} | |
function Update(sexp) { | |
var result = JsonToMathML(sexp); | |
dp(result); | |
showMath(result); | |
if(g_selected) { | |
var elem = $(g_selected.obj.objId); | |
elem.setAttribute("class", "selectedTarget"); | |
g_selected.elem = elem; | |
} | |
} | |
function FindIndex(arr, obj) { | |
for(var i = 0; i < arr.length; i++) { | |
if(arr[i] == obj) | |
return i; | |
} | |
return -1; | |
} | |
function MoveLeftTerm(sel) { | |
var parent = sel.obj.parent; | |
var i = FindIndex(parent, sel.obj); | |
if(i == 1) | |
return; | |
assertEq(parent[i], sel.obj); | |
var prev = parent[i-1]; | |
parent[i] = prev; | |
parent[i-1] = sel.obj; | |
} | |
function MoveRightTerm(sel) { | |
var parent = sel.obj.parent; | |
var i = FindIndex(parent, sel.obj); | |
if(i == parent.length -1 ) | |
return; | |
assertEq(parent[i], sel.obj); | |
var next = parent[i+1]; | |
parent[i] = next; | |
parent[i+1] = sel.obj; | |
} | |
function assertMatch(expectPat, actual) { | |
if(!actual.match(expectPat)) { | |
assertFail("pat not match. pat[" + expectPat + "], actual [" + actual + "]"); | |
} | |
} | |
function verify(input, expectPat, needLog) { | |
var sexp = JsonParser(input); | |
var result = JsonToMathML(sexp); | |
var actual_pat = expectPat; | |
if(needLog) | |
dp(result); | |
assertMatch(actual_pat, result); | |
} | |
function UnitTest() { | |
try { | |
verify('["pow", "e", "a"]', /<msup><mrow><mi[^>]*>e<\/mi><\/mrow><mrow><mi[^>]*>a<\/mi><\/mrow><\/msup>/); | |
verify('["*", "e", ["-", "a"]]', /<mi id="[0-9]*">e<\/mi><mo>\*<\/mo><mfenced id="[0-9]*"><mrow><mo>-<\/mo><mi id="[0-9]*">a<\/mi><\/mrow>/) | |
verify('["+", "λ", "a"]', /<mi id="[0-9]*">λ<\/mi><mo>\+<\/mo><mi id="[0-9]*">a<\/mi>/); | |
verify('["dotover", "x"]', /<mover><mi id="[0-9]*">x<\/mi><mo>.<\/mo><\/mover>/); | |
verify('["int", "x", "t"]', /<mo id="[0-9]*">∫<\/mo><mi id="[0-9]*">x<\/mi><mi id="[0-9]*">dt<\/mi>/); | |
verify('["int", "x", "t", 0, "∞"]', /<msubsup><mo id="[0-9]*">∫<\/mo><mn id="[0-9]*">0<\/mn><mi id="[0-9]*">∞<\/mi><\/msubsup><mi id="[0-9]*">x<\/mi><mi id="[0-9]*">dt<\/mi>/); | |
verify('["=", "x", "y"]', /<mi id="[0-9]*">x<\/mi><mo id="[0-9]*">=<\/mo><mi id="[0-9]*">y<\/mi>/); | |
dp("test sucess!"); | |
}catch(e) { | |
dp("test fail!"); | |
dp(e); | |
} | |
} | |
var KEY_LEFT = 37; | |
var KEY_RIGHT = 39; | |
var g_selected = undefined; | |
function onload() { | |
UnitTest(); | |
var canv = $("mathcanvas"); | |
canv.addEventListener("click", function(evt) { | |
if(g_selected) { | |
g_selected.elem.setAttribute("class", ""); | |
} | |
var id = evt.target.getAttribute("id"); | |
var obj = g_hash[id]; | |
if(obj.parent && obj.parent[0] == "-") | |
obj = obj.parent; | |
g_selected = {obj: obj, elem: evt.target}; | |
g_selected.elem.setAttribute("class", "selectedTarget"); | |
// alert(g_selected.elem); | |
}); | |
document.body.addEventListener("keypress", function(evt) { | |
if(evt.keyCode == KEY_LEFT) { | |
MoveLeftTerm(g_selected); | |
Update(g_sexp); | |
} else if (evt.keyCode == KEY_RIGHT) { | |
MoveRightTerm(g_selected); | |
Update(g_sexp); | |
} | |
// alert(evt.keyCode); | |
}); | |
// alert(document.getElementById("hoge")); | |
//document.getElementById("hoge").addEventListener("click", function() { | |
// alert("clicked!"); } ); | |
/* | |
document.getElementById("x").addEventListener("click", function() { | |
alert("x!"); } ); | |
document.getElementById("d").addEventListener("click", function() { | |
alert("d!"); } ); | |
*/ | |
} | |
</script> | |
<br> | |
<textarea id="input" rows="2" cols="100" ></textarea><br> | |
<textarea id="console" rows="10" cols="100" ></textarea><br> | |
<input value="OK" type="button" onclick="clicked();"> | |
<input value="Clear" type="button" onclick="onClear();"> | |
<br> | |
<div id="mathcanvas"></div> | |
以下は適当な例。<br> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mi> | |
ℒ | |
</mi> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<msubsup> | |
<mo>∫</mo> | |
<mi>a</mi> | |
<mi>∞</mi> | |
</msubsup> | |
<mi>x</mi> | |
<mi>dt</mi> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mo>∫</mo> | |
<mi>x</mi> | |
<mi>dt</mi> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mover> | |
<mi>r</mi> | |
<mo>.</mo> | |
</mover> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mo>λ</mo> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<msup> | |
<mrow> | |
<msub> | |
<mrow> | |
<mi> e </mi> | |
</mrow> | |
<mrow> | |
<mi>a</mi> | |
</mrow> | |
</msub> | |
</mrow> | |
<mrow> | |
<mo> - </mo> | |
<mi> ρ<!--greek small letter rho--> </mi> | |
<mi> x </mi> | |
</mrow> | |
</msup> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<msubsup> | |
<mrow> | |
<mi> e </mi> | |
</mrow> | |
<mrow> | |
<mi>a</mi> | |
</mrow> | |
<mrow> | |
<mo> - </mo> | |
<mi> ρ<!--greek small letter rho--> </mi> | |
<mi> x </mi> | |
</mrow> | |
</msubsup> | |
</math> | |
<br> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mn> 3 </mn> | |
<mo> + </mo> | |
<mn> 4 </mn> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mrow id="hoge"> | |
<munderover> | |
<mo>∫</mo> | |
<mn>0</mn> | |
<mn>1</mn> | |
</munderover> | |
<mrow> | |
<msup> | |
<mi>e</mi> | |
<mi id="x">x</mi> | |
</msup> | |
<mi id="d">d</mi> | |
<mi>x</mi> | |
</mrow> | |
</mrow> | |
</math> | |
<math xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mfenced> | |
<mrow> | |
<mi> a </mi> | |
<mo> + </mo> | |
<mi> b </mi> | |
</mrow> | |
</mfenced> | |
</math> | |
以下はダメ | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mrow> | |
<cn type="complex-cartesian"> 12.3 <sep/> 5 </cn> | |
<bind id="outer"><csymbol cd="fns1">lambda</csymbol> | |
<bvar><ci>x</ci></bvar> | |
<apply><ci>f</ci> | |
<bind id="inner"><csymbol cd="fns1">lambda</csymbol> | |
<bvar><ci>x</ci></bvar> | |
<share id="copy" href="#orig"/> | |
</bind> | |
<apply id="orig"><ci>g</ci><ci>x</ci></apply> | |
</apply> | |
</bind> | |
</mrow> | |
</math> | |
</body> | |
</html> |
Author
karino2
commented
Feb 25, 2012
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment