// JavaScript Document /* Functions.js by Opagust An introduction to User Tool Development is found here: http://www.noteworthysoftware.com/nwc2/help/intro_usertooldev.htm. This file contains general functions to use in your User Tools. Use this file in combination with 1 of the templates "ClipTextTemplate.js", "File2FileTemplate.js" and "File2TextTemplatejs". */ function QuitError(ErrMsg) { WScript.StdErr.Write(ErrMsg); WScript.quit(1); } // end function QuitError function ShowHelp(){ WScript.StdErr.Write(HelpTxt); WScript.quit(1); } // end function ShowHelpFile function ShowVar(Txt, Val) { if (Testing) { WScript.StdErr.Write(Txt + "==> " + Val+ "\r\n"); } } // end function ShowVar function ProcessPrompts(p) { var userprompt = WScript.Arguments.Item(p); switch (p) { case NPrompts - 1: if (userprompt == "Show"){ RC = 99; break;} if (userprompt == "Help") ShowHelp(); if (userprompt == "Test") {Testing = true; break;} if (userprompt != "Modify") QuitError("Invalid Execution mode '" + userprompt + "'"); // case 0: // case ... } } // End function ProcessPrompts function GetProp(prop){; //ShowVar("GetProp", prop); prop += ":"; var pl = prop.length; for (var p = 2; p < Parts.length; p++) { var head = Parts[p].substr(0,pl); if (head == prop) return(Parts[p].slice(pl)); // prop found } // end for return("*"); // prop not found } // end GetProp function SetProp(prop, op, val){; // prop: property to set // op: operator // val: value //ShowVar("SetProp", prop + op + val); var oldval = GetProp(prop); if (oldval == "*"){ if (op == "add") oldval = "" else if (op != "=") oldval = 0; } // end if var newval; if (op != "=" && op != "add") { oldval = parseInt(oldval); val = parseInt(val); } // end if val = parseInt(oldval); switch (op){ case "=" : newval = val; break; case "+" : newval = oldval + val; break; case "-" : newval = oldval - val; break; case "*" : newval = oldval * val; break; case "/" : newval = oldval / val; break; case "add": if (oldval == "") newval = val; else newval = oldval + "," + val; break; default : QuitError("Invalid operator " + op + " in function SetProp"); } // end switch prop += ":"; var pl = prop.length; for (var p = 2; p < Parts.length; p++) { var head = Parts[p].substr(0,pl); if (head == prop) { // prop found, set val // var oldval = Parts[p].slice(pl); Parts[p] = prop + newval; CurLine = Parts.join("|"); return; } // end if } // end for // prop not found, add prop Parts[Parts.length] = prop + newval; CurLine = Parts.join("|"); return; } // end SetProp function GetLineProp(line, prop){; var parts = new Array(); parts = line.split("|"); prop += ":"; var pl = prop.length; for (var p = 2; p < parts.length; p++) { var head = parts[p].substr(0,pl); if (head == prop) return(parts[p].slice(pl)); // prop found } // end for return("*"); // prop not found } // end GetLineProp function SetLineProp(line, prop, op, val){; var parts = new Array(); parts = line.split("|"); var oldval = GetLineProp(line, prop); if (oldval == "*"){ if (op == "add") oldval = "" else if (op != "=") oldval = 0; } // end if var newval; if (op != "=" && op != "add") { oldval = parseInt(oldval); val = parseInt(val); } // end if val = parseInt(oldval); switch (op){ case "=" : newval = val; break; case "+" : newval = oldval + val; break; case "-" : newval = oldval - val; break; case "*" : newval = oldval * val; break; case "/" : newval = oldval / val; break; case "add": if (oldval == "") newval = val; else newval = oldval + "," + val; break; default : QuitError("Invalid operator " + op + " in function SetLineProp"); } // end switch prop += ":"; var pl = prop.length; for (var p = 2; p < parts.length; p++) { var head = parts[p].substr(0,pl); if (head == prop) { // prop found, set val // var oldval = parts[p].slice(pl); parts[p] = prop + newval; line = parts.join("|"); return(line); } // end if } // end for // prop not found, add prop parts[parts.length] = prop + newval; line = parts.join("|"); return(line); } // end SetLineProp function RemoveProp(prop){; //ShowVar("RemoveProp", prop); prop += ":"; var pl = prop.length; for (var p = 2; p < Parts.length; p++) { var head = Parts[p].substr(0,pl); //ShowVar("head Parts", head); if (head == prop) { // prop found, remove for (var pk = p; pk < pl -1; pk++) { Parts[pk] = Parts[pk+1]; } // end for Parts.length -= 1; CurLine = Parts.join("|"); return; } // end if } // end for return; // prop not found, no action. } // end RemoveProp function GetOpt(opt){; //ShowVar("GetOptt", opt); var optpart = GetProp("Opts"); if (optpart == "*") return("**"); // No Opts present in Current Line. //ShowVar("optpart",optpart); var optarray = optpart.split(","); opt += "="; var ol = opt.length; for (var o = 0; o < optarray.length; o++) { var head = optarray[o].substr(0,ol); //ShowVar("head", head); if (head == opt) return(optarray[o].slice(ol)); // opt found } // end for return("*"); // opt not found } // end GetOpt function SetOpt(opt, op, val){; //ShowVar("SetOpt", opt + op + val); var oldprop = GetOpt(opt); opt += "="; var oldval = oldprop; if ((oldval == "*") || (oldval == "**") && (op != "=")) oldval = 0; var newval; if (op != "=") { oldval = parseInt(oldval); val = parseInt(val); } // end if var newval; switch (op){ case "=" : newval = val; break; case "+" : newval = oldval + val; break; case "-" : newval = oldval - val; break; case "*" : newval = oldval * val; break; case "/" : newval = oldval / val; break; default : QuitError("Invalid operator " + op + " in function SetProp"); } // end switch if (oldprop == "**"){ // no Opts present in Current Line, add Opts. SetProp("Opts", "=", opt + newval) return; } //end if var optpart = GetProp("Opts"); var optarray = optpart.split(","); //ShowVar("optarray", optarray); var ol = opt.length; for (var o = 0; o < optarray.length; o++) { var head = optarray[o].substr(0,ol); //ShowVar("head", head); if (head == opt) { // opt found, modify optarray element optarray[o] = opt + newval; optpart = optarray.join(","); SetProp("Opts", "=", optarray); return; } // end if } // end for // opt not found, add an element to optarray optarray[optarray.length] = opt + newval; optpart = optarray.join(","); SetProp("Opts", "=", optarray); return; } // end SetOpt function RemoveOpt(opt){; //ShowVar("RemoveOpt:", opt); var optpart = GetProp("Opts"); //ShowVar("optpart", optpart); opt += "="; if (optpart == "*") return; // no Opts present in Current Line, no action. var optarray = optpart.split(","); var ol = opt.length; for (var o = 0; o < optarray.length; o++) { var head = optarray[o].substr(0,ol); //ShowVar("head optarray", head); if (head == opt) { // opt found, remove. if (optarray.length == 1) {// only 1 opt, remove Opts in Current Line RemoveProp("Opts"); return; } // end if // more opts present,remove opt in Opts for (var ok = o; ok < optarray.length -1; ok++) { optarray[ok] = optarray[ok+1]; } // end for optarray.length -= 1; optpart = optarray.join(","); SetProp("Opts", "=", optpart); return; } // end if } // end for return; } // end RemoveOpt function InsertItem(array, it){ for(var p = 0; p < array.length; p++) { if (array[p] == it) return; } // end for // pos not found, insert pos array[array.length] = it; } // end InsertItem function InsertItemAt(array, it, at){ for(var p = array.length; p > at; p--) array[p] = array[p-1]; array[at] = it return; } // end InsertItemAt function InsertItemSorted(array, it){ ShowVar ("array before", array); var i = 0; while (i < array.length && it > array[i]) i++; for(var p = array.length; p > i, p--) array[p] = array[p-1]; array[i] = it; ShowVar ("array after", array); return; } // end InsertItemSorted function SearchItem(array, it){ for(var p = 0; p < array.length; p++) { if (array[p] == it) return(p); } // end for // pos not found, return -1 return(-1); } // end SearchItem function RemoveItem (array, it) { var al = array.length for(var p = 0; p < al; p++) { if (array[p] == it) { for (var ak = p; ak < al -1; ak++) { array[ak] = array[ak+1]; } // end for ak array.length -= 1; } // end if } // end for p } // end RemoveItem function RemoveItemAt (array, i) { var al = array.length for (var k = i; k < al -1; k++) { array[k] = array[k+1]; } // end for ak array.length -= 1; } // end RemoveItemAt function DurTimeSig() { // This function returns the duration of a whole measure from a given Time Signature. A number of 768 corresponds with a Time Sig of 4/4. This number is chosnen so that any possible combination with dotted and triplet results in an integer number. if (Parts[1] != "TimeSig") QuitError("Invalid call of function 'DurMeasure'"); tsPart = Parts[2].substr(10,3); if (tsPart == "Com" || tsPart == "All") return 768; // "Common" or "AllaBreve" else { var nums = tsPart.split("/"); var num1 = parseInt(nums[0]); var num2 = parseInt(nums[1]); return(768 * num1 / num2); // Calculate length of measure } } function DurItem(){ // This function returns the duration of note, rest, chord or restchord. A whole note has the duration of 768. This number is chosen so that any possible combination with dotted and triplet results in an integer number. // Special cases: // - a whole note has the duration of the measure (calculated inDurTimeSig). // - a grace note has a duration of zero. var di; if (Parts[1] != "Note" && Parts[1] != "Chord" && Parts[1] != "Rest" && Parts[1] != "RestChord" ) QuitError("Invalid call of function 'DurItem'"); var notelengths = { "16th":48, "32nd":24, "4th":192, "64th":12, "8th":96, "Half":384, "Whole":768 } var durstr = Parts[2].substr(4); var durparts = durstr.split(","); var dur = notelengths[durparts[0]]; if (Parts[1] == "Rest" && dur == 768) dur = TSDur; for (di=1; di < durparts.length; di++) { switch (durparts[di].substr(0,5)){ case "Dotte": dur = dur * 3 / 2; break; case "DblDo": dur = dur * 7 / 4; break; case "Tripl": dur = dur * 2 / 3; break; case "Grace": dur = 0; break; } // end switch } // end for return(dur); } function ModRestPos(nshift){ SetOpt("VertOffset", "+", nshift); return; } // end ModRestPos function ModPositions (nshift) { // This function moves an item (except rests) up or down. var minpos = 999; var maxpos = -999; var posprop = new Array("Pos","Pos2"); for (var pi in posprop){ var pospart = GetProp(posprop[pi]); if (pospart != "*") { var posarray = pospart.split(","); for (var mj=0; mj < posarray.length; mj++) { switch (posarray[mj].substr(0,1)){ case "n": case "b": case "#": case "x": case "v": var ps = 1; break; default: ps = 0; } // end switch var pos = parseInt(posarray[mj].slice(ps)); var newpos= pos+nshift; if (newpos < minpos) minpos = newpos; if (newpos > maxpos) maxpos = newpos; posarray[mj] = posarray[mj].replace(pos,newpos); } // end for mj pospart = posarray.join(","); SetProp(posprop[pi], "=", pospart); } // end if } // end for if(Parts[1] == "RestChord"){ if (maxpos < 0) SetOpt("Stem", "=", "Up"); else { if (minpos > 0) SetOpt("Stem", "=", "Down"); else { var abspos = Math.abs(minpos); if (Math.max(abspos, maxpos) < 0) SetOpt("Stem", "=", "Up"); else SetOpt("Stem", "=", "Down"); } // end else } // end else } // end if } // end ModPositions