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