1
0
Files
synapse/webclient/js/vextab/tabdiv-debug.js
2014-10-19 08:47:39 +02:00

2851 lines
96 KiB
JavaScript

/* parser generated by jison 0.4.15 */
/*
Returns a Parser object of the following structure:
Parser: {
yy: {}
}
Parser.prototype: {
yy: {},
trace: function(),
symbols_: {associative list: name ==> number},
terminals_: {associative list: number ==> name},
productions_: [...],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
table: [...],
defaultActions: {...},
parseError: function(str, hash),
parse: function(input),
lexer: {
EOF: 1,
parseError: function(str, hash),
setInput: function(input),
input: function(),
unput: function(str),
more: function(),
less: function(n),
pastInput: function(),
upcomingInput: function(),
showPosition: function(),
test_match: function(regex_match_array, rule_index),
next: function(),
lex: function(),
begin: function(condition),
popState: function(),
_currentRules: function(),
topState: function(),
pushState: function(condition),
options: {
ranges: boolean (optional: true ==> token location info will include a .range[] member)
flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
},
performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
rules: [...],
conditions: {associative list: name ==> set},
}
}
token location info (@$, _$, etc.): {
first_line: n,
last_line: n,
first_column: n,
last_column: n,
range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
}
the parseError function receives a 'hash' object with these members for lexer and parser errors: {
text: (matched text)
token: (the produced terminal token, if any)
line: (yylineno)
}
while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
loc: (yylloc)
expected: (string describing the set of expected tokens)
recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
}
*/
var parser = (function(){
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,6],$V1=[1,7],$V2=[1,8],$V3=[1,9],$V4=[5,11,13,14,15],$V5=[5,11,13,14,15,17,19,21],$V6=[2,17],$V7=[1,14],$V8=[5,11,13,14,15,17,19,21,22],$V9=[1,18],$Va=[1,19],$Vb=[1,20],$Vc=[1,21],$Vd=[1,43],$Ve=[1,32],$Vf=[1,33],$Vg=[1,42],$Vh=[1,41],$Vi=[1,39],$Vj=[1,48],$Vk=[1,55],$Vl=[1,50],$Vm=[1,51],$Vn=[1,52],$Vo=[1,53],$Vp=[1,54],$Vq=[1,56],$Vr=[1,44],$Vs=[1,45],$Vt=[1,46],$Vu=[1,47],$Vv=[1,57],$Vw=[5,11,13,14,15,17,19,21,25],$Vx=[5,11,13,14,15,17,19,21,23,31,32,37,38,45,48,57,61,62,63,64,65,66,70,71,73,75,76],$Vy=[2,79],$Vz=[1,67],$VA=[1,64],$VB=[1,65],$VC=[1,66],$VD=[1,73],$VE=[1,74],$VF=[1,78],$VG=[1,79],$VH=[1,80],$VI=[1,81],$VJ=[41,57,59,61,62,63,64,65,66,67,68,69],$VK=[38,45,48,76],$VL=[41,48,57,59,61,62,63,64,65,66,67,68,69,81],$VM=[5,11,13,14,15,17,19,21,23,31,32,37,38,41,45,48,57,61,62,63,64,65,66,70,71,73,75,76],$VN=[1,101],$VO=[44,46],$VP=[2,63],$VQ=[1,106],$VR=[5,11,13,14,15,17,19,21,23,31,32,37,38,45,48,57,59,61,62,63,64,65,66,70,71,73,75,76],$VS=[5,11,13,14,15,17,19,21,23,31,32,37,38,45,48,57,59,60,61,62,63,64,65,66,70,71,73,75,76],$VT=[25,71],$VU=[41,48,57,59,61,62,63,64,65,66,67,68,69],$VV=[5,11,13,14,15,17,19,21,23,31,32,37,38,44,45,46,48,57,61,62,63,64,65,66,70,71,73,75,76];
var parser = {trace: function trace() { },
yy: {},
symbols_: {"error":2,"e":3,"maybe_vextab":4,"EOF":5,"vextab":6,"stave":7,"voice":8,"maybe_options":9,"stave_data":10,"OPTIONS":11,"options":12,"TABSTAVE":13,"STAVE":14,"VOICE":15,"stave_additions":16,"TEXT":17,"text":18,"NOTES":19,"notes":20,"SLUR":21,"WORD":22,"=":23,"STR":24,",":25,"lingo":26,"line":27,"chord":28,"time":29,"bar":30,"[":31,"]":32,"tuplets":33,"annotations":34,"command":35,"rest":36,"|":37,":":38,"frets":39,"maybe_decorator":40,"/":41,"string":42,"chord_line":43,".":44,"(":45,")":46,"articulation":47,"NUMBER":48,"abc":49,"_":50,"timed_fret":51,"time_values":52,"maybe_dot":53,"time_unit":54,"maybe_slash":55,"w":56,"h":57,"q":58,"d":59,"S":60,"-":61,"s":62,"t":63,"T":64,"b":65,"p":66,"v":67,"V":68,"u":69,"^":70,"$":71,"annotation_words":72,"!":73,"COMMAND":74,"#":75,"ABC":76,"abc_accidental":77,"accidental_type":78,"@":79,"n":80,"~":81,"$accept":0,"$end":1},
terminals_: {2:"error",5:"EOF",11:"OPTIONS",13:"TABSTAVE",14:"STAVE",15:"VOICE",17:"TEXT",19:"NOTES",21:"SLUR",22:"WORD",23:"=",24:"STR",25:",",31:"[",32:"]",37:"|",38:":",41:"/",44:".",45:"(",46:")",48:"NUMBER",50:"_",56:"w",57:"h",58:"q",59:"d",60:"S",61:"-",62:"s",63:"t",64:"T",65:"b",66:"p",67:"v",68:"V",69:"u",70:"^",71:"$",73:"!",74:"COMMAND",75:"#",76:"ABC",79:"@",80:"n",81:"~"},
productions_: [0,[3,2],[4,0],[4,1],[6,1],[6,2],[7,3],[7,2],[7,2],[8,1],[8,1],[8,1],[10,1],[10,2],[16,2],[16,2],[16,2],[9,0],[9,1],[12,3],[12,4],[18,1],[18,3],[20,1],[20,2],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[30,1],[30,3],[30,3],[30,3],[30,3],[30,3],[27,4],[43,1],[43,3],[28,4],[28,5],[39,1],[39,1],[39,4],[39,2],[39,4],[51,5],[51,1],[51,5],[51,8],[51,1],[51,4],[29,3],[52,2],[54,1],[54,1],[54,1],[54,1],[53,0],[53,1],[55,0],[55,1],[42,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[40,1],[40,1],[40,1],[40,1],[40,0],[33,3],[33,5],[34,3],[72,1],[72,3],[35,3],[36,2],[36,3],[36,4],[49,3],[77,1],[77,2],[77,1],[77,2],[77,1],[77,0],[78,0],[78,1]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
/* this == yyval */
var $0 = $$.length - 1;
switch (yystate) {
case 1:
if (Vex.Flow.VexTab.DEBUG && $$[$0-1]) {
console.log($$[$0-1]);
console.log(JSON.stringify($$[$0-1], null, " "));
}
return $$[$0-1];
break;
case 2: case 17: case 79:
this.$ = null
break;
case 3: case 12: case 18: case 23: case 25: case 26: case 27: case 42: case 59: case 60: case 61: case 62: case 67:
this.$ = $$[$0]
break;
case 4: case 83:
this.$ = [$$[$0]]
break;
case 5:
this.$ = [].concat($$[$0-1], $$[$0])
break;
case 6:
this.$ = {
element: $$[$0-2],
options: $$[$0-1],
notes: $$[$0].notes,
text: $$[$0].text,
_l: _$[$0-2].first_line,
_c: _$[$0-2].first_column
}
break;
case 7:
this.$ = {
element: $$[$0-1],
options: $$[$0],
_l: _$[$0-1].first_line,
_c: _$[$0-1].first_column
}
break;
case 8:
this.$ = {
element: "options",
params: $$[$0],
_l: _$[$0-1].first_line,
_c: _$[$0-1].first_column
}
break;
case 13:
var text = [].concat($$[$0-1].text, $$[$0].text);
var notes = [].concat($$[$0-1].notes, $$[$0].notes);
var slurs = [].concat($$[$0-1].slurs, $$[$0].slurs)
this.$ = {text: text, notes: notes, slurs: slurs};
break;
case 14:
this.$ = {text: $$[$0], notes: [], slurs: []}
break;
case 15:
this.$ = {notes: $$[$0], text: [], slurs: []}
break;
case 16:
this.$ = {slurs: $$[$0], notes: [], text: []}
break;
case 19:
this.$ = [{
key: $$[$0-2],
value: $$[$0],
_l: _$[$0-2].first_line,
_c: _$[$0-2].first_column
}]
break;
case 20:
this.$ = [].concat($$[$0-3], [{
key: $$[$0-2],
value: $$[$0],
_l: _$[$0-2].first_line,
_c: _$[$0-2].first_column
}])
break;
case 21:
this.$ = [{text: $$[$0], _l: _$[$0].first_line, _c: _$[$0].first_column}]
break;
case 22:
this.$ = [].concat($$[$0-2], {text: $$[$0], _l: _$[$0].first_line, _c: _$[$0].first_column})
break;
case 24:
this.$ = [].concat($$[$0-1], $$[$0])
break;
case 28:
this.$ = [{
command: "bar",
type: $$[$0],
_l: _$[$0].first_line,
_c: _$[$0].first_column
}]
break;
case 29:
this.$ = [{
command: "open_beam",
_l: _$[$0].first_line,
_c: _$[$0].first_column
}]
break;
case 30:
this.$ = [{
command: "close_beam",
_l: _$[$0].first_line,
_c: _$[$0].first_column
}]
break;
case 31:
this.$ = [{
command: "tuplet",
params: $$[$0],
_l: _$[$0].first_line,
_c: _$[$0].first_column
}]
break;
case 32:
this.$ = [{
command: "annotations",
params: $$[$0],
_l: _$[$0].first_line,
_c: _$[$0].first_column
}]
break;
case 33:
this.$ = [{
command: "command",
params: $$[$0],
_l: _$[$0].first_line,
_c: _$[$0].first_column
}]
break;
case 34:
this.$ = [{
command: "rest",
params: $$[$0]
}]
break;
case 35:
this.$ = 'single'
break;
case 36:
this.$ = 'double'
break;
case 37:
this.$ = 'end'
break;
case 38:
this.$ = 'repeat-end'
break;
case 39:
this.$ = 'repeat-begin'
break;
case 40:
this.$ = 'repeat-both'
break;
case 41:
_.extend(_.last($$[$0-3]), {decorator: $$[$0-2]})
_.each($$[$0-3], function(fret) { fret['string'] = $$[$0] })
this.$ = $$[$0-3]
break;
case 43: case 84:
this.$ = [].concat($$[$0-2], $$[$0])
break;
case 44:
this.$ = [{chord: $$[$0-2], decorator: $$[$0]}]
break;
case 45:
this.$ = [{chord: $$[$0-2], articulation: $$[$0-4], decorator: $$[$0]}]
break;
case 46:
this.$ = [{
fret: $$[$0],
_l: _$[$0].first_line,
_c: _$[$0].first_column}]
break;
case 47:
this.$ = [{abc: $$[$0], _l: _$[$0].first_line, _c: _$[$0].first_column}]
break;
case 48:
this.$ = [{abc: $$[$0-3], octave: $$[$0-2],
fret: $$[$0], _l: _$[$0-3].first_line, _c: _$[$0-3].first_column}]
break;
case 49:
this.$ = [_.extend($$[$0], {articulation: $$[$0-1]})]
break;
case 50:
_.extend(_.last($$[$0-3]), {decorator: $$[$0-2]})
_.extend($$[$0], {articulation: $$[$0-1]})
$$[$0-3].push($$[$0])
this.$ = $$[$0-3]
break;
case 51:
this.$ = {
time: $$[$0-3], dot: $$[$0-2], fret: $$[$0],
_l: _$[$0-4].first_line, _c: _$[$0-4].first_column}
break;
case 52:
this.$ = {fret: $$[$0], _l: _$[$0].first_line, _c: _$[$0].first_column}
break;
case 53:
this.$ = {time: $$[$0-3], dot: $$[$0-2], abc: $$[$0]}
break;
case 54:
this.$ = {time: $$[$0-6], dot: $$[$0-5], abc: $$[$0-3], octave: $$[$0-2], fret: $$[$0]}
break;
case 55:
this.$ = {abc: $$[$0], _l: _$[$0].first_line, _c: _$[$0].first_column}
break;
case 56:
this.$ = {abc: $$[$0-3], octave: $$[$0-2],
fret: $$[$0], _l: _$[$0-3].first_line, _c: _$[$0-3].first_column}
break;
case 57:
this.$ = {time: $$[$0-1], dot: $$[$0]}
break;
case 58:
this.$ = $$[$0-1] + $$[$0]
break;
case 63:
this.$ = false
break;
case 64:
this.$ = true
break;
case 65:
this.$ = ''
break;
case 66: case 69:
this.$ = 's'
break;
case 68:
this.$ = '-'
break;
case 70:
this.$ = 't'
break;
case 71:
this.$ = 'T'
break;
case 72:
this.$ = 'b'
break;
case 73:
this.$ = 'h'
break;
case 74:
this.$ = 'p'
break;
case 75:
this.$ = 'v'
break;
case 76:
this.$ = 'V'
break;
case 77:
this.$ = 'u'
break;
case 78:
this.$ = 'd'
break;
case 80:
this.$ = {tuplet: $$[$0-1]}
break;
case 81:
this.$ = {tuplet: $$[$0-3], notes: $$[$0-1]}
break;
case 82: case 85:
this.$ = $$[$0-1]
break;
case 86:
this.$ = {position: 0}
break;
case 87:
this.$ = {position: $$[$0-1]}
break;
case 88:
this.$ = {position: $$[$0-1] * -1}
break;
case 89:
this.$ = {key: $$[$0-2], accidental: $$[$0-1], accidental_type: $$[$0]}
break;
case 90:
this.$ = "#"
break;
case 91:
this.$ = "##"
break;
case 92:
this.$ = "b"
break;
case 93:
this.$ = "bb"
break;
case 94:
this.$ = "n"
break;
case 96:
this.$ = null;
break;
case 97:
this.$ = "c"
break;
}
},
table: [{3:1,4:2,5:[2,2],6:3,7:4,8:5,11:$V0,13:$V1,14:$V2,15:$V3},{1:[3]},{5:[1,10]},{5:[2,3],7:11,8:5,11:$V0,13:$V1,14:$V2,15:$V3},o($V4,[2,4]),o($V5,$V6,{9:12,12:13,22:$V7}),{12:15,22:$V7},o($V8,[2,9]),o($V8,[2,10]),o($V8,[2,11]),{1:[2,1]},o($V4,[2,5]),o($V4,[2,7],{10:16,16:17,17:$V9,19:$Va,21:$Vb}),o($V5,[2,18],{22:$Vc}),{23:[1,22]},o($V4,[2,8],{22:$Vc}),o($V4,[2,6],{16:23,17:$V9,19:$Va,21:$Vb}),o($V5,[2,12]),{18:24,24:[1,25]},{20:26,23:$Vd,26:27,27:28,28:29,29:30,30:31,31:$Ve,32:$Vf,33:34,34:35,35:36,36:37,37:$Vg,38:$Vh,39:38,45:$Vi,47:40,48:$Vj,49:49,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq,70:$Vr,71:$Vs,73:$Vt,75:$Vu,76:$Vv},o($V5,$V6,{12:13,9:58,22:$V7}),{23:[1,59]},{22:[1,60]},o($V5,[2,13]),o($V5,[2,14],{25:[1,61]}),o($Vw,[2,21]),o($V5,[2,15],{27:28,28:29,29:30,30:31,33:34,34:35,35:36,36:37,39:38,47:40,49:49,26:62,23:$Vd,31:$Ve,32:$Vf,37:$Vg,38:$Vh,45:$Vi,48:$Vj,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq,70:$Vr,71:$Vs,73:$Vt,75:$Vu,76:$Vv}),o($Vx,[2,23]),o($Vx,[2,25]),o($Vx,[2,26]),o($Vx,[2,27]),o($Vx,[2,28]),o($Vx,[2,29]),o($Vx,[2,30]),o($Vx,[2,31]),o($Vx,[2,32]),o($Vx,[2,33]),o($Vx,[2,34]),o([41,57,61,62,63,64,65,66],$Vy,{40:63,59:$Vz,67:$VA,68:$VB,69:$VC}),{27:69,39:38,43:68,47:70,48:$Vj,49:49,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq,76:$Vv},{38:$VD,45:[1,71],48:$VE,49:75,51:72,76:$Vv},{48:$VF,52:76,54:77,56:$VG,57:$VH,58:$VI},o($Vx,[2,35]),{37:[1,82],38:[1,83]},{48:[1,84]},{22:[1,86],72:85},{74:[1,87]},{48:[1,89],61:[1,90],75:[1,88]},o($VJ,[2,46]),o($VJ,[2,47],{48:[1,91]}),o($VK,[2,68]),o($VK,[2,69]),o($VK,[2,70]),o($VK,[2,71]),o($VK,[2,72]),o($VK,[2,73]),o($VK,[2,74]),o($VL,[2,95],{77:92,75:[1,93],79:[1,94],80:[1,95]}),o($V5,[2,16]),{22:[1,96]},o($V8,[2,19]),{24:[1,97]},o($Vx,[2,24]),{41:[1,98],47:99,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq},o($VM,[2,75]),o($VM,[2,76]),o($VM,[2,77]),o($VM,[2,78]),{44:$VN,46:[1,100]},o($VO,[2,42]),{38:$VD,48:$VE,49:75,51:72,76:$Vv},{27:69,39:38,43:102,47:70,48:$Vj,49:49,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq,76:$Vv},o($VJ,[2,49]),{48:$VF,52:103,54:77,56:$VG,57:$VH,58:$VI},o($VJ,[2,52]),o($VJ,[2,55],{48:[1,104]}),o($Vx,$VP,{53:105,59:$VQ}),o($VR,[2,65],{55:107,60:[1,108]}),o($VS,[2,59]),o($VS,[2,60]),o($VS,[2,61]),o($VS,[2,62]),{23:[1,110],37:[1,109],38:[1,111]},{37:[1,112],38:[1,113]},{25:[1,115],70:[1,114]},{25:[1,117],71:[1,116]},o($VT,[2,83]),{73:[1,118]},o($Vx,[2,86]),{75:[1,119]},{48:[1,120]},{50:[1,121]},o($VU,[2,96],{78:122,81:[1,123]}),o($VL,[2,90],{75:[1,124]}),o($VL,[2,92],{79:[1,125]}),o($VL,[2,94]),o($V8,[2,20]),o($Vw,[2,22]),{42:126,48:[1,127]},{38:$VD,48:$VE,49:75,51:128,76:$Vv},o($Vx,$Vy,{40:129,59:$Vz,67:$VA,68:$VB,69:$VC}),{27:130,39:38,47:70,48:$Vj,49:49,57:$Vk,61:$Vl,62:$Vm,63:$Vn,64:$Vo,65:$Vp,66:$Vq,76:$Vv},{44:$VN,46:[1,131]},{38:$VP,53:132,59:$VQ},{50:[1,133]},o($Vx,[2,57]),o($Vx,[2,64]),o($VR,[2,58]),o($VR,[2,66]),o($Vx,[2,36]),o($Vx,[2,37]),o($Vx,[2,39]),o($Vx,[2,38]),o($Vx,[2,40]),o($Vx,[2,80]),{48:[1,134]},o($Vx,[2,82]),{22:[1,135]},o($Vx,[2,85]),o($Vx,[2,87]),{75:[1,136]},{48:[1,137]},o($VU,[2,89]),o($VU,[2,97]),o($VL,[2,91]),o($VL,[2,93]),o($VV,[2,41]),o($VV,[2,67]),o($VJ,[2,50]),o($Vx,[2,44]),o($VO,[2,43]),o($Vx,$Vy,{40:138,59:$Vz,67:$VA,68:$VB,69:$VC}),{38:[1,139]},{48:[1,140]},{70:[1,141]},o($VT,[2,84]),o($Vx,[2,88]),o($VJ,[2,48]),o($Vx,[2,45]),{48:[1,142],49:143,76:$Vv},o($VJ,[2,56]),o($Vx,[2,81]),o($VJ,[2,51]),o($VJ,[2,53],{48:[1,144]}),{50:[1,145]},{48:[1,146]},o($VJ,[2,54])],
defaultActions: {10:[2,1]},
parseError: function parseError(str, hash) {
if (hash.recoverable) {
this.trace(str);
} else {
throw new Error(str);
}
},
parse: function parse(input) {
var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
var args = lstack.slice.call(arguments, 1);
var lexer = Object.create(this.lexer);
var sharedState = { yy: {} };
for (var k in this.yy) {
if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
sharedState.yy[k] = this.yy[k];
}
}
lexer.setInput(input, sharedState.yy);
sharedState.yy.lexer = lexer;
sharedState.yy.parser = this;
if (typeof lexer.yylloc == 'undefined') {
lexer.yylloc = {};
}
var yyloc = lexer.yylloc;
lstack.push(yyloc);
var ranges = lexer.options && lexer.options.ranges;
if (typeof sharedState.yy.parseError === 'function') {
this.parseError = sharedState.yy.parseError;
} else {
this.parseError = Object.getPrototypeOf(this).parseError;
}
function popStack(n) {
stack.length = stack.length - 2 * n;
vstack.length = vstack.length - n;
lstack.length = lstack.length - n;
}
_token_stack:
function lex() {
var token;
token = lexer.lex() || EOF;
if (typeof token !== 'number') {
token = self.symbols_[token] || token;
}
return token;
}
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
while (true) {
state = stack[stack.length - 1];
if (this.defaultActions[state]) {
action = this.defaultActions[state];
} else {
if (symbol === null || typeof symbol == 'undefined') {
symbol = lex();
}
action = table[state] && table[state][symbol];
}
if (typeof action === 'undefined' || !action.length || !action[0]) {
var errStr = '';
expected = [];
for (p in table[state]) {
if (this.terminals_[p] && p > TERROR) {
expected.push('\'' + this.terminals_[p] + '\'');
}
}
if (lexer.showPosition) {
errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
} else {
errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
}
this.parseError(errStr, {
text: lexer.match,
token: this.terminals_[symbol] || symbol,
line: lexer.yylineno,
loc: yyloc,
expected: expected
});
}
if (action[0] instanceof Array && action.length > 1) {
throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
}
switch (action[0]) {
case 1:
stack.push(symbol);
vstack.push(lexer.yytext);
lstack.push(lexer.yylloc);
stack.push(action[1]);
symbol = null;
if (!preErrorSymbol) {
yyleng = lexer.yyleng;
yytext = lexer.yytext;
yylineno = lexer.yylineno;
yyloc = lexer.yylloc;
if (recovering > 0) {
recovering--;
}
} else {
symbol = preErrorSymbol;
preErrorSymbol = null;
}
break;
case 2:
len = this.productions_[action[1]][1];
yyval.$ = vstack[vstack.length - len];
yyval._$ = {
first_line: lstack[lstack.length - (len || 1)].first_line,
last_line: lstack[lstack.length - 1].last_line,
first_column: lstack[lstack.length - (len || 1)].first_column,
last_column: lstack[lstack.length - 1].last_column
};
if (ranges) {
yyval._$.range = [
lstack[lstack.length - (len || 1)].range[0],
lstack[lstack.length - 1].range[1]
];
}
r = this.performAction.apply(yyval, [
yytext,
yyleng,
yylineno,
sharedState.yy,
action[1],
vstack,
lstack
].concat(args));
if (typeof r !== 'undefined') {
return r;
}
if (len) {
stack = stack.slice(0, -1 * len * 2);
vstack = vstack.slice(0, -1 * len);
lstack = lstack.slice(0, -1 * len);
}
stack.push(this.productions_[action[1]][0]);
vstack.push(yyval.$);
lstack.push(yyval._$);
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
stack.push(newState);
break;
case 3:
return true;
}
}
return true;
}};
Vex.L("Starting parser.");
/* generated by jison-lex 0.3.4 */
var lexer = (function(){
var lexer = ({
EOF:1,
parseError:function parseError(str, hash) {
if (this.yy.parser) {
this.yy.parser.parseError(str, hash);
} else {
throw new Error(str);
}
},
// resets the lexer, sets new input
setInput:function (input, yy) {
this.yy = yy || this.yy || {};
this._input = input;
this._more = this._backtrack = this.done = false;
this.yylineno = this.yyleng = 0;
this.yytext = this.matched = this.match = '';
this.conditionStack = ['INITIAL'];
this.yylloc = {
first_line: 1,
first_column: 0,
last_line: 1,
last_column: 0
};
if (this.options.ranges) {
this.yylloc.range = [0,0];
}
this.offset = 0;
return this;
},
// consumes and returns one char from the input
input:function () {
var ch = this._input[0];
this.yytext += ch;
this.yyleng++;
this.offset++;
this.match += ch;
this.matched += ch;
var lines = ch.match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno++;
this.yylloc.last_line++;
} else {
this.yylloc.last_column++;
}
if (this.options.ranges) {
this.yylloc.range[1]++;
}
this._input = this._input.slice(1);
return ch;
},
// unshifts one char (or a string) into the input
unput:function (ch) {
var len = ch.length;
var lines = ch.split(/(?:\r\n?|\n)/g);
this._input = ch + this._input;
this.yytext = this.yytext.substr(0, this.yytext.length - len);
//this.yyleng -= len;
this.offset -= len;
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
this.match = this.match.substr(0, this.match.length - 1);
this.matched = this.matched.substr(0, this.matched.length - 1);
if (lines.length - 1) {
this.yylineno -= lines.length - 1;
}
var r = this.yylloc.range;
this.yylloc = {
first_line: this.yylloc.first_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.first_column,
last_column: lines ?
(lines.length === oldLines.length ? this.yylloc.first_column : 0)
+ oldLines[oldLines.length - lines.length].length - lines[0].length :
this.yylloc.first_column - len
};
if (this.options.ranges) {
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
}
this.yyleng = this.yytext.length;
return this;
},
// When called from action, caches matched text and appends it on next action
more:function () {
this._more = true;
return this;
},
// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
reject:function () {
if (this.options.backtrack_lexer) {
this._backtrack = true;
} else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
return this;
},
// retain first n characters of the match
less:function (n) {
this.unput(this.match.slice(n));
},
// displays already matched input, i.e. for error messages
pastInput:function () {
var past = this.matched.substr(0, this.matched.length - this.match.length);
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
},
// displays upcoming input, i.e. for error messages
upcomingInput:function () {
var next = this.match;
if (next.length < 20) {
next += this._input.substr(0, 20-next.length);
}
return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
},
// displays the character position where the lexing error occurred, i.e. for error messages
showPosition:function () {
var pre = this.pastInput();
var c = new Array(pre.length + 1).join("-");
return pre + this.upcomingInput() + "\n" + c + "^";
},
// test the lexed token: return FALSE when not a match, otherwise return token
test_match:function (match, indexed_rule) {
var token,
lines,
backup;
if (this.options.backtrack_lexer) {
// save context
backup = {
yylineno: this.yylineno,
yylloc: {
first_line: this.yylloc.first_line,
last_line: this.last_line,
first_column: this.yylloc.first_column,
last_column: this.yylloc.last_column
},
yytext: this.yytext,
match: this.match,
matches: this.matches,
matched: this.matched,
yyleng: this.yyleng,
offset: this.offset,
_more: this._more,
_input: this._input,
yy: this.yy,
conditionStack: this.conditionStack.slice(0),
done: this.done
};
if (this.options.ranges) {
backup.yylloc.range = this.yylloc.range.slice(0);
}
}
lines = match[0].match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno += lines.length;
}
this.yylloc = {
first_line: this.yylloc.last_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.last_column,
last_column: lines ?
lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
this.yylloc.last_column + match[0].length
};
this.yytext += match[0];
this.match += match[0];
this.matches = match;
this.yyleng = this.yytext.length;
if (this.options.ranges) {
this.yylloc.range = [this.offset, this.offset += this.yyleng];
}
this._more = false;
this._backtrack = false;
this._input = this._input.slice(match[0].length);
this.matched += match[0];
token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
if (this.done && this._input) {
this.done = false;
}
if (token) {
return token;
} else if (this._backtrack) {
// recover context
for (var k in backup) {
this[k] = backup[k];
}
return false; // rule action called reject() implying the next rule should be tested instead.
}
return false;
},
// return next match in input
next:function () {
if (this.done) {
return this.EOF;
}
if (!this._input) {
this.done = true;
}
var token,
match,
tempMatch,
index;
if (!this._more) {
this.yytext = '';
this.match = '';
}
var rules = this._currentRules();
for (var i = 0; i < rules.length; i++) {
tempMatch = this._input.match(this.rules[rules[i]]);
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
match = tempMatch;
index = i;
if (this.options.backtrack_lexer) {
token = this.test_match(tempMatch, rules[i]);
if (token !== false) {
return token;
} else if (this._backtrack) {
match = false;
continue; // rule action called reject() implying a rule MISmatch.
} else {
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
} else if (!this.options.flex) {
break;
}
}
}
if (match) {
token = this.test_match(match, rules[index]);
if (token !== false) {
return token;
}
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
if (this._input === "") {
return this.EOF;
} else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
},
// return next match that has a token
lex:function lex() {
var r = this.next();
if (r) {
return r;
} else {
return this.lex();
}
},
// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
begin:function begin(condition) {
this.conditionStack.push(condition);
},
// pop the previously active lexer condition state off the condition stack
popState:function popState() {
var n = this.conditionStack.length - 1;
if (n > 0) {
return this.conditionStack.pop();
} else {
return this.conditionStack[0];
}
},
// produce the lexer rule set which is active for the currently active lexer condition state
_currentRules:function _currentRules() {
if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
} else {
return this.conditions["INITIAL"].rules;
}
},
// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
topState:function topState(n) {
n = this.conditionStack.length - 1 - Math.abs(n || 0);
if (n >= 0) {
return this.conditionStack[n];
} else {
return "INITIAL";
}
},
// alias for begin(condition)
pushState:function pushState(condition) {
this.begin(condition);
},
// return the number of states currently on the stack
stateStackSize:function stateStackSize() {
return this.conditionStack.length;
},
options: {},
performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
var YYSTATE=YY_START;
switch($avoiding_name_collisions) {
case 0: this.begin('notes'); return 19;
break;
case 1: this.begin('options'); return 13;
break;
case 2: this.begin('options'); return 14;
break;
case 3: this.begin('options'); return 15;
break;
case 4: this.begin('options'); return 11;
break;
case 5: this.begin('text'); return 17;
break;
case 6: this.begin('options'); return 21;
break;
case 7:return 22
break;
case 8: this.begin('annotations'); return "$"
break;
case 9: this.begin('notes'); return "$"
break;
case 10:return 22
break;
case 11: this.begin('command'); return "!"
break;
case 12: this.begin('notes'); return "!"
break;
case 13:return 74
break;
case 14:return 24
break;
case 15:return 41
break;
case 16:return '+'
break;
case 17:return 38
break;
case 18:return 23
break;
case 19:return 45
break;
case 20:return 46
break;
case 21:return 31
break;
case 22:return 32
break;
case 23:return 70
break;
case 24:return 25
break;
case 25:return 37
break;
case 26:return 44
break;
case 27:return 75
break;
case 28:return 79
break;
case 29:return 65
break;
case 30:return 62
break;
case 31:return 57
break;
case 32:return 66
break;
case 33:return 63
break;
case 34:return 64
break;
case 35:return 61
break;
case 36:return 50
break;
case 37:return 67
break;
case 38:return 68
break;
case 39:return 69
break;
case 40:return 59
break;
case 41:return 48
break;
case 42:return 58
break;
case 43:return 56
break;
case 44:return 57
break;
case 45:return 59
break;
case 46:return 60
break;
case 47:return 76
break;
case 48:return 80
break;
case 49:return 81
break;
case 50: this.begin('INITIAL');
break;
case 51:/* skip whitespace */
break;
case 52:return 5
break;
case 53:return 'INVALID'
break;
}
},
rules: [/^(?:notes\b)/,/^(?:tabstave\b)/,/^(?:stave\b)/,/^(?:voice\b)/,/^(?:options\b)/,/^(?:text\b)/,/^(?:slur\b)/,/^(?:[^\s=]+)/,/^(?:[$])/,/^(?:[$])/,/^(?:[^,$]+)/,/^(?:[!])/,/^(?:[!])/,/^(?:[^!]+)/,/^(?:[^,\r\n]+)/,/^(?:\/)/,/^(?:\+)/,/^(?::)/,/^(?:=)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\^)/,/^(?:,)/,/^(?:\|)/,/^(?:\.)/,/^(?:#)/,/^(?:@)/,/^(?:[b])/,/^(?:[s])/,/^(?:[h])/,/^(?:[p])/,/^(?:[t])/,/^(?:[T])/,/^(?:[-])/,/^(?:[_])/,/^(?:[v])/,/^(?:[V])/,/^(?:[u])/,/^(?:[d])/,/^(?:[0-9]+)/,/^(?:[q])/,/^(?:[w])/,/^(?:[h])/,/^(?:[d])/,/^(?:[S])/,/^(?:[A-GXLR])/,/^(?:[n])/,/^(?:[~])/,/^(?:[\r\n]+)/,/^(?:\s+)/,/^(?:$)/,/^(?:.)/],
conditions: {"notes":{"rules":[8,11,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53],"inclusive":true},"text":{"rules":[14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,41,42,43,44,45,50,51,52,53],"inclusive":true},"slur":{"rules":[15,16,17,18,19,20,21,22,23,24,25,26,27,28,50,51,52,53],"inclusive":true},"annotations":{"rules":[9,10,15,16,17,18,19,20,21,22,23,24,25,26,27,28,50,51,52,53],"inclusive":true},"options":{"rules":[7,15,16,17,18,19,20,21,22,23,24,25,26,27,28,50,51,52,53],"inclusive":true},"command":{"rules":[12,13,15,16,17,18,19,20,21,22,23,24,25,26,27,28,50,51,52,53],"inclusive":true},"INITIAL":{"rules":[0,1,2,3,4,5,6,7,15,16,17,18,19,20,21,22,23,24,25,26,27,28,50,51,52,53],"inclusive":true}}
});
return lexer;
})();
parser.lexer = lexer;
function Parser () {
this.yy = {};
}
Parser.prototype = parser;parser.Parser = Parser;
return new Parser;
})();
if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
exports.parser = parser;
exports.Parser = parser.Parser;
exports.parse = function () { return parser.parse.apply(parser, arguments); };
exports.main = function commonjsMain(args) {
if (!args[1]) {
console.log('Usage: '+args[0]+' FILE');
process.exit(1);
}
var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
return exports.parser.parse(source);
};
if (typeof module !== 'undefined' && require.main === module) {
exports.main(process.argv.slice(1));
}
}/**
* VexFlow TabDiv
* Copyright Mohit Muthanna 2010 <mohit@muthanna.com>
*/
Vex.Flow.TabDiv = function(sel, options) {
if (arguments.length > 0) this.init(sel, options);
}
Vex.Flow.TabDiv.SEL = ".vex-tabdiv";
Vex.Flow.TabDiv.ERROR_NOCANVAS =
"<b>This browser does not support HTML5 Canvas</b><br/>" +
"Please use a modern browser such as <a href='http://google.com/chrome'>" +
"Google Chrome</a> or <a href='http://firefox.com'>Firefox</a>.";
Vex.Flow.TabDiv.prototype.init = function(sel, options) {
this.sel = sel;
// Grab code and clear tabdiv
this.code = $(sel).text();
$(sel).empty();
if ($(sel).css("position") == "static") {
$(sel).css("position", "relative");
}
// Get tabdiv properties
this.width = parseInt($(sel).attr("width")) || 400;
this.height = parseInt($(sel).attr("height")) || 200;
this.scale = parseFloat($(sel).attr("scale")) || 1.0;
// If the Raphael.js sources are included, then use Raphael, else
// resort to HTML5 Canvas.
if (typeof (Raphael) == "undefined") {
this.canvas = $('<canvas></canvas>').addClass("vex-canvas");
$(sel).append(this.canvas);
this.renderer = new Vex.Flow.Renderer(this.canvas[0],
Vex.Flow.Renderer.Backends.CANVAS);
} else {
this.canvas = $('<div></div>').addClass("vex-canvas");
$(sel).append(this.canvas);
this.renderer = new Vex.Flow.Renderer(this.canvas[0],
Vex.Flow.Renderer.Backends.RAPHAEL);
}
this.ctx_sel = $(sel).find(".vex-canvas");
this.renderer.resize(this.width, this.height);
this.ctx = this.renderer.getContext();
this.ctx.setBackgroundFillStyle(this.ctx_sel.css("background-color"));
this.ctx.scale(this.scale, this.scale);
// Grab editor properties
this.editor = $(sel).attr("editor") || "";
this.show_errors = $(sel).attr("show-errors") || "";
this.editor_width= $(sel).attr("editor_width") || this.width;
this.editor_height= $(sel).attr("editor_height") || 200;
var that = this;
if (this.editor == "true") {
this.text_area = $('<textarea></textarea>').addClass("editor").
val(this.code);
this.editor_error = $('<div></div>').addClass("editor-error");
$(sel).append($('<p/>')).append(this.editor_error);
$(sel).append($('<p/>')).append(this.text_area);
this.text_area.width(this.editor_width);
this.text_area.height(this.editor_height);
this.text_area.keyup(function() {
if (that.timeoutID) window.clearTimeout(that.timeoutID);
that.timeoutID =
window.setTimeout(function() {
// Draw only if code changed
if (that.code != that.text_area.val()) {
that.code = that.text_area.val();
that.redraw()
}
}, 250);
});
} if (this.show_errors == "true") {
this.editor_error = $('<div></div>').addClass("editor-error");
$(sel).append($('<p/>')).append(this.editor_error);
}
// Initialize parser.
this.artist = new Vex.Flow.Artist(10, 0, this.width, {scale: this.scale});
this.parser = new Vex.Flow.VexTab(this.artist);
if (Vex.Flow.Player) {
opts = {};
if (options) opts.soundfont_url = options.soundfont_url;
this.player = new Vex.Flow.Player(this.artist, opts);
}
this.redraw();
}
Vex.Flow.TabDiv.prototype.redraw = function() {
var that = this;
Vex.BM("Total render time: ", function() {
that.parse(); that.draw();});
return this;
}
Vex.Flow.TabDiv.prototype.drawInternal = function() {
if (!this.parser.isValid()) return this;
return this.artist.draw(this.renderer);
}
Vex.Flow.TabDiv.prototype.parseInternal = function() {
try {
this.artist.reset();
this.parser.reset();
this.parser.parse(this.code);
this.editor_error.empty();
} catch (e) {
if (this.editor_error) {
this.editor_error.empty();
this.editor_error.append(
$('<div></div>').addClass("text").html(
"Sucky VexTab: " + e.message));
}
}
return this;
}
Vex.Flow.TabDiv.prototype.parse = function() {
var that = this;
Vex.BM("Parse time: ", function() { that.parseInternal(); });
return this;
}
Vex.Flow.TabDiv.prototype.draw = function() {
var that = this;
Vex.BM("Draw time: ", function() { that.drawInternal(); });
return this;
}
// Automatic initialization.
Vex.Flow.TabDiv.start = function() {
$(Vex.Flow.TabDiv.SEL).each(function(index) {
new Vex.Flow.TabDiv(this);
});
}
$(function() {if (Vex.Flow.TabDiv.SEL) { Vex.Flow.TabDiv.start() }});
// Generated by CoffeeScript 1.8.0
(function() {
var __slice = [].slice,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
Vex.Flow.Artist = (function() {
var L, formatAndRender, getFingering, getScoreArticulationParts, getStrokeParts, makeBend, makeDuration, parseBool;
Artist.DEBUG = false;
L = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (Vex.Flow.Artist.DEBUG) {
return typeof console !== "undefined" && console !== null ? console.log.apply(console, ["(Vex.Flow.Artist)"].concat(__slice.call(args))) : void 0;
}
};
Artist.NOLOGO = false;
function Artist(x, y, width, options) {
this.x = x;
this.y = y;
this.width = width;
this.options = {
font_face: "Arial",
font_size: 10,
font_style: null,
bottom_spacing: 20 + (Vex.Flow.Artist.NOLOGO ? 0 : 10),
tab_stave_lower_spacing: 10,
note_stave_lower_spacing: 0,
scale: 1.0
};
if (options != null) {
_.extend(this.options, options);
}
this.reset();
}
Artist.prototype.reset = function() {
this.tuning = new Vex.Flow.Tuning();
this.key_manager = new Vex.Flow.KeyManager("C");
this.music_api = new Vex.Flow.Music();
this.customizations = {
"font-size": this.options.font_size,
"font-face": this.options.font_face,
"font-style": this.options.font_style,
"annotation-position": "bottom",
"scale": this.options.scale,
"width": this.width,
"stave-distance": 0,
"space": 0,
"player": "false",
"tempo": 120,
"instrument": "acoustic_grand_piano",
"accidentals": "standard",
"tab-stems": "false",
"tab-stem-direction": "up",
"beam-rests": "true",
"beam-stemlets": "true",
"beam-middle-only": "false",
"connector-space": 0
};
this.staves = [];
this.tab_articulations = [];
this.stave_articulations = [];
this.player_voices = [];
this.last_y = this.y;
this.current_duration = "q";
this.current_clef = "treble";
this.current_bends = {};
this.current_octave_shift = 0;
this.bend_start_index = null;
this.bend_start_strings = null;
this.rendered = false;
return this.renderer_context = null;
};
Artist.prototype.attachPlayer = function(player) {
return this.player = player;
};
Artist.prototype.setOptions = function(options) {
var k, v, valid_options;
L("setOptions: ", options);
valid_options = _.keys(this.customizations);
for (k in options) {
v = options[k];
if (__indexOf.call(valid_options, k) >= 0) {
this.customizations[k] = v;
} else {
throw new Vex.RERR("ArtistError", "Invalid option '" + k + "'");
}
}
this.last_y += parseInt(this.customizations.space, 10);
if (this.customizations.player === "true") {
return this.last_y += 15;
}
};
Artist.prototype.getPlayerData = function() {
return {
voices: this.player_voices,
context: this.renderer_context,
scale: this.customizations.scale
};
};
parseBool = function(str) {
return str === "true";
};
formatAndRender = function(ctx, tab, score, text_notes, customizations, options) {
var align_rests, beam_config, beams, format_stave, format_voices, formatter, i, multi_voice, notes, score_stave, score_voices, stem_direction, tab_stave, tab_voices, text_stave, text_voices, voice, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
if (tab != null) {
tab_stave = tab.stave;
}
if (score != null) {
score_stave = score.stave;
}
tab_voices = [];
score_voices = [];
text_voices = [];
beams = [];
format_stave = null;
text_stave = null;
beam_config = {
beam_rests: parseBool(customizations["beam-rests"]),
show_stemlets: parseBool(customizations["beam-stemlets"]),
beam_middle_only: parseBool(customizations["beam-middle-only"]),
groups: options.beam_groups
};
if (tab != null) {
multi_voice = tab.voices.length > 1 ? true : false;
_ref = tab.voices;
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
notes = _ref[i];
if (_.isEmpty(notes)) {
continue;
}
_.each(notes, function(note) {
return note.setStave(tab_stave);
});
voice = new Vex.Flow.Voice(Vex.Flow.TIME4_4).setMode(Vex.Flow.Voice.Mode.SOFT);
voice.addTickables(notes);
tab_voices.push(voice);
if (customizations["tab-stems"] === "true") {
if (multi_voice) {
beam_config.stem_direction = i === 0 ? 1 : -1;
} else {
beam_config.stem_direction = customizations["tab-stem-direction"] === "down" ? -1 : 1;
}
beam_config.beam_rests = false;
beams = beams.concat(Vex.Flow.Beam.generateBeams(voice.getTickables(), beam_config));
}
}
format_stave = tab_stave;
text_stave = tab_stave;
}
beam_config.beam_rests = parseBool(customizations["beam-rests"]);
if (score != null) {
multi_voice = score.voices.length > 1 ? true : false;
_ref1 = score.voices;
for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
notes = _ref1[i];
if (_.isEmpty(notes)) {
continue;
}
stem_direction = i === 0 ? 1 : -1;
_.each(notes, function(note) {
return note.setStave(score_stave);
});
voice = new Vex.Flow.Voice(Vex.Flow.TIME4_4).setMode(Vex.Flow.Voice.Mode.SOFT);
voice.addTickables(notes);
score_voices.push(voice);
if (multi_voice) {
beam_config.stem_direction = stem_direction;
beams = beams.concat(Vex.Flow.Beam.generateBeams(notes, beam_config));
} else {
beam_config.stem_direction = null;
beams = beams.concat(Vex.Flow.Beam.generateBeams(notes, beam_config));
}
}
format_stave = score_stave;
text_stave = score_stave;
}
for (_k = 0, _len2 = text_notes.length; _k < _len2; _k++) {
notes = text_notes[_k];
if (_.isEmpty(notes)) {
continue;
}
_.each(notes, function(voice) {
return voice.setStave(text_stave);
});
voice = new Vex.Flow.Voice(Vex.Flow.TIME4_4).setMode(Vex.Flow.Voice.Mode.SOFT);
voice.addTickables(notes);
text_voices.push(voice);
}
if (format_stave != null) {
format_voices = [];
formatter = new Vex.Flow.Formatter();
align_rests = false;
if (tab != null) {
if (!_.isEmpty(tab_voices)) {
formatter.joinVoices(tab_voices);
}
format_voices = tab_voices;
}
if (score != null) {
if (!_.isEmpty(score_voices)) {
formatter.joinVoices(score_voices);
}
format_voices = format_voices.concat(score_voices);
if (score_voices.length > 1) {
align_rests = true;
}
}
if (!_.isEmpty(text_notes) && !_.isEmpty(text_voices)) {
formatter.joinVoices(text_voices);
format_voices = format_voices.concat(text_voices);
}
if (!_.isEmpty(format_voices)) {
formatter.formatToStave(format_voices, format_stave, {
align_rests: align_rests
});
}
if (tab != null) {
_.each(tab_voices, function(voice) {
return voice.draw(ctx, tab_stave);
});
}
if (score != null) {
_.each(score_voices, function(voice) {
return voice.draw(ctx, score_stave);
});
}
_.each(beams, function(beam) {
return beam.setContext(ctx).draw();
});
if (!_.isEmpty(text_notes)) {
_.each(text_voices, function(voice) {
return voice.draw(ctx, text_stave);
});
}
if ((tab != null) && (score != null)) {
(new Vex.Flow.StaveConnector(score.stave, tab.stave)).setContext(ctx).draw();
}
if (score != null) {
return score_voices;
} else {
return tab_voices;
}
}
};
Artist.prototype.render = function(renderer) {
var LOGO, articulation, ctx, setBar, stave, voices, width, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
L("Render: ", this.options);
this.closeBends();
renderer.resize(this.customizations.width * this.customizations.scale, (this.last_y + this.options.bottom_spacing) * this.customizations.scale);
ctx = renderer.getContext();
ctx.scale(this.customizations.scale, this.customizations.scale);
ctx.clear();
ctx.setFont(this.options.font_face, this.options.font_size, "");
this.renderer_context = ctx;
setBar = function(stave, notes) {
var last_note;
last_note = _.last(notes);
if (last_note instanceof Vex.Flow.BarNote) {
notes.pop();
return stave.setEndBarType(last_note.getType());
}
};
_ref = this.staves;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
stave = _ref[_i];
L("Rendering staves.");
if (stave.tab != null) {
setBar(stave.tab, stave.tab_notes);
}
if (stave.note != null) {
setBar(stave.note, stave.note_notes);
}
if (stave.tab != null) {
stave.tab.setContext(ctx).draw();
}
if (stave.note != null) {
stave.note.setContext(ctx).draw();
}
stave.tab_voices.push(stave.tab_notes);
stave.note_voices.push(stave.note_notes);
voices = formatAndRender(ctx, stave.tab != null ? {
stave: stave.tab,
voices: stave.tab_voices
} : null, stave.note != null ? {
stave: stave.note,
voices: stave.note_voices
} : null, stave.text_voices, this.customizations, {
beam_groups: stave.beam_groups
});
this.player_voices.push(voices);
}
L("Rendering tab articulations.");
_ref1 = this.tab_articulations;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
articulation = _ref1[_j];
articulation.setContext(ctx).draw();
}
L("Rendering note articulations.");
_ref2 = this.stave_articulations;
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
articulation = _ref2[_k];
articulation.setContext(ctx).draw();
}
if (this.player != null) {
if (this.customizations.player === "true") {
this.player.setTempo(parseInt(this.customizations.tempo, 10));
this.player.setInstrument(this.customizations.instrument);
this.player.render();
} else {
this.player.removeControls();
}
}
this.rendered = true;
if (!Vex.Flow.Artist.NOLOGO) {
LOGO = "vexflow.com";
width = ctx.measureText(LOGO).width;
ctx.save();
ctx.setFont("Times", 10, "italic");
ctx.fillText(LOGO, (this.customizations.width - width) / 2, this.last_y + 25);
return ctx.restore();
}
};
Artist.prototype.isRendered = function() {
return this.rendered;
};
Artist.prototype.draw = function(renderer) {
return this.render(renderer);
};
Artist.prototype.getNoteForFret = function(fret, string) {
var accidental, new_note, new_octave, new_root, old_root, selected_note, spec, spec_props;
spec = this.tuning.getNoteForFret(fret, string);
spec_props = Vex.Flow.keyProperties(spec);
selected_note = this.key_manager.selectNote(spec_props.key);
accidental = null;
switch (this.customizations.accidentals) {
case "standard":
if (selected_note.change) {
accidental = selected_note.accidental != null ? selected_note.accidental : "n";
}
break;
case "cautionary":
if (selected_note.change) {
accidental = selected_note.accidental != null ? selected_note.accidental : "n";
} else {
accidental = selected_note.accidental != null ? selected_note.accidental + "_c" : void 0;
}
break;
default:
throw new Vex.RERR("ArtistError", "Invalid value for option 'accidentals': " + this.customizations.accidentals);
}
new_note = selected_note.note;
new_octave = spec_props.octave;
old_root = this.music_api.getNoteParts(spec_props.key).root;
new_root = this.music_api.getNoteParts(selected_note.note).root;
if (new_root === "b" && old_root === "c") {
new_octave--;
} else if (new_root === "c" && old_root === "b") {
new_octave++;
}
return [new_note, new_octave, accidental];
};
Artist.prototype.getNoteForABC = function(abc, string) {
var accidental, key, octave;
key = abc.key;
octave = string;
accidental = abc.accidental;
if (abc.accidental_type != null) {
accidental += "_" + abc.accidental_type;
}
return [key, octave, accidental];
};
Artist.prototype.addStaveNote = function(note_params) {
var acc, index, new_accidental, params, parts, stave_note, stave_notes, _i, _len, _ref;
params = {
is_rest: false,
play_note: null
};
_.extend(params, note_params);
stave_notes = _.last(this.staves).note_notes;
stave_note = new Vex.Flow.StaveNote({
keys: params.spec,
duration: this.current_duration + (params.is_rest ? "r" : ""),
clef: params.is_rest ? "treble" : this.current_clef,
auto_stem: params.is_rest ? false : true
});
_ref = params.accidentals;
for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
acc = _ref[index];
if (acc != null) {
parts = acc.split("_");
new_accidental = new Vex.Flow.Accidental(parts[0]);
if (parts.length > 1 && parts[1] === "c") {
new_accidental.setAsCautionary();
}
stave_note.addAccidental(index, new_accidental);
}
}
if (this.current_duration[this.current_duration.length - 1] === "d") {
stave_note.addDotToAll();
}
if (params.play_note != null) {
stave_note.setPlayNote(params.play_note);
}
return stave_notes.push(stave_note);
};
Artist.prototype.addTabNote = function(spec, play_note) {
var new_tab_note, tab_notes;
if (play_note == null) {
play_note = null;
}
tab_notes = _.last(this.staves).tab_notes;
new_tab_note = new Vex.Flow.TabNote({
positions: spec,
duration: this.current_duration
}, this.customizations["tab-stems"] === "true");
if (play_note != null) {
new_tab_note.setPlayNote(play_note);
}
tab_notes.push(new_tab_note);
if (this.current_duration[this.current_duration.length - 1] === "d") {
return new_tab_note.addDot();
}
};
makeDuration = function(time, dot) {
return time + (dot ? "d" : "");
};
Artist.prototype.setDuration = function(time, dot) {
var t;
if (dot == null) {
dot = false;
}
t = time.split(/\s+/);
L("setDuration: ", t[0], dot);
return this.current_duration = makeDuration(t[0], dot);
};
Artist.prototype.addBar = function(type) {
var TYPE, bar_note, stave;
L("addBar: ", type);
this.closeBends();
this.key_manager.reset();
stave = _.last(this.staves);
TYPE = Vex.Flow.Barline.type;
type = (function() {
switch (type) {
case "single":
return TYPE.SINGLE;
case "double":
return TYPE.DOUBLE;
case "end":
return TYPE.END;
case "repeat-begin":
return TYPE.REPEAT_BEGIN;
case "repeat-end":
return TYPE.REPEAT_END;
case "repeat-both":
return TYPE.REPEAT_BOTH;
default:
return TYPE.SINGLE;
}
})();
bar_note = new Vex.Flow.BarNote().setType(type);
stave.tab_notes.push(bar_note);
if (stave.note != null) {
return stave.note_notes.push(bar_note);
}
};
makeBend = function(from_fret, to_fret) {
var direction, text;
direction = Vex.Flow.Bend.UP;
text = "";
if (parseInt(from_fret, 10) > parseInt(to_fret, 10)) {
direction = Vex.Flow.Bend.DOWN;
} else {
text = (function() {
switch (Math.abs(to_fret - from_fret)) {
case 1:
return "1/2";
case 2:
return "Full";
case 3:
return "1 1/2";
default:
return "Bend to " + to_fret;
}
})();
}
return {
type: direction,
text: text
};
};
Artist.prototype.openBends = function(first_note, last_note, first_indices, last_indices) {
var first_frets, from_fret, i, index, last_frets, last_index, start_indices, start_note, tab_notes, to_fret, _base, _i, _len, _results;
L("openBends", first_note, last_note, first_indices, last_indices);
tab_notes = _.last(this.staves).tab_notes;
start_note = first_note;
start_indices = first_indices;
if (_.isEmpty(this.current_bends)) {
this.bend_start_index = tab_notes.length - 2;
this.bend_start_strings = first_indices;
} else {
start_note = tab_notes[this.bend_start_index];
start_indices = this.bend_start_strings;
}
first_frets = start_note.getPositions();
last_frets = last_note.getPositions();
_results = [];
for (i = _i = 0, _len = start_indices.length; _i < _len; i = ++_i) {
index = start_indices[i];
last_index = last_indices[i];
from_fret = first_note.getPositions()[first_indices[i]];
to_fret = last_frets[last_index];
if ((_base = this.current_bends)[index] == null) {
_base[index] = [];
}
_results.push(this.current_bends[index].push(makeBend(from_fret.fret, to_fret.fret)));
}
return _results;
};
Artist.prototype.closeBends = function(offset) {
var bend, k, phrase, tab_note, tab_notes, v, _i, _j, _len, _len1, _ref, _ref1;
if (offset == null) {
offset = 1;
}
if (this.bend_start_index == null) {
return;
}
L("closeBends(" + offset + ")");
tab_notes = _.last(this.staves).tab_notes;
_ref = this.current_bends;
for (k in _ref) {
v = _ref[k];
phrase = [];
for (_i = 0, _len = v.length; _i < _len; _i++) {
bend = v[_i];
phrase.push(bend);
}
tab_notes[this.bend_start_index].addModifier(new Vex.Flow.Bend(null, null, phrase), k);
}
_ref1 = tab_notes.slice(this.bend_start_index + 1, +((tab_notes.length - 2) + offset) + 1 || 9e9);
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
tab_note = _ref1[_j];
tab_note.setGhost(true);
}
this.current_bends = {};
return this.bend_start_index = null;
};
Artist.prototype.makeTuplets = function(tuplets, notes) {
var modifier, stave_notes, tab_modifier, tab_notes;
L("makeTuplets", tuplets, notes);
if (notes == null) {
notes = tuplets;
}
if (!_.last(this.staves).note) {
return;
}
stave_notes = _.last(this.staves).note_notes;
tab_notes = _.last(this.staves).tab_notes;
if (stave_notes.length < notes) {
throw new Vex.RERR("ArtistError", "Not enough notes for tuplet");
}
modifier = new Vex.Flow.Tuplet(stave_notes.slice(stave_notes.length - notes), {
num_notes: tuplets
});
this.stave_articulations.push(modifier);
tab_modifier = new Vex.Flow.Tuplet(tab_notes.slice(tab_notes.length - notes), {
num_notes: tuplets
});
if (this.customizations["tab-stems"] === "true") {
return this.tab_articulations.push(tab_modifier);
}
};
getFingering = function(text) {
return text.match(/^\.fingering\/([^.]+)\./);
};
Artist.prototype.makeFingering = function(text) {
var POS, badFingering, finger, fingering, fingers, modifier, note_number, number, p, parts, pieces, position, _i, _len;
parts = getFingering(text);
POS = Vex.Flow.Modifier.Position;
fingers = [];
fingering = [];
if (parts != null) {
fingers = (function() {
var _i, _len, _ref, _results;
_ref = parts[1].split(/-/);
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
p = _ref[_i];
_results.push(p.trim());
}
return _results;
})();
} else {
return null;
}
badFingering = function() {
return new Vex.RERR("ArtistError", "Bad fingering: " + parts[1]);
};
for (_i = 0, _len = fingers.length; _i < _len; _i++) {
finger = fingers[_i];
pieces = finger.match(/(\d+):([ablr]):([fs]):([^-.]+)/);
if (pieces == null) {
throw badFingering();
}
note_number = parseInt(pieces[1], 10) - 1;
position = POS.RIGHT;
switch (pieces[2]) {
case "l":
position = POS.LEFT;
break;
case "r":
position = POS.RIGHT;
break;
case "a":
position = POS.ABOVE;
break;
case "b":
position = POS.BELOW;
}
modifier = null;
number = pieces[4];
switch (pieces[3]) {
case "s":
modifier = new Vex.Flow.StringNumber(number).setPosition(position);
break;
case "f":
modifier = new Vex.Flow.FretHandFinger(number).setPosition(position);
}
fingering.push({
num: note_number,
modifier: modifier
});
}
return fingering;
};
getStrokeParts = function(text) {
return text.match(/^\.stroke\/([^.]+)\./);
};
Artist.prototype.makeStroke = function(text) {
var TYPE, parts, type;
parts = getStrokeParts(text);
TYPE = Vex.Flow.Stroke.Type;
type = null;
if (parts != null) {
switch (parts[1]) {
case "bu":
type = TYPE.BRUSH_UP;
break;
case "bd":
type = TYPE.BRUSH_DOWN;
break;
case "ru":
type = TYPE.ROLL_UP;
break;
case "rd":
type = TYPE.ROLL_DOWN;
break;
case "qu":
type = TYPE.RASQUEDO_UP;
break;
case "qd":
type = TYPE.RASQUEDO_DOWN;
break;
default:
throw new Vex.RERR("ArtistError", "Invalid stroke type: " + parts[1]);
}
return new Vex.Flow.Stroke(type);
} else {
return null;
}
};
getScoreArticulationParts = function(text) {
return text.match(/^\.(a[^\/]*)\/(t|b)[^.]*\./);
};
Artist.prototype.makeScoreArticulation = function(text) {
var POSTYPE, parts, pos, position, type;
parts = getScoreArticulationParts(text);
if (parts != null) {
type = parts[1];
position = parts[2];
POSTYPE = Vex.Flow.Modifier.Position;
pos = position === "t" ? POSTYPE.ABOVE : POSTYPE.BELOW;
return new Vex.Flow.Articulation(type).setPosition(pos);
} else {
return null;
}
};
Artist.prototype.makeAnnotation = function(text) {
var VJUST, aposition, default_vjust, font_face, font_size, font_style, just, makeIt, parts;
font_face = this.customizations["font-face"];
font_size = this.customizations["font-size"];
font_style = this.customizations["font-style"];
aposition = this.customizations["annotation-position"];
VJUST = Vex.Flow.Annotation.VerticalJustify;
default_vjust = aposition === "top" ? VJUST.TOP : VJUST.BOTTOM;
makeIt = function(text, just) {
if (just == null) {
just = default_vjust;
}
return new Vex.Flow.Annotation(text).setFont(font_face, font_size, font_style).setVerticalJustification(just);
};
parts = text.match(/^\.([^-]*)-([^-]*)-([^.]*)\.(.*)/);
if (parts != null) {
font_face = parts[1];
font_size = parts[2];
font_style = parts[3];
text = parts[4];
if (text) {
return makeIt(text);
} else {
return null;
}
}
parts = text.match(/^\.([^.]*)\.(.*)/);
if (parts != null) {
just = default_vjust;
text = parts[2];
switch (parts[1]) {
case "big":
font_style = "bold";
font_size = "14";
break;
case "italic":
case "italics":
font_face = "Times";
font_style = "italic";
break;
case "medium":
font_size = "12";
break;
case "top":
just = VJUST.TOP;
this.customizations["annotation-position"] = "top";
break;
case "bottom":
just = VJUST.BOTTOM;
this.customizations["annotation-position"] = "bottom";
}
if (text) {
return makeIt(text, just);
} else {
return null;
}
}
return makeIt(text);
};
Artist.prototype.addAnnotations = function(annotations) {
var annotation, e, fingering, fingerings, i, note, score_articulation, stave, stave_notes, stroke, tab_note, tab_notes, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;
stave = _.last(this.staves);
stave_notes = stave.note_notes;
tab_notes = stave.tab_notes;
if (annotations.length > tab_notes.length) {
throw new Vex.RERR("ArtistError", "More annotations than note elements");
}
if (stave.tab) {
_ref = tab_notes.slice(tab_notes.length - annotations.length);
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
tab_note = _ref[i];
if (getScoreArticulationParts(annotations[i])) {
score_articulation = this.makeScoreArticulation(annotations[i]);
tab_note.addModifier(score_articulation, 0);
} else if (getStrokeParts(annotations[i])) {
stroke = this.makeStroke(annotations[i]);
tab_note.addModifier(stroke, 0);
} else {
annotation = this.makeAnnotation(annotations[i]);
if (annotation) {
tab_note.addModifier(this.makeAnnotation(annotations[i]), 0);
}
}
}
} else {
_ref1 = stave_notes.slice(stave_notes.length - annotations.length);
for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
note = _ref1[i];
if (!getScoreArticulationParts(annotations[i])) {
annotation = this.makeAnnotation(annotations[i]);
if (annotation) {
note.addAnnotation(0, this.makeAnnotation(annotations[i]));
}
}
}
}
if (stave.note) {
_ref2 = stave_notes.slice(stave_notes.length - annotations.length);
_results = [];
for (i = _k = 0, _len2 = _ref2.length; _k < _len2; i = ++_k) {
note = _ref2[i];
score_articulation = this.makeScoreArticulation(annotations[i]);
if (score_articulation != null) {
note.addArticulation(0, score_articulation);
}
stroke = this.makeStroke(annotations[i]);
if (stroke != null) {
note.addStroke(0, stroke);
}
fingerings = this.makeFingering(annotations[i]);
if (fingerings != null) {
try {
_results.push((function() {
var _l, _len3, _results1;
_results1 = [];
for (_l = 0, _len3 = fingerings.length; _l < _len3; _l++) {
fingering = fingerings[_l];
_results1.push(note.addModifier(fingering.num, fingering.modifier));
}
return _results1;
})());
} catch (_error) {
e = _error;
throw new Vex.RERR("ArtistError", "Bad note number in fingering: " + annotations[i]);
}
} else {
_results.push(void 0);
}
}
return _results;
}
};
Artist.prototype.addTabArticulation = function(type, first_note, last_note, first_indices, last_indices) {
var articulation;
L("addTabArticulations: ", type, first_note, last_note, first_indices, last_indices);
if (type === "t") {
last_note.addModifier(new Vex.Flow.Annotation("T").setVerticalJustification(Vex.Flow.Annotation.VerticalJustify.BOTTOM));
}
if (_.isEmpty(first_indices) && _.isEmpty(last_indices)) {
return;
}
articulation = null;
if (type === "s") {
articulation = new Vex.Flow.TabSlide({
first_note: first_note,
last_note: last_note,
first_indices: first_indices,
last_indices: last_indices
});
}
if (type === "h" || type === "p") {
articulation = new Vex.Flow.TabTie({
first_note: first_note,
last_note: last_note,
first_indices: first_indices,
last_indices: last_indices
}, type.toUpperCase());
}
if (type === "T" || type === "t") {
articulation = new Vex.Flow.TabTie({
first_note: first_note,
last_note: last_note,
first_indices: first_indices,
last_indices: last_indices
}, " ");
}
if (type === "b") {
this.openBends(first_note, last_note, first_indices, last_indices);
}
if (articulation != null) {
return this.tab_articulations.push(articulation);
}
};
Artist.prototype.addStaveArticulation = function(type, first_note, last_note, first_indices, last_indices) {
var articulation;
L("addStaveArticulations: ", type, first_note, last_note, first_indices, last_indices);
articulation = null;
if (type === "b" || type === "s" || type === "h" || type === "p" || type === "t" || type === "T") {
articulation = new Vex.Flow.StaveTie({
first_note: first_note,
last_note: last_note,
first_indices: first_indices,
last_indices: last_indices
});
}
if (articulation != null) {
return this.stave_articulations.push(articulation);
}
};
Artist.prototype.getPreviousNoteIndex = function() {
var index, note, tab_notes;
tab_notes = _.last(this.staves).tab_notes;
index = 2;
while (index <= tab_notes.length) {
note = tab_notes[tab_notes.length - index];
if (note instanceof Vex.Flow.TabNote) {
return tab_notes.length - index;
}
index++;
}
return -1;
};
Artist.prototype.addDecorator = function(decorator) {
var modifier, score_modifier, score_notes, stave, tab_notes, _ref;
L("addDecorator: ", decorator);
if (decorator == null) {
return;
}
stave = _.last(this.staves);
tab_notes = stave.tab_notes;
score_notes = stave.note_notes;
modifier = null;
score_modifier = null;
if (decorator === "v") {
modifier = new Vex.Flow.Vibrato();
}
if (decorator === "V") {
modifier = new Vex.Flow.Vibrato().setHarsh(true);
}
if (decorator === "u") {
modifier = new Vex.Flow.Articulation("a|").setPosition(Vex.Flow.Modifier.Position.BOTTOM);
score_modifier = new Vex.Flow.Articulation("a|").setPosition(Vex.Flow.Modifier.Position.BOTTOM);
}
if (decorator === "d") {
modifier = new Vex.Flow.Articulation("am").setPosition(Vex.Flow.Modifier.Position.BOTTOM);
score_modifier = new Vex.Flow.Articulation("am").setPosition(Vex.Flow.Modifier.Position.BOTTOM);
}
if (modifier != null) {
_.last(tab_notes).addModifier(modifier, 0);
}
if (score_modifier != null) {
return (_ref = _.last(score_notes)) != null ? _ref.addArticulation(0, score_modifier) : void 0;
}
};
Artist.prototype.addArticulations = function(articulations) {
var art, current_indices, current_tab_note, has_bends, i, indices, n, pos, prev_index, prev_indices, prev_tab_note, stave, stave_notes, tab_notes, this_strings, valid_articulation, valid_strings, _i, _len, _ref;
L("addArticulations: ", articulations);
stave = _.last(this.staves);
tab_notes = stave.tab_notes;
stave_notes = stave.note_notes;
if (_.isEmpty(tab_notes) || _.isEmpty(articulations)) {
this.closeBends(0);
return;
}
current_tab_note = _.last(tab_notes);
has_bends = false;
_ref = ["b", "s", "h", "p", "t", "T", "v", "V"];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
valid_articulation = _ref[_i];
indices = (function() {
var _j, _len1, _results;
_results = [];
for (i = _j = 0, _len1 = articulations.length; _j < _len1; i = ++_j) {
art = articulations[i];
if ((art != null) && art === valid_articulation) {
_results.push(i);
}
}
return _results;
})();
if (_.isEmpty(indices)) {
continue;
}
if (valid_articulation === "b") {
has_bends = true;
}
prev_index = this.getPreviousNoteIndex();
if (prev_index === -1) {
prev_tab_note = null;
prev_indices = null;
} else {
prev_tab_note = tab_notes[prev_index];
this_strings = (function() {
var _j, _len1, _ref1, _results;
_ref1 = current_tab_note.getPositions();
_results = [];
for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
n = _ref1[i];
if (__indexOf.call(indices, i) >= 0) {
_results.push(n.str);
}
}
return _results;
})();
valid_strings = (function() {
var _j, _len1, _ref1, _ref2, _results;
_ref1 = prev_tab_note.getPositions();
_results = [];
for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
pos = _ref1[i];
if (_ref2 = pos.str, __indexOf.call(this_strings, _ref2) >= 0) {
_results.push(pos.str);
}
}
return _results;
})();
prev_indices = (function() {
var _j, _len1, _ref1, _ref2, _results;
_ref1 = prev_tab_note.getPositions();
_results = [];
for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
n = _ref1[i];
if (_ref2 = n.str, __indexOf.call(valid_strings, _ref2) >= 0) {
_results.push(i);
}
}
return _results;
})();
current_indices = (function() {
var _j, _len1, _ref1, _ref2, _results;
_ref1 = current_tab_note.getPositions();
_results = [];
for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
n = _ref1[i];
if (_ref2 = n.str, __indexOf.call(valid_strings, _ref2) >= 0) {
_results.push(i);
}
}
return _results;
})();
}
if (stave.tab != null) {
this.addTabArticulation(valid_articulation, prev_tab_note, current_tab_note, prev_indices, current_indices);
}
if (stave.note != null) {
this.addStaveArticulation(valid_articulation, stave_notes[prev_index], _.last(stave_notes), prev_indices, current_indices);
}
}
if (!has_bends) {
return this.closeBends(0);
}
};
Artist.prototype.addRest = function(params) {
var position, tab_note, tab_notes;
L("addRest: ", params);
this.closeBends();
if (params["position"] === 0) {
this.addStaveNote({
spec: ["r/4"],
accidentals: [],
is_rest: true
});
} else {
position = this.tuning.getNoteForFret((parseInt(params["position"], 10) + 5) * 2, 6);
this.addStaveNote({
spec: [position],
accidentals: [],
is_rest: true
});
}
tab_notes = _.last(this.staves).tab_notes;
if (this.customizations["tab-stems"] === "true") {
tab_note = new Vex.Flow.StaveNote({
keys: [position || "r/4"],
duration: this.current_duration + "r",
clef: "treble",
auto_stem: false
});
if (this.current_duration[this.current_duration.length - 1] === "d") {
tab_note.addDot(0);
}
return tab_notes.push(tab_note);
} else {
return tab_notes.push(new Vex.Flow.GhostNote(this.current_duration));
}
};
Artist.prototype.addChord = function(chord, chord_articulation, chord_decorator) {
var acc, accidental, accidentals, art, articulations, current_duration, current_position, current_string, decorators, durations, i, new_note, new_octave, note, num, num_notes, octave, play_note, play_notes, play_octave, saved_duration, spec, specs, stave, tab_specs, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2;
if (_.isEmpty(chord)) {
return;
}
L("addChord: ", chord);
stave = _.last(this.staves);
specs = [];
play_notes = [];
accidentals = [];
articulations = [];
decorators = [];
tab_specs = [];
durations = [];
num_notes = 0;
current_string = _.first(chord).string;
current_position = 0;
for (_i = 0, _len = chord.length; _i < _len; _i++) {
note = chord[_i];
num_notes++;
if ((note.abc != null) || note.string !== current_string) {
current_position = 0;
current_string = note.string;
}
if (specs[current_position] == null) {
specs[current_position] = [];
play_notes[current_position] = [];
accidentals[current_position] = [];
tab_specs[current_position] = [];
articulations[current_position] = [];
decorators[current_position] = [];
}
_ref = [null, null, null], new_note = _ref[0], new_octave = _ref[1], accidental = _ref[2];
play_note = null;
if (note.abc != null) {
octave = note.octave != null ? note.octave : note.string;
_ref1 = this.getNoteForABC(note.abc, octave), new_note = _ref1[0], new_octave = _ref1[1], accidental = _ref1[2];
if (accidental != null) {
acc = accidental.split("_")[0];
} else {
acc = "";
}
play_note = "" + new_note + acc;
if (note.fret == null) {
note.fret = 'X';
}
} else if (note.fret != null) {
_ref2 = this.getNoteForFret(note.fret, note.string), new_note = _ref2[0], new_octave = _ref2[1], accidental = _ref2[2];
play_note = this.tuning.getNoteForFret(note.fret, note.string).split("/")[0];
} else {
throw new Vex.RERR("ArtistError", "No note specified");
}
play_octave = parseInt(new_octave, 10) + this.current_octave_shift;
current_duration = note.time != null ? {
time: note.time,
dot: note.dot
} : null;
specs[current_position].push("" + new_note + "/" + new_octave);
play_notes[current_position].push("" + play_note + "/" + play_octave);
accidentals[current_position].push(accidental);
tab_specs[current_position].push({
fret: note.fret,
str: note.string
});
if (note.articulation != null) {
articulations[current_position].push(note.articulation);
}
durations[current_position] = current_duration;
if (note.decorator != null) {
decorators[current_position] = note.decorator;
}
current_position++;
}
for (i = _j = 0, _len1 = specs.length; _j < _len1; i = ++_j) {
spec = specs[i];
saved_duration = this.current_duration;
if (durations[i] != null) {
this.setDuration(durations[i].time, durations[i].dot);
}
this.addTabNote(tab_specs[i], play_notes[i]);
if (stave.note != null) {
this.addStaveNote({
spec: spec,
accidentals: accidentals[i],
play_note: play_notes[i]
});
}
this.addArticulations(articulations[i]);
if (decorators[i] != null) {
this.addDecorator(decorators[i]);
}
}
if (chord_articulation != null) {
art = [];
for (num = _k = 1; 1 <= num_notes ? _k <= num_notes : _k >= num_notes; num = 1 <= num_notes ? ++_k : --_k) {
art.push(chord_articulation);
}
this.addArticulations(art);
}
if (chord_decorator != null) {
return this.addDecorator(chord_decorator);
}
};
Artist.prototype.addNote = function(note) {
return this.addChord([note]);
};
Artist.prototype.addTextVoice = function() {
return _.last(this.staves).text_voices.push([]);
};
Artist.prototype.setTextFont = function(font) {
var parts;
if (font != null) {
parts = font.match(/([^-]*)-([^-]*)-([^.]*)/);
if (parts != null) {
this.customizations["font-face"] = parts[1];
this.customizations["font-size"] = parseInt(parts[2], 10);
return this.customizations["font-style"] = parts[3];
}
}
};
Artist.prototype.addTextNote = function(text, position, justification, smooth, ignore_ticks) {
var duration, font_face, font_size, font_style, just, note, struct, voices;
if (position == null) {
position = 0;
}
if (justification == null) {
justification = "center";
}
if (smooth == null) {
smooth = true;
}
if (ignore_ticks == null) {
ignore_ticks = false;
}
voices = _.last(this.staves).text_voices;
if (_.isEmpty(voices)) {
throw new Vex.RERR("ArtistError", "Can't add text note without text voice");
}
font_face = this.customizations["font-face"];
font_size = this.customizations["font-size"];
font_style = this.customizations["font-style"];
just = (function() {
switch (justification) {
case "center":
return Vex.Flow.TextNote.Justification.CENTER;
case "left":
return Vex.Flow.TextNote.Justification.LEFT;
case "right":
return Vex.Flow.TextNote.Justification.RIGHT;
default:
return Vex.Flow.TextNote.Justification.CENTER;
}
})();
duration = ignore_ticks ? "b" : this.current_duration;
struct = {
text: text,
duration: duration,
smooth: smooth,
ignore_ticks: ignore_ticks,
font: {
family: font_face,
size: font_size,
weight: font_style
}
};
if (text[0] === "#") {
struct.glyph = text.slice(1);
}
note = new Vex.Flow.TextNote(struct).setLine(position).setJustification(just);
return _.last(voices).push(note);
};
Artist.prototype.addVoice = function(options) {
var stave;
this.closeBends();
stave = _.last(this.staves);
if (stave == null) {
return this.addStave(options);
}
if (!_.isEmpty(stave.tab_notes)) {
stave.tab_voices.push(stave.tab_notes);
stave.tab_notes = [];
}
if (!_.isEmpty(stave.note_notes)) {
stave.note_voices.push(stave.note_notes);
return stave.note_notes = [];
}
};
Artist.prototype.addStave = function(element, options) {
var beam_groups, note_stave, opts, start_x, tab_stave, tabstave_start_x;
opts = {
tuning: "standard",
clef: "treble",
key: "C",
notation: element === "tabstave" ? "false" : "true",
tablature: element === "stave" ? "false" : "true",
strings: 6
};
_.extend(opts, options);
L("addStave: ", element, opts);
tab_stave = null;
note_stave = null;
start_x = this.x + this.customizations["connector-space"];
tabstave_start_x = 40;
if (opts.notation === "true") {
note_stave = new Vex.Flow.Stave(start_x, this.last_y, this.customizations.width - 20).addClef(opts.clef).addKeySignature(opts.key);
if (opts.time != null) {
note_stave.addTimeSignature(opts.time);
}
this.last_y += note_stave.getHeight() + this.options.note_stave_lower_spacing + parseInt(this.customizations["stave-distance"], 10);
tabstave_start_x = note_stave.getNoteStartX();
this.current_clef = opts.clef;
}
if (opts.tablature === "true") {
tab_stave = new Vex.Flow.TabStave(start_x, this.last_y, this.customizations.width - 20).setNumLines(opts.strings).addTabGlyph().setNoteStartX(tabstave_start_x);
this.last_y += tab_stave.getHeight() + this.options.tab_stave_lower_spacing;
}
this.closeBends();
beam_groups = Vex.Flow.Beam.getDefaultBeamGroups(opts.time);
this.staves.push({
tab: tab_stave,
note: note_stave,
tab_voices: [],
note_voices: [],
tab_notes: [],
note_notes: [],
text_voices: [],
beam_groups: beam_groups
});
this.tuning.setTuning(opts.tuning);
this.key_manager.setKey(opts.key);
};
Artist.prototype.runCommand = function(line, _l, _c) {
var words;
if (_l == null) {
_l = 0;
}
if (_c == null) {
_c = 0;
}
L("runCommand: ", line);
words = line.split(/\s+/);
switch (words[0]) {
case "octave-shift":
this.current_octave_shift = parseInt(words[1], 10);
return L("Octave shift: ", this.current_octave_shift);
default:
throw new Vex.RERR("ArtistError", "Invalid command '" + words[0] + "' at line " + _l + " column " + _c);
}
};
return Artist;
})();
}).call(this);
// Generated by CoffeeScript 1.8.0
(function() {
var __slice = [].slice,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
Vex.Flow.VexTab = (function() {
var L, newError;
VexTab.DEBUG = false;
L = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (Vex.Flow.VexTab.DEBUG) {
return typeof console !== "undefined" && console !== null ? console.log.apply(console, ["(Vex.Flow.VexTab)"].concat(__slice.call(args))) : void 0;
}
};
newError = function(object, msg) {
return new Vex.RERR("ParseError", "" + msg + " in line " + object._l + " column " + object._c);
};
function VexTab(artist) {
this.artist = artist;
this.reset();
}
VexTab.prototype.reset = function() {
this.valid = false;
return this.elements = false;
};
VexTab.prototype.isValid = function() {
return this.valid;
};
VexTab.prototype.getArtist = function() {
return this.artist;
};
VexTab.prototype.parseStaveOptions = function(options) {
var clefs, e, error, notation_option, num_strings, option, params, voices, _i, _len, _ref, _ref1, _ref2;
params = {};
if (options == null) {
return params;
}
notation_option = null;
for (_i = 0, _len = options.length; _i < _len; _i++) {
option = options[_i];
error = function(msg) {
return newError(option, msg);
};
params[option.key] = option.value;
switch (option.key) {
case "notation":
case "tablature":
notation_option = option;
if ((_ref = option.value) !== "true" && _ref !== "false") {
throw error("'" + option.key + "' must be 'true' or 'false'");
}
break;
case "key":
if (!_.has(Vex.Flow.keySignature.keySpecs, option.value)) {
throw error("Invalid key signature '" + option.value + "'");
}
break;
case "clef":
clefs = ["treble", "bass", "tenor", "alto", "percussion", "none"];
if (_ref1 = option.value, __indexOf.call(clefs, _ref1) < 0) {
throw error("'clef' must be one of " + (clefs.join(', ')));
}
break;
case "voice":
voices = ["top", "bottom", "new"];
if (_ref2 = option.value, __indexOf.call(voices, _ref2) < 0) {
throw error("'voice' must be one of " + (voices.join(', ')));
}
break;
case "time":
try {
new Vex.Flow.TimeSignature(option.value);
} catch (_error) {
e = _error;
throw error("Invalid time signature: '" + option.value + "'");
}
break;
case "tuning":
try {
new Vex.Flow.Tuning(option.value);
} catch (_error) {
e = _error;
throw error("Invalid tuning: '" + option.value + "'");
}
break;
case "strings":
num_strings = parseInt(option.value);
if (num_strings < 4 || num_strings > 8) {
throw error("Invalid number of strings: " + num_strings);
}
break;
default:
throw error("Invalid option '" + option.key + "'");
}
}
if (params.notation === "false" && params.tablature === "false") {
throw newError(notation_option, "Both 'notation' and 'tablature' can't be invisible");
}
return params;
};
VexTab.prototype.parseCommand = function(element) {
if (element.command === "bar") {
this.artist.addBar(element.type);
}
if (element.command === "tuplet") {
this.artist.makeTuplets(element.params.tuplet, element.params.notes);
}
if (element.command === "annotations") {
this.artist.addAnnotations(element.params);
}
if (element.command === "rest") {
this.artist.addRest(element.params);
}
if (element.command === "command") {
return this.artist.runCommand(element.params, element._l, element._c);
}
};
VexTab.prototype.parseChord = function(element) {
L("parseChord:", element);
return this.artist.addChord(_.map(element.chord, function(note) {
return _.pick(note, 'time', 'dot', 'fret', 'abc', 'octave', 'string', 'articulation', 'decorator');
}), element.articulation, element.decorator);
};
VexTab.prototype.parseFret = function(note) {
return this.artist.addNote(_.pick(note, 'time', 'dot', 'fret', 'string', 'articulation', 'decorator'));
};
VexTab.prototype.parseABC = function(note) {
return this.artist.addNote(_.pick(note, 'time', 'dot', 'fret', 'abc', 'octave', 'string', 'articulation', 'decorator'));
};
VexTab.prototype.parseStaveElements = function(notes) {
var element, _i, _len, _results;
L("parseStaveElements:", notes);
_results = [];
for (_i = 0, _len = notes.length; _i < _len; _i++) {
element = notes[_i];
if (element.time) {
this.artist.setDuration(element.time, element.dot);
}
if (element.command) {
this.parseCommand(element);
}
if (element.chord) {
this.parseChord(element);
}
if (element.abc) {
_results.push(this.parseABC(element));
} else if (element.fret) {
_results.push(this.parseFret(element));
} else {
_results.push(void 0);
}
}
return _results;
};
VexTab.prototype.parseStaveText = function(text_line) {
var bartext, command, createNote, font, justification, position, smooth, str, text, _i, _len, _results;
if (!_.isEmpty(text_line)) {
this.artist.addTextVoice();
}
position = 0;
justification = "center";
smooth = true;
font = null;
bartext = (function(_this) {
return function() {
return _this.artist.addTextNote("", 0, justification, false, true);
};
})(this);
createNote = (function(_this) {
return function(text) {
var e, ignore_ticks;
ignore_ticks = false;
if (text[0] === "|") {
ignore_ticks = true;
text = text.slice(1);
}
try {
return _this.artist.addTextNote(text, position, justification, smooth, ignore_ticks);
} catch (_error) {
e = _error;
throw newError(str, "Bad text or duration. Did you forget a comma?" + e);
}
};
})(this);
_results = [];
for (_i = 0, _len = text_line.length; _i < _len; _i++) {
str = text_line[_i];
text = str.text.trim();
if (text.match(/\.font=.*/)) {
font = text.slice(6);
_results.push(this.artist.setTextFont(font));
} else if (text[0] === ":") {
_results.push(this.artist.setDuration(text));
} else if (text[0] === ".") {
command = text.slice(1);
switch (command) {
case "center":
case "left":
case "right":
_results.push(justification = command);
break;
case "strict":
_results.push(smooth = false);
break;
case "smooth":
_results.push(smooth = true);
break;
case "bar":
case "|":
_results.push(bartext());
break;
default:
_results.push(position = parseInt(text.slice(1), 10));
}
} else if (text === "|") {
_results.push(bartext());
} else if (text.slice(0, 2) === "++") {
_results.push(this.artist.addTextVoice());
} else {
_results.push(createNote(text));
}
}
return _results;
};
VexTab.prototype.generate = function() {
var e, option, options, stave, _i, _j, _len, _len1, _ref, _ref1, _results;
_ref = this.elements;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
stave = _ref[_i];
switch (stave.element) {
case "stave":
case "tabstave":
this.artist.addStave(stave.element, this.parseStaveOptions(stave.options));
if (stave.notes != null) {
this.parseStaveElements(stave.notes);
}
if (stave.text != null) {
_results.push(this.parseStaveText(stave.text));
} else {
_results.push(void 0);
}
break;
case "voice":
this.artist.addVoice(this.parseStaveOptions(stave.options));
if (stave.notes != null) {
this.parseStaveElements(stave.notes);
}
if (stave.text != null) {
_results.push(this.parseStaveText(stave.text));
} else {
_results.push(void 0);
}
break;
case "options":
options = {};
_ref1 = stave.params;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
option = _ref1[_j];
options[option.key] = option.value;
}
try {
_results.push(this.artist.setOptions(options));
} catch (_error) {
e = _error;
throw newError(stave, e.message);
}
break;
default:
throw newError(stave, "Invalid keyword '" + stave.element + "'");
}
}
return _results;
};
VexTab.prototype.parse = function(code) {
var line, stripped_code;
vextab_parser.parseError = function(message, hash) {
L("VexTab parse error: ", message, hash);
message = "Unexpected text '" + hash.text + "' at line " + hash.loc.first_line + " column " + hash.loc.first_column + ".";
throw new Vex.RERR("ParseError", message);
};
if (code == null) {
throw new Vex.RERR("ParseError", "No code");
}
L("Parsing:\n" + code);
stripped_code = (function() {
var _i, _len, _ref, _results;
_ref = code.split(/\r\n|\r|\n/);
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
line = _ref[_i];
_results.push(line.trim());
}
return _results;
})();
this.elements = vextab_parser.parse(stripped_code.join("\n"));
if (this.elements) {
this.generate();
this.valid = true;
}
return this.elements;
};
return VexTab;
})();
}).call(this);