1// abc2svg - ABC to SVG translator
2// @source: https://chiselapp.com/user/moinejf/repository/abc2svg
3// Copyright (C) 2014-2020 Jean-Francois Moine - LGPL3+
4//#javascript
5window.onerror=function(msg,url,line){if(typeof msg=='string')
6alert("window error: "+msg+"\nURL: "+url+"\nLine: "+line)
7else if(typeof msg=='object')
8alert("window error: "+msg.type+' '+msg.target.src)
9else
10alert("window error: "+msg)
11return false}
12var user
13if(typeof abc2svg=="undefined")
14var abc2svg={}
15function dom_loaded(){var abc,new_page,src,a_inc={},errtxt='',app="abcweb",playing,abcplay,playconf={onend:function(){playing=false}},page,tune_lst,jsdir=document.currentScript?document.currentScript.src.match(/.*\//):(function(){var s_a=document.getElementsByTagName('script')
16for(var k=0;k<s_a.length;k++){if(s_a[k].src.indexOf(app)>=0)
17return s_a[k].src.match(/.*\//)||''}
18return""})()
19user={read_file:function(fn){return a_inc[fn]},errmsg:function(msg,l,c){errtxt+=clean_txt(msg)+'\n'},img_out:function(str){new_page+=str}}
20function clean_txt(txt){return txt.replace(/<|>|&.*?;|&/g,function(c){switch(c){case'<':return"&lt;"
21case'>':return"&gt;"
22case'&':return"&amp;"}
23return c})}
24abc2svg.playseq=function(evt){var i,j,svg=evt.target,e=svg
25while(svg.tagName!='svg'){svg=svg.parentNode
26if(!svg)
27return}
28i=svg.getAttribute('class')
29if(!i)
30return
31i=i.match(/tune(\d+)/)
32if(!i)
33return
34i=i[1]
35if(!abcplay){if(typeof AbcPlay=="undefined"){abc2svg.playseq=function(){}
36return}
37abcplay=AbcPlay(playconf)}
38if(!tune_lst){tune_lst=abc.tunes
39for(j=0;j<tune_lst.length;j++)
40abcplay.add(tune_lst[j][0],tune_lst[j][1],tune_lst[j][3])}
41s=tune_lst[i][0]
42i=e.getAttribute('class')
43if(i)
44i=i.match(/abcr _(\d+)_/)
45if(playing){abcplay.stop();if(!i)
46return}
47if(i){i=i[1]
48while(s&&s.istart!=i)
49s=s.ts_next
50if(!s){alert("play bug: no such symbol in the tune")
51return}}
52playing=true
53abcplay.play(s,null)}
54function toabc(s){return s.replace(/&gt;/g,'>').replace(/&lt;/g,'<').replace(/&amp;/g,'&').replace(/[ \t]+(%%|.:)/g,'$1')}
55abc2svg.loadjs=function(fn,relay,onerror){var s=document.createElement('script');if(/:\/\//.test(fn))
56s.src=fn
57else
58s.src=jsdir+fn;if(relay)
59s.onload=relay;s.onerror=onerror||function(){alert('error loading '+fn)}
60document.head.appendChild(s)}
61function render(){var i=0,j,k,res,re=/<script type="text\/vnd.abc"|<[^>]* class="abc"|%abc-\d|X:\d/g,re_stop=/\n<|\n%.begin[^\s]+/g
62if(typeof follow=="function")
63user.anno_stop=function(){};abc=new abc2svg.Abc(user)
64new_page=''
65if(typeof follow=="function")
66follow(abc,user,playconf)
67j=page.indexOf("<mei ")
68if(j>=0){k=page.indexOf("</mei>")+6
69abc.mei2mus(page.slice(j,k))
70document.body.innerHTML=new_page
71return}
72src='%%beginml\n'
73for(;;){res=re.exec(page)
74if(!res){src+=page.slice(i).replace(/\n%%/g,"\n%%%%")+"\n%%endml\n"
75break}
76j=re.lastIndex-res[0].length;src+=page.slice(i,j).replace(/\n%%/g,"\n%%%%")
77switch(res[0][0]){default:res=res[0].match(/<([^\s]*)/)[1]
78if(res=='script'){j=page.indexOf('>',j)+2
79i=page.indexOf('</'+res,j)
80src+="%%endml\n"+
81page.slice(j,i)
82i+=10}else{i=page.indexOf('>',j)+1
83src+=page.slice(j,i)+"\n%%endml\n"
84i=page.indexOf('\n',i)
85j=page.indexOf('</'+res,i)
86src+=toabc(page.slice(i,j))
87i=j}
88break
89case'%':case'X':if(j!=0&&page[j-1]!='\n'){src+=res[0]
90i=re.lastIndex
91continue}
92re_stop.lastIndex=j
93while(1){res=re_stop.exec(page)
94if(!res||res[0]=="\n<")
95break
96k=page.indexOf(res[0].replace("begin","end"),re_stop.lastIndex)
97if(k<0)
98break
99re_stop.lastIndex=k}
100if(!res||k<0)
101i=page.length
102else
103i=re_stop.lastIndex-1
104src+="%%endml\n"+page.slice(j,i)
105break}
106if(i<0)
107break
108re.lastIndex=i
109src+='%%beginml\n'}
110k=location.search.substr(1).split("&")
111for(i=0;i<k.length;i++){if(k[i]){j=k[i].split('=')
112if(j[0])
113abc.tosvg(app,"%%"+j[0]+" "+
114decodeURIComponent(j[1]))}}
115try{abc.tosvg(app,src)}catch(e){alert("abc2svg javascript error: "+e.message+"\nStack:\n"+e.stack)}
116abc2svg.abc_end()
117if(errtxt){new_page+='<pre class="nop" style="background:#ff8080">'+
118errtxt+"</pre>\n"
119errtxt=""}
120try{document.body.innerHTML=new_page}catch(e){alert("abc2svg bad generated SVG: "+e.message+"\nStack:\n"+e.stack)}
121window.onclick=abc2svg.playseq}
122function include(){var i,j,fn,r,k=0
123while(1){i=page.indexOf('%%abc-include ',k)
124if(i<0){render()
125return}
126i+=14
127j=page.indexOf('\n',i)
128fn=page.slice(i,j).trim()
129if(!a_inc[fn])
130break
131k=j}
132r=new XMLHttpRequest()
133r.open('GET',fn,true)
134r.onload=function(){if(r.status===200){a_inc[fn]=r.responseText
135if(abc2svg.modules.load(a_inc[fn],include))
136include()}else{a_inc[fn]='%\n'
137alert('Error getting '+fn+'\n'+r.statusText)
138include()}}
139r.onerror=function(){a_inc[fn]='%\n'
140alert('Error getting '+fn+'\n'+r.statusText)
141include()}
142r.send()}
143page=document.body.innerHTML
144if(!abc2svg.Abc){abc2svg.loadjs(page.indexOf("<mei ")>=0?"mei2svg-1.js":"abc2svg-1.js",dom_loaded)
145return}
146abc2svg.abc_end=function(){}
147if(abc2svg.modules.load(page,include))
148include()}
149window.addEventListener("load",dom_loaded)
150