1// abc2svg - ABC to SVG translator 2// @source: https://chiselapp.com/user/moinejf/repository/abc2svg 3// Copyright (C) 2014-2020 Jean-Francois Moine - LGPL3+ 4//wps.js 5function isQuoted(V){return V.q} 6function quote(V){V.q=true;return V} 7function unquote(V){delete V.q;return V} 8function Symbol(N){this.nm=N;return this} 9function isSymbol(V){return V&&V.constructor===Symbol} 10function symbolName(V){return V.nm} 11function isArray(V){return V&&V.constructor===Array} 12function inDs(Ds,K){for(var I=Ds.length-1;0<=I;--I){if("undefined"!=typeof Ds[I][K]) 13return Ds[I]} 14return false} 15function member(C,L){return 0<=L.indexOf(C)} 16function PsParser(){var Self=this;function init(L){Self.L=L;Self.N=L.length;Self.I=0;Self.D=0} 17function peek(){return Self.I<Self.N&&Self.L[Self.I]} 18function xchar(){return Self.I<Self.N&&Self.L[Self.I++]} 19function skip(){while(Self.I<Self.N&&member(Self.L[Self.I]," \t\n")) 20Self.I++} 21function comment(){while("%"==peek()){while(peek()&&"\n"!=peek()) 22xchar();skip()}} 23function text(){xchar();var L=[];var N=1;while(0<N&&peek()){var C=xchar();switch(C){case"(":N++;break;case")":N--;if(N<=0)C=false;break;case"\\":C=xchar();switch(C){case"(":break;case")":break;case"\\":break;case"n":C="\n";break;case"r":C="\r";break;case"t":C="\t";break;default:C=false} 24break} 25if(C!==false)L.push(C)} 26return L.join("")} 27function symbol(){var C=xchar();if(member(C,"()<>/% \t\n"))throw new Error("Symbol expected, got "+C);var N=member(C,"+-0123456789.");var F="."==C;var L=[C];while(peek()&&!member(peek(),"()<>[]{}/% \t\n")){C=xchar();L.push(C);if(N&&!member(C,"0123456789")){if(!F&&"."==C)F=true;else N=false}} 28L=L.join("");if(1==L.length&&member(L,"+-."))N=false;return N?(F?parseFloat(L):parseInt(L,10)):new Symbol(L)} 29function token(){skip();switch(peek()){case false:return undefined;case"%":return comment();case"[":return new Symbol(xchar());case"]":return new Symbol(xchar());case"{":Self.D++;return new Symbol(xchar());case"}":Self.D--;return new Symbol(xchar());case"/":xchar();var X=symbol();return quote(X);case"(":return text();case"<":xchar();if("<"!=peek())throw new Error("Encoded strings not implemented yet");xchar();return new Symbol("<<");case">":xchar();if(">"!=peek())throw new Error("Unexpected >");xchar();return new Symbol(">>");default:return symbol()}} 30PsParser.prototype.init=init;PsParser.prototype.peek=peek;PsParser.prototype.token=token;return this} 31function Ps0(Os,Ds,Es){function run(X,Z){if(isSymbol(X)&&!isQuoted(X)){var K=symbolName(X);var D=inDs(Ds,K);if(!D) 32throw new Error("bind error '"+K+"'");Es.push([false,D[K]])}else if(Z&&isArray(X)&&isQuoted(X)){if(0<X.length){var F=X[0];var R=quote(X.slice(1));if(0<R.length)Es.push([false,R]);run(F,false)}}else if("function"==typeof X)X();else Os.push(X)} 33function exec(){var X=Os.pop();run(X,false)} 34function step(){var C=Es.pop();var L=C.shift();var X=C.pop();for(var I=0;I<C.length;I++) 35Os.push(C[I]);run(X,true)} 36var PsP=new PsParser;function parse(L){PsP.init(L);while(PsP.peek()){var T=PsP.token();if(T||T===0){Os.push(T);if(PsP.D<=0||isSymbol(T)&&(member(symbolName(T),"[]{}")||"<<"==symbolName(T)||">>"==symbolName(T))){exec();while(0<Es.length) 37step()}}} 38return Os} 39Ps0.prototype.run=run;Ps0.prototype.exec=exec;Ps0.prototype.step=step;Ps0.prototype.parse=parse;return this} 40function Wps(psvg_i){var psvg=psvg_i;var Os=[];var Sd={};var Ds=[Sd];var Es=[];var Ps=new Ps0(Os,Ds,Es);Sd["true"]=function(){Os.push(true)};Sd["false"]=function(){Os.push(false)};Sd["null"]=function(){Os.push(null)};Sd["sub"]=function(){var X=Os.pop();Os.push(Os.pop()-X)};Sd["mul"]=function(){Os.push(Os.pop()*Os.pop())};Sd["div"]=function(){var X=Os.pop();Os.push(Os.pop()/X)};Sd["mod"]=function(){var X=Os.pop();Os.push(Os.pop()%X)};var M={};Sd["mark"]=function(){Os.push(M)};Sd["counttomark"]=function(){var N=0;for(var I=Os.length-1;0<=I;I--) 41if(M===Os[I])return Os.push(N);else N++;throw new Error("Mark not found")};Sd["<<"]=Sd["mark"];Sd[">>"]=function(){var D={};while(0<Os.length){var V=Os.pop();if(M===V)return Os.push(D);D[Os.pop()]=V} 42throw new Error("Mark not found")};Sd["exch"]=function(){var Y=Os.pop();var X=Os.pop();Os.push(Y);Os.push(X)};Sd["clear"]=function(){Os.length=0};Sd["pop"]=function(){Os.pop()};Sd["index"]=function(){Os.push(Os[Os.length-2-Os.pop()])};Sd["roll"]=function(){var J=Os.pop();var N=Os.pop();var X=[];var Y=[];if(J<0) 43J=N+J 44for(var I=0;I<N;I++) 45if(I<J)X.unshift(Os.pop());else Y.unshift(Os.pop());for(I=0;I<J;I++)Os.push(X.shift());for(I=0;I<N-J;I++)Os.push(Y.shift())};Sd["copy"]=function(){var N=Os.pop();if("object"==typeof N){var X=Os.pop();for(var I in X) 46N[I]=X[I];Os.push(N)}else{var X=Os.length-N;for(var I=0;I<N;I++) 47Os.push(Os[X+I])}};Sd["length"]=function(){Os.push(Os.pop().length)};Sd["astore"]=function(){var A=Os.pop();var N=A.length;for(var I=N-1;0<=I;I--) 48A[I]=Os.pop();Os.push(A)};Sd["array"]=function(){Os.push(new Array(Os.pop()))};Sd["eq"]=function(){var Y=Os.pop();var X=Os.pop();Os.push(X==Y)};Sd["lt"]=function(){var Y=Os.pop();var X=Os.pop();Os.push(X<Y)};Sd["ifelse"]=function(){var N=Os.pop();var P=Os.pop();var C=Os.pop();Es.push([false,C===true?P:N])};Sd["and"]=function(){var A=Os.pop();var B=Os.pop();if(true===A||false===A){Os.push(A==true&&B===true) 49return} 50Os.push(A&B)} 51Sd["repeat"]=function Xrepeat(){var B=Os.pop();var N=Os.pop();if(1<N)Es.push([true,N-1,B,Xrepeat]);if(0<N)Es.push([false,B])};Sd["for"]=function Xfor(){var B=Os.pop();var L=Os.pop();var K=Os.pop();var J=Os.pop();if(K<0){if(L<=J+K)Es.push([true,J+K,K,L,B,Xfor]);if(L<=J)Es.push([false,J,B])}else{if(J+K<=L)Es.push([true,J+K,K,L,B,Xfor]);if(J<=L)Es.push([false,J,B])}};Sd["exec"]=function(){Es.push([false,Os.pop()])};Sd["cvx"]=function(){var X=Os.pop();if(isSymbol(X)&&isQuoted(X))Os.push(unquote(X));else if(isArray(X)&&!isQuoted(X))Os.push(quote(X));else Os.push(X)};Sd["dict"]=function(){Os.pop();Os.push({})};Sd["get"]=function(){var K=Os.pop();var D=Os.pop();if(isSymbol(K))Os.push(D[symbolName(K)]);else Os.push(D[K])};Sd["getinterval"]=function(){var N=Os.pop(),K=Os.pop()+N,D=Os.pop(),A=[] 52while(--N>=0) 53A.push(D[K++]) 54Os.push(A)};Sd["put"]=function(){var V=Os.pop();var K=Os.pop();var D=Os.pop();if(isSymbol(K))D[symbolName(K)]=V;else D[K]=V};Sd["begin"]=function(){Ds.push(Os.pop())};Sd["end"]=function(){Ds.pop()};Sd["currentdict"]=function(){Os.push(Ds[Ds.length-1])};Sd["where"]=function(){var K=symbolName(Os.pop());var D=inDs(Ds,K);if(D){Os.push(D);Os.push(true)}else Os.push(false)};Sd["save"]=function(){var X=Ds.slice();for(var I=0;I<X.length;I++){var A=X[I];var B={};for(var J in A) 55B[J]=A[J];X[I]=B} 56Os.push(X)};Sd["restore"]=function(){var X=Os.pop();while(0<Ds.length) 57Ds.pop();while(0<X.length) 58Ds.unshift(X.pop())};Sd["type"]=function(){var A=Os.pop();var X;if(null===A)X="nulltype";else if(true===A||false===A)X="booleantype";else if(M===A)X="marktype";else if("string"==typeof A)X="stringtype";else if(isSymbol(A))X=isQuoted(A)?"nametype":"operatortype";else if("function"==typeof A)X="operatortype";else if(isArray(A))X="arraytype";else if("object"==typeof A)X="dicttype";else if(1*A==A)X=A%1==0?"integertype":"realtype";else throw new Error("Undefined type '"+A+"'");Os.push(X)};var Sb=true;Sd[".strictBind"]=function(){Sb=true===Os.pop()};Sd["bind"]=function(){Os.push(bind(Os.pop()))};function bind(X){if(isSymbol(X)&&!isQuoted(X)){return X}else if(isArray(X)&&isQuoted(X)){var N=X.length;var A=[];for(var I=0;I<N;I++){var Xi=X[I];var Xb=bind(Xi);if(isArray(Xi)) 59A=A.concat(isQuoted(Xi)?quote([Xb]):[Xb]);else 60A=A.concat(Xb)} 61return quote(A)} 62return X} 63Sd["="]=function(){var X=Os.pop();alert(X&&X.nm||X)};Sd["=="]=function(){alert(Os.pop())};Sd["stack"]=function(){alert(Os)};Sd["pstack"]=function(){alert(Os)};Sd[".call"]=function(){var N=Os.pop();var K=Os.pop();var D=Os.pop();var X=[];for(var I=0;I<N;I++)X.unshift(Os.pop());if(!D[K])throw new Error(".call: "+K+" undef") 64Os.push(D[K].apply(D,X))};Sd[".call0"]=function(){var N=Os.pop(),K=Os.pop(),D=Os.pop(),X=[] 65for(var I=0;I<N;I++)X.unshift(Os.pop());if(!D[K])throw new Error(".call0: "+K+" undef") 66D[K].apply(D,X)};Sd[".svg"]=function(){Os.push(psvg)};Sd[".math"]=function(){Os.push(Math)};Sd[".date"]=function(){Os.push(new Date())};Sd[".window"]=function(){Os.push(window)};Sd[".callback"]=function(){var X=Os.pop();Os.push(function(){Ps.run(X,true);while(0<Es.length) 67Ps.step()})};Sd[".minv"]=function(){var M=Os.pop();var a=M[0];var b=M[1];var d=M[2];var e=M[3];var g=M[4];var h=M[5];Os.push([e,b,d,a,d*h-e*g,b*g-a*h])};Sd[".mmul"]=function(){var B=Os.pop();var A=Os.pop();var a=A[0];var b=A[1];var d=A[2];var e=A[3];var g=A[4];var h=A[5];var r=B[0];var s=B[1];var u=B[2];var v=B[3];var x=B[4];var y=B[5];Os.push([a*r+b*u,a*s+b*v,d*r+e*u,d*s+e*v,g*r+h*u+x,g*s+h*v+y])};Sd[".xy"]=function(){var M=Os.pop();var Y=Os.pop();var X=Os.pop();Os.push(M[0]*X+M[2]*Y+M[4]);Os.push(M[1]*X+M[3]*Y+M[5])};Sd[".rgb"]=function(){var B=Os.pop();var G=Os.pop();var R=Os.pop();Os.push("rgb("+R+","+G+","+B+")")};Sd[".rgba"]=function(){var A=Os.pop();var B=Os.pop();var G=Os.pop();var R=Os.pop();Os.push("rgba("+R+","+G+","+B+","+A+")")};function parse(){var T=arguments;if(T.length) 68for(var I=0;I<T.length;I++) 69Ps.parse(T[I]);else Ps.parse(T);return Os} 70Wps.prototype.parse=parse;return this} 71function Psvg(abcobj_r){var svgbuf='',abcobj=abcobj_r,wps=new Wps(this),g=0,gchg,gcur={cx:0,cy:0,xoffs:0,yoffs:0,xscale:1,yscale:1,rotate:0,sin:0,cos:1,linewidth:0.7,dash:''},gc_stack=[],x_rot=0,y_rot=0,font_n="",font_n_old="",font_s=0,path;function getorig(){setg(0);return[gcur.xoffs-gcur.xorig,gcur.yoffs-gcur.yorig]} 72function defg1(){gchg=false;setg(0);svgbuf+="<g" 73if(gcur.xscale!=1||gcur.yscale!=1||gcur.rotate){svgbuf+=' transform="' 74if(gcur.xscale!=1||gcur.yscale!=1){if(gcur.xscale==gcur.yscale) 75svgbuf+="scale("+gcur.xscale.toFixed(3)+")" 76else 77svgbuf+="scale("+gcur.xscale.toFixed(3)+","+gcur.yscale.toFixed(3)+")"} 78if(gcur.rotate){if(gcur.xoffs||gcur.yoffs){var x,xtmp=gcur.xoffs,y=gcur.yoffs,_sin=gcur.sin,_cos=gcur.cos;x=xtmp*_cos-y*_sin;y=xtmp*_sin+y*_cos;svgbuf+=" translate("+x.toFixed(1)+","+ 79y.toFixed(1)+")";x_rot=gcur.xoffs;y_rot=gcur.yoffs;gcur.xoffs=0;gcur.yoffs=0} 80svgbuf+=" rotate("+gcur.rotate.toFixed(2)+")"} 81svgbuf+='"'} 82output_font(false) 83if(gcur.rgb) 84svgbuf+=' style="color:'+gcur.rgb+'"';svgbuf+=">\n";g=1} 85function objdup(obj){var k,tmp=new obj.constructor() 86for(k in obj) 87if(obj.hasOwnProperty(k)) 88tmp[k]=obj[k] 89return tmp} 90function output_font(back){var name=gcur.font_n 91if(!name) 92return 93var prop="",i=name.indexOf("Italic"),j=100,o=name.indexOf("Oblique"),b=name.indexOf("Bold"),flags=0 94if(b>0){prop=' font-weight="bold"';j=b;flags=2} 95if(i>0||o>0){if(i>0){prop+=' font-style="italic"';if(i<j) 96j=i;flags|=4} 97if(o>0){prop+=' font-style="oblique"';if(o<j) 98j=o;flags=8}} 99if(j!=100){if(name[j-1]=='-') 100j--;name=name.slice(0,j)} 101if(back){if(!(flags&2)&&font_n_old.indexOf("Bold")>=0) 102prop+=' font-weight="normal"';if(!(flags&12)&&(font_n_old.indexOf("Italic")>=0||font_n_old.indexOf("Oblique")>=0)) 103prop+=' font-style="normal"'} 104svgbuf+=' font-family="'+name+'"'+ 105prop+' font-size="'+gcur.font_s+'"'} 106function path_def(){if(path) 107return 108setg(1);gcur.px=gcur.cx;gcur.py=gcur.cy;path='<path d="m'+(gcur.xoffs+gcur.cx).toFixed(1)+' '+(gcur.yoffs-gcur.cy).toFixed(1)+'\n'} 109function path_end(){svgbuf+=path;path=''} 110function setg(newg){if(g==2){svgbuf+="</text>\n";g=1} 111if(newg==0){if(g){g=0;svgbuf+="</g>\n" 112if(gcur.rotate){gcur.xoffs=x_rot;gcur.yoffs=y_rot;x_rot=0;y_rot=0}}}else if(gchg){defg1()}} 113function strw(s){return s.length*gcur.font_s*0.5} 114Psvg.prototype.strw=strw;function arc(x,y,r,a1,a2,arcn){var x1,y1,x2,y2 115if(a1>=360) 116a1-=360 117if(a2>=360) 118a2-=360;x1=x+r*Math.cos(a1*Math.PI/180);y1=y+r*Math.sin(a1*Math.PI/180) 119if(gcur.cx!=undefined){if(path){if(x1!=gcur.cx||y1!=gcur.cy) 120path+='l' 121else 122path+='m';path+=(x1-gcur.cx).toFixed(1)+" "+ 123(-(y1-gcur.cy)).toFixed(1)}else{gcur.cx=x1;gcur.cy=y1;path_def()}}else{if(path) 124path='' 125gcur.cx=x1;gcur.cy=y1;path_def()} 126if(a1==a2){a2=180-a1;x2=x+r*Math.cos(a2*Math.PI/180);y2=y+r*Math.sin(a2*Math.PI/180);path+='a'+r.toFixed(2)+' '+r.toFixed(2)+' 0 0 '+ 127(arcn?'1 ':'0 ')+ 128(x2-x1).toFixed(2)+' '+ 129(y1-y2).toFixed(2)+' '+ 130r.toFixed(2)+' '+r.toFixed(2)+' 0 0 '+ 131(arcn?'1 ':'0 ')+ 132(x1-x2).toFixed(2)+' '+ 133(y2-y1).toFixed(2)+'\n';gcur.cx=x1;gcur.cy=y1}else{x2=x+r*Math.cos(a2*Math.PI/180);y2=y+r*Math.sin(a2*Math.PI/180);path+='a'+r.toFixed(2)+' '+r.toFixed(2)+' 0 0 '+ 134(arcn?'1 ':'0 ')+ 135(x2-x1).toFixed(2)+' '+ 136(y1-y2).toFixed(2)+'\n';gcur.cx=x2;gcur.cy=y2}} 137Psvg.prototype.arc=arc 138Psvg.prototype.arcn=function(x,y,r,a1,a2){arc(x,y,r,a1,a2,true)} 139Psvg.prototype.closepath=function(){if(path&&gcur.cx) 140rlineto(gcur.px-gcur.cx,gcur.py-gcur.cy)} 141Psvg.prototype.cx=function(){return gcur.cx} 142Psvg.prototype.cy=function(){return gcur.cy} 143Psvg.prototype.curveto=function(x1,y1,x2,y2,x,y){path_def();path+="\tC"+ 144(gcur.xoffs+x1).toFixed(1)+" "+(gcur.yoffs-y1).toFixed(1)+" "+ 145(gcur.xoffs+x2).toFixed(1)+" "+(gcur.yoffs-y2).toFixed(1)+" "+ 146(gcur.xoffs+x).toFixed(1)+" "+(gcur.yoffs-y).toFixed(1)+"\n";gcur.cx=x;gcur.cy=y} 147Psvg.prototype.eofill=function(){path_end();svgbuf+='" fill-rule="evenodd" fill="currentColor"/>\n'} 148Psvg.prototype.fill=function(){path_end();svgbuf+='" fill="currentColor"/>\n'} 149Psvg.prototype.gsave=function(){gc_stack.push(objdup(gcur))} 150Psvg.prototype.grestore=function(){gcur=gc_stack.pop();gchg=true} 151Psvg.prototype.lineto=function(x,y){path_def() 152if(x==gcur.cx) 153path+="\tv"+(gcur.cy-y).toFixed(1)+"\n" 154else if(y==gcur.cy) 155path+="\th"+(x-gcur.cx).toFixed(1)+"\n" 156else 157path+="\tl"+(x-gcur.cx).toFixed(1)+" "+ 158(gcur.cy-y).toFixed(1)+"\n";gcur.cx=x;gcur.cy=y} 159Psvg.prototype.moveto=function(x,y){gcur.cx=x;gcur.cy=y 160if(path){path+="\tM"+(gcur.xoffs+gcur.cx).toFixed(1)+" "+ 161(gcur.yoffs-gcur.cy).toFixed(1)+"\n"}else if(g==2){svgbuf+="</text>\n";g=1}} 162Psvg.prototype.newpath=function(){gcur.cx=gcur.cy=undefined} 163Psvg.prototype.rcurveto=function(x1,y1,x2,y2,x,y){path_def();path+="\tc"+ 164x1.toFixed(1)+" "+(-y1).toFixed(1)+" "+ 165x2.toFixed(1)+" "+(-y2).toFixed(1)+" "+ 166x.toFixed(1)+" "+(-y).toFixed(1)+"\n";gcur.cx+=x;gcur.cy+=y} 167function rlineto(x,y){path_def() 168if(x==0) 169path+="\tv"+(-y).toFixed(1)+"\n" 170else if(y==0) 171path+="\th"+x.toFixed(1)+"\n" 172else 173path+="\tl"+x.toFixed(1)+" "+ 174(-y).toFixed(1)+"\n";gcur.cx+=x;gcur.cy+=y} 175Psvg.prototype.rlineto=rlineto;Psvg.prototype.rmoveto=function(x,y){if(path){path+="\tm"+x.toFixed(1)+" "+ 176(-y).toFixed(1)+"\n"}else if(g==2){svgbuf+="</text>\n";g=1} 177gcur.cx+=x;gcur.cy+=y} 178Psvg.prototype.rotate=function(a){setg(0) 179var x,xtmp=gcur.xoffs,y=gcur.yoffs,_sin=gcur.sin,_cos=gcur.cos;x=xtmp*_cos-y*_sin;y=xtmp*_sin+y*_cos;gcur.xoffs=x/gcur.xscale;gcur.yoffs=y/gcur.yscale;xtmp=gcur.cx;y=gcur.cy;x=xtmp*_cos-y*_sin;y=-xtmp*_sin+y*_cos;gcur.cx=x/gcur.xscale;gcur.cy=y/gcur.yscale;a=360-a;gcur.rotate+=a 180if(gcur.rotate>180) 181gcur.rotate-=360 182else if(gcur.rotate<=-180) 183gcur.rotate+=360 184a=gcur.rotate*Math.PI/180;gcur.sin=_sin=Math.sin(a);gcur.cos=_cos=Math.cos(a);x=gcur.cx;gcur.cx=(x*_cos+gcur.cy*_sin)*gcur.xscale;gcur.cy=(-x*_sin+gcur.cy*_cos)*gcur.yscale;x=gcur.xoffs;gcur.xoffs=(x*_cos+gcur.yoffs*_sin)*gcur.xscale;gcur.yoffs=(-x*_sin+gcur.yoffs*_cos)*gcur.yscale;gchg=true} 185Psvg.prototype.scale=function(sx,sy){gcur.xoffs/=sx;gcur.yoffs/=sy;gcur.cx/=sx;gcur.cy/=sy;gcur.xscale*=sx;gcur.yscale*=sy;gchg=true} 186Psvg.prototype.selectfont=function(s,h){s=s.nm;if(font_s!=h||s!=font_n){gcur.font_n_old=gcur.font_n;gcur.font_n=s;gcur.font_s=h;gchg=true}} 187Psvg.prototype.setdash=function(a,o){var n=a.length,i 188if(n==0){gcur.dash='' 189return} 190gcur.dash=' stroke-dashoffset="'+o+'" stroke-dasharray="';i=0 191while(1){gcur.dash+=a[i] 192if(--n==0) 193break 194gcur.dash+=' '} 195gcur.dash+='"'} 196Psvg.prototype.setlinewidth=function(w){gcur.linewidth=w} 197Psvg.prototype.setrgbcolor=function(r,g,b){var rgb=0x1000000+ 198(Math.floor(r*255)<<16)+ 199(Math.floor(g*255)<<8)+ 200Math.floor(b*255);rgb=rgb.toString(16);rgb=rgb.replace('1','#') 201if(rgb!=gcur.rgb){gcur.rgb=rgb;gchg=true}} 202Psvg.prototype.show=function(s){var span,x,y 203if(gchg){if(g==2) 204span=true 205else 206defg1()} 207x=gcur.cx;y=gcur.cy 208if(span){svgbuf+="<tspan\n\t";output_font(true);svgbuf+=">"}else if(g!=2){if(!g) 209defg1() 210svgbuf+='<text x="'+(x+gcur.xoffs).toFixed(1)+'" y="'+ 211(gcur.yoffs-y).toFixed(1)+'">';g=2} 212svgbuf+=s.replace(/<|>|&| /g,function(c){switch(c){case'<':return"<" 213case'>':return">" 214case'&':return"&" 215case' ':return' '}}) 216if(span) 217svgbuf+="</tspan>";gcur.cx=x+strw(s)} 218Psvg.prototype.stroke=function(){path_end() 219if(gcur.linewidth!=0.7) 220svgbuf+='" stroke-width="'+gcur.linewidth.toFixed(1);svgbuf+='" stroke="currentColor" fill="none"'+gcur.dash+'/>\n'} 221Psvg.prototype.translate=function(x,y){gcur.xoffs+=x;gcur.yoffs-=y;gcur.cx-=x;gcur.cy-=y} 222Psvg.prototype.arp=function(val,x,y){var xy=getorig();ps_flush();abcobj.out_arp((x+xy[0])*abcobj.stv_g().scale,y-xy[1],val)} 223Psvg.prototype.ltr=function(val,x,y){var xy=getorig();ps_flush();abcobj.out_ltr((x+xy[0])*abcobj.stv_g().scale,y-xy[1],val)} 224Psvg.prototype.xygl=function(x,y,gl){var xy=getorig();ps_flush();abcobj.xygl((x+xy[0])*abcobj.stv_g().scale,y-xy[1],gl)} 225Psvg.prototype.xygls=function(str,x,y,gl){var xy=getorig();ps_flush();abcobj.out_deco_str((x+xy[0])*abcobj.stv_g().scale,y-xy[1],gl,str)} 226Psvg.prototype.xyglv=function(val,x,y,gl){var xy=getorig();ps_flush();abcobj.out_deco_val((x+xy[0])*abcobj.stv_g().scale,y-xy[1],gl,val)} 227Psvg.prototype.y0=function(y){var staff_tb=abcobj.get_staff_tb() 228return y+staff_tb[0].y} 229Psvg.prototype.y1=function(y){var staff_tb=abcobj.get_staff_tb() 230return y+staff_tb[1].y} 231function ps_flush(g0){if(g0) 232setg(0);if(!svgbuf) 233return 234abcobj.out_svg(svgbuf);svgbuf=''} 235Psvg.prototype.ps_flush=ps_flush 236Psvg.prototype.ps_eval=function(txt){wps.parse(txt);ps_flush(true)} 237function pscall(f,x,y,script){gcur.xorig=gcur.xoffs=abcobj.sx(0);gcur.yorig=gcur.yoffs=abcobj.sy(0);gcur.cx=0;gcur.cy=0;wps.parse(script+ 238(x/abcobj.stv_g().scale).toFixed(1)+' '+y.toFixed(1)+' '+f);ps_flush(true) 239return true} 240Psvg.prototype.psdeco=function(f,x,y,de){var dd,de2,script,defl,Os=wps.parse('/'+f+' where'),A=Os.pop(),staff_tb=abcobj.get_staff_tb() 241if(!A) 242return false;defl=0 243if(de.defl.nost) 244defl=1 245if(de.defl.noen) 246defl|=2 247if(de.s.stem>=0) 248defl|=4;Os.pop();script='/defl '+defl+' def ' 249if(de.lden){script+=x.toFixed(1)+' '+y.toFixed(1)+' ';de2=de.start;x=de2.x;y=de2.y+staff_tb[de2.st].y 250if(x>de.x-20) 251x=de.x-20} 252dd=de.dd 253if(de.has_val){script+=de.val+' '}else if(dd.str){script+='('+dd.str+') ';y+=dd.h*0.2} 254return pscall(f,x,y,script)} 255Psvg.prototype.psxygl=function(x,y,gl){var Os=wps.parse('/'+gl+' where'),A=Os.pop() 256if(!A) 257return false 258Os.pop() 259return pscall(gl,x,y,'dlw ')} 260Psvg.prototype.svgcall=function(f,x,y,v1,v2){var xy=getorig();ps_flush();f((x+xy[0])*abcobj.stv_g().scale,y-xy[1],v1,v2)} 261wps.parse("\ 262currentdict/systemdict currentdict put\n\ 263systemdict/{/mark cvx put\n\ 264systemdict/[/mark cvx put\n\ 265systemdict/]\n\ 266/counttomark cvx\n\ 267/array cvx\n\ 268/astore cvx\n\ 269/exch cvx\n\ 270/pop cvx\n\ 2715 array astore cvx put\n\ 272systemdict/}/] cvx/cvx cvx 2 array astore cvx put\n\ 273systemdict/def{currentdict 2 index 2 index put pop pop}put\n\ 274\n\ 275/maxlength 1000 def % TODO\n\ 276/.bdef{bind def}bind def\n\ 277/.xdef{exch def}.bdef\n\ 278/dup{0 index}.bdef\n\ 279/load{dup where pop exch get}.bdef\n\ 280/.ldef{load def}.bdef\n\ 281/if{{}ifelse}.bdef\n\ 282/cleartomark{array pop}.bdef\n\ 283/known{exch begin where{currentdict eq}{false}if end}.bdef\n\ 284/store{1 index where{3 1 roll put}{def}ifelse}.bdef\n\ 285/not{{false}{true}ifelse}.bdef\n\ 286%/.logand{{{true}{false}ifelse}{pop false}ifelse}.bdef\n\ 287%/and/.logand .ldef % TODO numeric and\n\ 288/.logor{{pop true}{{true}{false}ifelse}ifelse}.bdef\n\ 289/or/.logor .ldef % TODO numeric or\n\ 290/ne{eq not}.bdef\n\ 291/ge{lt not}.bdef\n\ 292/le{1 index 1 index eq 3 1 roll lt or}.bdef\n\ 293/gt{le not}.bdef\n\ 294/.repeat{1 1 4 2 roll for}.bdef\n\ 295\n\ 296%% math\n\ 297\n\ 298/floor{.math(floor)1 .call}.bdef\n\ 299\n\ 300/neg{0 exch sub}.bdef\n\ 301/add{neg sub}.bdef\n\ 302/idiv{div floor}.bdef\n\ 303\n\ 304/.pi{.math(PI)get}.bdef\n\ 305\n\ 306/abs{.math(abs)1 .call}.bdef\n\ 307%/.acos{.math(acos)1 .call}.bdef\n\ 308%/.asin{.math(asin)1 .call}.bdef\n\ 309/atan{.math(atan2)2 .call 180 mul .pi div}.bdef\n\ 310%/.atan2{.math(atan2)2 .call}.bdef\n\ 311%/ceiling{.math(ceil)1 .call}.bdef\n\ 312/cos{.pi mul 180 div .math(cos)1 .call}.bdef\n\ 313%/.exp{.math(exp)1 .call}.bdef\n\ 314%/log{.math(log)1 .call}.bdef\n\ 315%/.max{.math(max)2 .call}.bdef\n\ 316%/.min{.math(min)2 .call}.bdef\n\ 317%/.pow{.math(pow)2 .call}.bdef\n\ 318%/.random{.math(random)0 .call}.bdef\n\ 319%/rand{.random}.bdef % TODO follow spec\n\ 320%/round{.math(round)1 .call}.bdef\n\ 321%/sin{.math(sin)1 .call}.bdef\n\ 322%/sqrt{.math(sqrt)1 .call}.bdef\n\ 323%/.tan{.math(tan)1 .call}.bdef\n\ 324%/truncate{.math(truncate)1 .call}.bdef % TODO Math.truncate does not exist!\n\ 325\n\ 326% graphic\n\ 327/arc{.svg(arc)5 .call0}.bdef\n\ 328/arcn{.svg(arcn)5 .call0}.bdef\n\ 329/closepath{.svg(closepath)0 .call}.bdef\n\ 330/currentpoint{.svg(cx)0 .call .svg(cy)0 .call}.bdef\n\ 331/curveto{.svg(curveto)6 .call0}.bdef\n\ 332/eofill{.svg(eofill)0 .call0}.bdef\n\ 333/fill{.svg(fill)0 .call0}.bdef\n\ 334/grestore{.svg(grestore)0 .call0}.bdef\n\ 335/gsave{.svg(gsave)0 .call0}.bdef\n\ 336/lineto{.svg(lineto)2 .call0}.bdef\n\ 337/moveto{.svg(moveto)2 .call0}.bdef\n\ 338/newpath{.svg(newpath)0 .call0}.bdef\n\ 339/rcurveto{.svg(rcurveto)6 .call0}.bdef\n\ 340/rlineto{.svg(rlineto)2 .call0}.bdef\n\ 341/rmoveto{.svg(rmoveto)2 .call0}.bdef\n\ 342/rotate{.svg(rotate)1 .call0}.bdef\n\ 343/scale{.svg(scale)2 .call0}.bdef\n\ 344/selectfont{.svg(selectfont)2 .call0}.bdef\n\ 345/setdash{.svg(setdash)2 .call0}.bdef\n\ 346/setlinewidth{.svg(setlinewidth)1 .call0}.bdef\n\ 347/setrgbcolor{.svg(setrgbcolor)3 .call0}.bdef\n\ 348/show{.svg(show)1 .call0}.bdef\n\ 349/stroke{.svg(stroke)0 .call0}.bdef\n\ 350/stringwidth{.svg(strw)1 .call 1}.bdef %fixme: height KO\n\ 351/translate{.svg(translate)2 .call0}.bdef\n\ 352\n\ 353/setgray{255 mul dup dup setrgbcolor}.bdef\n\ 354% abcm2ps syms.c\n\ 355/!{bind def}bind def\n\ 356/T/translate load def\n\ 357/M/moveto load def\n\ 358/RM/rmoveto load def\n\ 359/L/lineto load def\n\ 360/RL/rlineto load def\n\ 361/C/curveto load def\n\ 362/RC/rcurveto load def\n\ 363/SLW/setlinewidth load def\n\ 364/defl 0 def\n\ 365/dlw{0.7 SLW}!\n\ 366/xymove{/x 2 index def/y 1 index def M}!\n\ 367/showc{dup stringwidth pop .5 mul neg 0 RM show}!\n\ 368%\n\ 369% abcm2ps internal glyphs\n\ 370/arp{.svg(arp)3 .call0}.bdef\n\ 371/ltr{.svg(ltr)3 .call0}.bdef\n\ 372/ft0{(acc-1).svg(xygl)3 .call0}.bdef\n\ 373/nt0{(acc3).svg(xygl)3 .call0}.bdef\n\ 374/sh0{(acc1).svg(xygl)3 .call0}.bdef\n\ 375/dsh0{(acc2).svg(xygl)3 .call0}.bdef\n\ 376/trl{(trl).svg(xygl)3 .call0}.bdef\n\ 377/lmrd{(lmrd).svg(xygl)3 .call0}.bdef\n\ 378/turn{(turn).svg(xygl)3 .call0}.bdef\n\ 379/umrd{(umrd).svg(xygl)3 .call0}.bdef\n\ 380/y0{.svg(y0)1 .call}.bdef\n\ 381/y1{.svg(y1)1 .call}.bdef\n")} 382abc2svg.psvg={do_begin_end:function(of,type,opt,text){if(type!="ps"){of(type,opt,text) 383return} 384if(opt=='nosvg') 385return 386if(!this.psvg) 387this.psvg=new Psvg(this);this.psvg.ps_eval.call(this.psvg,text)},psdeco:function(of,f,x,y,de){if(!this.psvg) 388return false 389return this.psvg.psdeco.call(this.psvg,f,x,y,de)},psxygl:function(of,x,y,gl){if(!this.psvg) 390return false 391return this.psvg.psxygl.call(this.psvg,x,y,gl)},set_hooks:function(abc){abc.do_begin_end=abc2svg.psvg.do_begin_end.bind(abc,abc.do_begin_end);abc.psdeco=abc2svg.psvg.psdeco.bind(abc,abc.psdeco);abc.psxygl=abc2svg.psvg.psxygl.bind(abc,abc.psxygl)}} 392abc2svg.modules.hooks.push(abc2svg.psvg.set_hooks);abc2svg.modules.beginps.loaded=true 393