-
-
Save hogeika/1926059 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()"> | |
<input value="Export" type="button" onclick="Export();"> | |
<input value="Import" type="button" onclick="Inport();"> | |
<div id="history" contenteditable="true"></div> | |
<script language="javascript"> | |
var g_VERVOSE = false; | |
function assertFail(msg) { | |
if(g_VERVOSE) | |
alert("fail! "+ msg); | |
throw msg; | |
} | |
function assertFalse(condition, msg) { | |
if(condition) | |
assertFail("assert false fail:" + 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); | |
} | |
function CE(tag){ | |
return document.createElement(tag); | |
} | |
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, nofence){ | |
if(term instanceof Array){ | |
if(!nofence) { | |
builder.push("<mfenced id=\""); | |
builder.push(term.objId); | |
builder.push("\"><mrow>"); | |
} | |
builder.push(JsonToMathML(term)); | |
if(!nofence) | |
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[0] == "-"; | |
} | |
function IsSingleTerm(term) { | |
return !(term[0] == "+"); | |
} | |
function PushMinusTerm(builder, term) { | |
assertEq(true, IsMinus(term)); | |
PushMrow(builder, term[0].objId); | |
PushMo(builder, "-"); | |
EvalTerm(builder,term[1], IsSingleTerm(term[1])); | |
builder.push('</mrow>'); | |
} | |
function FirstHeadIsNotMinus(sexp) { | |
if(sexp[0] == "-") | |
return false; | |
if(sexp[0] != "*") | |
return true; | |
return FirstHeadIsNotMinus(sexp[1]); | |
} | |
function EvalPlus(json) { | |
var builder = []; | |
var len = json.length; | |
PushMrow(builder, json[0].objId); | |
if(IsMinus(json[1])){ | |
PushMinusTerm(builder, json[1]); | |
} | |
else | |
EvalTerm(builder, json[1], IsSingleTerm(json[1])); | |
for(var i = 2; i < len; i++) { | |
if(IsMinus(json[i])){ | |
PushMinusTerm(builder, json[i]); | |
} | |
else { | |
PushMo(builder, "+"); | |
EvalTerm(builder,json[i], IsSingleTerm(json[i]) && FirstHeadIsNotMinus(json[i])); | |
} | |
} | |
builder.push('</mrow>'); | |
return builder.join(""); | |
} | |
function PushMrow(builder, id) { | |
builder.push('<mrow id="'+ id + '">'); | |
} | |
function EvalTimes(json) { | |
var builder = []; | |
var len = json.length; | |
PushMrow(builder, json[0].objId); | |
EvalTerm(builder, json[1], IsSingleTerm(json[1])); | |
for(var i = 2; i < len; i++) { | |
if(json[i-1] instanceof Number && json[i] instanceof Number) | |
PushMo(builder, "×"); | |
EvalTerm(builder,json[i], IsSingleTerm(json[i]) && !IsMinus(json[i])); | |
} | |
builder.push('</mrow>'); | |
return builder.join(""); | |
} | |
function EvalEqual(json) { | |
var builder = []; | |
EvalTerm(builder, json[1], true); | |
builder.push(Mo(json[0].objId, "=")); | |
EvalTerm(builder,json[2], true); | |
return builder.join(""); | |
} | |
function EvalPower(json) { | |
var builder = []; | |
builder.push("<msup>"); | |
EvalTerm(builder, json[1]); | |
EvalTerm(builder, json[2], true); | |
builder.push("</msup>"); | |
return builder.join(""); | |
} | |
function EvalPartial(json) { | |
var builder = []; | |
builder.push('<mfrac id="' +json[0].objId + '">'); | |
builder.push("<mrow>"); | |
PushMo(builder, "∂"); | |
EvalTerm(builder, json[1]); | |
builder.push("</mrow>"); | |
builder.push("<mrow>"); | |
PushMo(builder, "∂"); | |
EvalTerm(builder, json[2]); | |
builder.push("</mrow>"); | |
builder.push("</mfrac>"); | |
return builder.join(""); | |
} | |
function EvalFrac(json) { | |
var builder = []; | |
builder.push('<mfrac id="' +json[0].objId + '"><mrow>'); | |
EvalTerm(builder, json[1], true); | |
builder.push('</mrow><mrow>'); | |
EvalTerm(builder, json[2], true); | |
builder.push('</mrow></mfrac>'); | |
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], true); | |
// 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], true); | |
EvalTerm(builder, json[4], true); | |
builder.push("</msubsup>"); | |
EvalTerm(builder, json[1], true); | |
// 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 == "part") | |
{ | |
return EvalPartial(json); | |
} | |
if(tag == "/") | |
{ | |
return EvalFrac(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 EncloseMath(str,isBlock){ | |
var header ="<math " + (isBlock?"display=\"block\"":"") + "xmlns=\"http://www.w3.org/1998/Math/MathML\">" | |
var footer ="</math>" | |
return header + str + footer; | |
} | |
function showMath(str) { | |
var math = $("mathcanvas"); | |
math.innerHTML = EncloseMath(str,true); | |
} | |
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() { | |
g_selected = undefined; | |
g_sexp = JsonParser($("input").value); | |
var result = JsonToMathML(g_sexp); | |
dp(result); | |
showMath(result); | |
} | |
function UpdateSelection() { | |
if(g_selected) { | |
var elem = $(g_selected.obj.objId); | |
elem.setAttribute("class", "selectedTarget"); | |
g_selected.elem = elem; | |
} | |
} | |
function findSexp(sexp, id) { | |
if(sexp && sexp.objId == id) | |
return sexp; | |
if(sexp instanceof Array) { | |
for(var i = 0; i < sexp.length; i++) { | |
var res = findSexp(sexp[i], id) | |
if(res) | |
return res; | |
} | |
} | |
return false; | |
} | |
function HasArrayChild(sexp) { | |
for(var i = 0; i < sexp.length; i++) { | |
if(sexp[i].length > 1) { | |
return true; | |
} | |
} | |
return false; | |
} | |
function PushIndent(builder, level) { | |
for(var i = 0; i < level; i++) { | |
builder.push(" "); | |
} | |
} | |
function InnerSexpSerializer(sexp, builder, level) { | |
if(sexp instanceof Number) { | |
PushIndent(builder, level); | |
builder.push(sexp.toString()); | |
return; | |
} | |
if(sexp instanceof String) { | |
PushIndent(builder, level); | |
builder.push('"'); | |
builder.push(sexp); | |
builder.push('"'); | |
return; | |
} | |
if(sexp instanceof Array) { | |
PushIndent(builder, level); | |
builder.push("["); | |
assertFalse(sexp[0] instanceof Array, "head of array must not array."); | |
InnerSexpSerializer(sexp[0], builder, 0); | |
if(HasArrayChild(sexp)) { | |
for(var i = 1; i < sexp.length; i++) { | |
builder.push(",\n"); | |
InnerSexpSerializer(sexp[i], builder, level+1); | |
} | |
builder.push("\n"); | |
PushIndent(builder, level); | |
builder.push("]"); | |
} | |
else { | |
for(var i = 1; i < sexp.length; i++) { | |
builder.push(","); | |
InnerSexpSerializer(sexp[i], builder, 0); | |
} | |
builder.push("]"); | |
} | |
return; | |
} | |
alert(typeof(sexp)); | |
throw "unknown atom type inside S Expression Serializer"; | |
} | |
function SexpSerializer(sexp) { | |
var builder = []; | |
var level = 0; | |
InnerSexpSerializer(sexp, builder, level); | |
return builder.join(""); | |
} | |
function Update(sexp) { | |
var result = JsonToMathML(sexp); | |
dp(result); | |
showMath(result); | |
UpdateSelection(); | |
$("input").value = SexpSerializer(sexp); | |
} | |
function Copy(sexp) { | |
if(sexp instanceof Array) | |
Register(SexpSerializer(sexp)); | |
if(sexp instanceof String && IsHead(sexp)) | |
Register(SexpSerializer(sexp.parent)); | |
} | |
function Paste(sexp) { | |
var raw = SelectedRaw(); | |
if(IsHead(sexp)){ | |
sexp = sexp.parent; | |
} | |
if(sexp.parent){ | |
var parent = sexp.parent; | |
var i = FindIndex(parent, sexp); | |
parent[i] = JsonParser(raw); | |
} | |
} | |
function FindIndex(arr, obj) { | |
for(var i = 0; i < arr.length; i++) { | |
if(arr[i] == obj) | |
return i; | |
} | |
return -1; | |
} | |
function swap(array, i, j) { | |
var iobj = array[i]; | |
array[i] = array[j]; | |
array[j] = iobj; | |
} | |
function MoveLeftTermInternal(parent_sexp, target_sexp) { | |
var i = FindIndex(parent_sexp, target_sexp); | |
if(i == 1) | |
return; | |
assertEq(parent_sexp[i], target_sexp); | |
swap(parent_sexp, i, i-1); | |
} | |
function IsHead(obj) { | |
return obj.parent[0] == obj; | |
} | |
function MoveLeftTerm(sel) { | |
if(!sel.obj.parent) | |
return; | |
if(IsHead(sel.obj)) { | |
MoveLeftTermInternal(sel.obj.parent.parent, sel.obj.parent); | |
return ; | |
} | |
MoveLeftTermInternal(sel.obj.parent, sel.obj); | |
} | |
function MoveRightTermInternal(parent_sexp, target_sexp) { | |
var i = FindIndex(parent_sexp, target_sexp); | |
if(i == parent_sexp.length -1 ) | |
return; | |
assertEq(parent_sexp[i], target_sexp); | |
swap(parent_sexp, i, i+1); | |
} | |
function MoveRightTerm(sel) { | |
if(!sel.obj.parent) | |
return; | |
if(IsHead(sel.obj)) { | |
MoveRightTermInternal(sel.obj.parent.parent, sel.obj.parent); | |
return ; | |
} | |
MoveRightTermInternal(sel.obj.parent, sel.obj); | |
} | |
function PartialDerivative(sel) { | |
// NYI. | |
} | |
function WidenSelection(sel) { | |
var par = sel.obj.parent; | |
if(!par) | |
return; | |
if(!IsHead(sel.obj)){ | |
par = par[0]; // head is parent | |
} else { | |
par = par.parent[0]; | |
} | |
if(!par.objId) | |
return; | |
var par_elem = $(par.objId); | |
if(!par_elem) | |
return; | |
g_selected = {obj: par, elem: par_elem }; | |
} | |
function Register(raw){ | |
var history = $('history'); | |
var history_entry = CE('div'); | |
history_entry.contentEditable=false; | |
var form = CE('form'); | |
form.innerHTML='<input type="checkbox" name="is_selected" onclick="CheckClicked(event)">'; | |
var input = CE('input'); | |
input.type = 'button'; | |
input.value = 'revive'; | |
input.setAttribute('onclick','Revive(event)'); | |
form.appendChild(input); | |
var hidden = CE('input'); | |
hidden.type = 'hidden'; | |
hidden.name = 'raw_exp'; | |
hidden.value = raw; | |
form.appendChild(hidden); | |
var span = CE('span'); | |
span.innerHTML = EncloseMath(JsonToMathML(JsonParser(raw))); | |
form.appendChild(span); | |
history_entry.appendChild(form); | |
history.appendChild(history_entry); | |
/* | |
<div> | |
<form> | |
<input type="button" value="revive" onclick="Revive(event);"> | |
<input type="hidden" name="raw_exp" value="['+', 1, 2]"> | |
<span> | |
<math xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mi> | |
ℒ | |
</mi> | |
</math> | |
<span> | |
</form> | |
</div> | |
*/ | |
} | |
function Overwrite(raw){ | |
var history = $('history'); | |
var entries = history.childNodes; | |
for(var i=0; i < entries.length; i++){ | |
var entry = entries.item(i); | |
var form = entry.getElementsByTagName('form')[0]; | |
if(form.elements.namedItem('is_selected').checked) { | |
form.elements.namedItem('raw_exp').value=raw; | |
entry.getElementsByTagName('span')[0].innerHTML = EncloseMath(JsonToMathML(JsonParser(raw))); | |
return; | |
} | |
} | |
} | |
function SelectedRaw(){ | |
var history = $('history'); | |
var entries = history.childNodes; | |
var form; | |
for(var i=0; i < entries.length; i++){ | |
var entry = entries.item(i); | |
form = entry.getElementsByTagName('form')[0]; | |
if(form.elements.namedItem('is_selected').checked) { | |
return form.elements.namedItem('raw_exp').value; | |
} | |
} | |
if(form){ | |
return form.elements.namedItem('raw_exp').value; | |
} | |
} | |
function CheckClicked(e){ | |
var history = $('history'); | |
var entries = history.childNodes; | |
for(var i=0; i < entries.length; i++){ | |
var entry = entries.item(i); | |
var f = entry.getElementsByTagName('form')[0]; | |
var elem = f.elements.namedItem('is_selected'); | |
if(elem !== e.target){ | |
elem.checked = false; | |
} | |
} | |
} | |
function Revive(e){ | |
var target = e.target; | |
var from = target.form; | |
var input = $('input'); | |
input.value = from.elements.namedItem('raw_exp').value; | |
var history = $('history'); | |
var entries = history.childNodes; | |
for(var i=0; i < entries.length; i++){ | |
var entry = entries.item(i); | |
var f = entry.getElementsByTagName('form')[0]; | |
var elem = f.elements.namedItem('is_selected'); | |
elem.checked = false; | |
} | |
from.elements.namedItem('is_selected').checked=true; | |
clicked(); | |
} | |
function Export(){ | |
var forms = $('history').getElementsByTagName('form'); | |
var builder = []; | |
builder.push('['); | |
for(var i = 0; i < forms.length; i++){ | |
builder.push("'"); | |
builder.push(encodeURI(forms.item(i).elements.namedItem('raw_exp').value)); | |
builder.push("'"); | |
builder.push(','); | |
} | |
builder.push(']'); | |
prompt("Export", builder.join("")); | |
} | |
function Inport(){ | |
var input = $('input').value; | |
var array = eval(input); | |
for(var i=0; i < array.length; i++){ | |
Register(decodeURI(array[i])); | |
} | |
} | |
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 EvalTest() { | |
verify('["pow", "e", "a"]', /<msup><mi[^>]*>e<\/mi><mi[^>]*>a<\/mi><\/msup>/); | |
verify('["pow", "e", ["*", "a", "b"]]', /<msup><mi[^>]*>e<\/mi><mrow[^>]*><mi[^>]*>a<\/mi><mi id="[0-9]*">b<\/mi><\/mrow><\/msup>/); | |
verify('["*", "e", ["-", "a"]]', /<mrow id="[0-9]*"><mi id="[0-9]*">e<\/mi><mfenced id="[0-9]*"><mrow><mrow id="[0-9]*"><mo>-<\/mo><mi id="[0-9]*">a<\/mi><\/mrow><\/mrow><\/mfenced><\/mrow>/); | |
//<mn id="84">3</mn><mo>+</mo><mrow id="86"><mi id="87">e</mi><mfenced id="91"><mrow><mrow id="89"><mo>-</mo><mi id="90">a</mi></mrow></mrow></mfenced></mrow> | |
verify('["+", 3, ["*", "e", ["-", "a"]]]', /<mn id="[0-9]*">3<\/mn><mo>\+<\/mo><mrow id="[0-9]*"><mi id="[0-9]*">e<\/mi><mfenced id="[0-9]*"><mrow><mrow id="[0-9]*"><mo>-<\/mo><mi id="[0-9]*">a<\/mi><\/mrow><\/mrow><\/mfenced><\/mrow>/); | |
// <mn id="106">3</mn><mo>+</mo><mfenced id="114"><mrow><mrow id="108"><mrow id="110"><mo>-</mo><mi id="111">a</mi></mrow><mi id="113">e</mi></mrow></mrow></mfenced> | |
verify('["+",3,["*",["-","a"], "e"]]', /<mn id="[0-9]*">3<\/mn><mo>\+<\/mo><mfenced id="[0-9]*"><mrow><mrow id="[0-9]*"><mrow id="[0-9]*"><mo>-<\/mo><mi id="[0-9]*">a<\/mi><\/mrow><mi id="[0-9]*">e<\/mi><\/mrow><\/mrow><\/mfenced>/); | |
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", "y"], "t"]', /<mo id="[0-9]*">∫<\/mo><mrow id="[0-9]*"><mi id="[0-9]*">x<\/mi><mo>\+<\/mo><mi id="[0-9]*">y<\/mi><\/mrow><mi id="[0-9]*">dt<\/mi>/); | |
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>/); | |
verify('["=", "x", ["+", "y", "z"]]', /<mi id="[0-9]*">x<\/mi><mo id="[0-9]*">=<\/mo><mrow id="[0-9]*"><mi id="[0-9]*">y<\/mi><mo>\+<\/mo><mi id="[0-9]*">z<\/mi><\/mrow>/); | |
verify('["part", "y", "x"]', /<mfrac id="[0-9]*"><mrow><mo>∂<\/mo><mi id="[0-9]*">y<\/mi><\/mrow><mrow><mo>∂<\/mo><mi id="[0-9]*">x<\/mi><\/mrow><\/mfrac>/); | |
verify('["/", "x", "y"]', /<mfrac id="[0-9]*"><mrow><mi id="[0-9]*">x<\/mi><\/mrow><mrow><mi id="[0-9]*">y<\/mi><\/mrow><\/mfrac>/); | |
} | |
function verifySerializer(input, expect) { | |
var actual = SexpSerializer(JsonParser(input)); | |
assertEq(expect, actual); | |
} | |
function SerializerTest() { | |
verifySerializer(["a", 1, 2],'["a",1,2]'); | |
verifySerializer(["a", [1, 2]],'["a",\n [1,2]\n]'); | |
} | |
function UnitTest() { | |
try { | |
EvalTest(); | |
SerializerTest(); | |
dp("test sucess!"); | |
}catch(e) { | |
dp("test fail!"); | |
dp(e); | |
} | |
} | |
var KEY_ENTER = 13; | |
var KEY_LEFT = 37; | |
var KEY_RIGHT = 39; | |
var KEY_C = 67; | |
var KEY_D = 68; | |
var KEY_V = 86; | |
var KEY_W = 87; | |
var g_selected = undefined; | |
function onload() { | |
UnitTest(); | |
var canv = $("mathcanvas"); | |
canv.addEventListener("click", function(evt) { | |
UnSelectExpression(); | |
var id = evt.target.getAttribute("id"); | |
var obj = g_hash[id]; | |
if(!obj) { | |
return; | |
} | |
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("keyup", function(evt) { | |
if(!g_selected) | |
return; | |
// alert(evt.keyCode); | |
if(evt.keyCode == KEY_D && | |
evt.shiftKey) { | |
PartialDerivative(g_selected); | |
Update(g_sexp); | |
} | |
if(evt.keyCode == KEY_W) { | |
WidenSelection(g_selected); | |
Update(g_sexp); | |
} | |
if(evt.keyCode == KEY_C) { | |
Copy(g_selected.obj); | |
} | |
if(evt.keyCode == KEY_V){ | |
Paste(g_selected.obj); | |
Update(g_sexp); | |
} | |
}); | |
document.body.addEventListener("keypress", function(evt) { | |
if(!g_selected) | |
return; | |
if(evt.keyCode == KEY_LEFT) { | |
MoveLeftTerm(g_selected); | |
Update(g_sexp); | |
} else if (evt.keyCode == KEY_RIGHT) { | |
MoveRightTerm(g_selected); | |
Update(g_sexp); | |
} else if (evt.keyCode == KEY_ENTER){ | |
Register($("input").value); | |
} | |
// alert(evt.keyChar); | |
// alert(evt.keyCode); | |
}); | |
} | |
function UnSelectExpression() { | |
if(g_selected) { | |
g_selected.elem.setAttribute("class", ""); | |
} | |
g_selected = undefined; | |
} | |
</script> | |
<br> | |
<textarea id="input" rows="2" cols="100" onfocus="UnSelectExpression();"></textarea><br> | |
<input value="Set" type="button" onclick="clicked();"> | |
<input value="Register" type="button" onclick="Register($('input').value);"> | |
<input value="Overwrite" type="button" onclick="Overwrite($('input').value);"> | |
<br> | |
<div id="mathcanvas"></div> | |
<hr> | |
<input value="Clear" type="button" onclick="onClear();"><br> | |
<textarea id="console" rows="10" cols="100" ></textarea><br> | |
以下は適当な例。<br> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mi id="73">x</mi><mo id="72">=</mo><mrow id="75"><mi id="76">y</mi><mo>+</mo><mi id="77">z</mi></mrow> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mfrac id="687"> | |
<mrow id="691"> | |
<mi id="692">b</mi> | |
<mi id="693">c</mi> | |
</mrow> | |
<mrow> | |
<mrow id="696"> | |
<mo>-</mo> | |
<mi id="697">x(t)</mi> | |
</mrow> | |
<mo>+</mo> | |
<mi id="699">a</mi> | |
<mo>+</mo> | |
<mfrac id="701"> | |
<mrow id="703"> | |
<mi id="704">π</mi> | |
<mi id="705">k</mi> | |
</mrow> | |
<msup> | |
<mi id="709">e</mi> | |
<mrow id="711"> | |
<mo>-</mo> | |
<mrow id="713"> | |
<mi id="714">ρ</mi> | |
<mi id="715">t</mi> | |
</mrow> | |
</mrow> | |
</msup> | |
</mfrac> | |
<mrow id="722"> | |
<mn id="723">2</mn> | |
<mi id="724">b</mi> | |
</mrow> | |
</mrow> | |
</mfrac> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mfrac><mi>x</mi><mi>y</mi></mfrac> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<msup> | |
<mi>a</mi> | |
<mi>b</mi> | |
</msup> | |
</math> | |
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> | |
<mrow class="selectedTarget"> | |
<mi>a</mi> | |
<mi>b</mi> | |
<mi>c</mi> | |
</mrow> | |
</math> | |
<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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment