/*
JSP to JSXG 1.8.108
2016-2018
Henri Tanskanen
This file is the core of JSP to JSXG convertor.
JSP to JSXG converter is free to use tool under UEF licence.
JSP to JSXG was programmed during working proccess of my
Master's Thesis. Purpose was mainly to use it in converting
previously made JSP sketches in new form. For myself this tool
has also been in use for several times just to simplify the creation
of a JSXGraph image, since the JSP syntax is easier to write.
JSP to JSXG convertor is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
//macros update
var jsp_macros = "";
/** JAVASKETCHPAD TO JSXGRAPH CONVERTER : MAIN FUNCTION
* This is the main function, that creates converted JSXGraph code from code-input and other input elements.
* This function connects all the parts that are needed when constructing JSXG element from JSP element.
* Input variables are:
* code_input that is jsp code we want to convert (String)
* size_input (optional) has table size information as width and height for example [400,400] (Array)
* elementname_input (optional) has the element name information (String)
* isFullPageConvert (optional) has the info if we are using fullpage convertor (boolean)
* @param {String} code_input - original Java Sketchpad code
* @param {Array<Int>} size_input - tablesize
* @param {String} elementname_input - element name
* @param {Boolean} isFullPageConvert - if is full page conver
* @return {String} codestring - fully converted code to JSXGraph
*/
function jspToJsx(code_input, size_input, elementname_input, isFullPageConvert) {
var locusPoints=30,
animticks = 50,
locus_counter = 0,
startingtime = 0,
endingtime = 0,
executiontime = 0,
evas = [],
codestring = "",
boardname = "",
elid = "",
origstring = "<h3><u>JavaSketchpad code</u></h3>",
tmpstring = "",
errors = "<u>Errors:</u><br><br>",
sketch = "",
jsxrenderer = "",
boardstyle = "",
boarddiv = "",
board_update_events = "",
scriptsource = "",
styleSource = "",
utf8Encoding = "",
clearTraceStyling = getUserVal('cleartracestyle'),
mathjaxsource,
font_family,
sgrid,
use_hide_el = true,
buttonstyle="<sty"+"le>.jxgbox button {padding:",
animtype,
sketchrows = [],
sketchrows_comment =[],
elr =[],
el =[],
calc = [],
animate = [],
unit = 1,
right_side_titles_and_buttons = [];
try {
clearAll(['jsxgimage','jsxgcode','JSketchPadCode','testing', 'errormessages'], ['err_comms', 'err_info', 'err_submit_btn', 'ERRORS']);
/* reading sketchcode and setting
* coordinate system (if in code command UnitPoint, else 100px)
*/
if (code_input.length>12)
sketch = code_input;
else
sketch = getUserVal(code_input).replace(/(\r\n|\n|\r|" ")/gm,"");
sketch = sketch.replace(/(\t)/gm, " ");
sketch = sketch.trim();
//BREAK IF CODE WONT PASS DUMMYTEST
if (!codeDummyTest(sketch)) {
alert('There is some problems in your JSP-code. Convertion was stopped. Check your code!');
return false;
//
}
//check codestyle (and switch from JSP-$ if needed)
if(!checkJSPStyle(sketch)) sketch = varJSPtoNumJSP(sketch);
// Reading sketch settings from user interface
let UI_SETTINGS = new JSPtoJSXUISettings(sketch,'boardwidthinput', 'boardheightinput', 'scale', 'zoom', 'jsxgboardname', 'jsxgelementid', 'source', 'addmathjax', 'mathjax_source', 'addstylesheet', 'stylesource',
'originalcode', 'jsxrenderer_sel', 'jsxpointsize', 'measurementaccuracy', 'animationsel', 'addgridlayer', 'cleartracebutton', 'cleartracestyle', 'latex', 'latex_fixedtext', 'jsxgimageborders', 'addutf8',
'forcewhiteback', 'usehighlight', 'showgrid', 'drawaxis', 'hide_element', 'curve_locus', 'jsxshowinfo', 'usebuttonstyle', 'buttonpaddingsel', 'buttonmargintopsel', 'buttonbackgroundcolorsel', 'buttonverticaladjsel',
'jsxlabelalignment', 'vectortranslation_correction');
if (elementname_input && isFullPageConvert) {
UI_SETTINGS.boardName = UI_SETTINGS.elementID = elementname_input;
}
//input codearea to err_jspcode for submitting errors
document.getElementById('err_jspcode').value = sketch;
document.getElementById('jsxgboardname').value = boardname = UI_SETTINGS.boardName;
document.getElementById('jsxgelementid').value = elid = UI_SETTINGS.elementId;
sketchrows = separateCommands(sketch); // getting the rows from the JSP code
for (var i in sketchrows) { //creating each jsp-jsx object
elr[i] = sketchpadrowToJsxgElement(sketchrows[i], UI_SETTINGS.appletsize, UI_SETTINGS.coord_div, UI_SETTINGS.scale, UI_SETTINGS.scale, UI_SETTINGS.has_origin_unit, boardname); // each row into JSXG object
}
// reading user input for jsxgraphcore.js source
scriptsource = getUserVal('source');
if (scriptsource.length < 2) {
alert('Invalid JSXGraph script source.');
return null;
}
// reading stylesheet source
if (getUserVal('addstylesheet')) {
styleSource = getUserVal('stylesource');
if (styleSource.length < 2) {
alert('Invalid stylesheet script source.');
return null;
}
else {
styleSource = "<link rel='stylesheet' type='text/css' href='"+styleSource+"' />\n";
}
}
//utf-8 encoding
if (getUserVal('addutf8'))
utf8Encoding = "<!-- HTML5 --><meta charset='utf-8'> \n<!-- HTML 4.x --><meta http-equiv='content-type' content='text/html; charset=utf-8'>\n";
//jsx renderer
if (document.getElementById('jsxrenderer_sel').value != 'default')
jsxrenderer = "\trenderer:'"+ document.getElementById('jsxrenderer_sel').value +"',\n ";
//hiding option 12.3.2018
if (document.getElementById('hide_element').checked == true) use_hide_el = false;
// getting animation type option
animtype = document.getElementById('animationsel').value;
if (animtype != "animtype1") animticks = eval(animtype.slice(10, 12));
//buttonstyle
if (UI_SETTINGS.buttonStyling) {
buttonstyle = "#"+boardname+
" button {padding:" + UI_SETTINGS.buttonPadding +
"margin-top:"+ UI_SETTINGS.buttonMarginTop +
"background-color:"+ UI_SETTINGS.buttonBackground +
"}\n";
} else buttonstyle = "";
boardstyle = "<sty"+"le>#"+boardname + " {\n" +
"\tborder-style:solid;\n"+
"\tborder-width:"+UI_SETTINGS.addBorder+"px;\n"+
"\twidth:"+UI_SETTINGS.appletsize[0]+"px;\n"+
"\theight: "+UI_SETTINGS.appletsize[1]+"px;\n"+
"\toverflow: hidden;\n"+
"\tposition: relative;\n"+
"\tbackground-color:#"+UI_SETTINGS.bgColour+";"+
"}\n"+
"\t"+buttonstyle+
//UI_SETTINGS.labelsizeStyleAddon+
"</s"+"tyle>\n";
boarddiv = "<div class='jxgbox' id='"+boardname+"' > </div>"
// initializing board element for the html page (this program)
document.getElementById("jsxgimage").innerHTML = /*buttonstyle.replace('#'+boardname, '.jxgbox')+*/boardstyle+boarddiv;
// writing var board iniatilizing and variable definitions into codestring, evaluating them
// and replacing boardname for generated code
codestring = "var "+boardname+
"_b = JXG.JSXGraph.initBoard('"+boardname+"', {\n"+
jsxrenderer+
"\tboundingbox:["+UI_SETTINGS.boardsize+"],\n"+
"\toriginX:"+UI_SETTINGS.originXY.X+", originY:"+UI_SETTINGS.originXY.Y+",\n"+
"\tzoomX:"+UI_SETTINGS.zoom+", zoomY:"+UI_SETTINGS.zoom+",\n"+
"\tkeepaspectratio:false,\n"+
"\taxis:"+UI_SETTINGS.drawAxis+",\n"+
"\tshowCopyright: false,\n"+
"\tshowNavigation: false,\n"+
"\tgrid: "+UI_SETTINGS.showGrid+",\n";
if (document.getElementById('cleartracebutton').value == 'show' || (document.getElementById('cleartracebutton').value == 'auto' && sketch.indexOf('traced')>0))
codestring = codestring + "\tshowClearTraces:true\n";
codestring = codestring +
"} );\n"+
// defining variables that will be written in converter code
"var "+
elid+"_el=[],\n"+
elid+"_tel=[],\n"+
elid+"_transf=[],\n"+
elid+"_transf2=[],\n"+
elid+"_animOn=false,\n"+
elid+"_unit;\n\n";
if (codestring.indexOf('showClearTraces:true')>0) codestring+="document.getElementById('"+boardname+"_navigationbar').firstChild.innerHTML = '"+clearTraceStyling+"';\n";
if (UI_SETTINGS.addGridLayers > 0) {
for (var i=0; i<UI_SETTINGS.addGridLayers; i++) {
codestring += boardname + "_b.create('grid', []);\n";
}
}
eval(codestring); // eavaluating board and varaibles for the sample sketch in the right column of converter page
if (!isFullPageConvert)
codestring += "\n";
codestring = codestring.replace("JSXBoard",boardname); // replacing boardname with user defined name
if (contains(UI_SETTINGS.printJsp, 'Yes') && !isFullPageConvert) {
if (contains(UI_SETTINGS.printJsp,'Yes with tags'))
document.getElementById("JSketchPadCode").innerHTML = getOrigString(elr, UI_SETTINGS.width, UI_SETTINGS.height, true);
else
document.getElementById("JSketchPadCode").innerHTML = getOrigString(elr, UI_SETTINGS.width, UI_SETTINGS.height, false);
}
for (var i in elr) {
el[elr[i].Row] = elr[i];
sketchrows_comment[elr[i].Row] = elr[i];
// console.log wanted object values for testing
//console.log("Row: "+elr[i].Row +", Type: "+elr[i].Type+", JsxType: "+elr[i].JsxType+", Pos: "+elr[i].Pos+", Opt: "+elr[i].Opts+", Att.Info: "+elr[i].Att.Info+ ", Anim: "+elr[i].Anim);
}
//MathJax in code
var add_mathjax = "";
if (document.getElementById('addmathjax').checked == true)
add_mathjax = "<"+"scr"+"ipt src='" + document.getElementById('mathjax_source').value + "'>"+"<"+"/"+"scr"+"ipt>\n";
else add_mathjax = "";
// Beginning of the codestring for the user
codestring += "<><script src ='" + scriptsource +"'> <"+"/scr"+"ipt"+"> \n"+
styleSource +
utf8Encoding +
add_mathjax +
boardstyle +
boarddiv +"\n<"+
"script"+">//![CDATA[\n"+
"(function(){\n"+
codestring;
//this is to calculate time that convertion takes
var startingtime = new Date().getTime();
console.log('all ok start to convert');
for (var i in el) {
if (el[i].Att.Stop)
break;
else if (el[i].Row ) {
var obj_c = elid+"_el["+el[i].Row+"] = "+boardname+"_b.create";
// POINTS * * * * /
if (el[i].JsxType == 'point') {
evas[el[i].Row] = obj_c+"('point', ["+el[i].Pos+"],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'unitpoint'){
evas[el[i].Row] = obj_c+"('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].X()+"+1+";}, function(){return "+elid+"_el["+el[i].Pos[0]+"].Y();}],"+setAttributes(el[i],'',use_hide_el,elid)+" );";
}
else if (el[i].JsxType == 'midpoint'){
evas[el[i].Row] = obj_c+"('midpoint', ["+elid+"_el["+el[i].Pos[0]+"]],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'intersection') {
evas[el[i].Row] = obj_c+"('intersection', ["+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"], "+el[i].Att.Info+"],"+setAttributes(el[i],'alwaysIntersect:false',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'glider') {
tmpstring = gliderPoint(eval(elid+"_el["+el[i].Pos[0]+"]"),el[i].Pos[1],eval(elid+"_el["+el[el[i].Pos[0]].Pos[0]+"]"))[0]+","+gliderPoint(eval(elid+"_el["+el[i].Pos[0]+"]"),el[i].Pos[1],eval(elid+"_el["+el[el[i].Pos[0]].Pos[0]+"]"))[1];
evas[el[i].Row] = obj_c+"('glider', ["+tmpstring+","+elid+"_el["+el[i].Pos[0]+"]],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'plotxy') {
// PlotXY(objRef1, objRef2, objRef3);
// Defines the point on the coordinate system objRef2 specified horizontally by the value of measurement objRef3 and vertically by the value of objRef1.
// That is, PlotXY() plots the point (objRef3, objRef1) on objRef2.
//
evas[el[i].Row] = obj_c+"('point', [function() {return "+elid+"_el["+el[el[i].Pos[1]].Pos[0]+"].X() + "+calc[el[i].Pos[2]]+";}, function() {return "+elid+"_el["+el[el[i].Pos[1]].Pos[0]+"].Y() + "+calc[el[i].Pos[0]]+";}],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
// * * * * /POINTS /
// CIRCLES * * * * * /
else if (el[i].JsxType == 'circle') {
evas[el[i].Row] = obj_c+"('"+el[i].JsxType+"', ["+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]],"+setAttributes(el[i],'',use_hide_el,elid)+"); ";
}
else if (el[i].JsxType == 'circle by radius') {
evas[el[i].Row] = obj_c+"('circle', ["+elid+"_el["+el[i].Pos[0]+"], function(){return "+elid+"_el["+el[i].Pos[1]+"].L();}],"+setAttributes(el[i],'',use_hide_el,elid)+"); ";
}
// * * * * * * /CIRCLES /
// STAIGHT LINES * * * * /
else if (el[i].JsxType == 'line' || el[i].JsxType == 'perpendicular' || el[i].JsxType == 'parallel') {
evas[el[i].Row] = obj_c+"('"+el[i].JsxType+"', ["+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[0]+"]],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'segment') {
evas[el[i].Row] = obj_c+"('"+el[i].JsxType+"', ["+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'ray') {
evas[el[i].Row] = obj_c+"('line', ["+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[0]+"]],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'axisx') {
evas[el[i].Row] = obj_c+"('axis', [["+elid+"_el["+el[i].Pos[0]+"][0].X(),"+elid+"_el["+el[i].Pos[0]+"][0].Y()], ["+elid+"_el["+el[i].Pos[0]+"][0].X()+1, "+elid+"_el["+el[i].Pos[0]+"][0].Y()]],"+setAttributes(el[i], '')+"); " +elid+"_el["+el[i].Row+"].removeAllTicks();";
}
else if (el[i].JsxType == 'axisy') {
evas[el[i].Row] = obj_c+"('axis', [["+elid+"_el["+el[i].Pos[0]+"][0].X(),"+elid+"_el["+el[i].Pos[0]+"][0].Y()], ["+elid+"_el["+el[i].Pos[0]+"][0].X(), "+elid+"_el["+el[i].Pos[0]+"][0].Y()+1]],"+setAttributes(el[i], '')+"); "+elid+"_el["+el[i].Row+"].removeAllTicks();";
}
// * * * * /STRAIGHT LINES /
// INTERIORS * * * * * /
else if (el[i].JsxType == 'polygon') {
for (var j=0; j<el[i].Pos.length; j++) {
if (j != el[i].Pos.length-1) tmpstring = tmpstring + elid+"_el["+el[i].Pos[j]+"],"; else tmpstring = tmpstring + elid+"_el["+el[i].Pos[j]+"],"; }
evas[el[i].Row] = obj_c+"('polygon', ["+tmpstring+"],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'circle interior') {
if ((el[el[i].Pos[0]].JsxType == 'circle' || el[el[i].Pos[0]].JsxType == 'circle by radius') && el[i].Opts.indexOf('visible:false')<0) {
evas[el[i].Row] = elid+"_el["+el[i].Pos[0]+"].setAttribute({color:'"+el[i].Att.Color+"'});"; }
else evas[el[i].Row] = "";
}
// * * * * /INTERIORS /
// TRANSFORMATIONS * * * * /
else if (el[i].JsxType == 'reflection') {
evas[el[i].Row] = obj_c+"('"+el[i].JsxType+"', ["+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'dilation') {
evas[el[i].Row] = obj_c+"('point', [function(){return "+el[i].Pos[2]+"*("+elid+"_el["+el[i].Pos[0]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X())+"+elid+"_el["+el[i].Pos[1]+"].X();},function(){return "+el[i].Pos[2]+"*("+elid+"_el["+el[i].Pos[0]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y())+"+elid+"_el["+el[i].Pos[1]+"].Y();}],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'dilation/segmentratio') {
evas[el[i].Row] = obj_c+"('point', [function(){return ("+elid+"_el["+el[i].Pos[2]+"].L()/"+elid+"_el["+el[i].Pos[3]+"].L())*("+elid+"_el["+el[i].Pos[0]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X())+"+elid+"_el["+el[i].Pos[1]+"].X();},function(){return ("+elid+"_el["+el[i].Pos[2]+"].L()/"+elid+"_el["+el[i].Pos[3]+"].L())*("+elid+"_el["+el[i].Pos[0]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y())+"+elid+"_el["+el[i].Pos[1]+"].Y();}],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'dilation/3ptratio') {
// Dilation/3PtRatio (objRef1, objRef2, objRef3, objRef4, objRef5);
// Defines the image of any objRef1 dilated with respect to center point objRef2 by the signed ratio implied by the distances between points objRef3, 4, and 5.
// If these three points are A, B, and C, respectively, the three-point ratio implied by them is |AC|/|AB|.
evas[el[i].Row] = obj_c+"('point', [function(){return Math.sign(Math.cos(JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[3]+"], "+elid+"_el["+el[i].Pos[2]+"], "+elid+"_el["+el[i].Pos[4]+"]))) * ("+elid+"_el["+el[i].Pos[2]+"].Dist("+elid+"_el["+el[i].Pos[4]+"]) / "+elid+"_el["+el[i].Pos[2]+"].Dist("+elid+"_el["+el[i].Pos[3]+"])) * ("+elid+"_el["+el[i].Pos[0]+"].X() - "+elid+"_el["+el[i].Pos[1]+"].X()) + "+elid+"_el["+el[i].Pos[1]+"].X()},function() {return Math.sign(Math.cos(JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[3]+"], "+elid+"_el["+el[i].Pos[2]+"], "+elid+"_el["+el[i].Pos[4]+"]))) * ("+elid+"_el["+el[i].Pos[2]+"].Dist("+elid+"_el["+el[i].Pos[4]+"]) / "+elid+"_el["+el[i].Pos[2]+"].Dist("+elid+"_el["+el[i].Pos[3]+"])) * ("+elid+"_el["+el[i].Pos[0]+"].Y() - "+elid+"_el["+el[i].Pos[1]+"].Y()) + "+elid+"_el["+el[i].Pos[1]+"].Y()}],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'dilation/markedratio') {
evas[el[i].Row] = obj_c+"('point', [function(){var ratio = "+calc[el[i].Pos[2]]+";return ratio*("+elid+"_el["+el[i].Pos[0]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X())+"+elid+"_el["+el[i].Pos[1]+"].X();},function(){var ratio = "+calc[el[i].Pos[2]]+";return ratio*("+elid+"_el["+el[i].Pos[0]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y())+"+elid+"_el["+el[i].Pos[1]+"].Y();}],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'rotation') {
//5.5.6 Rotation (objRef1, objRef2, num);
//Defines the image of any objRef1 rotated around center point objRef2 by the radian angle specified by num.
//eval(elid+"_transf[el[i].Row] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+","+elid+"_el[el[i].Pos[1]]], {type:'rotate'})");
//codestring = codestring +
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+","+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});";
evas[el[i].Row] = evas[el[i].Row] + obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], "+elid+"_transf["+el[i].Row+"]], {name:'"+el[i].Att.Name+"', color:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+", fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute, size:"+el[i].Att.Size+", showInfoBox:"+el[i].Att.Infobox+", label:"+el[i].Att.LabelAlign+"} );";
}
else if (el[i].JsxType == 'rotation/measuredangle') {
//5.5.6 Rotation (objRef1, objRef2, objRef3);
// Defines the image of any objRef1 rotated around center point objRef2 by the radian angle expressed by measurement objRef3.
if (eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='circle') {
//el[i].CType = "circles";
//evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[+el[i].Pos[2]]+"},"+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});" + obj_c+"('point',["+elid+"_el["+el[i].Pos[0]+"].center, "+elid+"_transf["+el[i].Row+"]],"+setAttributes(el[i], "fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute",use_hide_el)+"); "+boardname+"_b.create('circle', ["+elid+"_el["+el[i].Row+"], function(){return "+elid+"_el["+el[i].Pos[0]+"].radius;}],"+setAttributes(el[el[i].Pos[0]],'',use_hide_el,elid)+");";
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[+el[i].Pos[2]]+"},"+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});" + elid+"_el["+el[i].Row+"] = " + boardname + "_b.create('point',["+elid+"_el["+el[i].Pos[0]+"].center, "+elid+"_transf["+el[i].Row+"]],"+setAttributes(el[i], "fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute",use_hide_el)+"); "+elid+"_tel["+el[i].Row +"] = " + boardname + "_b.create('circle', ["+elid+"_el["+el[i].Row+"], function(){return "+elid+"_el["+el[i].Pos[0]+"].radius;}],"+setAttributes(el[/*el[i].Pos[0]*/el[i].Row],'',use_hide_el,elid,'circles')+");";
}
else {
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[+el[i].Pos[2]]+"},"+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});" + obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], "+elid+"_transf["+el[i].Row+"]],"+setAttributes(el[i], "fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", use_hide_el,elid)+");";
}
if(el[i].Opts.indexOf('traced')>=0 && el[i].Opts.indexOf('visible:false')<0) {
//evas[el[i].Row] = evas[el[i].Row] + "\n\n"+ boardname+"_b.on('update', function(){if("+calc[+el[i].Pos[2]]+">=0 || "+calc[+el[i].Pos[2]]+"<0) "+elid+"_el["+el[i].Row+1 +"].setAttribute('trace:true'); });"
board_update_events = board_update_events + "if("+calc[+el[i].Pos[2]]+">=0 || "+calc[+el[i].Pos[2]]+"<0) "+elid+"_tel["+el[i].Row +"].setAttribute('trace:true');";
}
}
else if (el[i].JsxType == 'rotation/markedangle') {
/* Rotation/MarkedAngle (objRef1, objRef2, objRef3, objRef4, objRef5);
* Defines the image of any objRef1 rotated around center point objRef2 by the directed angle implied by the three points objRef3-objRef4-objRef5.
* JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[2]+"], "+elid+"_el["+el[i].Pos[3]+"], "+elid+"_el["+el[i].Pos[4]+"])
*/
if (el[el[i].Pos[0]].CType == 'points'){
evas[el[i].Row] = elid+"_transf[el[i].Row] = "+boardname+"_b.create('transform', [function() {return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[2]+"], "+elid+"_el["+el[i].Pos[3]+"], "+elid+"_el["+el[i].Pos[4]+"]);},"+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});\n" + obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], "+elid+"_transf["+el[i].Row+"]],"+setAttributes(el[i], "fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", use_hide_el,elid)+");";
el[i].ParentType = 'points';
} else if (el[el[i].Pos[0]].CType == 'straightlines') {
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function() {return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[2]+"], "+elid+"_el["+el[i].Pos[3]+"], "+elid+"_el["+el[i].Pos[4]+"]);},"+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});"
evas[el[i].Row] = evas[el[i].Row] + "\n" + obj_c +
"('" + eval(elid+"_el["+el[i].Pos[0]+"]").getType() + "', ["+
"["+elid+"_el["+el[i].Pos[0]+"].point1, "+elid+"_transf["+el[i].Row+"]], "+
"["+elid+"_el["+el[i].Pos[0]+"].point2, "+elid+"_transf["+el[i].Row+"]]],"+setAttributes(el[el[i].Pos[0]], "fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", el[i] )+");";
el[i].ParentType = 'straightlines';
}
else {
alert('Rotation/MarkedAngle works only for points and straight lines for now... Convertion stopped on line ' + el[i].Row + "," + el[i].Type + "(" + el[i].Pos + ")[" + el[i].Opts.slice(1) + "];");
return null;
}
}
else if (el[i].JsxType == 'translation') {
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', ["+UI_SETTINGS.scale*el[i].Pos[1]/UI_SETTINGS.coord_div+","+ UI_SETTINGS.scale*el[i].Pos[2]/UI_SETTINGS.coord_div+"], {type:'translate'});" + obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], "+elid+"_transf["+el[i].Row+"]],"+setAttributes(el[i], "fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'translation/fixedangle/markeddistance') {
/* Translation/FixedAngle/MarkedDistance (objRef1, objRef2, num);
* Defines the image of any objRef1 translated by the distance expressed by measurement objRef2 in the direction expressed by num radians.
* [ https://www.math.uni-bielefeld.de/~lisken/jsp/qref.html ]
*/
if (el[el[i].Pos[0]].CType == 'points' || el[el[i].Pos[0]].CType == 'transformations' || jsp_macros.indexOf(el[el[i].Pos[0]].Type)>=0) {
eval(elid+"_transf[el[i].Row] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, 0], {type:'translate'})");
eval(elid+"_transf2[el[i].Row] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"]], {type:'rotate'})");
codestring = codestring + elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, 0], {type:'translate'});";
codestring = codestring + elid+"_transf2["+el[i].Row+"] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"]], {type:'rotate'});";
evas[el[i].Row] = obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], ["+elid+"_transf["+el[i].Row+"],"+elid+"_transf2["+el[i].Row+"]]],"+setAttributes(el[i], "fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", use_hide_el,elid)+");";
}
else if (el[el[i].Pos[0]].CType == 'straightlines') {
eval(elid+"_transf[el[i].Row] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, 0], {type:'translate'})");
eval(elid+"_transf2[el[i].Row] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"].point1], {type:'rotate'})");
eval(elid+"_transf2[el[i].Row +1 ] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"].point2], {type:'rotate'})");
codestring = codestring + elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, 0], {type:'translate'});";
codestring = codestring + elid+"_transf2["+el[i].Row+"] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"].point1], {type:'rotate'});";
codestring = codestring + elid+"_transf2["+el[i].Row + 1+"] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"].point2], {type:'rotate'});";
evas[el[i].Row] = obj_c+"('line', [["+elid+"_el["+el[i].Pos[0]+"].point1, ["+elid+"_transf["+el[i].Row+"],"+elid+"_transf2["+el[i].Row+"]]], ["+elid+"_el["+el[i].Pos[0]+"].point2, ["+elid+"_transf["+el[i].Row+"],"+elid+"_transf2["+el[i].Row+"+1]]]],"+setAttributes(el[i], "fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", use_hide_el,elid)+");";
}
else {
alert( el[i].Type + " not working for " + el[el[i].Pos[0]].CType + ", \nline " + el[i].Row + " in JSP code. \nConverting was stopped!");
return 'null';
}
}
else if (el[i].JsxType == 'translation/markedangle/markeddistance') {
/* Translation/MarkedAngle/MarkedDistance (objRef1, objRef2, objRef3);
* Defines the image of any objRef1 translated by the distance expressed by distance measurement objRef3 in the direction expressed by angle measurement objRef2.
* [ https://www.math.uni-bielefeld.de/~lisken/jsp/qref.html ]
*/
eval(elid+"_transf[el[i].Row] = "+boardname+"_b.create('transform', [function(){return Math.abs("+elid+"_el["+el[i].Pos[0]+"].X()-("+calc[el[i].Pos[2]]+"/UI_SETTINGS.coord_div))+"+elid+"_el["+el[i].Pos[0]+"].X();}, 0], {type:'translate'})");
eval(elid+"_transf2[el[i].Row] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, "+elid+"_el["+el[i].Pos[0]+"]], {type:'rotate'})");
codestring = codestring + elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return Math.abs("+elid+"_el["+el[i].Pos[0]+"].X()-("+calc[el[i].Pos[2]]+"/UI_SETTINGS.coord_div))+"+elid+"_el["+el[i].Pos[0]+"].X();}, 0], {type:'translate'});";
codestring = codestring + elid+"_transf2["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, "+elid+"_el["+el[i].Pos[0]+"]], {type:'rotate'});";
evas[el[i].Row] = obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], ["+elid+"_transf["+el[i].Row+"],"+elid+"_transf2["+el[i].Row+"]]],"+setAttributes(el[i], "fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", use_hide_el,elid)+");";
}
else if (el[i].JsxType == 'vectortranslation') {
// VectorTranslation (objRef1, objRef2, objRef3);
// Defines the image of any objRef1 translated by the vector implied by two points objRef2 -> objRef3.
// objRef2 is the foot of the vector, and objRef3 is its tail.
if (eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='point' || eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='glider' || el[el[i].Pos[0]].JsxType=='intersection' || eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='reflection' || eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='midpoint') {
//evas[el[i].Row] = obj_c+"('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].X()+(Math.sign("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X()))*Math.abs("+elid+"_el["+el[i].Pos[1]+"].X()-"+elid+"_el["+el[i].Pos[2]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].Y()+(Math.sign("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y()))*Math.abs("+elid+"_el["+el[i].Pos[1]+"].Y()-"+elid+"_el["+el[i].Pos[2]+"].Y());}],"+setAttributes(el[i],'',use_hide_el,elid)+");";
//evas[el[i].Row] = obj_c+"('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}],"+setAttributes(el[i],'',use_hide_el,elid)+");";
eval (elid + "_transf[" + el[i].Row + "] = " + boardname + "_b.create('transform', [function(){return "+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X();},function(){return "+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y();}], {type:'translate'});");
codestring = codestring + elid + "_transf[" + el[i].Row + "] = " + boardname + "_b.create('transform', [function(){return "+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X();},function(){return "+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y();}], {type:'translate'});";
evas[el[i].Row] = obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], "+ elid+"_transf["+el[i].Row+"]],"+setAttributes(el[i],'',use_hide_el,elid)+");";
}
// FOR SEGMENT
else if (eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='segment') {
if (el[el[i].Pos[0]].Att.ArrowF == true) el[i].Att.ArrowF=true; else el[i].Att.ArrowF=false;
if (el[el[i].Pos[0]].Att.ArrowL == true) el[i].Att.ArrowL=true; else el[i].Att.ArrowL=false;
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].point1.X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].point1.Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}] );"+elid+"_transf["+el[i].Row+"].hideElement(); "+elid+"_transf2["+el[i].Row+"] = "+boardname+"_b.create('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].point2.X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].point2.Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}] );"+elid+"_transf2["+el[i].Row+"].hideElement(); "+obj_c+"('segment', ["+elid+"_transf["+el[i].Row+"], "+elid+"_transf2["+el[i].Row+"]], "+setAttributes(el[i],'strokeWidth:'+el[i].Att.Strokewidth,use_hide_el,elid)+" );";
}
// FOR LINE
else if (eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='line') {
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].point1.X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].point1.Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}] );"+elid+"_transf["+el[i].Row+"].hideElement(); "+elid+"_transf2["+el[i].Row+"] = "+boardname+"_b.create('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].point2.X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].point2.Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}] );"+elid+"_transf2["+el[i].Row+"].hideElement(); "+obj_c+"('line', ["+elid+"_transf["+el[i].Row+"], "+elid+"_transf2["+el[i].Row+"]], "+setAttributes(el[i],'strokeWidth:'+el[i].Att.Strokewidth,use_hide_el,elid)+" );";
}
// FOR CIRCLES
else if (eval(elid+"_el["+el[i].Pos[0]+"].getType()") =='circle') {
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].center.X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].center.Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}] );"+elid+"_transf["+el[i].Row+"].hideElement(); "+obj_c+"('circle', ["+elid+"_transf["+el[i].Row+"], function() {return "+elid+"_el["+el[i].Pos[0]+"].Radius();}], "+setAttributes(el[i],'strokeWidth:'+el[i].Att.Strokewidth,use_hide_el,elid)+" );";
}
}
// * * * * * * /TRANSFORMATIONS /
// * * * * * * IMAGES /
else if (el[i].JsxType == 'image') {
// Image (num1, num2, string);
// Defines a rectangular picture image positioned in the plane at the (X, Y) location specified by (num1, num2).
// string specifies the URL of the image relative to the URL of the web page which contains this
//
let imgWidth="",
imgHeight="";
document.getElementById('hiddenimg').src = el[i].Pos[2];
imgWidth = document.getElementById('hiddenimg').width;
imgHeight = document.getElementById('hiddenimg').height;
[imgWidth, imgHeight] = [imgWidth/UI_SETTINGS.coord_div, imgHeight/UI_SETTINGS.coord_div];
evas[el[i].Row] = obj_c+"('image', ['"+el[i].Pos[2]+"',["+el[i].Pos[0]+","+el[i].Pos[1]+"], ["+imgWidth+","+imgHeight+"]], {visible:"+el[i].Att.Visible+"} );";
}
// * * * * * * /IMAGES /
// MEASUREMENTS * * * * * /
else if (el[i].JsxType == 'length') {
// Length(obj1, numX, numY, string);
// Constructs a measurement of the length of segment obj1.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].L();} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[1]+','+el[i].Pos[2]+',function(){return "'+el[i].Pos[3] +'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'angle') {
// Angle(obj1, obj2, obj3, numX, numY, string);
// Constructs a measurement of the angle implied by the three points obj1, obj2, and obj3, with obj2 being the vertex of the angle.
// The angle will be reported as either a directed or an undirected angle, depending on the setting of the global DirectedAngles parameter.
//evas[el[i].Row] = "function "+elid+el[i].Row+"() {if (JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]) < 3.141593) return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]); else return 6.28318530718 - JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]);}";
if (UI_SETTINGS.directed_angles == 1)
evas[el[i].Row] = "function "+elid+el[i].Row+"() {if (JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]) < 3.141593) return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]); else return -1* (6.28318530718 - JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]));}";
else if (UI_SETTINGS.directed_angles == 0)
evas[el[i].Row] = "function "+elid+el[i].Row+"() { return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]);}";
else errors = errors + "DirectedAngles parameter is invalid!\n";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[3]+','+el[i].Pos[4]+',function(){return "'+el[i].Pos[5] +'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'circumference') {
// Circumference(obj1, numX, numY, string);
// Constructs a measurement of the circumference of circle or circle interior obj1.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].Radius()*Math.PI*2} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[1]+','+el[i].Pos[2]+',function(){return "'+el[i].Pos[3]+'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'radius') {
// Radius(obj1, numX, numY, string);
// Constructs a measurement of the radius of circle or circle interior obj1.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].Radius()} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[1]+','+el[i].Pos[2]+',function(){return "'+el[i].Pos[3]+'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'area') {
// Area (obj1, numX, numY, string);
// Constructs a measurement of the area of the circle, circle interior, or polygon interior obj1. Note that the area is reported in square distance units.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].Area()} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[1]+','+el[i].Pos[2]+',function(){return "'+el[i].Pos[3]+'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'slope') {
// Slope (obj1, numX, numY, string);
// Constructs a measurement of the slope of straight object obj1.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].getSlope()} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[1]+','+el[i].Pos[2]+',function(){return "'+el[i].Pos[3]+'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'calculate') {
// Calculate(numX, numY, prefixStr, exprStr) (objRef1, ..., objRefN);
// Constructs a measurement of the value of a calculated expression. numX, numY, and prefixStr are the standard left and top coordinates and prefix string of every measurement object; exprStr contains a representation of the expression to calculate, and objRef1 through objRefN are object identifiers of any other measurement objects the value of which act as components of the expression.
///
// The exprStr expression is expressed in reverse Polish notation (RPN), in which arithmetic operators follow their operands. RPN eliminates the need for parentheses, because the order of evaluation is strictly left-to-right. Thus "(1+2)/3" can be phrased in RPN as "1 2 + 3 /".
//
// Valid tokens within exprStr include:
//
// numeric constants. Any real number can be expressed, with an optional preliminary negative sign (for negative numbers) and an optional single decimal point (for expressing non-integer values). A numeric constant may include a terminal space to delimit it in circumstances where two numeric constants are adjacent.
// +, -, /, *. These operators perform their standard arithmetic operation: addition, subtraction, division, and multiplication.
// ^: This operator performs exponentiation.
// %: This operator performs unary negation.
// @xxxx: This operator applies a predefined function. xxxx is a four-character sequence indicating the function, and may be one of the following: sin_ (sine), cos_ (cosine), tan_ (tangent), abs_ (absolute value), sqrt (square root), ln__ (natural log), rond (rounding), trnc (truncation toward zero), sgn_ (signnum), asin (arcsine), acos (arccosine), atan (arctangent), or log_ (base-10 logarithm).
// x where x is in {A-Z}. This operand substitutes the value of another measurement in the sketch: A corresponds to measurement objRef1, B corresponds to measurement objRef2, etc. It is an error to pass an operator that does not have a corresponding objRef; i. e. to refer to C when you only supply two objRefs in the construction (implicitly, A and B).
// #xy where x is in {A-Z} and y is in {1-9}. This operand substitutes the value of component y of a vector-based measurement x. x refers to an objRef according to the same rules above (i. e. A is objRef1, B is objRef2, etc.). Parent objRefx must be a vector-based measurement: in DR3 of JavaSketchpad, the only vector-based measurement is the Coordinate pair. y indicates the component of the vector to isolate. In DR3, the only legal values for y are 1 and 2: 1 indicates the x-component of a coordinate pair, 2 indicates the y-component of that pair.
// Examples:
//
// Calculate(10, 10, 'Sum is ','AB+C+') (5, 6, 7);
//
// Calculates the sum of measurement objects #5, 6, and 7 in the sketch, and positions their sum at (10, 10) on the coordinate plane.
//
// Calculate(20, 20, 'Distance is ','#A1#B1-2^#A2#B2-2^+@sqrt') (8, 9);
//
// Calculates the Euclidean distance (sqrt[dX^2+dY^2]) between the two coordinate pair measurements referenced as objects #8 and 9 in the sketch.
//
// Note that a space character may be used inside exprStr to delimit individual tokens. This allows you to express one plus three as '1 3+' where '13+' would be interpreted as thirteen plus (whatever preceded it).
//
// Note also that the objRef list must not be empty, even if no tokens in the expression refer to object references (i. e. even if the expression's value is constant). This is a limitation of DR3, and will be fixed in the next release.
var tmp = [];
for (var k=0; k<el[i].Pos[4].length; k++)
tmp[k] = el[i].Pos[4][k];
calc[el[i].Row] = calculateFunction(el[i].Pos[3],tmp,calc,el[i].Row);
evas[el[i].Row] = (obj_c+'("text", ['+el[i].Pos[0]+','+el[i].Pos[1]+',function(){return "'+el[i].Pos[2] + ' " + Math.round(('+calc[el[i].Row]+')*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+' + "'+el[i].Att.Suffix+'";}],{color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'});');
//if (!el[i].Att.Visible)
//evas[el[i].Row] = evas[el[i].Row] + elid+"_el["+el[i].Row+"].hideElement();";
}
else if (el[i].JsxType == 'distance') {
/// Distance(obj1, obj2, numX, numY, string);
// Constructs a measurement of the distance between obj1 and obj2.
// obj2 must be a point, obj1 may be either a point or a straight object,
// in which case the distance is reported as the minimum (perpendicular) distance between point obj2 and the extended line containing obj1.
if (el[el[i].Pos[0]].CType == 'points')
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[1]+"].Dist("+elid+"_el["+el[i].Pos[0]+"] ) * "+UI_SETTINGS.unit_in_pixels+"} ";
else if (el[el[i].Pos[0]].CType == 'straightlines' || el[el[i].Pos[0]].ParentType == 'straightlines') {
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return Math.abs(("+elid+"_el["+el[i].Pos[1]+"].X()*("+elid+"_el["+el[i].Pos[0]+"].point2.Y()-"+elid+"_el["+el[i].Pos[0]+"].point1.Y())) - ("+elid+"_el["+el[i].Pos[1]+"].Y()*("+elid+"_el["+el[i].Pos[0]+"].point2.X()-"+elid+"_el["+el[i].Pos[0]+"].point1.X())) + "+elid+"_el["+el[i].Pos[0]+"].point2.X()*"+elid+"_el["+el[i].Pos[0]+"].point1.Y() - "+elid+"_el["+el[i].Pos[0]+"].point2.Y()*"+elid+"_el["+el[i].Pos[0]+"].point1.X() ) / Math.sqrt(Math.pow(("+elid+"_el["+el[i].Pos[0]+"].point2.Y()-"+elid+"_el["+el[i].Pos[0]+"].point1.Y()),2) + Math.pow(("+elid+"_el["+el[i].Pos[0]+"].point2.X()-"+elid+"_el["+el[i].Pos[0]+"].point1.X()),2)) * "+UI_SETTINGS.unit_in_pixels+";} ";
}else
errors = errors + "distance measurement from point to "+ el[el[i].Pos[0]].CType + " is not working (Line "+el[i].Row+")!<br>";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[2]+','+el[i].Pos[3]+',function(){return "'+el[i].Pos[4] + ' " + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'ratio/segments') {
// Ratio/Segments (obj1, obj2, numX, numY, string);
// Constructs a measurement of the ratio of the length of segment obj1 to the length of segment obj2. That is, this construction measures |obj|/|obj2|.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].L() / "+elid+"_el["+el[i].Pos[1]+"].L()} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[2]+','+el[i].Pos[3]+',function(){return "'+el[i].Pos[4] + ' " + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'ratio/points') {
/// Ratio/Points (obj1, obj2, obj3, numX, numY, string);
// Constructs a measurement of the three-point ratio implied by points obj1, obj2, and obj3.
// If these points are A, B, and C, respectively, then the three-point ratio is |AC|/|AB|.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return Math.sign(Math.cos(JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[1]+"], "+elid+"_el["+el[i].Pos[0]+"], "+elid+"_el["+el[i].Pos[2]+"])))*"+elid+"_el["+el[i].Pos[0]+"].Dist("+elid+"_el["+el[i].Pos[2]+"]) / "+elid+"_el["+el[i].Pos[0]+"].Dist("+elid+"_el["+el[i].Pos[1]+"])} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[3]+','+el[i].Pos[4]+',function(){return "'+el[i].Pos[5]+ ' " + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+' + "'+el[i].Att.Suffix+'";}],'+setAttributes(el[i],"",use_hide_el,elid)+');';
}
// * * * * * /MEASUREMENTS /
// BUTTONS /
else if (el[i].JsxType == 'text') {
if (document.getElementById('latex_fixedtext').checked == true)
evas[el[i].Row] = obj_c+'("text", ['+el[i].Pos[0]+','+el[i].Pos[1]+',function(){return "\\\\"+"( '+el[i].Pos[2]+' \\\\"+")";}],'+setAttributes(el[i],"",use_hide_el,elid)+');';
else
evas[el[i].Row] = obj_c+'("text", ['+el[i].Pos[0]+','+el[i].Pos[1]+',function(){return "'+el[i].Pos[2]+'";}],'+setAttributes(el[i],"",use_hide_el,elid)+');';
}
else if (el[i].JsxType == 'movebutton') {
for (var j = 0; j < el[i].Anim.length; j+=2)
tmpstring = tmpstring +elid+"_el["+el[i].Anim[j+1]+"].moveTo(["+elid+"_el["+el[i].Anim[j]+"].X(), "+elid+"_el["+el[i].Anim[j]+"].Y()],"+el[i].Pos[2]+");";
evas[el[i].Row] = obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[3]+' ", function() {'+tmpstring+'} ],'+setAttributes(el[i],"",use_hide_el,elid)+');';
el[i].Anim = tmpstring;
}
else if (el[i].JsxType == 'showbutton') {
for (var j = 0; j < el[i].Anim.length; j++) {
if (el[el[i].Anim[j]]) {
if (el[el[i].Anim[j]].CType == 'buttons' || el[el[i].Anim[j]].CType == 'measurements')
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].showElement();";
else if (el[el[i].Anim[j]].JsxType == 'originandunit')
tmpstring = tmpstring + boardname +"_b.addGrid();";
else if (el[el[i].Anim[j]].JsxType == 'locus') {
if (el[el[el[i].Anim[j]].Pos[1]].JsxType == 'point' && UI_SETTINGS.locusSetting) {tmpstring = tmpstring + elid+el[el[i].Anim[j]].Row+"visible=true;"+elid+"Locus"+el[el[i].Anim[j]].Row+"("+elid+"_el["+el[el[i].Anim[j]].Pos[2]+"],"+elid+"_el["+el[el[i].Anim[j]].Pos[0]+"],"+elid+"_el["+el[el[i].Anim[j]].Pos[1]+"]);";}
else tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({visible:true});";
}
else
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({visible:true});";
//if (el[i].Pos[2].indexOf("Jäljitä") >= 0 || el[i].Pos[2].indexOf("Trace") >= 0)
if (el[el[i].Anim[j]].Opts.indexOf('traced')>=0){
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({trace:true});";
}
}
else errors = errors + "- Error in JSP-code on line {"+el[i].Row+"}. ShowButton is trying to show element that does not excist!<br>";
}
evas[el[i].Row] = obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[2]+' ", function() {'+tmpstring+'} ],'+setAttributes(el[i],"",use_hide_el,elid)+');';
el[i].Anim = tmpstring;
}
else if (el[i].JsxType == 'hidebutton') {
for (var j = 0; j < el[i].Anim.length; j++) {
if (el[el[i].Anim[j]]) {
if (el[el[i].Anim[j]].CType == 'buttons' || el[el[i].Anim[j]].CType == 'measurements')
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].hideElement();";
else if (el[el[i].Anim[j]].JsxType == 'originandunit')
tmpstring = tmpstring + boardname +"_b.removeGrids();";
else if (el[el[i].Anim[j]].JsxType == 'locus') {
if (el[el[el[i].Anim[j]].Pos[1]].JsxType == 'point' && UI_SETTINGS.locusSetting) {tmpstring = tmpstring + elid+el[el[i].Anim[j]].Row+"visible=false;"+elid+"Locus"+el[el[i].Anim[j]].Row+"("+elid+"_el["+el[el[i].Anim[j]].Pos[2]+"],"+elid+"_el["+el[el[i].Anim[j]].Pos[0]+"],"+elid+"_el["+el[el[i].Anim[j]].Pos[1]+"]);";}
else tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({visible:false});";
}
else
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({visible:false});";
//if (el[i].Pos[2].indexOf("Lopeta") >= 0 || el[i].Pos[2].indexOf("Stop") >= 0) {
if (el[el[i].Anim[j]].Opts.indexOf('traced')>=0) {
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({trace:false});";
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].clearTrace();";
}
}
else errors = errors + "- Error in JSP-code on line {"+el[i].Row+"}. HideButton is trying to hide element that does not excist!<br>";
}
evas[el[i].Row] = obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[2]+' ", function() {'+tmpstring+'} ],'+setAttributes(el[i],"",use_hide_el,elid)+');';
el[i].Anim = tmpstring;
}
else if (el[i].JsxType == 'animatebutton') { //ANIMBUTTON
/* AnimateButton
(xpos, ypos, label) (point/path pairs)
(speeds) (once-only flags) (direction flags); */
evas[el[i].Row] ="";
for (var j=0; j<el[i].Anim[0].length; j+=2) {
tmpstring = tmpstring +
"if (!anim"+el[i].Row+j+") {\n"+
"\tanim"+el[i].Row+j+"=true; \n"+
"\t"+elid+"_animOn=true; \n"+
"animateOn"+el[i].Row+j+"();\n"+
"} else {\n"+
"\tanim"+el[i].Row+j+" = false; \n"+
"\t"+elid+"_animOn=false; \n"+
"\tanimateOff"+el[i].Row+j+"();\n"+
"}";
//Create anim path (corners of the board, or segment start and end point)
if (el[i].Anim[3][j] == 1) {//If counter clockwise (on circle) or start-end-start-point on segment
// VANHA TOIMIVA: evas[el[i].Row] = evas[el[i].Row] + "var "+elid+"_path"+el[i].Row+j+"=[];if("+elid+"_el["+el[i].Anim[0][j+1]+"].getType()=='segment'){"+elid+"_path"+el[i].Row+j+"=["+elid+"_el["+el[i].Anim[0][j+1]+"].point1,"+elid+"_el["+el[i].Anim[0][j+1]+"].point2,"+elid+"_el["+el[i].Anim[0][j+1]+"].point1];}else{"+elid+"_path"+el[i].Row+j+"=[["+boardsize[2]+","+boardsize[1]+"],["+boardsize[0]+","+boardsize[1]+"],["+boardsize[0]+","+boardsize[3]+"],["+boardsize[2]+","+boardsize[3]+"],["+boardsize[2]+","+boardsize[1]+"]];}";
evas[el[i].Row] = evas[el[i].Row] +
"function "+elid+"_path"+el[i].Row+j+"(a,b,c) {\n"+
"\tif(a.getType()=='segment'){\n"+
//"\t\treturn [[a.point2.X(), a.point2.Y()], [a.point1.X(), a.point1.Y()], [a.point2.X(), a.point2.Y()]];\n"+
"\t\treturn [[b.X(), b.Y()], [a.point1.X(), a.point1.Y()], [b.X(), b.Y()]];\n"+
"\t}else{\n"+
//"\t\tvar c_x = a.center.X(), c_y = a.center.Y(); \n"+
//"\t\tif(c-c_y<0) b=(3.1416-b)+3.1416; \n"+
//"\t\treturn [[c_x+a.radius*Math.cos(b),c_y+a.radius*Math.sin(b)], \n"+
/*"\t\t\t[c_x+a.radius*Math.cos(b+1.5708),c_y+a.radius*Math.sin(b+1.5708)], \n"+
"\t\t\t[c_x+a.radius*Math.cos(b+3.1416),c_y+a.radius*Math.sin(b+3.1416)], \n"+
"\t\t\t[c_x+a.radius*Math.cos(b+4.7124),c_y+a.radius*Math.sin(b+4.7124)], \n"+
"\t\t\t[c_x+a.radius*Math.cos(b),c_y+a.radius*Math.sin(b)]]; \n"+*/
"return [["+UI_SETTINGS.boardsize[2]+",0], [0,"+UI_SETTINGS.boardsize[1]+"], ["+UI_SETTINGS.boardsize[0]+", 0], [0, "+UI_SETTINGS.boardsize[3]+"], ["+UI_SETTINGS.boardsize[2]+", 0]];"+
"\t}\n"+
"}";
}
else //if clockwise (on circle) or only on-way movement on segment
evas[el[i].Row] = evas[el[i].Row] +
"function "+elid+"_path"+el[i].Row+j+"(a,b,c) {\n"+
"\tif(a.getType()=='segment'){\n"+
"\t\treturn [[a.point1.X(), a.point1.Y()], [a.point2.X(), a.point2.Y()]];\n"+
"\t}else{\n"+
//"\t\tvar c_x = a.center.X(), c_y = a.center.Y(); \n"+
//"\t\tif(c-c_y<0)b=(3.1416-b)+3.1416; \n"+
/*"\t\treturn [[c_x+a.radius*3*Math.cos(b),c_y+a.radius*3*Math.sin(b)], \n"+
"\t\t\t[c_x+a.radius*3*Math.cos(b-1.5708),c_y+a.radius*3*Math.sin(b-1.5708)], \n"+
"\t\t\t[c_x+a.radius*3*Math.cos(b-3.1416),c_y+a.radius*3*Math.sin(b-3.1416)], \n"+
"\t\t\t[c_x+a.radius*3*Math.cos(b-4.7124),c_y+a.radius*3*Math.sin(b-4.7124)], \n"+
"\t\t\t[c_x+a.radius*3*Math.cos(b),c_y+a.radius*3*Math.sin(b)]]; \n"+*/
"return [["+UI_SETTINGS.boardsize[2]+",0], [0,"+UI_SETTINGS.boardsize[3]+"], ["+UI_SETTINGS.boardsize[0]+", 0], [0, "+UI_SETTINGS.boardsize[1]+"], ["+UI_SETTINGS.boardsize[2]+", 0]];"+
"\t}\n"+
"}";
// create variable anim[Row nr][j] and functions needed (animOn, animOff)
if (el[i].Anim[2][j] == 0) { // if run repeatedly
if (eval(elid+"_el["+el[i].Anim[0][j+1]+"]").getType() == 'segment')
evas[el[i].Row] = evas[el[i].Row] +
"var anim"+el[i].Row+j+" = false; \n"+
"var antype"+el[i].Row+j+"="+elid+"_el["+el[i].Anim[0][j]+"].getType(); \n"+
"function animateOn"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[i].Anim[0][j+1]+"]); \n"+
//"\t"+elid+"_el["+el[i].Anim[0][j]+"].setGliderPosition(0);\n"+
//"\tvar path_"+el[i].Row+"="+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"]); \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong("+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"]), "+el[i].Anim[1][j]+", {callback: animateOn"+el[i].Row+j+"});\n"+
//"\tfor (var i=0; i<path_"+el[i].Row+".length; i++) {"+elid+"_el["+el[i].Anim[0][j]+"].moveTo(path_"+el[i].Row+"[i], 1000);}\n"+
//"var piste;"+
//"\twhile(anim"+el[i].Row+j+") {piste = ["+elid+"_el["+el[i].Anim[0][j+1]+"].X(),"+elid+"_el["+el[i].Anim[0][j+1]+"].Y()]; "+elid+"_el["+el[i].Anim[0][j]+"].visit([2,2], 1000);}\n"+
"}; \n"+
"function animateOff"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].visit([0,0], 1); \n"+
"\tif (antype"+el[i].Row+j+" == 'point')"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\tif (antype"+el[i].Row+j+" == 'glider')"+
"\t\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[el[i].Anim[0][j]].Pos[0]+"]); \n"+
"}; ";
else
evas[el[i].Row] = evas[el[i].Row] +
"var anim"+el[i].Row+j+" = false; \n"+
"var antype"+el[i].Row+j+"="+elid+"_el["+el[i].Anim[0][j]+"].getType(); \n"+
"function animateOn"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[i].Anim[0][j+1]+"]); \n"+
//"\tvar path_"+el[i].Row+"="+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"], Math.acos(("+elid+"_el["+el[i].Anim[0][j]+"].X()-"+elid+"_el["+el[i].Anim[0][j+1]+"].center.X())/"+elid+"_el["+el[i].Anim[0][j+1]+"].radius), "+elid+"_el["+el[i].Anim[0][j]+"].Y()); \n"+
//"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong("+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"], Math.acos(("+elid+"_el["+el[i].Anim[0][j]+"].X()-"+elid+"_el["+el[i].Anim[0][j+1]+"].center.X())/"+elid+"_el["+el[i].Anim[0][j+1]+"].radius), "+elid+"_el["+el[i].Anim[0][j]+"].Y()), "+el[i].Anim[1][j]+", {callback: animateOn"+el[i].Row+j+"});\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong("+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"]), "+el[i].Anim[1][j]+", {callback: animateOn"+el[i].Row+j+"});\n"+
//"\t"+elid+"_el["+el[i].Anim[0][j]+"].startAnimation(1,100); \n"+
//"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveTo(path_"+el[i].Row+"[i], 1000); \n"+
//"\t for(var i=0; i<4; i++) {"+elid+"_el["+el[i].Anim[0][j]+"].slideObject(path_"+el[i].Row+"[i])} \n"+
//"\tfor (var i=0; i<path_"+el[i].Row+".length; i++) {"+elid+"_el["+el[i].Anim[0][j]+"].moveTo(path_"+el[i].Row+"[i], 1000);}\n"+
"}; \n"+
"function animateOff"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].visit([0,0], 1); \n"+
"\tif (antype"+el[i].Row+j+" == 'point')"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\tif (antype"+el[i].Row+j+" == 'glider')"+
"\t\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[el[i].Anim[0][j]].Pos[0]+"]); \n"+
"}; ";
// elid+"_el["+el[i].Anim[0][j+1]+"].on('drag', function(){if("+elid+"_animOn)var path_"+el[i].Row+"="+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"], Math.acos(("+elid+"_el["+el[i].Anim[0][j]+"].X()-"+elid+"_el["+el[i].Anim[0][j+1]+"].center.X())/"+elid+"_el["+el[i].Anim[0][j+1]+"].radius), "+elid+"_el["+el[i].Anim[0][j]+"].Y()); \n"+
// "\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong(path_"+el[i].Row+", "+el[i].Anim[1][j]+", {callback: animateOn"+el[i].Row+j+"});});";
}
else { // if run only once
//evas[el[i].Row] = evas[el[i].Row] + "var anim"+el[i].Row+j+" = false; var antype"+el[i].Row+j+"="+elid+"_el["+el[i].Anim[0][j]+"].getType(); function animateOn"+el[i].Row+j+"() {"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[i].Anim[0][j+1]+"]); "+elid+"_el["+el[i].Anim[0][j]+"].moveAlong("+elid+"_path"+el[i].Row+j+", "+el[i].Anim[1][j]+");}; function animateOff"+el[i].Row+j+"() {"+elid+"_el["+el[i].Anim[0][j]+"].visit([0,0], 1); if (antype"+el[i].Row+j+" == 'point')"+elid+"_el["+el[i].Anim[0][j]+"].free(); if (antype"+el[i].Row+j+" == 'glider')"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[el[i].Anim[0][j]].Pos[0]+"]);}; ";
if (eval(elid+"_el["+el[i].Anim[0][j+1]+"]").getType() == 'segment')
evas[el[i].Row] = evas[el[i].Row] +
"var anim"+el[i].Row+j+" = false; \n"+
"var antype"+el[i].Row+j+"="+elid+"_el["+el[i].Anim[0][j]+"].getType(); \n"+
"function animateOn"+el[i].Row+j+"() {\n"+
"\tanim"+el[i].Row+j+" = false; \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[i].Anim[0][j+1]+"]); \n"+
"\tvar path_"+el[i].Row+"="+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"], "+elid+"_el["+el[i].Anim[0][j]+"]); \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong(path_"+el[i].Row+", "+el[i].Anim[1][j]+");\n"+
"}; \n"+
"function animateOff"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].visit([0,0], 1); \n"+
"\tif (antype"+el[i].Row+j+" == 'point')"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\tif (antype"+el[i].Row+j+" == 'glider')"+
"\t\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[el[i].Anim[0][j]].Pos[0]+"]); \n"+
"}; ";
else
evas[el[i].Row] = evas[el[i].Row] +
"var anim"+el[i].Row+j+" = false; \n"+
"var antype"+el[i].Row+j+"="+elid+"_el["+el[i].Anim[0][j]+"].getType(); \n"+
"function animateOn"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[i].Anim[0][j+1]+"]); \n"+
//"\tvar path_"+el[i].Row+"="+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"], Math.acos(("+elid+"_el["+el[i].Anim[0][j]+"].X()-"+elid+"_el["+el[i].Anim[0][j+1]+"].center.X())/"+elid+"_el["+el[i].Anim[0][j+1]+"].radius), "+elid+"_el["+el[i].Anim[0][j]+"].Y()); "+
//"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong(path_"+el[i].Row+", "+el[i].Anim[1][j]+");\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong("+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"]), "+el[i].Anim[1][j]+", {callback: animateOn"+el[i].Row+j+"});\n"+
"}; \n"+
"function animateOff"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].visit([0,0], 1); \n"+
"\tif (antype"+el[i].Row+j+" == 'point')"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\tif (antype"+el[i].Row+j+" == 'glider')"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[el[i].Anim[0][j]].Pos[0]+"]); \n"+
"}; ";
}
}
if (animtype.indexOf("animtype1")>=0) evas[el[i].Row] = evas[el[i].Row] + 'function click'+el[i].Row+'() {'+tmpstring+'} '+obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[2]+'", function() { click'+el[i].Row+'();}], {fixed:true} );';
// if user selected 'animtype2' the this
else {
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[2]+' ", function() {if ('+elid+'_animOn){'+elid+'_el['+el[i].Anim[0][0]+'].stopAnimation(); '+elid+'_animOn=false;} else{'+elid+'_el['+el[i].Anim[0][0]+'].startAnimation(1,'+animticks+'); '+elid+'_animOn=true;}}], {fixed:true, showInfoBox:'+el[i].Att.Infobox+'});';
if (eval(elid+"_el["+el[i].Anim[0][0]+"]").getType()!="glider")
errors = errors + "Error on line ["+el[i].Row+"]: You can't use animation2 for other objects than 'Point on object'. <br>Some animation may not work properly.<br><br>";
}
el[i].Anim = tmpstring;
} //ANIMBUTTON
else if (el[i].JsxType == 'simultaneousbutton') {
for (var j = 0; j < el[i].Anim.length; j++) {
tmpstring = " "+tmpstring + el[el[i].Anim[j]].Anim;
}
evas[el[i].Row] = obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[2]+' ", function(){'+tmpstring+'} ],'+setAttributes(el[i],"",use_hide_el,elid)+');';
el[i].Anim = tmpstring;
}
// * * * * * * /BUTTONS
// COORDINATE SYSTEM * * * * /
else if(el[i].JsxType == 'originandunit') {
evas[el[i].Row] = elid+"_el["+el[i].Row+"] = ["+elid+"_el["+el[i].Pos[0]+"],function(){return "+elid+"_el["+el[i].Pos[0]+"].Dist("+elid+"_el["+el[i].Pos[1]+"]);}];";
evas[el[i].Row] += elid+"_unit = ["+elid+"_el["+el[i].Pos[0]+"],function(){return "+elid+"_el["+el[i].Pos[0]+"].Dist("+elid+"_el["+el[i].Pos[1]+"]);}];";
//evas[el[i].Row] += boardname+'_b.moveOrigin('+UI_SETTINGS.scale * getOrigin(sketch).slice(0,getOrigin(sketch).indexOf(','))+','+UI_SETTINGS.scale * getOrigin(sketch).slice(getOrigin(sketch).indexOf(',')+1,getOrigin(sketch).length)+');';
evas[el[i].Row] += boardname+"_b.moveOrigin("+el[el[i].Pos[0]].oPos+");";
// evas[el[i].Row] += "var " + elid+"_grid = " + boardname+"_b.create('grid', []);";
//evas[el[i].Row] += boardname+"_b.update();";
//evas[el[i].Row] += elid+"_el["+el[i].Pos[1]+"].on('drag', function(){"+boardname+"_b.setAttribute({unitx : 90});});" + boardname+"_b.fullUpdate();";
}
else if(el[i].JsxType == 'coordinates') {
/*Coordinates(obj1, obj2, numX, numY, string);
Constructs a measurement of the ordered pair of coordinates representing point obj1's location with respect to the coordinate system obj2.
https://www.math.uni-bielefeld.de/~lisken/cgi-bin/jsp_qref?5.7.11+5.9*+5.7
*/
calc[el[i].Row] = ["function(){return "+elid+"_el["+el[i].Pos[0]+"].X();}", "function(){return "+elid+"_el["+el[i].Pos[0]+"].Y();}"];
evas[el[i].Row] = obj_c+"('text', ["+el[i].Pos[2]+","+el[i].Pos[3]+",function(){return '"+el[i].Pos[4]+" ('+ Math.round("+elid+"_el["+el[i].Pos[0]+"].X()*"+UI_SETTINGS.measurementAccuracy+")/"+UI_SETTINGS.measurementAccuracy+" +','+ Math.round("+elid+"_el["+el[i].Pos[0]+"].Y()*"+UI_SETTINGS.measurementAccuracy+")/"+UI_SETTINGS.measurementAccuracy+" +')';}], {name:'"+el[i].Att.Name+"',color:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+", anchorX:'"+el[i].Att.AnchorX+"', fixed:"+el[i].Att.Fixed+", showInfoBox:"+el[i].Att.Infobox+", anchorX:'left'} );";
}
// * * * * * /COORDINATE SYSTEM /
// LOCUS * * * * * * /
else if (el[i].JsxType == 'locus') {
if (el[i].Pos[3]>100) el[i].Pos[3] = 100;
// First let's check if Locus is replaced
// el.locusToReplace = row of the locus
// el.replaceLocus = replace function as string "function(x){something...}"
if(el[i].JSPComment.indexOf('calcLocus')>=0) {
var newLocus = calc[el[i].replaceLocus[0]];
while (newLocus.indexOf(elid+el[i].replaceLocus[1]+'()')>0) {
newLocus = newLocus.replace(elid+el[i].replaceLocus[1]+'()', el[i].replaceLocus[2]);
}
//console.log(calc[el[i].replaceLocus[0]]);
newLocus = obj_c + "('functiongraph', [function("+el[i].replaceLocus[2]+") {return " /*+ elid + "_unit() * "*/ + newLocus/*+"+"+elid+"_unit[0].Y()*/+";}";
if (typeof el[i].replaceLocus[3] === 'object' && typeof el[i].replaceLocus[3][0] === 'number' && typeof el[i].replaceLocus[3][1] === 'number')
newLocus += ", "+el[i].replaceLocus[3] + "], "+setAttributes(el[i],'',use_hide_el,elid)+");";
else if (typeof el[i].replaceLocus[3] === 'number')
newLocus += ", function(){return "+elid+"_el["+el[i].replaceLocus[3]+"].point1.X();}, function(){return "+elid+"_el["+el[i].replaceLocus[3]+"].point2.X();} ], "+setAttributes(el[i],'',use_hide_el,elid)+");";
else
newLocus += "], "+setAttributes(el[i],'',use_hide_el,elid)+");";
console.log('Locus '+el[i].Original_line+' replaced to: '+newLocus);
evas[el[i].Row] = newLocus;
}
else if(el[i].JSPComment.indexOf('locus')>=0) {
try {
var lrtmp1 = lrtmp2 = '';
var reps = []; reps = (replaceJspVariablesFromString(el[i].replaceLocus));
/*while (el[i].replaceLocus.indexOf('@')>0) {
lrtmp1 = el[i].replaceLocus.slice(el[i].replaceLocus.indexOf('@'), el[i].replaceLocus.indexOf('@', el[i].replaceLocus.indexOf('@')+1)+1);
if (calc[eval(lrtmp1.slice(1,lrtmp1.length-1))])
lrtmp2 = calc[eval(lrtmp1.slice(1,lrtmp1.length-1))];
else lrtmp2 = elid + "_el[" + lrtmp1.slice(1,lrtmp1.length-1) +"]";
el[i].replaceLocus = el[i].replaceLocus.replace(lrtmp1, lrtmp2);
} */
for (var j=0; j<reps.length; j++) {
while (el[i].replaceLocus.indexOf('{'+reps[j]+'}')>=0){
lrtmp1 = '{'+reps[j]+'}';
if (calc[eval(reps[j])])
lrtmp2 = calc[eval(reps[j])];
else lrtmp2 = elid + "_el[" + reps[j] + "]";
el[i].replaceLocus = el[i].replaceLocus.replace(lrtmp1, lrtmp2);
}
}
if (el[i].replaceLocus.indexOf('functiongraph')<0) {
el[i].replaceLocus = "'functiongraph', [" + el[i].replaceLocus + "]";
}
el[i].replaceLocus += ', ' + setAttributes(el[i],"",use_hide_el,elid);
evas[el[i].Row] = obj_c+"( "+el[i].replaceLocus+ ");";
} catch(err) {alert(err.message + err);}
} else {
// JSP description: Locus(obj1, obj2, obj3, num);
//Constructs the locus of obj1 as point obj2 moves along the path determined by obj3.
//JavaSketchpad devotes num samples to the representation of the locus--higher values of
//num correspond to more accurate approximations of the locus, but take more time and computer memory to process.
var usertick = 1/30; //set user ticks here
if (el[i].Pos[3] <= 20) usertick = 1/eval(el[i].Pos[3]);
else usertick = 1/((eval(el[i].Pos[3]) / 21) + 20);
// If locus is created by path of a glider, locus will be created normally as a tracecurve construction in JSXGraph
if (eval(elid+"_el["+el[i].Pos[1]+"]").getType() == 'glider')
evas[el[i].Row] = obj_c+"('tracecurve', ["+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[0]+"]], {name:'"+el[i].Att.Name+"', strokeColor:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+", numberPoints:"+el[i].Pos[3]+", highlight:false} );";
else if (eval(elid+"_el["+el[i].Pos[1]+"]").getType() == 'point') {
locus_counter = locus_counter +1;
var lrobj = [];
var end_gh_r = eval(el[i].Pos[0]);
var k = eval(el[i].Pos[1]);
var need_to_duplicate = [];
var tmp_listnr = 0;
var tmp_duplicate = "";
var tmp_duplicates = [];
var tmp_tmp = "";
var numPoints = eval(el[i].Pos[3]);
if (numPoints<50) numPoints = 50;
else if (numPoints>100) numPoints = 100;
if (el[el[i].Pos[2]].JsxType == 'circle') {
if (!UI_SETTINGS.locusSetting) {
lrobj.push(eval(el[i].Pos[1])); //starting row to check + duplicate
need_to_duplicate.push(eval(el[i].Pos[1]));
while(k < end_gh_r) {
k = k+1;
for (var j=0; j<need_to_duplicate.length; j++) {
if (evas[el[k].Row].indexOf(elid+"_el["+need_to_duplicate[j]+"]")>=0 && need_to_duplicate.indexOf(k)<0) {
need_to_duplicate.push(k);
}
}
} // here is the list for lines needed to duplicate : alert(need_to_duplicate);
if (el[need_to_duplicate[0]].JsxType == 'point')
tmp_duplicates.push( "var " + elid + "_dup"+locus_counter+" = [];\n"+
elid + "_dup"+locus_counter+"["+need_to_duplicate[0]+"] = " + boardname + "_b.create('glider', ["+elid+"_el["+el[i].Pos[2]+"]], );\n"+ elid + "_dup"+locus_counter+"["+need_to_duplicate[0]+"].hideElement();");
else {alert("Something went wrong in Locus operation!"); return null;}
for (var j = 1; j<need_to_duplicate.length; j++) {
tmp_duplicate = evas[need_to_duplicate[j]];
for (var m=0; m<need_to_duplicate.length; m++) {
while(tmp_duplicate.indexOf(elid+"_el["+need_to_duplicate[m]+"]")>=0)
tmp_duplicate = tmp_duplicate.replace(elid+"_el["+need_to_duplicate[m]+"]", elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"]");
while(tmp_duplicate.indexOf(elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"].hideElement();")>=0)
tmp_duplicate = tmp_duplicate.replace(elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"].hideElement();", "\n");
if (tmp_duplicate.indexOf('],{')>0) {
tmp_tmp = tmp_duplicate.slice(tmp_duplicate.indexOf('],{')+2, tmp_duplicate.lastIndexOf('}')+1);
tmp_duplicate = tmp_duplicate.replace(tmp_tmp, " {} ");
}
}
tmp_duplicates.push(tmp_duplicate + elid + "_dup"+locus_counter+"["+need_to_duplicate[j]+"].hideElement()");
}
evas[el[i].Row] = "";
for (var j=0; j<tmp_duplicates.length; j++) {
evas[el[i].Row] = evas[el[i].Row] + tmp_duplicates[j] + "\n";
}
evas[el[i].Row] = evas[el[i].Row] + obj_c + "('tracecurve', ["+elid+"_dup"+locus_counter+"["+el[i].Pos[1]+"],"+elid+"_dup"+locus_counter+"["+el[i].Pos[0]+"]], {name:'"+el[i].Att.Name+"', strokeColor:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+", numberPoints:"+numPoints+", highlight:false} );";
}
// If locus is created by path that is circle or segment, and a point other than glider mover along that path, locus will be created by this algorithm
// Algorithm creates locus like explained next:
// - make the point to be a gliderpoint on wanted path
// - move point along that path distance of a tick (user can define, default is 30 ticks)
// - while point is moving along path, collect the coordinatedata of the point we want to draw the locus
// - clear all old segments if there are any, and create segments between all the coordinatepoint from the data
// - make point not to be gliderpoint anymore, and return it to its startingpoint
// - make events for the nessessary objects to launch this function
else {
// vanhja "toimiva"
//evas[el[i].Row] = "var "+elid+el[i].Row+"visible="+el[i].Att.Visible+";"+ elid+"_el["+el[i].Row+"]=[]; function "+elid+"Locus"+el[i].Row+"(obj1,obj2,obj3){var objstart=[obj3.X(),obj3.Y()];var locuspath=[];var tick=0;obj3.makeGlider(obj1);while(tick<=1.02){obj3.setGliderPosition(tick); locuspath.push([obj2.X(),obj2.Y()]); tick=tick+"+usertick+";} for(var i=0; i<locuspath.length; i++){"+boardname+"_b.removeObject("+elid+"_el["+el[i].Row+"][i]); if(i==0)"+elid+"_el["+el[i].Row+"][i]="+boardname+"_b.create('segment',[locuspath[i],locuspath[locuspath.length-1]],{strokeWidth:1,fixed:true,visible:"+elid+el[i].Row+"visible}); else "+elid+"_el["+el[i].Row+"][i]="+boardname+"_b.create('segment',[locuspath[i-1],locuspath[i]],{strokeWidth:1,fixed:true, visible:"+elid+el[i].Row+"visible}); } if(!"+elid+"_animOn){obj3.free(); obj3.setPosition(JXG.COORDS_BY_USER, objstart); "+boardname+"_b.update();} return locuspath; }";
evas[el[i].Row] = "var "+elid+el[i].Row+"visible="+el[i].Att.Visible+";"+ elid+"_el["+el[i].Row+"]=[]; \n"+
"function "+elid+"Locus"+el[i].Row+"(obj1,obj2,obj3){\n\t"+
"var objstart=[obj3.X(),obj3.Y()],\n\t"+
"\tlocuspathx=[], locuspathy=[],\n\t"+
"\ttick=0;\n\t"+
"obj3.makeGlider(obj1);\n\t"+
"while(tick<=1.00){\n\t\t"+
"obj3.setGliderPosition(tick); \n\t\t"+
"locuspathx.push(obj2.X()); \n\t\t"+
"locuspathy.push(obj2.Y()); \n\t\t"+
"tick=tick+"+usertick+";} \n\t"+
boardname+"_b.removeObject("+elid+"_el["+el[i].Row+"][0]); \n\t"+
elid+"_el["+el[i].Row+"][0]="+boardname+"_b.create('curve',[locuspathx, locuspathy],{doAdvancedPlot:false,numberPointsLow:10,numberPointsHigh:10, strokeWidth:1,fixed:true,visible:"+elid+el[i].Row+"visible}); \n\t"+
"if(!"+elid+"_animOn){\n\t\t"+
"obj3.free(); \n\t\t"+
"obj3.setPosition(JXG.COORDS_BY_USER, objstart); \n\t\t"+
boardname+"_b.update();\n\t} \n"+
"}";
//alert(evas[el[i].Row]);
evas[el[i].Row] = evas[el[i].Row] + elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n";
evas[el[i].Row] = evas[el[i].Row] +
elid+"_el["+el[i].Pos[2]+"].on('up', function() {\n"+
"\t"+ elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n});\n"+
elid+"_el["+el[i].Pos[2]+"].center.on('up', function() {\n"+
"\t"+ elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n});";
if (el[el[i].Pos[2]].JsxType == 'circle') {
evas[el[i].Row] = evas[el[i].Row] +
elid+"_el["+el[el[el[i].Pos[2]].Pos[1]].Row+"].on('up', function() {\n"+
"\t"+ elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n});";
}
}
}
else if (el[el[i].Pos[2]].JsxType == 'segment') {
if (!UI_SETTINGS.locusSetting) {
lrobj.push(eval(el[i].Pos[1])); //starting row to check + duplicate
//alert(lrobj[0] +","+ end_gh_r);
need_to_duplicate.push(eval(el[i].Pos[1]));
while(k < end_gh_r) {
k = k+1;
for (var j=0; j<need_to_duplicate.length; j++) {
if (evas[el[k].Row].indexOf(elid+"_el["+need_to_duplicate[j]+"]")>=0 && need_to_duplicate.indexOf(k)<0) {
need_to_duplicate.push(k);
}
}
} // here is the list for lines needed to duplicate : alert(need_to_duplicate);
if (el[need_to_duplicate[0]].JsxType == 'point')
tmp_duplicates.push( "var " + elid + "_dup"+locus_counter+" = [];\n"+
elid + "_dup"+locus_counter+"["+need_to_duplicate[0]+"] = " + boardname + "_b.create('glider', ["+elid+"_el["+el[i].Pos[2]+"]], );\n"+ elid + "_dup"+locus_counter+"["+need_to_duplicate[0]+"].hideElement();");
else {alert("Something went wrong in Locus operation!"); return null;}
for (var j = 1; j<need_to_duplicate.length; j++) {
tmp_duplicate = evas[need_to_duplicate[j]];
for (var m=0; m<need_to_duplicate.length; m++) {
while(tmp_duplicate.indexOf(elid+"_el["+need_to_duplicate[m]+"]")>=0)
tmp_duplicate = tmp_duplicate.replace(elid+"_el["+need_to_duplicate[m]+"]", elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"]");
while(tmp_duplicate.indexOf(elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"].hideElement();")>=0)
tmp_duplicate = tmp_duplicate.replace(elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"].hideElement();", "\n");
if (tmp_duplicate.indexOf('],{')>0) {
tmp_tmp = tmp_duplicate.slice(tmp_duplicate.indexOf('],{')+2, tmp_duplicate.lastIndexOf('}')+1);
tmp_duplicate = tmp_duplicate.replace(tmp_tmp, " {} ");
}
}
tmp_duplicates.push(tmp_duplicate + elid + "_dup"+locus_counter+"["+need_to_duplicate[j]+"].hideElement()");
}
evas[el[i].Row] = "";
for (var j=0; j<tmp_duplicates.length; j++) {
evas[el[i].Row] = evas[el[i].Row] + tmp_duplicates[j] + "\n";
}
evas[el[i].Row] = evas[el[i].Row] + obj_c + "('tracecurve', ["+elid+"_dup"+locus_counter+"["+el[i].Pos[1]+"],"+elid+"_dup"+locus_counter+"["+el[i].Pos[0]+"]], {name:'"+el[i].Att.Name+"', strokeColor:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+", numberPoints:"+numPoints+", highlight:false} );";
}
else {
//vanha "toimiva"
//evas[el[i].Row] = "var "+elid+el[i].Row+"visible="+el[i].Att.Visible+";"+ elid+"_el["+el[i].Row+"]=[]; function "+elid+"Locus"+el[i].Row+"(obj1,obj2,obj3){var objstart=[obj3.X(),obj3.Y()];var locuspath=[];var tick=0;obj3.makeGlider(obj1);while(tick<=1.02){obj3.setGliderPosition(tick); locuspath.push([obj2.X(),obj2.Y()]); tick=tick+"+usertick+";} for(var i=0; i<locuspath.length; i++){"+boardname+"_b.removeObject("+elid+"_el["+el[i].Row+"][i]); if(i==0)"+elid+"_el["+el[i].Row+"][i]="+boardname+"_b.create('segment',[locuspath[i],locuspath[i]],{strokeWidth:1,fixed:true,visible:"+elid+el[i].Row+"visible}); else "+elid+"_el["+el[i].Row+"][i]="+boardname+"_b.create('segment',[locuspath[i-1],locuspath[i]],{strokeWidth:1,fixed:true, visible:"+elid+el[i].Row+"visible}); } if(!"+elid+"_animOn){obj3.free(); obj3.setPosition(JXG.COORDS_BY_USER, objstart); "+boardname+"_b.update();} return locuspath; }";
evas[el[i].Row] = "var "+elid+el[i].Row+"visible="+el[i].Att.Visible+";"+ elid+"_el["+el[i].Row+"]=[]; \n"+
"function "+elid+"Locus"+el[i].Row+"(obj1,obj2,obj3){\n"+
"\tvar objstart=[obj3.X(),obj3.Y()],\n\t"+
"\tlocuspathx=[], locuspathy=[],\n"+
"\ttick=0;\n"+
"\tobj3.makeGlider(obj1);\n"+
"\tobj3.setGliderPosition(0);\n"+
"\tlocuspathx.push(obj2.X());locuspathy.push(obj2.Y());\n"+
"\tobj3.setGliderPosition(1);\n"+
"\tlocuspathx.push(obj2.X());locuspathy.push(obj2.Y());\n"+
"\t"+boardname+"_b.removeObject("+elid+"_el["+el[i].Row+"][0]); \n"+
"\t"+elid+"_el["+el[i].Row+"][0]="+boardname+"_b.create('curve',[locuspathx,locuspathy],{strokeWidth:1,fixed:true,visible:"+elid+el[i].Row+"visible}); \n"+
"\tif(!"+elid+"_animOn){\n"+
"\t\tobj3.free(); \n"+
"\t\tobj3.setPosition(JXG.COORDS_BY_USER, objstart); \n"+
"\t\t"+boardname+"_b.update();\n"+
"} \n"+
"}";
evas[el[i].Row] = evas[el[i].Row] + elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);";
evas[el[i].Row] = evas[el[i].Row] +
elid+"_el["+el[i].Pos[2]+"].on('up', function() {\n"+
"\t"+elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n"+
"});\n"+
elid+"_el["+el[i].Pos[2]+"].point1.on('up', function() {\n"+
"\t"+elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n"+
"});\n"+
elid+"_el["+el[i].Pos[2]+"].point2.on('up', function(){\n"+
"\t"+elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n"+
"});";
}
}
else errors = errors + "Traced point [line:"+el[i].Pos[1]+"] is not a type 'Point on object' [type is "+el[el[i].Pos[1]].Type+"].<br> 'Locus' can be constructed for a 'Point'-element only if path [line:"+el[i].Pos[2]+"] in 'Circle' or 'Segment'.<br>Locus [line:"+el[i].Row+"] was not constructed!<br><br>";
}
else
//evas[el[i].Row] = obj_c+"('locus', ["+elid+"_el["+el[i].Pos[0]+"]], {name:'"+el[i].Att.Name+"', strokeColor:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+"} );";
errors = errors + "Error on line ["+el[i].Row+"]: Traced point on line ["+el[i].Pos[1]+"] is not a type 'Point on object'.<br> This locus may not work properly. <br><br>";
}
}
// * * * * * /LOCUS /
// ********* / MACROS /
else if (jsp_macros.indexOf(el[i].Type) >= 0) {
tmp = "";
for (var k in el[i].Pos) {
tmp = tmp + elid + "_el[" + el[i].Pos[k] + "],";
}
tmp = tmp.slice(0,tmp.lastIndexOf(','));
//tmp = tmp + '"' + setAttributes(el[i], '') + '"';
evas[el[i].Row] = elid+"_el["+el[i].Row+"] = " + el[i].Type + "(" + tmp + ");\n" + elid+"_el["+ el[i].Row +"].setAttribute("+setAttributes(el[i], '')+");";
//alert(evas[el[i].Row]);
}
else {
errors = errors + "Operator '"+el[i].Type+"' is unknown or is not supported yet.<br> Converting stopped on line ["+el[i].Row+"]. <br><br>";
//errors = errors + el[i].Original_line + "\n\n";
//errors = errors + "\n" + document.getElementById(code_input).value.slice(document.getElementById(code_input).value.lastIndexOf(';', el[i].att), document.getElementById(code_input).value.indexOf(';'), el[i].att ) + " might also be bad $JSP name for element.";
break;
}
if (el[i].Macro.length > 0) {
tmp = "";
//alert('toimii tähän saakka');
for (var j = 1; j<el[i].Macro.length; j++) {
//alert(el[i].Macro[j].Row);
if (j<el[i].Macro.length-1) {
el[i].Macro[j] = "\tvar " + el[i].Macro[0].slice(0,3) + "_" + el[i].Macro[j].Row + " = " + boardname + "_b.create" + getMacroFunction(el[i].Macro[j]) + "\n";
tmp = tmp + el[i].Macro[j];
}
else el[i].Macro[j] = "\treturn " + document.getElementById('jsxgboardname').value + "_b.create" + getMacroFunction(el[i].Macro[j]) + "\n";
}
el[i].Macro[0] = "function " + el[i].Macro[0] + " { \n";
el[i].Macro[el[i].Macro.length-1] = el[i].Macro[el[i].Macro.length-1] + "}\n";
tmp = el[i].Macro[0] + tmp + el[i].Macro[el[i].Macro.length-1];
evas[el[i].Row] = tmp + evas[el[i].Row];
}
//Hide buttons and measurements if they are 'hidden' in options field
if (!el[i].Att.Visible && (el[i].CType == 'measurements' || el[i].CType == 'buttons') ) {evas[el[i].Row] = evas[el[i].Row] + elid+"_el["+el[i].Row+"].hideElement();";}
//update 12.3.2018: visibility setting
if (use_hide_el == true && el[i].JSPComment.indexOf('attVisible')<0 /*&& el[i].Opts.indexOf('traced')<0*/ && !(el[i].CType == 'measurements' || el[i].CType == 'buttons' || jsp_macros.indexOf(el[i].Type)<0) || el[i].JsxType == 'macros') {
if (evas[el[i].Row].indexOf('visible:false,')>=0) {
evas[el[i].Row] = evas[el[i].Row].replace(evas[el[i].Row].slice(evas[el[i].Row].indexOf('visible'), evas[el[i].Row].indexOf(',', evas[el[i].Row].indexOf('visible'))+1), '');
evas[el[i].Row] = evas[el[i].Row] + elid+"_el["+el[i].Row+"].hideElement();";
}
else if (evas[el[i].Row].indexOf('visible:false}')>=0) {
evas[el[i].Row] = evas[el[i].Row].replace(evas[el[i].Row].slice(evas[el[i].Row].indexOf('visible'), evas[el[i].Row].indexOf('}', evas[el[i].Row].indexOf('visible'))), '');
evas[el[i].Row] = evas[el[i].Row] + elid+"_el["+el[i].Row+"].hideElement();"; }
} //end update
if (use_hide_el == true && el[i].JSPComment.indexOf('attVisible')<0 && (el[i].Type == 'VectorTranslation' || el[i].Type == 'Point on object') && evas[el[i].Row].indexOf('visible:false,')>0) {
evas[el[i].Row] = evas[el[i].Row].replace(evas[el[i].Row].slice(evas[el[i].Row].indexOf('visible'), evas[el[i].Row].indexOf(',', evas[el[i].Row].indexOf('visible'))+1), '');
evas[el[i].Row] = evas[el[i].Row] + elid+"_el["+el[i].Row+"].hideElement();";
}
} //end of else
//18.9. ,-attribute, labelsize
if (contains(el[i].JSPComment,'smallLabel'))
evas[el[i].Row]+= elid+"_el["+el[i].Row+"].label.setAttribute({fontSize:11});";
if (contains(el[i].JSPComment,'bigLabel'))
evas[el[i].Row]+= elid+"_el["+el[i].Row+"].label.setAttribute({fontSize:13});";
//if (el[i].JSPComment.indexOf('latex')>=0) alert(evas[el[i].Row]);
//CONVERT ROW
eval(evas[el[i].Row]);
//alert(evas[el[i].Row]);
tmpstring = "";
if (document.getElementById('originalcode').value == 'Comment' && !isFullPageConvert)
codestring = codestring + "\n /* " +getOrigString(el[i], 0, 0, false, 'SketchrowOnly')+ " */\n";
if (el[i].comment.length>0 || el[i].JSPComment.length>0 || el[i].LastComment.length>0 ) {
try {
//add normal comment if there is one
if (el[i].comment.length>1)
codestring = codestring + el[i].comment + "\n" ;
//add new jsx code string
codestring = codestring + evas[el[i].Row] + "\n";
//add dot command if there is one
if (el[i].JSPComment.length>1)
codestring = codestring + "/* " + el[i].JSPComment.slice(0, this.length-1) + " */\n";
//finally add last comment if there is one at the end of the code
if (el[i].LastComment.length > 1)
codestring = codestring + el[i].LastComment + "\n";
} catch(e) {alert(el[i].comment);}
}
else
codestring = codestring + evas[el[i].Row] + "\n" ;
if (!isFullPageConvert){
codestring = codestring+"\n";
}
} //end of for
if (board_update_events.length > 0) {
board_update_events = boardname+"_b.on('update', function(){" + board_update_events + "});\n\n";
codestring = codestring + board_update_events;
eval(board_update_events);
}
if (sketch == 'null') errors = errors + document.getElementById('errormessages_prog').innerHTML;
//Check for errors
if (errors.length>0 && document.getElementById(code_input) && document.getElementById(code_input).value.length>0) document.getElementById('ERRORS').style.display="block";
} //end of try
catch(err){
document.getElementById('ERRORS').style.display="inline-block";
errors = errors + "<br>ERROR OCCURRED DURING COMPILATION!<br>Error name: "+err.name+"<br>Error message: "+err.message+"<br>Error stack: "+err.stack+"<br><br>Operation on line "+el[evas.length-1].Type+"("+el[evas.length-1].Pos +") caused this problem.";
//document.getElementById('errormessages_dev').innerHTML = "<form action='posterror.php' method='POST' name='Error occurred in JSPtoJSXG'><br>"+"<textarea rows='3' cols='30' name='errormes' style='display:none;'>"+errors+"<"+"/"+"textarea><br>"+"<textarea rows='3' cols='30' name='jspcode' style='display:none;'>"+document.getElementById(code_input).value+"<"+"/"+"textarea><br>"+"<textarea rows='3' cols='40' name='comms'>"+"your own comments here..."+"<"+"/"+"textarea><br>"+"<input type='submit' value='Send errormessage' /"+"></"+"form>";
document.getElementById('err_mes').value = errors;
document.getElementById('err_comms').value = "write comments (optional)";
//document.getElementById('err_jspcode').value = document.getElementById(code_input);
document.getElementById('err_comms').style.display = "block";
document.getElementById('err_info').style.display = "block";
document.getElementById('err_submit_btn').style.display = "block";
}
// stop the clock
endingtime = new Date().getTime();
//calculate time used in convertion
executiontime = (endingtime - startingtime) / 1000;
codestring = codestring + "})();//]]>\n<"+"/"+"script"+">"; // end of the converted codetext
var add_mathjax_button = "";
/*if (document.getElementById('latex').checked == true || document.getElementById('latex_fixedtext').checked == true)
//MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
add_mathjax_button = '<input onclick="runMathJax()" value="Run MathJax Hub" type="button" class="browseButton">';
*/
/*if (isFullPageConvert) {
document.getElementById('jsxgimage').innerHTML = "";
if (errors.length > 30 || sketch == 'null') document.getElementById('errormessages').innerHTML = "<font color='red'><b>Convertion done in "+executiontime+" seconds, but some errors occurred.<br><br></b></font>"+errors;
else document.getElementById('errormessages').innerHTML = "<font color='green'><b>Convertion done in "+executiontime+" seconds, no errors occurred.</b></font>";
return codestring;
}
else {*/
//codestring = "<div><div style='display:inline-block; letter-spacing:1.5px;'>"+add_mathjax_button+"<div style='display:inline-block;margin-right:20px;'><font size='4'><b>JSXGraph code:</b></font></div></div> <div style='display:inline-block; '> <input onclick='downloadJSX()' value='Save JSX/HTML' type='button' class='browseButton'></div> <div style='display:inline-block; '> <input onclick='editJSXcode(1)' value='Open this in JSX code-editor' type='button' class='browseButton' /></div> <div style='display:inline-block; '> <input onclick='copyToClipboard()' value='Copy JSX code to clipboard' type='button' class='browseButton'></div></div><div style='display:block; margin-top:2px;'><textarea id ='jsxcode' cols='' rows='' value="+codestring+" </textarea></div>";
codestring = add_mathjax_button+"<textarea id ='jsxcode' cols='' rows='' value="+codestring+" </textarea>";
right_side_titles_and_buttons = document.getElementsByClassName('right_side_hidden_element');
document.getElementById("jsxgcode").innerHTML = codestring;
if (errors.length > 30 || sketch == 'null') document.getElementById('errormessages').innerHTML = "<font color='red'><b>Convertion done in "+executiontime+" seconds, but some errors occurred.<br><br></b></font>"+errors;
else document.getElementById('errormessages').innerHTML = "<font color='green'><b>Convertion done in "+executiontime+" seconds, no errors.</b></font>";
try {
if (!isFullPageConvert) {
for(var i=0; i<right_side_titles_and_buttons.length; i++)
right_side_titles_and_buttons[i].style.display = "block";
document.getElementById('jsxcode').style.width = "100%";
document.getElementById('jsxcode').style.height = window.screen.availHeight/2.5 +"px";
document.getElementById('JSketchPadCode').style.width = "100%";
document.getElementById('JSketchPadCode').style.height = window.screen.availHeight/2.5 +"px";
}
} catch(e) {alert(e.message)}
codestring = codestring.slice(codestring.indexOf('cript src =')-2, codestring.lastIndexOf('</script')+9);
//run mathjax hub automatically
if (document.getElementById('latex').checked || document.getElementById('latex_fixedtext').checked || codestring.indexOf('\\\\')>=0) {
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
}
console.log('Converting took ' + executiontime);
if (errors != '<u>Errors:</u><br><br>') console.log('Convertion done. Errors:\n\t'+errors.slice(errors.indexOf('<br>')+8)); else console.log('Convertion ready, no errors.');
return codestring;
}
(function($){
$.fn.linenumbers = function(in_opts, prt){
// Settings and Defaults
var opt = $.extend({
col_width: '25px',
start: 1,
digits: 4.
},in_opts);
var is_long = false;
return this.each(function(){
// Get some numbers sorted out for the CSS changes
var new_textarea_width = '0px';
$(this).css({'width':'inherit'});
new_textarea_width = (parseInt($(this).css('width'))-parseInt(opt.col_width))+'px';
// Create the div and the new textarea and style it
$(this).before('<div id="linenumbersdiv" style="width:'+$(this).css('width')+';"><textarea style="width:'+new_textarea_width+';height:100%;float:left;margin-right:'+'-'+new_textarea_width+';margin-left:0px;margin-top:0px;margin-bottom:0px;font-family:monospace;white-space:pre;overflow:hidden;font-size:13px;" disabled="disabled"></textarea>');
$(this).after('<div style="clear:both;"></div></div>');
// Edit the existing textarea's styles
$(this).css({'font-family':'monospace','width':new_textarea_width,'float':'right'/*, 'line-height':$(this).css('line-height'), 'font-size':$(this).css('font-size')*/});
// Define a simple variable for the line-numbers box
var lnbox = $(this).parent().find('textarea[disabled="disabled"]');
// Bind some actions to all sorts of events that may change it's contents
$(this).bind('blur focus change keyup keydown',function(){
// Break apart and regex the lines, everything to spaces sans linebreaks
var lines = "\n"+$(this).val();
lines = lines.match(/[^\n]*\n[^\n]*/gi);
//add one (empty) line
lines.push('');
// declare output var
var line_number_output='';
// declare spacers and max_spacers vars, and set defaults
var max_spacers = ''; var spacers = '';
for(i=0;i<opt.digits;i++){
max_spacers += ' ';
}
// Loop through and process each line
$.each(lines,function(k,v){
// Add a line if not blank
if(k!=0){
line_number_output += "\n";
}
// Determine the appropriate number of leading spaces
lencheck = k+opt.start+'!';
spacers = max_spacers.substr(lencheck.length-1);
// Add the line, trimmed and with out line number, to the output variable
line_number_output += spacers+(k+opt.start)+'.'+v.replace(/\n/gi,'').replace(/./gi,' ').substr(opt.digits+1);
});
//for (var i=0; i<lines.length; i++) {
// if (lines[i].length>10) is_long = true;
//}
//if (is_long)
//line_number_output += '\n' + (lines.length+1) + '.';
// Give the text area out modified content.
$(lnbox).val(line_number_output);
// Change scroll position as they type, makes sure they stay in sync
$(lnbox).scrollTop($(this).scrollTop());
})
// Lock scrolling together, for mouse-wheel scrolling
$(this).scroll(function(){
$(lnbox).scrollTop($(this).scrollTop());
});
// Fire it off once to get things started
$(this).trigger('change');
});
};
})(jQuery);
class JSPtoJSXUISettings {
constructor(code, width, height, scale, zoom, boardName, elementId, scriptSource, addMathjax, mathjaxSource, addStylesheet, stylesheetSource, printJsp, JSXrenderer, pointSize, measurementAccuracy,
animation, addGridLayers, addClearTrace, clearTraceStyle, latexPoints, latexTexts, addBorder, addUTF8, forceWhiteBack, useHightlight, showGrid, drawAxis,
useAttributeVisible, locusSetting, showObjectCoordinates, buttonStyling, buttonPadding, buttonMarginTop, buttonBackground, buttonVerticalAdj, labelAlign, vectorTranslationVerticalCorrection) {
console.log('UI SETTINGS:');
this.code = this.getSketchCode(code);
console.log('CODE SET OK!');
this.scale = eval(this.getUserVal(scale));
console.log('scale set ok: '+this.scale);
this.width = this.readWidthHeight(this.code, width, height, this.scale).Width;
this.height = this.readWidthHeight(this.code, width, height, this.scale).Height;
console.log('width and height set ok:\n\t'+this.width +'\n\t'+this.height);
this.zoom = this.getUserVal(zoom);
console.log('zoom set ok: '+this.zoom);
this.boardName = this.getBoardName(boardName, elementId).boardname;
this.elementId = this.getBoardName(boardName, elementId).elid;
console.log('boardname and elid set ok:\n\t' +this.boardName + '\n\t' + this.elementId);
this.scriptSource = this.getUserVal(scriptSource);
this.addMathjax = this.getUserVal(addMathjax);
this.mathjaxSource = this.getUserVal(mathjaxSource);
this.addStylesheet = this.getUserVal(addStylesheet);
this.stylesheetSource = this.getUserVal(stylesheetSource);
console.log('sources set ok:\n\tJSXGraph source: \t' +this.scriptSource + '\n\tUse mathjax source: \t' + this.addMathjax + ' ' + this.mathjaxSource + '\n\tUse stylesheet source: \t' + addStylesheet + ' ' + this.stylesheetSource);
this.printJsp = this.getUserVal(printJsp);
this.JSXrenderer = this.getUserVal(JSXrenderer);
this.pointSize = this.getUserVal(pointSize);
this.measurementAccuracy = this.getUserVal(measurementAccuracy);
this.animation = this.getUserVal(animation);
this.addGridLayers = eval(this.getUserVal(addGridLayers).slice(this.getUserVal(addGridLayers).length-1));
this.addClearTrace = this.getUserVal(addClearTrace);
this.clearTraceStyle = this.getUserVal(clearTraceStyle);
console.log('selection menus set ok:\n\tprintJSP:\t' + this.printJsp + '\n\tJSXrenderer:\t'+this.JSXrenderer+'\n\tpointSize:\t'+this.pointSize+'\n\tmeasAccu:\t'+this.measurementAccuracy+'\n\tanimation:\t'+this.animation+'\n\tgridLayers:\t'+this.addGridLayers+'\n\tadd cleartrace:\t'+this.addClearTrace+'\n\tcleartstyle:\t'+this.clearTraceStyle);
this.latexPoints = this.getUserVal(latexPoints);
this.latexTexts = this.getUserVal(latexTexts);
this.addBorder = this.getBorderWidth(this.getUserVal(addBorder));
this.addUTF8 = this.getUserVal(addUTF8);
this.forceWhiteBack = this.getUserVal(forceWhiteBack);
this.useHightlight = this.getUserVal(useHightlight);
this.showGrid = this.getUserVal(showGrid);
this.drawAxis = this.getUserVal(drawAxis);
this.useAttributeVisible = this.getUserVal(useAttributeVisible);
this.locusSetting = this.getUserVal(locusSetting);
this.showObjectCoordinates = this.getUserVal(showObjectCoordinates);
console.log('radio selections set ok');
this.buttonStyling = this.getUserVal(buttonStyling);
this.buttonPadding = this.getUserVal(buttonPadding);
this.buttonMarginTop = this.getUserVal(buttonMarginTop);
this.buttonBackground = this.getUserVal(buttonBackground);
this.buttonVerticalAdj = this.getUserVal(buttonVerticalAdj);
console.log('button stylings set ok');
this.labelAlign = this.getUserVal(labelAlign);
console.log('label alignment set ok');
this.vectorTranslationVerticalCorrection = this.getUserVal(vectorTranslationVerticalCorrection);
console.log('vector translation vertical correction set ok');
}
// getter for appletsize
get appletsize() {
return [this.scale * this.width, this.scale * this.height];
}
// coordinate system setting
// getter for unit_in_pixels
get unit_in_pixels() {
if (contains(this.code,"UnitPoint")) {
return eval(this.code.slice(this.code.indexOf(",", this.code.indexOf("UnitPoint"))+1, this.code.indexOf(")", this.code.indexOf("UnitPoint")))) * this.scale;
//eval(getValueFromString(this.code, 'UnitPoint'))
}
else return 1;
}
get coord_div() {
return eval(this.unit_in_pixels);
}
//getter for has_origin_unit (string) (if there is Origin&Unit object in jsp code)
get has_origin_unit() {
if (contains(this.code,"Origin&Unit") || contains(this.code,"OriginAndUnit")) {
//if (!contains(this.code,"$")) {
return getOrigin(this.code);
//}
//return "";
}
return "";
}
// getter for boardsize
get boardsize() {
return [Math.round(((this.appletsize[0]/this.coord_div/2)*-1)*100)/100, Math.round((this.appletsize[1]/this.coord_div/2)*100)/100, Math.round((this.appletsize[0]/this.coord_div/2)*100)/100, Math.round(((this.appletsize[1]/this.coord_div/2)*-1)*100)/100];
}
//getter for origin info
get originXY() {
return {X: Math.round(100*(this.scale*this.appletsize[0]/this.coord_div/2))/100, Y: Math.round(100*(this.scale*this.appletsize[1]/this.coord_div/2))/100}
}
// getter for unitxy // setting unitx and unity // for hiding buttons outside the borders of the image //
get unitxy() {
return {X : this.scale*this.appletsize[0]/this.coord_div, Y : this.scale*this.appletsize[1]/this.coord_div};
}
// angles
get directed_angles() {
if (contains(this.code,'DirectedAngles')) {
try {
return eval(getValueFromString(this.code, 'DirectedAngles', '='));
} catch(err) {alert("Convertor error, <br> JSP Param 'DirectedAngles' caused this error. <br>"+ err.message);
console.log("Convertor error, <br> JSP Param 'DirectedAngles' caused this error. <br>"+ err.message);
}
}
else return 1;
}
//board colour attributes
get bgColour() {
let back_red, back_blue, back_green;
if (this.forceWhiteBack) return "FFFFFF";
if (contains(this.code,'BackRed')) {try{back_red = eval(getValueFromString(this.code, 'BackRed', '=')); }catch(e){alert(e.message)}}
if (contains(this.code,'BackGreen')) {try {back_green = eval(getValueFromString(this.code, 'BackGreen', '=')); }catch(e){alert(e.message)}}
if (contains(this.code,'BackBlue')) {try {back_blue = eval(getValueFromString(this.code, 'BackBlue', '=')); }catch(e){alert(e.message)}}
if (back_red && back_green && back_blue) return rgbToHex(back_red, back_green, back_blue);
else return "FFFFFF";
}
//codestring add-ons
//big/small labels
get labelsizeStyleAddon() {
let labels = '';
if (contains(this.code, 'smallLabel'))
labels += '\t.'+this.boardName+'_smalllabels {font:10px; }\n';
else if (contains(this.code, 'bigLabel'))
labels += '\t.'+this.boardName+'_biglabels {font:20px; }\n';
return labels;
}
getSketchCode(code) {
if (code != 'codearea') {
return code;
}
else return this.getUserVal(code)
}
//method that reads boardname and element id
getBoardName(boardName, elementId) {
//let boardName="", elementId="";
if ((contains(this.code,'JSX board name') && contains(this.code,'JSX element id')) || contains(this.code,'JSX boardname') && contains(this.code,'JSX element id')) {
if (contains(this.code,'JSX board name')) boardName = getValueFromString(this.code, 'JSX board name');
else boardName = getValueFromString(this.code, 'JSX boardname');
elementId = getValueFromString(this.code, 'JSX element id');
return {boardname: boardName, elid: elementId};
}
else {
boardName = getUserVal(boardName);
elementId = getUserVal(elementId);
if (boardName == '' && elementId == '') return {boardname : 'JXGboard', elid : 'el'};
if (boardName == '' ) return {boardname : 'JXGboard', elid : elementId}
if (elementId == '' ) return {boardname : boardName, elid : 'el'}
return {boardname : boardName, elid : elementId};
}
}
//if (boardname.indexOf(' ')>=0 || elid.indexOf(' ')>=0)
//alert("Spaces not allowed in JSXGraph board name or element id!");
// method that reads value from ui
getUserVal(id, type) {
if (!type && document.getElementById(id).type == 'checkbox')
type = 'radio';
if (type == 'radio')
return document.getElementById(id).checked;
else {
if (document.getElementById(id).value.length < 1) {
console.log('Empty ' + id + ' value!');
alert('Empty ' + id + ' value!');
return null;
}
return document.getElementById(id).value;
}
}
// method to read width and height values (from jsp code or ui values)
readWidthHeight(sketch, width, height, scale) {
if (contains(sketch.toUpperCase(),"WIDTH") && contains(sketch.toUpperCase(),"HEIGHT")) {
return {Width: getBoardSizeFromCode(sketch)[0], Height: getBoardSizeFromCode(sketch)[1]};
}
else {
return {Width: getUserVal(width), Height: getUserVal(height)};
}
}
getBorderWidth(bool) {
if (bool === true) return "1";
else return "0";
}
}
/*
* Method to check if in long string file in given index has a specific word, checking char by char
* This is for dotcommands checking, max dotcommand length is 10 chars!
* str = long string file
* ind = given index to start checking from
* wrd = word to look for
* len = max dotcommand length by user (optional, default 10 char)
*/
function hasDotcommandInIndx(str, ind, wrd, len) {
var str_shrink = '';
var max_len = ind + 10;
if (len) max_len = ind + len;
//create shorter string
for (var i = ind; i<max_len; i++) {
str_shrink += str.charAt(ind);
}
//check
if (str_shrink.indexOf(wrd)>=0) return true;
return false;
}
/*
*
* returns all variables that need to be replaced
*
*/
function replaceJspVariablesFromString(str) {
var output = [];
var tmp = "";
var max_len = 3;
for (var i=0; i<str.length; i++) {
if (str.charAt(i) == '{') {
i++;
tmp = (str.slice(i, bracketClosure(str, '{', i)-1));
if (tmp.length<=max_len && Number.isInteger(eval(tmp))) output.push(str.slice(i, bracketClosure(str, '{', i)-1));
}
}
return output;
}
/*
* Return line count for some string to occur in given texarea (id value)
*
*
*/
function lineCount(id, txt) {
var str = document.getElementById(id).value;
if (str.indexOf(txt)<0) return -1;
return (str.slice(0, str.indexOf(txt)).match(/\n/g)||[]).length + 1;
//return (str.slice(0, str.indexOf(txt)).match(/[^\n]*\n[^\n]*/gi)).length +1;
}
/**
* Simple string cleaning function (trim and replace all ' with "), return changed s (String).
* @method cleanString
* @param {String} s - string
* @return {String} s - "cleaned" string
*/
function cleanString(s) {
s = s.trim();
//s = s.replace(/"/g, "\'');
return s;
}
/**
* Help function to change colour from RBG to Hex
* source: http://www.javascripter.net/faq/rgbtohex.htm
* @method rgbToHex
* @param {String} R -
* @param {String} G -
* @param {String} B -
* @return {String} toHex(R)+toHex(G)+toHex(B) - calculated Hex-colour
*/
function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B)}
/**
* Help function to change colour from RBG to Hex
* source: http://www.javascripter.net/faq/rgbtohex.htm
* @method toHex
* @param {String} n - value to be changed
* @return {String} changed Hex-value
*/
function toHex(n) {
n = parseInt(n,10);
if (isNaN(n)) return "00";
n = Math.max(0,Math.min(n,255));
return "0123456789ABCDEF".charAt((n-n%16)/16)
+ "0123456789ABCDEF".charAt(n%16);
} /* /source */
/**
* Check if input (string) is jspcode with $variables
* @method checkJSPStyle
* @param {String} c - JSP code
* @return {Boolean}
*/
function checkJSPStyle(c) {
if (c.indexOf('$')>=0) //if there is $-char in code return false
return false;
return true;
}
/*
* Check if char is alphabet
* @method isAlpabet
* @param {Char} c - char
* @return {boolean} true if c is an alphabet else false
*/
function isAlphabet(c) {
var alphabets = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (alphabets.indexOf(c)>=0) return true;
return false;
}
function contains(a, obj) {
if (a.indexOf(obj) > -1) return true;
return false;
}
/**
* returns index of bracket closure from a string
s = given string
b = bracket style (start bracket)
t = index (number or indexOf(string))
*/
function bracketClosure(s, b, t) {
var counter = 0;
var bracket_style = '}';
var i;
if (b == '(') bracket_style = ')';
else if (b == '[') bracket_style = ']';
if (Number.isInteger(t)) {
i=t;
while (counter > -1) {
if (s.charAt(i) == b) {counter = counter+1; i++}
else if (s.charAt(i) == bracket_style) {counter= counter-1; i++}
else i++;
if (i==s.length-1) return i;
}
}
else if (!Number.isInteger(t)) {
i = s.indexOf(b,s.indexOf(t))+1
if (i<0) return s.length-1;
while (counter > -1) {
if (s[i] == b) {counter=counter+1; i++}
else if (s[i] == bracket_style) {counter=counter-1; i++}
else i++;
if (i==s.length-1) return i;
}
}
else {alert('error'); return null;}
return i;
}
/* s: string
* c: starting string
* m: start from m (string) after c
* i: index to start from
*/
function getValueFromString(s, c, m, i) {
var goodChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_";
var value = "";
var ind = 0;
if (i) ind = i;
else if (m) ind = s.indexOf(m, s.indexOf(c));
else ind = s.indexOf(c) + c.length;
while(s.charAt(ind) == ' ' || goodChars.indexOf(s.charAt(ind))<0) ind = ind+1;
while(goodChars.indexOf(s.charAt(ind))>=0) {
value = value + s[ind];
ind=ind+1;
}
return value;
}
function changeTextApostrophes(text) {
var t = text;
var count = 0;
var i1, i2;
var strp = [];
var tmp;
var result = "";
if (t.indexOf("'")<0)
return t;
else {
strp.push(t.slice(0, t.indexOf("'")));
var i = t.indexOf("'");
/*for (var i=t.indexOf("'"); i<t.length; i++)*/ while (i < t.length) {
if (t.charAt(i) == "'") {
i1 = i;
while (t.charAt(i) == "'" && i < t.length) {
count = count + 1;
i = i + 1;
}
i2 = i;
tmp = t.slice(i1, i2);
//alert(tmp);
count = count / 2;
//alert(t[i+1]);
for (var j=0; j<count; j++)
tmp = tmp.replace("''", "\'");
//i = i2;
count = 0;
strp.push(tmp);
}
else {
i1= i;
while (t.charAt(i) != "'" && i < t.length)
i = i + 1;
i2 = i;
tmp = t.slice(i1,i2);
//alert(tmp);
strp.push(tmp);
//i = i2;
}
}
for (var i = 0; i<strp.length; i++)
result = result + strp[i];
return result;
}
}
function uniq_fast(a) {
var seen = {};
var out = [];
var len = a.length;
var j = 0;
for(var i = 0; i < len; i++) {
var item = a[i];
if(seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
}
return out;
}
/**
* Divides one big string file (original Java Sketchpad code) into array of separate rows and returns rows (Array).
* @method separateCommands
* @param {String} a - Java Sketchpad code -string
* @return {Array<String>} rows - separated rows from Java Sketchpad code as an array
**/
function separateCommands(a, is_macro) {
var rows = [],
indx = 0,
i = 0,
numbers = "1234567890",
br_numb = "1}2}3}4}5}6}7}8}9}0}",
sr_numb = "{1{2{3{4{5{6{7{8{9",
comment="",
tmp = "",
tmp2 = "",
macro = "",
wo_nr = [],
add = 0,
bug_stopper = 0;
while (a.indexOf('<!--')>0 && a.indexOf('-->')>0) {
a=a.slice(0, a.indexOf('<!--'))+a.slice(a.indexOf('-->')+3);
}
//let's put the index for i
if (a.indexOf('£(') < a.indexOf('{'))
i = a.indexOf('£(');
else i = a.indexOf('{');
if (is_macro) {
rows.push(a.slice(0, a.indexOf(')')+1))
a = a.slice(a.indexOf(')')+1);
i = indx = 0;
while ( i < a.length) {
if (a.charAt(i) == ';') {
rows.push(a.slice(indx, i+1));
i++;
indx = i;
}
else i++;
}
}
while(i<a.length ) {
if (a[i] == '{' && numbers.indexOf(a[i+1])>=0) {
indx = a.indexOf(';', i);
if (comment.length > 0) {
rows.push(comment + a.slice(i, indx+1));
comment = "";
} else {
rows.push(a.slice(i, indx+1));
}
i = indx;
}
else if (a.charAt(i) == '£' && a.charAt(i+1) == '(') {
macro = "MACRO:" + a.slice(i+2, a.indexOf('£)',i)) + ":MACRO ";
i = a.indexOf('£)',i)+1;
rows.push(macro);
}
else if (hasDotcommandInIndx(a,i,'{,LabelAl',9) || hasDotcommandInIndx(a,i,'{,label',7) || hasDotcommandInIndx(a,i,'{,text',6) || hasDotcommandInIndx(a,i,'{,dash',6) || hasDotcommandInIndx(a,i,'{,latex',7)) {
rows.push(a.slice(i+2, bracketClosure(a, '{', i+3)));
if (rows[rows.length-2].indexOf('//comment')>=0) {
tmp = rows[rows.length-2].slice(rows[rows.length-2].lastIndexOf('//')+2, rows[rows.length-2].lastIndexOf(';')+1);
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf('//')+2) + "//comment:" + rows.pop() + "//" + tmp;
}
else if (rows[rows.length-2].indexOf('/*comment')>=0){
tmp = rows[rows.length-2].slice(rows[rows.length-2].lastIndexOf('*/')+2, rows[rows.length-2].lastIndexOf(';')+1);
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf('*/')+2) + "//comment:" + rows.pop() + "//" + tmp;
}
else
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf(']')) + "//comment:" + rows.pop() + "//];";
i = bracketClosure(a, '{', i+1)-1;
}
else if (hasDotcommandInIndx(a, i, '{,calcLocus', 11) || hasDotcommandInIndx(a, i, '{,locus', 7) || hasDotcommandInIndx(a, i, '{,jxg', 5) || hasDotcommandInIndx(a, i, '{,setAtt', 8) || hasDotcommandInIndx(a,i,'{,smallLabel', 12) || hasDotcommandInIndx(a,i,'{,bigLabel', 10)) {
indx = i+2;
tmp2 = a.slice(i+1, bracketClosure(a, '{', i+1)-1);
rows.push(tmp2);
if (rows[rows.length-2].indexOf('//comment')>=0) {
tmp = rows[rows.length-2].slice(rows[rows.length-2].lastIndexOf('*/')+2, rows[rows.length-2].lastIndexOf(';')+1);
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf('*/')+2) + "//comment:" + rows.pop() + "//" + tmp;
}
else rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf(']')) + "//comment: " + rows.pop() + "//];";
i = bracketClosure(a, '{', i+1);
}
else if (a[i] == '{' && a[i+1] == ',') { // useroption (e.g. arrowL or psize()) as commends in JSP code after command line
rows.push(a.slice(i+2, bracketClosure(a, '{', i+3)-1));
if (rows[rows.length-2].indexOf('//comment')>=0) {
tmp = rows[rows.length-2].slice(rows[rows.length-2].lastIndexOf('*/')+2, rows[rows.length-2].lastIndexOf(';')+1);
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf('*/')+2) + "//comment:" + rows.pop() + "//" + tmp;
}
else if (rows[rows.length-2].indexOf('/*comment')>=0){
tmp = rows[rows.length-2].slice(rows[rows.length-2].lastIndexOf('*/')+2, rows[rows.length-2].lastIndexOf(';')+1);
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf('*/')+2) + "//comment:" + rows.pop() + "//" + tmp;
}
else
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf(']')) + "//comment:" + rows.pop() + "//];";
i = bracketClosure(a, '{', i+1)-1;
}
else if (a[i] == '{' && numbers.indexOf(a[i+1])<0) {
comment = comment + '/*comment:' + a.slice(i+1, bracketClosure(a, '{', i+1)-1) + '*/' ;
i = bracketClosure(a, '{', i+1)-1;
}
i++;
bug_stopper = bug_stopper +1;
} //end of while
//add last comment possibly
if (comment.length > 0) {
//comment = comment.replace('comment', 'lastcomment');
rows[rows.length-1] = rows[rows.length-1] + comment.slice(0, comment.indexOf('/*')+2) + 'lastComment' + comment.slice(comment.indexOf('comment')+7) ;
//alert(rows[rows.length-1]);
comment = "";
}
for (var i=0; i<rows.length; i++) {
if (rows[i].indexOf('MACRO:')>=0) {
rows[i] = rows[i] + rows[i+1];
rows.splice(i+1, 1);
}
}
//console.log(rows);
return rows;
}
//var jsp = /*points*/ "Point|FixedPoint|Midpoint|Point on object|Intersect|Intersect1|Intersect2|PlotXY|UnitPoint|DriverPoint|"+
// /*straight lines*/ "Segment|Ray|Line|Perpendicular|Parallel|AxisX|AxisY|Polygon|Circle interior|Circle|Circle by radius|"+
// /*transformations*/ "Reflection|Dilation|Dilation/SegmentRatio|Dilation/3PtRatio|Dilation/MarkedRatio|Rotation|Rotation/MarkedAngle|"+
// "Translation|VectorTranslation|Translation/FixedAngle/MarkedDistance|PolarTranslation|"+
// "Translation/MarkedAngle/FixedDistance|Translation/MarkedAngle/MarkedDistance|"+
// /*image*/ "Image|"+
// /*measurements*/ "Length|Angle|Perimeter|Circumference|Radius|Area|Slope|Distance|Ratio/Segments|Ratio/Points|Calculate|Parameter|"+
// /*text & buttons*/ "FixedText|ShowButton|HideButton|MoveButton|AnimateButton|"+
// /*coord system */ "Coordinates|Origin&Unit|UnitCircle|"+
// /*locus*/ "Locus|";
function getMacroFunction(e,attributes) {
//var attributes ="{}";
if (!attributes)
attributes = setAttributes(e, '');
if (e.Type == 'Point' || e.Type == 'FixedPoint') {
return "('point', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");";
}
else if (e.Type == 'Midpoint') {
return "('midpoint', ["+e.Pos[0]+"], "+attributes+");";
}
else if (e.Type == 'Point on object') {
try { return "('glider', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");"; }
catch(e) { alert('Error: Point on object can\'t be used in macro. '); return null; }
}
else if (e.Type == 'Segment') {
return "('segment', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");";
}
else if (e.Type == 'Line' || e.Type == 'Perpendicular' || e.Type == 'Parallel') {
return "('line', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");";
}
else if (e.Type == 'Polygon') {
//return "('polygon', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");";
alert('Error: Polygon can\'t be used in macro. Contact admin.'); return null;
}
else if (e.Type == 'Ray') {
return "('line', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");";
}
else if (e.Type == 'Intersect' || e.Type == 'Intersect2' || e.Type == 'Intersect1') {
return "('intersection', ["+e.Pos+", "+e.Att.Info+"], "+attributes+");";
}
else if (e.Type == 'Dilation/3PtRatio') {
return "('point', [function(){return Math.sign(Math.cos(JXG.Math.Geometry.rad("+e.Pos[3]+", "+e.Pos[2]+", "+e.Pos[4]+"))) * ("+e.Pos[2]+".Dist("+e.Pos[4]+") / "+e.Pos[2]+".Dist("+e.Pos[3]+")) * ("+e.Pos[0]+".X() - "+e.Pos[1]+".X()) + "+e.Pos[1]+".X()},function() {return Math.sign(Math.cos(JXG.Math.Geometry.rad("+e.Pos[3]+", "+e.Pos[2]+", "+e.Pos[4]+"))) * ("+e.Pos[2]+".Dist("+e.Pos[4]+") / "+e.Pos[2]+".Dist("+e.Pos[3]+")) * ("+e.Pos[0]+".Y() - "+e.Pos[1]+".Y()) + "+e.Pos[1]+".Y()}], "+attributes+");";
}
else {
alert('Macro failed! ');
return null;
}
}
function getMacroPosValues(e){
var values = [], ind1 = 0, ind2 = 0;
for (var i = 0; i<e.length; i++) {
if (e[i] == ',') {
values.push(e.slice(ind1, i));
ind1 = i+1;
}
}
values.push(e.slice(ind1));
return values;
}
/**
* Slices one row of JavaSketchpad code to javascript object that has following informtion:
* - Row (row number in sketchpad code),
* - Type (Type of sketchpad element as sketchpad constructor),
* - JsxType (type as javascript understands element [in this algorithm]),
* - Pos (includes info about position [x- and y-coordinates], possible name [buttons, texts, measurements] or/and objects [rows] that are referred to),
* - Opts (sliced string from '[' to ']' in sketchpad code),
* - Att (specific info included in Opts [sketchpad code sliced from '[' to ']'] as a jsxgraph attributes. This info includes following attributes:
* Name, Color, Fixed, Visible, WithLabel, StrokeWidth, Straightlast, Straightfirst, AnchorX, Trace, Size, Infobox, LabelAlign
* - Anim (has the info needed to create buttons [list of the objects (rows) referred to when creating a button],
* @method sketchpadrowToJsxgElement
* @param {String} a - One row of Java Sketchpad code
* @return {Object} el - Object that has information separated from original Java Sketchpad element
**/
function sketchpadrowToJsxgElement(a, appletsize,coord_div,scalex,scaley,has_origin_unit,boardname) {
var el,
row,
type='',
jsxtype='',
ref='',
ctype='',
orig=a,
pos,
opts,
hlight,
att,
visib=true,
anim=[],
tmpanim,
labalig="",
psize,
sinfo,
comment="",
jspcomment="",
labelalign,
arrowf=false,
arrowl=false,
snaptogrid="false",
jxg_command = "",
set_attr = "",
suf="",
macro ="",
input_macro = "";
macro_add = 1,
fixed=false,
tmp="",
orig_line="";
var usercomments = ['arrowL','arrowF','psize','snapToGrid','text','latex','LabelAlign','labelAlign','showInfoBox','label','locus','calcLocus','setAttribute#','jxg#','attVisible','highlight','dash', 'smallLabel','bigLabel'],
extraattributes = "",
loc_to_rep=0,
rep_loc ="",
first_jspcomment = -2,
last_comment = "";
//if last row is a comment
a = a.trim();
if (a.indexOf('];')<0) a = a.slice(0,a.length-1) + "[];";
if (a.indexOf("font(")>0) {
a = a.replace(a.slice(a.indexOf("font("), a.indexOf(")", a.indexOf("font("))+1), a.slice(a.indexOf("font(")+6, a.indexOf(")", a.indexOf("font("))-1));
}
//macros 2.5.2018
if (a.indexOf('MACRO:')>=0 && a.indexOf(':MACRO')>=0) {
try {
macro = a.slice(a.indexOf('MACRO:') + 6, a.indexOf(':MACRO'));
a = a.slice(a.indexOf(':MACRO')+7);
macro = separateCommands(macro, true);
macro[0] = macro[0].trim();
macro[0] = macro[0].slice(0, macro[0].length-1) + ",att)";
} catch(e) {alert('Creating macro-list failed');}
try {
jsp_macros = jsp_macros + macro[0].slice(0, macro[0].indexOf('(')).trim();
} catch(e) {alert('Error while adding macro name value to all_macros string')}
for (var i in macro) {
if (i>0) {
macro[i] = "{" + i + "} " + macro[i];
macro_add = macro_add+1;
}
macro[i] = macro[i].replace(/£1/gi, '#1');
macro[i] = macro[i].replace(/£/gi, '');
if (i>0) {
macro[i] = sketchpadrowToJsxgElement(macro[i]);
if (macro[i].Pos.indexOf('#1')>=0) {
tmp = macro[0].slice(0,3) + '_' + (macro[i].Row-1);
macro[i].Pos = macro[i].Pos.replace(/#1/gi, tmp);
}
changeTypeToJSX(macro[i]);
macro[i].Pos = getMacroPosValues(macro[i].Pos);
changeAttributesToJSX(macro[i]);
changeOptionsToJSX(macro[i]);
}
}
}
if (a.indexOf('/*comment:')>=0 ) {
if (a.indexOf('lastComment')>=0) {
comment = a.slice(a.indexOf('/*'), a.lastIndexOf('*/', a.indexOf('lastComment'))+2);
}
else
comment = a.slice(a.indexOf('/*'), a.lastIndexOf('*/')+2);
}
if (a.indexOf('//comment:')>=0 ) {
jspcomment = a.slice(a.indexOf('//comment'), a.lastIndexOf('//')+2);
}
if (a.indexOf('lastComment')>=0) {
last_comment = a.slice(a.indexOf('/*', a.indexOf('{')), a.lastIndexOf('*')+1) + "/";
while(last_comment.indexOf('comment:')>=0)
last_comment = last_comment.replace('comment:', '');
a = a.slice(a.indexOf('{'), a.indexOf('/*', a.indexOf('{')));
}
if (jspcomment.length>0) {
a = a.replace(jspcomment, '');
jspcomment = "{" + jspcomment + "}";
while (jspcomment.indexOf('//comment:')>=0)
jspcomment = jspcomment.replace('//comment:', ',');
while(jspcomment.indexOf('//')>=0)
jspcomment = jspcomment.replace('//', '}\n{');
while(jspcomment.indexOf('{}')>=0)
jspcomment = jspcomment.replace('{}', '');
while(jspcomment.indexOf('}}')>=0)
jspcomment = jspcomment.replace('}}', '}');
if (jspcomment.indexOf('lastComment')>=0)
jspcomment = jspcomment.slice(0, bracketClosure(jspcomment, '{'));
}
if (comment.length>0) {
while (comment.indexOf('comment:')>=0) {
comment = comment.replace('comment:', '');
}
while (comment.indexOf('*//*')>=0) {
comment = comment.replace('*//*', '}\n{');
}
comment = comment.replace('*/', '*/\n')
if (last_comment.length<1)
a = a.slice(a.lastIndexOf('*/')+2, a.length-1);
}
if (last_comment.length>0) {
while (last_comment.indexOf('lastComment:')>=0) {
last_comment = last_comment.replace('lastComment:', '');
}
while (last_comment.indexOf('*//*')>=0) {
last_comment = last_comment.replace('*//*', '}\n{');
}
last_comment = last_comment.replace('*/', '*/\n')
}
try {row = eval(a.slice(a.indexOf("{")+1, a.indexOf("}"))); } catch(e) {alert(e.message)}
type = a.slice(a.indexOf("}")+1, a.indexOf("(")).trim();
if (a.indexOf(")[")>=0 && a.indexOf(")['")<0 && a.indexOf(") ['") && a.indexOf(")[ '") && a.indexOf(") [ '"))
pos = a.slice(a.indexOf("(")+1, a.indexOf(")[")).trim();
else pos = a.slice(a.indexOf("(")+1, a.lastIndexOf(")", a.lastIndexOf("[")-1)).trim();
ref = pos;
opts = a.slice(a.indexOf("["), a.indexOf("]")+1).trim();
if (type=="Calculate" || type=="Ratio/Points") {
if (a.indexOf("layer(")>=0)
a = a.replace(a.slice(a.indexOf("layer("), a.indexOf(")", a.indexOf("layer("))+1), "");
if (a.indexOf("color(")>=0) {
tmp = a.slice(a.indexOf("color("), a.indexOf(")", a.indexOf("color("))+1);
a = a.replace(tmp, "colorvaluehere"); //change 'color(...)' to 'colorvaluehere'
}
if (a.indexOf("suffix")>0)
pos = a.slice(a.indexOf("(")+1, a.lastIndexOf(")", a.indexOf("suffix")-1)+1).trim();
else pos = a.slice(a.indexOf("(")+1, a.lastIndexOf(")")+1).trim();
if (a.indexOf("colorvaluehere")>=0)
a = a.replace("colorvaluehere",tmp); //change 'colorvaluehere' back to 'color(...)'
}
else if (type=="MoveButton" || type=="ShowButton" || type=="HideButton" || type=="SimultaneousButton") {
//anim = eval("["+a.slice(a.indexOf('(', a.indexOf('(') + 1)+1, a.indexOf(')', a.indexOf(')') + 1))+"]");
if (opts.indexOf("color(")==-1 && opts.indexOf("layer(")==-1)
anim = eval("["+a.slice(a.lastIndexOf('(')+1, a.lastIndexOf(')'))+"]");
else anim = eval("["+a.slice(a.lastIndexOf('(', a.lastIndexOf('['))+1, a.lastIndexOf(')', a.lastIndexOf('[')))+"]");
}
else if (type=="AnimateButton") {
if (a.lastIndexOf('[')>0)
tmpanim = a.slice(a.indexOf(")", a.lastIndexOf("'"))+1,a.lastIndexOf(")", a.lastIndexOf('['))) + "]";
else
tmpanim = a.slice(a.indexOf(")", a.lastIndexOf("'"))+1,a.lastIndexOf(")")) + "]";
tmpanim = tmpanim.replace(/\(/g, "[");
tmpanim = tmpanim.replace(/\)/g, "]");
anim[0] = eval(tmpanim.slice(tmpanim.indexOf("["),tmpanim.indexOf("]")+1));
anim[1] = eval(tmpanim.slice(tmpanim.indexOf("][")+1,tmpanim.indexOf("]",tmpanim.indexOf("][")+1)+1));
anim[2] = eval(tmpanim.slice(tmpanim.indexOf("[",tmpanim.indexOf("][")+2), tmpanim.lastIndexOf("][")+1));
anim[3] = eval(tmpanim.slice(tmpanim.lastIndexOf("][")+1,tmpanim.lastIndexOf("]")+1));
for (var i=0; i<anim[0].length; i+=2) { //change to ms and other options, make extras zero
anim[1][i] = anim[1][i]*1000; anim[1].splice(i+1,0,0);
anim[2].splice(i+1,0,0);
anim[3].splice(i+1,0,0);
}
}
//if JSP object type is measurement set fixed true and ctype = 'measurements'
if (type == 'Coordinates' || type == 'Length' || type == 'Angle' || type == 'Perimeter' ||
type == 'Circumference' || type == 'Radius' || type == 'Area' || type == 'Slope' ||
type == 'Distance' || type == 'Ratio/Segments' || type == 'Ratio/Points' || type == 'Calculate' || type == 'Parameter') {
fixed = true;
ctype = 'measurements'
}
if (type == 'ShowButton' || type == 'HideButton' || type == 'SimultaneousButton' || type == 'AnimateButton' || type == 'MoveButton') {
fixed = true;
ctype = 'buttons';
}
if (type == 'Point' || type == 'Point on object' || type == 'UnitPoint')
ctype = 'points';
// check extra-attributes here
// POINT SIZE
psize = eval(document.getElementById('jsxpointsize').value);
if (a.indexOf("psize(")>0) {
psize = eval(a.slice(a.indexOf("psize(")+6, a.indexOf(")", a.indexOf("psize(")+6)));
}
if (jspcomment.indexOf("psize")>0) {
//psize = eval(jspcomment.slice(jspcomment.indexOf("psize(")+6, jspcomment.indexOf(")", jspcomment.indexOf("psize(")+6)));
psize = eval(jspcomment.slice(jspcomment.indexOf("(", jspcomment.indexOf('psize'))+1, bracketClosure(jspcomment, '(', 'psize')-1));
}
// SHOW INFOBOX
if (document.getElementById('jsxshowinfo').checked == true) sinfo = true;
else sinfo = false;
if (a.indexOf("showInfoBox")>0 || jspcomment.indexOf('showInfoBox') > 0)
sinfo = true;
// LABEL ALIGNMENT
labelalign = createLabelAlign(document.getElementById('jsxlabelalignment').value, 0);
if (a.indexOf("LabelAlign(")>0) {
labalig = a.slice(a.indexOf("LabelAlign(")+11, a.indexOf(")", a.indexOf("LabelAlign(")));
labelalign = createLabelAlign(labalig,0);
}
if (jspcomment.indexOf("LabelAlign")>0) {
//alert(jspcomment);
labalig = jspcomment.slice(jspcomment.indexOf("(", jspcomment.indexOf('LabelAlign'))+1, bracketClosure(jspcomment, '(', 'LabelAlign')-1);
labelalign = createLabelAlign(labalig,0);
}
if (jspcomment.indexOf("labelAlign")>0) {
//alert(jspcomment);
labalig = jspcomment.slice(jspcomment.indexOf("(", jspcomment.indexOf('labelAlign'))+1, bracketClosure(jspcomment, '(', 'labelAlign')-1);
labelalign = createLabelAlign(labalig,0);
}
if (type == "VectorTranslation")
labelalign = createLabelAlign(document.getElementById('jsxlabelalignment').value, eval(document.getElementById('vectortranslation_correction').value));
if (labalig.length>0) {
labelalign = "{offset:["+labalig+"]}"; }
// ARROWS
if (a.indexOf("arrowF") > 0 || jspcomment.indexOf('arrowF')>0)
arrowf = true;
if (a.indexOf("arrowL")>0 || jspcomment.indexOf('arrowL')> 0)
arrowl = true;
//locusToFunction comment
if (jspcomment.indexOf('locus') >= 0) {
loc_to_rep = row;
rep_loc = jspcomment.slice(jspcomment.indexOf('(')+1, jspcomment.lastIndexOf(')'));
}
// locus from calculate
if (jspcomment.indexOf('calcLocus') >= 0) {
rep_loc = eval('['+jspcomment.slice(jspcomment.indexOf('(')+1, jspcomment.lastIndexOf(')'))+']');
}
//update 4.4.2018 highlight
if (jspcomment.indexOf('highlight')>=0 || document.getElementById('usehighlight').checked == true)
hlight = true;
else hlight = false;
// SNAP TO
if (a.indexOf("snapToGrid")>0 || jspcomment.indexOf('snapToGrid')> 0)
snaptogrid = true;
// isvisible?
if (a.indexOf('hidden')>0) visib= false; else visib = true;
att= { Name:'',
Color:'black',
Fixed:fixed,
Visible:visib,
Withlabel:true,
Strokewidth:1,
Straightlast:true,
Straightfirst:true,
AnchorX:'middle',
Info:0,
Trace:false,
Size:psize,
Infobox:sinfo,
LabelAlign:labelalign,
Stop:false,
ArrowF:arrowf,
ArrowL:arrowl,
SnapToGrid:snaptogrid,
Highlight:hlight,
Suffix:suf
};
el= { Row:row,
Type:type,
JsxType:jsxtype,
CType:ctype,
ParentType:'none',
oPos:pos,
Pos:pos,
Opts:opts,
Att:att,
Anim:anim,
Macro: macro,
comment,
JSPComment:jspcomment,
LastComment:last_comment,
Ref:ref,
isReferred:true,
Orig: orig,
Original_line: a,
locusToReplace:loc_to_rep,
replaceLocus:rep_loc,
bname:boardname
};
el = changeTypeToJSX(el);
el = changePosInfoToJSX(el,appletsize,coord_div,scalex,scaley,has_origin_unit);
el = changeAttributesToJSX(el);
el = changeOptionsToJSX(el);
return el;
}
/**
* Check if param p is valid JSP constructor or not. Return true in case p is JSP constructor, else false
* @method checkJSPitem
* @param {String} p - string value JSP constructor
* @return {boolen} true if p is JSP type constructor, else false
*/
function checkJSPitem(p) {
var jsp = /*points*/ "|Point|FixedPoint|Midpoint|Point on object|Intersect|Intersect1|Intersect2|PlotXY|UnitPoint|DriverPoint|"+
/*straight lines*/ "|Segment|Ray|Line|Perpendicular|Parallel|AxisX|AxisY|Polygon|Circle interior|Circle|Circle by radius|"+
/*transformations*/ "|Reflection|Dilation|Dilation/SegmentRatio|Dilation/3PtRatio|Dilation/MarkedRatio|Rotation|Rotation/MarkedAngle|"+
"|Translation|VectorTranslation|Translation/FixedAngle/MarkedDistance|PolarTranslation|"+
"|Translation/MarkedAngle/FixedDistance|Translation/MarkedAngle/MarkedDistance|"+
/*image*/ "|Image|"+
/*measurements*/ "|Length|Angle|Perimeter|Circumference|Radius|Area|Slope|Distance|Ratio/Segments|Ratio/Points|Calculate|Parameter|"+
/*text & buttons*/ "|FixedText|ShowButton|HideButton|MoveButton|AnimateButton|SimultaneousButton|"+
/*coord system */ "|Coordinates|Origin&Unit|UnitCircle|"+
/*locus*/ "|Locus|";
if (jsp.indexOf(p)<0) return false;
else return true;
}
/**
* To check code for simple errors which are length, brackets etc.
* @method codeDummyTest
* @param {String} code -
* @return {Boolean} valid - true if code passes dummy-test, else false
*/
function codeDummyTest(code) {
var valid = true;
if (code.length == 0) return true;
if (code.indexOf('(')<0 || code.indexOf(')')<0) valid = false;
else if (code.indexOf('[')<0 || code.indexOf(']')<0) valid = false;
else if (code.indexOf(';')<0) valid = false;
else if (code.length>0 && code.length<10) valid = false;
else if (code.indexOf(' {0} ')>-1) valid = false;
return valid;
}
/**
* Calculates and returns path for the animation
* @method getCircleAnimationPath
* @param {Strign} object - object in convertor
* @param {String} type - type of an object
* @param {Int} direction - direction of the animation, possible values are 0 or 1, if not given direction will be 1
* @return {String} path - retuns path as a string that has the array in it
*/
function getAnimationPath(object, type, direction) {
var c = object;
var path = [];
var next_tick = 0;
var ticksaddon = 0.1;
if (type == 'circle') {
while (next_tick <= 1) {
path.push("["+c+".X("+next_tick+"), "+c+".Y("+next_tick+")]");
next_tick = Math.round((next_tick + ticksaddon)*10)/10;
}
if (direction == 1) path = path.reverse();
//path.pop();
}
else {
if (direction == 0) {
path.push("["+c+".point2.X(),"+c+".point2.Y()]");
path.push("["+c+".point1.X(),"+c+".point1.Y()]");
path.push("["+c+".point2.X(),"+c+".point2.Y()]");
}
else {
path.push("["+c+".point1.X(),"+c+".point1.Y()]");
path.push("["+c+".point2.X(),"+c+".point2.Y()]");
path.push("["+c+".point1.X(),"+c+".point1.Y()]");
}
}
return "["+path+"]";
}
/**
* This function creates label offset for the elements in jsxgboard
* @method createLabelAlign
* @param {String} l - value given in UI, direction for moving label
* @param {String} a - value is how much to move the label
* @return {String} - attribute to change label position in JSXGraph image
*/
function createLabelAlign(l, v) {
if (l == "ct") {return "{offset:[0," + (10+v) + "]}"}
else if (l == "rt") {return "{offset:[10," + (10+v) + "]}"}
else if (l == "rm") {return "{offset:[10," + (0+v) + "]}"}
else if (l == "rb") {return "{offset:[10," + (-10+v) + "]}"}
else if (l == "cb") {return "{offset:[0," + (-10+v) + "]}"}
else if (l == "lb") {return "{offset:[-10," + (-10+v) + "]}"}
else if (l == "lm") {return "{offset:[-10," + (0+v) + "]}"}
else if (l == "lt") {return "{offset:[-10," + (10+v) + "]}"}
else try {
//alert("{offset:["+l+"]}");
return "{offset:["+l+"]}";
} catch(e){alert(e.message);}
}
/*
* reads and return board dimensions from code
* @param {String} codetxt - JSP code
* @return {Object[array]} - width and height values as string in list [width(String), height(String)]
*
*/
function getBoardSizeFromCode(codetxt) {
var goodChar="0123456789", goodWidth=["WIDTH", "Width", "width"], goodHeight=["HEIGHT", "Height", "height"], indx1=0, indx2=0, w="", h="";
for (var i=0; i<goodWidth.length; i++) {
if (codetxt.indexOf(goodWidth[i])>=0) {
indx1 = codetxt.indexOf(goodWidth[i]);
while (goodChar.indexOf(codetxt[indx1])==-1)
indx1++;
indx2 = indx1;
while (goodChar.indexOf(codetxt[indx2])>=0)
indx2++;
w = codetxt.slice(indx1, indx2);
indx1=0; indx2=0;
}
}
if (w.lenght<1) alert("Load error. File has no width value.");
for (var i=0; i<goodHeight.length; i++) {
if (codetxt.indexOf(goodHeight[i])>=0) {
indx1 = codetxt.indexOf(goodHeight[i]);
while (goodChar.indexOf(codetxt[indx1])==-1)
indx1++;
indx2 = indx1;
while (goodChar.indexOf(codetxt[indx2])>=0)
indx2++;
h = codetxt.slice(indx1, indx2);
indx1=0; indx2=0;
}
}
if (h.lenght<1) alert("Load error. File has no height value.");
return [w,h];
}
/*
* THIS WILL BE REMOVED AND REPLACED WITH BETTER SOLUTION IN FUTURE
* generates original code from converted object
* @param {Object[array]} e - converted code in list
* @param {} w -
* @param {} h -
* @param {Boolean} withtags -
* @param {Object} options -
* @return {String} - generated JSP code as string
*/
function getOrigString(e, w, h, withtags, options) {
var s="";
var com = "", jspcom = "", lastcom = "";
var end = "\n{ This JavaSketchpad code was generated by JSP to JSXG convertor }\n{ see http://cs.uef.fi/matematiikka/ABACUS/JavasketcpadToJSXgraph/ }\n";
if (options == 'SketchrowOnly') {
if (e.JSPComment.length == 0 && e.comment.length > 0) s = s + "{" + e.comment.slice(2,this.length-3) + "}" ;
s = s + "{"+e.Row+"} " + e.Type + "(";
s = s+e.Pos + ")";
s = s + e.Opts + ";\n";
s = s.replace('))[', ')[');
if (e.comment.length > 0 && e.JSPComment.length > 0) s = s + e.JSPComment + "";
return s;
}
else {
for (var i in e) {
if (e[i].comment.length > 1)
com = '\n{' + e[i].comment.slice(2, this.length-3) + '}\n';
if (e[i].JSPComment.length > 1)
jspcom = e[i].JSPComment + '';
if (e[i].LastComment.length > 1)
lastcom = '{' + e[i].LastComment.slice(2, this.length-3) + '}';
//if (e[i].JSPComment.length == 0 && e[i].comment.length > 0) { s = s + "{" + e[i].comment.slice(2,e[i].comment.length-3) + "}\n" ; }
s= s+com;
s = s + "\n{"+e[i].Row+"} " + e[i].Type + "(";
s = s+e[i].Pos + ")";
s = s + e[i].Opts + ";\n";
s = s.replace('))[', ')[');
//if (e[i].JSPComment.length > 0) s = s + e[i].JSPComment + "\n";
s = s+jspcom;
s = s+lastcom;
com = '';
jspcom = '';
lastcom = '';
}
if (withtags){
return '<font size="4" style="letter-spacing:1.5px;"><b>JavaSketchpad code:</b></font><input onclick="copyJSPToClipboard()"" value="Copy JSP code to clipboard" type="button" class="browseButton"> <br><textarea id="jspgeneratedcode" cols="120" rows="50"><APPLET \nCODEBASE="jsp" ARCHIVE="jsp4.jar" CODE="GSP.class" WIDTH='+w+' HEIGHT='+h+' ALIGN=Left>\n<PARAM NAME=Offscreen VALUE=1><PARAM NAME=Frame VALUE=1>\n<PARAM NAME=MeasureInDegrees VALUE=1><PARAM NAME=DirectedAngles VALUE=0>\n<PARAM NAME=BackRed VALUE=250><PARAM NAME=BackGreen VALUE=250><PARAM NAME=BackBlue VALUE=250>\n<PARAM NAME=Construction VALUE="\n'+s+end+'">\n</APPLET></textarea>';
}
else
return '<font size="4" style="letter-spacing:1.5px;"><b>JavaSketchpad code:</b></font><input onclick="copyJSPToClipboard()"" value="Copy JSP code to clipboard" type="button" class="browseButton"> <br><textarea id="jspgeneratedcode" cols="120" rows="50">' + s + end +'</textarea>';
}
}
/*
* get JSP command from line
* @param {String} s - codeline
* @param {Integer} i - index of string
* @param {String} c - string to look from s to get index
* @param {String} m - string to look after c
* @return {String} value - JSP command as string
*/
function getJSPCmndFromString(s, i, c, m) {
var goodChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_/";
var value = "";
var ind = 0;
if (i>=0) ind = i;
else if (m) ind = s.indexOf(m, s.indexOf(c));
else ind = s.indexOf(c) + c.length;
while(s.charAt(ind) == ' ' || goodChars.indexOf(s.charAt(ind))<0) ind = ind+1;
while(goodChars.indexOf(s.charAt(ind))>=0) {
value = value + s[ind];
ind=ind+1;
}
return value;
}
/**
* Function to change coordinates so that the (0,0) is the origo.
* @method changeToCoord
* @param {Int} x - x coordinate in Java Sketchpad form
* @param {Int} y - y coordinate in Java Sketchpad form
* @param {Array<Int>} appletsize - appletsize
* @param {Int} coord_div - coordinates dividor if coordinates has been set in Java Sketchpad code using Origin&Unit and Unitpoint commands
* @param {Double} scalex - factor that is used in scaling the image horizontally
* @param {Double} scaley - factor that is used in scaling the image vertically (this is not actually used, since the scalex and scaley are defines as the same value in main function)
* @param {String} hasorigin - coordinates of origin if it has been changes in original Java Sketchapd code
* @return {Array} - created coordinates (Array)
*/
function changeToCoord(x,y,appletsize, coord_div, scalex, scaley, hasorign) {
var origin, moved_origin;
origin = [appletsize[0]/coord_div/2, appletsize[1]/coord_div/2];
if (hasorign.length > 0) {
moved_origin = eval('['+hasorign+']');
//moved_origin = hasorign;
moved_origin[0] = moved_origin[0]*scalex; moved_origin[1] = moved_origin[1]*scaley; //alert(moved_origin);
x = (-1*(origin[0]-((scalex*x)/coord_div))-((moved_origin[0]-(appletsize[0]/2))/coord_div));
y = (origin[1]-((scaley*y)/coord_div)+((moved_origin[1]-(appletsize[1]/2))/coord_div));
}
else {
x = (-1*(origin[0]-((scalex*x)/coord_div)));
y = (origin[1]-((scaley*y)/coord_div));
}
return [Math.round(x*100)/100, Math.round(y*100)/100];
}
/**
* Checks if there is Origin&Unit constructor in code, and return originelements rownr (String).
* @method getOrigin
* @param {String} a - original Java Sketchpad code
* @return {String} org - information that is in the Origin&Unit line between the brackets '(' and ')'
*/
function getOrigin(a) {
var rw="", ind, org;
if (a.indexOf('Origin&Unit')>=0)
rw = a.slice(a.indexOf('(', a.indexOf('Origin&Unit'))+1, a.indexOf(',', a.indexOf('Origin&Unit')));
else if (a.indexOf('OriginAndUnit')>=0)
rw = a.slice(a.indexOf('(', a.indexOf('OriginAndUnit'))+1, a.indexOf(',', a.indexOf('OriginAndUnit')));
rw = '{'+rw+'}';
org = a.slice(a.indexOf('(',a.indexOf(rw))+1, a.indexOf(')',a.indexOf(rw)));
return org;
}
/**
* Changes all input code $name variablenames to {rownumber} representation and returns changed code (string)
* @method varJSPtoNumJSP
* @param {String} c - JSP code in $-form
* @return {String} c - JAva Sketchpad code in {row no}-form
*/
function varJSPtoNumJSP(c) {
var dList = [], dStr="", dVar="", indx1, indx2, j, dTmp="", commends=[], tmp="", tmp2="", tmp3="", tmp4="", bcmem, add=0 , bug_stopper = 0;
//check for commends and "extra" lines
while (c.indexOf('${')>=0 && bug_stopper <= 5000) {
//removing $jsp comments - update on 04.04.2018
c = c.slice(0, c.indexOf('${')) + c.slice(c.indexOf('$}')+2);
bug_stopper++;
if (bug_stopper >= 5000) {alert ("Error 1. Error in converting $JSP comments!"); return "null";}
} //tmp = "";
if (bug_stopper != 0) {bug_stopper = 0;}
//check for macros and rename all $-chars
while (c.indexOf('$(')>=0 && bug_stopper <= 5000) {
tmp = tmp2 = c.slice(c.indexOf('$('), c.indexOf('$)')+2);
//while (tmp2.indexOf('$')>=0)
//tmp2 = tmp2.replace('$', '#');
tmp2 = tmp2.replace(/\$/gi, '£');
c = c.replace(tmp, tmp2);
bug_stopper++;
if (bug_stopper >= 5000) {alert ("Error 1. Error in converting $JSP comments!"); return "null";}
}
tmp = tmp2 = "";
if (bug_stopper != 0) {bug_stopper = 0;}
while (c.indexOf('#')>=0 && c.indexOf('#')<c.indexOf('$') && bug_stopper <= 5000) {
commends.push(c.slice(c.indexOf('#'), c.indexOf('$')));
tmp2 = commends.pop();
if ((tmp2.indexOf('WIDTH')>=0 || tmp2.indexOf('Width')>=0 || tmp2.indexOf('width')>=0) && (tmp2.indexOf('HEIGHT')>=0) || tmp2.indexOf('Height')>=0 || tmp2.indexOf('height')>=0)
tmp = tmp2;
c = c.replace(tmp2, "");
bug_stopper++;
if (bug_stopper >= 5000) {alert ("Error 2. Error in converting $JSP code!"); return "null";}
} c = tmp + c;
tmp = tmp2 = "";
if (bug_stopper != 0) {bug_stopper = 0;}
var k = 1;
j = c.indexOf('$');
for(var i=j; i<c.length; i++) {
if (c.charAt(i) == '$' && c.charAt(i+1)!='{' && c.charAt(i+1)!='}' && c.charAt(i+1)!='(' && c.charAt(i+1)!=')') {
indx1 = bcmem = i;
while (c.charAt(i)!=' ' && c.charAt(i)!=',' && c.charAt(i)!=')' && c.charAt(i)!='@' && c.charAt(i)!='(') i++;
indx2 = i;
dVar = c.slice(indx1,indx2);
if (checkJSPitem('|'+dVar.slice(1)+'|') && !checkJSPitem('|' + getValueFromString(c,'','',indx2) + '|')) {
document.getElementById('errormessages_prog').innerHTML = dVar + ' on line '+ lineCount('codearea', dVar) +' is not a valid variable name without object construction command!\n ';
$('#codearea').linenumbers({col_width:'37px', digits:'3'}, lineCount('codearea', dVar));
return 'null';
}
dVar = dVar + '|';
if (dStr.indexOf(dVar)==-1 && dVar != '$1|') {
dStr = dStr + dVar;
dList.push([dVar,k++]);
}
if (c.indexOf(';',i) >= 0 )
i = c.indexOf(';',i);
else {
document.getElementById('errormessages_prog').innerHTML = 'There is a semicolon (;) missing on line <font color="#F00">' + c.slice(indx1, indx1+60) + '</font>';
return 'null';
}
} //end of if
//if dot command 3.5.2018
else if (c.charAt(i) == '{' && c.charAt(i+1) == ',') {
i = bracketClosure(c, '{', i+1)-1;
}
/* update on 16.3.2018: User can input commands without variable name. Creates temporary variable name for each of these lines. */
else if (c.charAt(i) != ' ' && c.charAt(i) != '{' && c.charAt(i) != ';' && c.charAt(i) != '$' && c.charAt(i) != '<' && isAlphabet(c.charAt(i))) {
indx = i;
while (c.charAt(i) != ';' && c.charAt(i) != '}' && c.charAt(i) != '>') i++;
indx2=i+1;
if (c.charAt(i) == ';') {
tmp3 = (c.slice(indx,i));
//alert(tmp3);
try {
//if (checkJSPitem(tmp3.slice(0, tmp3.indexOf('(')).trim()) && tmp3.indexOf(';')<0) {
if (checkJSPitem(getJSPCmndFromString(tmp3, 0)) && tmp3.indexOf(';')<0) {
//if (c.slice(indx,indx2+1).indexOf('$') >= 0 && (c.slice(indx,indx2+1).indexOf('$') < c.slice(indx,indx2+1).indexOf(';'))) {
//document.getElementById('errormessages_prog').innerHTML = "Found error in code. <br>Look for the line:<br><br>" + c.slice(indx,indx2+1) + "<br><br>and fix it! May be unknown command, error in syntax or missing ';'. <br><br>Convertion was stopped.";
//c= c.slice(0, indx); i=0;
//return "null";
//}
//alert(tmp3.slice(0, tmp3.indexOf('(')));
//if (c.indexOf(tmp3, indx2) < 0) {
tmp4 = '$var_wthout_name_'+add+' '+tmp3;
//c = c.replace(tmp3, tmp4);
c = c.slice(0,indx) + tmp4 + ";" + c.slice(indx2);
//alert(c);
add++;
i = bcmem-1;
//}
//else {
//document.getElementById('errormessages_prog').innerHTML = "Found error in code. <br>Look for the line:<br><br>" + c.slice(indx,indx2+1) + "<br><br>and fix it! There is duplicate of this line in code.";
//c= c.slice(0, indx); i=0;
//return "null";
//}
bug_stopper++;
if (bug_stopper > 10000) {
alert("ERROR! \n(" + tmp3 +")\nThis caused problems! ");
return null;
}
//if (c[i] == ';') alert(c[i] + c[i+1] + c[i+2]);
}
else {
//alert("Found error in code. \nLook for the line:\n\n" + tmp3 + "\n\nand fix it! \n\nConvertion was done to the point where error occurred.");
//alert(tmp3);
document.getElementById('errormessages_prog').innerHTML = "Error 7. Found error in code. <br>Look for the line:<br><br>"+ getJSPCmndFromString(tmp3,0) + "<br>" + c.slice(indx,indx2+1) + "<br><br>and fix it! May be unknown command, error in syntax or missing ';'. <br><br>Convertion was stopped.";
//return "{1} FixedText(50,10,'ERROR IN CODE!')[];";
//alert(c.slice(0, bcmem));
//return c.slice(0, bcmem);
c= c.slice(0, indx); i=0;
return "null";
}
} catch(e) {document.getElementById('ERRORS').innerHTML = e.message;}
}
}
/*end of update */
//alert(c);
} //end of for loop
dList.sort(function(a,b) {
return b[0].length - a[0].length;
});
//alert(dList);
for(var i=0; i<dList.length; i++) {
dList[i][0] = dList[i][0].replace('|', '');
bug_stopper++;
if (bug_stopper>=10000) {document.getElementById('errormessages_prog').innerHTML = "Error 3. Error in $JSP convertion."; return "null";}
}
if (bug_stopper != 10000) {bug_stopper = 0}
while (c.indexOf('$1')>=0) {
c = c.replace('$1', '#-1#');
}
while (c.indexOf('$2')>=0) {
c = c.replace('$2', '#-2#');
}
while (c.indexOf('$3')>=0) {
c = c.replace('$3', '#-3#');
}
while (c.indexOf('$4')>=0) {
c = c.replace('$4', '#-4#');
}
//update 7.9.2018 replace variables in ,locus{ }
var locus_indexses = [];
var locuses = [];
var old_locuses = [];
//var new_locuses = [];
var ex_in = 0;
while (c.indexOf(',locus', ex_in)>0) {
locus_indexses.push(c.indexOf(',locus',ex_in));
locuses.push(c.slice(c.indexOf(',locus',ex_in), bracketClosure(c, '{', c.indexOf(',locus',ex_in))));
ex_in = c.indexOf(',locus',ex_in)+6;
}
//update 7.9.2018
if (locuses.length>0) {
for (var j=0; j<locuses.length; j++) {
old_locuses[j] = locuses[j];
for(var k=0; k<dList.length; k++) {
while (locuses[j].indexOf(dList[k][0])>=0) locuses[j] = locuses[j].replace(dList[k][0], "{"+dList[k][1]+"}");
}
c = c.replace(old_locuses[j], locuses[j]);
}
}
for(var i=0; i<dList.length; i++) {
j=i+1;
c = c.replace(dList[i][0], "{"+dList[i][1]+"}");
while(c.indexOf(dList[i][0])>=0 && (c[c.indexOf(dList[i][0])+dList[i][0].length] == ' ' || c[c.indexOf(dList[i][0])+dList[i][0].length] == ',' || c[c.indexOf(dList[i][0])+dList[i][0].length] == ')' || c[c.indexOf(dList[i][0])+dList[i][0].length] == '@')) {
c = c.replace(dList[i][0], dList[i][1]);
bug_stopper++;
if (bug_stopper>=10000) {document.getElementById('errormessages_prog').innerHTML = "Error 4. Error in replacing $JSP variables to {rows}."; return "null";}
}
}
if (bug_stopper != 10000) {bug_stopper = 0}
while (c.indexOf('$')>=0) {
for (var i=0; i<dList.length; i++) {
j=i+1;
while(c.indexOf(dList[i][0])>=0 && (c[c.indexOf(dList[i][0])+dList[i][0].length] == ' ' || c[c.indexOf(dList[i][0])+dList[i][0].length] == ',' || c[c.indexOf(dList[i][0])+dList[i][0].length] == ')'))
c = c.replace(dList[i], j);
}
while (c.indexOf('${')>=0)
c = c.replace('${', '{');
while (c.indexOf('$}')>=0)
c = c.replace('$}', '}');
bug_stopper++;
if (bug_stopper>=10000) {document.getElementById('errormessages_prog').innerHTML = "Error 5. Error in replacing $JSP variables to {rows}.<br>Check that there is no undefined variables in your $JSP code and variables without name are not referred to.<br><br>Maybe this is the cause of error :<br> "+c.slice(c.indexOf('$'), c.indexOf(',',c.indexOf('$'))) +"<br><br> Check also that there are no missing semicolons (;) on command lines, possibly before command line :<br> " + c.slice(c.indexOf('$'), c.indexOf(',',c.indexOf('$'))) + "..."; return "null";}
}
//alert(c);
return c;
}
function subAndSup(s) {
var r = s;
var tmp = "";
if (r.indexOf('SUB{'>=0) || r.indexOf('SUP{')>=0) {
while (r.indexOf('SUB{')>=0) {
tmp = r.slice(r.indexOf('SUB{'), bracketClosure(r, '{', 'SUB{')+1);
r = r.replace(tmp, '\\\\"+")<sub>\\\\"+"('+tmp.slice(tmp.indexOf("{")+1, tmp.lastIndexOf("}"))+'\\\\"+")</su'+'b>\\\\"+"(');
}
while (r.indexOf('SUP{')>=0) {
tmp = r.slice(r.indexOf('SUP{'), bracketClosure(r, '{', 'SUP{')+1);
r = r.replace(tmp, '\\\\"+")<sup>\\\\"+"('+tmp.slice(tmp.indexOf("{")+1, tmp.lastIndexOf("}"))+'\\\\"+")</su'+'p>\\\\"+"(');
}
r = r.replace("\\\\'+'( \\\\'+')", "");
r = r.replace("\\\\'+'(\\\\'+')", "");
return r;
}
return r;
}
function labelByUser(a) {
if (a.Opts.indexOf('label')>=0)
a.Att.Name = a.Opts.slice(a.Opts.indexOf("(", a.Opts.indexOf('label'))+2, a.Opts.lastIndexOf("'", bracketClosure(a.Opts, '(', 'label')));
if (a.JSPComment.indexOf('label(')>=0) {
a.Att.Name = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('label('))+1, a.JSPComment.lastIndexOf("'"));
a.Att.Name = subAndSup(a.Att.Name);
}
a.Att.Name = changeTextApostrophes(a.Att.Name);
return a;
}
/**
* Function to create string that contains funtion as a string for 'Calculate' operation.
* E.g. input calculateFunction("A2+3*@sin_", [5]) will product a string "(Math.sin((3*(A+2))))", where A is replaced with value from row no 5 in Java Sketchpad code.
* Inputs are string (a), array of element indexes (b) and measurements (calculations) in that indexes in array b are referring to.
* Uses function mathCalc to create string.
* @method calculateFunction(string, array, array)
* @param {String} a - string that has the calculation, for example "A2+3*@sin_"
* @param {Array<Int>} b - array of elements in calculate command that are used as variables. For example if command is Calculate(0,315,'f(x,y) = ','A2^ B2^ -')(53,54)[magenta], b will be [53,54]
* @param {Array<String>} calc - has the calculations that jsptojsx convertor has created as strings.
* @return {String} ans - answer for the calculation
*/
function calculateFunction(a,b,calc, line) {
var i, j=0, tmpstr="", obj = [], terms = [], ans="", vbstr="", indx=0, v_indx=0;
var abc = "ABCDEFGHIJ", operators = "+-*/^%!", functions = "sin_ cos_ tan_ abs_ sqrt ln__ rond trnc sgn_ asin acos atan log_";
var alrt = false;
a = a.slice(a.lastIndexOf("'", a.lastIndexOf("'")-1)+1, a.lastIndexOf("'"));
//for checking purposes, insert @alrt at the end of the calcultion to alert the return function
if (a.indexOf('@alrt')>0) {
a = a.slice(0, a.indexOf('@alrt'));
alrt = true;
}
//Gettin values for variables here
while (a.indexOf("#")>=0){
indx = a.indexOf("#");
/*if (a[indx+1] == 'A') j=0;
else if (a[indx+1] == 'B') j=1;
else if (a[indx+1] == 'C') j=2;
else if (a[indx+1] == 'D') j=3;*/
if (a[indx+2] == '1') v_indx=0;
else v_indx = 1;
tmpstr = calc[b[getNumberOfCharForCalculate(a[indx+1])]][v_indx];
tmpstr = tmpstr.replace("function(){return ","");
tmpstr = tmpstr.replace(";}","");
while (tmpstr.indexOf("Dist")>=0 || tmpstr.indexOf("JXG.")>=0 || tmpstr.indexOf("Geometry")>=0) {
tmpstr = tmpstr.replace("Dist","dist"); //change Dist() because it has capital 'D'
tmpstr = tmpstr.replace("JXG.","jxg."); //change capital JXG
tmpstr = tmpstr.replace("Geometry","geometry"); //change capital Geometry
}
tmpstr = "|"+tmpstr+"|";
vbstr = a.slice(indx, indx+3);
while(a.indexOf(vbstr)>=0)
a = a.replace(vbstr, tmpstr);
vbstr="";
}
for (i=0; i<abc.length; i++) {
if (a.indexOf(abc[i])>=0 ) {
//tmpstr = calc[b[j]];
tmpstr = calc[b[getNumberOfCharForCalculate(abc[i])]];
tmpstr = tmpstr.replace("function(){return ","");
tmpstr = tmpstr.replace(";}","");
while (tmpstr.indexOf("Dist")>=0 || tmpstr.indexOf("JXG.")>=0 || tmpstr.indexOf("Geometry")>=0) {
tmpstr = tmpstr.replace("Dist","dist"); //change Dist() because it has capital 'D'
tmpstr = tmpstr.replace("JXG.","jxg."); //change capital JXG
tmpstr = tmpstr.replace("Geometry","geometry"); //change capital Geometry
}
tmpstr = "|"+tmpstr+"|";
while(a.indexOf(abc[i])>=0 )
a = a.replace(abc[i], " "+tmpstr+" ");
j++;
}
}
while (a.indexOf("dist")>=0 || a.indexOf("jxg.")>=0 || a.indexOf("geometry")>=0) {
a=a.replace("dist","Dist"); //change all lowletter 'dist' back to 'Dist'
a=a.replace("jxg.","JXG."); //change capital JXG
a=a.replace("geometry","Geometry"); //change capital Geometry
}
if (a.indexOf(',|')>=0 || a.indexOf('|,')>=0) { alert('Error in calculate command line '+ line +', check your commas and apostrophes.'); return null;}
for (i=0; i<a.length; i++){
if (a[i] == "@") {
i++;
terms.push(a[i++]+a[i++]+a[i++]+a[i]);
}
else if (a[i] == "|") {
terms.push(a.slice(i+1,a.indexOf("|",i+1)));
i = a.indexOf("|",i+1);
}
else if (operators.indexOf(a[i]) >= 0) {
terms.push(a[i]);
}
else if (a[i] != " ") {
var string =""; j=i;
while(a[j] != " " && a[j] != "@" && operators.indexOf(a[j]) == -1 && abc.indexOf(a[j]) == -1) {
string = string+a[j];
j++;
}
terms.push(string); i=j-1;
}
}
for (i=0; i<terms.length; i++) {
if (functions.indexOf(terms[i].toString()) >= 0) {
ans = mathCalc(terms[i], obj.pop());
obj.push(ans);
}
else if (operators.indexOf(terms[i].toString()) >=0) {
ans = mathCalc(terms[i], obj.pop(), obj.pop());
obj.push(ans);
}
else {
obj.push(terms[i]);
}
}
if (obj.length>0)
ans = obj.pop();
if (alrt) alert (ans);
console.log('result of calculate: '+ans);
return ans;
}
/**
* Creates one calculation with given operator and inputs. Second input is optional.
* E.g. mathCalc("+", "1", "5") returns string "(1+5)" and
* mathCalc("@sin_", "3.14") returns string "Math.sin(3.14)".
* @method mathCalc
* @param {String} f - mathematical operation
* @param {String} a - mathematical value or expression
* @param {String} b - mathematical value or expression
* @return {String} mathematical expression as a JavaScript string
*/
function mathCalc(f,a,b) {
if (f == "+") {return "("+b+"+"+a+")";}
else if (f == "-") {return "("+b+"-"+a+")";}
else if (f == "*") {return "("+b+"*"+a+")";}
else if (f == "/") {return "("+b+"/"+a+")";;}
else if (f == "^") {return "Math.pow("+b+","+a+")";}
else if (f == "%") {return "(-1*"+a+")";}
else if (f == "!") {return "(-1*"+a+")";}
else if (f == "sin_") {return "Math.sin("+a+")";}
else if (f == "cos_") {return "Math.cos("+a+")";}
else if (f == "tan_") {return "Math.tan("+a+")";}
else if (f == "abs_") {return "Math.abs("+a+")";}
else if (f == "sqrt") {return "Math.sqrt("+a+")";}
else if (f == "ln__") {return "Math.log("+a+")";}
//else if (f == "rond") {if (Math.abs(Math.abs(a)-Math.abs(Math.floor(a))) < Math.abs(Math.abs(a)-Math.abs(Math.ceil(a)))) return Math.floor(a); else return Math.ceil(a);}
else if (f == "trnc") {return "Math.floor("+a+")";} // SGN_!
else if (f == "rond") {return "Math.round("+a+")";}
else if (f == "sgn_") {return "Math.sign("+a+")";}
else if (f == "asin") {return "Math.asin("+a+")";}
else if (f == "acos") {return "Math.acos("+a+")";}
else if (f == "atan") {return "Math.atan("+a+")";}
else if (f == "log_") {return "Math.log10("+a+")";}
}
/**
* Simple function to get number of char for the Calculate operation (get order of variable)
* @method getNumberOfCharForClaculation
* @param {String} a - alphabet from A to F
* @return {Int} integer from 0 to 5
*/
function getNumberOfCharForCalculate(a) {
if (a=='A') return 0;
else if (a=='B') return 1;
else if (a=='C') return 2;
else if (a=='D') return 3;
else if (a=='E') return 4;
else if (a=='F') return 5;
else if (a=='G') return 6;
else if (a=='H') return 7;
else if (a=='I') return 8;
else if (a=='J') return 9;
else return 0;
}
/**
* Changes property JsxType of an element given as object created in sketchpadrowToJsxgElement(string)
* [mostly just changes property to lowercase letters]
* Also change the CType (constructor type), possible types are:
* points, straightlines, circles, measurements, transformations, images, buttons, coordinatesystem, locus
* @method changeTypeToJSX
* @param {Object} a -
* @return {Object} a - return the object
*/
function changeTypeToJSX(a) {
try {
if (a.Type == "FixedPoint") {
a.JsxType = 'point';
a.Opts = a.Opts.replace("]",",fixed:true]");
a.CType = 'points';
}
else if (a.Type == "Point" || a.Type == "PlotXY" || a.Type == "UnitPoint") {
a.JsxType = a.Type.toLowerCase();
a.CType = 'points';
}
else if (a.Type == "Origin&Unit" || a.Type == "OriginAndUnit" || a.Type == "Origin&Unit") {
a.JsxType = 'originandunit';
a.CType = 'coorninatesystem';
a.ParentType = 'point';
}
else if (a.Type == "Point on object") {
a.JsxType = 'glider';
a.CType = 'points';
a.ParentType = 'line';
}
else if (a.Type == "MidPoint" || a.Type == "Midpoint") {
a.JsxType = a.Type.toLowerCase();
a.CType = 'points';
a.ParentType = 'line';
}
else if (a.Type=='Line' || a.Type == 'Segment' || a.Type == 'Ray' || a.Type == 'Parallel' || a.Type == 'Perpendicular' || a.Type == 'AxisX' || a.Type == 'AxisY') {
a.JsxType = a.Type.toLowerCase();
a.CType = 'straightlines';
a.ParentType = 'point';
}
else if (a.Type == 'Circle' || a.Type == 'Circle by radius' ) {
a.JsxType = a.Type.toLowerCase();
a.CType = 'circles';
a.ParentType = 'point';
}
else if (a.Type == "FixedText") {
a.JsxType = 'text';
a.CType = 'buttons';
}
else if (a.Type == "Intersect1" || a.Type == "Intersect2" || a.Type == "Intersect") {
if (a.Type == "Intersect2") a.Att.Info = 0; else a.Att.Info = 1;
a.JsxType = 'intersection';
a.CType = 'points';
a.ParentType = 'line';
}
else if ( a.Type == 'Reflection' || a.Type == 'Dilation' || a.Type == 'Dilation/SegmentRatio' || a.Type == 'Dilation/3ptRatio' || a.Type == 'Dilation/3PtRatio' ||
a.Type == 'Dilation/MarkedRatio' || a.Type == 'Rotation' || a.Type == 'Rotation/MarkedAngle' || a.Type == 'Rotation/MeasuredAngle' ||
a.Type == 'Translation' || a.Type == 'VectorTranslation' || a.Type == 'Translation/MarkedAngle/MarkedDistance' ||
a.Type == 'Translation/Markedangle/Markeddistance' || a.Type == 'PolarTranslation' || a.Type == 'Translation/FixedAngle/MarkedDistance') {
a.JsxType = a.Type.toLowerCase();
a.CType = 'transformations';
}
else if ( a.Type == 'Coordinates' || a.Type == 'Length' || a.Type == 'Angle' || a.Type == 'Perimeter' || a.Type == 'Circumference' ||
a.Type == 'Radius' || a.Type == 'Area' || a.Type == 'Slope' || a.Type == 'Distance' || a.Type == 'Ratio/Segments' ||
a.Type == 'Ratio/Points' || a.Type == 'Calculate' || a.Type == 'Parameter') {
a.JsxType = a.Type.toLowerCase();
a.CType = 'measurements'
}
else if (a.Type == 'ShowButton' || a.Type == 'HideButton' || a.Type == 'SimultaneousButton' || a.Type == 'AnimateButton' || a.Type == 'MoveButton') {
a.JsxType = a.Type.toLowerCase();
a.CType = 'buttons';
}
else if (a.Type == 'Polygon' ) {
a.JsxType = 'polygon';
a.CType = 'interiors';
}
else if (a.Type == 'Circle interior' ) {
a.JsxType = a.Type.toLowerCase();
a.CType = 'interiors';
}
else if (a.Type == 'Locus') {
a.JsxType = a.Type.toLowerCase();
a.CType='curves';
}
else if (jsp_macros.indexOf(a.Type)>=0)
a.JsxType = 'macros';
else {
a.JsxType = a.Type.toLowerCase();
a.CType = 'unknown';
//alert(a.JsxType);
}
} catch(e) {alert( "Error (element-handles: function getElemRefs): " + e.message);}
return a;
}
/**
* Changes property Pos of an element given as object created in sketchpadrowToJsxgElement(string)
* Outcome depends of type of the element as follows:
* - Point will change Pos to array with point coordinates [x,y],
* - Unit coord will change Pos to array with reference to object and a coordinate [ref to obj, y],
* @method changePosInfoToJSX
* @param {Object} a -
* @param {Array} applets -
* @param {Int} coordd - coord divider, this is read from the original code in the main function JSPtoSJX
* @param {Double} scx - scale x factor, this is read in the main function
* @param {Double} scy - scale y factor, this is read in the main function
* @param {Int} hasoriginunit - origin&unit info read in the main function from the original code
* @return {Object} a - return the object with changed values
* ...
*/
function changePosInfoToJSX(a, applets, coordd, scx, scy, hasoriginunit) {
var x,y,o,t,values = [], laba, butvadj=0;
//button vertical adjustment:
if (document.getElementById('usebuttonstyle').checked == true) butvadj = document.getElementById('buttonverticaladjsel').value;
x = a.Pos.slice(0,a.Pos.indexOf(","));
y = a.Pos.slice(a.Pos.indexOf(",")+1,a.Pos.length);
if (a.Pos.indexOf('#-1#')>=0 || a.Pos.indexOf('#-2#')>=0 || a.Pos.indexOf('#-3#')>=0|| a.Pos.indexOf('#-4#')>=0) {
while (a.Pos.indexOf('#-1#')>=0)
a.Pos = a.Pos.replace('#-1#', a.Row-1);
while (a.Pos.indexOf('#-2#')>=0)
a.Pos = a.Pos.replace('#-2#', a.Row-2);
while (a.Pos.indexOf('#-3#')>=0)
a.Pos = a.Pos.replace('#-3#', a.Row-3);
while (a.Pos.indexOf('#-4#')>=0)
a.Pos = a.Pos.replace('#-4#', a.Row-4);
}
if (a.JsxType == 'point')
a.Pos = changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit);
else if (a.JsxType == 'unitpoint'){
a.Pos = [eval(x), changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[1]];
}
else if (a.JsxType == 'originandunit') {
a.Pos = eval("["+a.Pos+"]");
}
else if (a.JsxType == 'text' || a.JsxType == 'image') {
y = a.Pos.slice(a.Pos.indexOf(",")+1,a.Pos.indexOf(",", a.Pos.indexOf(",")+1));
t = a.Pos.slice(a.Pos.indexOf("'")+1,a.Pos.lastIndexOf("'"));
t = cleanString(t);
if (a.JSPComment.indexOf('text')>=0) t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('text'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
if (a.JSPComment.indexOf('latex')>=0) t = '\\\\"+"( ' + a.JSPComment.slice(a.JSPComment.indexOf('(', a.JSPComment.indexOf("latex"))+1, bracketClosure(a.JSPComment, "(", "latex")-1) + ' \\\\"+")';
t=subAndSup(t);
t=changeTextApostrophes(t);
if (a.JSPComment.indexOf('LabelAlign')>=0 || a.JSPComment.indexOf('labelAlign')>=0) {laba = eval(a.Att.LabelAlign.slice(a.Att.LabelAlign.indexOf('['), a.Att.LabelAlign.indexOf(']')+1)); x = eval(x)+eval(laba[0]); y = eval(y) + eval(laba[1]);}
a.Pos = [changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[0],changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[1],t];
}
else if (a.JsxType == 'movebutton') {
y = eval(a.Pos.slice(a.Pos.indexOf(",")+1,a.Pos.indexOf(",", a.Pos.indexOf(",")+1))) + eval(butvadj);
o = 1000 * eval(a.Pos.slice(a.Pos.indexOf(",", a.Pos.indexOf(",")+1)+1, a.Pos.indexOf(",'")));
t = a.Pos.slice(a.Pos.indexOf("'")+1, a.Pos.lastIndexOf("'"));
if (a.JSPComment.indexOf('text')>=0) t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('label'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
t=subAndSup(t);
t=changeTextApostrophes(t);
a.Pos = [changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[0],changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[1],o,t];
}
else if (a.JsxType == 'showbutton' || a.JsxType == 'hidebutton' || a.JsxType == 'simultaneousbutton' || a.JsxType == 'animatebutton') {
y = eval(a.Pos.slice(a.Pos.indexOf(",")+1,a.Pos.indexOf(",", a.Pos.indexOf(",")+1))) + eval(butvadj);
t = a.Pos.slice(a.Pos.indexOf("'")+1,a.Pos.lastIndexOf("'"));
if (t.indexOf('F(')>=0) { t=t.replace(/F/g, 'F'); }
if (t.length==0) t="UNLABELED BUTTON";
if (a.JSPComment.indexOf('text')>=0) t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('label'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
t=subAndSup(t);
t=changeTextApostrophes(t);
a.Pos = [changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[0], changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[1], t];
}
else if (a.JsxType == 'ratio/points' || a.JsxType == 'angle') {
values = eval("["+a.Pos.slice(0,a.Pos.lastIndexOf(",", a.Pos.indexOf("'")))+"]");
values[3] = changeToCoord(values[3],values[4],applets,coordd,scx,scy,hasoriginunit)[0];
values[4] = changeToCoord(values[3],values[4],applets,coordd,scx,scy,hasoriginunit)[1];
if (a.JSPComment.indexOf('text')>=0)
t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('text'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
else if (a.JSPComment.indexOf('latex')>=0) t = "\\\\'+'( " + a.JSPComment.slice(a.JSPComment.indexOf("(", a.JSPComment.indexOf('latex'))+1, bracketClosure(a.JSPComment, '(', 'latex')-1) + " \\\\'+')";
else
t = (a.Pos.slice(a.Pos.indexOf("'")+1,a.Pos.lastIndexOf("'")));
t=subAndSup(t);
t=changeTextApostrophes(t);
values.push(t);
if (a.JSPComment.indexOf('LabelAlign')>=0) {laba = eval(a.Att.LabelAlign.slice(a.Att.LabelAlign.indexOf('['), a.Att.LabelAlign.indexOf(']')+1)); values[3] = eval(values[3]+laba[0]); values[4] = eval(values[4] + laba[1]);}
a.Pos = values;
}
else if (a.JsxType == 'distance' || a.JsxType == 'coordinates' || a.JsxType == 'ratio/segments') {
values = eval("["+a.Pos.slice(0,a.Pos.lastIndexOf(",", a.Pos.indexOf("'")))+"]");
values[2] = changeToCoord(values[2],values[3],applets,coordd,scx,scy,hasoriginunit)[0];
values[3] = changeToCoord(values[2],values[3],applets,coordd,scx,scy,hasoriginunit)[1];
if (a.JSPComment.indexOf('text')>=0)
t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('text'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
else if (a.JSPComment.indexOf('latex')>=0) t = "\\\\'+'( " + a.JSPComment.slice(a.JSPComment.indexOf("(", a.JSPComment.indexOf('latex'))+1, bracketClosure(a.JSPComment, '(', 'latex')-1) + " \\\\'+')";
else
t = (a.Pos.slice(a.Pos.indexOf("'")+1,a.Pos.lastIndexOf("'")));
t=subAndSup(t);
t=changeTextApostrophes(t);
values.push(t);
if (a.JSPComment.indexOf('LabelAlign')>=0) {laba = eval(a.Att.LabelAlign.slice(a.Att.LabelAlign.indexOf('['), a.Att.LabelAlign.indexOf(']')+1)); values[3] = eval(values[3]+laba[0]); values[4] = eval(values[4] + laba[1]);}
a.Pos = values;
}
else if (a.JsxType == 'length' || a.JsxType == 'circumference' || a.JsxType == 'radius' || a.JsxType == 'area' || a.JsxType == 'slope') {
values = eval("["+a.Pos.slice(0,a.Pos.lastIndexOf(",", a.Pos.indexOf("'")))+"]");
values[1] = changeToCoord(values[1],values[2],applets,coordd,scx,scy,hasoriginunit)[0];
values[2] = changeToCoord(values[1],values[2],applets,coordd,scx,scy,hasoriginunit)[1];
if (a.JSPComment.indexOf('text')>=0)
t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('text'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
else if (a.JSPComment.indexOf('latex')>=0) t = "\\\\'+'( " + a.JSPComment.slice(a.JSPComment.indexOf("(", a.JSPComment.indexOf('latex'))+1, bracketClosure(a.JSPComment, '(', 'latex')-1) + " \\\\'+')";
else
t = (a.Pos.slice(a.Pos.indexOf("'")+1,a.Pos.lastIndexOf("'")));
t=subAndSup(t);
t=changeTextApostrophes(t);
values.push(t);
if (a.JSPComment.indexOf('LabelAlign')>=0) {laba = eval(a.Att.LabelAlign.slice(a.Att.LabelAlign.indexOf('['), a.Att.LabelAlign.indexOf(']')+1)); values[3] = eval(values[3]+laba[0]); values[4] = eval(values[4] + laba[1]);}
a.Pos = values;
}
else if (a.JsxType == 'calculate') {
values = eval("["+ a.Pos.slice(0,a.Pos.indexOf(",", a.Pos.indexOf(",")+1)) + "]");
values = changeToCoord(values[0],values[1],applets,coordd,scx,scy,hasoriginunit);
if (a.JSPComment.indexOf('text')>=0)
values[2] = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('text'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
else if (a.JSPComment.indexOf('latex')>=0) values[2] = "\\\\'+'( " + a.JSPComment.slice(a.JSPComment.indexOf("(", a.JSPComment.indexOf('latex'))+1, bracketClosure(a.JSPComment, '(', 'latex')-1) + " \\\\'+')";
else {
values[2] = a.Pos.slice(a.Pos.indexOf("'")+1, a.Pos.lastIndexOf("'", a.Pos.lastIndexOf("'")-1));
values[2] = values[2].slice(0, values[2].lastIndexOf("'"));
values[2] = cleanString(values[2]);
}
values[2]=subAndSup(values[2]);
values[2]=changeTextApostrophes(values[2]);
values[3] = a.Pos;
values[4] = eval("["+a.Pos.slice(a.Pos.lastIndexOf("(")+1,a.Pos.lastIndexOf(")"))+"]");
if (a.JSPComment.indexOf('LabelAlign')>=0) {laba = eval(a.Att.LabelAlign.slice(a.Att.LabelAlign.indexOf('['), a.Att.LabelAlign.indexOf(']')+1)); values[0] = eval(values[0]+laba[0]); values[1] = eval(values[1] + laba[1]);}
a.Pos = values;
}
else {
a.Pos = eval("["+a.Pos+"]");
}
return a;
}
/*
* Inputs references to objects parents
* @param {Object} el - Converter element
* @return {Object} el - Converter element with refs set
*
*/
function getElemRefs(el) {
try {
if (el.Type == 'Point on object' || el.Type == 'UnitPoint' || el.Type == 'Dilation' || el.Type == 'Rotation' || el.Type == 'Translation/FixedAngle/MarkedDistance' || el.Type == 'Translation/MarkedAngle/FixedDistance' || el.Type == 'Locus') {
el.Ref = eval('[' + el.Pos.slice(0, this.lastIndexOf(',')) + ']');
}
else if (el.Type == 'Translation' || el.Type == 'PolarTranslation' ) {
el.Ref = eval('[' + el.Pos.slice(0, this.lastIndexOf(',', this.lastIndexOf(','))) + ']');
}
else if (el.CType == 'measurements') {
if (el.Type == 'Angle' || el.Type == 'Ratio/Points') //has 3 objRef (Angle, Ratio/Points)
el.Ref = eval('[' + el.Pos.slice(0, this.indexOf(',', this.indexOf(',', this.indexOf(',')+1)+1)) + ']');
else if (el.Type == 'Distance' || el.Type == 'Ratio/Segments') //has 2 objRef (Distance, Ratio/Segments, )
el.Ref = eval('[' + el.Pos.slice(0, this.indexOf(',', this.indexOf(',')+1)) + ']');
else if (el.Type == 'Calculate') //is calculate
el.Ref = eval('[' + el.Pos.slice(this.lastIndexOf('(')+1, this.length-1) + ']');
else //has 1 objRef (Length, Perimeter, Circumference, Radius, Area, Slope, Coordinates, Parameter)
el.Ref = eval('[' + el.Pos.slice(0, this.indexOf(',')) + ']');
}
else if (el.CType == 'buttons') {
el.Ref = eval('[' + el.Pos.slice(this.lastIndexOf('(')+1, this.length) + ']');
}
else if (el.Type == 'FixedText' || el.Type == 'FixedPoint' || el.Type == 'Point' || el.Type == 'Image')
el.Ref = -1;
else {
el.Ref = eval('[' + el.Pos + ']');
}
} catch(err) {alert("Error (element-handles: function getElemRefs): Line " + el.Row + ", " +err.message);}
return el;
}
/**
* Changes some values in original Java Sketchpad code into form that JSXGraph can understand.
* @method changeOptionsToJSX
* @param {Object} a - object a is created from original code and has the values that will be changed
* @return {Object} a - return object a with changed values
*/
function changeOptionsToJSX(a) {
//change brackets
a.Opts = a.Opts.replace("[", "{");
a.Opts = a.Opts.replace("]", "}");
a.Opts = a.Opts.replace(a.Opts.slice(a.Opts.indexOf("layer"), a.Opts.indexOf("layer")+9), "");
//change color
a.Opts = a.Opts.replace("black", "color:'black'");
a.Opts = a.Opts.replace("white", "color:'white'");
a.Opts = a.Opts.replace("red", "color:'red'");
a.Opts = a.Opts.replace("blue", "color:'blue'");
a.Opts = a.Opts.replace("green", "color:'green'");
a.Opts = a.Opts.replace("yellow", "color:'yellow'");
a.Opts = a.Opts.replace("magenta", "color:'magenta'");
a.Opts = a.Opts.replace("cyan", "color:'cyan'");
// change name
a.Opts = a.Opts.replace("label('", "name:'");
a.Opts = a.Opts.replace("label ('", "name:'");
a.Opts = a.Opts.replace("'),", "',");
a.Opts = a.Opts.replace("')", "'");
// text alignment
a.Opts = a.Opts.replace("justifyLeft", "anchorX:'left'");
a.Opts = a.Opts.replace("justifyCenter", "anchorX:'middle'");
a.Opts = a.Opts.replace("justifyRight", "anchorX:'right'");
//change other options
a.Opts = a.Opts.replace("hidden", "visible:false");
a.Opts = a.Opts.replace("thick", "strokeWidth=2");
a.Opts = a.Opts.replace("bold,", "");
a.Opts = a.Opts.replace("{plain,", "{");
a.Opts = a.Opts.replace("font(", "");
a.Opts = a.Opts.replace("'Helvetica',", "");
a.Opts = a.Opts.replace(",,", ",");
return a;
}
/**
* Changes some attributes from original Java Sketchpad code into form that JSXGraph can understand
* @method changeAttributesToJSX(string)
* @param {Object} a - object a is created from original code and has the values that will be changed
* @return {Object} a - return object a with changed values
*/
function changeAttributesToJSX(a) {
var tmpcolor = [], tmp="", ind=0;
// name attribute
if (a.Opts.indexOf("label")>=0 || (a.JSPComment.indexOf("label")>=0 && a.JSPComment.indexOf("label") != a.JSPComment.indexOf("labelAlign"))) {
a=labelByUser(a); //attributes-handler
}
if (document.getElementById('latex').checked == true && a.Att.Name.length > 0) {
tmp = a.Att.Name;
//alert(tmp);
a.Att.Name = '\\\\'+'"+"('+tmp+'\\\\'+'"+")';
a.Att.Name = a.Att.Name.replace('\\\\"+"( \\\\"+")', '');
a.Att.Name = a.Att.Name.replace('\\\\"+"(\\\\"+")', '');
//alert(a.Att.Name);
}
// colour attribute
if (a.Opts.indexOf("white")>=0)
a.Att.Color = 'grey';
else if (a.Opts.indexOf("black")>=0)
a.Att.Color = 'black';
else if (a.Opts.indexOf("red")>=0)
a.Att.Color = 'red';
else if (a.Opts.indexOf("blue")>=0)
a.Att.Color = 'blue';
else if (a.Opts.indexOf("green")>=0)
a.Att.Color = 'green'
else if (a.Opts.indexOf("yellow")>=0)
a.Att.Color = 'yellow'
else if (a.Opts.indexOf("magenta")>=0)
a.Att.Color = 'magenta';
else if (a.Opts.indexOf("cyan")>=0)
a.Att.Color = 'cyan';
else if (a.Opts.indexOf("color(")>=0) {
tmpcolor = eval("[" + a.Opts.slice(a.Opts.indexOf("color(")+6, a.Opts.indexOf(")", a.Opts.indexOf("color(")+6)) + "]");
a.Att.Color = "#"+ rgbToHex(tmpcolor[0],tmpcolor[1],tmpcolor[2]);
}
// visible attribute
if (a.Opts.indexOf("hidden")>=0)
a.Att.Visible = false;
if (a.Opts.indexOf("traced")>=0)
a.Att.Trace = true;
// thickness attribute
if (a.Opts.indexOf("thick3")>=0 || a.Opts.indexOf("thick")>=0)
a.Att.Strokewidth = 3;
if (a.Opts.indexOf("thick6")>=0)
a.Att.Strokewidth = 6;
if (a.Opts.indexOf("thick5")>=0)
a.Att.Strokewidth = 5;
if (a.Opts.indexOf("thick4")>=0)
a.Att.Strokewidth = 4;
if (a.Opts.indexOf("thick2")>=0)
a.Att.Strokewidth = 2;
if (a.Opts.indexOf("thick") <0 )
a.Att.Strokewidth = 1;
if (a.Opts.indexOf("fixed:true") >= 0)
a.Att.Fixed = true;
else if (a.Opts.indexOf("fixed:false") >= 0)
a.Att.Fixed = false;
// text alignment attribute
if (a.Opts.indexOf("justifyLeft") >= 0)
a.Att.AnchorX = 'left';
else if (a.Opts.indexOf("justifyCenter") >= 0)
a.Att.AnchorX = 'middle';
else if (a.Opts.indexOf("justifyRight") >= 0)
a.Att.AnchorX = 'right';
//suffix
if (a.Opts.indexOf("suffix") >= 0) {
a.Att.Suffix = a.Opts.slice(a.Opts.indexOf("'",a.Opts.indexOf("suffix"))+1, a.Opts.indexOf("'",a.Opts.indexOf("'",a.Opts.indexOf("suffix"))+1));
}
if (a.Opts.indexOf("_BREAK") >=0)
a.Att.Stop = true;
return a;
}
/**
* Get options as a full string {options}, that has all the options that are needed in construction of this object.
* The purpose of this function is to shorten the converted code.
* This is also to make changing of defaul options easier (for example point color).
* @method setAttributes
* @param {Object} e - Object that has option values
* @param {String} s - optional, extra option to add options string. This is for some special attributes. Function just adds s in the return string.
* @return {String} options - String that has only the options needed, for example {name:'A', color:'red'}. There will be no options that values are default in JSXgraph syntax
*/
function setAttributes(e, s, own, n, type) {
//straightLast:"+el[i].Att.Straightlast+", straightFirst:"+el[i].Att.Straightfirst+", lastArrow:"+el[i].Att.ArrowL+", firstArrow:"+el[i].Att.ArrowF+"} );";
var options = "{";
let labelSettings = e.Att.LabelAlign.slice(1,e.Att.LabelAlign.length-1);
if (contains(e.JSPComment,'smallLabel'))
labelSettings += ',cssClass:"'+e.bname+'_smalllabels",highlightCssClass:"'+e.bname+'_smalllabels"';
if (contains(e.JSPComment,'bigLabel'))
labelSettings += ',cssClass:"'+e.bname+'_biglabels",highlightCssClass:"'+e.bname+'_biglabels"';
if (e.CType == 'points') {
options += 'name:"'+e.Att.Name+'",';
if (e.Att.Name.length > 0 ) options += "label:{"+labelSettings+"},";
if (e.Att.Color.length > 0) options += "color:'"+e.Att.Color+"',";
if (!e.Att.Visible) options += "visible:"+e.Att.Visible+",";
if (e.Att.Fixed) options += "fixed:"+e.Att.Fixed+",";
if (e.Att.Size != 2) options += "size:"+e.Att.Size+",";
//if (e.Att.Trace == true) options += "trace:"+e.Att.Trace+", ";
if (!e.Att.Infobox) options += "showInfoBox:"+e.Att.Infobox+",";
if (e.Att.SnapToGrid == true) options += "snapToGrid:"+e.Att.SnapToGrid+",";
}
else if (e.CType == 'straightlines' || e.CType == 'curves') {
if (e.Att.Name.length > 0) options += "label:'"+e.Att.Name+"',";
if (e.Att.Color.length > 0) options += "strokeColor:'"+e.Att.Color+"',";
if (e.JsxType == 'ray') options += "straightFirst:false,";
options += "strokeWidth:"+e.Att.Strokewidth+",";
if (e.Att.ArrowL == true) options += "lastArrow:true,";
if (e.Att.ArrowF == true) options += "firstArrow:true,";
if (e.JSPComment.indexOf('dash')>=0) options += "dash:" + (e.JSPComment.slice(e.JSPComment.indexOf('(')+1, e.JSPComment.lastIndexOf(')'))) + ",";
if (!e.Att.Visible) options += "visible:"+e.Att.Visible+",";
}
else if (e.CType == 'circles' || type == 'circles') {
if (e.Att.Name.length > 0) options += "label:'"+e.Att.Name+"',";
if (e.Att.Color.length > 0) options += "strokeColor:'"+e.Att.Color+"',";
if (!e.Att.Visible) options += "visible:"+e.Att.Visible+",";
if (e.Att.Trace == true) options += "trace:"+e.Att.Trace+", ";
options += "strokeWidth:"+e.Att.Strokewidth+",";
if (e.JSPComment.indexOf('dash')>=0) options += "dash:" + (e.JSPComment.slice(e.JSPComment.indexOf('(')+1, e.JSPComment.lastIndexOf(')'))) + ",";
}
else if (e.CType == 'interiors') {
//{name:'"+el[i].Att.Name+"', fillColor:'"+el[i].Att.Color+"', withLines:false,visible:"+el[i].Att.Visible+", highlight:false, showInfoBox:"+el[i].Att.Infobox+", label:"+el[i].Att.LabelAlign+"}
options += "fillColor:'"+e.Att.Color+"',withLines:false,";
if (!e.Att.Visible) options += "visible:"+e.Att.Visible+",";
if (e.Att.Name.length > 0) options += "label:'"+e.Att.Name+"',";
}
else if (e.CType == 'transformations') {
options += 'name:"'+e.Att.Name+'",';
if (e.Att.Name.length > 0 /*&& e.Att.LabelAlign != '{offset:[0,10]}'*/) options += "label:"+e.Att.LabelAlign+",";
if (e.Att.Color.length > 0 && e.Att.Color != 'red') options += "color:'"+e.Att.Color+"',";
if (!e.Att.Visible) options += "visible:"+e.Att.Visible+",";
if (e.Att.Size != 2) options += "size:"+e.Att.Size+",";
if (!e.Att.Infobox) options += "showInfoBox:"+e.Att.Infobox+",";
}
else if (e.CType == 'measurements') {
if (e.Att.Color.length > 0 && e.Att.Color != 'black') options += "color:'"+e.Att.Color+"',";
if (e.Att.Fixed) options += "fixed:true,";
}
else if (e.CType == 'buttons') {
options += "fixed:true,";
if (e.Att.Color.length > 0 && e.Att.Color != 'black') options += "color:'"+e.Att.Color+"',";
if (e.JsxType=='text') options += "anchorX:'"+e.Att.AnchorX+"',";
}
else {
options += "color:'"+e.Att.Color+"',";
}
//update 4.4.2018 highlight
if (!e.Att.Highlight)
options += "highlight:false,";
if (s.length>0) options += s;
if (options[options.length-1]==",")
return options.slice(0,options.length-1) + "}";
else
return options + "}";
}
/**
* Function that creates and returns (Array) position of the glider point.
* Param variables are string and number(a,b).
* @method gliderPoint
* @param {Object} a - JSXGraph Object
* @param {Double} b - this is to set the glider point
* @param {Object} c - Object circle
* @return {Array} - coordinates for moving glider to right position
*/
function gliderPoint(a,b,c) {
var d, dx, dy, x=0,y=0, p1x, p2x, p1y, p2y;
if (a.getType() == 'segment' || a.getType() == 'line' || a.getType() == 'axis') {
//alert(a.getType() +", ");
p1x = a.point1.X();
p2x = a.point2.X();
p1y = a.point1.Y();
p2y = a.point2.Y();
dx = p2x - p1x;
dy = p2y - p1y;
/*x = p1x + (dx * b);
y = p1y + (dy * b);
*/
x = p1x + (b*dx);
y = p1y + (b*dy);
return [x,y];
}
else if (a.getType() == 'parallel' || a.getType() == 'perpendicular') {
x = a.point1.X()+b;
y = a.point1.Y()+b;
return [x,y];
}
else if (a.getType() == 'circle') {
d = a.Radius();
x = c.X() + d*Math.cos(b);
y = c.Y() - d*Math.sin(b);
return [x,y];
}
}
function distanceToStraightline(l, p) {
var p1 = l.point1,
p2 = l.point2,
dist = Math.abs((p.X()*(p2.Y()-p1.Y())) - (p.Y()*(p2.X()-p1.X())) + p2.X()*p1.Y() - p2.Y()*p1.X() ) / Math.sqrt(Math.pow((p2.Y()-p1.Y()),2) + Math.pow((p2.X()-p1.X()),2));
return dist;
}
function trimJspCode(code_input) {
var code = "",
coderows = [],
row = [],
all_refs = [],
hidden_and_not_ref = [],
out = '',
tmp = '';
//read JSP-code
code= document.getElementById(code_input).value.replace(/(\r\n|\n|\r|" ")/gm,"");
code = code.replace(/(\t)/gm, " ");
code = code.trim();
if (!codeDummyTest(code)) {
alert('There is some problems in your JSP-code. Check your code!');
return false;
//
}
coderows = separateCommands(code);
for (var i=0; i<coderows.length; i++) {
row[i] = sketchpadrowToJsxgElement(coderows[i]);
row[i] = getElemRefs(row[i]);
//tmp = tmp + "\n" + row[i].Ref + ", is visible: " + row[i].Att.Visible;
}
try {
for (var i=0; i<row.length; i++) {
all_refs = all_refs.concat(row[i].Ref);
} //alert(all_refs);
} catch(e){alert(e.message);}
all_refs = uniq_fast(all_refs);
try {
for (var i=0; i<row.length; i++) {
if (contains(all_refs, row[i].Row)) row[i].isReferred = true;
else row[i].isReferred = false;
if (!row[i].Att.Visible && !row[i].isReferred && row[i].Type != 'UnitPoint') {
hidden_and_not_ref.push(row[i].Row);
tmp = tmp + "\n" + row[i].Orig;
}
}
if (hidden_and_not_ref.length>0) {
tmp = 'These '+hidden_and_not_ref.length+' lines can be removed from the JSP-code:\n' +tmp + "\n\nDelete these lines?";
} else {tmp = "Nothing can be removed."; alert(tmp); return false;}
} catch(e) {alert(e.message);}
if (confirm(tmp)) {
var len = hidden_and_not_ref.length;
for(var i=len-1; i>-1; i--)
row.splice(hidden_and_not_ref[i]-1, 1);
for (var i=0; i<row.length; i++)
out = out + row[i].Orig +'\n';
document.getElementById(code_input).value = out;
alert('Deleted '+len+ ' lines.');
return true;
}
return false;
}
var code_to_mem;
window.onload = function() {
/*const index_updated = {
date: "2018/10/08 ",
time: "21:25",
};
const convertor_updated = {
date : "2018/10/08 ",
time : "21:25",
};
document.getElementById('lastupdateindex-date').innerHTML = index_updated.date + index_updated.time;
document.getElementById('lastupdatecore-date').innerHTML = convertor_updated.date + convertor_updated.time;
*/
var dropdown_courses_menu = document.querySelector('#dropdown-course-selectors');
var main_course_selection = document.querySelector('#course_selection');
$.get('./php/constructcoursesdata.php', function(data) {
console.log('Courses data written in json/courses-data.json');
var requestExampleJson = new XMLHttpRequest();
requestExampleJson.open('GET', './json/courses-files.json');
requestExampleJson.responseType = 'json';
requestExampleJson.send();
requestExampleJson.onload = function() {
var jsonObj = requestExampleJson.response;
var newSelection;
for(var i in jsonObj) {
var newCourseOption = document.createElement('option');
newCourseOption.value = Object.keys(jsonObj[i])[0];
newCourseOption.textContent = Object.keys(jsonObj[i])[0];
main_course_selection.appendChild(newCourseOption);
newSelection = document.createElement('select');
newSelection.id = (Object.keys(jsonObj[i])[0]);
newSelection.classList.add('courses-selection');
if (i==0) newSelection.classList.add('courses-selection-visible');
else newSelection.classList.add('courses-selection-hidden');
var newOption;
for (var key in jsonObj[i]) {
for (var j=0; j<jsonObj[i][key].length; j++) {
if (jsonObj[i][key][j] !== '.') {
newOption = document.createElement('option');
newOption.value = jsonObj[i][key][j];
newOption.textContent = jsonObj[i][key][j];
newSelection.appendChild(newOption);
}
}
}
newSelection.addEventListener('change', function() {
console.log('open file ' + this.value);
openSelectionFile(this.id, this.value);
})
dropdown_courses_menu.appendChild(newSelection);
}
};
});
$("#course_selection").change(function() {
var set_id = "#"+($(this).val());
var hide_classes = ".courses-selection";
console.log('selected menu '+set_id);
$(hide_classes).removeClass('courses-selection-visible').addClass('courses-selection-hidden');
$(set_id).removeClass('courses-selection-hidden').addClass('courses-selection-visible');
});
$("#addmathjax").change(function() {
if ($(this).prop('checked') ==true) {
$("#mathjax_source").prop('disabled', false);
$("#mathjax_source_text").css('color','#ddd');
}
else {
$("#mathjax_source").prop('disabled', true);
$("#mathjax_source_text").css('color','#888');
}
});
$("#addstylesheet").change(function() {
if ($(this).prop('checked') ==true) {
$("#stylesource").prop('disabled', false);
}
else {
$("#stylesource").prop('disabled', true);
}
});
//button styling -button
$("#usebuttonstyle").change(function() {
if ($(this).prop('checked') ==true) {
$(".button_options_selection").prop('disabled', false);
}
else {
$(".button_options_selection").prop('disabled', true);
}
});
$(function() {
$('#codearea').linenumbers({col_width:'37px', digits:'3'});
});
} //end of window.onload
/* copyToClipboard
*Helpfunction to copy JXGcode to clipboard.
*/
function copyToClipboard() {
document.getElementById('jsxcode').select();
document.execCommand('copy');
//alert("Copying done!");
}
function copyJSPToClipboard() {
document.getElementById('jspgeneratedcode').select();
document.execCommand('copy');
}
/* openNewWindow
Is used when link is wanted to open in new window.
*/
function openNewWindow(link) {
window.open(link, link, "toolbar=0,status=0,menubar=0,scrollbars=1");
}
function openNewConverterWindow(link) {
window.open(link, link, "fullscreen=yes, status=0");
}
function editJSXcode(link, code, img) {
if (link == 0) document.getElementById('hidden_jsx_editor_value').innerHTML = "";
else document.getElementById('hidden_jsx_editor_value').innerHTML = "1";
window.open('html/JSXeditor.html','html/JSXeditor.html', 'fullscreen=yes');
}
/**
* This function checks some things from string (the JSP code), inputs code into codearea and runs function jspToJsx
* @param {String} codetxt - code as string
* @return {Boolea} - false if codetxt not found, else true;
*/
function inputCodeAndValues(codetxt) {
if(!codetxt) return false;
var sizew=400, sizeh=400; bname="JSXBoard", ename="id"
sizew = getWidthHeight(codetxt)[0];
sizeh = getWidthHeight(codetxt)[1];
if (codetxt.indexOf("BNAME=")>=0 && codetxt.indexOf("#BNAME")>=0)
bname = codetxt.slice(codetxt.indexOf("BNAME=")+6, codetxt.indexOf("#"));
if (codetxt.indexOf("ENAME=")>=0 && codetxt.indexOf("#ENAME")>=0)
ename = codetxt.slice(codetxt.indexOf("ENAME=")+6, codetxt.indexOf("#", codetxt.indexOf("#")+1));
if (!checkJSPStyle(codetxt)) {
if (codetxt.indexOf("<JSP>")>=0 && codetxt.indexOf("</JSP>")>=0) {
codetxt = codetxt.slice(codetxt.indexOf("<JSP>"), codetxt.indexOf("</JSP>")+6);
}
else {
if (codetxt.lastIndexOf(';')<codetxt.lastIndexOf('$}'))
codetxt = codetxt.slice(codetxt.indexOf("$"), codetxt.lastIndexOf("$}")+2);
else
codetxt = codetxt.slice(codetxt.indexOf("$"), codetxt.lastIndexOf(";")+1);
}
}
else codetxt = codetxt.slice(codetxt.indexOf("{"), codetxt.lastIndexOf(";")+1);
document.getElementById('codearea').value = codetxt;
document.getElementById('boardwidthinput').value = sizew;
document.getElementById('boardheightinput').value = sizeh;
document.getElementById('jsxgboardname').value = bname;
document.getElementById('jsxgelementid').value = ename;
clearAll(['jsxgimage','jsxgcode','JSketchPadCode','testing','errormessages'], ['err_comms', 'err_info', 'err_submit_btn', 'ERRORS']);
document.getElementById('ERRORS').style.display = "inline-block";
jspToJsx('codearea');
return true;
}
function convertPagetoJSX(codetxt) {
var imglisting=[], sizelisting=[], namelisting=[], convertedlisting=[], tmp="";
while (codetxt.indexOf('<APPLET')>=0) {
tmp = codetxt.slice(codetxt.indexOf('<APPLET'), codetxt.indexOf('</APPLET>')+9);
codetxt = codetxt.replace(tmp, "<REPAPPLET>");
imglisting.push(tmp);
}
for (var i=0; i<imglisting.length; i++) {
sizelisting.push(getWidthHeight(imglisting[i]));
}
for (var i=0; i<imglisting.length; i++) {
namelisting.push("img_"+i);
}
for (var i=0; i<imglisting.length; i++) {
imglisting[i] = imglisting[i].slice(imglisting[i].indexOf('{'), imglisting[i].lastIndexOf(';')+1);
}
for (var i=0; i<imglisting.length; i++) {
convertedlisting.push(jspToJsx(imglisting[i], sizelisting[i], namelisting[i], true));
}
for (var i=0; i<convertedlisting.length; i++) {
codetxt = codetxt.replace("<REPAPPLET>", convertedlisting[i]);
}
document.getElementById("codearea").value = codetxt;
document.getElementById("loading").style.display = "none";
document.getElementById("jsxgimage").innerHTML = "All "+convertedlisting.length+" images converted ok!<br><br><input onclick='downloadConvPage()' value='Save converted html' type='button' class='browseButton'>";
clearAll(['jsxgcode','JSketchPadCode','testing'], ['err_comms', 'err_info', 'err_submit_btn']);
//alert("All "+convertedlisting.length+" images converted ok!");
return null;
}
/* source: http://www.htmlgoodies.com/beyond/javascript/read-text-files-using-the-javascript-filereader.html#fbid=40sibQt8vco
*/
function readSingleFile(evt) {
//Retrieve the first (and only!) File from the FileList object
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
inputCodeAndValues(contents);
}
r.readAsText(f);
}
else
alert("Failed to load file");
}
function readFullPageFile(evt) {
//Retrieve the first (and only!) File from the FileList object
var f = evt.target.files[0];
document.getElementById("loading").style.display = "block";
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
convertPagetoJSX(contents);
}
r.readAsText(f);
}
else
alert("Failed to load file");
}
//function downloadFile(){
function downloadJSX(){
var text=document.getElementById('jsxcode').value;
var filename = document.getElementById('jsxgboardname').value +".html";
var blob = new Blob([text], {type: "text/plain"});
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
}
//function downloadConvPage(){
function downloadConvPage(){
var text=document.getElementById('codearea').value;
var filename = "convertedpage.html";
var blob = new Blob([text], {type: "text/plain"});
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
}
/* not in use anymore function selectChange(c) {
var sel = "";
try {
if (c == 'course') {
sel = document.getElementById('course_selection').value;
if (sel == 'JSPTestfiles') {
document.getElementById('JSPTestfiles').style.display = 'inline-block';
document.getElementById('MatematiikanJohdantoKurssi2018').style.display = 'none';
}
else if (sel == 'MatematiikanJohdantoKurssi2018') {
document.getElementById('JSPTestfiles').style.display = 'none';
document.getElementById('MatematiikanJohdantoKurssi2018').style.display = 'inline-block';
}
return true;
}
else if(c == 'JSPTestfiles') {
sel = document.getElementById('JSPTestfiles').value;
if (sel != '-1') inputCodeAndValues(getSelectedExample(sel));
}
else if (c == 'MatematiikanJohdantoKurssi2018') {
sel = document.getElementById('MatematiikanJohdantoKurssi2018').value;
if (sel != '-1') inputCodeAndValues(MatematiikanJohdantoKurssi2018(sel));
}
$('#codearea').linenumbers({col_width:'37px', digits:'3'});
return true;
} catch(e) {alert(e.message);}
}
*/
/**
* Open file fron path and convert it
* @param {String} folder - folder name
* @param {String} file - file name with extension
*/
function openSelectionFile(folder, file) {
if (file == '..') return null;
var sel = './jspfiles/'+folder+'/' + file;
var request = new XMLHttpRequest();
request.open('GET', sel);
request.responseType = 'text';
request.send();
request.onload = function() {
var file = request.responseText;
console.log('File '+sel+' was read!');
//check $JSP
if (file.indexOf('<JSP>')>=0) file = file.slice(file.indexOf('<JSP>'), file.indexOf('</JSP>'));
inputCodeAndValues(file);
}
}
/**
* Get width and height values from code (string)
* @param {String} codetxt - code
* @return {Object} [array] - array that has dimension values: [width, height]
*/
function getWidthHeight(codetxt) {
var goodChar="0123456789", goodWidth=["WIDTH", "width", "Width"], goodHeight=["HEIGHT", "height", "Height"], indx1=0, indx2=0, w="", h="";
for (var i=0; i<goodWidth.length; i++) {
if (codetxt.indexOf(goodWidth[i])>=0) {
indx1 = codetxt.indexOf(goodWidth[i]);
while (goodChar.indexOf(codetxt[indx1])==-1)
indx1++;
indx2 = indx1;
while (goodChar.indexOf(codetxt[indx2])>=0)
indx2++;
w = codetxt.slice(indx1, indx2);
indx1=0; indx2=0;
}
}
if (w.lenght<1) alert("Load error. File has no width value.");
for (var i=0; i<goodHeight.length; i++) {
if (codetxt.indexOf(goodHeight[i])>=0) {
indx1 = codetxt.indexOf(goodHeight[i]);
while (goodChar.indexOf(codetxt[indx1])==-1)
indx1++;
indx2 = indx1;
while (goodChar.indexOf(codetxt[indx2])>=0)
indx2++;
h = codetxt.slice(indx1, indx2);
indx1=0; indx2=0;
}
}
if (h.lenght<1) alert("Load error. File has no height value.");
return [w,h];
}
/* clearArea
*/
function clearArea() {
document.getElementById('codearea').value="";
document.getElementById('codearea').select();
}
function runMathJax() {
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
}
/*
* Hide/Open menuarea and enlarge/shrink codearea
*/
function enlargeCodearea(t) {
var menus = document.getElementById('menuarea');
var editor = document.getElementById('left-column-editor-area');
var codebox = document.getElementById('codearea');
var arrow_down = document.getElementById('menuarea_hiddener');
var arrow_up = document.getElementById('menuarea_opener');
var exp_height = window.screen.availHeight / 1.3;
if (t==1) {
menus.style.display = "none";
editor.style.height = exp_height+"px";
codebox.rows = "60";
arrow_down.style.display = "none";
arrow_up.style.display = "block";
}
else {
menus.style.display = "block";
editor.style.height = "500px";
codebox.rows = "32";
arrow_down.style.display = "block";
arrow_up.style.display = "none";
}
return true;
}
function switchDollarJSPtoJSP(codearea) {
var code = document.getElementById(codearea).value;
code_to_mem = code;
//alert(varJSPtoNumJSP(code));
document.getElementById(codearea).value = varJSPtoNumJSP(code);
}
function JspCodeAddRows() {
var code = document.getElementById('codearea').value;
code = code.replace(/; /g, ';');
code = code.replace(/;/g, ';\n');
document.getElementById('codearea').value = code;
}
function JspCodeDeleteRows() {
var code = document.getElementById('codearea').value;
code = code.replace(/\n\n/g, '\n');
//code = code.replace(/;/g, ';\n');
code = code.replace('{', '\n {');
code = code.replace('$', '\n $');
document.getElementById('codearea').value = code;
}
/*
* Get value from user selection
* @param {String} id - HTML id of element to check
* @param {String} type - type of HTML element as string
* @return {Boolean} - if type == 'radio' return true if radio/checkbox is checked
* @return {String} - value of selected element i.e. textarea
*/
function getUserVal(id, type) {
if (!type && document.getElementById(id).type == 'checkbox')
type = 'radio';
if (type === 'radio')
return document.getElementById(id).checked;
return document.getElementById(id).value;
}
/*
* clears jsxg images and other stuff from HTML document
* @param {Object} clearlist - list of element ids to set innerHTML = ""
* @param {Object} hidelist - list of element ids to set display:none
* @param {Object} hideclass - list if classnames that will set display none
*/
function clearAll(clearlist, hidelist, hideclass) {
var hide_all_class;
//clear innerHTML
for (var i=0; i<clearlist.length; i++) document.getElementById(clearlist[i]).innerHTML = "";
//hide elements
for (var i=0; i<hidelist.length; i++) document.getElementById(hidelist[i]).style.display = "none";
if (hideclass) {
hide_all_class = document.getElementsByClassName(hideclass);
for (var i=0; i<hide_all_class.length; i++)
hide_all_class[i].style.display = "none";
}
}