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"<" 21case'>':return">" 22case'&':return"&"} 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(/>/g,'>').replace(/</g,'<').replace(/&/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