1// abc2svg - ABC to SVG translator 2// @source: https://chiselapp.com/user/moinejf/repository/abc2svg 3// Copyright (C) 2014-2019 Jean-Francois Moine - LGPL3+ 4//combine.js-module to add a combine chord line 5abc2svg.combine={comb_v:function(){var C=abc2svg.C,delsym=[] 6function may_combine(s){var nhd2,s2=s.ts_next 7if(!s2||(s2.type!=C.NOTE&&s2.type!=C.REST)) 8return false 9if(s2.v==s.v||s2.st!=s.st||s2.time!=s.time||s2.dur!=s.dur) 10return false 11if(s.combine<=0&&s2.type!=s.type) 12return false 13if(s.a_gch&&s2.a_gch) 14return false 15if(s.type==C.REST){if(s.type==s2.type&&s.invis&&!s2.invis) 16return false 17return true} 18if(s2.a_ly) 19return false 20if(s2.beam_st!=s.beam_st||s2.beam_end!=s.beam_end) 21return false;nhd2=s2.nhd 22if(s.combine<=1&&s.notes[0].pit<=s2.notes[nhd2].pit+1) 23return false 24return true} 25function combine_notes(s,s2){var nhd,type,m;for(m=0;m<=s2.nhd;m++) 26s2.notes[m].s=s 27Array.prototype.push.apply(s.notes,s2.notes);s.nhd=nhd=s.notes.length-1;s.notes.sort(abc2svg.pitcmp) 28if(s.combine>=3){for(m=nhd;m>0;m--){if(s.notes[m].pit==s.notes[m-1].pit&&s.notes[m].acc==s.notes[m-1].acc) 29s.notes.splice(m,1)} 30s.nhd=nhd=s.notes.length-1} 31s.ymx=3*(s.notes[nhd].pit-18)+4;s.ymn=3*(s.notes[0].pit-18)-4;type=s.notes[0].tie_ty 32if((type&0x07)==C.SL_AUTO) 33s.notes[0].tie_ty=C.SL_BELOW|(type&C.SL_DOTTED);type=s.notes[nhd].tie_ty 34if((type&0x07)==C.SL_AUTO) 35s.notes[nhd].tie_ty=C.SL_ABOVE|(type&C.SL_DOTTED)} 36function do_combine(s){var s2,nhd,nhd2,type 37while(1){nhd=s.nhd;s2=s.ts_next;nhd2=s2.nhd 38if(s.type!=s2.type){if(s2.type!=C.REST){s2=s;s=s2.ts_next}}else if(s.type==C.REST){if(s.invis&&!s2.invis) 39delete s.invis}else{combine_notes.call(this,s,s2) 40if(s2.tie_s) 41s.tie_s=s2.tie_s} 42if(s2.sls){if(s.sls) 43Array.prototype.push.apply(s.sls,s2.sls) 44else 45s.sls=s2.sls} 46if(s2.sl1) 47s.sl1=true 48if(s2.a_gch) 49s.a_gch=s2.a_gch 50if(s2.a_dd){if(!s.a_dd) 51s.a_dd=s2.a_dd 52else 53Array.prototype.push.apply(s.a_dd,s2.a_dd)} 54delsym.push({s:s2,r:s});this.unlksym(s2) 55if(s.in_tuplet||!may_combine.call(this,s)) 56break}} 57function tie_repl(s){var s1=s.tie_s,i=delsym.length 58while(--i>=0){if(delsym[i].s==s1){s.tie_s=delsym[i].r 59break}}} 60var s,s2,g,i,r 61for(s=this.get_tsfirst();s;s=s.ts_next){switch(s.type){case C.REST:if(s.combine==undefined||s.combine<0) 62continue 63if(may_combine.call(this,s)) 64do_combine.call(this,s) 65continue 66default:continue 67case C.NOTE:if(s.combine==undefined||s.combine<=0) 68continue 69break} 70if(!s.beam_st) 71continue 72if(s.beam_end){if(may_combine.call(this,s)) 73do_combine.call(this,s) 74continue} 75s2=s 76while(1){if(!may_combine.call(this,s2)){s2=null 77break} 78if(s2.beam_end) 79break 80do{s2=s2.next}while(s2.type!=C.NOTE&&s2.type!=C.REST)} 81if(!s2) 82continue 83s2=s 84while(1){do_combine.call(this,s2) 85if(s2.beam_end) 86break 87do{s2=s2.next}while(s2.type!=C.NOTE&&s2.type!=C.REST)}} 88for(s=this.get_tsfirst();s;s=s.ts_next){if(s.tie_s) 89tie_repl(s)}},do_pscom:function(of,text){if(text.slice(0,13)=="voicecombine ") 90this.set_v_param("combine",text.split(/[ \t]/)[1]) 91else 92of(text)},new_note:function(of,gr,tp){var curvoice=this.get_curvoice() 93var s=of(gr,tp) 94if(s&&s.notes&&curvoice.combine!=undefined) 95s.combine=curvoice.combine 96return s},set_stem_dir:function(of){of();abc2svg.combine.comb_v.call(this)},set_vp:function(of,a){var i,curvoice=this.get_curvoice() 97for(i=0;i<a.length;i++){if(a[i]=="combine="){curvoice.combine=a[i+1] 98break}} 99of(a)},set_hooks:function(abc){abc.do_pscom=abc2svg.combine.do_pscom.bind(abc,abc.do_pscom);abc.new_note=abc2svg.combine.new_note.bind(abc,abc.new_note);abc.set_stem_dir=abc2svg.combine.set_stem_dir.bind(abc,abc.set_stem_dir);abc.set_vp=abc2svg.combine.set_vp.bind(abc,abc.set_vp)}} 100abc2svg.modules.hooks.push(abc2svg.combine.set_hooks);abc2svg.modules.voicecombine.loaded=true 101