// abc2svg - ABC to SVG translator // @source: https://chiselapp.com/user/moinejf/repository/abc2svg // Copyright (C) 2014-2023 Jean-Francois Moine - LGPL3+ //abc2svg-abc2svg.js if(typeof abc2svg=="undefined") var abc2svg={};abc2svg.C={BLEN:1536,BAR:0,CLEF:1,CUSTOS:2,SM:3,GRACE:4,KEY:5,METER:6,MREST:7,NOTE:8,PART:9,REST:10,SPACE:11,STAVES:12,STBRK:13,TEMPO:14,BLOCK:16,REMARK:17,FULL:0,EMPTY:1,OVAL:2,OVALBARS:3,SQUARE:4,SL_ABOVE:0x01,SL_BELOW:0x02,SL_AUTO:0x03,SL_HIDDEN:0x04,SL_DOTTED:0x08,SL_ALI_MSK:0x70,SL_ALIGN:0x10,SL_CENTER:0x20,SL_CLOSE:0x40};abc2svg.sym_name=['bar','clef','custos','smark','grace','key','meter','Zrest','note','part','rest','yspace','staves','Break','tempo','','block','remark'] abc2svg.keys=[new Int8Array([-1,-1,-1,-1,-1,-1,-1]),new Int8Array([-1,-1,-1,0,-1,-1,-1]),new Int8Array([0,-1,-1,0,-1,-1,-1]),new Int8Array([0,-1,-1,0,0,-1,-1]),new Int8Array([0,0,-1,0,0,-1,-1]),new Int8Array([0,0,-1,0,0,0,-1]),new Int8Array([0,0,0,0,0,0,-1]),new Int8Array([0,0,0,0,0,0,0]),new Int8Array([0,0,0,1,0,0,0]),new Int8Array([1,0,0,1,0,0,0]),new Int8Array([1,0,0,1,1,0,0]),new Int8Array([1,1,0,1,1,0,0]),new Int8Array([1,1,0,1,1,1,0]),new Int8Array([1,1,1,1,1,1,0]),new Int8Array([1,1,1,1,1,1,1])] abc2svg.p_b40=new Int8Array([2,8,14,19,25,31,37]) abc2svg.b40_p=new Int8Array([0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6]) abc2svg.b40_a=new Int8Array([-2,-1,0,1,2,-3,-2,-1,0,1,2,-3,-2,-1,0,1,2,-2,-1,0,1,2,-3,-2,-1,0,1,2,-3,-2,-1,0,1,2,-3,-2,-1,0,1,2]) abc2svg.b40_m=new Int8Array([-2,-1,0,1,2,0,0,1,2,3,4,0,2,3,4,5,6,3,4,5,6,7,0,5,6,7,8,9,0,7,8,9,10,11,0,9,10,11,12,13]) abc2svg.b40k=new Int8Array([36,1,2,3,8,2,2,7,8,13,14,2,8,13,14,19,20,13,14,19,20,25,2,19,24,25,30,31,2,25,30,31,36,37,2,31,36,37,42,43]) abc2svg.b40sf=new Int8Array([-2,-7,0,7,2,88,0,-5,2,-3,4,88,2,-3,4,-1,6,-3,4,-1,6,1,88,-1,-6,1,-4,3,88,1,-4,3,-2,5,88,3,-2,5,0,7]) abc2svg.isb40=new Int8Array([0,1,6,11,12,17,18,23,28,29,34,35]) abc2svg.pab40=function(p,a){p+=19 var b40=((p/7)|0)*40+abc2svg.p_b40[p%7] if(a&&a!=3) b40+=a return b40} abc2svg.b40p=function(b){return((b/40)|0)*7+abc2svg.b40_p[b%40]-19} abc2svg.b40a=function(b){return abc2svg.b40_a[b%40]} abc2svg.b40m=function(b){return((b/40)|0)*12+abc2svg.b40_m[b%40]} abc2svg.ch_alias={"maj":"","min":"m","-":"m","°":"dim","+":"aug","+5":"aug","maj7":"M7","Δ7":"M7","Δ":"M7","min7":"m7","-7":"m7","ø7":"m7b5","°7":"dim7","min+7":"m+7","aug7":"+7","7+5":"+7","7#5":"+7","sus":"sus4","7sus":"7sus4"} abc2svg.font_tb=[] abc2svg.font_st={} abc2svg.ft_w={thin:100,extralight:200,light:300,regular:400,medium:500,semi:600,demi:600,semibold:600,demibold:600,bold:700,extrabold:800,ultrabold:800,black:900,heavy:900} abc2svg.ft_re=new RegExp('\ -?Thin|-?Extra Light|-?Light|-?Regular|-?Medium|\ -?[DS]emi|-?[DS]emi[ -]?Bold|\ -?Bold|-?Extra[ -]?Bold|-?Ultra[ -]?Bold|-?Black|-?Heavy/',"i") abc2svg.rat=function(n,d){var a,t,n0=0,d1=0,n1=1,d0=1 while(1){if(d==0) break t=d a=(n/d)|0 d=n%d n=t t=n0+a*n1 n0=n1 n1=t t=d0+a*d1 d0=d1 d1=t} return[n1,d1]} abc2svg.pitcmp=function(n1,n2){return n1.pit-n2.pit} abc2svg.Abc=function(user){"use strict";var C=abc2svg.C;var require=empty_function,system=empty_function,write=empty_function,XMLHttpRequest=empty_function;var OPEN_BRACE=0x01,CLOSE_BRACE=0x02,OPEN_BRACKET=0x04,CLOSE_BRACKET=0x08,OPEN_PARENTH=0x10,CLOSE_PARENTH=0x20,STOP_BAR=0x40,FL_VOICE=0x80,OPEN_BRACE2=0x0100,CLOSE_BRACE2=0x0200,OPEN_BRACKET2=0x0400,CLOSE_BRACKET2=0x0800,MASTER_VOICE=0x1000,IN=96,CM=37.8,YSTEP var errs={bad_char:"Bad character '$1'",bad_grace:"Bad character in grace note sequence",bad_transp:"Bad transpose value",bad_val:"Bad value in $1",bar_grace:"Cannot have a bar in grace notes",ignored:"$1: inside tune - ignored",misplaced:"Misplaced '$1' in %%score",must_note:"!$1! must be on a note",must_note_rest:"!$1! must be on a note or a rest",nonote_vo:"No note in voice overlay",not_ascii:"Not an ASCII character",not_enough_n:'Not enough notes/rests for %%repeat',not_enough_m:'Not enough measures for %%repeat',not_enough_p:"Not enough parameters in %%map",not_in_tune:"Cannot have '$1' inside a tune",notransp:"Cannot transpose with a temperament"} var self=this,glovar={meter:{type:C.METER,wmeasure:1,a_meter:[]},},info={},parse={ctx:{},prefix:'%',state:0,ottava:[],line:new scanBuf},tunes=[],psvg function clone(obj,lvl){if(!obj) return obj var tmp=new obj.constructor for(var k in obj) if(obj.hasOwnProperty(k)){if(lvl&&typeof obj[k]=="object") tmp[k]=clone(obj[k],lvl-1) else tmp[k]=obj[k]} return tmp} function errbld(sev,txt,fn,idx){var i,j,l,c,h if(user.errbld){switch(sev){case 0:sev="warn";break case 1:sev="error";break default:sev="fatal";break} user.errbld(sev,txt,fn,idx) return} if(idx!=undefined&&idx>=0){i=l=0 while(1){j=parse.file.indexOf('\n',i) if(j<0||j>idx) break l++;i=j+1} c=idx-i} h="" if(fn){h=fn if(l) h+=":"+(l+1)+":"+(c+1);h+=" "} switch(sev){case 0:h+="Warning: ";break case 1:h+="Error: ";break default:h+="Internal bug: ";break} user.errmsg(h+txt,l,c)} function error(sev,s,msg,a1,a2,a3,a4){var i,j,regex,tmp if(!sev&&cfmt.quiet) return if(s){if(s.err) return s.err=true} if(user.textrans){tmp=user.textrans[msg] if(tmp) msg=tmp} if(arguments.length>3) msg=msg.replace(/\$./g,function(a){switch(a){case'$1':return a1 case'$2':return a2 case'$3':return a3 default:return a4}}) if(s&&s.fname) errbld(sev,msg,s.fname,s.istart) else errbld(sev,msg)} function scanBuf(){this.index=0;scanBuf.prototype.char=function(){return this.buffer[this.index]} scanBuf.prototype.next_char=function(){return this.buffer[++this.index]} scanBuf.prototype.get_int=function(){var val=0,c=this.buffer[this.index] while(c>='0'&&c<='9'){val=val*10+Number(c);c=this.next_char()} return val}} function syntax(sev,msg,a1,a2,a3,a4){var s={fname:parse.fname,istart:parse.istart+parse.line.index} error(sev,s,msg,a1,a2,a3,a4)} function js_inject(js){if(!/eval *\(|Function|setTimeout|setInterval/.test(js)) eval('"use strict";\n'+js) else syntax(1,"Unsecure code")} var dd_tb={},a_de,cross var decos={dot:"0 stc 6 1.5 1",tenuto:"0 emb 6 4 3",slide:"1 sld 3 7 1",arpeggio:"2 arp 12 10 3",roll:"3 roll 5,4 5 6",lowermordent:"3 lmrd 6,5 4 6",uppermordent:"3 umrd 6,5 4 6",trill:"3 trl 14 5 8",upbow:"3 upb 10,2 3 7",downbow:"3 dnb 9 4 6",gmark:"3 grm 7 4 6",wedge:"0 wedge 8 1.5 1",longphrase:"5 lphr 0 1 16",mediumphrase:"5 mphr 0 1 16",shortphrase:"5 sphr 0 1 16",turnx:"3 turnx 7,2.5 5 6",invertedturn:"3 turn 7,2 5 6","0":"3 fng 5,5 3 3 0","1":"3 fng 5,5 3 3 1","2":"3 fng 5,5 3 3 2","3":"3 fng 5,5 3 3 3","4":"3 fng 5,5 3 3 4","5":"3 fng 5,5 3 3 5",plus:"3 dplus 8,2 2 4","+":"3 dplus 8,2 2 4",">":"5 accent 3.5,3.5 4 4",accent:"5 accent 3.5,3.5 4 4",emphasis:"5 accent 3.5,3.5 4 4",marcato:"3 marcato 9 5 5","^":"3 marcato 9 5 5",mordent:"3 lmrd 6,5 4 6",open:"3 opend 8 3 3",snap:"3 snap 10 3 3",thumb:"3 thumb 10 3 3",turn:"3 turn 7,2.5 5 6","trill(":"5 ltr 8 0 0","trill)":"5 ltr 8 0 0","8va(":"5 8va 12 6 6","8va)":"5 8va 12 6 6","8vb(":"4 8vb 10,5 6 6","8vb)":"4 8vb 10,5 6 6","15ma(":"5 15ma 12 9 9","15ma)":"5 15ma 12 9 9","15mb(":"4 15mb 12 9 9","15mb)":"4 15mb 12 9 9",breath:"5 brth 0 1 16",caesura:"5 caes 0 1 20",short:"5 short 0 1 16",tick:"5 tick 0 1 16",coda:"5 coda 22,5 10 10",dacapo:"5 dacs 16 20 20 Da Capo",dacoda:"5 dacs 16 20 20 Da Coda","D.C.":"5 dcap 16,3 12 12","D.S.":"5 dsgn 16,3 12 12","D.C.alcoda":"5 dacs 16 38 38 D.C. al Coda","D.S.alcoda":"5 dacs 16 38 38 D.S. al Coda","D.C.alfine":"5 dacs 16 38 38 D.C. al Fine","D.S.alfine":"5 dacs 16 38 38 D.S. al Fine",fermata:"5 hld 12 7.5 7.5",fine:"5 dacs 16 14 14 Fine",invertedfermata:"7 hld 12 8 8",segno:"5 sgno 22,2 5 5",f:"6 f 12,5 3 4",ff:"6 ff 12,5 8 5",fff:"6 fff 12,5 11 9",ffff:"6 ffff 12,5 15 12",mf:"6 mf 12,5 8 10",mp:"6 mp 12,5 9 10",p:"6 p 12,5 3 6",pp:"6 pp 12,5 8 9",ppp:"6 ppp 12,5 14 11",pppp:"6 pppp 12,5 14 17",pralltriller:"3 umrd 6,5 4 6",sfz:"6 sfz 12,5 9 9",ped:"7 ped 14 6 10","ped-up":"7 pedoff 12 4 4","ped(":"7 lped 14 1 1","ped)":"7 lped 14 1 1","crescendo(":"6 cresc 15,2 0 0","crescendo)":"6 cresc 15,2 0 0","<(":"6 cresc 15,2 0 0","<)":"6 cresc 15,2 0 0","diminuendo(":"6 dim 15,2 0 0","diminuendo)":"6 dim 15,2 0 0",">(":"6 dim 15,2 0 0",">)":"6 dim 15,2 0 0","-(":"8 gliss 0 0 0","-)":"8 gliss 0 0 0","~(":"8 glisq 0 0 0","~)":"8 glisq 0 0 0",invisible:"32 0 0 0 0",beamon:"33 0 0 0 0",trem1:"34 0 0 0 0",trem2:"34 0 0 0 0",trem3:"34 0 0 0 0",trem4:"34 0 0 0 0",xstem:"35 0 0 0 0",beambr1:"36 0 0 0 0",beambr2:"36 0 0 0 0",rbstop:"37 0 0 0 0","/":"38 0 0 6 6","//":"38 0 0 6 6","///":"38 0 0 6 6","beam-accel":"39 0 0 0 0","beam-rall":"39 0 0 0 0",stemless:"40 0 0 0 0",rbend:"41 0 0 0 0",editorial:"42 0 0 0 0","sacc-1":"3 sacc-1 6,4 4 4",sacc3:"3 sacc3 6,5 4 4",sacc1:"3 sacc1 6,4 4 4",courtesy:"43 0 0 0 0","cacc-1":"3 cacc-1 0 0 0",cacc3:"3 cacc3 0 0 0",cacc1:"3 cacc1 0 0 0","tie(":"44 0 0 0 0","tie)":"44 0 0 0 0"},f_near=[d_near,d_slide,d_arp],f_note=[null,null,null,d_upstaff,d_upstaff],f_staff=[null,null,null,null,null,d_upstaff,d_upstaff,d_upstaff] function y_get(st,up,x,w){var y,p_staff=staff_tb[st],i=(x/2)|0,j=((x+w)/2)|0 if(i<0) i=0 if(j>=YSTEP){j=YSTEP-1 if(i>j) i=j} if(up){y=p_staff.top[i++] while(i<=j){if(yp_staff.bot[i]) y=p_staff.bot[i];i++}} return y} function y_set(st,up,x,w,y){var p_staff=staff_tb[st],i=(x/2)|0,j=((x+w)/2)|0 if(i<0) i=0 if(j>=YSTEP){j=YSTEP-1 if(i>j) i=j} if(up){while(i<=j){if(p_staff.top[i]y) p_staff.bot[i]=y;i++}}} function up3(s,pos){switch(pos&0x07){case C.SL_ABOVE:return 1 case C.SL_BELOW:return 0} return!s.second} function up6(s,pos){switch(pos&0x07){case C.SL_ABOVE:return true case C.SL_BELOW:return false} if(s.multi) return s.multi>0 if(!s.p_v.have_ly) return false return(s.pos.voc&0x07)!=C.SL_ABOVE} function d_arp(de){var m,h,dx,s=de.s,dd=de.dd,xc=dd.wr if(s.type==C.NOTE){for(m=0;m<=s.nhd;m++){if(s.notes[m].acc){dx=s.notes[m].shac}else{dx=1-s.notes[m].shhd switch(s.head){case C.SQUARE:dx+=3.5 break case C.OVALBARS:case C.OVAL:dx+=2 break}} if(dx>xc) xc=dx}} h=3*(s.notes[s.nhd].pit-s.notes[0].pit)+4;m=dd.h if(h0&&y<24){y=(((y+9)/6)|0)*6-6} if(up){y+=dd.hd s.ymx=y+dd.h}else if(dd.name[0]=='w'){de.inv=true y-=dd.h s.ymn=y}else{y-=dd.h s.ymn=y-dd.hd} de.x-=dd.wl de.y=y if(s.type==C.NOTE) de.x+=s.notes[s.stem>=0?0:s.nhd].shhd if(dd.name[0]=='d'){if(!(s.beam_st&&s.beam_end)){if(up){if(s.stem>0) de.x+=3.5}else{if(s.stem<0) de.x-=3.5}}else{if(up&&s.stem>0){y=s.y+(y-s.y)*.6 if(y>=27){de.y=y s.ymx=de.y+dd.h}}}}} function d_slide(de){var m,dx,s=de.s,yc=s.notes[0].pit,xc=5 for(m=0;m<=s.nhd;m++){if(s.notes[m].acc){dx=4+s.notes[m].shac}else{dx=5-s.notes[m].shhd switch(s.head){case C.SQUARE:dx+=3.5 break case C.OVALBARS:case C.OVAL:dx+=2 break}} if(s.notes[m].pit<=yc+3&&dx>xc) xc=dx} de.x-=xc;de.y=3*(yc-18)} function d_trill(de){if(de.ldst) return var y,w,tmp,dd=de.dd,de2=de.prev,up=de.start.up,s2=de.s,st=s2.st,s=de.start.s,x=s.x function sh_st(){var de3,de2=de.start,s=de2.s,i=de2.ix while(--i>=0){de3=a_de[i] if(!de3||de3.s!=s) break} while(1){i++ de3=a_de[i] if(!de3||de3.s!=s) break if(de3==de2) continue if(!(up^de3.up)&&(de3.dd.name=="trill"||de3.dd.func==6)){x+=de3.dd.wr+2 break}}} function sh_en(){var de3,i=de.ix while(--i>0){de3=a_de[i] if(!de3||de3.s!=s2) break} while(1){i++ de3=a_de[i] if(!de3||de3.s!=s2) break if(de3==de) continue if(!(up^de3.up)&&de3.dd.func==6){w-=de3.dd.wl break}}} if(de2){x=de2.s.x+de.dd.wl+2 de2.val-=de2.dd.wr if(de2.val<8) de2.val=8} de.st=st de.up=up sh_st() if(de.defl.noen){w=de.x-x if(w<20){x=de.x-20-3;w=20}}else{w=s2.x-x-4 sh_en(de) if(w<20) w=20} y=y_get(st,up,x-dd.wl,w) if(up){tmp=staff_tb[s.st].topbar+2 if(ytmp) y=tmp y-=dd.h} if(de2){if(up){if(y=de2.y){y=de2.y}else{do{de2.y=y de2=de2.prev}while(de2)}}} de.lden=false;de.has_val=true;de.val=w;de.x=x;de.y=y if(up) y+=dd.h;else y-=dd.hd y_set(st,up,x,w,y) if(up) s.ymx=s2.ymx=y else s.ymn=s2.ymn=y} function d_upstaff(de){if(de.ldst) return if(de.start){d_trill(de) return} var y,inv,up=de.up,s=de.s,dd=de.dd,x=de.x,w=dd.wl+dd.wr switch(dd.glyph){case"brth":case"caes":case"lphr":case"mphr":case"sphr":case"short":case"tick":y=staff_tb[s.st].topbar+2+dd.hd if(s.type==C.BAR){s.invis=1}else{if(dd.glyph=="brth"&&y=0?0:s.nhd].shhd;switch(dd.ty){case'@':case'<':case'>':y=de.y break} if(y==undefined){if(up){y=y_get(s.st,true,x-dd.wl,w) +dd.hd if(de.y>y) y=de.y s.ymx=y+dd.h}else{y=y_get(s.st,false,x-dd.wl,w) -dd.h if(de.y10&&x>realwidth-dd.wr) de.x=x=realwidth-dd.wr-dd.wl if(up) y_set(s.st,1,x-dd.wl,w,y+dd.h) else y_set(s.st,0,x-dd.wl,w,y-dd.hd) de.y=y} function deco_add(param){var dv=param.match(/(\S*)\s+(.*)/);decos[dv[1]]=dv[2]} function deco_def(nm,nmd){if(!nmd) nmd=nm var a,dd,dd2,nm2,c,i,elts,str,hd,text=decos[nmd] if(!text&&/\d[()]$/.test(nmd)) text=decos[nmd.replace(/\d/,'')] if(!text){if(cfmt.decoerr) error(1,null,"Unknown decoration '$1'",nm) return} a=text.match(/(\d+)\s+(.+?)\s+([0-9.,]+)\s+([0-9.]+)\s+([0-9.]+)/) if(!a){error(1,null,"Invalid decoration '$1'",nm) return} var c_func=Number(a[1]),h=a[3],wl=parseFloat(a[4]),wr=parseFloat(a[5]) if(isNaN(c_func)){error(1,null,"%%deco: bad C function value '$1'",a[1]) return} if(c_func>10&&(c_func<32||c_func>44)){error(1,null,"%%deco: bad C function index '$1'",c_func) return} if(h.indexOf(',')>0){h=h.split(',') hd=h[1] h=h[0]}else{hd=0} if(h>50||wl>80||wr>80){error(1,null,"%%deco: abnormal h/wl/wr value '$1'",text) return} dd=dd_tb[nm] if(!dd){dd={name:nm} dd_tb[nm]=dd} dd.func=nm.indexOf("head-")==0?9:c_func;dd.glyph=a[2];dd.h=Number(h) dd.hd=Number(hd) dd.wl=wl;dd.wr=wr;str=text.replace(a[0],'').trim() if(str){if(str[0]=='"') str=str.slice(1,-1);if(str[0]=='@'&&!str.match(/^@([0-9.-]+),([0-9.-]+);?/)){error(1,null,"%%deco: bad position '$1'",str) return} dd.str=str} if(dd.func==6&&dd.str==undefined) dd.str=nm c=nm.slice(-1) if(c=='('||(c==')'&&nm.indexOf('(')<0)){dd.str=null;nm2=nm.slice(0,-1)+(c=='('?')':'(');dd2=dd_tb[nm2] if(dd2){if(c=='('){dd.dd_en=dd2;dd2.dd_st=dd}else{dd.dd_st=dd2;dd2.dd_en=dd}}} return dd} function do_ctie(nm,s,nt1){var nt2=cross[nm],nm2=nm.slice(0,-1)+(nm.slice(-1)=='('?')':'(') if(nt2){error(1,s,"Conflict on !$1!",nm) return} nt1.s=s nt2=cross[nm2] if(!nt2){cross[nm]=nt1 return} if(nm.slice(-1)==')'){nt2=nt1 nt1=cross[nm2]} cross[nm2]=null if(nt1.midi!=nt2.midi||nt1.s.time+nt1.s.dur!=nt2.s.time){error(1,s,"Bad tie")}else{nt1.tie_ty=C.SL_AUTO nt1.tie_e=nt2 nt2.tie_s=nt1 nt1.s.ti1=nt2.s.ti2=true}} function get_dd(nm){var ty,p,dd=dd_tb[nm] if(dd) return dd if("<>^_@".indexOf(nm[0])>=0&&!/^([>^]|[<>]\d?[()])$/.test(nm)){ty=nm[0] if(ty=='@'){p=nm.match(/@([-\d]+),([-\d]+)/) if(p) ty=p[0] else ty=''} dd=deco_def(nm,nm.replace(ty,''))}else{dd=deco_def(nm)} if(!dd) return if(ty){if(ty[0]=='@'){dd.x=Number(p[1]) dd.y=Number(p[2]) ty='@'} dd.ty=ty} return dd} function deco_cnv(s,prev){var i,j,dd,nm,note,s1,court while(1){nm=a_dcn.shift() if(!nm) break dd=get_dd(nm) if(!dd) continue switch(dd.func){case 0:if(s.type==C.BAR&&nm=="dot"){s.bar_dotted=true continue} case 1:case 2:if(!s.notes){error(1,s,errs.must_note_rest,nm) continue} break case 4:case 5:i=nm.match(/1?[85]([vm])([ab])([()])/) if(i){j=i[1]=='v'?1:2 if(i[2]=='b') j=-j if(!s.ottava) s.ottava=[] s.ottava[i[3]=='('?0:1]=j glovar.ottava=1} break case 8:if(s.type!=C.NOTE){error(1,s,errs.must_note,nm) continue} note=s.notes[s.nhd] if(!note.a_dd) note.a_dd=[] note.a_dd.push(dd) continue case 9:if(!s.notes){error(1,s,errs.must_note_rest,nm) continue} for(j=0;j<=s.nhd;j++){note=s.notes[j] note.invis=true if(!note.a_dd) note.a_dd=[] note.a_dd.push(dd)} continue case 10:if(s.notes){for(j=0;j<=s.nhd;j++) s.notes[j].color=nm}else{s.color=nm} break case 32:s.invis=true break case 33:if(s.type!=C.BAR){error(1,s,"!beamon! must be on a bar") continue} s.beam_on=true break case 34:if(s.type!=C.NOTE||!prev||prev.type!=C.NOTE||s.dur!=prev.dur){error(1,s,"!$1! must be on the last of a couple of notes",nm) continue} s.trem2=true;s.beam_end=true;s.beam_st=false;prev.beam_st=true;prev.beam_end=false;s.ntrem=prev.ntrem=Number(nm[4]);for(j=0;j<=s.nhd;j++) s.notes[j].dur*=2;for(j=0;j<=prev.nhd;j++) prev.notes[j].dur*=2 break case 35:if(s.type!=C.NOTE){error(1,s,errs.must_note,nm) continue} s.xstem=true;break case 36:if(s.type!=C.NOTE){error(1,s,errs.must_note,nm) continue} if(nm[6]=='1') s.beam_br1=true else s.beam_br2=true break case 37:s.rbstop=1 break case 38:if(s.type!=C.NOTE){error(1,s,errs.must_note,nm) continue} s.trem1=true;s.ntrem=nm.length break case 39:if(s.type!=C.NOTE){error(1,s,errs.must_note,nm) continue} s.feathered_beam=nm[5]=='a'?1:-1;break case 40:s.stemless=true break case 41:s.rbstop=2 break case 42:if(!s.notes[0].acc) continue nm="sacc"+s.notes[0].acc.toString() dd=dd_tb[nm] if(!dd){dd=deco_def(nm) if(!dd){error(1,s,errs.bad_val,"!editorial!") continue}} delete s.notes[0].acc curvoice.acc[s.notes[0].pit+19]=0 break case 43:j=curvoice.acc[s.notes[0].pit+19] if(s.notes[0].acc||!j) continue court=1 break case 44:do_ctie(nm,s,s.notes[0]) continue} if(!s.a_dd) s.a_dd=[] s.a_dd.push(dd)} if(court){a_dcn.push("cacc"+j) dh_cnv(s,s.notes[0])}} function dh_cnv(s,nt){var k,nm,dd while(1){nm=a_dcn.shift() if(!nm) break dd=get_dd(nm) if(!dd) continue switch(dd.func){case 0:case 1:case 3:case 4:case 8:break default:error(1,s,"Cannot have !$1! on a head",nm) continue case 9:nt.invis=true break case 32:nt.invis=true continue case 10:nt.color=nm continue case 40:s.stemless=true continue case 44:do_ctie(nm,s,nt) continue} if(!nt.a_dd) nt.a_dd=[] nt.a_dd.push(dd)}} function deco_update(s,dx){var i,de,nd=a_de.length for(i=0;i':w=wr+dd.wl+dd.wr+6 if(s.wrwl) wl=w}} return wl} Abc.prototype.draw_all_deco=function(){if(!a_de.length) return var de,dd,s,note,f,st,x,y,y2,ym,uf,i,str,a,new_de=[],ymid=[] st=nstaff;y=staff_tb[st].y while(--st>=0){y2=staff_tb[st].y;ymid[st]=(y+24+y2)*.5;y=y2} while(1){de=a_de.shift() if(!de) break dd=de.dd if(!dd) continue if(dd.dd_en) continue s=de.s f=dd.glyph;i=f.indexOf('/') if(i>0){if(s.stem>=0) f=f.slice(0,i) else f=f.slice(i+1)} if(f_staff[dd.func]) set_sscale(s.st) else set_scale(s);st=de.st;if(!staff_tb[st].topbar) continue x=de.x;y=de.y+staff_tb[st].y if(de.m!=undefined){note=s.notes[de.m];if(note.shhd) x+=note.shhd*stv_g.scale}else if(dd.func==6&&((de.pos&C.SL_ALI_MSK)==C.SL_CENTER||((de.pos&C.SL_ALI_MSK)==0&&!s.fmt.dynalign))&&((de.up&&st>0)||(!de.up&&stym)){y2=y_get(st,!de.up,de.x,de.val) +staff_tb[st].y if(de.up) y2-=dd.h if((de.up&&y2>ym)||(!de.up&&y2=10) continue pos=0 break case 3:case 4:case 5:pos=s.pos.orn break case 6:pos=s.pos.dyn break} switch(dd.ty){case'^':pos=(pos&~0x07)|C.SL_ABOVE break case'_':pos=(pos&~0x07)|C.SL_BELOW break case'<':case'>':pos=(pos&0x07)|C.SL_CLOSE if(dd.ty=='<'){x-=dd.wr+8 if(s.notes[0].acc) x-=8}else{x+=dd.wl+8} y=3*(s.notes[0].pit-18) -(dd.h-dd.hd)/2 break case'@':x+=dd.x y+=dd.y break} if((pos&0x07)==C.SL_HIDDEN) continue de={s:s,dd:dd,st:s.st,ix:a_de.length,defl:{},x:x,y:y} if(pos) de.pos=pos up=0 if(dd.ty=='^'){up=1}else if(dd.ty=='_'){}else{switch(dd.func){case 0:if(s.multi) up=s.multi>0 else up=s.stem<0 break case 3:case 5:up=up3(s,pos) break case 6:case 7:up=up6(s,pos) break}} de.up=up if(dd.name.indexOf("inverted")>=0) de.inv=1 if(s.type==C.BAR&&!dd.ty) de.x-=s.wl/2-2 a_de.push(de) if(dd.dd_en){de.ldst=true}else if(dd.dd_st){de.lden=true;de.defl.nost=true} if(f_near[dd.func]) f_near[dd.func](de)}} function create_dh(s,m){var de,k,dd,note=s.notes[m],nd=note.a_dd.length,x=s.x for(k=0;k'){de.x+=dd.wl+8}}} a_de.push(de) if(dd.dd_en){de.ldst=true}else if(dd.dd_st){de.lden=true;de.defl.nost=true}}} function create_all(s){if(s.invis&&s.play) return if(s.a_dd) create_deco(s) if(s.notes){for(var m=0;m=0){de3=a_de[j] if(!de3.start) continue if(de3.s.time0&s.bar_num&&s.bar_num%cfmt.measurenb) x+=6 if(s.type!=C.BAR){w=s.rbstop?0:s.x-realwidth+4}else if((s.bar_type.length>1&&s.bar_type!="[]")||s.bar_type=="]"){if(s1.st>0&&!(cur_sy.staves[s1.st-1].flags&STOP_BAR)) w=s.wl else if(s.bar_type.slice(-1)==':') w=12 else if(s.bar_type[0]!=':') w=0 else w=8}else{w=(s.rbstop&&!s.rbstart)?0:8} w=(s.x-x-w) if(!s.next&&!s.rbstop&&!p_voice.bar_start){p_voice.bar_start=_bar(s) p_voice.bar_start.bar_type="" p_voice.bar_start.rbstart=1} if(s1.text) xy_str(x+4,y2-gene.curfont.size,s1.text);xypath(x,y2);if(s1.rbstart==2) output+='m0 10v-10';output+='h'+w.toFixed(1) if(s.rbstop==2) output+='v10';output+='"/>\n';y_set(s1.st,true,x,w,y+2) if(s.rbstart) s=s.prev}} for(i=0;i<=nstaff;i++) minmax[i]={ymin:0,ymax:0} for(i=0;i'||dd.ty=='@') continue f_staff[dd.func](de) if(dd.func!=6||dd.dd_en) continue if((de.pos&C.SL_ALI_MSK)==C.SL_ALIGN||((de.pos&C.SL_ALI_MSK)==0&&de.s.fmt.dynalign>0)){if(de.up){if(de.y>minmax[de.st].ymax) minmax[de.st].ymax=de.y}else{if(de.y0){y2=y+dd.h+2 if(y2>staff_tb[de.st].ann_top) staff_tb[de.st].ann_top=y2}else{y2=y-dd.hd-2 if(y2'||dd.dd_en) continue w=de.val||(dd.wl+dd.wr) if((de.pos&C.SL_ALI_MSK)==C.SL_ALIGN||((de.pos&C.SL_ALI_MSK)==0&&de.s.fmt.dynalign>0)){if(de.up) y=minmax[de.st].ymax else y=minmax[de.st].ymin;de.y=y}else{y=de.y} if(de.up) y+=dd.h;else y-=dd.hd y_set(de.st,de.up,de.x,w,y)} for(i=0;instaff) return set_dscale(st) if(staff_tb[st].staffscale!=1){font_size=get_font("measure").size;param_set_font("measurefont","* "+ (font_size/staff_tb[st].staffscale).toString())} set_font("measure");w0=cwidf('0');s=tsfirst;bar_num=gene.nbar if(bar_num>1){if(cfmt.measurenb==0){any_nb=true;y=y_get(st,true,0,20) if(y=10) w*=bar_num>=100?3:2 if(gene.curfont.pad) w+=gene.curfont.pad*2 x=(s.prev?s.prev.x+s.prev.wr/2:s.x-s.wl)-w y=y_get(st,true,x,w)+5 if(y=10) w*=bar_num>=100?3:2 if(gene.curfont.pad) w+=gene.curfont.pad*2 x=s.x y=y_get(st,true,x,w) if(y0){if(ynstaff) return set_dscale(st,1) var ymin=staff_tb[st].topbar+2,dosh=0,shift=1,x=-100,yn=0 for(s=tsfirst;s;s=s.ts_next){s2=s.part if(!s2||s2.invis) continue if(!some_part){some_part=s;set_font("parts");h=gene.curfont.size+2+ gene.curfont.pad*2} if(s2.x==undefined) s2.x=s.x-10 w=strwh(s2.text)[0] y=y_get(st,true,s2.x,w+3) if(yminymin) ymin=y if(x>=s.x-16&&!(dosh&(shift>>1))) dosh|=shift shift<<=1 x=s.x-16+w} if(some_tempo){set_sscale(-1) set_font("tempo") h=gene.curfont.size ymin+=2 ymin*=staff_tb[st].staffscale for(s=some_tempo;s;s=s.ts_next){if(s.type!=C.TEMPO||s.invis) continue w=s.tempo_wh[0] y=ymin if(dosh&1) y+=h if(user.anno_start||user.anno_stop){s.wl=16 s.wr=w-16 s.ymn=y s.ymx=s.ymn+14 anno_start(s)} writempo(s,s.x-16,y) anno_stop(s) y_set(st,1,s.x-16,w,y+h+2) dosh>>=1}}} var STEM_MIN=16,STEM_MIN2=14,STEM_MIN3=12,STEM_MIN4=10,STEM_CH_MIN=14,STEM_CH_MIN2=10,STEM_CH_MIN3=9,STEM_CH_MIN4=9,BEAM_DEPTH=3.2,BEAM_OFFSET=.25,BEAM_SHIFT=5,BEAM_STUB=7,SLUR_SLOPE=.5,GSTEM=15,GSTEM_XOFF=2.3 var cache,anno_a=[] function b_pos(grace,stem,nflags,b){var top,bot,d1,d2,shift=!grace?BEAM_SHIFT:3.5,depth=!grace?BEAM_DEPTH:1.8 function rnd6(y){var iy=Math.round((y+12)/6)*6-12 return iy-y} if(stem>0){bot=b-(nflags-1)*shift-depth if(bot>26) return 0 top=b}else{top=b+(nflags-1)*shift+depth if(top<-2) return 0 bot=b} d1=rnd6(top-BEAM_OFFSET);d2=rnd6(bot+BEAM_OFFSET) return d1*d1>d2*d2?d2:d1} function sym_dup(s){var m,note s=clone(s) s.invis=true delete s.extra;delete s.text delete s.a_gch delete s.a_ly delete s.a_dd;delete s.tp s.notes=clone(s.notes) for(m=0;m<=s.nhd;m++){note=s.notes[m]=clone(s.notes[m]) delete note.a_dd} return s} var min_tb=[[STEM_MIN,STEM_MIN,STEM_MIN2,STEM_MIN3,STEM_MIN4,STEM_MIN4],[STEM_CH_MIN,STEM_CH_MIN,STEM_CH_MIN2,STEM_CH_MIN3,STEM_CH_MIN4,STEM_CH_MIN4]] Abc.prototype.calculate_beam=function(bm,s1){var s,s2,g,notes,nflags,st,v,two_staves,two_dir,x,y,ys,a,b,stem_err,max_stem_err,p_min,p_max,s_closest,stem_xoff,scale,visible,dy if(!s1.beam_st){s=sym_dup(s1);lkvsym(s,s1);lktsym(s,s1);s.x-=12 if(s.x>s1.prev.x+12) s.x=s1.prev.x+12;s.beam_st=true delete s.beam_end;s.tmp=true delete s.sls;s1=s} notes=nflags=0;two_staves=two_dir=false;st=s1.st;v=s1.v;stem_xoff=s1.grace?GSTEM_XOFF:3.5 for(s2=s1;;s2=s2.next){if(s2.type==C.NOTE){if(s2.nflags>nflags) nflags=s2.nflags;notes++ if(s2.st!=st) two_staves=true if(s2.stem!=s1.stem) two_dir=true if(!visible&&!s2.invis&&(!s2.stemless||s2.trem2)) visible=true if(s2.beam_end) break} if(!s2.next){for(;;s2=s2.prev){if(s2.type==C.NOTE) break} s=sym_dup(s2);s.next=s2.next if(s.next) s.next.prev=s;s2.next=s;s.prev=s2;s.ts_next=s2.ts_next if(s.ts_next) s.ts_next.ts_prev=s;s2.ts_next=s;s.ts_prev=s2 delete s.beam_st;s.beam_end=true;s.tmp=true delete s.sls;s.x+=12 if(s.x=0){x=stem_xoff+s.notes[0].shhd if(s.notes[s.nhd].pit>p_max){p_max=s.notes[s.nhd].pit;s_closest=s}}else{x=-stem_xoff+s.notes[s.nhd].shhd if(s.notes[0].pit=3&&s_closest!=s1&&s_closest!=s2) a=0 y=s1.ys+staff_tb[st].y if(a==undefined) a=(s2.ys+staff_tb[s2.st].y-y)/(s2.xs-s1.xs) if(a!=0){a=s1.fmt.beamslope*a/(s1.fmt.beamslope+Math.abs(a)) if(a>-.04&&a<.04) a=0} b=(y+s2.ys+staff_tb[s2.st].y)/2-a*(s2.xs+s1.xs)/2 max_stem_err=0;s=s1 if(two_dir){ys=((s1.grace?3.5:BEAM_SHIFT)*(nflags-1)+ BEAM_DEPTH)*.5 if(s1.nflags==s2.nflags);else if(s1.stem!=s2.stem&&s1.nflagss1.xs) s=s.ts_prev for(;s&&s.time<=s2.time;s=s.ts_next){if(s.type!=C.NOTE||s.invis||(s.st!=st&&s.v!=v)){continue} x=s.v==v?s.xs:s.x;ys=a*x+b-staff_tb[s.st].y if(s.v==v){stem_err=min_tb[s.nhd==0?0:1][s.nflags] if(s.stem>0){if(s.notes[s.nhd].pit>26){stem_err-=2 if(s.notes[s.nhd].pit>28) stem_err-=2} stem_err-=ys-3*(s.notes[s.nhd].pit-18)}else{if(s.notes[0].pit<18){stem_err-=2 if(s.notes[0].pit<16) stem_err-=2} stem_err-=3*(s.notes[0].pit-18)-ys} stem_err+=BEAM_DEPTH+BEAM_SHIFT*(s.nflags-1)}else{if(s1.stem>0){if(s.stem>0){if(s.ymn>ys+4||s.ymxv) stem_err=s.ymx-ys else stem_err=s.ymn+8-ys}else{stem_err=s.ymx-ys}}else{if(s.stem<0){if(s.ymxys-beam_h-2) continue if(s.vmax_stem_err) max_stem_err=stem_err}}else{for(;;s=s.next){ys=a*s.xs+b-staff_tb[s.st].y;stem_err=GSTEM-2 if(s.stem>0) stem_err-=ys-(3*(s.notes[s.nhd].pit-18)) else stem_err+=ys-(3*(s.notes[0].pit-18));stem_err+=3*(s.nflags-1) if(stem_err>max_stem_err) max_stem_err=stem_err if(s==s2) break}} if(max_stem_err>0) b+=s1.stem*max_stem_err if(!two_staves&&!two_dir) for(s=s1.next;;s=s.next){switch(s.type){case C.REST:if(!s.multi) break g=s.ts_next if(!g||g.st!=st||(g.type!=C.NOTE&&g.type!=C.REST)) break case C.BAR:if(s.invis) break case C.CLEF:y=a*s.x+b if(s1.stem>0){y=s.ymx-y +BEAM_DEPTH+BEAM_SHIFT*(nflags-1) +2 if(y>0) b+=y}else{y=s.ymn-y -BEAM_DEPTH-BEAM_SHIFT*(nflags-1) -2 if(y<0) b+=y} break case C.GRACE:for(g=s.extra;g;g=g.next){y=a*g.x+b if(s1.stem>0){y=g.ymx-y +BEAM_DEPTH+BEAM_SHIFT*(nflags-1) +2 if(y>0) b+=y}else{y=g.ymn-y -BEAM_DEPTH-BEAM_SHIFT*(nflags-1) -2 if(y<0) b+=y}} break} if(s==s2) break} if(a==0) b+=b_pos(s1.grace,s1.stem,nflags,b-staff_tb[st].y) for(s=s1;;s=s.next){switch(s.type){case C.NOTE:s.ys=a*s.xs+b-staff_tb[s.st].y if(s.stem>0){s.ymx=s.ys+2.5 if(s.ts_prev&&s.ts_prev.stem>0&&s.ts_prev.st==s.st&&s.ts_prev.ymn0){y-=dy if(s1.multi==0&&y>12) y=12 if(s.y<=y) break}else{y+=dy if(s1.multi==0&&y<12) y=12 if(s.y>=y) break} if(s.head!=C.FULL) y=(((y+3+12)/6)|0)*6-12;s.y=y break} if(s==s2) break} if(staff_tb[st].y==0) return false bm.s1=s1;bm.a=a;bm.b=b;bm.nflags=nflags return true} function draw_beams(bm){var s,i,beam_dir,shift,bshift,bstub,bh,da,bd,k,k1,k2,x1,s1=bm.s1,s2=bm.s2 function draw_beam(x1,x2,dy,h,bm,n){var y1,dy2,s=bm.s1,nflags=s.nflags if(s.ntrem) nflags-=s.ntrem if(s.trem2&&n>nflags){if(s.dur>=C.BLEN/2){x1=s.x+6;x2=bm.s2.x-6}else if(s.dur\n'} anno_start(s1,'beam') if(!s1.grace){bshift=BEAM_SHIFT;bstub=BEAM_STUB;shift=.34;bh=BEAM_DEPTH}else{bshift=3.5;bstub=3.2;shift=.29;bh=1.8} bh/=stv_g.scale beam_dir=s1.stem if(s1.stem!=s2.stem&&s1.nflags0){da=-da;bshift=da*s1.xs}else{bshift=da*s2.xs} da=da*beam_dir} shift=0 for(i=2;i<=bm.nflags;i++){shift+=bshift if(da!=0) bm.a+=da for(s=s1;;s=s.next){if(s.type!=C.NOTE||s.nflagss.nflags-s.ntrem){x1=(s.dur>=C.BLEN/2)?s.x:s.xs;draw_beam(x1-5,x1+5,(shift+2.5)*beam_dir,bh,bm,i) if(s==s2) break continue} k1=s while(1){if(s==s2) break k=s.next if(k.type==C.NOTE||k.type==C.REST){if(k.trem1){if(k.nflags-k.ntrem2)) break s=k} k2=s while(k2.type!=C.NOTE) k2=k2.prev;x1=k1.xs bd=beam_dir if(k1==k2){if(k1==s1){x1+=bstub}else if(k1==s2){x1-=bstub}else if(k1.beam_br1||(k1.beam_br2&&i>2)){x1+=bstub}else{k=k1.next while(k.type!=C.NOTE) k=k.next if(k.beam_br1||(k.beam_br2&&i>2)){x1-=bstub}else{k1=k1.prev while(k1.type!=C.NOTE) k1=k1.prev if(k1.nflagsi;j--){if(cur_sy.st_print[j]) break} if(i==j&&l==0) return yb=staff_tb[j].y+staff_tb[j].botbar*staff_tb[j].staffscale;h=staff_tb[i].y+staff_tb[i].topbar*staff_tb[i].staffscale-yb;xypath(x,yb);output+="v"+(-h).toFixed(1)+'"/>\n' for(i=0;i<=nst;i++){fl=cur_sy.staves[i].flags if(fl&OPEN_BRACE) draw_sysbra(x,i,CLOSE_BRACE) if(fl&OPEN_BRACKET) draw_sysbra(x,i,CLOSE_BRACKET) if(fl&OPEN_BRACE2) draw_sysbra(x-6,i,CLOSE_BRACE2) if(fl&OPEN_BRACKET2) draw_sysbra(x-6,i,CLOSE_BRACKET2)}} function draw_meter(s){if(!s.a_meter) return var dx,i,j,meter,x,st=s.st,p_staff=staff_tb[st],y=p_staff.y;if(p_staff.stafflines!='|||||') y+=(p_staff.topbar+p_staff.botbar)/2-12 for(i=0;i\n\ A\n\ B\n\ \n',x,y+6,m_gl(meter.top),m_gl(meter.bot))}else{out_XYAB('\ A\n',x,y+12,m_gl(meter.top))}}} var acc_nd={} function draw_acc(x,y,a){if(typeof a=="object"){var c,n=a[0],d=a[1] c=n+'_'+d a=acc_nd[c] if(!a){a=abc2svg.rat(Math.abs(n),d) d=a[1] a=(n<0?-a[0]:a[0]).toString() if(d!=1) a+='_'+d acc_nd[c]=a}} xygl(x,y,"acc"+a)} function set_hl(p_st,n,x,dx1,dx2){var i,hl if(n>=0){hl=p_st.hlu[n] if(!hl) hl=p_st.hlu[n]=[]}else{hl=p_st.hld[-n] if(!hl) hl=p_st.hld[-n]=[]} for(i=0;i=hl[i][0]) break} if(i==hl.length){hl.push([x,dx1,dx2])}else if(x>hl[i][0]){hl.splice(++i,0,[x,dx1,dx2])}else{if(dx1hl[i][2]) hl[i][2]=dx2}} Abc.prototype.draw_hl=function(s){var i,j,n,note,hla=[],st=s.st,p_staff=staff_tb[st] if(!p_staff.hll||s.invis) return for(i=0;i<=s.nhd;i++){note=s.notes[i] if(!p_staff.hlmap[note.pit-p_staff.hll]) hla.push([note.pit-18,note.shhd*stv_g.scale])} n=hla.length if(!n) return var dx1,dx2,hl,shhd,hlp,stafflines=p_staff.stafflines,top=stafflines.length-1,yu=top,bot=p_staff.botline/6,yl=bot,dx=s.grace?4:hw_tb[s.head]*1.3 note=s.notes[s.stem<0?s.nhd:0] shhd=note.shhd for(i=0;ishhd?hla[i][1]:shhd)+dx if(hlp>1 n--}else if(hlp>top*2){yu=hlp>>1 n--} set_hl(p_staff,hlp>>1,s.x,dx1,dx2)} dx1=shhd-dx dx2=shhd+dx while(++yltop) set_hl(p_staff,yu,s.x,dx1,dx2) if(!n) return i=yl;j=yu while(i>bot&&stafflines[i]=='-') i-- while(j0){for(nacc=0;nacc9?sharp1:sharp2 for(i=0;iold_sf;i--){xygl(x,staffb+shift,"acc3");shift+=p_seq[-i];x+=5.5} if(s.k_sf!=0) x+=3}} if(s.k_sf>0){shift=sharp_cl[clef_ix];p_seq=shift>9?sharp1:sharp2 for(i=0;is.k_sf;i--){xygl(x,staffb+shift,"acc-1");shift+=p_seq[-i];x+=5.5} if(s.fmt.cancelkey&&i>old_sf){x+=2 for(;i>old_sf;i--){xygl(x,staffb+shift,"acc3");shift+=p_seq[-i];x+=5.5}}}}else if(a_acc.length){var acc,last_acc=a_acc[0].acc,last_shift=100,s2={st:st,nhd:0,notes:[{}]} for(i=0;i27) shift-=21 if(i!=0&&(shift>last_shift+18||shift2&&s.v==cur_sy.top_voice&&s.fmt.measrepnb>0&&!(s.rep_nb%s.fmt.measrepnb)) nrep_out(x,yb+p_staff.topbar,s.rep_nb)} anno_a.push(s) return} set_scale(s);anno_start(s);if(s.notes[0].color) set_color(s.notes[0].color);y=s.y;i=5-s.nflags if(i==7&&y==12&&p_staff.stafflines.length<=2) y-=6 if(!s.notes[0].invis) xygl(x,y+yb,rest_tb[i]) if(s.dots){x+=8;y+=yb+3 j=s.dots i=(s.dur_orig/12)>>((5-s.nflags)-j) while(j-->0){xygl(x,y,(i&(1<\n' if(s.tacet) out_XYAB('A\n',s.x,y+18,s.tacet) else out_XYAB('A\n',s.x,y+22,m_gl(p)) anno_a.push(s)} function grace_slur(s){var yy,x0,y0,x3,y3,bet1,bet2,dy1,dy2,last,below,so=s,g=s.extra while(1){if(!g.next) break g=g.next} last=g below=((g.stem>=0||s.multi<0)&&g.notes[0].pit<=28)||g.notes[0].pit<16 if(below){yy=127 for(g=s.extra;g;g=g.next){if(g.y-2) x3-=4;y3=3*(s.notes[0].pit-18)-5;dy1=(x3-x0)*.4 if(dy1>3) dy1=3;dy2=dy1;bet1=.2;bet2=.8 if(y0>y3+7){x0=last.x-1;y0+=.5;y3+=6.5;x3=s.x-5.5;dy1=(y0-y3)*.8;dy2=(y0-y3)*.2;bet1=0}else if(y3>y0+4){y3=y0+4;x0=last.x+2;y0=last.y-4}}else{yy=-127 for(g=s.extra;g;g=g.next){if(g.y>yy){yy=g.y;last=g}} x0=last.x;y0=last.y+5 if(s.extra!=last){x0-=4;y0-=1} s=s.next;x3=s.x-1 if(s.stem>=0&&s.nflags>-2) x3-=2;y3=3*(s.notes[s.nhd].pit-18)+5;dy1=(x0-x3)*.4 if(dy1<-3) dy1=-3;dy2=dy1;bet1=.2;bet2=.8 if(y0g.ymx) g.ymx=y0}} function draw_gracenotes(s){var x1,y1,last,note,bm={},g=s.extra while(1){if(g.beam_st&&!g.beam_end){if(self.calculate_beam(bm,g)) draw_beams(bm)} anno_start(g) draw_note(g,!bm.s2) if(g==bm.s2) bm.s2=null anno_a.push(s) if(!g.next) break g=g.next} last=g if(s.sappo){g=s.extra if(!g.next){x1=9 y1=g.stem>0?5:-5}else{x1=(g.next.x-g.x)*.5+4 y1=(g.ys+g.next.ys)*.5-g.y if(g.stem>0) y1-=1 else y1+=1} note=g.notes[g.stem<0?0:g.nhd] out_acciac(x_head(g,note),y_head(g,note),x1,y1,g.stem>0)} g=s.slur if(g){anno_start(s,'slur') xypath(g.x0,g.y0+staff_tb[s.st].y) output+='c'+g.x1.toFixed(1)+' '+g.y1.toFixed(1)+' '+g.x2.toFixed(1)+' '+g.y2.toFixed(1)+' '+g.x3.toFixed(1)+' '+g.y3.toFixed(1)+'"/>\n' anno_stop(s,'slur')}} function setdoty(s,y_tb){var m,m1,y for(m=0;m<=s.nhd;m++){y=3*(s.notes[m].pit-18) if((y%6)==0){if(s.dot_low) y-=3 else y+=3} y_tb[m]=y} for(m=0;my_tb[m]) continue m1=m while(m1>0){if(y_tb[m1]>y_tb[m1-1]+6) break m1--} if(3*(s.notes[m1].pit-18)-y_tb[m1]=0){if(s.stem>=0) p=p.slice(0,i) else p=p.slice(i+1)}}else if(s.type==C.CUSTOS){p="custos"}else{switch(head){case C.OVAL:p="HD" break case C.OVALBARS:if(s.head!=C.SQUARE){p="HDD" break} case C.SQUARE:if(nflags>-4){p="breve"}else{p="longa" inv=s.stem>0} if(!tsnext&&s.next&&s.next.type==C.BAR&&!s.next.next) dots=0 x_note+=1 break case C.EMPTY:p="Hd" break default:p="hd" break}} if(note.color!=undefined) old_color=set_color(note.color) if(p){if(inv){g_open(x_note,y_note,0,1,-1);x_note=y_note=0} if(!self.psxygl(x_note,y_note,p)) xygl(x_note,y_note,p) if(inv) g_close()} if(dots){dotx=x+(7.7+s.xmx)*stv_g.scale if(y_tb[m]==undefined){y_tb[m]=3*(s.notes[m].pit-18) if((s.notes[m].pit&1)==0) y_tb[m]+=3} doty=y_tb[m]+staffb i=(note.dur/12)>>((5-nflags)-dots) while(dots-->0){xygl(dotx,doty,(i&(1<0){if(s.stem>=0) slen-=1 else slen+=1} out_stem(x,y,slen,s.grace)}else{out_stem(x,y,slen,s.grace,nflags,s.fmt.straightflags)}}else if(s.xstem){s2=s.ts_prev;slen=(s2.stem>0?s2.y:s2.ys)-s.y;slen+=staff_tb[s2.st].y-staffb;out_stem(x,y,slen)} if(fl&&s.trem1){var ntrem=s.ntrem||0,x1=x;slen=3*(s.notes[s.stem>0?s.nhd:0].pit-18) if(s.head==C.FULL||s.head==C.EMPTY){x1+=(s.grace?GSTEM_XOFF:3.5)*s.stem if(s.stem>0) slen+=6+5.4*ntrem else slen-=6+5.4}else{if(s.stem>0) slen+=5+5.4*ntrem else slen-=5+5.4} slen/=s.p_v.scale;out_trem(x1,staffb+slen,ntrem)} for(m=0;m<=s.nhd;m++) draw_basic_note(s,m,y_tb)} function prev_scut(s){while(s.prev){s=s.prev if(s.rbstart) return s} s=s.p_v.sym while(s.type!=C.CLEF) s=s.ts_prev if(s.next&&s.next.type==C.KEY) s=s.next if(s.next&&s.next.type==C.METER) return s.next return s} function slur_direction(k1,k2){var s,some_upstem,low,dir function slur_multi(s1,s2){if(s1.multi) return s1.multi if(s2.multi) return s2.multi return 0} if(k1.grace&&k1.stem>0) return-1 dir=slur_multi(k1,k2) if(dir) return dir for(s=k1;;s=s.next){if(s.type==C.NOTE){if(!s.stemless){if(s.stem<0) return 1 some_upstem=true} if(s.notes[0].pit<22) low=true} if(s.time==k2.time) break} if(!some_upstem&&!low) return 1 return-1} function slur_out(x1,y1,x2,y2,dir,height,dotted){var dx,dy,dz,alfa=.3,beta=.45;dy=y2-y1 if(dy<0) dy=-dy;dx=x2-x1 if(dx>40.&&dy/dx<.7){alfa=.3+.002*(dx-40.) if(alfa>.7) alfa=.7} var mx=.5*(x1+x2),my=.5*(y1+y2),xx1=mx+alfa*(x1-mx),yy1=my+alfa*(y1-my)+height;xx1=x1+beta*(xx1-x1);yy1=y1+beta*(yy1-y1) var xx2=mx+alfa*(x2-mx),yy2=my+alfa*(y2-my)+height;xx2=x2+beta*(xx2-x2);yy2=y2+beta*(yy2-y2);dy=2*dir;dz=.2+.001*dx if(dz>.6) dz=.6;dz*=dir dx*=.03 var scale_y=1 if(!dotted) output+='\n'} function draw_slur(path,sl,recurr){var i,k,g,x1,y1,x2,y2,height,addy,s_st2,a,y,z,h,dx,dy,ty=sl.ty,dir=(ty&0x07)==C.SL_ABOVE?1:-1,n=path.length,i1=0,i2=n-1,not1=sl.nts,k1=path[0],k2=path[i2],nn=1 set_dscale(k1.st) for(i=1;ik1.st) h=-h for(i=0;ih) h=a.ymx}}else{for(i1=1;i1h) h=a.ymx} for(i1=i;i1s_st2.st?'/':'\\' if(sl.ty&C.SL_CENTER) ty=ty+ty else if(k1.st==k2.st) ty=ty=='/'?'/\\':'\\/' else ty+=dir>0?'+':'-' var savout=output output="" draw_slur(path,sl,1) gene.a_sl.push([k1,s_st2,ty,output]) output=savout return} x1=k1.x if(k1.notes&&k1.notes[0].shhd) x1+=k1.notes[0].shhd;x2=k2.x if(k2.notes) x2+=k2.notes[0].shhd if(not1){y1=3*(not1.pit-18)+2*dir x1+=3}else{y1=dir>0?k1.ymx+2:k1.ymn-2 if(k1.type==C.NOTE){if(dir>0){if(k1.stem>0){x1+=5 if(k1.beam_end&&k1.nflags>=-1&&!k1.in_tuplet){if(k1.nflags>0){x1+=2;y1=k1.ys-3}else{y1=k1.ys-6}}else{y1=k1.ys+3}}else{y1=k1.y+8}}else{if(k1.stem<0){x1-=1 if(k2.grace){y1=k1.y-8}else if(k1.beam_end&&k1.nflags>=-1&&(!k1.in_tuplet||k1.ys0){x1+=2;y1=k1.ys+3}else{y1=k1.ys+6}}else{y1=k1.ys-3}}else{y1=k1.y-8}}}} if(sl.nte){y2=3*(sl.nte.pit-18)+2*dir x2-=3}else{y2=dir>0?k2.ymx+2:k2.ymn-2 if(k2.type==C.NOTE){if(dir>0){if(k2.stem>0){x2+=1 if(k2.beam_st&&k2.nflags>=-1&&!k2.in_tuplet) y2=k2.ys-6 else y2=k2.ys+3}else{y2=k2.y+8}}else{if(k2.stem<0){x2-=5 if(k2.beam_st&&k2.nflags>=-1&&!k2.in_tuplet) y2=k2.ys+6 else y2=k2.ys-3}else{y2=k2.y-8}}}} if(k1.type!=C.NOTE){y1=y2+1.2*dir;x1=k1.x+k1.wr*.5 if(x1>x2-12) x1=x2-12} if(k2.type!=C.NOTE){if(k1.type==C.NOTE) y2=y1+1.2*dir else y2=y1 if(k1!=k2) x2=k2.x-k2.wl*.3} if(nn>=3){k=path[1] if(k.type!=C.BAR&&k.x0){y=k.ymx-2 if(y1y) y1=y}} k=path[i2-1] if(k.type!=C.BAR&&k.x>x2-48){if(dir>0){y=k.ymx-2 if(y2y) y2=y}}} a=(y2-y1)/(x2-x1) if(a>SLUR_SLOPE||a<-SLUR_SLOPE){a=a>SLUR_SLOPE?SLUR_SLOPE:-SLUR_SLOPE if(a*dir>0) y1=y2-a*(x2-x1) else y2=y1+a*(x2-x1)} y=y2-y1 if(y>8) y=8 else if(y<-8) y=-8 z=y if(z<0) z=-z;dx=.5*z;dy=.3*y if(y*dir>0){x2-=dx;y2-=dy}else{x1+=dx;y1+=dy} if(k1.grace) x1=k1.x-GSTEM_XOFF*.5 if(k2.grace) x2=k2.x+GSTEM_XOFF*1.5;h=0;a=(y2-y1)/(x2-x1) if(k1!=k2&&k1.v==k2.v){addy=y1-a*x1 for(i=1;i0){y=3*(k.notes[k.nhd].pit-18)+6 if(yh) h=y}else{y=3*(k.notes[0].pit-18)-6 if(y>k.ymn) y=k.ymn;y-=a*k.x+addy if(y0){y=3*(g.notes[g.nhd].pit-18)+6 if(yh) h=y}else{y=3*(g.notes[0].pit-18)-6 if(y>g.ymn) y=g.ymn;y-=a*g.x+addy if(y3) height=(.08*(x2-x1)+12)*dir else height=(.03*(x2-x1)+8)*dir if(dir>0){if(height<3*h) height=3*h if(height>40) height=40}else{if(height>3*h) height=3*h if(height<-40) height=-40} y=y2-y1 if(y<0) y=-y if(dir>0){if(height<.8*y) height=.8*y}else{if(height>-.8*y) height=-.8*y} height*=k1.fmt.slurheight;slur_out(x1,y1,x2,y2,dir,height,ty&C.SL_DOTTED);dx=x2-x1;a=(y2-y1)/dx;addy=y1-a*x1 if(height>0) addy+=4*Math.sqrt(height)-2 else addy-=4*Math.sqrt(-height)-2 for(i=0;iy) k.ymn=y if(recurr) continue if(i==i2-1){dx=x2 if(sl.nte) dx-=5}else{dx=k.x+k.wr} if(i!=0) x1=k.x if(!i||i==i2) y-=height/3 dx-=x1-k.wl y_set(k1.st,dir>0,x1-k.wl,dx,y)}} function draw_slurs(s,last){var gr1,i,m,note,sls,nsls function draw_sls(s,sl){var k,v,i,dir,s3,path=[],s2=sl.se if(last&&s2.time>last.time) return switch(sl.loc){case'i':s=prev_scut(s) break case'o':for(s3=s;s3.ts_next;s3=s3.ts_next);s2=s3 for(;s3;s3=s3.ts_prev){if(s3.v==s.v){s2=s3 break} if(s3.st==s.st) s2=s3 if(s3.ts_prev.time!=s2.time) break} break} if(s.p_v.s_next&&s2.time>=tsnext.time){if(s2.time==tsnext.time){if(s2.grace){for(s3=tsnext;s3&&s3.time==s2.time;s3=s3.ts_next){if(s3.type==C.GRACE){s3=null break}}}else{for(s3=tsnext;s3.time==s2.time;s3=s3.ts_next){if(s3==s2){s3=null break}}}}else{s3=null} if(!s3){s.p_v.sls.push(sl);s2=s.p_v.s_next.prev while(s2.next) s2=s2.next;sl=Object.create(sl)}} switch(sl.ty&0x07){case C.SL_ABOVE:dir=1;break case C.SL_BELOW:dir=-1;break default:dir=s.v!=s2.v?1:slur_direction(s,s2) sl.ty&=~0x07 sl.ty|=dir>0?C.SL_ABOVE:C.SL_BELOW break} if(s.v==s2.v){v=s.v}if(!cur_sy.voices[s.v]||!cur_sy.voices[s2.v]){v=s.v>s2.v?s.v:s2.v}else if(dir*(cur_sy.voices[s.v].range<=cur_sy.voices[s2.v].range?1:-1)>0) v=s.v else v=s2.v if(gr1&&!(s2.grace&&s.v==s2.v&&s.time==s2.time)){do{path.push(s);s=s.next}while(s);s=gr1.next}else{path.push(s);if(s.grace) s=s.next else s=s.ts_next} if(!s2.grace){while(s){if(s.v==v) path.push(s) if(s==s2) break s=s.ts_next}}else if(s.grace){while(1){path.push(s) if(s==s2) break s=s.next}}else{k=s2 while(k.prev) k=k.prev while(1){if(s.v==v) path.push(s) if(s.extra==k) break s=s.ts_next} s=k while(1){path.push(s) if(s==s2) break s=s.next}} for(i=1;i=s1.nflags) nb_only=false break}}} if(nb_only&&!s2.beam_end){for(s3=s2.next;s3;s3=s3.next){if(s3.type==C.NOTE||s3.type==C.REST){if(!s3.beam_br1&&!s3.beam_br2&&s3.nflags>=s2.nflags) nb_only=false break}}}}} if(nb_only){if(tp.f[2]==1) return set_font("tuplet") xm=(s2.x+s1.x)/2 if(dir==C.SL_ABOVE) ym=y_get(upstaff,1,xm-4,8) else ym=y_get(upstaff,0,xm-4,8)- gene.curfont.size if(s1.stem*s2.stem>0){if(s1.stem>0) xm+=1.5 else xm-=1.5} if(tp.f[2]==0) xy_str(xm,ym,tp.p.toString(),'c') else xy_str(xm,ym,tp.p+':'+tp.q,'c') for(s3=s1;;s3=s3.next){if(s3.x>=xm) break} if(dir==C.SL_ABOVE){ym+=gene.curfont.size if(s3.ymxym) s3.ymn=ym;y_set(upstaff,false,xm-3,6,ym)} return} x1=s1.x-4 if(s2.dur>s2.prev.dur){s3=s2.next if(!s3||s3.time!=s2.time+s2.dur){for(s3=s2.ts_next;s3;s3=s3.ts_next){if(s3.seqst&&s3.time>=s2.time+s2.dur) break}} x2=s3?s3.x-s3.wl-5:realwidth-6}else{x2=s2.x+4 r=s2.stem>=0?0:s2.nhd if(s2.notes[r].shhd>0) x2+=s2.notes[r].shhd if(s2.st==upstaff&&s2.stem>0) x2+=3.5} if(dir==C.SL_ABOVE){if(s1.st==s2.st){y1=y2=staff_tb[upstaff].topbar+2}else{y1=s1.ymx;y2=s2.ymx} if(s1.st==upstaff){for(s3=s1;!s3.dur;s3=s3.next);ym=y_get(upstaff,1,s3.x-4,8) if(ym>y1) y1=ym if(s1.stem>0) x1+=3} if(s2.st==upstaff){for(s3=s2;!s3.dur;s3=s3.prev);ym=y_get(upstaff,1,s3.x-4,8) if(ym>y2) y2=ym} xm=.5*(x1+x2);ym=.5*(y1+y2);a=(y2-y1)/(x2-x1);s0=3*(s2.notes[s2.nhd].pit-s1.notes[s1.nhd].pit)/(x2-x1) if(s0>0){if(a<0) a=0 else if(a>s0) a=s0}else{if(a>0) a=0 else if(ady) dy=yx-yy if(s3==s2) break} ym+=dy;y1=ym+a*(x1-xm);y2=ym+a*(x2-xm);ym+=6 for(s3=s1;;s3=s3.next){if(s3.st==upstaff){yy=ym+(s3.x-xm)*a if(s3.ymx0){if(a<0) a=0 else if(a>s0) a=s0 if(a>.35) a=.35}else{if(a>0) a=0 else if(ayy) s3.ymn=yy;y_set(upstaff,false,s3.x-3,6,yy)} if(s3==s2) break}} if(tp.f[2]==1){out_tubr(x1,y1+4,x2-x1,y2-y1,dir==C.SL_ABOVE);return} out_tubrn(x1,y1,x2-x1,y2-y1,dir==C.SL_ABOVE,tp.f[2]==0?tp.p.toString():tp.p+':'+tp.q);if(dir==C.SL_ABOVE) y_set(upstaff,true,xm-3,6,yy+2) else y_set(upstaff,false,xm-3,6,yy)} function draw_tie(not1,not2,job){var m,x1,s,y,h,time,p=job==2?not1.pit:not2.pit,dir=(not1.tie_ty&0x07)==C.SL_ABOVE?1:-1,s1=not1.s,st=s1.st,s2=not2.s,x2=s2.x,sh=not1.shhd for(m=0;m0){if(msh) sh=s1.notes[m+1].shhd}else{if(m>0&&p==s1.notes[m-1].pit+1) if(s1.notes[m-1].shhd>sh) sh=s1.notes[m-1].shhd} x1=s1.x+sh if(job!=2){for(m=0;m0){if(m0&&p==s2.notes[m-1].pit+1) if(s2.notes[m-1].shhdx2-20) x1=x2-20 break case 2:x2=s1.next?s1.next.x:realwidth if(x2!=realwidth) x2-=(x2-x1)*.4 if(x220){x1+=3.5 x2-=3.5}else{x1+=1.5 x2-=1.5} if(s1.dots&&!(not1.pit&1)&&((dir>0&&!s1.dot_low)||(dir<0&&s1.dot_low))) x1+=5 y=staff_tb[st].y+3*(p-18)+dir h=(.03*(x2-x1)+16)*dir*s1.fmt.tieheight slur_out(x1,y,x2,y,dir,h,not1.tie_ty&C.SL_DOTTED)} function draw_all_ties(p_voice){var s,s1,s2,clef_chg,x,dx,m,not1,not2,tim2=0 s1=p_voice.sym set_color(s1.color) for(;s1;s1=s1.next){if(s1.ti2&&s1.time!=tim2){for(m=0;m<=s1.nhd;m++){not2=s1.notes[m] not1=not2.tie_s if(!not1||not1.s.v!=s1.v) continue draw_tie(not1,not2,1)}} if(!s1.ti1) continue if(s1.type==C.GRACE){for(s=s1.extra;s;s=s.next){for(m=0;m<=s1.nhd;m++){not1=s.notes[m] not2=not1.tie_e if(!not2) continue draw_tie(not1,not2) tim2=not2.s.time}} continue} for(m=0;m<=s1.nhd;m++){not1=s1.notes[m] not2=not1.tie_e if(!not2){if(not1.tie_ty) draw_tie(not1,not1,2) continue} s2=not2.s if(tsnext&&s2.time>=tsnext.time){draw_tie(not1,not2,2) continue} tim2=s2.time for(s=s1.ts_next;s!=s2;s=s.ts_next){if(s.st!=s1.st) continue if(s.type==C.CLEF){clef_chg=true break}} if(clef_chg||s1.st!=s2.st){draw_tie(not1,not2,2) draw_tie(not1,not2,3) clef_chg=false}else{draw_tie(not1,not2)}}}} function draw_sym_near(){var p_voice,p_st,s,v,st,y,g,w,i,st,dx,top,bot,ymn,output_sav=output;function set_yab(s1,s2){var y,k=realwidth/YSTEP,i=(s1.x/k)|0,j=(s2.x/k)|0,a=(s1.ys-s2.ys)/(s1.xs-s2.xs),b=s1.ys-s1.xs*a,p_st=staff_tb[s1.st] k*=a if(s1.stem>0){while(i<=j){y=k*i+b if(p_st.top[i]y) p_st.bot[i]=y i++}}} output="" YSTEP=Math.ceil(realwidth/2) for(st=0;st<=nstaff;st++){p_st=staff_tb[st] p_st.top=new Float32Array(YSTEP) p_st.bot=new Float32Array(YSTEP) for(i=0;i0){if(s.stemless){dx=-5;w=10}else if(s.beam_st){dx=3;w=s.beam_end?4:10}else{dx=-8;w=s.beam_end?11:16} y_set(s.st,true,s.x+dx,w,s.ymx);ymn=s.ymn if(s.notes[0].acc&&ymn>3*(s.notes[0].pit-18)-9) ymn=3*(s.notes[0].pit-18)-9 y_set(s.st,false,s.x-s.wl,s.wl+s.wr,ymn)}else{y_set(s.st,true,s.x-s.wl,s.wl+s.wr,s.ymx);if(s.stemless){dx=-5;w=10}else if(s.beam_st){dx=-6;w=s.beam_end?4:10}else{dx=-8;w=s.beam_end?5:16} dx+=s.notes[0].shhd;y_set(s.st,false,s.x+dx,w,s.ymn)} if(s.notes[s.nhd].acc){y=3*(s.notes[s.nhd].pit-18) +(s.notes[s.nhd].acc==-1?11:10) y_set(s.st,true,s.x-10,10,y)} if(s.notes[0].acc){y=3*(s.notes[0].pit-18) -(s.notes[0].acc==-1?5:10) y_set(s.st,false,s.x-10,10,y)}} draw_deco_note() for(v=0;vp_st.top[i]) p_st.top[i]=top if(bot=0) draw_measnb();set_dscale(-1) for(v=0;v=0;st--){if(stl[st]) break} if(st<0) return for(v=0;vnstaff){st--;p_staff=staff_tb[st]} p_staff=staff_tb[st] for(i=0;imaxsep) dy=maxsep;y+=dy;p_staff.y=-y;while(!gene.st_print[++prev_staff]) staff_tb[prev_staff].y=-y while(1){sy_staff_prev=sy.staves[prev_staff] if(sy_staff_prev) break sy=sy.next}} mbot=0 for(i=0;ival) mbot=val} if(mbot>p_staff.ann_bot) mbot=p_staff.ann_bot;mbot*=staff_tb[prev_staff].staffscale for(st=0;st<=nstaff;st++){p_staff=staff_tb[st];dy=p_staff.y if(p_staff.staffscale!=1){p_staff.scale_str='transform="translate(0,'+ (posy-dy).toFixed(1)+') '+'scale('+p_staff.staffscale.toFixed(2)+')"'}} if(mbot==0){for(st=nstaff;st>=0;st--){if(gene.st_print[st]) break} if(st<0) return y} dy=-mbot;staffsep=fmt.staffsep*.5 if(dymaxsep) dy=maxsep;return y+dy} function draw_systems(indent){var s,s2,st,x,x2,res,sy,xstaff=[],stl=[],bar_bot=[],bar_height=[],ba=[],sb="",thb="" function bar_set(){var st,staffscale,top,bot,dy=0 for(st=0;st<=cur_sy.nstaff;st++){if(xstaff[st]<0){bar_bot[st]=bar_height[st]=0 continue} staffscale=staff_tb[st].staffscale;top=staff_tb[st].topbar*staffscale;bot=staff_tb[st].botbar*staffscale if(dy==0) dy=staff_tb[st].y+top;bar_bot[st]=staff_tb[st].y+bot;bar_height[st]=dy-bar_bot[st];dy=(cur_sy.staves[st].flags&STOP_BAR)?0:bar_bot[st]}} function draw_staff(st,x1,x2){var w,i,dy,ty,y=0,ln="",stafflines=staff_tb[st].stafflines,l=stafflines.length,il=6*staff_tb[st].staffscale if(!/[\[|]/.test(stafflines)) return w=x2-x1;set_sscale(-1) if(cache&&cache.st_l==stafflines&&staff_tb[st].staffscale==1&&cache.st_w==(w|0)){xygl(x1,staff_tb[st].y,'stdef'+cfmt.fullsvg) return} for(i=0;i'} y=staff_tb[st].y if(!cache&&w>get_lwidth()-10&&staff_tb[st].staffscale==1){cache={st_l:stafflines,st_w:w|0} i='stdef'+cfmt.fullsvg;if(ln.indexOf('\n'+ln+'\n';xygl(x1,y,i) return} out_XYAB('\n'+ln+'\n\n',x1,y)} function draw_bar(s,bot,h){var i,s2,yb,w,bar_type=s.bar_type,st=s.st,p_staff=staff_tb[st],x=s.x if(st!=0&&s.ts_prev&&s.ts_prev.type!=C.BAR) h=p_staff.topbar*p_staff.staffscale;s.ymx=s.ymn+h;set_sscale(-1) anno_start(s) if(s.color) set_color(s.color);yb=p_staff.y+12;if(p_staff.stafflines!='|||||') yb+=(p_staff.topbar+p_staff.botbar)/2-12 if(s.bar_mrep){set_sscale(st) if(s.bar_mrep==1){for(s2=s.prev;s2.type!=C.REST;s2=s2.prev);xygl(s2.x,yb,"mrep")}else{xygl(x,yb,"mrep2") if(s.v==cur_sy.top_voice) nrep_out(x,yb+p_staff.topbar,s.bar_mrep)} set_sscale(-1)} if(bar_type=='||:') bar_type='[|:' for(i=bar_type.length;--i>=0;){switch(bar_type[i]){case"|":if(s.bar_dotted){w=(5*p_staff.staffscale).toFixed(1);out_XYAB('\n',x,bot,w,h)}else if(s.color){out_XYAB('\n',x,bot,h)}else{sb+='M'+sx(x).toFixed(1) +' '+self.sy(bot).toFixed(1) +'v-'+h.toFixed(1)} break default:x-=3;if(s.color) out_XYAB('\n',x+1.5,bot,h) else thb+='M'+sx(x+1.5).toFixed(1) +' '+self.sy(bot).toFixed(1) +'v-'+h.toFixed(1) break case":":x-=2;set_sscale(st);xygl(x+1,yb-12,"rdots") set_sscale(-1) break} x-=3} set_color();anno_stop(s)} function out_bars(){var i,b,bx,l=ba.length set_font("annotation");bx=gene.curfont.box if(bx) gene.curfont.box=0 for(i=0;i\n' if(thb) output+='\n'} function hl_rest(s){var j,p_st=staff_tb[s.st],i=5-s.nflags,x=s.x,y=s.y if(i<6) return if(i==7&&y==12&&p_st.stafflines.length<=2) y-=6 j=y/6 switch(i){default:switch(p_st.stafflines[j+1]){case'|':case'[':break default:set_hl(p_st,j+1,x,-7,7) break} if(i==9){y-=6 j--} break case 7:y+=6 j++ case 6:break} switch(p_st.stafflines[j]){case'|':case'[':break default:set_hl(p_st,j,x,-7,7) break}} function st1(st,s){var tim=s.time do{s=s.ts_next}while(s.st!=st) while(s.prev&&s.prev.time>=tim) s=s.prev if(s.bar_type) return s.x return s.x-s.wl} for(st=0;st<=nstaff;st++){stl[st]=cur_sy.st_print[st] xstaff[st]=!stl[st]?-1:0} bar_set();draw_lstaff(0) for(s=tsfirst;s;s=s.ts_next){switch(s.type){case C.STAVES:sy=s.sy for(st=0;st<=nstaff;st++){x=xstaff[st] if(x<0){if(sy.st_print[st]){xstaff[st]=st1(st,s) stl[st]=true} continue} if(sy.st_print[st]&&cur_sy.staves[st]&&sy.staves[st].stafflines==cur_sy.staves[st].stafflines) continue if(s.ts_prev.bar_type){x2=s.ts_prev.x}else{x2=(s.ts_prev.x+s.x)/2 xstaff[st]=-1} draw_staff(st,x,x2) xstaff[st]=sy.st_print[st]?x2:-1} cur_sy=sy;bar_set() continue case C.BAR:if(s.invis||!s.bar_type||!cur_sy.st_print[s.st]) break if(s.second&&(!s.ts_prev||(s.ts_prev.type==C.BAR&&s.ts_prev.st==s.st))) break ba.push([s,bar_bot[s.st],bar_height[s.st]]) break case C.STBRK:if(cur_sy.voices[s.v]&&cur_sy.voices[s.v].range==0){if(s.xmx>14){var nv=0 for(var i=0;i0) nv++} for(s2=s.ts_next;s2;s2=s2.ts_next){if(s2.type!=C.STBRK) break nv--} if(nv==0) draw_lstaff(s.x)}} st=s.st;x=xstaff[st] if(x>=0){s2=s.prev if(!s2) break x2=s2.type==C.BAR?s2.x:s.x-s.xmx if(x>=x2) break draw_staff(st,x,x2) xstaff[st]=s.x} break case C.GRACE:for(s2=s.extra;s2;s2=s2.next) self.draw_hl(s2) break case C.NOTE:if(!s.invis) self.draw_hl(s) break case C.REST:if(s.fmr||(s.rep_nb&&s.rep_nb>=0)) center_rest(s) if(!s.invis) hl_rest(s) break}} for(st=0;st<=nstaff;st++){x=xstaff[st] if(x<0||x>=realwidth) continue draw_staff(st,x,realwidth)} draw_all_hl() out_bars() draw_vname(indent,stl)} Abc.prototype.draw_symbols=function(p_voice){var bm={},s,x,y,st;for(s=p_voice.sym;s;s=s.next){if(s.invis){switch(s.type){case C.CLEF:if(s.time>=staff_tb[s.st].clef.time) staff_tb[s.st].clef=s continue case C.KEY:p_voice.ckey=s default:continue case C.NOTE:break}} st=s.st x=s.x;set_color(s.color) switch(s.type){case C.NOTE:set_scale(s) if(s.beam_st&&!s.beam_end){if(self.calculate_beam(bm,s)) draw_beams(bm)} if(!s.invis){anno_start(s);draw_note(s,!bm.s2);anno_a.push(s)} if(s==bm.s2) bm.s2=null break case C.REST:if(!gene.st_print[st]) break draw_rest(s);break case C.BAR:break case C.CLEF:if(s.time>=staff_tb[st].clef.time) staff_tb[st].clef=s if(s.second||!staff_tb[st].topbar||!gene.st_print[st]) break set_color();set_sscale(st);anno_start(s);y=staff_tb[st].y if(s.clef_name) xygl(x,y+s.y,s.clef_name) else if(!s.clef_small) xygl(x,y+s.y,s.clef_type+"clef") else xygl(x,y+s.y,"s"+s.clef_type+"clef") if(s.clef_octave){if(s.clef_octave>0){y+=s.ymx-10 if(s.clef_small) y-=1}else{y+=s.ymn+6 if(s.clef_small) y+=1} xygl(x-2,y,(s.clef_octave==7||s.clef_octave==-7)?"oct":"oct2")} anno_a.push(s) break case C.METER:p_voice.meter=s if(s.second||!staff_tb[s.st].topbar) break set_color();set_sscale(s.st);anno_start(s);draw_meter(s);anno_a.push(s) break case C.KEY:p_voice.ckey=s if(s.second||!staff_tb[s.st].topbar) break set_color();set_sscale(s.st);anno_start(s);self.draw_keysig(x,s);anno_a.push(s) break case C.MREST:draw_mrest(s) break case C.GRACE:set_scale(s);draw_gracenotes(s) break case C.SPACE:case C.STBRK:break case C.CUSTOS:set_scale(s);draw_note(s,0) break case C.BLOCK:case C.REMARK:case C.STAVES:case C.TEMPO:break default:error(2,s,"draw_symbols - Cannot draw symbol "+s.type) break}} set_scale(p_voice.sym)} function draw_all_sym(){var p_voice,v,n=voice_tb.length function draw_sl2(){var i,a,d,dy,dy2,dy2o,dz,n,sl while(1){sl=gene.a_sl.shift() if(!sl) break i=sl[3].indexOf('d="M')+4 output+=sl[3].slice(0,i) a=new Float32Array(sl[3].slice(i).match(/[\d.-]+/g)) a[1]-=staff_tb[sl[0].st].y dy2o=sl[0].fmt.sysstaffsep+24 dy2=staff_tb[sl[1].st].y-staff_tb[sl[0].st].y switch(sl[2]){case"//":case"\\\\":d=-(sl[1].prev.prev.y+staff_tb[sl[0].st].y +sl[1].prev.next.y+staff_tb[sl[1].st].y) -2*(a[1]-posy) a[5]=d-a[5] a[7]=d-a[7] if(a.length>8){d=sl[2][0]=='/'?3:-3 a[8]=-a[8] a[10]=-a[3]+d a[12]=-a[5]+d a[14]=-a[7]} break case"/\\":case"\\/":d=sl[2][0]=='/'?dy2-dy2o-10:dy2+dy2o+10 a[3]+=d a[5]+=d if(a.length>8){a[10]+=d a[12]+=d} break default:d=sl[2][0]=='/'?dy2-dy2o:-dy2-dy2o a[5]+=d a[7]+=d if(a.length>8){a[12]-=d a[14]-=d} break} output+=a[0].toFixed(1)+' '+a[1].toFixed(1) +'c'+a[2].toFixed(1)+' '+a[3].toFixed(1) +' '+a[4].toFixed(1)+' '+a[5].toFixed(1) +' '+a[6].toFixed(1)+' '+a[7].toFixed(1) if(a.length>8) output+='v'+a[8].toFixed(1) +'c'+a[9].toFixed(1) +' '+a[10].toFixed(1) +' '+a[11].toFixed(1) +' '+a[12].toFixed(1) +' '+a[13].toFixed(1) +' '+a[14].toFixed(1) output+='"/>\n'}} for(v=0;v=22?C.SL_ABOVE:C.SL_BELOW else if(s.multi) dir=s.multi>0?C.SL_ABOVE:C.SL_BELOW else dir=s.stem<0?C.SL_ABOVE:C.SL_BELOW if(s.multi){for(i=0;i<=s.nhd;i++){ty=s.notes[i].tie_ty if(!((ty&0x07)==C.SL_AUTO)) continue s.notes[i].tie_ty=(ty&C.SL_DOTTED)|dir} continue} if(ntie<=1){for(i=0;i<=s.nhd;i++){ty=s.notes[i].tie_ty if(ty){if((ty&0x07)==C.SL_AUTO) s.notes[i].tie_ty=(ty&C.SL_DOTTED)|dir break}} continue} if(!sec){if(ntie&1){ntie=(ntie-1)/2;dir=C.SL_BELOW for(i=0;i<=s.nhd;i++){ty=s.notes[i].tie_ty if(!ty) continue if(ntie==0){if(s.notes[i].pit>=22) dir=C.SL_ABOVE} if((ty&0x07)==C.SL_AUTO) s.notes[i].tie_ty=(ty&C.SL_DOTTED)|dir if(ntie--==0) dir=C.SL_ABOVE} continue} ntie/=2;dir=C.SL_BELOW for(i=0;i<=s.nhd;i++){ty=s.notes[i].tie_ty if(!ty) continue if((ty&0x07)==C.SL_AUTO) s.notes[i].tie_ty=(ty&C.SL_DOTTED)|dir if(--ntie==0) dir=C.SL_ABOVE} continue} pit=128 for(i=0;i<=s.nhd;i++){if(s.notes[i].tie_ty){if(pit<128&&s.notes[i].pit<=pit+1){ntie=i break} pit=s.notes[i].pit}} dir=C.SL_BELOW for(i=0;i<=s.nhd;i++){ty=s.notes[i].tie_ty if(!ty) continue if(ntie==i) dir=C.SL_ABOVE if((ty&0x07)==C.SL_AUTO) s.notes[i].tie_ty=(ty&C.SL_DOTTED)|dir}}} function set_tie_room(){var p_voice,s,s2,v,dx,y,dy for(v=0;v24&&s.notes[s.nhd].tie_ty&&(s.notes[s.nhd].tie_ty&0x07)==C.SL_ABOVE);else continue s2=s.next while(s2&&s2.type!=C.NOTE) s2=s2.next if(s2){if(s2.st!=s.st) continue dx=s2.x-s.x-10}else{dx=realwidth-s.x-10} if(dx<100) dy=9 else if(dx<300) dy=12 else dy=16 if(s.notes[s.nhd].pit>24){y=3*(s.notes[s.nhd].pit-18)+dy if(s.ymxy) s.ymn=y if(s2&&s2.ymn>y) s2.ymn=y;y_set(s.st,false,s.x+5,dx,y)}}}} var musicfont='url("data:application/octet-stream;base64,\ AAEAAAAOAIAAAwBgRkZUTZHVOuoAAFgMAAAAHEdERUYAFQAUAABX8AAAABxPUy8yWMFdCgAAAWgA\ AABWY21hcHlUuFMAAAQIAAAD5mN2dCAAIgKIAAAH8AAAAARnYXNw//8AAwAAV+gAAAAIZ2x5ZqUq\ QgUAAAkcAABF/GhlYWQVmDJzAAAA7AAAADZoaGVhCWn/GwAAASQAAAAkaG10eNm9+0EAAAHAAAAC\ SGxvY2HHqraAAAAH9AAAASZtYXhwANkBEgAAAUgAAAAgbmFtZeq7sB0AAE8YAAADFXBvc3SIfxKM\ AABSMAAABbUAAQAAAAEAANGbj/xfDzz1AAsEAAAAAADRlyIXAAAAAOBezej/OPzvBUsEiAAAAAgA\ AgAAAAAAAAABAAAEiPzvAFwEJf84/XQFSwABAAAAAAAAAAAAAAAAAAAAkgABAAAAkgDhAAUAAAAA\ AAIAAAABAAEAAABAAC4AAAAAAAEBgAGQAAUACAKZAswAAACPApkCzAAAAesAMwEJAAACAAUDAAAA\ AAAAAAAAARAAAAAAAAAAAAAAAFBmRWQAQAAA7LcDOP84AFwEiAMRAAAAAQAAAAAAAAF2ACIAAAAA\ AVUAAAGQAAACWAAAAFcAAAAjAAAAJQAAACT//wBkAAAEIwAABCUAAAHg/9wDugAAAwsAAALSAAAC\ v/+6AdYAAAMLAAADDgAAAyf/yADIAAABaAAAAa4AAAEiAAABkAAAAXwAAAGQAAABkAAAAYEAAAGQ\ AAABkAAAAYEAAAGZAAkBmAAJAfQAAAEEABQBBAAKAmsAJAISAAABwgAAAUIAAAFAAAABSv/+ASwA\ AAIwAAABSgAAAUoAAABkAAABQAAAAUAAAAFAAAABQAAAAGQAAAE2AAAA5gAAATYAAAE7AAABOwAA\ ATsAAAE7AAABOwAAATsAAAE7AAABOwAAATsAAAE7AAABDQAAAMgAAAD/AAABCwAUAW4AAACMAAAA\ jAAAAQ0AMgFu//UAqQAAAToAAAFA//0AUAAAAVQAAABkAAABGAAAAlgAAAC2AAABkAAFAIIAAACC\ AAABLAAAASwAAADuAAAA/wAAAUkAAAGPAAAB2AAAAdgAAAIz//ADIP/hAXv/tAG4/9sBFv9+ARP/\ 2wDcAAAA6P/kAr//tAIz/7QCv/+0Ayv/2wFf/9sCaf9+AV//fgJp/34BXwAAAf0ABQG1AAABtQAA\ AkQADQJEAA0BGAAAATYAAAEs//8BLAAAAPoAAADIAAABGP84APoAAADIAAAEDQAAAhwADAH0AAAB\ 9AAAAfQAAAH0AAAB9AAAAfQAAAB4AAAALQAAAhwAAAD6AAAA+v/oAcIAAAFIAAABQAAAAgoAAAIK\ AAAAZAAAAAAAAwAAAAMAAAAcAAEAAAAAAuAAAwABAAAAHAAEAsQAAABgAEAABQAgAAAAIOAA4DDg\ OeBI4FDgXOBi4GngjOCV4KTgqeCz4QHhu+Hn4gDiSeJk4mvig+Ss5MDk0eTq5QHlMeU55W3lguXQ\ 5eLmGOYk5jDmUOZV6RjpIOkl6V3qAuqk7Knst///AAAAAAAg4ADgMOA44EPgUOBc4GLgaeB64JTg\ oOCp4LPhAeG54efh8uJA4mDiauKA5KDkwOTO5OHlAOUg5TnlZuWC5dDl4uYQ5iTmMOZQ5lXpEOkg\ 6SXpXeoC6qTsouy3//8AA//kIAUf1gAAAAAfvh+zH64fqAAAAAAAAB+CH3kfLAAAHkkAAAAAAAAA\ AAAAAAAbkwAAAAAAAAAAGzcAABr0GqcalgAAGlkaThovGisAABdnF2MXLBaIFecAABPaAAEAAAAA\ AAAAAABYAFoAAAAAAAAAAABcAIAAggAAAAAAAACEAAAAhgCiALQAvAC+AMQAAADaAOAA8gD0AAAB\ FAAAAAAAAAEcAAAAAAAAAAABJAAAAAAAAAAAAAABKgAAAAAABwAIAAkAAAAKAAsADAANABIAEwAU\ ABUAFgAAABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgAuAAAALwAxAAAA\ MgAAAAAAMwAAADQAAAAAADUAAAA2ADcAOAA5ADoAOwA8AD0APgA/AEAAQQBCAEMARABFAEYARwBI\ AEkASgBLAEwATQBOAAAATwAAAFAAAAAAAAAAUQAAAAAAAABSAFQAAAAAAFUAVgBXAFgAWQBaAFsA\ XABdAF4AXwBgAGEAYgBjAGQAZQBmAGcAAAAAAAAAaABpAGoAawBsAAAAbQBuAG8AcQByAAAAcwAA\ AAAAdAB1AHkAAAB6AAAAewAAAAAAAAB8AIEAggCDAAAAhACFAAAAAACGAIwAjQAAAI4AAACPAAAA\ kAAAAQYAAAMAAAAAAAAAAQIAAAACAAAAAAAAAAAAAAAAAAAAAQAABAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiAogAAAAqACoAKgA2AD4AbgB6\ AIYAkgCwASQBgAHwAjQCwANSA7IDxgRkBPYFTgWOBhAGMgZGBpgG6AcIB04HjgfICBQIVAiaCPQJ\ CAkuCVQJhgmiCcQJ7AoCChwKUgpgCmwKeAqKCqYKyArWCuoK/AsMC1gLaAuCC5wL1AwMDFoMpg0M\ DW4N7A5kDooOpA7UDv4PVg9wD4oPsBAKECoQaBCQEKQQsBC+EM4Q9hEeEVYRYhFuEXoRhhGoEc4S\ BBJSErITJhNME3oTzhRCFJYU1hUaFXAWihdiF/gYqhlsGf4a0BvkHNAdEh1WHaAduh3eHfIeBh42\ HkYeWB50Hooerh7eH7ogdiCeILwg7iEsIV4hoCGyIcAh3CH2IhwiPiJsIoYisCLsIv4AAAACACIA\ AAEyAqoAAwAHAC6xAQAvPLIHBADtMrEGBdw8sgMCAO0yALEDAC88sgUEAO0ysgcGAfw8sgECAO0y\ MxEhESczESMiARDuzMwCqv1WIgJmAAABAAAAAAGRAZAAAwAAMREhEQGRAZD+cAABAAAAAAAAAAAA\ AAAAMQAAAQAAAAAAVwQDACAAABE1NjU0JyY1NDcGFRQXFhUUBxYVFAcGFRQXJjU0NzY1NDUjElc/\ FSVNTSUVP1cSIwIDAhhDNmA5NGY6MksiOWFNYRgYZkxgOSVKMjpmNDlgNkgAAQAAAAAAIwPoAAMA\ ABEzESMjIwPo/BgAAQAAAfQAJQPoAAMAABEzESMlJQPo/gwAAf//A2QAJARgAAMAABEzByMkASQE\ YPwAAgAAAUAAZAKeAAcADwAAEiImNDYyFhQCIiY0NjIWFEcqHR0qHR0qHR0qHQI6HSodHSr+6R0q\ HR0qAAAABQAAAAAEJAGuAC8ANwA/AEcAUwAAITUzHgEzMjY1NCcuBDU0NjMyFhc3MxcjLgEjIgYV\ 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\ VVc9ARVWTUQJHVVXPQEVVk1E/o4CrClId0QhGTk2KykrLC0nKywtJyssJUg9OjczORuqKUl4RAMN\ BCldQ1SGKUl4RAMNBCldQ1SGKUl4RAMNBCldQ1QAAAAFAAD9VQE8AhIAJAAyAEAATgBcAAAZATMe\ BhUUBxYVFAcWFRQHFhUUBxYVFAc2NTQuAyM1HgMXNDY1NC4DJx4DFzQ2NTQuAyceAxc0NjU0LgMn\ HgMXNDY1NC4DHgYnMzs4LhwSEhISEhISEx4FKT5IQBYJRE1WFQEpPkhBFglETVYVASk+SEEWCURN\ VhUBKT5IQRYJRE1WFQEpPkhB/rsDVxs5Mzc6PUglLCsnLSwrJy0sKyctLCspKzY5GSE3ZEU0GKsk\ VENdKQMNBDdlRTMZqyRUQ10pBAwEN2VFMxmrJFRDXSkDDgM3ZUUzGaskVENdKQQMBDdlRTMZAAAF\ AAD9vAE8AnkAIwAwAD0ASgBXAAAZATMyPgI1NCcWFRQHFhUUBxYVFAcWFRQHFhUUDgUHNTI+AjU0\ JjUOAycyPgI1NCY1DgMnMj4CNTQmNQ4DJzI+AjU0JjUOAx4cVVc9BR4TEhISEhISEhwuODszJwYd\ VVc9ARVWTUQJHVVXPQEVVk1ECR1VVz0BFVZNRAkdVVc9ARVWTUT9vANXKUh3RCEZOTYrKSssLScr\ LC0nKywtJyssJUg9OjczORuqKUl4RAMNBCldQ1SGKUl4RAMNBCldQ1SGKUl4RAMNBCldQ1SGKUl4\ RAMNBCldQ1QAAAACAAD/ZADhAbAACgAWAAA3IgYdATY3NjU0JjcyFhUUBwYjETMRNmcUKyImKx0H\ IzlLUkQoI3omE7kPODsvGyYmMiNJTFICTP68NAAAAgAA/oYAxQF6AAMADAAAFzc1BxEVNxEjNQcR\ NxyQkKkZrAFlLZYtAUnoNP3A4jMCQwEAAAIAAP6YAP8BaAADAB8AADcVNzUDIzUHNTc1BzU3NTMV\ NzUzFTcVBxU3FQcVIzUHU1paHjU1NTUeWh01NTU1HVpGpxun/jejD1wPpw9aD6ifHKujD1wPpw9a\ D6ifHAAAAAEAFP+EAQsAegAeAAAXNSYnBzAVIzUzNycwIzUzFRYXNzA1MxUjBgcXMDMVwygMM0g5\ MzM5SCESNEg5IRM0OXw7Jg0zO0oyMkg5IhEzOUciETRIAAQAAP9qAWwBsAAOABwAKwA6AAA3DgEd\ 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\ ICAfGR0bIsoMKCggIB8ZHRsiygwoKCAgHxkdGyLLCQQpKB8gHhkdG00CAvtuDAAAAAEAAP0MAhkC\ rgBWAAAlBiMiJjU0NjMyFhUUBzI/AQYjIiY1NDYzMhYVFAcyPwEiDgEjIiY1NDYzMhYVFAcyNzYy\ FwEnEwYjIiY1NDYzMhYVFAcyPwEGIyImNTQ2MzIWFRQHMjcBPyghKzcnGxwpF0ELNigfKzcnGxwp\ Fz8LNAEgHBMrNycbHCkXSC4BFgP+ai1VKCErNycbHCkXQQs6KCErNycbHCkXQQs0DCgoICAfGR0b\ IsQMKCggIB8ZHRsixwkEKSgfIB4ZHRtNAgL6gAwBJAwoKCAgHxkdGyLIDCgoICAfGR0bIgAD//D/\ BgImAPoABwAPABMAADYiJjQ2MhYUACImNDYyFhQFATMBUDIjIzIjAYgyIyMyI/3SAbh+/kdLIzIj\ IzL+zyMyIyMyWgH0/gwABP/h/wYDBwD6AAcADwATABcAADYiJjQ2MhYUACImNDYyFhQFATMBMwEz\ AUEyIyMyIwJ3MiMjMiP84wG4e/5HeQG4e/5HSyMyIyMy/s8jMiMjMloB9P4MAfT+DAAC/7T/iAF8\ ARgAEQA7AAA3FjMyNjc2NTQnJiMiBgcGFRQXIicHMzIUKwEiNDsBEzY1NCMiDgMHBiY3Njc2MzIW\ Fz4BMzIWFRQGxQIFEjIODQ8CBBI1Cw8nKhktNAsL4QsLS2gGCwgMDwsZCgUbBTEPFyUjJAcdJiMe\ LVkoATUkICYlBQEzHCckKS4geh4eAR0SDA8HFBIsEAgPCVgQGRMaHg80MElrAAAB/9v/9gG+ARgA\ UwAANwYHBisBIj8BNiYjIgYHBiY3PgMzMhc2MzIXPgEzMhYVFA8BBhUUMzI3PgU3NhYHDgIjIiY1\ ND8BNjU0IyIPAQYHJwYmPwE2NTQjIgdQBwgEBDUNDUIEBggNFiQFFQQUECIfEjcLJCQtCQspExkk\ BS8ECAEEBQsHDAMNAQYVBhIXLR8VGQU0ARUbCEEIDyYNCARDARUbCBURAwEapw0PGjkIDAklGjAS\ KCgoEBgjGgsPfQsJDgIDCQYPBRIBCQ0LHx8aFhMNDYgCBA4UqxYBAQEPCKsCBA4UAAAAAf9+/2AB\ XgG4AEEAAAciJjU0NjMyFhUUBwYVFDMyPgc3IyI1NDsBPgEzMhYVFAYjIiY1NDc2NCMiDgcHMzIU\ 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\ AwGbFGk0IDAXExIXEgoZBwwKBwgFBgMGATYUFD8hdl8gMBcTEhcSChkLEA8LDQoPDRTmxcEmIBoi\ FA8OCwcNDgYREyUkPDdVJxUTS18mIBoiFA8OCwYccwwGAUtfJiAaIhQPDgsGHAULChQNGg0eBijF\ wSYgGiIUDw4LBw0OBhETJSQ8N1UAAAAB/37/YAN0AbgAqgAAEzM+ATMyFhUUBiMiJjU0NzY0IyIH\ BgcXPgEzMhYVFAYjIiY1NDc2NCMiDgcHMzIUKwEOASMiJjU0NjMyFhUUBwYVFDMyPgc3Iw4BIyIm\ NTQ2MzIWFRQHBhUUMzI+BzcjDgEjIiY1NDYzMhYVFAcGFRQzMj4HNyMiNTQ7AT4BMzIWFRQGIyIm\ NTQ3NjQjIg4CBwbMnBRpNCAwFxMSFxIKGSYXAwGbFGk0IDAXExIXEgoZBwwKBwgFBgMGATYTEz8h\ dl8gMBcTEhcSChkLEA8LDQoPDRQKmyF2XyAwFxMSFxIKGQsQDwsNCg4NFQqbIXZfIDAXExIXEgoZ\ CxAPCw0KDg0UCjUTEUEUaTQgMBcTEhcSChkOFQ4IBgIBDktfJiAaIhQPDgsGHHMMBgFLXyYgGiIU\ Dw4LBhwFCwoUDRoNHgYoxcEmIBoiFA8OCwcNDgYREyUkPDdVJ8XBJiAaIhQPDgsHDQ4GERMlJDs4\ VSfFwSYgGiIUDw4LBw0OBhETJSQ8N1UnFRNLXyYgGiIUDw4LBhwTJyIbCgAB/37/YASAAbgA4AAA\ ARc+ATMyFhUUBiMiJjU0NzY0IyIHBgcXPgEzMhYVFAYjIiY1NDc2NCMiDgcHMzIUKwEOASMiJjU0\ NjMyFhUUBwYVFDMyPgc3Iw4BIyImNTQ2MzIWFRQHBhUUMzI+BzcjDgEjIiY1NDYzMhYVFAcGFRQz\ Mj4HNyMOASMiJjU0NjMyFhUUBwYVFDMyPgc3IyI1NDsBPgEzMhYVFAYjIiY1NDc2NCMiBwYHFz4B\ MzIWFRQGIyImNTQ3NjQjIg4HAdicFGk0IDAXExIXEgoZJhcDAZsUaTQgMBcTEhcSChkHDAoHCAUG\ AwYBNhMTPyF2XyAwFxMSFxIKGQsQDwsNCg8NFAqbIXZfIDAXExIXEgoZCxAPCw0KDg0UCpshdl8g\ MBcTEhcSChkLEA8LDQoPDRQKmyF2XyAwFxMSFxIKGQsQDwsNCg4NFAo1ExFBFGk0IDAXExIXEgoZ\ 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\ Abn+b0ZpOCdFahwBTu81XEdOdUlIckFJ7wAAAAACAAD/eQILAqgAHwAoAAAlNREzHgQVFAcWFRQH\ NjU0JiMRFAYjIiY1NDYzMhMeARc0NjU0JgEiHgkwODYjFRYiBXY4eVkyPHpYMT0OhRsBdmvmAVck\ RztCWDMlMjAkLkEZIV+e/tZGaTgnRWoBdjuiNQMOA1+fAAABAAD/zgBkADIABwAAFiImNDYyFhRH\ Kh0dKh0yHSodHSoAAAAAAA4ArgABAAAAAAAAAIMBCAABAAAAAAABAAcBnAABAAAAAAACAAcBtAAB\ AAAAAAADAB8B/AABAAAAAAAEAAcCLAABAAAAAAAFAAgCRgABAAAAAAAGAAcCXwADAAEECQAAAQYA\ AAADAAEECQABAA4BjAADAAEECQACAA4BpAADAAEECQADAD4BvAADAAEECQAEAA4CHAADAAEECQAF\ ABACNAADAAEECQAGAA4CTwBDAG8AcAB5AHIAaQBnAGgAdAAgAFwAMgA1ADEAIAAyADAAMQA4AC0A\ MgAwADEAOQAgAEoAZQBhAG4ALQBGAHIAYQBuAGMAbwBpAHMAIABNAG8AaQBuAGUALgAgAFQAaABp\ AHMAIABmAG8AbgB0ACAAaQBzACAAbABpAGMAZQBuAHMAZQBkACAAdQBuAGQAZQByACAAdABoAGUA\ IABTAEkATAAgAE8AcABlAG4AIABGAG8AbgB0ACAATABpAGMAZQBuAHMAZQAgAFwAKABoAHQAdABw\ ADoALwAvAHMAYwByAGkAcAB0AHMALgBzAGkAbAAuAG8AcgBnAC8ATwBGAEwAXAApAC4AAENvcHly\ aWdodCBcMjUxIDIwMTgtMjAxOSBKZWFuLUZyYW5jb2lzIE1vaW5lLiBUaGlzIGZvbnQgaXMgbGlj\ ZW5zZWQgdW5kZXIgdGhlIFNJTCBPcGVuIEZvbnQgTGljZW5zZSBcKGh0dHA6Ly9zY3JpcHRzLnNp\ bC5vcmcvT0ZMXCkuAABhAGIAYwAyAHMAdgBnAABhYmMyc3ZnAABSAGUAZwB1AGwAYQByAABSZWd1\ bGFyAABGAG8AbgB0AEYAbwByAGcAZQAgADoAIABhAGIAYwAyAHMAdgBnACAAOgAgADEANAAtADQA\ LQAyADAAMgAzAABGb250Rm9yZ2UgOiBhYmMyc3ZnIDogMTQtNC0yMDIzAABhAGIAYwAyAHMAdgBn\ AABhYmMyc3ZnAABWAGUAcgBzAGkAbwBuACAAAFZlcnNpb24gAABhAGIAYwAyAHMAdgBnAABhYmMy\ c3ZnAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJIAAAABAAIBAgADAQMBBAEF\ AQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BHwEgASEB\ IgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgEvATABMQEyATMBNAE1ATYBNwE4ATkBOgE7ATwBPQE+\ AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoB\ WwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3\ AXgBeQF6AXsBfAF9AX4BfwGAAYEBggGDAYQBhQGGAYcBiAGJAYoBiwGMAY0BjgGPBi5ub2RlZgd1\ bmlFMDAwB3VuaUUwMzAHdW5pRTAzOAd1bmlFMDM5B3VuaUUwNDMHdW5pRTA0NQd1bmlFMDQ2B3Vu\ aUUwNDcHdW5pRTA0OAd1bmlFMDUwB3VuaUUwNUMHdW5pRTA2Mgd1bmlFMDY5B3VuaUUwN0EHdW5p\ RTA3Qgd1bmlFMDdDB3VuaUUwN0QHdW5pRTA3RQd1bmlFMDgwB3VuaUUwODEHdW5pRTA4Mgd1bmlF\ MDgzB3VuaUUwODQHdW5pRTA4NQd1bmlFMDg2B3VuaUUwODcHdW5pRTA4OAd1bmlFMDg5B3VuaUUw\ OEEHdW5pRTA4Qgd1bmlFMDhDB3VuaUUwOTQHdW5pRTA5NQd1bmlFMEEwB3VuaUUwQTEHdW5pRTBB\ Mgd1bmlFMEEzB3VuaUUwQTQHdW5pRTBBOQd1bmlFMEIzB3VuaUUxMDEHdW5pRTFCOQd1bmlFMUJC\ B3VuaUUxRTcHdW5pRTFGMgd1bmlFMUY0B3VuaUUxRjcHdW5pRTFGOQd1bmlFMUZDB3VuaUUxRkUH\ dW5pRTFGRgd1bmlFMjAwB3VuaUUyNDAHdW5pRTI0MQd1bmlFMjQyB3VuaUUyNDMHdW5pRTI0NAd1\ bmlFMjQ1B3VuaUUyNDYHdW5pRTI0Nwd1bmlFMjQ4B3VuaUUyNDkHdW5pRTI2MAd1bmlFMjYxB3Vu\ aUUyNjIHdW5pRTI2Mwd1bmlFMjY0B3VuaUUyNmEHdW5pRTI2Ygd1bmlFMjgwB3VuaUUyODEHdW5p\ RTI4Mgd1bmlFMjgzB3VuaUU0QTAHdW5pRTRBMgd1bmlFNEE0B3VuaUU0QTgHdW5pRTRBQwd1bmlF\ NEMwB3VuaUU0Q0UHdW5pRTREMQd1bmlFNEUxB3VuaUU0RTIHdW5pRTRFMwd1bmlFNEU0B3VuaUU0\ RTUHdW5pRTRFNgd1bmlFNEU3B3VuaUU0RTgHdW5pRTRFOQd1bmlFNEVBB3VuaUU1MDAHdW5pRTUw\ MQd1bmlFNTIwB3VuaUU1MjEHdW5pRTUyMgd1bmlFNTIzB3VuaUU1MjQHdW5pRTUyNQd1bmlFNTI5\ B3VuaUU1MkEHdW5pRTUyQgd1bmlFNTJDB3VuaUU1MkQHdW5pRTUyRgd1bmlFNTMwB3VuaUU1MzEH\ dW5pRTUzOQd1bmlFNTY2B3VuaUU1NjcHdW5pRTU2OQd1bmlFNTZDB3VuaUU1NkQHdW5pRTU4Mgd1\ bmlFNUQwB3VuaUU1RTIHdW5pRTYxMAd1bmlFNjEyB3VuaUU2MTQHdW5pRTYxOAd1bmlFNjI0B3Vu\ aUU2MzAHdW5pRTY1MAd1bmlFNjU1B3VuaUU5MTAHdW5pRTkxMQd1bmlFOTEyB3VuaUU5MTQHdW5p\ RTkxNQd1bmlFOTE4B3VuaUU5MjAHdW5pRTkyNQd1bmlFOTVEB3VuaUVBMDIHdW5pRUFBNAd1bmlF\ Q0EyB3VuaUVDQTMHdW5pRUNBNQd1bmlFQ0E3B3VuaUVDQTkHdW5pRUNCNwAAAAAAAAH//wACAAEA\ AAAAAAAADAAUAAQAAAACAAAAAQAAAAEAAAAAAAEAAAAA399K6gAAAADRlyIXAAAAAOBezeg=\ ") format("truetype")' var font_scale_tb={serif:1,serifBold:1,'sans-serif':1,'sans-serifBold':1,Palatino:1.1,monospace:1.35},txt_ff="text,serif",fmt_lock={} var cfmt={"abc-version":"1",annotationfont:{name:"text,sans-serif",size:12},aligncomposer:1,beamslope:.4,bardef:{"[":"","[]":"","|:":"[|:","|::":"[|::","|:::":"[|:::",":|":":|]","::|":"::|]",":::|":":::|]","::":":][:"},breaklimit:.7,breakoneoln:true,cancelkey:true,composerfont:{name:txt_ff,style:"italic",size:14},composerspace:6,decoerr:true,dynalign:true,footerfont:{name:txt_ff,size:16},fullsvg:'',gchordfont:{name:"text,sans-serif",size:12},gracespace:new Float32Array([6,8,11]),graceslurs:true,headerfont:{name:txt_ff,size:16},historyfont:{name:txt_ff,size:16},hyphencont:true,indent:0,infofont:{name:txt_ff,style:"italic",size:14},infoname:'R "Rhythm: "\n\ B "Book: "\n\ S "Source: "\n\ D "Discography: "\n\ N "Notes: "\n\ Z "Transcription: "\n\ H "History: "',infospace:0,keywarn:true,leftmargin:1.4*CM,lineskipfac:1.1,linewarn:true,maxshrink:.65,maxstaffsep:2000,maxsysstaffsep:2000,measrepnb:1,measurefont:{name:txt_ff,style:"italic",size:10},measurenb:-1,musicfont:{name:"music",src:musicfont,size:24},musicspace:6,partsfont:{name:txt_ff,size:15},parskipfac:.4,partsspace:8,pagewidth:21*CM,"propagate-accidentals":"o",printmargin:0,rightmargin:1.4*CM,rbmax:4,rbmin:2,repeatfont:{name:txt_ff,size:9},scale:1,slurheight:1.0,spatab:new Float32Array([10.2,13.3,17.3,22.48,29.2,38,49.4,64.2,83.5,108.5]),staffsep:46,stemheight:21,stretchlast:.25,stretchstaff:true,subtitlefont:{name:txt_ff,size:16},subtitlespace:3,sysstaffsep:34,tempofont:{name:txt_ff,weight:"bold",size:12},textfont:{name:txt_ff,size:16},textspace:14,tieheight:1.0,titlefont:{name:txt_ff,size:20},titlespace:6,titletrim:true,topspace:22,tuplets:[0,0,0,0],tupletfont:{name:txt_ff,style:"italic",size:12},vocalfont:{name:txt_ff,weight:"bold",size:13},vocalspace:10,voicefont:{name:txt_ff,weight:"bold",size:13},writefields:"CMOPQsTWw",wordsfont:{name:txt_ff,size:16},wordsspace:5,"writeout-accidentals":"n"} var sfmt={bardef:true,barsperstaff:true,beamslope:true,breaklimit:true,bstemdown:true,cancelkey:true,dynalign:true,flatbeams:true,gracespace:true,hyphencont:true,keywarn:true,maxshrink:true,maxstaffsep:true,measrepnb:true,rbmax:true,rbmin:true,shiftunison:true,slurheight:true,squarebreve:true,staffsep:true,stemheight:true,stretchlast:true,stretchstaff:true,tieheight:true,timewarn:true,vocalspace:true} function get_bool(param){return!param||!/^(0|n|f)/i.test(param)} function get_font_scale(param){var i,font,a=info_split(param) if(a.length<=1) return var scale=+a[a.length-1] if(isNaN(scale)||scale<=0.5){syntax(1,"Bad scale value in %%font") return} font_scale_tb[a[0]]=scale} function set_font_fac(font){var scale=font_scale_tb[font.fname||font.name] if(!scale) scale=1.1;font.swfac=font.size*scale} function param_set_font(xxxfont,p){var font,n,a,ft2,k if(xxxfont[xxxfont.length-2]=='-'){n=xxxfont[xxxfont.length-1] if(n<'1'||n>'9') return xxxfont="u"+n+"font"} font={} a=p.match(/\s+(no)?box(\s|$)/) if(a){if(a[1]){font.box=false font.pad=0}else{font.box=true font.pad=2.5} p=p.replace(a[0],a[2])} a=p.match(/\s+padding=([\d.]+)(\s|$)/) if(a){font.pad=a[1]?+a[1]:0 p=p.replace(a[0],a[2])} a=p.match(/\s+class=(.*?)(\s|$)/) if(a){font.class=a[1];p=p.replace(a[0],a[2])} a=p.match(/\s+wadj=(.*?)(\s|$)/) if(a){if(typeof document=="undefined") switch(a[1]){case'none':font.wadj='' break case'space':font.wadj='spacing' break case'glyph':font.wadj='spacingAndGlyphs' break default:syntax(1,errs.bad_val,"%%"+xxxfont) break} p=p.replace(a[0],a[2])} a=p.match(/\s+([0-9.]+|\*)$/) if(a){if(a[1]!="*") font.size=+a[1] p=p.replace(a[0],"")} if(p[0]=='u'&&p.slice(0,4)=="url("){n=p.indexOf(')',1) if(n<0){syntax(1,"No end of url in font family") return} font.src=p.slice(0,n+1) font.fid=abc2svg.font_tb.length abc2svg.font_tb.push(font) font.name='ft'+font.fid p=p.replace(font.src,'')} a=p.match(/[- ]?[nN]ormal/) if(a){font.normal=true p=p.replace(a[0],'')} a=p.match(abc2svg.ft_re) if(a){font.weight=abc2svg.ft_w[a[0].replace(/[ -]/,'').toLowerCase()] p=p.replace(a[0],'')} a=p.match(/[- ]?[iI]talic/) if(a){font.style="italic" p=p.replace(a[0],'')} a=p.match(/[- ]?[oO]blique/) if(a){font.style="oblique" p=p.replace(a[0],'')} if(!font.src){if(p[0]=='"'){n=p.indexOf('"',1) if(n<0){syntax(1,"No end of string in font family") return} p=p.slice(1,n)} p=p.trim() switch(p){case"":case"*":p="";break case"Times-Roman":case"Times":p="serif";break case"Helvetica":p="sans-serif";break case"Courier":p="monospace";break case"music":p=cfmt.musicfont.name;break default:if(p.indexOf("Fig")>0) font.figb=true break}} if(p&&!font.name) font.name=p if(font.size) set_font_fac(font) if(!font.name||!font.size){ft2=cfmt[xxxfont] for(k in ft2){if(!ft2.hasOwnProperty(k)||font[k]!=undefined) continue switch(k){case"fid":case"used":break case"style":case"weight":if(font.normal) break default:font[k]=ft2[k] break}} if(!font.swfac) set_font_fac(font)} if(font.pad==undefined) font.pad=0 font.fname=font.name if(font.weight>=700) font.fname+='Bold' cfmt[xxxfont]=font} function get_unit(param){var v=param.toLowerCase().match(/(-?[\d.]+)(.*)/) if(!v) return NaN v[1]=+v[1] switch(v[2]){case"cm":return v[1]*CM case"in":return v[1]*IN case"pt":return v[1]*.75 case"px":case"":return v[1]} return NaN} function set_infoname(param){var tmp=cfmt.infoname.split("\n"),letter=param[0] for(var i=0;i0) v=v.slice(0,i) return textopt[v]} var posval={above:C.SL_ABOVE,auto:0,below:C.SL_BELOW,down:C.SL_BELOW,hidden:C.SL_HIDDEN,opposite:C.SL_HIDDEN,under:C.SL_BELOW,up:C.SL_ABOVE} function set_pos(k,v){k=k.slice(0,3) if(k=="ste") k="stm" set_v_param("pos",'"'+k+' '+v+'"')} function set_writefields(parm){var c,i,a=parm.split(/\s+/) if(get_bool(a[1])){for(i=0;i=0) cfmt.writefields=cfmt.writefields.replace(c,'')}}} function set_v_param(k,v){k=[k+'=',v] if(parse.state<3) memo_kv_parm(curvoice?curvoice.id:'*',k) else if(curvoice) set_kv_parm(k) else memo_kv_parm('*',k)} function set_page(){if(!img.chg) return img.chg=false;img.lm=cfmt.leftmargin-cfmt.printmargin if(img.lm<0) img.lm=0;img.rm=cfmt.rightmargin-cfmt.printmargin if(img.rm<0) img.rm=0;img.width=cfmt.pagewidth-2*cfmt.printmargin if(img.width-img.lm-img.rm<100){error(0,undefined,"Bad staff width");img.width=img.lm+img.rm+150} img.lw=(img.width-img.lm-img.rm -2) / cfmt.scale set_posx()} Abc.prototype.set_format=function(cmd,param){var f,f2,v,i if(/.+font(-[\d])?$/.test(cmd)){if(cmd=="soundfont") cfmt.soundfont=param else param_set_font(cmd,param) return} if(sfmt[cmd]&&parse.ufmt) cfmt=Object.create(cfmt) switch(cmd){case"aligncomposer":case"barsperstaff":case"infoline":case"measurenb":case"rbmax":case"rbmin":case"measrepnb":case"shiftunison":v=parseInt(param) if(isNaN(v)){syntax(1,"Bad integer value");break} cfmt[cmd]=v break case"abc-version":case"bgcolor":case"fgcolor":case"propagate-accidentals":case"titleformat":case"writeout-accidentals":cfmt[cmd]=param break case"beamslope":case"breaklimit":case"lineskipfac":case"maxshrink":case"pagescale":case"parskipfac":case"scale":case"slurheight":case"stemheight":case"tieheight":f=+param if(isNaN(f)||!param||f<0){syntax(1,errs.bad_val,'%%'+cmd) break} switch(cmd){case"scale":f/=.75 case"pagescale":if(f<.1) f=.1 cmd="scale";img.chg=true break} cfmt[cmd]=f break case"annotationbox":case"gchordbox":case"measurebox":case"partsbox":param_set_font(cmd.replace("box","font"),"* * "+(get_bool(param)?"box":"nobox")) break case"altchord":case"bstemdown":case"breakoneoln":case"cancelkey":case"checkbars":case"contbarnb":case"custos":case"decoerr":case"flatbeams":case"graceslurs":case"graceword":case"hyphencont":case"keywarn":case"linewarn":case"quiet":case"squarebreve":case"splittune":case"straightflags":case"stretchstaff":case"timewarn":case"titlecaps":case"titleleft":cfmt[cmd]=get_bool(param) break case"dblrepbar":param=":: "+param case"bardef":v=param.split(/\s+/) if(v.length!=2){syntax(1,errs.bad_val,"%%bardef")}else{if(parse.ufmt) cfmt.bardef=Object.create(cfmt.bardef) cfmt.bardef[v[0]]=v[1]} break case"chordalias":v=param.split(/\s+/) if(!v.length) syntax(1,errs.bad_val,"%%chordalias") else abc2svg.ch_alias[v[0]]=v[1]||"" break case"composerspace":case"indent":case"infospace":case"maxstaffsep":case"maxsysstaffsep":case"musicspace":case"partsspace":case"staffsep":case"subtitlespace":case"sysstaffsep":case"textspace":case"titlespace":case"topspace":case"vocalspace":case"wordsspace":f=get_unit(param) if(isNaN(f)) syntax(1,errs.bad_val,'%%'+cmd) else cfmt[cmd]=f break case"page-format":user.page_format=get_bool(param) break case"print-leftmargin":syntax(0,"$1 is deprecated - use %%printmargin instead",'%%'+cmd) cmd="printmargin" case"printmargin":case"leftmargin":case"pagewidth":case"rightmargin":f=get_unit(param) if(isNaN(f)){syntax(1,errs.bad_val,'%%'+cmd) break} cfmt[cmd]=f;img.chg=true break case"concert-score":if(cfmt.sound!="play") cfmt.sound="concert" break case"writefields":set_writefields(param) break case"volume":cmd="dynamic" case"dynamic":case"gchord":case"gstemdir":case"ornament":case"stemdir":case"vocal":set_pos(cmd,param) break case"font":get_font_scale(param) break case"fullsvg":if(parse.state!=0){syntax(1,errs.not_in_tune,"%%fullsvg") break} cfmt[cmd]=param break case"gracespace":v=param.split(/\s+/) for(i=0;i<3;i++) if(isNaN(+v[i])){syntax(1,errs.bad_val,"%%gracespace") break} if(parse.ufmt) cfmt[cmd]=new Float32Array(3) for(i=0;i<3;i++) cfmt[cmd][i]=+v[i] break case"tuplets":v=param.split(/\s+/) f=v[3] if(f) f=posval[f] if(f) v[3]=f if(curvoice) curvoice.tup=v else cfmt[cmd]=v break case"infoname":set_infoname(param) break case"notespacingfactor":v=param.match(/([.\d]+)[,\s]*(\d+)?/) if(v){f=+v[1] if(isNaN(f)||f<1||f>2){f=0}else if(v[2]){f2=+v[2] if(isNaN(f)) f=0}else{f2=cfmt.spatab[5]}} if(!f){syntax(1,errs.bad_val,"%%"+cmd) break} cfmt[cmd]=param cfmt.spatab=new Float32Array(10) i=5;do{cfmt.spatab[i]=f2 f2/=f}while(--i>=0) i=5;f2=cfmt.spatab[i] for(;++i1){syntax(1,errs.bad_val,'%%'+cmd) break}} cfmt[cmd]=v break case"combinevoices":syntax(1,"%%combinevoices is deprecated - use %%voicecombine instead") break case"voicemap":set_v_param("map",param) break case"voicescale":set_v_param("scale",param) break case"rbdbstop":v=get_bool(param) if(v&&cfmt["abc-version"]>="2.2") cfmt["abc-version"]="1" else if(!v&&cfmt["abc-version"]<"2.2") cfmt["abc-version"]="2.2" break default:if(!parse.state) cfmt[cmd]=param break} if(sfmt[cmd]&&parse.ufmt){parse.ufmt=false}} function st_font(font){var n=font.name,r="" if(font.weight) r+=font.weight+" " if(font.style) r+=font.style+" " if(n.indexOf('"')<0&&n.indexOf(' ')>0) n='"'+n+'"' return r+font.size.toFixed(1)+'px '+n} function style_font(font){return'font:'+st_font(font)} Abc.prototype.style_font=style_font function font_class(font){var f='f'+font.fid+cfmt.fullsvg if(font.class) f+=' '+font.class if(font.box) f+=' '+'box' return f} function use_font(font){if(!font.used){font.used=true;if(font.fid==undefined){font.fid=abc2svg.font_tb.length abc2svg.font_tb.push(font) if(!font.swfac) set_font_fac(font) if(!font.pad) font.pad=0} add_fstyle(".f"+font.fid+ (cfmt.fullsvg||"")+"{"+style_font(font)+"}") if(font.src) add_fstyle("@font-face{\n\ font-family:"+font.name+";\n\ src:"+font.src+"}") if(font==cfmt.musicfont) add_fstyle(".f"+font.fid +(cfmt.fullsvg||"") +' text,tspan{white-space:pre}')}} function get_font(fn){var font,font2,fid,st fn+="font" font=cfmt[fn] if(!font){syntax(1,"Unknown font $1",fn) return gene.curfont} if(!font.name||!font.size){font2=Object.create(gene.deffont) if(font.name) font2.name=font.name if(font.normal){if(font2.weight) font2.weight=null if(font2.style) font2.style=null}else{if(font.weight) font2.weight=font.weight if(font.style) font2.style=font.style} if(font.src) font2.src=font.src if(font.size) font2.size=font.size st=st_font(font2) if(font.class){font2.class=font.class st+=' '+font.class} fid=abc2svg.font_st[st] if(fid!=undefined) return abc2svg.font_tb[fid] abc2svg.font_st[st]=abc2svg.font_tb.length font2.fid=font2.used=undefined font=font2} use_font(font) return font} var sav={},mac={},maci={},modone={} var abc_utf={"=D":"Đ","=H":"Ħ","=T":"Ŧ","=d":"Ä‘","=h":"ħ","=t":"ŧ","/O":"Ø","/o":"ø","/L":"Ł","/l":"Å‚","vL":"Ľ","vl":"ľ","vd":"ď",".i":"ı","AA":"Ã…","aa":"Ã¥","AE":"Æ","ae":"æ","DH":"Ð","dh":"ð","OE":"Å’","oe":"Å“","ss":"ß","TH":"Þ","th":"þ"} var oct_acc={"1":"\u266f","2":"\u266d","3":"\u266e","4":"𝄪","5":"𝄫"} function cnv_escape(src,flag){var c,c2,dst="",i,j=0 while(1){i=src.indexOf('\\',j) if(i<0) break dst+=src.slice(j,i);c=src[++i] if(!c) return dst+'\\' switch(c){case'0':case'2':if(src[i+1]!='0') break c2=oct_acc[src[i+2]] if(c2){dst+=c2;j=i+3 continue} break case'u':j=Number("0x"+src.slice(i+1,i+5));if(isNaN(j)||j<0x20){dst+=src[++i]+"\u0306" j=i+1 continue} c=String.fromCharCode(j) if(c=='\\'){i+=4 break} dst+=c j=i+5 continue case't':dst+='\t';j=i+1 continue case'n':dst+='\n';j=i+1 continue default:c2=abc_utf[src.slice(i,i+2)] if(c2){dst+=c2;j=i+2 continue} c2=src[i+1] if(!c2) break if(!/[A-Za-z]/.test(c2)) break switch(c){case'`':dst+=c2+"\u0300" j=i+2 continue case"'":dst+=c2+"\u0301" j=i+2 continue case'^':dst+=c2+"\u0302" j=i+2 continue case'~':dst+=c2+"\u0303" j=i+2 continue case'=':dst+=c2+"\u0304" j=i+2 continue case'_':dst+=c2+"\u0305" j=i+2 continue case'.':dst+=c2+"\u0307" j=i+2 continue case'"':dst+=c2+"\u0308" j=i+2 continue case'o':dst+=c2+"\u030a" j=i+2 continue case'H':dst+=c2+"\u030b" j=i+2 continue case'v':dst+=c2+"\u030c" j=i+2 continue case'c':dst+=c2+"\u0327" j=i+2 continue case';':dst+=c2+"\u0328" j=i+2 continue} break} if(flag=='w') dst+='\\' dst+=c j=i+1} return dst+src.slice(j)} var include=0 function do_include(fn){var file,parse_sav if(!user.read_file){syntax(1,"No read_file support") return} if(include>2){syntax(1,"Too many include levels") return} file=user.read_file(fn) if(!file){syntax(1,"Cannot read file '$1'",fn) return} include++;parse_sav=clone(parse);tosvg(fn,file);parse_sav.state=parse.state;parse=parse_sav;include--} function tosvg(in_fname,file,bol,eof){var i,c,eol,end,select,line0,line1,last_info,opt,text,a,b,s,pscom,txt_add='\n' function tune_selected(){var re,res,i=file.indexOf('K:',bol) if(i<0){return false} i=file.indexOf('\n',i) if(parse.select.test(file.slice(parse.bol,i))) return true re=/\n\w*\n/;re.lastIndex=i;res=re.exec(file) if(res) eol=re.lastIndex else eol=eof return false} function uncomment(src,flag){if(!src) return src var i=src.indexOf('%') if(i==0) return'' if(i>0) src=src.replace(/([^\\])%.*/,'$1').replace(/\\%/g,'%');src=src.replace(/\s+$/,'') if(flag&&src.indexOf('\\')>=0) return cnv_escape(src,flag) return src} function end_tune(){generate() cfmt=sav.cfmt;info=sav.info;char_tb=sav.char_tb;glovar=sav.glovar;maps=sav.maps;mac=sav.mac;maci=sav.maci;parse.tune_v_opts=null;parse.scores=null;parse.ufmt=false delete parse.ctrl init_tune() img.chg=true;set_page()} function do_voice(select,in_tune){var opt,bol if(select=="end") return if(in_tune){if(!parse.tune_v_opts) parse.tune_v_opts={};opt=parse.tune_v_opts}else{if(!parse.voice_opts) parse.voice_opts={};opt=parse.voice_opts} opt[select]=[] while(1){bol=++eol if(file[bol]!='%') break eol=file.indexOf('\n',eol);if(file[bol+1]!=line1) continue bol+=2 if(eol<0) text=file.slice(bol) else text=file.slice(bol,eol);a=text.match(/\S+/) switch(a[0]){default:opt[select].push(uncomment(text,true)) continue case"score":case"staves":case"tune":case"voice":bol-=2 break} break} eol=parse.eol=bol-1} function tune_filter(){var o,opts,j,pc,h,i=file.indexOf('K:',bol) i=file.indexOf('\n',i);h=file.slice(parse.bol,i) for(i in parse.tune_opts){if(!parse.tune_opts.hasOwnProperty(i)) continue if(!(new RegExp(i)).test(h)) continue opts=parse.tune_opts[i] for(j=0;jeof) eol=eof;parse.eol=eol while(1){eol-- switch(file[eol]){case' ':case'\t':continue} break} eol++ if(eol==bol){if(parse.state==1){parse.istart=bol;syntax(1,"Empty line in tune header - ignored")}else if(parse.state>=2){end_tune() parse.state=0 if(parse.select){eol=file.indexOf('\nX:',parse.eol) if(eol<0) eol=eof parse.eol=eol}} continue} parse.istart=parse.bol=bol;parse.iend=eol;parse.line.index=0;line0=file[bol];line1=file[bol+1] if((line0=='I'&&line1==':')||line0=='%'){if(line0=='%'&&parse.prefix.indexOf(line1)<0) continue if(file[bol+2]=='a'&&file[bol+3]=='b'&&file[bol+4]=='c'&&file[bol+5]==' '){bol+=6;line0=file[bol];line1=file[bol+1]}else{pscom=true}} if(pscom){pscom=false;bol+=2 text=file.slice(bol,eol) a=text.match(/([^\s]+)\s*(.*)/) if(!a||a[1][0]=='%') continue switch(a[1]){case"abcm2ps":case"ss-pref":parse.prefix=a[2] continue case"abc-include":do_include(uncomment(a[2])) continue} if(a[1].slice(0,5)=='begin'){b=a[1].substr(5);end='\n'+line0+line1+"end"+b;i=file.indexOf(end,eol) if(i<0){syntax(1,"No $1 after %%$2",end.slice(1),a[1]);parse.eol=eof continue} self.do_begin_end(b,uncomment(a[2]),file.slice(eol+1,i).replace(/\n%[^%].*$/gm,'').replace(/^%%/gm,'')) parse.eol=file.indexOf('\n',i+6) if(parse.eol<0) parse.eol=eof continue} switch(a[1]){case"select":if(parse.state!=0){syntax(1,errs.not_in_tune,"%%select") continue} select=uncomment(text.slice(7)) if(select[0]=='"') select=select.slice(1,-1);if(!select){delete parse.select continue} select=select.replace(/\(/g,'\\(');select=select.replace(/\)/g,'\\)');parse.select=new RegExp(select,'m') continue case"tune":if(parse.state!=0){syntax(1,errs.not_in_tune,"%%tune") continue} select=uncomment(a[2]) if(!select){parse.tune_opts={} continue} if(select=="end") continue if(!parse.tune_opts) parse.tune_opts={};parse.tune_opts[select]=opt={t_opts:[]};while(1){bol=++eol if(file[bol]!='%') break eol=file.indexOf('\n',eol);if(file[bol+1]!=line1) continue bol+=2 if(eol<0) text=file.slice(bol) else text=file.slice(bol,eol);a=text.match(/([^\s]+)\s*(.*)/) switch(a[1]){case"tune":break case"voice":do_voice(uncomment(a[2],true),true) continue default:opt.t_opts.push(uncomment(text,true)) continue} break} if(parse.tune_v_opts){opt.v_opts=parse.tune_v_opts;parse.tune_v_opts=null} parse.eol=bol-1 continue case"voice":if(parse.state!=0){syntax(1,errs.not_in_tune,"%%voice") continue} select=uncomment(a[2]) if(!select){parse.voice_opts=null continue} do_voice(select) continue} self.do_pscom(uncomment(text,true)) continue} if(line1!=':'||!/[A-Za-z+]/.test(line0)){last_info=undefined;if(parse.state<2) continue parse.line.buffer=uncomment(file.slice(bol,eol)) if(parse.line.buffer) parse_music_line() continue} bol+=2 while(1){switch(file[bol]){case' ':case'\t':bol++ continue} break} if(line0=='+'){if(!last_info){syntax(1,"+: without previous info field") continue} txt_add=' ';line0=last_info} text=uncomment(file.slice(bol,eol),line0) switch(line0){case'X':if(parse.state!=0){syntax(1,errs.ignored,line0) continue} if(parse.select&&!tune_selected()){eol=file.indexOf('\nX:',parse.eol) if(eol<0) eol=eof;parse.eol=eol continue} sav.cfmt=clone(cfmt);sav.info=clone(info,2) sav.char_tb=clone(char_tb);sav.glovar=clone(glovar);sav.maps=clone(maps,1);sav.mac=clone(mac);sav.maci=clone(maci);info.X=text;parse.state=1 if(user.page_format&&blkdiv<1) blkdiv=1 if(parse.tune_opts) tune_filter() continue case'T':switch(parse.state){case 0:continue case 1:case 2:if(info.T==undefined) info.T=text else info.T+="\n"+text continue} s=new_block("title");s.text=text continue case'K':switch(parse.state){case 0:continue case 1:info.K=text break} do_info(line0,text) continue case'W':if(parse.state==0||cfmt.writefields.indexOf(line0)<0) break if(info.W==undefined) info.W=text else info.W+=txt_add+text break case'm':if(parse.state>=2){syntax(1,errs.ignored,line0) continue} a=text.match(/(.*?)[= ]+(.*)/) if(!a||!a[2]){syntax(1,errs.bad_val,"m:") continue} mac[a[1]]=a[2];maci[a[1][0]]=true break case's':if(parse.state!=3||cfmt.writefields.indexOf(line0)<0) break get_sym(text,txt_add==' ') break case'w':if(parse.state!=3||cfmt.writefields.indexOf(line0)<0) break get_lyrics(text,txt_add==' ') break case'|':if(parse.state<2) continue parse.line.buffer=text parse_music_line() continue default:if("ABCDFGHNOSZ".indexOf(line0)>=0){if(parse.state>=2){syntax(1,errs.ignored,line0) continue} if(!info[line0]) info[line0]=text else info[line0]+=txt_add+text break} do_info(line0,text) continue} txt_add='\n';last_info=line0} if(include) return if(parse.state>=2) end_tune();parse.state=0} Abc.prototype.tosvg=tosvg var gene,staff_tb,nstaff,tsnext,realwidth,insert_meter,spf_last,smallest_duration var dx_tb=new Float32Array([10,10,11,13,15]) var hw_tb=new Float32Array([4.7,5,6,7.2,7.5]) var w_note=new Float32Array([3.5,3.7,5,6,7]) function identify_note(s,dur_o){var head,flags,dots=0,dur=dur_o if(dur%12!=0) error(1,s,"Invalid note duration $1",dur);dur/=12 if(!dur) error(1,s,"Note too short") for(flags=5;dur;dur>>=1,flags--){if(dur&1) break} dur>>=1 if((dur+1)&dur){if(s.type!=C.REST||dur_o!=s.p_v.wmeasure) error(0,s,"Non standard note duration $1",dur_o)} while(dur>>dots>0) dots++ flags-=dots if(flags>=0){head=C.FULL}else switch(flags){default:error(1,s,"Note too long") flags=-4 case-4:head=C.SQUARE break case-3:head=s.fmt.squarebreve?C.SQUARE:C.OVALBARS break case-2:head=C.OVAL break case-1:head=C.EMPTY break} return[head,dots,flags]} function set_head_shift(s){var i,i1,i2,d,ps,dx,dx_head=dx_tb[s.head],dir=s.stem,n=s.nhd if(!n) return dx=dx_head*.74 if(s.grace) dx*=.6 if(dir>=0){i1=1;i2=n+1;ps=s.notes[0].pit}else{dx=-dx;i1=n-1;i2=-1;ps=s.notes[n].pit} var shift=false,dx_max=0 for(i=i1;i!=i2;i+=dir){d=s.notes[i].pit-ps;ps=s.notes[i].pit if(!d){if(shift){var new_dx=s.notes[i].shhd=s.notes[i-dir].shhd+dx if(dx_max3||(d>=2&&s.head!=C.SQUARE)){shift=false}else{shift=!shift if(shift){s.notes[i].shhd=dx if(dx_max=0;){dx=notes[i].shhd if(!dx||dx>0) continue dx=dx_head-dx;ps=notes[i].pit for(i1=n;--i1>=0;){if(!notes[i1].acc) continue p1=notes[i1].pit if(p1ps+3) continue if(notes[i1].shac=0;){if(notes[i1].acc){p1=notes[i1].pit dx1=notes[i1].shac if(!dx1){dx1=notes[i1].shhd if(dx1<0) dx1=dx_head-dx1 else dx1=dx_head} break}} if(i1<0) return for(i2=0;i2ps+4){if(dx1>dx2) dx2=dx1 notes[i1].shac=notes[i2].shac=dx2}else{notes[i1].shac=dx1 if(notes[i1].pit!=notes[i2].pit) dx1+=7 notes[i2].shac=dx2=dx1} dx2+=7 for(i=i1;--i>i2;){acc=notes[i].acc if(!acc) continue dx=notes[i].shac if(dxi;){if(!notes[i1].acc) continue p1=notes[i1].pit if(p1>=ps+4){if(p1>ps+4||acc<0||notes[i1].acc<0) continue} if(dx>notes[i1].shac-6){dx1=notes[i1].shac+7 if(dx1>dx) dx=dx1}} notes[i].shac=dx}} function set_acc_shft(){var s,s2,st,i,acc,st,t,dx_head,notes s=tsfirst while(s){if(s.type!=C.NOTE||s.invis){s=s.ts_next continue} st=s.st;t=s.time;acc=false for(s2=s;s2;s2=s2.ts_next){if(s2.time!=t||s2.type!=C.NOTE||s2.st!=st) break if(acc) continue for(i=0;i<=s2.nhd;i++){if(s2.notes[i].acc){acc=true break}}} if(!acc){s=s2 continue} dx_head=dx_tb[s.head] notes=[] for(;s!=s2;s=s.ts_next){if(!s.invis) Array.prototype.push.apply(notes,s.notes)} notes.sort(abc2svg.pitcmp) acc_shift(notes,dx_head)}} function lkvsym(s,next){s.next=next;s.prev=next.prev if(s.prev) s.prev.next=s else s.p_v.sym=s;next.prev=s} function lktsym(s,next){var old_wl s.ts_next=next if(next){s.ts_prev=next.ts_prev if(s.ts_prev) s.ts_prev.ts_next=s;next.ts_prev=s}else{error(2,s,"Bad linkage") s.ts_prev=null} s.seqst=!s.ts_prev||s.time!=s.ts_prev.time||(w_tb[s.ts_prev.type]!=w_tb[s.type]&&!!w_tb[s.ts_prev.type]) if(!next||next.seqst) return next.seqst=next.time!=s.time||(w_tb[s.type]!=w_tb[next.type]&&!!w_tb[s.type]) if(next.seqst){old_wl=next.wl self.set_width(next) if(next.a_ly) ly_set(next) if(!next.shrink){next.shrink=next.wl if(next.prev) next.shrink+=next.prev.wr}else{next.shrink+=next.wl-old_wl} next.space=0}} function unlksym(s){if(s.next) s.next.prev=s.prev if(s.prev) s.prev.next=s.next else s.p_v.sym=s.next if(s.ts_next){if(s.seqst){if(s.ts_next.seqst){s.ts_next.shrink+=s.shrink;s.ts_next.space+=s.space}else{s.ts_next.seqst=true;s.ts_next.shrink=s.shrink;s.ts_next.space=s.space}}else{if(s.ts_next.seqst&&s.ts_prev&&s.ts_prev.seqst&&!w_tb[s.ts_prev.type]){s.ts_next.seqst=false s.shrink=s.ts_next.shrink s.space=s.ts_next.space}} s.ts_next.ts_prev=s.ts_prev} if(s.ts_prev) s.ts_prev.ts_next=s.ts_next if(tsfirst==s) tsfirst=s.ts_next if(tsnext==s) tsnext=s.ts_next} function insert_clef(s,clef_type,clef_line){var p_voice=s.p_v,new_s,st=s.st if(s.type==C.BAR&&s.prev&&s.prev.type==C.BAR&&s.prev.bar_type[0]!=':') s=s.prev;p_voice.last_sym=s.prev if(!p_voice.last_sym) p_voice.sym=null;p_voice.time=s.time;new_s=sym_add(p_voice,C.CLEF);new_s.next=s;s.prev=new_s;new_s.clef_type=clef_type;new_s.clef_line=clef_line;new_s.st=st;new_s.clef_small=true delete new_s.second;new_s.notes=[] new_s.notes[0]={pit:s.notes[0].pit} new_s.nhd=0;while(!s.seqst) s=s.ts_prev;lktsym(new_s,s) if(s.soln){new_s.soln=true delete s.soln} return new_s} function set_float(){var p_voice,st,staff_chg,v,s,s1,up,down for(v=0;v=19){staff_chg=false continue} if(s.notes[s.nhd].pit<=12){staff_chg=true s.st++ continue} up=127 for(s1=s.ts_prev;s1;s1=s1.ts_prev){if(s1.st!=st||s1.v==s.v) break if(s1.type==C.NOTE) if(s1.notes[0].pitup-3){staff_chg=false continue} down=-127 for(s1=s.ts_next;s1;s1=s1.ts_next){if(s1.st!=st+1||s1.v==s.v) break if(s1.type==C.NOTE) if(s1.notes[s1.nhd].pit>down) down=s1.notes[s1.nhd].pit} if(down==-127){if(staff_chg) s.st++ continue} if(s.notes[0].pit=0;m--){if(g.notes[m].shac-2>dx) dx=g.notes[m].shac-2} x+=dx;g.x=x if(g.nflags<=0) g.beam_st=g.beam_end=true next=g.next if(!next){g.beam_end=true break} if(next.nflags<=0) g.beam_end=true if(g.beam_end){next.beam_st=true;x+=gspinside/4} if(g.nflags<=0) x+=gspinside/4 if(g.y>next.y+8) x-=1.5 x+=gspinside} next=s.next if(next&&next.type==C.NOTE){if(g.y>=3*(next.notes[next.nhd].pit-18)) gspright-=1 else if(g.beam_st&&g.y<3*(next.notes[next.nhd].pit-18)-4) gspright+=2} x+=gspright;return x} function set_w_chs(s){var i,ch,w0,s0,dw,x=0,n=0 set_font("vocal") for(;s;s=s.ts_next){if(s.shrink){x+=s.shrink;n++} if(s.a_ly) ly_set(s) if(!s.a_gch) continue for(i=0;ix+ch.x){if(s.prev&&s.prev.seqst&&s.prev.type==C.BAR) n-- dw=(w0-x-ch.x)/n while(1){s0=s0.ts_next if(s0.shrink) s0.shrink+=dw if(s0==s||s0.type==C.BAR) break}}} s0=s;w0=ch.text.wh[0];n=0;x=0 break}}} function gchord_width(s,wlnote,wlw){var gch,w,ix,arspc=0 for(ix=0;ixwlw) wlw=w break case'>':w=gch.text.wh[0]+s.wr if(w>arspc) arspc=w break}} if(s.wr0) s.wr+=s.xmx+4;for(s2=s.prev;s2;s2=s2.prev){if(w_tb[s2.type]) break} if(s2){switch(s2.type){case C.BAR:case C.CLEF:case C.KEY:case C.METER:wlnote+=3 break case C.STBRK:wlnote+=8 break}} for(m=0;m<=s.nhd;m++){nt=s.notes[m] xx=nt.shhd if(xx<0){if(wlnote<-xx+5) wlnote=-xx+5} acc=nt.acc if(acc){tmp=nt.shac+ (typeof acc=="object"?5.5:3.5) if(wlnote0&&s.nflags>0){if(s.wr=2) s.wr+=3.5*(s.dots-1)} if(s.trem2&&s.beam_end&&wlnote<20) wlnote=20 wlw=wlnote if(s2){switch(s2.type){case C.NOTE:if(s2.stem>0&&s.stem<0){if(wlw<7) wlw=7} if((s.y>27&&s2.y>27)||(s.y<-3&&s2.y<-3)){if(wlw<6) wlw=6} if(s2.tie){if(wlw<14) wlw=14} break case C.CLEF:if(s2.second||s2.clef_small) break case C.KEY:if(s.a_gch) wlw+=4 case C.METER:wlw+=3 break}} if(s.a_gch) wlw=gchord_width(s,wlnote,wlw) if(s.prev&&s.prev.type==C.GRACE){s.prev.wl+=wlnote-4.5 s.wl=s.prev.wl}else{s.wl=wlw} return case C.SPACE:xx=s.width/2;s.wr=xx if(s.a_gch) xx=gchord_width(s,xx,xx) if(s.a_dd) xx=deco_width(s,xx) s.wl=xx return case C.BAR:bar_type=s.bar_type switch(bar_type){case"|":w=5 break case"[":w=0 break default:w=2+2.8*bar_type.length for(i=0;i0&s.bar_num&&s.bar_num%cfmt.measurenb) s.wr+=4} return case C.CLEF:if(s.invis){s.wl=s.wr=1 return} if(s.prev&&s.prev.type==C.STBRK){s.wl=6 s.wr=13 delete s.clef_small return} s.wl=s.clef_small?11:12 s.wr=s.clef_small?8:13 return case C.KEY:if(s.invis){s.wl=s.wr=0 return} s.wl=0 esp=3 n1=s.k_sf if(s.k_old_sf&&(s.fmt.cancelkey||n1==0)) n2=s.k_old_sf else n2=0 if(n1*n2>=0){if(n1<0) n1=-n1 if(n2<0) n2=-n2 if(n2>n1) n1=n2}else{n1-=n2 if(n1<0) n1=-n1;esp+=3} if(s.k_bagpipe=='p') n1++ if(s.k_a_acc){n2=s.k_a_acc.length if(s.exp) n1=n2 else n1+=n2 if(n2) last_acc=s.k_a_acc[0].acc for(i=1;is.k_a_acc[i-1].pit+6||acc.pitmeter.bot.length) meter=meter.top else meter=meter.bot;for(m=0;m=C.BLEN/2){if(smallest_duration>=C.BLEN) len/=4 else len/=2}else if(!s.next&&len>=C.BLEN){len/=2} if(len>=C.BLEN/4){if(len=C.BLEN/8) i=4 else if(len>=C.BLEN/16) i=3 else if(len>=C.BLEN/32) i=2 else if(len>=C.BLEN/64) i=1 else i=0} l=len-((C.BLEN/16/8)<=9) i=8 space+=(cfmt.spatab[i+1]-cfmt.spatab[i])*l/((C.BLEN/16/8)<=-1&&s.stem>0){stemdir=true for(s2=s.ts_prev;s2&&s2.time==ptime;s2=s2.ts_prev){if(s2.type==C.NOTE&&(s2.nflags<-1||s2.stem>0)){stemdir=false break}} if(stemdir){for(s2=s.ts_next;s2&&s2.time==s.time;s2=s2.ts_next){if(s2.type==C.NOTE&&(s2.nflags<-1||s2.stem<0)){stemdir=false break}} if(stemdir) space*=.9}} return space} function set_sp_tup(s,s_et){var tim=s.time,ttim=s_et.time-tim,sp=time2space(s,ttim),s2=s,wsp=0 while(1){s2=s2.ts_next if(s2.seqst){wsp+=s2.space if(s2.bar_type) wsp+=10} if(s2==s_et) break} sp=(sp+wsp)/2/ttim while(1){s=s.ts_next if(s.seqst){s.space=sp*(s.time-tim) tim=s.time} if(s==s_et) break}} function _bar(s){return{type:C.BAR,bar_type:"|",fname:s.fname,istart:s.istart,iend:s.iend,v:s.v,p_v:s.p_v,st:s.st,dur:0,time:s.time+(s.dur||0),nhd:0,notes:[{pit:s.notes?s.notes[0].pit:22}],seqst:true,invis:true,prev:s,fmt:s.fmt}} function add_end_bar(s){var b=_bar(s),sn=s.ts_next b.wl=0 b.wr=0 b.ts_prev=s b.next=s.next b.ts_next=s.ts_next b.shrink=s.type==C.STBRK?0:(s.wr+3) if(s.next) s.next.prev=b s.ts_next.ts_prev=b s.next=s.ts_next=b b.space=sn.space*.9-3 return b} function set_allsymwidth(first){var val,st,s_chs,stup,itup,s=tsfirst,s2=s,xa=0,xl=[],wr=[],maxx=xa,tim=s.time while(1){itup=0 do{if((s.a_gch||s.a_ly)&&!s_chs) s_chs=s;self.set_width(s);st=s.st if(xl[st]==undefined) xl[st]=0 if(wr[st]==undefined) wr[st]=0;val=xl[st]+wr[st]+s.wl if(val>maxx) maxx=val if(s.dur&&s.dur!=s.notes[0].dur&&first) itup=1 s=s.ts_next}while(s&&!s.seqst);s2.shrink=maxx-xa s2.space=s2.ts_prev?set_space(s2,tim):0 if(s2.space==0&&s2.ts_prev&&s2.ts_prev.type==C.SPACE&&s2.ts_prev.seqst) s2.space=s2.ts_prev.space/=2 if(itup){if(!stup) stup=s2}else if(stup&&stup.v==s2.v){set_sp_tup(stup,s2) stup=null} if(!s2.shrink){if(s2.type==C.CLEF&&!s2.ts_prev.bar_type){delete s2.seqst;s2.time=tim}else{s2.shrink=10}} tim=s2.time if(!s) break s=s2 do{wr[s.st]=0 s=s.ts_next}while(!s.seqst) xa=maxx do{st=s2.st;xl[st]=xa if(s2.wr>wr[st]) wr[st]=s2.wr s2=s2.ts_next}while(!s2.seqst)} if(stup) set_sp_tup(stup,s2) if(first&&s_chs) set_w_chs(s_chs)} function to_rest(so){var s=clone(so) s.prev.next=so.ts_prev=so.prev=s.ts_prev.ts_next=s s.next=s.ts_next=so so.seqst=false so.invis=so.play=true s.type=C.REST delete s.in_tuplet delete s.tp delete s.a_dd delete s.a_gch delete s.sls return s} function set_repeat(s){var s2,s3,i,j,dur,n=s.repeat_n,k=s.repeat_k,st=s.st,v=s.v s.repeat_n=0 if(n<0){n=-n;i=n for(s3=s.prev;s3;s3=s3.prev){if(!s3.dur){if(s3.type==C.BAR){error(1,s3,"Bar in repeat sequence") return} continue} if(--i<=0) break} if(!s3){error(1,s,errs.not_enough_n) return} dur=s.time-s3.time;i=k*n for(s2=s;s2;s2=s2.next){if(!s2.dur){if(s2.type==C.BAR){error(1,s2,"Bar in repeat sequence") return} continue} if(--i<=0) break} if(!s2||!s2.next){error(1,s,errs.not_enough_n) return} for(s2=s.prev;s2!=s3;s2=s2.prev){if(s2.type==C.NOTE){s2.beam_end=true break}} for(j=k;--j>=0;){i=n if(s.dur) i--;s2=s.ts_next while(i>0){if(s2.st==st){s2.invis=s2.play=true if(s2.seqst&&s2.ts_next.seqst) s2.seqst=false if(s2.v==v&&s2.dur) i--} s2=s2.ts_next} s=to_rest(s) s.dur=s.notes[0].dur=dur;s.rep_nb=-1;s.beam_st=true;self.set_width(s) s.head=C.SQUARE;for(s=s2;s;s=s.ts_next){if(s.st==st&&s.v==v&&s.dur) break}} return} i=n for(s2=s.prev.prev;s2;s2=s2.prev){if(s2.type==C.BAR||s2.time==tsfirst.time){if(--i<=0) break}} if(!s2){error(1,s,errs.not_enough_m) return} dur=s.time-s2.time if(n==1) i=k else i=n for(s2=s;s2;s2=s2.next){if(s2.type==C.BAR){if(--i<=0) break}} if(!s2){error(1,s,errs.not_enough_m) return} i=k if(n==2&&i>1){s2=s2.next if(!s2){error(1,s,errs.not_enough_m) return} s2.repeat_n=n;s2.repeat_k=--i} dur/=n if(n==2){s3=s for(s2=s.ts_next;;s2=s2.ts_next){if(s2.st!=st) continue if(s2.type==C.BAR){if(s2.v==v) break continue} s2.invis=s2.play=true if(s2.seqst&&s2.ts_next.seqst) s2.seqst=false} s3=to_rest(s3) s3.dur=s3.notes[0].dur=dur;s3.invis=true s2.bar_mrep=2 s3=s2.next;for(s2=s3.ts_next;;s2=s2.ts_next){if(s2.st!=st) continue if(s2.type==C.BAR){if(s2.v==v) break continue} if(!s2.dur) continue s2.invis=s2.play=true if(s2.seqst&&s2.ts_next.seqst) s2.seqst=false} s3=to_rest(s3) s3.dur=s3.notes[0].dur=dur;s3.invis=true;self.set_width(s3) return} s3=s for(j=k;--j>=0;){for(s2=s3.ts_next;;s2=s2.ts_next){if(s2.st!=st) continue if(s2.type==C.BAR){if(s2.v==v) break continue} if(!s2.dur) continue s2.invis=s2.play=true if(s2.seqst&&s2.ts_next.seqst) s2.seqst=false} s3=to_rest(s3) s3.dur=s3.notes[0].dur=dur;s3.beam_st=true if(k==1){s3.rep_nb=1 break} s3.rep_nb=k-j+1;s3=s2.next}} function custos_add(s){var p_voice,new_s,i,s2=s while(1){if(s2.type==C.NOTE) break s2=s2.next if(!s2) return} p_voice=s.p_v;p_voice.last_sym=s.prev;p_voice.time=s.time;new_s=sym_add(p_voice,C.CUSTOS);new_s.next=s;s.prev=new_s;new_s.wl=0 new_s.wr=4 lktsym(new_s,s);new_s.shrink=s.shrink if(new_s.shrink<8+4) new_s.shrink=8+4;new_s.space=s2.space;new_s.head=C.FULL new_s.stem=s2.stem new_s.nhd=s2.nhd;new_s.notes=[] for(i=0;iw) w=s4.wr if(s4.seqst) break s4=s4.ts_prev} s3.shrink+=w s3.space=0 s4=s3 while(1){if(s4.ts_next.seqst) break s4=s4.ts_next} w=0 while(1){if(s4.wl>w) w=s4.wl s4=s4.ts_next if(s4.seqst) break} s4.shrink=s3.wr+w} delete s3.part continue} if(w_tb[s2.type]) break}} s=bardiv(s) do_warn(s) if(s.ts_prev.type!=C.STAVES){set_eol(s) return s} for(s=s.ts_prev;s;s=s.ts_prev){if(s.seqst&&s.type!=C.CLEF) break} done=0 ptyp=s.type for(;;s=s.ts_next){if(!s) return s if(s.type==ptyp) continue ptyp=s.type if(done<0) break switch(s.type){case C.STAVES:if(!s.ts_prev) return if(s.ts_prev.type==C.BAR) break while(s.ts_next){if(w_tb[s.ts_next.type]&&s.ts_next.type!=C.CLEF) break s=s.ts_next} if(!s.ts_next||s.ts_next.type!=C.BAR) continue s=s.ts_next case C.BAR:if(done) break done=1;continue case C.STBRK:if(!s.stbrk_forced) unlksym(s) else done=-1 continue case C.CLEF:if(done) break continue default:if(!done||(s.prev&&s.prev.type==C.GRACE)) continue break} break} set_eol(s) return s} function get_ck_width(){var r0,r1,p_voice=voice_tb[0] self.set_width(p_voice.clef);self.set_width(p_voice.ckey);self.set_width(p_voice.meter) return[p_voice.clef.wl+p_voice.clef.wr+ p_voice.ckey.wl+p_voice.ckey.wr,p_voice.meter.wl+p_voice.meter.wr]} function get_width(s,next){var shrink,space,w=0,wmx=0,sp_fac=(1-s.fmt.maxshrink) while(s!=next){if(s.seqst){shrink=s.shrink wmx+=shrink if((space=s.space)=xmin) break} s4=s if(s==next){if(s) s=set_nl(s) return s} s3=null for(;s!=next;s=s.ts_next){x=s.x if(!x) continue if(x>xmax) break if(s.type!=C.BAR) continue if(x=xmax) break if(!beam&&!s.in_tuplet&&(xmid-s5.x>x-xmid||(s.time-bar_time)%(C.BLEN/4)==0)) s3=s} if(s.beam_st) beam|=1<=xmax) break if(s3&&x>=xmid){if(xmid-s3.x>x-xmid) s3=s break} s3=s}} s=s3 while(s.ts_next){s=s.ts_next if(s.seqst) break} if(s.nl){error(0,s,"Line split problem - adjust maxshrink and/or breaklimit");nlines=2 for(s=s.ts_next;s!=next;s=s.ts_next){if(!s.x) continue if(--nlines<=0) break}} s=set_nl(s) if(!s||(next&&s.time>=next.time)) break wwidth-=s.x-first.x;indent=0} return s} function cut_tune(lwidth,lsh){var s2,i,mc,pg_sav={leftmargin:cfmt.leftmargin,rightmargin:cfmt.rightmargin,pagewidth:cfmt.pagewidth,scale:cfmt.scale},indent=lsh[0]-lsh[1],ckw=get_ck_width(),s=tsfirst lwidth-=lsh[1] if(cfmt.indent&&cfmt.indent>lsh[0]) indent+=cfmt.indent lwidth-=ckw[0] indent+=ckw[1] if(cfmt.custos&&voice_tb.length==1) lwidth-=12 i=s.fmt.barsperstaff if(i){for(s2=s;s2;s2=s2.ts_next){if(s2.type!=C.BAR||!s2.bar_num||--i>0) continue while(s2.ts_next&&s2.ts_next.type==C.BAR) s2=s2.ts_next if(s2.ts_next) s2.ts_next.soln=true i=s.fmt.barsperstaff}} s2=s for(;s;s=s.ts_next){if(s.type==C.BLOCK){switch(s.subtype){case"leftmargin":case"rightmargin":case"pagescale":case"pagewidth":case"scale":case"staffwidth":if(!s.soln) self.set_format(s.subtype,s.param) break case"mc_start":mc={lm:cfmt.leftmargin,rm:cfmt.rightmargin} break case"mc_new":case"mc_end":if(!mc) break cfmt.leftmargin=mc.lm cfmt.rightmargin=mc.rm img.chg=1 break}} if(!s.ts_next){s=null}else if(!s.soln){continue}else{s.soln=false if(s.time==s2.time) continue while(!s.seqst) s=s.ts_prev} set_page() lwidth=get_lwidth()-lsh[1]-ckw[0] s2=set_lines(s2,s,lwidth,indent) if(!s2) break s=s2.type==C.BLOCK?s2.ts_prev:s indent=0} cfmt.leftmargin=pg_sav.leftmargin cfmt.rightmargin=pg_sav.rightmargin cfmt.pagewidth=pg_sav.pagewidth cfmt.scale=pg_sav.scale img.chg=1 set_page()} function set_yval(s){switch(s.type){case C.CLEF:if(s.second||s.invis){s.ymx=s.ymn=12 break} s.y=(s.clef_line-1)*6 switch(s.clef_type){default:s.ymx=s.y+28 s.ymn=s.y-14 break case"c":s.ymx=s.y+13 s.ymn=s.y-11 break case"b":s.ymx=s.y+7 s.ymn=s.y-12 break} if(s.clef_small){s.ymx-=2;s.ymn+=2} if(s.ymx<26) s.ymx=26 if(s.ymn>-1) s.ymn=-1 if(s.clef_octave){if(s.clef_octave>0) s.ymx+=12 else s.ymn-=12} break case C.KEY:if(s.k_sf>2) s.ymx=24+10 else if(s.k_sf>0) s.ymx=24+6 else s.ymx=24+2;s.ymn=-2 break default:s.ymx=24;s.ymn=0 break}} function set_ottava(){var s,s1,st,o,d,m=nstaff+1,staff_d=new Int8Array(m) function sym_ott(s,d){var g,m,note switch(s.type){case C.REST:if(voice_tb.length==1) break case C.NOTE:if(!s.p_v.ckey.k_drum){for(m=s.nhd;m>=0;m--){note=s.notes[m];if(!note.opit) note.opit=note.pit;note.pit+=d}} break case C.GRACE:for(g=s.extra;g;g=g.next){if(!s.p_v.ckey.k_drum){for(m=0;m<=g.nhd;m++){note=g.notes[m] if(!note.opit) note.opit=note.pit note.pit+=d}}} break}} function deco_rm(s){for(var i=s.a_dd.length;--i>=0;){if(s.a_dd[i].name.match(/1?[85][vm][ab]/)) s.a_dd.splice(i,1)}} for(s=tsfirst;s;s=s.ts_next){st=s.st o=s.ottava if(o){if(o[0]){if(staff_d[st]&&!o[1]){sym_ott(s,staff_d[st]) deco_rm(s) continue}}else if(!staff_d[st]){deco_rm(s) continue} s1=s while(s1&&!s1.seqst) s1=s1.ts_prev if(s1){while(s1!=s){if(s1.st==st){if(o[1]) sym_ott(s1,-staff_d[st]) if(o[0]) sym_ott(s1,-o[0]*7)} s1=s1.ts_next}} if(o[0]){staff_d[st]=-o[0]*7}else{staff_d[st]=0}} if(staff_d[st]) sym_ott(s,staff_d[st])}} function mrest_expand(){var s,s2 function mexp(s){var bar,s3,s4,tim,nbar,nb=s.nmes,dur=s.dur/nb,s2=s.next while(!s2.bar_type) s2=s2.next bar=s2 while(!s2.bar_num) s2=s2.ts_prev nbar=s2.bar_num-s.nmes s.type=C.REST s.notes[0].dur=s.dur=s.dur_orig=dur s.nflags=-2 s.head=C.FULL s.fmr=1 tim=s.time+dur s3=s while(--nb>0){s2=clone(bar) delete s2.soln delete s2.a_gch delete s2.a_dd delete s2.text delete s2.rbstart delete s2.rbstop lkvsym(s2,s.next) s2.time=tim while(s3.timemax) max=s.notes[s.nhd].pit} if(min>=19||(min>=13&&clef_type_start!='b')) return't' if(max<=13||(max<=19&&clef_type_start!='t')) return'b' if(clef_type_start=='a'){if((max+min)/2>=16) clef_type_start='t' else clef_type_start='b'} var clef_type=clef_type_start,s_last=s,s_last_chg=null for(s=s_start;s!=s_last;s=s.ts_next){if(s.type==C.STAVES&&s!=s_start) break if(s.st!=st||s.type!=C.NOTE) continue time=s.time if(clef_type=='t'){if(s.notes[0].pit>12||s.notes[s.nhd].pit>20){if(s.notes[0].pit>20) s_last_chg=s continue} s2=s.ts_prev if(s2&&s2.time==time&&s2.st==st&&s2.type==C.NOTE&&s2.notes[0].pit>=19) continue s2=s.ts_next if(s2&&s2.st==st&&s2.time==time&&s2.type==C.NOTE&&s2.notes[0].pit>=19) continue}else{if(s.notes[0].pit<=12||s.notes[s.nhd].pit<20){if(s.notes[s.nhd].pit<=12) s_last_chg=s continue} s2=s.ts_prev if(s2&&s2.time==time&&s2.st==st&&s2.type==C.NOTE&&s2.notes[0].pit<=13) continue s2=s.ts_next if(s2&&s2.st==st&&s2.time==time&&s2.type==C.NOTE&&s2.notes[0].pit<=13) continue} if(!s_last_chg){clef_type=clef_type_start=clef_type=='t'?'b':'t';s_last_chg=s continue} s3=s for(s2=s.ts_prev;s2!=s_last_chg;s2=s2.ts_prev){if(s2.st!=st) continue if(s2.type==C.BAR){s3=s2.bar_type[0]!=':'?s2:s2.next break} if(s2.type!=C.NOTE) continue if(s2.beam_st&&!s2.p_v.second) s3=s2} if(s3.time==s_last_chg.time){s_last_chg=s continue} s_last_chg=s;clef_type=clef_type=='t'?'b':'t';s2=insert_clef(s3,clef_type,clef_type=="t"?2:4);s2.clef_auto=true} return clef_type_start} function set_clefs(){var s,s2,st,v,p_voice,g,new_type,new_line,p_staff,pit,staff_clef=new Array(nstaff+1),sy=cur_sy,mid=[] staff_tb=new Array(nstaff+1) for(st=0;st<=nstaff;st++){staff_clef[st]={autoclef:true} staff_tb[st]={output:"",sc_out:""}} for(st=0;st<=sy.nstaff;st++) mid[st]=(sy.staves[st].stafflines.length-1)*3 for(s=tsfirst;s;s=s.ts_next){if(s.repeat_n) set_repeat(s) switch(s.type){case C.STAVES:sy=s.sy for(st=0;st<=nstaff;st++) staff_clef[st].autoclef=true for(v=0;v1||s.bar_mrep){s.y=12 s.ymx=38 s.ymn=0 break} if(voice_tb.length==1){s.y=12;s.ymx=24;s.ymn=0 break} case C.NOTE:delta=staff_delta[st] if(delta&&!s.p_v.ckey.k_drum){for(m=s.nhd;m>=0;m--){note=s.notes[m] note.opit=note.pit note.pit+=delta}} if(s.type==C.REST){s.y=(((s.notes[0].pit-18)/2)|0)*6;s.ymx=s.y+rest_sp[5-s.nflags][0];s.ymn=s.y-rest_sp[5-s.nflags][1]} if(s.durnst){var msg="*** fatal set_stem_dir(): bad staff number "+st+" max "+nst;error(2,null,msg);throw new Error(msg)} v=u.v;v_st=v_st_tb[v] if(!v_st){v_st={st1:-1,st2:-1} v_st_tb[v]=v_st} if(v_st.st1<0){v_st.st1=st}else if(v_st.st1!=st){if(st>v_st.st1){if(st>v_st.st2) v_st.st2=st}else{if(v_st.st1>v_st.st2) v_st.st2=v_st.st1;v_st.st1=st}} st_v=st_v_tb[st];rvoice=sy.voices[v].range;for(i=st_v.length;--i>=0;){vobj=st_v[i] if(vobj.v==rvoice) break} if(i<0){vobj={v:rvoice,ymx:0,ymn:24} for(i=0;ivobj.ymx) vobj.ymx=u.ymx if(u.ymn=0){if(st==v_st.st1) s.multi=-1 else if(st==v_st.st2) s.multi=1 continue} if(st_v.length<=1){if(s.floating) s.multi=st==voice_tb[v].st?-1:1 continue} rvoice=sy.voices[v].range for(i=st_v.length;--i>=0;){if(st_v[i].v==rvoice) break} if(i<0) continue if(i==st_v.length-1){s.multi=-1}else{s.multi=1 if(i&&i+2==st_v.length){if(st_v[i].ymn-s.fmt.stemheight>=st_v[i+1].ymx) s.multi=-1;t=s.ts_next if(s.ts_prev&&s.ts_prev.time==s.time&&s.ts_prev.st==s.st&&s.notes[s.nhd].pit==s.ts_prev.notes[0].pit&&s.beam_st&&s.beam_end&&(!t||t.st!=s.st||t.time!=s.time)) s.multi=-1}}} while(s&&s.type==C.BAR) s=s.ts_next}} function set_rest_offset(){var s,s2,v,end_time,not_alone,v_s,y,ymax,ymin,shift,dots,dx,v_s_tb=[],sy=cur_sy for(s=tsfirst;s;s=s.ts_next){if(s.invis) continue if(s.type==C.STAVES) sy=s.sy if(!s.dur) continue v_s=v_s_tb[s.v] if(!v_s){v_s={} v_s_tb[s.v]=v_s} v_s.s=s;v_s.st=s.st;v_s.end_time=s.time+s.dur if(s.type!=C.REST) continue ymin=-127;ymax=127;not_alone=dots=false for(v=0;v<=v_s_tb.length;v++){v_s=v_s_tb[v] if(!v_s||!v_s.s||v_s.st!=s.st||v==s.v) continue if(v_s.end_time<=s.time) continue not_alone=true;s2=v_s.s if(sy.voices[v].rangeymin){ymin=s2.ymx if(s2.dots) dots=true}}else{if(s2.y>ymin) ymin=s2.y}}} end_time=s.time+s.dur for(s2=s.ts_next;s2;s2=s2.ts_next){if(s2.time>=end_time) break if(s2.st!=s.st||!s2.dur||s2.invis) continue not_alone=true if(sy.voices[s2.v].rangeymin){ymin=s2.ymx if(s2.dots) dots=true}}else{if(s2.y>ymin) ymin=s2.y}}} if(!not_alone){s.y=12;s.ymx=24;s.ymn=0 continue} if(ymax==127&&s.y<12){shift=12-s.y s.y+=shift;s.ymx+=shift;s.ymn+=shift} if(ymin==-127&&s.y>12){shift=s.y-12 s.y-=shift;s.ymx-=shift;s.ymn-=shift} shift=ymax-s.ymx if(shift<0){shift=Math.ceil(-shift/6)*6 if(s.ymn-shift>=ymin){s.y-=shift;s.ymx-=shift;s.ymn-=shift continue} dx=dots?15:10;s.notes[0].shhd=dx;s.xmx=dx continue} shift=ymin-s.ymn if(shift>0){shift=Math.ceil(shift/6)*6 if(s.ymx+shift<=ymax){s.y+=shift;s.ymx+=shift;s.ymn+=shift continue} dx=dots?15:10;s.notes[0].shhd=dx;s.xmx=dx continue}}} function new_sym(s,p_v,last_s){s.p_v=p_v s.v=p_v.v s.st=p_v.st s.time=last_s.time if(p_v.last_sym){s.next=p_v.last_sym.next if(s.next) s.next.prev=s;p_v.last_sym.next=s;s.prev=p_v.last_sym} p_v.last_sym=s;lktsym(s,last_s)} function init_music_line(){var p_voice,s,s1,s2,s3,last_s,v,st,shr,shrmx,shl,shlp,p_st,top,nv=voice_tb.length,fmt=tsfirst.fmt for(v=0;v=0&&s.a_meter.length break} if(s.part) s.next.part=s.part unlksym(s) case C.TEMPO:case C.BLOCK:case C.REMARK:continue} break}} last_s=tsfirst for(v=0;v0){s.nflags+=s.ntrem}else{if(s.nflags<=-2){s.stemless=true s.prev.stemless=true} s.nflags=s.ntrem} s.prev.nflags=s.nflags} for(s=p_voice.sym;s;s=s.next){if(s.type==C.NOTE){pitch=s.notes[0].pit break}} for(s=p_voice.sym;s;s=s.next){if(s.a_gch) self.gch_build(s) switch(s.type){case C.MREST:start_flag=true break case C.BAR:res=s.fmt.bardef[s.bar_type] if(res) s.bar_type=res if(!s.beam_on) start_flag=true if(!s.next&&s.prev&&!s.invis&&s.prev.head==C.OVALBARS) s.prev.head=C.SQUARE break case C.GRACE:for(s2=s.extra;s2;s2=s2.next){s2.notes.sort(abc2svg.pitcmp) res=identify_note(s2,s2.dur_orig) s2.head=res[0] s2.dots=res[1] s2.nflags=res[2] if(s2.trem2&&(!s2.next||s2.next.trem2)) trem_adj(s2)} break case C.NOTE:case C.REST:res=identify_note(s,s.dur_orig);s.head=res[0];s.dots=res[1];s.nflags=res[2] if(s.nflags<=-2) s.stemless=true if(s.xstem) s.nflags=0 if(s.trem1){if(s.nflags>0) s.nflags+=s.ntrem else s.nflags=s.ntrem} if(s.next&&s.next.trem2) break if(s.trem2){trem_adj(s) break} nflags=s.nflags if(s.ntrem) nflags+=s.ntrem if(s.type==C.REST&&s.beam_end&&!s.beam_on){start_flag=true} if(start_flag||nflags<=0){if(lastnote){lastnote.beam_end=true;lastnote=null} if(nflags<=0){s.beam_st=s.beam_end=true}else if(s.type==C.NOTE||s.beam_on){s.beam_st=true;start_flag=false}} if(s.beam_end) start_flag=true if(s.type==C.NOTE||s.beam_on) lastnote=s break} if(s.type==C.NOTE){if(s.nhd) s.notes.sort(abc2svg.pitcmp) pitch=s.notes[0].pit for(s2=s.prev;s2;s2=s2.prev){if(s2.type!=C.REST) break s2.notes[0].pit=pitch}}else{if(!s.notes){s.notes=[] s.notes[0]={} s.nhd=0} s.notes[0].pit=pitch}} if(lastnote) lastnote.beam_end=true} function set_rb(p_voice){var s2,n,s=p_voice.sym while(s){if(s.type!=C.BAR||!s.rbstart||s.norepbra){s=s.next continue} n=0;s2=null for(s=s.next;s;s=s.next){if(s.type!=C.BAR) continue if(s.rbstop) break if(!s.next){s.rbstop=2 break} n++ if(n==s.fmt.rbmin) s2=s if(n==s.fmt.rbmax){if(s2) s=s2;s.rbstop=1 break}}}} var delpit=[0,-7,-14,0] function set_global(){var p_voice,v,nv=voice_tb.length,sy=cur_sy,st=sy.nstaff insert_meter=cfmt.writefields.indexOf('M')>=0 while(1){sy=sy.next if(!sy) break if(sy.nstaff>st) st=sy.nstaff} nstaff=st;check_end_bar() for(v=0;v1){set_float() if(glovar.mrest_p) mrest_expand()} if(glovar.ottava&&cfmt.sound!="play") set_ottava();set_clefs();self.set_pitch(null)} function get_lshift(){var st,v,p_v,p1,po,fnt,w,sy=cur_sy,lsh1=0,lsho=0,nv=voice_tb.length function get_wx(p,wx){var w,j,i=0 p+='\n' while(1){j=p.indexOf("\n",i) if(j<0) break w=strwh(p.slice(i,j))[0]+12 if(w>wx) wx=w if(j<0) break i=j+1} return wx} for(v=0;vlsh1) lsh1=w} if(po){w=get_wx(po,lsho) if(w>lsho) lsho=w}} w=0 while(sy){for(st=0;st<=sy.nstaff;st++){if(sy.staves[st].flags&(OPEN_BRACE2|OPEN_BRACKET2)){w=12 break} if(sy.staves[st].flags&(OPEN_BRACE|OPEN_BRACKET)) w=6} if(w==12) break sy=sy.next} lsh1+=w lsho+=w return[lsh1,lsho]} function set_indent(lsh){var st,v,w,p_voice,p,i,j,font,vnt=0,nv=voice_tb.length for(v=0;vpu) pu=g.notes[g.nhd].pit if(g.notes[0].pitmid_p*2){s.stem=-1}else{if(s.fmt.bstemdown) s.stem=-1}} if(!s.stem) s.stem=laststem}else{n=(s.notes[s.nhd].pit+s.notes[0].pit)/2 if(n==mid_p&&s.nhd>1){for(m=0;m=mid_p) break} n=m*2mid_p||s.fmt.bstemdown) s.stem=-1 else s.stem=laststem}}else{if(s.beam_st&&!s.beam_end) beam=true} if(s.beam_end) beam=false;laststem=s.stem;if(s_opp){for(g=s_opp.extra;g;g=g.next) g.stem=-laststem;s_opp.stem=-laststem;s_opp=null}}} function same_head(s1,s2){var i1,i2,l1,l2,head,i11,i12,i21,i22,sh1,sh2,shu=s1.fmt.shiftunison||0 if(shu>=3) return false if((l1=s1.dur)>=C.BLEN) return false if((l2=s2.dur)>=C.BLEN) return false if(s1.stemless&&s2.stemless) return false if(s1.dots!=s2.dots){if(shu&1||s1.dots*s2.dots!=0) return false} if(s1.stem*s2.stem>0) return false i1=i2=0 if(s1.notes[0].pit>s2.notes[0].pit){if(s1.stem<0) return false while(s2.notes[i2].pit!=s1.notes[0].pit){if(++i2>s2.nhd) return false}}else if(s1.notes[0].pits1.nhd) return false}} if(s2.notes[i2].acc!=s1.notes[i1].acc) return false;i11=i1;i21=i2;sh1=s1.notes[i1].shhd;sh2=s2.notes[i2].shhd do{i1++;i2++ if(i1>s1.nhd){break} if(i2>s2.nhd){break} if(s2.notes[i2].acc!=s1.notes[i1].acc) return false if(sh10) return false}else if(i2<=s2.nhd){if(s1.stem>0) return false} i12=i1;i22=i2;head=0 if(l1!=l2){if(l1=C.BLEN/2?2:1}else{return false}} if(!head) head=s1.p_v.scale-2){if(s.stem>0){w=-w;i=s.notes[0].pit*2;j=(Math.ceil((s.ymx-2)/3)+18)*2}else{i=(Math.ceil((s.ymn+2)/3)+18)*2;j=s.notes[s.nhd].pit*2} if(i<0) i=0 if(j>=MAXPIT) j=MAXPIT-1 while(i<=j) left[i++]=w} shift=s.notes[s.stem>0?0:s.nhd].shhd;for(m=0;m<=s.nhd;m++){w=-s.notes[m].shhd+w_base+shift;i=s.notes[m].pit*2 if(i<0) i=0 else if(i>=MAXPIT-1) i=MAXPIT-2 if(w>left[i]) left[i]=w if(s.head!=C.SQUARE) w-=1 if(w>left[i-1]) left[i-1]=w if(w>left[i+1]) left[i+1]=w} return left} function set_right(s){var m,i,j,k,shift,w_base=w_note[s.head],w=w_base,flags=s.nflags>0&&s.beam_st&&s.beam_end,right=[] for(i=0;i-2){if(s.stem<0){w=-w;i=(Math.ceil((s.ymn+2)/3)+18)*2;j=s.notes[s.nhd].pit*2;k=i+4}else{i=s.notes[0].pit*2;j=(Math.ceil((s.ymx-2)/3)+18)*2} if(i<0) i=0 if(j>MAXPIT) j=MAXPIT while(i0){if(s.xmx==0) i=s.notes[s.nhd].pit*2 else i=s.notes[0].pit*2;i+=4 if(i<0) i=0 for(;i0?0:s.nhd].shhd for(m=0;m<=s.nhd;m++){w=s.notes[m].shhd+w_base-shift;i=s.notes[m].pit*2 if(i<0) i=0 else if(i>=MAXPIT-1) i=MAXPIT-2 if(w>right[i]) right[i]=w if(s.head!=C.SQUARE) w-=1 if(w>right[i-1]) right[i-1]=w if(w>right[i+1]) right[i+1]=w} return right} function set_overlap(){var s,s1,s2,s3,i,i1,i2,m,sd,t,dp,d,d2,dr,dr2,dx,left1,right1,left2,right2,right3,pl,pr,sy=cur_sy function v_invert(){s1=s2;s2=s;d=d2;pl=left1;pr=right1;dr2=dr} for(s=tsfirst;s;s=s.ts_next){if(s.type!=C.NOTE||s.invis){if(s.type==C.STAVES) sy=s.sy continue} if(s.xstem&&s.ts_prev.stem<0){for(m=0;m<=s.nhd;m++){s.notes[m].shhd-=7;s.notes[m].shac+=16}} s2=s while(1){s2=s2.ts_next if(!s2) break if(s2.time!=s.time){s2=null break} if(s2.type==C.NOTE&&!s2.invis&&s2.st==s.st) break} if(!s2) continue s1=s if(sy.voices[s1.v].ranges2.ymx||s1.ymx0&&s2.stem<0&&s1.notes[0].pit==s2.notes[s2.nhd].pit+1)||(s1.stem<0&&s2.stem>0&&s1.notes[s1.nhd].pit+1==s2.notes[0].pit)){if(s1.stem<0){s1=s2;s2=s} d=s1.notes[0].shhd+7 for(m=0;m<=s2.nhd;m++) s2.notes[m].shhd+=d s2.xmx+=d s1.xmx=s2.xmx continue} right1=set_right(s1);left2=set_left(s2);s3=s1.ts_prev if(s3&&s3.time==s1.time&&s3.st==s1.st&&s3.type==C.NOTE&&!s3.invis){right3=set_right(s3) for(i=0;iright1[i]) right1[i]=right3[i]}}else{s3=null} d=-10 for(i=0;id) d=left2[i]+right1[i]} if(d<-3&&((s2.notes[0].pit&1)||!(s1.dots||s2.dots)||(!(s1.notes[s1.nhd].pit==s2.notes[0].pit+2&&s1.dot_low)&&!(s1.notes[s1.nhd].pit+2==s2.notes[0].pit&&s2.dot_low)))) continue right2=set_right(s2);left1=set_left(s1) if(s3){right3=set_left(s3) for(i=0;ileft1[i]) left1[i]=right3[i]}} d2=dr=dr2=-100 for(i=0;id2) d2=left1[i]+right2[i] if(right2[i]>dr2) dr2=right2[i] if(right1[i]>dr) dr=right1[i]} t=0;i1=s1.nhd;i2=s2.nhd while(1){dp=s1.notes[i1].pit-s2.notes[i2].pit switch(dp){case 2:if(!(s1.notes[i1].pit&1)) s1.dot_low=false break case 1:if(s1.notes[i1].pit&1) s2.dot_low=true else s1.dot_low=false break case 0:if(s1.notes[i1].acc!=s2.notes[i2].acc){t=-1 break} if(s2.notes[i2].acc){if(!s1.notes[i1].acc) s1.notes[i1].acc=s2.notes[i2].acc s2.notes[i2].acc=0} if(s1.dots&&s2.dots&&(s1.notes[i1].pit&1)) t=1 break case-1:if(s1.notes[i1].pit&1) s2.dot_low=false else s1.dot_low=true break case-2:if(!(s1.notes[i1].pit&1)) s2.dot_low=false break} if(t<0) break if(dp>=0){if(--i1<0) break} if(dp<=0){if(--i2<0) break}} if(t<0){unison_acc(s1,s2,i1,i2) continue} sd=0;if(s1.dots){if(s2.dots){if(!t) sd=1}else{v_invert()}}else if(s2.dots){if(d2+dr=0?0:s1.nhd;d+=s1.notes[m].shhd;m=s2.stem>=0?0:s2.nhd;d-=s2.notes[m].shhd if(s1.dots){dx=7.7+s1.xmx+ 3.5*s1.dots-3.5+ 3;if(!sd){d2=-100;for(i1=0;i1<=s1.nhd;i1++){i=s1.notes[i1].pit if(!(i&1)){if(!s1.dot_low) i++ else i--} i*=2 if(i<1) i=1 else if(i>=MAXPIT-1) i=MAXPIT-2 if(pl[i]>d2) d2=pl[i] if(pl[i-1]+1>d2) d2=pl[i-1]+1 if(pl[i+1]+1>d2) d2=pl[i+1]+1} if(dx+d2+2>d) d=dx+d2+2}else{if(dx=MAXPIT-1) i=MAXPIT-2 if(pr[i]>d2) d2=pr[i] if(pr[i-1]+1>d2) d2=pr[i-1]=1 if(pr[i+1]+1>d2) d2=pr[i+1]+1} if(d2>4.5&&7.7+s1.xmx+2=0;m--){s2.notes[m].shhd+=d} s2.xmx+=d if(sd) s1.xmx=s2.xmx}} Abc.prototype.set_stems=function(){var s,s2,g,slen,scale,ymn,ymx,nflags,ymin,ymax for(s=tsfirst;s;s=s.ts_next){if(s.type!=C.NOTE){if(s.type!=C.GRACE) continue ymin=ymax=s.mid for(g=s.extra;g;g=g.next){slen=GSTEM if(g.nflags>1) slen+=1.2*(g.nflags-1);ymn=3*(g.notes[0].pit-18);ymx=3*(g.notes[g.nhd].pit-18) if(s.stem>=0){g.y=ymn;g.ys=ymx+slen;ymx=Math.round(g.ys)}else{g.y=ymx;g.ys=ymn-slen;ymn=Math.round(g.ys)} ymx+=4 ymn-=4 if(ymnymax) ymax=ymx;g.ymx=ymx;g.ymn=ymn} s.ymx=ymax;s.ymn=ymin continue} set_head_shift(s);nflags=s.nflags if(s.beam_st&&!s.beam_end){if(s.feathered_beam) nflags=++s.nflags for(s2=s.next;;s2=s2.next){if(s2.type==C.NOTE){if(s.feathered_beam) s2.nflags++ if(s2.beam_end) break}} if(s2.nflags>nflags) nflags=s2.nflags}else if(!s.beam_st&&s.beam_end){for(s2=s.prev;;s2=s2.prev){if(s2.beam_st) break} if(s2.nflags>nflags) nflags=s2.nflags} slen=s.fmt.stemheight switch(nflags){case 2:slen+=0;break case 3:slen+=4;break case 4:slen+=8;break case 5:slen+=12;break} if((scale=s.p_v.scale)!=1) slen*=(scale+1)*.5;ymn=3*(s.notes[0].pit-18) if(s.nhd>0){slen-=2;ymx=3*(s.notes[s.nhd].pit-18)}else{ymx=ymn} if(s.ntrem) slen+=2*s.ntrem if(s.stemless){if(s.stem>=0){s.y=ymn;s.ys=ymx}else{s.ys=ymn;s.y=ymx} s.ymx=ymx+4;s.ymn=ymn-4}else if(s.stem>=0){if(s.notes[s.nhd].pit>26&&(nflags<=0||!s.beam_st||!s.beam_end)){slen-=2 if(s.notes[s.nhd].pit>28) slen-=2} s.y=ymn if(s.notes[0].tie) ymn-=3;s.ymn=ymn-4;s.ys=ymx+slen if(s.yss.mid) s.ys=s.mid;s.ymn=(s.ys-2.5)|0;s.y=ymx if(s.notes[s.nhd].tie) ymx+=3;s.ymx=ymx+4}}} var blocks=[] Abc.prototype.block_gen=function(s){switch(s.subtype){case"leftmargin":case"rightmargin":case"pagescale":case"pagewidth":case"scale":case"staffwidth":self.set_format(s.subtype,s.param) break case"mc_start":if(multicol){error(1,s,"No end of the previous %%multicol") break} multicol={posy:posy,maxy:posy,lm:cfmt.leftmargin,rm:cfmt.rightmargin,w:cfmt.pagewidth,sc:cfmt.scale} break case"mc_new":if(!multicol){error(1,s,"%%multicol new without start") break} if(posy>multicol.maxy) multicol.maxy=posy cfmt.leftmargin=multicol.lm cfmt.rightmargin=multicol.rm cfmt.pagewidth=multicol.w cfmt.scale=multicol.sc posy=multicol.posy img.chg=1 break case"mc_end":if(!multicol){error(1,s,"%%multicol end without start") break} if(posy') blkdiv=2 break case"sep":set_page();vskip(s.sk1);output+='\n';vskip(s.sk2);break case"text":set_font(s.font) use_font(s.font) write_text(s.text,s.opt) break case"title":write_title(s.text,true) break case"vskip":vskip(s.sk);break}} function sym_staff_move(st){for(var s=tsfirst;s;s=s.ts_next){if(s.nl) break if(s.st==st&&s.type!=C.CLEF){s.st++ if(s.type!=C.TEMPO) s.invis=true}}} function set_piece(){var s,last,p_voice,st,v,nv,tmp,non_empty=[],non_empty_gl=[],sy=cur_sy function reset_staff(st){var p_staff=staff_tb[st],sy_staff=sy.staves[st] if(!p_staff) p_staff=staff_tb[st]={} p_staff.y=0;p_staff.stafflines=sy_staff.stafflines;p_staff.staffscale=sy_staff.staffscale;p_staff.ann_top=p_staff.ann_bot=0} function set_brace(){var st,i,empty_fl,n=sy.staves.length for(st=0;st=l-2){if(p_staff.stafflines[i]!='.'){p_staff.botbar-=6;p_staff.topbar+=6}else{p_staff.botbar-=12;p_staff.topbar+=12 continue}} if(!non_empty_gl[st]) continue p_staff.hll=17+i*2 p_staff.hlmap=new Int8Array((l-i+1)*2 +2) for(j=1;instaff){switch(s.type){case C.CLEF:staff_tb[st].clef=s break case C.KEY:s.p_v.ckey=s break case C.METER:s.p_v.meter=s break} unlksym(s) continue} if(non_empty[st]) continue switch(s.type){default:continue case C.BAR:if(s.bar_mrep||sy.staves[st].staffnonote>1) break continue case C.GRACE:break case C.NOTE:case C.REST:case C.SPACE:case C.MREST:if(sy.staves[st].staffnonote>1) break if(s.invis) continue if(sy.staves[st].staffnonote||s.type==C.NOTE) break continue} non_empty_gl[st]=non_empty[st]=true} tsnext=s;set_brace() sy.st_print=new Uint8Array(non_empty);set_top_bot() for(st=0;stwidth){error(1,s,"Line too much shrunk $1 $2 $3",xmin.toFixed(1),xx.toFixed(1),width.toFixed(1)) break} if(s.space){if(s.space=width){x=0 for(;s;s=s.ts_next){if(s.seqst) x+=s.shrink;s.x=x} spf_last=0}else if((ll&&xx+xs>width*(1-s.fmt.stretchlast))||(!ll&&(xx+xs>width||s.fmt.stretchstaff))){if(xx==xse) xx+=5 for(var cnt=4;--cnt>=0;){spf=(width-xs-xse)/(xx-xse);xx=0;xse=0;x=0 for(s=tsfirst;s;s=s.ts_next){if(s.seqst){if(s.space){if(s.space*spf<=s.shrink){xse+=s.shrink;xx+=s.shrink;x+=s.shrink}else{xx+=s.space;x+=s.space*spf}}else{x+=s.shrink}} s.x=x} if(Math.abs(x-width)<0.1) break} spf_last=spf}else{spf=1-s.fmt.maxshrink if(spf_last&&xx*spf_last+xs=0){p_v=voice_tb[v] if(p_v.sym&&p_v.s_prev){p_v.sym.prev=p_v.s_prev p_v.s_prev.next=p_v.sym} s=p_v.s_next p_v.s_next=null p_v.sym=s if(s){if(s.prev) s.prev.next=s p_v.s_prev=s.prev s.prev=null}else{p_v.s_prev=null}}} function set_posx(){posx=img.lm/cfmt.scale} function gen_init(){var s=tsfirst,tim=s.time for(;s;s=s.ts_next){if(s.time!=tim){set_page() return} switch(s.type){case C.NOTE:case C.REST:case C.MREST:case C.SPACE:set_page() return default:continue case C.STAVES:cur_sy=s.sy continue case C.BLOCK:if(s.play) continue self.block_gen(s) break} unlksym(s) if(s.p_v.s_next==s) s.p_v.s_next=s.next} tsfirst=null} Abc.prototype.output_music=function(){var v,lwidth,indent,lsh,line_height,ts1st,tslast,p_v,nv=voice_tb.length set_global() if(nv>1) self.set_stem_dir() for(v=0;v1){set_rest_offset();set_overlap()} set_allsymwidth(1) lsh=get_lshift() if(cfmt.singleline){v=get_ck_width();lwidth=lsh[0]+v[0]+v[1]+get_width(tsfirst,null)[0] v=cfmt.singleline==2?get_lwidth():lwidth if(v>lwidth) lwidth=v else img.width=lwidth*cfmt.scale+img.lm+img.rm+2}else{lwidth=get_lwidth();cut_tune(lwidth,lsh)} gen_init() if(!tsfirst) return ts1st=tsfirst v=nv while(--v>=0) voice_tb[v].osym=voice_tb[v].sym spf_last=0 while(1){set_piece();indent=set_indent(lsh) if(!line_height&&cfmt.indent&&indent=0){p_v=voice_tb[v] if(p_v.sym&&p_v.s_prev) p_v.sym.prev=p_v.s_prev p_v.sym=p_v.osym}} var a_gch,a_dcn=[],multicol,maps={} var qplet_tb=new Int8Array([0,1,3,2,3,0,2,0,3,0]),ntb="CDEFGABcdefgab" function set_ref(s){s.fname=parse.fname;s.istart=parse.istart;s.iend=parse.iend} function new_clef(clef_def){var s={type:C.CLEF,clef_line:2,clef_type:"t",v:curvoice.v,p_v:curvoice,time:curvoice.time,dur:0},i=1 set_ref(s) switch(clef_def[0]){case'"':i=clef_def.indexOf('"',1);s.clef_name=clef_def.slice(1,i);i++ break case'a':if(clef_def[1]=='u'){s.clef_type="a";s.clef_auto=true;i=4 break} i=4 case'C':s.clef_type="c";s.clef_line=3 break case'b':i=4 case'F':s.clef_type="b";s.clef_line=4 break case'n':i=4 s.invis=true break case't':if(clef_def[1]=='e'){s.clef_type="c";s.clef_line=4 break} i=6 case'G':break case'p':i=4 case'P':s.clef_type="p";s.clef_line=3;break default:syntax(1,"Unknown clef '$1'",clef_def) return} if(clef_def[i]>='1'&&clef_def[i]<='9'){s.clef_line=+clef_def[i] i++} delete curvoice.snd_oct if(clef_def[i+1]!='8'&&clef_def[i+1]!='1') return s switch(clef_def[i]){case'^':s.clef_oct_transp=true case'+':s.clef_octave=clef_def[i+1]=='8'?7:14 if(!s.clef_oct_transp) curvoice.snd_oct=clef_def[i+1]==8?12:24 break case'_':s.clef_oct_transp=true case'-':s.clef_octave=clef_def[i+1]=='8'?-7:-14 if(!s.clef_oct_transp) curvoice.snd_oct=clef_def[i+1]==8?-12:-24 break} return s} function get_interval(param,score){var i,val,tmp,note,pit tmp=new scanBuf;tmp.buffer=param pit=[] for(i=0;i<2;i++){note=tmp.buffer[tmp.index]?parse_acc_pit(tmp):null if(!note){if(i!=1||!score){syntax(1,errs.bad_transp) return} pit[i]=242}else{if(typeof note.acc=="object"){syntax(1,errs.bad_transp) return} pit[i]=abc2svg.pab40(note.pit,note.acc)}} return pit[1]-pit[0]} function nt_trans(nt,a){var ak,an,d,b40,n if(typeof a=="object"){n=a[0] d=a[1] a=n>0?1:-1} b40=abc2svg.pab40(nt.pit,a) +curvoice.tr_sco nt.pit=abc2svg.b40p(b40) an=abc2svg.b40a(b40) if(!d){if(an==-3) return an a=an if(nt.acc){if(!a) a=3}else{if(!curvoice.ckey.k_none) a=0} nt.acc=a return an} switch(an){case-2:if(n>0) n-=d*2 else n-=d break case-1:if(n>0) n-=d break case 0:case 3:if(n>0) n-=d else n+=d break case 1:if(n<0) n+=d break case 2:if(n<0) n+=d*2 else n+=d break} nt.acc=[n,d] return an} function set_linebreak(param){var i,item for(i=0;i<128;i++){if(char_tb[i]=="\n") char_tb[i]=nil} param=param.split(/\s+/) for(i=0;i":continue case"":item='\n' break default:syntax(1,"Bad value '$1' in %%linebreak - ignored",item) continue} char_tb[item.charCodeAt(0)]='\n'}} function set_user(parm){var k,c,v,a=parm.match(/(.)[=\s]*(\[I:.+\]|".+"|!.+!)$/) if(!a){syntax(1,'Lack of starting [, ! or " in U: / %%user') return} c=a[1];v=a[2] if(c[0]=='\\'){if(c[1]=='t') c='\t' else if(!c[1]) c=' '} k=c.charCodeAt(0) if(k>=128){syntax(1,errs.not_ascii) return} switch(char_tb[k][0]){case'0':case'd':case'i':case' ':break case'"':case'!':case'[':if(char_tb[k].length>1) break default:syntax(1,"Bad user character '$1'",c) return} switch(v){case"!beambreak!":v=" " break case"!ignore!":v="i" break case"!nil!":case"!none!":v="d" break} char_tb[k]=v} function get_st_lines(param){if(!param) return if(/^[\]\[|.-]+$/.test(param)) return param.replace(/\]/g,'[') var n=+param switch(n){case 0:return"..." case 1:return"..|" case 2:return".||" case 3:return".|||"} if(isNaN(n)||n<0||n>16) return return"||||||||||||||||".slice(0,n)} function new_block(subtype){var c_v,s={type:C.BLOCK,subtype:subtype,dur:0} c_v=curvoice if(subtype.slice(0,4)!="midi") curvoice=voice_tb[0] sym_link(s) if(c_v) curvoice=c_v return s} Abc.prototype.set_vp=function(a){var s,item,pos,val,clefpit,tr_p=0 while(1){item=a.shift() if(!item) break if(item.slice(-1)=='='&&!a.length){syntax(1,errs.bad_val,item) break} switch(item){case"clef=":s=a.shift() break case"clefpitch=":item=a.shift() if(item){val=ntb.indexOf(item[0]) if(val>=0){switch(item[1]){case"'":val+=7 break case',':val-=7 if(item[2]==',') val-=7 break} clefpit=4-val break}} syntax(1,errs.bad_val,item) break case"octave=":val=+a.shift() if(isNaN(val)) syntax(1,errs.bad_val,item) else curvoice.octave=val break case"cue=":curvoice.scale=a.shift()=='on'?.7:1 break case"instrument=":item=a.shift() val=item.indexOf('/') if(val<0){val=get_interval('c'+item) if(val==undefined) break curvoice.sound=val tr_p|=2 val=0}else{val=get_interval('c'+item.slice(val+1)) if(val==undefined) break curvoice.sound=val tr_p|=2 val=get_interval(item.replace('/','')) if(val==undefined) break} curvoice.score=cfmt.sound?curvoice.sound:val tr_p|=1 break case"map=":curvoice.map=a.shift() break case"name=":case"nm=":curvoice.nm=a.shift() if(curvoice.nm[0]=='"') curvoice.nm=cnv_escape(curvoice.nm.slice(1,-1)) curvoice.new_name=true break case"stem=":case"pos=":if(item=="pos=") item=a.shift().slice(1,-1).split(' ') else item=["stm",a.shift()];val=posval[item[1]] if(val==undefined){syntax(1,errs.bad_val,"%%pos") break} switch(item[2]){case"align":val|=C.SL_ALIGN;break case"center":val|=C.SL_CENTER;break case"close":val|=C.SL_CLOSE;break} if(!pos) pos={} pos[item[0]]=val break case"scale=":val=+a.shift() if(isNaN(val)||val<.5||val>2) syntax(1,errs.bad_val,"%%voicescale") else curvoice.scale=val break case"score=":if(cfmt.nedo){syntax(1,errs.notransp) break} item=a.shift() if(cfmt.sound) break val=get_interval(item,true) if(val!=undefined){curvoice.score=val tr_p|=1} break case"shift=":if(cfmt.nedo){syntax(1,errs.notransp) break} val=get_interval(a.shift()) if(val!=undefined){curvoice.shift=val tr_p=3} break case"sound=":if(cfmt.nedo){syntax(1,errs.notransp) break} val=get_interval(a.shift()) if(val==undefined) break curvoice.sound=val if(cfmt.sound) curvoice.score=val tr_p|=2 break case"subname=":case"sname=":case"snm=":curvoice.snm=a.shift() if(curvoice.snm[0]=='"') curvoice.snm=curvoice.snm.slice(1,-1);break case"stafflines=":val=get_st_lines(a.shift()) if(val==undefined) syntax(1,"Bad %%stafflines value") else if(curvoice.st!=undefined) par_sy.staves[curvoice.st].stafflines=val else curvoice.stafflines=val break case"staffnonote=":val=+a.shift() if(isNaN(val)) syntax(1,"Bad %%staffnonote value") else curvoice.staffnonote=val break case"staffscale=":val=+a.shift() if(isNaN(val)||val<.3||val>2) syntax(1,"Bad %%staffscale value") else curvoice.staffscale=val break case"tacet=":val=a.shift() curvoice.tacet=val||undefined break case"transpose=":if(cfmt.nedo){syntax(1,errs.notransp) break} val=get_transp(a.shift()) if(val==undefined){syntax(1,errs.bad_transp)}else{curvoice.sound=val if(cfmt.sound) curvoice.score=val tr_p=2} break default:switch(item.slice(0,4)){case"treb":case"bass":case"alto":case"teno":case"perc":s=item break default:if("GFC".indexOf(item[0])>=0) s=item else if(item.slice(-1)=='=') a.shift() break} break}} if(pos){curvoice.pos=clone(curvoice.pos) for(item in pos) if(pos.hasOwnProperty(item)) curvoice.pos[item]=pos[item]} if(s){s=new_clef(s) if(s){if(clefpit) s.clefpit=clefpit get_clef(s)}} if(tr_p&2){tr_p=(curvoice.sound|0)+(curvoice.shift|0) if(tr_p) curvoice.tr_snd=abc2svg.b40m(tr_p+122)-36 else if(curvoice.tr_snd) curvoice.tr_snd=0}} function set_kv_parm(a){if(!curvoice.init){curvoice.init=true if(info.V){if(info.V[curvoice.id]) a=info.V[curvoice.id].concat(a) if(info.V['*']) a=info.V['*'].concat(a)}} if(a.length) self.set_vp(a)} function memo_kv_parm(vid,a){if(!a.length) return if(!info.V) info.V={} if(info.V[vid]) Array.prototype.push.apply(info.V[vid],a) else info.V[vid]=a} function new_key(param){var i,key_end,c,tmp,note,sf="FCGDAEB".indexOf(param[0])-1,mode=0,s={type:C.KEY,dur:0} set_ref(s);i=1 if(sf<-1){switch(param[0]){case'H':key_end=true if(param[1].toLowerCase()!='p'){syntax(1,"Unknown bagpipe-like key") break} s.k_bagpipe=param[1];sf=param[1]=='P'?0:2;i++ if(!cfmt.temper) cfmt.temper=new Float32Array([11.62,12.55,1.66,2.37,3.49,0,1.66,2.37,3.49,4.41,5.53,0,3.49,4.41,5.53,6.63,7.35,4.41,5.53,6.63,7.35,8.19,0,6.63,7.35,8.19,9.39,10.51,0,8.19,9.39,10.51,11.62,12.55,0,10.51,11.62,12.55,1.66,1.66]) break case'P':syntax(1,"K:P is deprecated");sf=0;s.k_drum=true;key_end=true break case'n':if(param.indexOf("none")==0){sf=0;s.k_none=true;i=4 break} default:s.k_map=[] s.k_mode=0 return[s,info_split(param)]}} if(!key_end){switch(param[i]){case'#':sf+=7;i++;break case'b':sf-=7;i++;break} param=param.slice(i).trim() switch(param.slice(0,3).toLowerCase()){default:if(param[0]!='m'||(param[1]!=' '&¶m[1]!='\t'&¶m[1]!='\n')){key_end=true break} case"aeo":case"m":case"min":sf-=3;mode=5 break case"dor":sf-=2;mode=1 break case"ion":case"maj":break case"loc":sf-=5;mode=6 break case"lyd":sf+=1;mode=3 break case"mix":sf-=1;mode=4 break case"phr":sf-=4;mode=2 break} if(!key_end) param=param.replace(/\w+\s*/,'') if(param.indexOf("exp ")==0){param=param.replace(/\w+\s*/,'') if(!param) syntax(1,"No accidental after 'exp'");s.exp=1} c=param[0] if(c=='^'||c=='_'||c=='='){s.k_a_acc=[];tmp=new scanBuf;tmp.buffer=param do{note=parse_acc_pit(tmp) if(!note) break s.k_a_acc.push(note);c=param[tmp.index] while(c==' ') c=param[++tmp.index]}while(c=='^'||c=='_'||c=='=');param=param.slice(tmp.index)}else if(s.exp&¶m.indexOf("none")==0){sf=0 param=param.replace(/\w+\s*/,'')}} if(sf<-7||sf>7){syntax(1,"Key with double sharps/flats") if(sf>7) sf-=12 else sf+=12} s.k_sf=sf;s.k_map=s.k_bagpipe&&!sf?abc2svg.keys[9]:abc2svg.keys[sf+7] if(s.k_a_acc){s.k_map=new Int8Array(s.k_map) i=s.k_a_acc.length while(--i>=0){note=s.k_a_acc[i] s.k_map[(note.pit+19)%7]=note.acc}} s.k_mode=mode s.k_b40=[1,24,7,30,13,36,19,2,25,8,31,14,37,20,3][sf+7] return[s,info_split(param)]} function new_meter(p){var p_v,s={type:C.METER,dur:0,a_meter:[]},meter={},val,v,m1=0,m2,i=0,j,wmeasure,in_parenth;set_ref(s) if(p.indexOf("none")==0){i=4;wmeasure=1}else{wmeasure=0 while(i'9'){syntax(1,"Bad char '$1' in M:",p[i]) return} m2=2;meter.top=p[i++] for(;;){while(p[i]>='0'&&p[i]<='9') meter.top+=p[i++] if(p[i]==')'){if(p[i+1]!='/') break i++} if(p[i]=='/'){i++;if(p[i]<='0'||p[i]>'9'){syntax(1,"Bad char '$1' in M:",p[i]) return} meter.bot=p[i++] while(p[i]>='0'&&p[i]<='9') meter.bot+=p[i++] break} if(p[i]!=' '&&p[i]!='+') break if(i>=p.length||p[i+1]=='(') break meter.top+=p[i++]} m1=+meter.top break} if(!in_parenth){if(meter.bot) m2=+meter.bot wmeasure+=m1*C.BLEN/m2} s.a_meter.push(meter);meter={} while(p[i]==' ') i++ if(p[i]=='+'){meter.top=p[i++];s.a_meter.push(meter);meter={}}}} if(p[i]=='='){val=p.substring(++i).match(/^(\d+)\/(\d+)$/) if(!val){syntax(1,"Bad duration '$1' in M:",p.substring(i)) return} wmeasure=C.BLEN*val[1]/val[2]} if(!wmeasure){syntax(1,errs.bad_val,'M:') return} s.wmeasure=wmeasure if(cfmt.writefields.indexOf('M')<0) s.a_meter=[] if(parse.state!=3){info.M=p;glovar.meter=s if(parse.state){if(!glovar.ulen){if(wmeasure<=1||wmeasure>=C.BLEN*3/4) glovar.ulen=C.BLEN/8 else glovar.ulen=C.BLEN/16} for(v=0;v0){d=text.slice(0,i).split(/\s+/) text=text.slice(i+1).replace(/^\s+/,'') while(1){c=d.shift() if(!c) break nd=get_nd(c) if(!nd) return if(!s.tempo_notes) s.tempo_notes=[] s.tempo_notes.push(nd)} if(text.slice(0,4)=="ca. "){s.tempo_ca='ca. ' text=text.slice(4)} i=text.indexOf('/') if(i>0){nd=get_nd(text) if(!nd) return s.new_beat=nd}else{s.tempo=+text if(!s.tempo||isNaN(s.tempo)){syntax(1,"Bad tempo value") return}}} if(parse.state<2||(!curvoice.time&&!glovar.tempo)){info.Q=txt glovar.tempo=s return} if(!glovar.tempo) syntax(0,"No previous tempo") if(new_ctrl(s)) sym_link(s)} function do_info(info_type,text){var s,d1,d2,a,vid,tim,v,p_v if(curvoice&&curvoice.ignore){switch(info_type){default:return case'P':case'Q':case'V':break}} switch(info_type){case'I':self.do_pscom(text) break case'L':a=text.match(/^1\/(\d+)(=(\d+)\/(\d+))?$/) if(a){d1=+a[1] if(!d1||(d1&(d1-1))!=0) break d1=C.BLEN/d1 if(a[2]){d2=+a[4] d2=d2?+a[3]/d2*C.BLEN:0}else{d2=d1}}else if(text=="auto"){d1=d2=-1} if(!d2){syntax(1,"Bad L: value") break} if(parse.state<=1){glovar.ulen=d1}else{curvoice.ulen=d1;curvoice.dur_fact=d2/d1} break case'M':new_meter(text) break case'U':set_user(text) break case'P':if(!parse.state) break if(parse.state==1){info.P=text break} s={type:C.PART,text:text,time:tim} if(!new_ctrl(s)) break sym_link(s) if(cfmt.writefields.indexOf(info_type)<0) s.invis=true break case'Q':if(!parse.state) break new_tempo(text) break case'V':get_voice(text) if(parse.state==3) curvoice.ignore=!par_sy.voices[curvoice.v] break case'K':if(!parse.state) break get_key(text) break case'N':case'R':if(!info[info_type]) info[info_type]=text else info[info_type]+='\n'+text break case'r':if(!user.keep_remark||parse.state!=3) break s={type:C.REMARK,text:text,dur:0} sym_link(s) break default:syntax(0,"'$1:' line ignored",info_type) break}} function adjust_dur(s){var s2,time,auto_time,i,fac;s2=curvoice.last_sym if(!s2) return;if(s2.type==C.MREST||s2.type==C.BAR) return while(s2.type!=C.BAR&&s2.prev) s2=s2.prev;time=s2.time;auto_time=curvoice.time-time fac=curvoice.wmeasure/auto_time if(fac==1) return for(;s2;s2=s2.next){s2.time=time if(!s2.dur||s2.grace) continue s2.dur*=fac;s2.dur_orig*=fac;time+=s2.dur if(s2.type!=C.NOTE&&s2.type!=C.REST) continue for(i=0;i<=s2.nhd;i++) s2.notes[i].dur*=fac} curvoice.time=s.time=time} function new_bar(){var s2,c,bar_type,line=parse.line,s={type:C.BAR,fname:parse.fname,istart:parse.bol+line.index,dur:0,multi:0} if(vover&&vover.bar) get_vover('|') if(glovar.new_nbar){s.bar_num=glovar.new_nbar;glovar.new_nbar=0} bar_type=line.char() while(1){c=line.next_char() switch(c){case'|':case'[':case']':case':':bar_type+=c continue} break} if(bar_type[0]==':'){if(bar_type==':'){bar_type='|';s.bar_dotted=true}else{s.rbstop=2}} if(a_gch) csan_add(s) if(a_dcn.length) deco_cnv(s) if(bar_type.slice(-1)=='['&&!(/[0-9" ]/.test(c))){bar_type=bar_type.slice(0,-1);line.index--;c='['} if(c>'0'&&c<='9'){s.text=c while(1){c=line.next_char() if("0123456789,.-".indexOf(c)<0) break s.text+=c}}else if(c=='"'&&bar_type.slice(-1)=='['){s.text="" while(1){c=line.next_char() if(!c){syntax(1,"No end of repeat string") return} if(c=='"'){line.index++ break} s.text+=c}} if(bar_type[0]==']'){s.rbstop=2 if(bar_type.length!=1) bar_type=bar_type.slice(1) else s.invis=true} s.iend=parse.bol+line.index if(s.text&&bar_type.slice(-1)=='['&&bar_type!='[') bar_type=bar_type.slice(0,-1) if(bar_type.slice(-1)==':'){s.rbstop=1 if(s.text){syntax(1,"Variant ending on a left repeat bar") delete s.text} curvoice.tie_s_rep=null} if(s.text){s.rbstart=s.rbstop=2 if(s.text[0]=='1'){curvoice.tie_s_rep=curvoice.tie_s if(curvoice.acc_tie) curvoice.acc_tie_rep=curvoice.acc_tie.slice() else if(curvoice.acc_tie_rep) curvoice.acc_tie_rep=null}else{curvoice.tie_s=curvoice.tie_s_rep if(curvoice.acc_tie_rep) curvoice.acc_tie=curvoice.acc_tie_rep.slice()} if(curvoice.norepbra&&!curvoice.second) s.norepbra=1} if(curvoice.ulen<0) adjust_dur(s);if((bar_type=="["||bar_type=="|:")&&!curvoice.eoln&&!s.a_gch&&!s.invis){s2=curvoice.last_sym if(s2&&s2.type==C.BAR){if((bar_type=="["&&!s2.text)||s.norepbra){if(s.text){s2.text=s.text if(curvoice.st&&!s.norepbra&&!(par_sy.staves[curvoice.st-1].flags&STOP_BAR)) s2.xsh=4} if(s.norepbra) s2.norepbra=1 if(s.rbstart) s2.rbstart=s.rbstart if(s.rbstop) s2.rbstop=s.rbstop return} if(bar_type=="|:"){switch(s2.bar_type){case":|":s2.bar_type="::";s2.rbstop=2 return}}}} switch(bar_type){case"[":case"[]":case"[|]":s.invis=true;bar_type=s.rbstart?"[":"[]" break case":|:":case":||:":bar_type="::" break case"||":if(cfmt["abc-version"]>="2.2") break case"[|":case"|]":s.rbstop=2 break} s.bar_type=bar_type if(!curvoice.lyric_restart) curvoice.lyric_restart=s if(!curvoice.sym_restart) curvoice.sym_restart=s sym_link(s);s.st=curvoice.st if(s.text&&s.st>0&&!s.norepbra&&!(par_sy.staves[s.st-1].flags&STOP_BAR)&&bar_type!='[') s.xsh=4 if(!s.bar_dotted&&!s.invis) curvoice.acc=[]} function parse_staves(p){var v,vid,vids={},a_vf=[],err=false,flags=0,brace=0,bracket=0,parenth=0,flags_st=0,e,a=p.match(/[^[\]|{}()*+\s]+|[^\s]/g) if(!a){syntax(1,errs.bad_val,"%%score") return} while(1){e=a.shift() if(!e) break switch(e){case'[':if(parenth||brace+bracket>=2){syntax(1,errs.misplaced,'[');err=true break} flags|=brace+bracket==0?OPEN_BRACKET:OPEN_BRACKET2;bracket++;flags_st<<=8;flags_st|=OPEN_BRACKET break case'{':if(parenth||brace||bracket>=2){syntax(1,errs.misplaced,'{');err=true break} flags|=!bracket?OPEN_BRACE:OPEN_BRACE2;brace++;flags_st<<=8;flags_st|=OPEN_BRACE break case'(':if(parenth){syntax(1,errs.misplaced,'(');err=true break} flags|=OPEN_PARENTH;parenth++;flags_st<<=8;flags_st|=OPEN_PARENTH break case'*':if(brace&&!parenth&&!(flags&(OPEN_BRACE|OPEN_BRACE2))) flags|=FL_VOICE break case'+':flags|=MASTER_VOICE break case']':case'}':case')':syntax(1,"Bad voice ID in %%score");err=true break default:vid=e while(1){e=a.shift() if(!e) break switch(e){case']':if(!(flags_st&OPEN_BRACKET)){syntax(1,errs.misplaced,']');err=true break} bracket--;flags|=brace+bracket==0?CLOSE_BRACKET:CLOSE_BRACKET2;flags_st>>=8 continue case'}':if(!(flags_st&OPEN_BRACE)){syntax(1,errs.misplaced,'}');err=true break} brace--;flags|=!bracket?CLOSE_BRACE:CLOSE_BRACE2;flags&=~FL_VOICE;flags_st>>=8 continue case')':if(!(flags_st&OPEN_PARENTH)){syntax(1,errs.misplaced,')');err=true break} parenth--;flags|=CLOSE_PARENTH;flags_st>>=8 continue case'|':flags|=STOP_BAR continue} break} if(vids[vid]){syntax(1,"Double voice in %%score") err=true}else{vids[vid]=true a_vf.push([vid,flags])} flags=0 if(!e) break a.unshift(e) break}} if(flags_st!=0){syntax(1,"'}', ')' or ']' missing in %%score");err=true} if(err||!a_vf.length) return return a_vf} function info_split(text){if(!text) return[] var a=text.match(/[^\s"=]+=?|"[^"]*"/g) if(!a){syntax(1,"Unterminated string") return[]} return a} var reg_dur=/(\d*)(\/*)(\d*)/g function parse_dur(line){var res,num,den;reg_dur.lastIndex=line.index;res=reg_dur.exec(line.buffer) if(!res[0]) return[1,1];num=res[1]||1;den=res[3]||1 if(!res[3]) den*=1<='1'&&c<='9')||c=='/'){nd=parse_dur(line);if(acc<0) nd[0]=-nd[0] if(cfmt.nedo&&nd[1]==1){nd[0]*=12 nd[1]*=cfmt.nedo} acc=nd c=line.char()}} pit=ntb.indexOf(c)+16;c=line.next_char() if(pit<16){syntax(1,"'$1' is not a note",line.buffer[line.index-1]) return} while(c=="'"){pit+=7;c=line.next_char()} while(c==','){pit-=7;c=line.next_char()} note={pit:pit,shhd:0,shac:0} if(acc) note.acc=acc return note} function set_map(note,acc){var pit=note.pit,nn=not2abc(pit,acc),map=maps[curvoice.map] if(!map[nn]){nn='o'+nn.replace(/[',]+/,'') if(!map[nn]){nn='k'+ntb[(pit+75- curvoice.ckey.k_sf*11)%7] if(!map[nn]){nn='all' if(!map[nn]) return}}} note.map=map=map[nn] if(map[1]){note.pit=pit=map[1].pit note.acc=map[1].acc if(map[1].notrp){note.notrp=1 note.noplay=1}} if(map[2]) note.color=map[2] nn=map[3] if(nn) note.midi=pit2mid(nn.pit+19,nn.acc)} function parse_basic_note(line,ulen){var nd,note=parse_acc_pit(line) if(!note) return if(line.char()=='0'){parse.stemless=true;line.index++} nd=parse_dur(line);note.dur=ulen*nd[0]/nd[1] return note} function parse_vpos(){var line=parse.line,ty=0 if(a_dcn.length&&a_dcn[a_dcn.length-1]=="dot"){ty=C.SL_DOTTED a_dcn.pop()} switch(line.next_char()){case"'":line.index++ return ty+C.SL_ABOVE case",":line.index++ return ty+C.SL_BELOW case'?':line.index++ return ty+C.SL_CENTER} return ty+C.SL_AUTO} function slur_add(s,nt){var i,s2,sl for(i=curvoice.sls.length;--i>=0;){sl=curvoice.sls[i] if(sl.ss==s) continue curvoice.sls.splice(i,1) sl.se=s if(nt) sl.nte=nt s2=sl.ss if(!s2.sls) s2.sls=[] s2.sls.push(sl) if(sl.grace) sl.grace.sl1=true return} for(s2=s.prev;s2;s2=s2.prev){if(s2.type==C.BAR&&s2.bar_type[0]==':'&&s2.text){if(!s2.sls) s2.sls=[];s2.sls.push({ty:C.SL_AUTO,ss:s2,se:s}) if(nt) s2.sls[s2.sls.length-1].nte=nt return}} if(!s.sls) s.sls=[];s.sls.push({ty:C.SL_AUTO,se:s,loc:'i'}) if(nt) s.sls[s.sls.length-1].nte=nt} function pit2mid(pit,acc){var p=[0,2,4,5,7,9,11][pit%7],o=((pit/7)|0)*12,p0,p1,s,b40 if(curvoice.snd_oct) o+=curvoice.snd_oct if(acc==3) acc=0 if(acc){if(typeof acc=="object"){s=acc[0]/acc[1] if(acc[1]==100) return p+o+s}else{s=acc}}else{if(cfmt.temper) return cfmt.temper[abc2svg.p_b40[pit%7]]+o return p+o} if(!cfmt.nedo){if(!cfmt.temper){p+=o+s return p}}else{if(typeof acc!="object"){b40=abc2svg.p_b40[pit%7]+acc return cfmt.temper[b40]+o} if(acc[1]==cfmt.nedo){b40=abc2svg.p_b40[pit%7] return cfmt.temper[b40]+o+s}} p0=cfmt.temper[abc2svg.p_b40[pit%7]] if(s>0){p1=cfmt.temper[(abc2svg.p_b40[pit%7]+1)%40] if(p1p0) p1-=12 s=-s} return p0+o+(p1-p0)*s} function do_ties(s,tie_s){var i,m,not1,not2,mid,g,nt=0,se=(tie_s.time+tie_s.dur)==curvoice.time for(m=0;m<=s.nhd;m++){not2=s.notes[m] mid=not2.midi if(tie_s.type!=C.GRACE){for(i=0;i<=tie_s.nhd;i++){not1=tie_s.notes[i] if(!not1.tie_ty) continue if(not1.midi==mid&&(!se||!not1.tie_e)){not2.tie_s=not1 not2.s=s if(se){not1.tie_e=not2 not1.s=tie_s} nt++ break}}}else{for(g=tie_s.extra;g;g=g.next){not1=g.notes[0] if(!not1.tie_ty) continue if(not1.midi==mid){g.ti1=true not2.tie_s=not1 not2.s=s not1.tie_e=not2 not1.s=g nt++ break}}}} if(!nt) error(1,tie_s,"Bad tie") else s.ti2=true} Abc.prototype.new_note=function(grace,sls){var note,s,in_chord,c,dcn,type,tie_s,acc_tie,i,n,s2,nd,res,num,dur,apit,div,ty,dpit=0,sl1=[],line=parse.line,a_dcn_sav=a_dcn a_dcn=[] parse.stemless=false;s={type:C.NOTE,fname:parse.fname,stem:0,multi:0,nhd:0,xmx:0} s.istart=parse.bol+line.index if(curvoice.color) s.color=curvoice.color if(grace){s.grace=true}else{if(curvoice.tie_s){tie_s=curvoice.tie_s curvoice.tie_s=null} if(a_gch) csan_add(s) if(parse.repeat_n){s.repeat_n=parse.repeat_n;s.repeat_k=parse.repeat_k;parse.repeat_n=0}} c=line.char() switch(c){case'X':s.invis=true case'Z':s.type=C.MREST;c=line.next_char() s.nmes=(c>'0'&&c<='9')?line.get_int():1;if(curvoice.wmeasure==1){error(1,s,"multi-measure rest, but no measure!") return} s.dur=curvoice.wmeasure*s.nmes if(curvoice.second){delete curvoice.eoln curvoice.time+=s.dur return} if(s.nmes==1){s.type=C.REST;s.dur_orig=s.dur;s.fmr=1 s.notes=[{pit:18,dur:s.dur}]}else{glovar.mrest_p=true if(par_sy.voices.length==1){s.tacet=curvoice.tacet delete s.invis}} break case'y':s.type=C.SPACE;s.invis=true;s.dur=0;c=line.next_char() if(c>='0'&&c<='9') s.width=line.get_int() else s.width=10 if(tie_s){curvoice.tie_s=tie_s tie_s=null} break case'x':s.invis=true case'z':s.type=C.REST;line.index++;nd=parse_dur(line);s.dur_orig=((curvoice.ulen<0)?C.BLEN:curvoice.ulen)*nd[0]/nd[1];s.dur=s.dur_orig*curvoice.dur_fact;if(s.dur==curvoice.wmeasure) s.fmr=1 s.notes=[{pit:18,dur:s.dur_orig}] break case'[':in_chord=true;c=line.next_char() default:if(curvoice.acc_tie){acc_tie=curvoice.acc_tie curvoice.acc_tie=null} s.notes=[] while(1){if(in_chord){while(1){if(!c) break i=c.charCodeAt(0);if(i>=128){syntax(1,errs.not_ascii) return} type=char_tb[i] switch(type[0]){case'(':sl1.push(parse_vpos());c=line.char() continue case'!':if(type.length>1) a_dcn.push(type.slice(1,-1)) else get_deco() c=line.next_char() continue} break}} note=parse_basic_note(line,s.grace?C.BLEN/4:curvoice.ulen<0?C.BLEN:curvoice.ulen) if(!note) return if(curvoice.octave) note.pit+=curvoice.octave*7 apit=note.pit+19 i=note.acc if(!i){if(cfmt["propagate-accidentals"][0]=='p') i=curvoice.acc[apit%7] else i=curvoice.acc[apit] if(!i) i=curvoice.ckey.k_map[apit%7]||0} if(i){if(cfmt["propagate-accidentals"][0]=='p') curvoice.acc[apit%7]=i else if(cfmt["propagate-accidentals"][0]!='n') curvoice.acc[apit]=i} if(acc_tie&&acc_tie[apit]) i=acc_tie[apit] if(curvoice.map&&maps[curvoice.map]) set_map(note,i) if(!note.midi) note.midi=pit2mid(apit,i) if(curvoice.tr_sco&&!note.notrp){i=nt_trans(note,i) if(i==-3){error(1,s,"triple sharp/flat") i=note.acc>0?1:-1 note.pit+=i note.acc=i} dpit=note.pit+19-apit} if(curvoice.tr_snd) note.midi+=curvoice.tr_snd if(i){switch(cfmt["writeout-accidentals"][1]){case'd':s2=curvoice.ckey if(!s2.k_a_acc) break for(n=0;n0){n=num*2-1;s.dur=s.dur*n/num;s.dur_orig=s.dur_orig*n/num for(i=0;i<=s.nhd;i++) s.notes[i].dur=s.notes[i].dur*n/num;s2.dur/=num;s2.dur_orig/=num for(i=0;i<=s2.nhd;i++) s2.notes[i].dur/=num}else{num=-num;n=num*2-1;s.dur/=num;s.dur_orig/=num for(i=0;i<=s.nhd;i++) s.notes[i].dur/=num;s2.dur=s2.dur*n/num;s2.dur_orig=s2.dur_orig*n/num for(i=0;i<=s2.nhd;i++) s2.notes[i].dur=s2.notes[i].dur*n/num} curvoice.time=s2.time+s2.dur;for(s2=s2.next;s2;s2=s2.next) s2.time=curvoice.time}}else{div=curvoice.ckey.k_bagpipe?8:4 for(i=0;i<=s.nhd;i++) s.notes[i].dur/=div;s.dur/=div;s.dur_orig/=div if(grace.stem) s.stem=grace.stem} curvoice.last_note=s c=line.char() while(1){switch(c){case'.':if(line.buffer[line.index+1]!='-') break a_dcn.push("dot") line.index++ case'-':ty=parse_vpos() for(i=0;i<=s.nhd;i++){s.notes[i].tie_ty=ty s.notes[i].s=s} curvoice.tie_s=grace||s curvoice.tie_s.ti1=true for(i=0;i<=s.nhd;i++){note=s.notes[i] apit=note.pit+19 -dpit if(curvoice.acc[apit]||(acc_tie&&acc_tie[apit])){if(!curvoice.acc_tie) curvoice.acc_tie=[] n=curvoice.acc[apit] if(acc_tie&&acc_tie[apit]) n=acc_tie[apit] curvoice.acc_tie[apit]=n}} c=line.char() continue} break} if(tie_s) do_ties(s,tie_s)} sym_link(s) if(!grace){if(!curvoice.lyric_restart) curvoice.lyric_restart=s if(!curvoice.sym_restart) curvoice.sym_restart=s} if(a_dcn_sav.length){a_dcn=a_dcn_sav deco_cnv(s,s.prev)} if(grace&&s.ottava) grace.ottava=s.ottava if(parse.stemless) s.stemless=true s.iend=parse.bol+line.index return s} function tp_adj(s,fact){var d,tim=s.time,to=curvoice.time-tim,tt=to*fact curvoice.time=tim+tt while(1){s.in_tuplet=true if(!s.grace){s.time=tim if(s.dur){d=Math.round(s.dur*tt/to) to-=s.dur s.dur=d tt-=s.dur tim+=s.dur}} if(!s.next){if(s.tpe) s.tpe++ else s.tpe=1 break} s=s.next}} function get_deco(){var c,line=parse.line,i=line.index,dcn="" while(1){c=line.next_char() if(!c){line.index=i syntax(1,"No end of decoration") return} if(c=='!') break dcn+=c} a_dcn.push(dcn)} var nil="0",char_tb=[nil,nil,nil,nil,nil,nil,nil,nil,nil," ","\n",nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil," ","!",'"',"i","\n",nil,"&",nil,"(",")","i",nil,nil,"-","!dot!",nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,"|","i","<","n","<","i","i","n","n","n","n","n","n","n","!fermata!","d","d","d","!emphasis!","!lowermordent!","d","!coda!","!uppermordent!","d","d","!segno!","!trill!","d","d","d","n","d","n","[","\\","|","n","n","i","n","n","n","n","n","n","n","d","d","d","d","d","d","d","d","d","d","d","d","d","!upbow!","!downbow!","d","n","n","n","{","|","}","!gmark!",nil,] function parse_music_line(){var grace,last_note_sav,a_dcn_sav,no_eol,s,tps,tp=[],tpn=-1,sls=[],line=parse.line function check_mac(m){var i,j,b for(i=1,j=line.index+1;i=14){n-=7;c+="'"} return ntb[n]+c} function expand(m,b){if(b==undefined) return m var c,i,r="",n=m.length for(i=0;i='h'&&c<='z'){r+=n2n(b+c.charCodeAt(0)-'n'.charCodeAt(0))}else{r+=c}} return r} function parse_mac(k,m,b){var te,ti,curv,s,line_sav=line,istart_sav=parse.istart;parse.line=line=new scanBuf;parse.istart+=line_sav.index;if(cfmt.writefields.indexOf('m')<0){line.buffer=k.replace('n',n2n(b)) s=curvoice.last_sym ti=curvoice.time parse_seq(true) if(!s) s=curvoice.sym for(s=s.next;s;s=s.next) s.noplay=true te=curvoice.time curv=curvoice curvoice=clone_voice(curv.id+'-p') if(!par_sy.voices[curvoice.v]){curvoice.second=true par_sy.voices[curvoice.v]={st:curv.st,second:true,range:curvoice.v}} curvoice.time=ti s=curvoice.last_sym parse.line=line=new scanBuf parse.istart+=line_sav.index line.buffer=expand(m,b) parse_seq(true) if(curvoice.time!=te) syntax(1,"Bad length of the macro sequence") if(!s) s=curvoice.sym for(;s;s=s.next) s.invis=s.play=true curvoice=curv}else{line.buffer=expand(m,b) parse_seq(true)} parse.line=line=line_sav parse.istart=istart_sav} function parse_seq(in_mac){var c,idx,type,k,s,dcn,i,n,text,note while(1){c=line.char() if(!c) break if(!in_mac&&maci[c]){n=undefined for(k in mac){if(!mac.hasOwnProperty(k)||k[0]!=c) continue if(k.indexOf('n')<0){if(line.buffer.indexOf(k,line.index) !=line.index) continue line.index+=k.length}else{n=check_mac(k) if(n==undefined) continue} parse_mac(k,mac[k],n) n=1 break} if(n) continue} idx=c.charCodeAt(0) if(idx>=128){syntax(1,errs.not_ascii) line.index++ break} type=char_tb[idx] switch(type[0]){case' ':s=curvoice.last_note if(s){s.beam_end=true if(grace) grace.gr_shift=true} break case'\n':if(cfmt.barsperstaff) break curvoice.eoln=true break case'&':if(grace){syntax(1,errs.bad_grace) break} c=line.next_char() if(c==')'){get_vover(c) break} get_vover('&') continue case'(':c=line.next_char() if(c>'0'&&c<='9'){if(grace){syntax(1,errs.bad_grace) break} var pplet=line.get_int(),qplet=qplet_tb[pplet],rplet=pplet c=line.char() if(c==':'){c=line.next_char() if(c>'0'&&c<='9'){qplet=line.get_int();c=line.char()} if(c==':'){c=line.next_char() if(c>'0'&&c<='9'){rplet=line.get_int();c=line.char()}else{syntax(1,"Invalid 'r' in tuplet") continue}}} if(qplet==0||qplet==undefined) qplet=(curvoice.wmeasure%9)==0?3:2;if(tpn<0) tpn=tp.length tp.push({p:pplet,q:qplet,r:rplet,ro:rplet,f:curvoice.tup||cfmt.tuplets}) continue} if(c=='&'){if(grace){syntax(1,errs.bad_grace) break} get_vover('(') break} line.index--;sls.push(parse_vpos()) continue case')':s=curvoice.last_sym if(s){switch(s.type){case C.SPACE:if(!s.notes){s.notes=[] s.notes[0]={}} case C.NOTE:case C.REST:break case C.GRACE:for(s=s.extra;s.next;s=s.next);break default:s=null break}} if(!s){syntax(1,errs.bad_char,c) break} slur_add(s) break case'!':if(type.length>1) a_dcn.push(type.slice(1,-1)) else get_deco() break case'"':if(grace){syntax(1,errs.bad_grace) break} parse_gchord(type) break case'[':if(type.length>1){self.do_pscom(type.slice(3,-1)) break} var c_next=line.buffer[line.index+1] if('|[]: "'.indexOf(c_next)>=0||(c_next>='1'&&c_next<='9')){if(grace){syntax(1,errs.bar_grace) break} new_bar() continue} if(line.buffer[line.index+2]==':'){if(grace){syntax(1,errs.bad_grace) break} i=line.buffer.indexOf(']',line.index+1) if(i<0){syntax(1,"Lack of ']'") break} text=line.buffer.slice(line.index+3,i).trim() parse.istart=parse.bol+line.index;parse.iend=parse.bol+ ++i;line.index=0;do_info(c_next,text);line.index=i continue} case'n':s=self.new_note(grace,sls) if(!s) continue if(grace||!s.notes) continue if(tpn>=0){s.tp=tp.slice(tpn) tpn=-1 if(tps) s.tp[0].s=tps tps=s}else if(!tps){continue} k=tp[tp.length-1] if(--k.r>0) continue while(1){tp_adj(tps,k.q/k.p) i=k.ro if(k.s) tps=k.s tp.pop() if(!tp.length){tps=null break} k=tp[tp.length-1] k.r-=i if(k.r>0) break} continue case'<':if(!curvoice.last_note){syntax(1,"No note before '<'") break} if(grace){syntax(1,"Cannot have a broken rhythm in grace notes") break} n=c=='<'?1:-1 while(c=='<'||c=='>'){n*=2;c=line.next_char()} curvoice.brk_rhythm=n continue case'i':break case'{':if(grace){syntax(1,"'{' in grace note") break} last_note_sav=curvoice.last_note;curvoice.last_note=null;a_dcn_sav=a_dcn;a_dcn=[] grace={type:C.GRACE,fname:parse.fname,istart:parse.bol+line.index,dur:0,multi:0} if(curvoice.color) grace.color=curvoice.color switch(curvoice.pos.gst&0x07){case C.SL_ABOVE:grace.stem=1;break case C.SL_BELOW:grace.stem=-1;break case C.SL_HIDDEN:grace.stem=2;break} sym_link(grace);c=line.next_char() if(c=='/'){grace.sappo=true break} continue case'|':if(grace){syntax(1,errs.bar_grace) break} new_bar() continue case'}':if(curvoice.ignore){grace=null break} s=curvoice.last_note if(!grace||!s){syntax(1,errs.bad_char,c) break} if(a_dcn.length) syntax(1,"Decoration ignored");grace.extra=grace.next;grace.extra.prev=null;grace.next=null;curvoice.last_sym=grace;grace=null if(!s.prev&&!curvoice.ckey.k_bagpipe){for(i=0;i<=s.nhd;i++) s.notes[i].dur*=2;s.dur*=2;s.dur_orig*=2} curvoice.last_note=last_note_sav;a_dcn=a_dcn_sav break case"\\":if(!line.buffer[line.index+1]){no_eol=true break} default:syntax(1,errs.bad_char,c) break} line.index++}} if(parse.state!=3) return if(parse.tp){tp=parse.tp tpn=parse.tpn tps=parse.tps parse.tp=null} parse_seq() if(tp.length){parse.tp=tp parse.tps=tps parse.tpn=tpn} if(sls.length) syntax(1,"Start of slur without note") if(grace){syntax(1,"No end of grace note sequence");curvoice.last_sym=grace.prev;curvoice.last_note=last_note_sav if(grace.prev) grace.prev.next=null} if(!no_eol&&!cfmt.barsperstaff&&!vover&&char_tb['\n'.charCodeAt(0)]=='\n') curvoice.eoln=true if(curvoice.eoln&&cfmt.breakoneoln&&curvoice.last_note) curvoice.last_note.beam_end=true} var sheet var add_fstyle=typeof document!="undefined"?function(s){var e if(cfmt.fullsvg) font_style+="\n"+s if(!sheet){if(abc2svg.sheet){sheet=abc2svg.sheet e=sheet.cssRules.length while(--e>=0) sheet.deleteRule(e)}else{e=document.createElement('style') document.head.appendChild(e) abc2svg.sheet=sheet=e.sheet}} s=s.match(/[^{]+{[^}]+}/g) while(1){e=s.shift() if(!e) break sheet.insertRule(e,sheet.cssRules.length)}}:function(s){font_style+="\n"+s} var sw_tb=new Float32Array([.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.250,.333,.408,.500,.500,.833,.778,.333,.333,.333,.500,.564,.250,.564,.250,.278,.500,.500,.500,.500,.500,.500,.500,.500,.500,.500,.278,.278,.564,.564,.564,.444,.921,.722,.667,.667,.722,.611,.556,.722,.722,.333,.389,.722,.611,.889,.722,.722,.556,.722,.667,.556,.611,.722,.722,.944,.722,.722,.611,.333,.278,.333,.469,.500,.333,.444,.500,.444,.500,.444,.333,.500,.500,.278,.278,.500,.278,.778,.500,.500,.500,.500,.333,.389,.278,.500,.500,.722,.500,.500,.444,.480,.200,.480,.541,.500]),ssw_tb=new Float32Array([.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.000,.278,.278,.355,.556,.556,.889,.667,.191,.333,.333,.389,.584,.278,.333,.278,.278,.556,.556,.556,.556,.556,.556,.556,.556,.556,.556,.278,.278,.584,.584,.584,.556,1.015,.667,.667,.722,.722,.667,.611,.778,.722,.278,.500,.667,.556,.833,.722,.778,.667,.778,.722,.667,.611,.722,.667,.944,.667,.667,.611,.278,.278,.278,.469,.556,.333,.556,.556,.500,.556,.556,.278,.556,.556,.222,.222,.500,.222,.833,.556,.556,.556,.556,.333,.500,.278,.556,.500,.722,.500,.500,.500,.334,.260,.334,.584,.512]),cw_tb=sw_tb function cwid(c){var i=c.charCodeAt(0) if(i>=0x80){if(i>=0x300&&i<0x370) return 0;i=0x61} return cw_tb[i]} function cwidf(c){return cwid(c)*gene.curfont.swfac} var strwh (function(){if(typeof document!="undefined"){var el strwh=function(str){if(str.wh) return str.wh if(!el){el=document.createElement('text') el.style.position='absolute' el.style.top='-1000px' el.style.padding='0' document.body.appendChild(el)} var c,font=gene.curfont,h=font.size,w=0,n=str.length,i0=0,i=0 el.className=font_class(font) el.style.lineHeight=1 if(typeof str=="object"){el.innerHTML=str str.wh=[el.clientWidth,el.clientHeight] return str.wh} str=str.replace(/<|>|&[^&\s]*?;|&/g,function(c){switch(c){case'<':return"<" case'>':return">" case'&':return"&"} return c}) while(1){i=str.indexOf('$',i) if(i>=0){c=str[i+1] if(c=='0'){font=gene.deffont}else if(c>='1'&&c<='9'){font=get_font("u"+c)}else{i++ continue}} el.innerHTML=str.slice(i0,i>=0?i:undefined) w+=el.clientWidth if(el.clientHeight>h) h=el.clientHeight if(i<0) break el.style.font=style_font(font).slice(5);i+=2;i0=i} return[w,h]}}else{strwh=function(str){var font=gene.curfont,swfac=font.swfac,h=font.size,w=0,i,j,c,n=str.length for(i=0;i='1'&&c<='9'){font=get_font("u"+c)}else{c='$' break} i++;swfac=font.swfac if(font.size>h) h=font.size continue case'&':if(str[i+1]==' ') break j=str.indexOf(';',i) if(j>0&&j-i<10){i=j;c='a'} break} w+=cwid(c)*swfac} return[w,h]}}})() function str2svg(str){if(typeof str=="object") return str var n_font,wh,o_font=gene.deffont,c_font=gene.curfont,o="" function tspan(nf,of){var cl if(nf.class&&nf.name==of.name&&nf.size==of.size&&nf.weight==of.weight&&nf.style==of.style) cl=nf.class else cl=font_class(nf) return''} if(c_font!=o_font) o=tspan(c_font,o_font) o+=str.replace(/<|>|&[^&\s]*?;|&|\$./g,function(c){switch(c){case'<':return"<" case'>':return">" case'&':return"&" default:if(c[0]!='$') break if(c[1]=='0') n_font=gene.deffont else if(c[1]>='1'&&c[1]<='9') n_font=get_font("u"+c[1]) else break c='' if(n_font==c_font) return c if(c_font!=o_font) c="" c_font=n_font if(c_font==o_font) return c return c+tspan(c_font,o_font)} return c}) if(c_font!=o_font) o+="" o=new String(o) if(typeof document!="undefined") strwh(o) else o.wh=strwh(str) gene.curfont=c_font return o} function set_font(xxx){if(typeof xxx=="string") xxx=get_font(xxx) cw_tb=xxx.name.slice(0,4)=='sans'?ssw_tb:sw_tb gene.curfont=gene.deffont=xxx} function out_str(str){output+=str2svg(str)} function xy_str(x,y,str,action,w,wh){if(!wh) wh=str.wh||strwh(str) output+='' break case'j':output+='" textLength="'+w.toFixed(1)+'">' break case'r':output+='" text-anchor="end">' break default:output+='">' break} out_str(str);output+="\n"} function trim_title(title,is_subtitle){var i if(cfmt.titletrim){i=title.lastIndexOf(", ") if(i<0||title[i+2]<'A'||title[i+2]>'Z'){i=0}else if(cfmt.titletrim==1){if(i=0) i=0}else{if(i=0) title=info.X+'. '+title if(cfmt.titlecaps) return title.toUpperCase() return title} function get_lwidth(){if(img.chg) set_page() return img.lw} function write_title(title,is_subtitle){var h,wh if(!title) return set_page();title=trim_title(title,is_subtitle) if(is_subtitle){set_font("subtitle");h=cfmt.subtitlespace}else{set_font("title");h=cfmt.titlespace} wh=strwh(title) wh[1]+=gene.curfont.pad*2 vskip(wh[1]+h+gene.curfont.pad) h=gene.curfont.pad+wh[1]*.22 if(cfmt.titleleft) xy_str(0,h,title,null,null,wh) else xy_str(get_lwidth()/2,h,title,"c",null,wh)} function put_inf2r(x,y,str1,str2,action){if(!str1){if(!str2) return str1=str2;str2=null} if(!str2) xy_str(x,y,str1,action) else xy_str(x,y,str1+' ('+str2+')',action)} function write_text(text,action){if(action=='s') return set_page();var wh,font,o,strlw=get_lwidth(),sz=gene.curfont.size,lineskip=sz*cfmt.lineskipfac,parskip=sz*cfmt.parskipfac,i,j,x,words,w,k,ww,str;switch(action){default:font=gene.curfont switch(action){case'c':x=strlw/2;break case'r':x=strlw-font.pad;break default:x=font.pad;break} j=0 while(1){i=text.indexOf('\n',j) if(i==j){vskip(parskip);blk_flush() use_font(gene.curfont) while(text[i+1]=='\n'){vskip(lineskip);i++} if(i==text.length) break}else{if(i<0) str=text.slice(j) else str=text.slice(j,i) ww=strwh(str) vskip(ww[1]*cfmt.lineskipfac +font.pad*2) xy_str(x,font.pad+ww[1]*.2,str,action) if(i<0) break} j=i+1} vskip(parskip);blk_flush() break case'f':case'j':j=0 while(1){i=text.indexOf('\n\n',j) if(i<0) words=text.slice(j) else words=text.slice(j,i);words=words.split(/\s+/);w=k=wh=0 for(j=0;j=strlw){vskip(wh*cfmt.lineskipfac) xy_str(0,ww[1]*.2,words.slice(k,j).join(' '),action,strlw) k=j;w=ww[0] wh=0} if(ww[1]>wh) wh=ww[1]} if(w!=0){vskip(wh*cfmt.lineskipfac) xy_str(0,ww[1]*.2,words.slice(k).join(' '))} vskip(parskip);blk_flush() if(i<0) break while(text[i+2]=='\n'){vskip(lineskip);i++} if(i==text.length) break use_font(gene.curfont);j=i+2} break}} function put_words(words){var p,i,j,nw,w,lw,x1,x2,i1,i2,do_flush,maxn=0,n=1 function put_wline(p,x){var i=0,k=0 if(p[0]=='$'&&p[1]>='0'&&p[1]<='9'){gene.curfont=p[1]=='0'?gene.deffont:get_font("u"+p[1]) p=p.slice(2)} if((p[i]>='0'&&p[i]<='9')||p[i+1]=='.'){while(imaxn){maxn=p.length i1=i}} w=get_lwidth()/2 lw=strwh(words[i1])[0] i1=i2=0 if(lw>1 for(i=0;i>=1} if(i2){x1=(w-lw)/2+10 x2=x1+w}else{x2=w-lw/2+10} do_flush=true for(i=0;i'Z'){switch(c){case'+':align='+' c=p[i++] break case',':fmt+='\n' default:continue case'<':align='l' c=p[i++] break case'>':align='r' c=p[i++] break}}else{switch(p[i]){case'-':align='l' i++ break case'1':align='r' i++ break case'0':i++ default:align='c' break}} if(!info_val[c]){if(!info[c]) continue info_val[c]=info[c].split('\n');info_nb[c]=1}else{info_nb[c]++} fmt+=align+c} fmt+='\n' var ya={l:cfmt.titlespace,c:cfmt.titlespace,r:cfmt.titlespace},xa={l:0,c:lwidth*.5,r:lwidth},yb={},str;p=fmt;i=0 while(1){yb.l=yb.c=yb.r=y=0;j=i while(1){align=p[j++] if(align=='\n') break c=p[j++] if(align=='+'||yb[align]) continue str=info_val[c] if(!str) continue font_name=info_font[c] if(!font_name) font_name="history";font=get_font(font_name);sz=font.size*1.1 if(info_sz[c]) sz+=info_sz[c] if(y0){y+=sz;str=info_val[c].shift();xy_str(x,-y,str,align)}} info_nb[c]--;ya[align]=y} if(ya.c>ya.l) ya.l=ya.c if(ya.r>ya.l) ya.l=ya.r if(i>=p.length) break ya.c=ya.r=ya.l} vskip(ya.l)} function write_heading(){var i,j,area,composer,origin,rhythm,down1,down2,lwidth=get_lwidth() vskip(cfmt.topspace) if(cfmt.titleformat){write_headform(lwidth);vskip(cfmt.musicspace) return} if(info.T&&cfmt.writefields.indexOf('T')>=0){i=0 while(1){j=info.T.indexOf("\n",i) if(j<0){write_title(info.T.substring(i),i!=0) break} write_title(info.T.slice(i,j),i!=0);i=j+1}} down1=down2=0 if(parse.ckey.k_bagpipe&&!cfmt.infoline&&cfmt.writefields.indexOf('R')>=0) rhythm=info.R if(rhythm){set_font("composer");down1=cfmt.composerspace+gene.curfont.size+2 xy_str(0,-down1+gene.curfont.size*.22,rhythm)} area=info.A if(cfmt.writefields.indexOf('C')>=0) composer=info.C if(cfmt.writefields.indexOf('O')>=0) origin=info.O if(composer||origin||cfmt.infoline){var xcomp,align;set_font("composer");if(cfmt.aligncomposer<0){xcomp=0;align=' '}else if(cfmt.aligncomposer==0){xcomp=lwidth*.5;align='c'}else{xcomp=lwidth;align='r'} if(composer||origin){down2=cfmt.composerspace+2 i=0 while(1){down2+=gene.curfont.size if(composer) j=composer.indexOf("\n",i) else j=-1 if(j<0){put_inf2r(xcomp,-down2+gene.curfont.size*.22,composer?composer.substring(i):null,origin,align) break} xy_str(xcomp,-down2+gene.curfont.size*.22,composer.slice(i,j),align);i=j+1}} rhythm=rhythm?null:info.R if((rhythm||area)&&cfmt.infoline){set_font("info");down2+=cfmt.infospace+gene.curfont.size put_inf2r(lwidth,-down2+gene.curfont.size*.22,rhythm,area,'r')}} if(info.P&&cfmt.writefields.indexOf('P')>=0){set_font("parts");i=cfmt.partsspace+gene.curfont.size+gene.curfont.pad if(down1+i>down2) down2=down1+i else down2+=i xy_str(0,-down2+gene.curfont.size*.22,info.P) down2+=gene.curfont.pad}else if(down1>down2){down2=down1} vskip(down2+cfmt.musicspace)} var output="",style='\ \n.stroke{stroke:currentColor;fill:none}\ \n.bW{stroke:currentColor;fill:none;stroke-width:1}\ \n.bthW{stroke:currentColor;fill:none;stroke-width:3}\ \n.slW{stroke:currentColor;fill:none;stroke-width:.7}\ \n.slthW{stroke:currentColor;fill:none;stroke-width:1.5}\ \n.sW{stroke:currentColor;fill:none;stroke-width:.7}\ \n.box{outline:1px solid black;outline-offset:1px}',font_style='',posx=cfmt.leftmargin/cfmt.scale,posy=0,img={width:cfmt.pagewidth,lm:cfmt.leftmargin,rm:cfmt.rightmargin,chg:1},defined_glyph={},defs='',fulldefs='',stv_g={scale:1,dy:0,st:-1,v:-1,g:0},blkdiv=0 var tgls={"mtr ":{x:0,y:0,c:"\u0020"},brace:{x:0,y:0,c:"\ue000"},lphr:{x:0,y:23,c:"\ue030"},mphr:{x:0,y:23,c:"\ue038"},sphr:{x:0,y:26,c:"\ue039"},short:{x:0,y:32,c:"\ue038"},tick:{x:0,y:29,c:"\ue039"},rdots:{x:-1,y:0,c:"\ue043"},dsgn:{x:-12,y:0,c:"\ue045"},dcap:{x:-12,y:0,c:"\ue046"},sgno:{x:-5,y:0,c:"\ue047"},coda:{x:-10,y:0,c:"\ue048"},tclef:{x:-8,y:0,c:"\ue050"},cclef:{x:-8,y:0,c:"\ue05c"},bclef:{x:-8,y:0,c:"\ue062"},pclef:{x:-6,y:0,c:"\ue069"},spclef:{x:-6,y:0,c:"\ue069"},stclef:{x:-8,y:0,c:"\ue07a"},scclef:{x:-8,y:0,c:"\ue07b"},sbclef:{x:-7,y:0,c:"\ue07c"},oct:{x:0,y:2,c:"\ue07d"},oct2:{x:0,y:2,c:"\ue07e"},mtr0:{x:0,y:0,c:"\ue080"},mtr1:{x:0,y:0,c:"\ue081"},mtr2:{x:0,y:0,c:"\ue082"},mtr3:{x:0,y:0,c:"\ue083"},mtr4:{x:0,y:0,c:"\ue084"},mtr5:{x:0,y:0,c:"\ue085"},mtr6:{x:0,y:0,c:"\ue086"},mtr7:{x:0,y:0,c:"\ue087"},mtr8:{x:0,y:0,c:"\ue088"},mtr9:{x:0,y:0,c:"\ue089"},mtrC:{x:0,y:0,c:"\ue08a"},"mtr+":{x:0,y:0,c:"\ue08c"},"mtr(":{x:0,y:0,c:"\ue094"},"mtr)":{x:0,y:0,c:"\ue095"},HDD:{x:-7,y:0,c:"\ue0a0"},breve:{x:-7,y:0,c:"\ue0a1"},HD:{x:-5.2,y:0,c:"\ue0a2"},Hd:{x:-3.8,y:0,c:"\ue0a3"},hd:{x:-3.7,y:0,c:"\ue0a4"},ghd:{x:2,y:0,c:"\ue0a4",sc:.66},pshhd:{x:-3.7,y:0,c:"\ue0a9"},pfthd:{x:-3.7,y:0,c:"\ue0b3"},x:{x:-3.7,y:0,c:"\ue0a9"},"circle-x":{x:-3.7,y:0,c:"\ue0b3"},srep:{x:-5,y:0,c:"\ue101"},"dot+":{x:-5,y:0,sc:.7,c:"\ue101"},diamond:{x:-4,y:0,c:"\ue1b9"},triangle:{x:-4,y:0,c:"\ue1bb"},dot:{x:-1,y:0,c:"\ue1e7"},flu1:{x:-.3,y:0,c:"\ue240"},fld1:{x:-.3,y:0,c:"\ue241"},flu2:{x:-.3,y:0,c:"\ue242"},fld2:{x:-.3,y:0,c:"\ue243"},flu3:{x:-.3,y:3.5,c:"\ue244"},fld3:{x:-.3,y:-4,c:"\ue245"},flu4:{x:-.3,y:8,c:"\ue246"},fld4:{x:-.3,y:-9,c:"\ue247"},flu5:{x:-.3,y:12.5,c:"\ue248"},fld5:{x:-.3,y:-14,c:"\ue249"},"acc-1":{x:-1,y:0,c:"\ue260"},"cacc-1":{x:-18,y:0,c:"\ue26a\ue260\ue26b"},"sacc-1":{x:-1,y:0,sc:.7,c:"\ue260"},acc3:{x:-1,y:0,c:"\ue261"},"cacc3":{x:-18,y:0,c:"\ue26a\ue261\ue26b"},sacc3:{x:-1,y:0,sc:.7,c:"\ue261"},acc1:{x:-2,y:0,c:"\ue262"},"cacc1":{x:-18,y:0,c:"\ue26a\ue262\ue26b"},sacc1:{x:-2,y:0,sc:.7,c:"\ue262"},acc2:{x:-3,y:0,c:"\ue263"},"acc-2":{x:-3,y:0,c:"\ue264"},"acc-1_2":{x:-2,y:0,c:"\ue280"},"acc-3_2":{x:-3,y:0,c:"\ue281"},acc1_2:{x:-1,y:0,c:"\ue282"},acc3_2:{x:-3,y:0,c:"\ue283"},accent:{x:-3,y:2,c:"\ue4a0"},stc:{x:0,y:-2,c:"\ue4a2"},emb:{x:0,y:-2,c:"\ue4a4"},wedge:{x:0,y:0,c:"\ue4a8"},marcato:{x:-3,y:-2,c:"\ue4ac"},hld:{x:-7,y:-2,c:"\ue4c0"},brth:{x:0,y:0,c:"\ue4ce"},caes:{x:0,y:8,c:"\ue4d1"},r00:{x:-1.5,y:0,c:"\ue4e1"},r0:{x:-1.5,y:0,c:"\ue4e2"},r1:{x:-3.5,y:-6,c:"\ue4e3"},r2:{x:-3.2,y:0,c:"\ue4e4"},r4:{x:-3,y:0,c:"\ue4e5"},r8:{x:-3,y:0,c:"\ue4e6"},r16:{x:-4,y:0,c:"\ue4e7"},r32:{x:-4,y:0,c:"\ue4e8"},r64:{x:-4,y:0,c:"\ue4e9"},r128:{x:-4,y:0,c:"\ue4ea"},mrep:{x:-6,y:0,c:"\ue500"},mrep2:{x:-9,y:0,c:"\ue501"},p:{x:-3,y:0,c:"\ue520"},f:{x:-3,y:0,c:"\ue522"},pppp:{x:-15,y:0,c:"\ue529"},ppp:{x:-14,y:0,c:"\ue52a"},pp:{x:-8,y:0,c:"\ue52b"},mp:{x:-8,y:0,c:"\ue52c"},mf:{x:-8,y:0,c:"\ue52d"},ff:{x:-7,y:0,c:"\ue52f"},fff:{x:-10,y:0,c:"\ue530"},ffff:{x:-14,y:0,c:"\ue531"},sfz:{x:-10,y:0,c:"\ue539"},trl:{x:-5,y:-2,c:"\ue566"},turn:{x:-5,y:0,c:"\ue567"},turnx:{x:-5,y:0,c:"\ue569"},umrd:{x:-6,y:2,c:"\ue56c"},lmrd:{x:-6,y:2,c:"\ue56d"},dplus:{x:-3,y:0,c:"\ue582"},sld:{x:-8,y:12,c:"\ue5d0"},grm:{x:-3,y:-2,c:"\ue5e2"},dnb:{x:-3,y:0,c:"\ue610"},upb:{x:-2,y:0,c:"\ue612"},opend:{x:-2,y:-2,c:"\ue614"},roll:{x:0,y:0,c:"\ue618"},thumb:{x:-2,y:-2,c:"\ue624"},snap:{x:-2,y:-2,c:"\ue630"},ped:{x:-10,y:0,c:"\ue650"},pedoff:{x:-5,y:0,c:"\ue655"},mtro:{x:0,y:0,c:"\ue911"},mtrc:{x:0,y:0,c:"\ue915"},"mtr.":{x:0,y:0,c:"\ue920"},"mtr|":{x:0,y:0,c:"\ue925"},longa:{x:-4.7,y:0,c:"\ue95d"},custos:{x:-4,y:3,c:"\uea02"},ltr:{x:2,y:6,c:"\ueaa4"}} var glyphs={} function m_gl(s){return s.replace(/[Cco]\||[co]\.|./g,function(e){var m=tgls["mtr"+e] return m?m.c:0})} function def_use(gl){var i,j,g if(defined_glyph[gl]) return defined_glyph[gl]=true;g=glyphs[gl] if(!g){error(1,null,"Unknown glyph: '$1'",gl) return} j=0 while(1){i=g.indexOf('xlink:href="#',j) if(i<0) break i+=13;j=g.indexOf('"',i);def_use(g.slice(i,j))} defs+='\n'+g} function defs_add(text){var i,j,gl,tag,is,ie=0 text=text.replace(//g,'') while(1){is=text.indexOf('<',ie);if(is<0) break i=text.indexOf('id="',is) if(i<0) break i+=4;j=text.indexOf('"',i);if(j<0) break gl=text.slice(i,j);ie=text.indexOf('>',j);if(ie<0) break if(text[ie-1]=='/'){ie++}else{i=text.indexOf(' ',is);if(i<0) break tag=text.slice(is+1,i);ie=text.indexOf('',ie) if(ie<0) break ie+=3+tag.length} if(text.substr(is,7)=='=0?staff_tb[st].staffscale:1 if(st>=0&&new_scale!=1) dy=staff_tb[st].y else dy=posy if(new_scale==stv_g.scale&&dy==stv_g.dy) return stv_g.scale=new_scale;stv_g.dy=dy;stv_g.st=st;stv_g.v=-1;set_g()} function set_scale(s){var new_dy,new_scale=s.p_v.scale if(new_scale==1){set_sscale(s.st) return} new_dy=posy if(staff_tb[s.st].staffscale!=1){new_scale*=staff_tb[s.st].staffscale;new_dy=staff_tb[s.st].y} if(new_scale==stv_g.scale&&stv_g.dy==posy) return stv_g.scale=new_scale;stv_g.dy=new_dy;stv_g.st=staff_tb[s.st].staffscale==1?-1:s.st;stv_g.v=s.v;set_g()} function set_dscale(st,no_scale){if(output){if(stv_g.started){stv_g.started=false glout() output+="\n"} if(stv_g.st<0){staff_tb[0].output+=output}else if(stv_g.scale==1){staff_tb[stv_g.st].output+=output}else{staff_tb[stv_g.st].sc_out+=output} output=""} if(st<0) stv_g.scale=1 else stv_g.scale=no_scale?1:staff_tb[st].staffscale;stv_g.st=st;stv_g.dy=0} function delayed_update(){var st,new_out,text for(st=0;st<=nstaff;st++){if(staff_tb[st].sc_out){output+='\n'+ staff_tb[st].sc_out+'\n';staff_tb[st].sc_out=""} if(!staff_tb[st].output) continue output+='\n'+ staff_tb[st].output+'\n';staff_tb[st].output=""}} function anno_out(s,t,f){if(s.istart==undefined) return var type=s.type,h=s.ymx-s.ymn+4,wl=s.wl||2,wr=s.wr||2 if(s.grace) type=C.GRACE f(t||abc2svg.sym_name[type],s.istart,s.iend,s.x-wl-2,staff_tb[s.st].y+s.ymn+h-2,wl+wr+4,h,s)} function a_start(s,t){anno_out(s,t,user.anno_start)} function a_stop(s,t){anno_out(s,t,user.anno_stop)} function empty_function(){} var anno_start=empty_function,anno_stop=empty_function function anno_put(){var s while(1){s=anno_a.shift() if(!s) break switch(s.type){case C.CLEF:case C.METER:case C.KEY:case C.REST:if(s.type!=C.REST||s.rep_nb){set_sscale(s.st) break} case C.GRACE:case C.NOTE:case C.MREST:set_scale(s) break} anno_stop(s)}} function out_XYAB(str,x,y,a,b){x=sx(x);y=sy(y);output+=str.replace(/X|Y|A|B|F|G/g,function(c){switch(c){case'X':return x.toFixed(1) case'Y':return y.toFixed(1) case'A':return a case'B':return b case'F':return a.toFixed(1) default:return b.toFixed(1)}})} function g_open(x,y,rot,sx,sy){glout() out_XYAB('\n';stv_g.g++} function g_close(){glout() stv_g.g--;output+='\n'} Abc.prototype.out_svg=function(str){output+=str} function sx(x){if(stv_g.g) return x return(x+posx)/stv_g.scale} Abc.prototype.sx=sx function sy(y){if(stv_g.g) return-y if(stv_g.scale==1) return posy-y if(stv_g.v>=0) return(stv_g.dy-y)/voice_tb[stv_g.v].scale return stv_g.dy-y} Abc.prototype.sy=sy;Abc.prototype.sh=function(h){if(stv_g.st<0) return h/stv_g.scale return h} Abc.prototype.ax=function(x){return x+posx} Abc.prototype.ay=function(y){if(stv_g.st<0) return posy-y return posy+(stv_g.dy-y)*stv_g.scale-stv_g.dy} Abc.prototype.ah=function(h){if(stv_g.st<0) return h return h*stv_g.scale} function out_sxsy(x,sep,y){x=sx(x);y=sy(y);output+=x.toFixed(1)+sep+y.toFixed(1)} Abc.prototype.out_sxsy=out_sxsy function xypath(x,y,fill){if(fill) out_XYAB('\n'}} for(st=0;st<=nstaff;st++){p_st=staff_tb[st] if(!p_st.hlu) continue set_sscale(st) hlud(p_st.hlu,6) hlud(p_st.hld,-6)}} var gla=[[],[],"",[],[],[]] function glout(){var e,v=[] if(gla[0].length){while(1){e=gla[0].shift() if(e==undefined) break v.push(e.toFixed(1))} output+=''+gla[2]+'\n' gla[2]=""} if(!gla[3].length) return output+='\n'} function xygl(x,y,gl){if(glyphs[gl]){def_use(gl) out_XYAB('\n',x,y,gl)}else{var tgl=tgls[gl] if(tgl){x+=tgl.x*stv_g.scale;y-=tgl.y if(tgl.sc){out_XYAB('B\n',x,y,tgl.sc,tgl.c)}else{gla[0].push(sx(x)) gla[1].push(sy(y)) gla[2]+=tgl.c}}else{error(1,null,'no definition of $1',gl)}}} function out_acciac(x,y,dx,dy,up){if(up){x-=1;y+=4}else{x-=5;y-=4} out_XYAB('\n',x,y,dx,-dy)} function out_brace(x,y,h){x+=posx-6;y=posy-y;h/=24;output+=''+tgls.brace.c+'\n'} function out_bracket(x,y,h){x+=posx-5;y=posy-y-3;h+=2;output+='\n'} function out_hyph(x,y,w){var n,a_y,d=25+((w/20)|0)*3 if(w>15.) n=((w-15)/d)|0 else n=0;x+=(w-d*n-5)/2;out_XYAB('\n',x,y+4,Math.round((d-5)/stv_g.scale),d*n+5)} function out_stem(x,y,h,grace,nflags,straight){var dx=grace?GSTEM_XOFF:3.5,slen=-h if(h<0) dx=-dx;x+=dx*stv_g.scale if(stv_g.v>=0) slen/=voice_tb[stv_g.v].scale;gla[3].push(sx(x)) gla[3].push(sy(y)) gla[3].push(slen) if(!nflags) return y+=h if(h>0){if(!straight){if(!grace){xygl(x,y,"flu"+nflags) return}else{output+='=0){out_XYAB('MX Yl7 3.2 0 3.2 -7 -3.2z\n',x,y);y-=5.4}}else{while(--nflags>=0){out_XYAB('MX Yl3 1.5 0 2 -3 -1.5z\n',x,y);y-=3}}}}else{if(!straight){if(!grace){xygl(x,y,"fld"+nflags) return}else{output+='=0){out_XYAB('MX Yl7 -3.2 0 -3.2 -7 3.2z\n',x,y);y+=5.4}}}} output+='"/>\n'} function out_trem(x,y,ntrem){out_XYAB('\n'} function out_tubr(x,y,dx,dy,up){var h=up?-3:3;y+=h;dx/=stv_g.scale;output+='\n'} function out_tubrn(x,y,dx,dy,up,str){var dxx,sw=str.length*10,h=up?-3:3;set_font("tuplet") xy_str(x+dx/2,y+dy/2-gene.curfont.size*.1,str,'c') dx/=stv_g.scale if(!up) y+=6;output+='\n'+'\n'} function out_wln(x,y,w){out_XYAB('\n',x,y+1,w)} var deco_str_style={crdc:{dx:0,dy:5,style:'font:italic 14px text,serif',anchor:' text-anchor="middle"'},dacs:{dx:0,dy:3,style:'font:16px text,serif',anchor:' text-anchor="middle"'},pf:{dx:0,dy:5,style:'font:italic bold 16px text,serif'},'@':{dx:0,dy:5,style:'font:12px text,sans-serif'}} function out_deco_str(x,y,name,str){if(name=='fng'){out_XYAB('\ A\n',x-2,y,m_gl(str)) return} var f,a_deco=deco_str_style[name] if(!a_deco){xygl(x,y,name) return} x+=a_deco.dx;y+=a_deco.dy;if(!a_deco.def){style+="\n."+name+" {"+a_deco.style+"}";a_deco.def=true} out_XYAB('',x,y,name,a_deco.anchor||"");set_font("annotation");out_str(str);output+='\n'} function out_arp(x,y,val){g_open(x,y,270);x=0;val=Math.ceil(val/6) while(--val>=0){xygl(x,6,"ltr");x+=6} g_close()} function out_cresc(x,y,val,defl){x+=val*stv_g.scale val=-val;out_XYAB('\n' else output+='-4l'+(-val).toFixed(1)+' -4"/>\n'} function out_dim(x,y,val,defl){out_XYAB('\n' else output+='-4l'+(-val).toFixed(1)+' -4"/>\n'} function out_ltr(x,y,val){y+=4;val=Math.ceil(val/6) while(--val>=0){xygl(x,y,"ltr");x+=6}} Abc.prototype.out_lped=function(x,y,val,defl){if(!defl.nost) xygl(x,y,"ped");if(!defl.noen) xygl(x+val+6,y,"pedoff")} function out_8va(x,y,val,defl){if(val<18){val=18 x-=4} if(!defl.nost){out_XYAB('8\ va\n',x-8,y);x+=12;val-=12} y+=6;out_XYAB('\n',x,y,val) if(!defl.noen) out_XYAB('\n',x+val,y)} function out_8vb(x,y,val,defl){if(val<18){val=18 x-=4} if(!defl.nost){out_XYAB('8\ vb\n',x-8,y);x+=10 val-=10} out_XYAB('\n',x,y,val) if(!defl.noen) out_XYAB('\n',x+val,y)} function out_15ma(x,y,val,defl){if(val<25){val=25 x-=6} if(!defl.nost){out_XYAB('15\ ma\n',x-10,y);x+=20;val-=20} y+=6;out_XYAB('\n',x,y,val) if(!defl.noen) out_XYAB('\n',x+val,y)} function out_15mb(x,y,val,defl){if(val<24){val=24 x-=5} if(!defl.nost){out_XYAB('15\ mb\n',x-10,y);x+=18 val-=18} out_XYAB('\n',x,y,val) if(!defl.noen) out_XYAB('\n',x+val,y)} var deco_val_tb={arp:out_arp,cresc:out_cresc,dim:out_dim,ltr:out_ltr,lped:function(x,y,val,defl){self.out_lped(x,y,val,defl)},"8va":out_8va,"8vb":out_8vb,"15ma":out_15ma,"15mb":out_15mb} function out_deco_val(x,y,name,val,defl){if(deco_val_tb[name]) deco_val_tb[name](x,y,val,defl) else error(1,null,"No function for decoration '$1'",name)} function out_glisq(x2,y2,de){var ar,a,len,de1=de.start,x1=de1.x,y1=de1.y+staff_tb[de1.st].y,dx=x2-x1,dy=self.sh(y1-y2) if(!stv_g.g) dx/=stv_g.scale ar=Math.atan2(dy,dx) a=ar/Math.PI*180 len=(dx-(de1.s.dots?13+de1.s.xmx:8) -8-(de.s.notes[0].shac||0)) / Math.cos(ar) g_open(x1,y1,a);x1=de1.s.dots?13+de1.s.xmx:8;len=len/6|0 if(len<1) len=1 while(--len>=0){xygl(x1,0,"ltr");x1+=6} g_close()} function out_gliss(x2,y2,de){var ar,a,len,de1=de.start,x1=de1.x,y1=de1.y+staff_tb[de1.st].y,dx=x2-x1,dy=self.sh(y1-y2) if(!stv_g.g) dx/=stv_g.scale ar=Math.atan2(dy,dx) a=ar/Math.PI*180 len=(dx-(de1.s.dots?13+de1.s.xmx:8) -8-(de.s.notes[0].shac||0)) / Math.cos(ar) g_open(x1,y1,a);xypath(de1.s.dots?13+de1.s.xmx:8,0) output+='h'+len.toFixed(1)+'" stroke-width="1"/>\n';g_close()} var deco_l_tb={glisq:out_glisq,gliss:out_gliss} function out_deco_long(x,y,de){var s,p_v,m,nt,i,name=de.dd.glyph,de1=de.start if(!deco_l_tb[name]){error(1,null,"No function for decoration '$1'",name) return} p_v=de.s.p_v if(de.defl.noen){s=p_v.s_next while(s&&!s.dur) s=s.next if(s){for(m=0;m<=s.nhd;m++){nt=s.notes[m] if(!nt.a_dd) continue for(i=0;i'+ p+'') j=p.length>1?2:1 w+=j*gene.curfont.swfac dy=''} str.push('=') w+=cwidf('=') if(s.tempo_ca){str.push(s.tempo_ca) w+=strwh(s.tempo_ca)[0] j=s.tempo_ca.length+1} if(s.tempo){str.push(s.tempo) w+=strwh(s.tempo.toString())[0]}else{p=tempo_note(s,s.new_beat) str.push(''+ p+'') j=p.length>1?2:1 w+=j*gene.curfont.swfac dy='y'}} if(s.tempo_str2){if(dy) str.push(''+ s.tempo_str2+'') else str.push(s.tempo_str2) w+=strwh(s.tempo_str2)[0]} s.tempo_str=str.join(' ') w+=cwidf(' ')*(str.length-1) s.tempo_wh=[w,13.0]} function writempo(s,x,y){var bh set_font("tempo") if(gene.curfont.box){gene.curfont.box=false bh=gene.curfont.size+4} output+=''+s.tempo_str+'\n' if(bh){gene.curfont.box=true output+='\n'} s.invis=true} function vskip(h){posy+=h} function svg_flush(){if(multicol||!output||!user.img_out||posy==0) return var i,font,head='\n' +fulldefs if(style||font_style){head+='\n'} if(defs) head+=''+defs+'\n\n' if(cfmt.scale!=1){head+='\n';g='\n'} if(psvg) psvg.ps_flush(true);if(blkdiv>0){user.img_out(blkdiv==1?'
':'
') blkdiv=-1} user.img_out(head+output+g+"");output="" font_style='' if(cfmt.fullsvg){defined_glyph={} for(i=0;i') blkdiv=0}} Abc.prototype.blk_flush=blk_flush var par_sy,cur_sy,voice_tb,curvoice,staves_found,vover,tsfirst function voice_filter(){var opt function vfilt(opts,opt){var i,sel=new RegExp(opt) if(sel.test(curvoice.id)||sel.test(curvoice.nm)){for(i=0;itime) continue w=w_tb[s.type] if(s.type==C.GRACE&&s.next&&s.next.type==C.GRACE) w-- if(s.time127) break if(wmin==6) b_chk() ir=0 while(1){v=vn[ir++] if(v==undefined) break s=vtb[v] if(!s||s.time!=time) continue w=w_tb[s.type] if(!w&&s.type==C.GRACE&&s.next&&s.next.type==C.GRACE) w-- if(w!=wmin) continue if(!w&&s.type==C.PART){if(s.prev) s.prev.next=s.next vtb[v]=s.next if(s.next){s.next.part=s s.next.prev=s.prev if(s.soln) s.next.soln=1} continue} if(s.type==C.STAVES) new_sy=s.sy if(fl){fl=0;s.seqst=true} s.ts_prev=prev prev.ts_next=s prev=s vtb[v]=s.next} if(wmin) fl=1}} function voice_adj(sys_chg){var p_voice,s,s2,v,sl function set_feathered_beam(s1){var s,s2,t,d,b,i,a,d=s1.dur,n=1 for(s=s1;s;s=s.next){if(s.beam_end||!s.next) break n++} if(n<=1){delete s1.feathered_beam return} s2=s;b=d/2;a=d/(n-1);t=s1.time if(s1.feathered_beam>0){for(s=s1,i=n-1;s!=s2;s=s.next,i--){d=((a*i)|0)+b;s.dur=d;s.time=t;t+=d}}else{for(s=s1,i=0;s!=s2;s=s.next,i++){d=((a*i)|0)+b;s.dur=d;s.time=t;t+=d}} s.dur=s.time+s.dur-t;s.time=t} if(curvoice&&curvoice.clone){parse.istart=parse.eol do_cloning()} if(par_sy.one_v) fill_mr_ba(voice_tb[par_sy.top_voice]) for(v=0;v=staves_found) break} for(;s;s=s.next){if(w_tb[s.type]<5&&s.type!=C.STAVES&&s.type!=C.CLEF&&s.time&&(!s.prev||s.time>s.prev.time+s.prev.dur)){s2={type:C.BAR,bar_type:"[]",v:s.v,p_v:s.p_v,st:s.st,time:s.time,dur:0,next:s,prev:s.prev,fmt:s.fmt,invis:1} if(s.prev) s.prev.next=s2 else voice_tb[s.v].sym=s2 s.prev=s2} switch(s.type){case C.GRACE:if(!cfmt.graceword) continue for(s2=s.next;s2;s2=s2.next){switch(s2.type){case C.SPACE:continue case C.NOTE:if(!s2.a_ly) break s.a_ly=s2.a_ly;s2.a_ly=null break} break} continue} if(s.feathered_beam) set_feathered_beam(s)}}} function new_syst(init){var st,v,sy_staff,p_voice,sy_new={voices:[],staves:[],top_voice:0} if(init){cur_sy=par_sy=sy_new return} for(v=0;vptim+wmeasure&&s.prev.type!=C.MREST) return 1 for(s3=s.next;s3&&s3.time==s.time;s3=s3.next);for(;s3&&!s3.bar_type;s3=s3.next);return s3&&(s3.time-bar_tim)%wmeasure} for(s=tsfirst;;s=s.ts_next){if(!s) return switch(s.type){case C.METER:wmeasure=s.wmeasure case C.CLEF:case C.KEY:case C.STBRK:continue case C.BAR:if(s.bar_num) bar_num=s.bar_num break} break} for(s2=s.ts_next;s2;s2=s2.ts_next){if(s2.type==C.BAR&&s2.time){if(s2.timetim||s2.dur) break if(!s2.bar_type) continue if(s2.bar_type!='[') nu=0 if(s2.text) txt=s2.text} if(s.bar_num){bar_num=s.bar_num ptim=bar_tim=tim continue} if(wmeasure==1){if(s.bar_dotted) continue if(txt){if(!cfmt.contbarnb){if(txt[0]=='1') rep_tim=bar_num else bar_num=rep_tim}} if(!nu) s.bar_num=++bar_num continue} n=bar_num+(tim-bar_tim)/wmeasure k=n-(n|0) if(cfmt.checkbars&&k&&check_meas()) error(0,s,"Bad measure duration") if(tim>ptim+wmeasure){n|=0 k=0 bar_tim=tim bar_num=n} if(txt){if(txt[0]=='1'){if(!cfmt.contbarnb) rep_tim=tim-bar_tim if(!nu) s.bar_num=n}else{if(!cfmt.contbarnb) bar_tim=tim-rep_tim n=bar_num+(tim-bar_tim)/wmeasure if(n==(n|0)) s.bar_num=n}}else{n|=0 s.bar_num=n} if(!k) ptim=tim break}}} function not2abc(pit,acc){var i,nn='' if(acc&&acc!=3){if(typeof acc!="object"){nn=['__','_','','^','^^'][acc+2]}else{i=acc[0] if(i>0){nn+='^'}else{nn+='_' i=-i} nn+=i+'/'+acc[1]}} nn+=ntb[(pit+75)%7] for(i=pit;i>=23;i-=7) nn+="'" for(i=pit;i<16;i+=7) nn+="," return nn} function get_map(text){if(!text) return var i,note,notes,map,tmp,ns,ty='',a=text.split(/\s+/) if(a.length<3){syntax(1,not_enough_p) return} ns=a[1] if(ns[0]=='*'||ns.indexOf("all")==0){ns='all'}else{if(ns.indexOf("octave,")==0||ns.indexOf("key,")==0){ty=ns[0] ns=ns.split(',')[1] ns=ns.replace(/[,']+/,'').toUpperCase() if(ns.indexOf("key,")==0) ns=ns.replace(/[=^_]+/,'')} tmp=new scanBuf tmp.buffer=ns note=parse_acc_pit(tmp) if(!note){syntax(1,"Bad note in %%map") return} ns=ty+not2abc(note.pit,note.acc)} notes=maps[a[0]] if(!notes) maps[a[0]]=notes={} map=notes[ns] if(!map) notes[ns]=map=[] a.shift() a.shift() if(!a.length) return a=info_split(a.join(' ')) i=0 if(a[0].indexOf('=')<0){if(a[0][0]!='*'){tmp=new scanBuf;tmp.buffer=a[0];map[1]=parse_acc_pit(tmp)} if(!a[1]) return i++ if(a[1].indexOf('=')<0){map[0]=a[1].split(',') i++}} for(;i=0){var val=parseInt(param) if(isNaN(val)||val<-36||val>36){syntax(1,errs.bad_transp) return} val+=36 val=((val/12|0)-3)*40+abc2svg.isb40[val%12] if(param.slice(-1)=='b') val+=4 return val}} Abc.prototype.do_pscom=function(text){var h1,val,s,cmd,param,n,k,b cmd=text.match(/[^\s]+/) if(!cmd) return cmd=cmd[0];if(curvoice&&curvoice.ignore){switch(cmd){case"staves":case"score":break default:return}} param=text.replace(cmd,'').trim() if(param.slice(-5)==' lock'){fmt_lock[cmd]=true;param=param.slice(0,-5).trim()}else if(fmt_lock[cmd]){return} switch(cmd){case"clef":if(parse.state>=2){s=new_clef(param) if(s) get_clef(s)} return case"deco":deco_add(param) return case"linebreak":set_linebreak(param) return case"map":get_map(param) return case"maxsysstaffsep":case"sysstaffsep":if(parse.state==3){val=get_unit(param) if(isNaN(val)){syntax(1,errs.bad_val,"%%"+cmd) return} par_sy.voices[curvoice.v][cmd[0]=='m'?"maxsep":"sep"]=val return} break case"multicol":switch(param){case"start":case"new":case"end":break default:syntax(1,"Unknown keyword '$1' in %%multicol",param) return} s={type:C.BLOCK,subtype:"mc_"+param,dur:0} if(parse.state>=2){curvoice=voice_tb[0] curvoice.eoln=1 sym_link(s) return} set_ref(s) self.block_gen(s) return case"ottava":if(parse.state!=3) return n=parseInt(param) if(isNaN(n)||n<-2||n>2||(!n&&!curvoice.ottava)){syntax(1,errs.bad_val,"%%ottava") return} k=n if(n){curvoice.ottava=n}else{n=curvoice.ottava curvoice.ottava=0} a_dcn.push(["15mb","8vb","","8va","15ma"][n+2] +(k?'(':')')) return case"repbra":if(curvoice) curvoice.norepbra=!get_bool(param) return case"repeat":if(parse.state!=3) return if(!curvoice.last_sym){syntax(1,"%%repeat cannot start a tune") return} if(!param.length){n=1;k=1}else{b=param.split(/\s+/);n=parseInt(b[0]);k=parseInt(b[1]) if(isNaN(n)||n<1||(curvoice.last_sym.type==C.BAR&&n>2)){syntax(1,"Incorrect 1st value in %%repeat") return} if(isNaN(k)){k=1}else{if(k<1){syntax(1,"Incorrect 2nd value in %%repeat") return}}} parse.repeat_n=curvoice.last_sym.type==C.BAR?n:-n;parse.repeat_k=k return case"sep":var h2,len,values,lwidth;set_page();lwidth=img.width-img.lm-img.rm;h1=h2=len=0 if(param){values=param.split(/\s+/);h1=get_unit(values[0]) if(values[1]){h2=get_unit(values[1]) if(values[2]) len=get_unit(values[2])} if(isNaN(h1)||isNaN(h2)||isNaN(len)){syntax(1,errs.bad_val,"%%sep") return}} if(h1<1) h1=14 if(h2<1) h2=h1 if(len<1) len=90 if(parse.state>=2){s=new_block(cmd);s.x=(lwidth-len)/2/cfmt.scale;s.l=len/cfmt.scale;s.sk1=h1;s.sk2=h2 return} vskip(h1);output+='\n';vskip(h2);blk_flush() return case"setbarnb":val=parseInt(param) if(isNaN(val)||val<1){syntax(1,"Bad %%setbarnb value") break} glovar.new_nbar=val return case"staff":if(parse.state!=3) return val=parseInt(param) if(isNaN(val)){syntax(1,"Bad %%staff value '$1'",param) return} var st if(param[0]=='+'||param[0]=='-') st=curvoice.cst+val else st=val-1 if(st<0||st>nstaff){syntax(1,"Bad %%staff number $1 (cur $2, max $3)",st,curvoice.cst,nstaff) return} delete curvoice.floating;curvoice.cst=st return case"staffbreak":if(parse.state!=3) return s={type:C.STBRK,dur:0} if(param.slice(-1)=='f'){s.stbrk_forced=true param=param.replace(/\sf$/,'')} if(param){val=get_unit(param) if(isNaN(val)){syntax(1,errs.bad_val,"%%staffbreak") return} s.xmx=val}else{s.xmx=14} sym_link(s) return case"tacet":if(param[0]=='"') param=param.slice(1,-1) case"stafflines":case"staffscale":case"staffnonote":set_v_param(cmd,param) return case"staves":case"score":if(!parse.state) return if(parse.scores&&parse.scores.length>0){text=parse.scores.shift();cmd=text.match(/([^\s]+)\s*(.*)/);param=cmd[2] cmd=cmd[1]} get_staves(cmd,param) return case"center":case"text":k=cmd[0]=='c'?'c':cfmt.textoption set_font("text") if(parse.state>=2){s=new_block("text") s.text=param s.opt=k s.font=cfmt.textfont return} write_text(param,k) return case"transpose":if(cfmt.sound) return val=get_transp(param) if(val==undefined){val=get_interval(param) if(val==undefined) return} switch(parse.state){case 0:cfmt.transp=0 case 1:cfmt.transp=(cfmt.transp||0)+val return} cfmt.transp=(cfmt.transp||0)+val key_trans() return case"tune":return case"user":set_user(param) return case"voicecolor":if(curvoice) curvoice.color=param return case"vskip":val=get_unit(param) if(isNaN(val)){syntax(1,errs.bad_val,"%%vskip") return} if(val<0){syntax(1,"%%vskip cannot be negative") return} if(parse.state>=2){s=new_block(cmd);s.sk=val return} vskip(val);return case"newpage":case"leftmargin":case"rightmargin":case"pagescale":case"pagewidth":case"printmargin":case"scale":case"staffwidth":if(parse.state>=2){s=new_block(cmd);s.param=param return} if(cmd=="newpage"){blk_flush() if(user.page_format) blkdiv=2 return} break} self.set_format(cmd,param)} Abc.prototype.do_begin_end=function(type,opt,text){var i,j,action,s switch(type){case"js":js_inject(text) break case"ml":if(cfmt.pageheight){syntax(1,"Cannot have %%beginml with %%pageheight") break} if(parse.state>=2){s=new_block(type);s.text=text}else{blk_flush() if(user.img_out) user.img_out(text)} break case"svg":j=0 while(1){i=text.indexOf('',i) j=text.indexOf('',i) if(j<0){syntax(1,"No in %%beginsvg sequence") break} style+=text.slice(i+1,j).replace(/\s+$/,'')} j=0 while(1){i=text.indexOf('\n',j) if(i<0) break j=text.indexOf('',i) if(j<0){syntax(1,"No in %%beginsvg sequence") break} defs_add(text.slice(i+6,j))} break case"text":action=get_textopt(opt);if(!action) action=cfmt.textoption set_font("text") if(text.indexOf('\\')>=0) text=cnv_escape(text) if(parse.state>1){s=new_block(type);s.text=text s.opt=action s.font=cfmt.textfont break} write_text(text,action) break}} function generate(){var s,v,p_voice;if(a_dcn.length){syntax(1,"Decoration without symbol") a_dcn=[]} if(parse.tp){syntax(1,"No end of tuplet") s=parse.tps if(s) delete s.tp delete parse.tp} if(vover){syntax(1,"No end of voice overlay");get_vover(vover.bar?'|':')')} voice_adj();sort_all() if(tsfirst){for(v=0;vmxt){p_v2=voice_tb[v] mxt=p_v2.time}} if(p_v.time>=mxt) return var p_v_sav=curvoice,dur=mxt-p_v.time,s={type:C.MREST,stem:0,multi:0,nhd:0,xmx:0,frm:1,dur:dur,dur_orig:dur,nmes:dur/p_v.wmeasure,notes:[{pit:18,dur:dur}],tacet:p_v.tacet},s2={type:C.BAR,bar_type:'|',dur:0,multi:0} if(p_v2.last_sym.bar_type) s2.bar_type=p_v2.last_sym.bar_type glovar.mrest_p=1 curvoice=p_v sym_link(s) sym_link(s2) curvoice=p_v_sav} function get_staves(cmd,parm){var s,p_voice,p_voice2,i,flags,v,vid,a_vf,st,range,nv=voice_tb.length,maxtime=0 if(parm){a_vf=parse_staves(parm) if(!a_vf) return}else if(staves_found<0){syntax(1,errs.bad_val,'%%'+cmd) return} for(v=0;vmaxtime) maxtime=p_voice.time} if(!maxtime){par_sy.staves=[] par_sy.voices=[]}else{voice_adj(true) for(v=0;v0&&p_voice.norepbra==undefined&&!(par_sy.staves[st-1].flags&STOP_BAR)) p_voice.norepbra=true} curvoice=parse.state>=2?voice_tb[par_sy.top_voice]:null} function clone_voice(id){var v,p_voice for(v=0;vvover.p_voice.time) vover.p_voice.time=curvoice.time} curvoice.acc=[] p_voice2=vover.p_voice s=curvoice.last_sym if(s.type==C.SPACE&&p_voice2.last_sym.type!=C.SPACE){s.p_v=p_voice2 s.v=s.p_v.v while(s.prev.type==C.SPACE){s=s.prev s.p_v=p_voice2 s.v=s.p_v.v} s2=s.prev s2.next=null s.prev=p_voice2.last_sym s.prev.next=s p_voice2.last_sym=curvoice.last_sym curvoice.last_sym=s2} curvoice=p_voice2 vover=null return} if(type=='('){if(vover){syntax(1,"Voice overlay already started") return} vover={p_voice:curvoice,time:curvoice.time} return} if(!curvoice.last_note){syntax(1,errs.nonote_vo) return} curvoice.last_note.beam_end=true;p_voice2=curvoice.voice_down if(!p_voice2){p_voice2=clone_voice(curvoice.id+'o');curvoice.voice_down=p_voice2;p_voice2.time=0;p_voice2.second=true;p_voice2.last_note=null v2=p_voice2.v;if(par_sy.voices[curvoice.v]){par_sy.voices[v2]={st:curvoice.st,second:true} range=par_sy.voices[curvoice.v].range for(v=0;vrange) par_sy.voices[v].range++} par_sy.voices[v2].range=range+1}} p_voice2.ulen=curvoice.ulen p_voice2.dur_fact=curvoice.dur_fact p_voice2.acc=[] if(!vover){time=p_voice2.time if(curvoice.ignore) s=null else for(s=curvoice.last_sym;;s=s.prev){if(s.type==C.BAR||s.time<=time) break} vover={bar:(s&&s.bar_type)?s.bar_type:'|',p_voice:curvoice,time:s?s.time:curvoice.time}}else{if(curvoice!=vover.p_voice&&curvoice.time!=vover.p_voice.time){syntax(1,"Wrong duration in voice overlay") if(curvoice.time>vover.p_voice.time) vover.p_voice.time=curvoice.time}} p_voice2.time=vover.time;curvoice=p_voice2} function is_voice_sig(){var s if(curvoice.time) return false if(!curvoice.last_sym) return true for(s=curvoice.last_sym;s;s=s.prev) if(w_tb[s.type]) return false return true} function get_clef(s){var s2,s3 if(s.clef_type=='p'){s2=curvoice.ckey s2.k_drum=1 s2.k_sf=0 s2.k_b40=2 s2.k_map=abc2svg.keys[7] if(!curvoice.key) curvoice.key=s2} if(!curvoice.time&&is_voice_sig()){curvoice.clef=s s.fmt=cfmt return} for(s2=curvoice.last_sym;s2&&s2.time==curvoice.time;s2=s2.prev){if(w_tb[s2.type]) break} if(s2&&s2.time==curvoice.time&&s2.k_sf!=undefined){s3=s2 s2=s2.prev} if(s2&&s2.time==curvoice.time&&s2.bar_type&&s2.bar_type[0]!=':') s3=s2 if(s3){s2=curvoice.last_sym curvoice.last_sym=s3.prev sym_link(s) s.next=s3 s3.prev=s curvoice.last_sym=s2 if(s.soln){delete s.soln curvoice.eoln=true}}else{sym_link(s)} if(s.prev) s.clef_small=1} function get_key(parm){var v,p_voice,transp,sndtran,nt,a=new_key(parm),s_key=a[0],s=s_key,empty=s.k_sf==undefined&&!s.k_a_acc a=a[1] if(empty) s.invis=1 if(parse.state==1){parse.ckey=s if(empty){s_key.k_sf=0;s_key.k_none=true s_key.k_map=abc2svg.keys[7]} for(v=0;v0) vs=vid.split(',') else vs=[vid] if(parse.state<2){while(1){vid=vs.shift() if(!vid) break if(a.length) memo_kv_parm(vid,a) if(vid!='*'&&parse.state==1) curvoice=new_voice(vid)} return} if(vid=='*'){syntax(1,"Cannot have V:* in tune body") return} curvoice=new_voice(vs[0]) if(vs.length>1){vs.shift() curvoice.clone={vs:vs,a:a,bol:parse.iend} if(parse.file[curvoice.clone.bol-1]!=']') curvoice.clone.bol++} set_kv_parm(a) key_trans() v=curvoice.v if(curvoice.new){delete curvoice.new if(staves_found<0){curvoice.st=curvoice.cst=++nstaff;par_sy.nstaff=nstaff;par_sy.voices[v]={st:nstaff,range:v} par_sy.staves[nstaff]={stafflines:curvoice.stafflines||"|||||",staffscale:1}}else if(!par_sy.voices[v]){curvoice.ignore=1 return}} if(!curvoice.filtered&&par_sy.voices[v]&&(parse.voice_opts||parse.tune_v_opts)){curvoice.filtered=true;voice_filter()}} function goto_tune(){var v,p_voice set_page();write_heading();if(glovar.new_nbar){gene.nbar=glovar.new_nbar glovar.new_nbar=0}else{gene.nbar=1} parse.state=3 for(v=0;v=0){p_voice=voice_tb[v];delete p_voice.new;p_voice.st=p_voice.cst=v;par_sy.voices[v]={st:v,range:v} par_sy.staves[v]={stafflines:p_voice.stafflines||"|||||",staffscale:1}}}} function get_sym(p,cont){var s,c,i,j,d if(curvoice.ignore) return if(cont){s=curvoice.sym_cont if(!s){syntax(1,"+: symbol line without music") return}}else{if(curvoice.sym_restart){curvoice.sym_start=curvoice.sym_restart;curvoice.sym_restart=null} s=curvoice.sym_start if(!s) s=curvoice.sym if(!s){syntax(1,"s: without music") return}} i=0 while(1){while(p[i]==' '||p[i]=='\t') i++;c=p[i] if(!c) break switch(c){case'|':while(s&&s.type!=C.BAR) s=s.next if(!s){syntax(1,"Not enough measure bars for symbol line") return} s=s.next;i++ continue case'!':case'"':j=++i i=p.indexOf(c,j) if(i<0){syntax(1,c=='!'?"No end of decoration":"No end of chord symbol/annotation");i=p.length continue} d=p.slice(j-1,i+1) break case'*':break default:d=c.charCodeAt(0) if(d<128){d=char_tb[d] if(d.length>1&&(d[0]=='!'||d[0]=='"')){c=d[0] break}} syntax(1,errs.bad_char,c) break} while(s&&s.type!=C.NOTE) s=s.next if(!s){syntax(1,"Too many elements in symbol line") return} switch(c){default:break case'!':a_dcn.push(d.slice(1,-1)) deco_cnv(s,s.prev) break case'"':parse_gchord(d) if(a_gch) csan_add(s) break} s=s.next;i++} curvoice.sym_cont=s} function get_lyrics(text,cont){var s,word,p,i,j,ly,dfnt,ln,c,cf if(curvoice.ignore) return if((curvoice.pos.voc&0x07)!=C.SL_HIDDEN) curvoice.have_ly=true if(cont){s=curvoice.lyric_cont if(!s){syntax(1,"+: lyric without music") return} dfnt=get_font("vocal") if(gene.deffont!=dfnt){if(gene.curfont==gene.deffont) gene.curfont=dfnt gene.deffont=dfnt}}else{set_font("vocal") if(curvoice.lyric_restart){curvoice.lyric_start=s=curvoice.lyric_restart;curvoice.lyric_restart=null;curvoice.lyric_line=0}else{curvoice.lyric_line++;s=curvoice.lyric_start} if(!s) s=curvoice.sym if(!s){syntax(1,"w: without music") return}} p=text;i=0 cf=gene.curfont while(1){while(p[i]==' '||p[i]=='\t') i++ if(!p[i]) break ln=0 j=parse.istart+i+2 switch(p[i]){case'|':while(s&&s.type!=C.BAR) s=s.next if(!s){syntax(1,"Not enough measure bars for lyric line") return} s=s.next;i++ continue case'-':case'_':word=p[i] ln=p[i]=='-'?2:3 break case'*':word="" break default:word="";while(1){if(!p[i]) break switch(p[i]){case'_':case'*':case'|':i-- case' ':case'\t':break case'~':word+=' ' i++ continue case'-':ln=1 break case'\\':if(!p[++i]) continue word+=p[i++] continue case'$':word+=p[i++] c=p[i] if(c=='0') gene.curfont=gene.deffont else if(c>='1'&&c<='9') gene.curfont=get_font("u"+c) default:word+=p[i++] continue} break} break} while(s&&s.type!=C.NOTE) s=s.next if(!s){syntax(1,"Too many words in lyric line") return} if(word&&(s.pos.voc&0x07)!=C.SL_HIDDEN){ly={t:word,font:cf,istart:j,iend:j+word.length} if(ln) ly.ln=ln if(!s.a_ly) s.a_ly=[] s.a_ly[curvoice.lyric_line]=ly cf=gene.curfont} s=s.next;i++} curvoice.lyric_cont=s} function ly_set(s){var i,j,ly,d,s1,s2,p,w,spw,xx,sz,shift,dw,s3=s,wx=0,wl=0,n=0,dx=0,a_ly=s.a_ly,align=0 for(s2=s.ts_next;s2;s2=s2.ts_next){if(s2.shrink){dx+=s2.shrink n++} if(s2.bar_type){dx+=3 break} if(!s2.a_ly) continue i=s2.a_ly.length while(--i>=0){ly=s2.a_ly[i] if(!ly) continue if(!ly.ln||ly.ln<2) break} if(i>=0) break} for(i=0;i=2){ly.shift=0 continue} spw=cwid(' ')*ly.font.swfac w=p.wh[0]+spw*1.5 if(s.type==C.GRACE){shift=s.wl}else if((p[0]>='0'&&p[0]<='9'&&p.length>2)||p[1]==':'||p[0]=='('||p[0]==')'){if(p[0]=='('){sz=spw}else{j=p.indexOf(' ') set_font(ly.font) if(j>0) sz=strwh(p.slice(0,j))[0] else sz=w*.2} shift=(w-sz)*.4 if(shift>14) shift=14 shift+=sz if(p[0]>='0'&&p[0]<='9'){if(shift>align) align=shift}}else{shift=w*.4 if(shift>14) shift=14} ly.shift=shift if(shift>wl) wl=shift w-=shift if(w>wx) wx=w} while(!s3.seqst) s3=s3.ts_prev if(s3.ts_prev&&s3.ts_prev.bar_type) wl-=4 if(s3.wl0){for(i=0;i='0'&&ly.t[0]<='9') ly.shift=align}}} function draw_lyric_line(p_voice,j,y){var p,lastx,w,s,s2,ly,lyl,ln,hyflag,lflag,x0,shift if(p_voice.hy_st&(1<=2){if(x0==0&&lastx>s.x-18) lastx=s.x-18 if(ln==2) hyflag=true else lflag=true;x0=s.x-shift continue} x0=s.x-shift;if(ln) hyflag=true if(user.anno_start||user.anno_stop){s2={p_v:s.p_v,st:s.st,istart:ly.istart,iend:ly.iend,ts_prev:s,ts_next:s.ts_next,x:x0,y:y,ymn:y,ymx:y+gene.curfont.size,wl:0,wr:w} anno_start(s2,'lyrics')} xy_str(x0,y,p) anno_stop(s2,'lyrics') lastx=x0+w} if(hyflag){hyflag=false;x0=realwidth-10 if(x00){if(y>-tsfirst.fmt.vocalspace) y=-tsfirst.fmt.vocalspace;y*=sc for(j=0;j=0;){draw_lyric_line(p_voice,j,y+a_h[j]*.22) y+=a_h[j]*1.1} return y/sc} function draw_all_lyrics(){var p_voice,s,v,nly,i,x,y,w,a_ly,ly,lyst_tb=new Array(nstaff+1),nv=voice_tb.length,h_tb=new Array(nv),nly_tb=new Array(nv),above_tb=new Array(nv),rv_tb=new Array(nv),top=0,bot=0,st=-1 for(v=0;vy) bot=y while(nlyh_tb[v][i]) h_tb[v][i]=ly.t.wh[1]}}}else{y=y_get(p_voice.st,1,0,realwidth) if(topy) bot=y} if(!lyst_tb[st]) lyst_tb[st]={} lyst_tb[st].top=top;lyst_tb[st].bot=bot;nly_tb[v]=nly if(nly==0) continue if(p_voice.pos.voc) above_tb[v]=(p_voice.pos.voc&0x07)==C.SL_ABOVE else if(voice_tb[v+1]&&voice_tb[v+1].st==st&&voice_tb[v+1].have_ly) above_tb[v]=true else above_tb[v]=false if(above_tb[v]) lyst_tb[st].a=true else lyst_tb[st].b=true} i=0 for(v=0;v0) lyst_tb[st].bot=draw_lyrics(p_voice,nly_tb[v],h_tb[v],lyst_tb[st].bot,1)} while(--i>=0){v=rv_tb[i];p_voice=voice_tb[v];st=p_voice.st;set_dscale(st,true);lyst_tb[st].top=draw_lyrics(p_voice,nly_tb[v],h_tb[v],lyst_tb[st].top,-1)} for(v=0;v0){for(s=p_voice.sym;s;s=s.next){if(s.a_ly){y_set(st,0,s.x-2,10,bot)}}}else{y_set(st,0,0,realwidth,bot)}}}} function parse_gchord(type){var c,text,gch,x_abs,y_abs,i,j,istart,iend,ann_font=get_font("annotation"),h_ann=ann_font.size,line=parse.line function get_float(){var txt='' while(1){c=text[i++] if("1234567890.-".indexOf(c)<0) return parseFloat(txt) txt+=c}} istart=parse.bol+line.index if(type.length>1){text=type.slice(1,-1);iend=istart+1}else{i=++line.index while(1){j=line.buffer.indexOf('"',i) if(j<0){syntax(1,"No end of chord symbol/annotation") return} if(line.buffer[j-1]!='\\'||line.buffer[j-2]=='\\') break i=j+1} text=cnv_escape(line.buffer.slice(line.index,j)) line.index=j iend=parse.bol+line.index+1} if(ann_font.pad) h_ann+=ann_font.pad i=0;type='g' while(1){c=text[i] if(!c) break gch={text:"",istart:istart,iend:iend,font:ann_font} switch(c){case'@':type=c;i++;x_abs=get_float() if(c!=','){syntax(1,"',' lacking in annotation '@x,y'");y_abs=0}else{y_abs=get_float() if(c!=' ') i--} gch.x=x_abs;gch.y=y_abs break case'^':gch.pos=C.SL_ABOVE case'_':if(c=='_') gch.pos=C.SL_BELOW case'<':case'>':i++;type=c break default:switch(type){case'g':gch.font=get_font("gchord") gch.pos=curvoice.pos.gch||C.SL_ABOVE break case'^':gch.pos=C.SL_ABOVE break case'_':gch.pos=C.SL_BELOW break case'@':gch.x=x_abs;y_abs-=h_ann;gch.y=y_abs break} break} gch.type=type while(1){c=text[i] if(!c) break switch(c){case'\\':c=text[++i] if(c=='n') break gch.text+='\\' if(!c) break default:gch.text+=c;i++ continue case'&':while(1){gch.text+=c;c=text[++i] switch(c){default:continue case';':case undefined:case'\\':break} break} if(c==';'){i++;gch.text+=c continue} break case';':break} i++ break} gch.otext=gch.text if(!a_gch) a_gch=[] a_gch.push(gch)}} var note_names="CDEFGAB",acc_name=["bb","b","","#","##"] function gch_tr1(p,tr){var i,o,n,a,ip,b40,csa=p.split('/') for(i=0;i8) xspc=8;gch.x=-xspc;break case'<':gch.x=-(wh[0]+6);y_left-=wh[1];gch.y=y_left+wh[1]/2 break case'>':gch.x=6;y_right-=wh[1];gch.y=y_right+wh[1]/2 break}} y_left/=2;y_right/=2 for(ix=0;ix':gch.y-=y_right break}}} Abc.prototype.draw_gchord=function(i,s,x,y){if(s.invis&&s.play) return var y2,an=s.a_gch[i],h=an.text.wh[1],pad=an.font.pad,w=an.text.wh[0]+pad*2,dy=h*.22 if(an.font.figb){h*=2.4 dy+=an.font.size*1.3} switch(an.type){case'_':y-=h+pad break case'^':y+=pad break case'<':case'>':if(an.type=='<'){if(s.notes[0].acc) x-=s.notes[0].shac x-=pad}else{if(s.xmx) x+=s.xmx if(s.dots) x+=1.5+3.5*s.dots x+=pad} y+=(s.type==C.NOTE?(((s.notes[s.nhd].pit+s.notes[0].pit)>>1)- 18)*3:12) -h/2 break default:if(y>=0) y+=pad else y-=h+pad break case'@':y+=(s.type==C.NOTE?(((s.notes[s.nhd].pit+s.notes[0].pit)>>1)- 18)*3:12) -h/2 if(y>0){y2=y+h+pad+2 if(y2>staff_tb[s.st].ann_top) staff_tb[s.st].ann_top=y2}else{y2=y-2 if(y2=0) y_set(s.st,1,x,w,y+h+pad+2) else y_set(s.st,0,x,w,y-pad)} use_font(an.font) set_font(an.font) set_dscale(s.st) if(user.anno_start) user.anno_start("annot",an.istart,an.iend,x-2,y+h+2,w+4,h+4,s) xy_str(x,y+dy,an.text) if(user.anno_stop) user.anno_stop("annot",an.istart,an.iend,x-2,y+h+2,w+4,h+4,s)} function draw_all_chsy(){var s,san1,an,i,x,y,w,n_an=0,minmax=new Array(nstaff+1) function set_an_yu(j){var an,i,s,x,y,w for(s=san1;s;s=s.ts_next){an=s.a_gch if(!an) continue i=an.length-j-1 an=an[i] if(!an) continue if(an.pos==C.SL_ABOVE){x=s.x+an.x w=an.text.wh[0] if(w&&x+w>realwidth) x=realwidth-w y=y_get(s.st,1,x,w)+2 if(an.type=='g'&&yrealwidth) x=realwidth-w y=y_get(s.st,0,x,w)-2 if(an.type=='g'&&y>minmax[s.st].ydn) y=minmax[s.st].ydn self.draw_gchord(i,s,x,y)}} for(i=0;i<=nstaff;i++) minmax[i]={ydn:staff_tb[i].botbar-3,yup:staff_tb[i].topbar+4} for(s=tsfirst;s;s=s.ts_next){an=s.a_gch if(!an) continue if(!san1) san1=s i=an.length if(i>n_an) n_an=i while(--i>=0){if(an[i].type=='g'){an=an[i] x=s.x+an.x w=an.text.wh[0] if(w&&x+w>realwidth) x=realwidth-w if(an.pos==C.SL_ABOVE){y=y_get(s.st,true,x,w)+2 if(y>minmax[s.st].yup) minmax[s.st].yup=y}else if(an.pos==C.SL_BELOW){y=y_get(s.st,false,x,w)-2 if(y