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"&lt;"
213case'>':return"&gt;"
214case'&':return"&amp;"
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