|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var JSONSchema = require('./jsonschema-b4'); |
|
|
|
|
|
var ParserLint = function() { |
|
|
"use strict"; |
|
|
var decorationList = { type: 'array', optional: true, items: { type: 'string', Enum: [ |
|
|
"trill", "lowermordent", "uppermordent", "mordent", "pralltriller", "accent", |
|
|
"fermata", "invertedfermata", "tenuto", "0", "1", "2", "3", "4", "5", "+", "wedge", |
|
|
"open", "thumb", "snap", "turn", "roll", "irishroll", "breath", "shortphrase", "mediumphrase", "longphrase", |
|
|
"segno", "coda", "D.S.", "D.C.", "fine", "crescendo(", "crescendo)", "diminuendo(", "diminuendo)", "glissando(", "glissando)", |
|
|
"p", "pp", "f", "ff", "mf", "mp", "ppp", "pppp", "fff", "ffff", "sfz", "repeatbar", "repeatbar2", "slide", |
|
|
"upbow", "downbow", "staccato", "trem1", "trem2", "trem3", "trem4", |
|
|
"/", "//", "///", "////", "turnx", "invertedturn", "invertedturnx", "arpeggio", "trill(", "trill)", "xstem", |
|
|
"mark", "marcato", "umarcato", "D.C.alcoda", "D.C.alfine", "D.S.alcoda", "D.S.alfine", "editorial", "courtesy" |
|
|
] } }; |
|
|
|
|
|
var tempoProperties = { |
|
|
duration: { type: "array", optional: true, output: "join", requires: [ 'bpm'], items: { type: "number"} }, |
|
|
bpm: { type: "number", optional: true, requires: [ 'duration'] }, |
|
|
endChar: { type: 'number'}, |
|
|
preString: { type: 'string', optional: true}, |
|
|
postString: { type: 'string', optional: true}, |
|
|
startChar: { type: 'number'}, |
|
|
suppress: { type: 'boolean', Enum: [ true ], optional: true}, |
|
|
suppressBpm: { type: 'boolean', Enum: [ true ], optional: true} |
|
|
}; |
|
|
|
|
|
var appendPositioning = function(properties) { |
|
|
var ret = Object.assign({},properties); |
|
|
ret.startChar = { type: 'number' }; |
|
|
ret.endChar = { type: 'number' }; |
|
|
return ret; |
|
|
}; |
|
|
|
|
|
var prependPositioning = function(properties) { |
|
|
var ret = {}; |
|
|
ret.startChar = { type: 'number' }; |
|
|
ret.endChar = { type: 'number' }; |
|
|
return Object.assign(ret, properties); |
|
|
}; |
|
|
|
|
|
var fontType = { |
|
|
type: 'object', optional: true, properties: { |
|
|
box: { type: 'boolean', Enum: [ true ], optional: true }, |
|
|
face: { type: 'string', optional: true }, |
|
|
weight: { type: 'string', Enum: [ 'bold', 'normal' ], optional: true }, |
|
|
style: { type: 'string',Enum: [ 'italic', 'normal' ], optional: true }, |
|
|
decoration: { type: 'string', Enum: [ 'underline', 'none' ], optional: true }, |
|
|
size: { type: 'number', optional: true } |
|
|
} |
|
|
}; |
|
|
|
|
|
var percMapElement = { |
|
|
type: 'object', optional: true, properties: { |
|
|
sound: { type: 'number', minimum: 35, maximum: 81 }, |
|
|
noteHead: { type: 'string', Enum: ['normal', 'harmonic', 'rhythm', 'x', 'triangle'], optional: true }, |
|
|
} |
|
|
}; |
|
|
var percMapProps = { |
|
|
"C": percMapElement, |
|
|
"_C": percMapElement, |
|
|
"^C": percMapElement, |
|
|
"=C": percMapElement, |
|
|
"D": percMapElement, |
|
|
"_D": percMapElement, |
|
|
"^D": percMapElement, |
|
|
"=D": percMapElement, |
|
|
"E": percMapElement, |
|
|
"_E": percMapElement, |
|
|
"^E": percMapElement, |
|
|
"=E": percMapElement, |
|
|
"F": percMapElement, |
|
|
"_F": percMapElement, |
|
|
"^F": percMapElement, |
|
|
"=F": percMapElement, |
|
|
"G": percMapElement, |
|
|
"_G": percMapElement, |
|
|
"^G": percMapElement, |
|
|
"=G": percMapElement, |
|
|
"A": percMapElement, |
|
|
"_A": percMapElement, |
|
|
"^A": percMapElement, |
|
|
"=A": percMapElement, |
|
|
"B": percMapElement, |
|
|
"_B": percMapElement, |
|
|
"^B": percMapElement, |
|
|
"=B": percMapElement, |
|
|
"c": percMapElement, |
|
|
"_c": percMapElement, |
|
|
"^c": percMapElement, |
|
|
"=c": percMapElement, |
|
|
"d": percMapElement, |
|
|
"_d": percMapElement, |
|
|
"^d": percMapElement, |
|
|
"=d": percMapElement, |
|
|
"e": percMapElement, |
|
|
"_e": percMapElement, |
|
|
"^e": percMapElement, |
|
|
"=e": percMapElement, |
|
|
"f": percMapElement, |
|
|
"_f": percMapElement, |
|
|
"^f": percMapElement, |
|
|
"=f": percMapElement, |
|
|
"g": percMapElement, |
|
|
"_g": percMapElement, |
|
|
"^g": percMapElement, |
|
|
"=g": percMapElement, |
|
|
"a": percMapElement, |
|
|
"_a": percMapElement, |
|
|
"^a": percMapElement, |
|
|
"=a": percMapElement, |
|
|
}; |
|
|
|
|
|
var clefProperties = { |
|
|
stafflines: { type: 'number', minimum: 0, maximum: 10, optional: true }, |
|
|
staffscale: { type: 'number', minimum: 0.1, maximum: 10, optional: true }, |
|
|
transpose: { type: 'number', minimum: -24, maximum: 24, optional: true }, |
|
|
type: { type: 'string', Enum: [ 'treble', 'tenor', 'bass', 'alto', 'treble+8', 'tenor+8', 'bass+8', 'alto+8', 'treble-8', 'tenor-8', 'bass-8', 'alto-8', 'none', 'perc' ] }, |
|
|
verticalPos: { type: 'number', minimum: -20, maximum: 10 }, |
|
|
clefPos: { type: 'number', minimum: 2, maximum: 10, optional: true } |
|
|
}; |
|
|
|
|
|
var chordProperties = { |
|
|
type: "object", properties: { |
|
|
name: { type: 'string'}, |
|
|
chord: { type: 'object', optional: true, properties: { |
|
|
root: { type: 'string', Enum: [ 'A', 'B', 'C', 'D', 'E', 'F', 'G' ]}, |
|
|
type: { type: 'string', Enum: [ 'm', '7', 'm7', 'maj7', 'M7', '6', 'm6', 'aug', '+', 'aug7', 'dim', 'dim7', '9', 'm9', 'maj9', 'M9', '11', 'dim9', 'sus', 'sus9', '7sus4', '7sus9', '5' ]} |
|
|
} |
|
|
}, |
|
|
position: { type: 'string', Enum: [ 'above', 'below', 'left', 'right', 'default' ], optional: true, prohibits: [ 'rel_position' ] }, |
|
|
rel_position: { type: 'object', properties: { x: { type: 'number' }, y: { type: 'number' } }, optional: true, prohibits: [ 'position' ] } |
|
|
} |
|
|
}; |
|
|
|
|
|
var slurProperties = { type: 'array', optional: true, output: "noindex", items: { |
|
|
type: 'object', optional: true, properties: { |
|
|
label: { type: 'number', minimum: 0 }, |
|
|
direction: { type: 'string', optional: true, Enum: [ 'up', 'down' ] }, |
|
|
style: { type: 'string', optional: true, Enum: [ 'dotted' ] } |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
var tieProperties = { type: 'object', optional: true, properties: { |
|
|
direction: { type: 'string', optional: true, Enum: [ 'up', 'down' ] }, |
|
|
style: { type: 'string', optional: true, Enum: [ 'dotted' ] } |
|
|
} }; |
|
|
|
|
|
var barProperties = { |
|
|
barNumber: { type: 'number', optional: true }, |
|
|
chord: { type: 'array', optional: true, output: "noindex", items: chordProperties }, |
|
|
decoration: decorationList, |
|
|
endEnding: { type: 'boolean', Enum: [ true ], optional: true }, |
|
|
startEnding: { type: 'string', optional: true }, |
|
|
type: { type: 'string', Enum: [ 'bar_dbl_repeat', 'bar_right_repeat', 'bar_left_repeat', 'bar_invisible', 'bar_thick_thin', 'bar_thin_thin', 'bar_thin', 'bar_thin_thick' ] } |
|
|
}; |
|
|
|
|
|
var noteProperties = { |
|
|
beambr: { type: 'number', minimum: 1, maximum: 5, optional: true }, |
|
|
chord: { type: 'array', optional: true, output: "noindex", items: chordProperties }, |
|
|
decoration: decorationList, |
|
|
duration: { type: 'number' }, |
|
|
endBeam: { type: 'boolean', Enum: [ true ], prohibits: [ 'startBeam', 'beambr' ], optional: true }, |
|
|
endSlur: { type: 'array', optional: true, output: "join", items: { type: 'number', minimum: 0 } }, |
|
|
endTriplet: { type: 'boolean', Enum: [ true ], optional: true }, |
|
|
fonts: { type: 'object', optional: true, properties: { |
|
|
annotationfont: fontType, |
|
|
gchordfont: fontType, |
|
|
measurefont: fontType, |
|
|
repeatfont: fontType, |
|
|
tripletfont: fontType, |
|
|
vocalfont: fontType |
|
|
}}, |
|
|
gracenotes: { type: 'array', optional: true, output: "noindex", items: { |
|
|
type: "object", properties: { |
|
|
acciaccatura: { type: 'boolean', Enum: [ true ], optional: true}, |
|
|
accidental: { type: 'string', Enum: [ 'sharp', 'flat', 'natural', 'dblsharp', 'dblflat', 'quarterflat', 'quartersharp' ], optional: true }, |
|
|
duration: { type: 'number' }, |
|
|
endBeam: { type: 'boolean', Enum: [ true ], prohibits: [ 'startBeam', 'beambr' ], optional: true }, |
|
|
endSlur: { type: 'array', optional: true, output: "join", items: { type: 'number', minimum: 0 } }, |
|
|
endTie: { type: 'boolean', Enum: [ true ], optional: true }, |
|
|
midipitch: { type: 'number', optional: true }, |
|
|
name: { type: 'string' }, |
|
|
pitch: { type: 'number' }, |
|
|
verticalPos: { type: 'number' }, |
|
|
startBeam: { type: 'boolean', Enum: [ true ], prohibits: [ 'endBeam', 'beambr' ], optional: true }, |
|
|
startSlur: slurProperties, |
|
|
startTie: tieProperties, |
|
|
} |
|
|
}}, |
|
|
lyric: { type: 'array', optional: true, output: "noindex", items: { |
|
|
type: 'object', properties: { |
|
|
syllable: { type :'string' }, |
|
|
divider: { type: 'string', Enum: [ '-', ' ', '_' ]} |
|
|
}}}, |
|
|
noStem: { type: 'boolean', Enum: [ true ], optional: true }, |
|
|
pitches: { type: 'array', optional: true, output: "noindex", prohibits: [ 'rest' ], items: { |
|
|
type: 'object', properties: { |
|
|
accidental: { type: 'string', Enum: [ 'sharp', 'flat', 'natural', 'dblsharp', 'dblflat', 'quarterflat', 'quartersharp' ], optional: true }, |
|
|
endSlur: { type: 'array', optional: true, output: "join", items: { type: 'number', minimum: 0 } }, |
|
|
endTie: { type: 'boolean', Enum: [ true ], optional: true }, |
|
|
midipitch: { type: 'number', optional: true }, |
|
|
name: { type: 'string' }, |
|
|
pitch: { type: 'number' }, |
|
|
verticalPos: { type: 'number' }, |
|
|
startSlur: slurProperties, |
|
|
startTie: tieProperties, |
|
|
style: { type: 'string', Enum: ['normal', 'harmonic', 'rhythm', 'x', 'triangle'], optional: true }, |
|
|
} |
|
|
}}, |
|
|
positioning: { type: 'object', optional: true, properties: { |
|
|
chordPosition: { type: 'string', Enum: [ 'above', 'below', 'hidden' ], optional: true}, |
|
|
dynamicPosition: { type: 'string', Enum: [ 'above', 'below', 'hidden' ], optional: true}, |
|
|
ornamentPosition: { type: 'string', Enum: [ 'above', 'below', 'hidden' ], optional: true}, |
|
|
vocalPosition: { type: 'string', Enum: [ 'above', 'below', 'hidden' ], optional: true}, |
|
|
volumePosition: { type: 'string', Enum: [ 'above', 'below', 'hidden' ], optional: true} |
|
|
}}, |
|
|
rest: { type: 'object', optional: true, prohibits: [ 'pitches', 'lyric' ], properties: { |
|
|
type: { type: 'string', Enum: [ 'invisible', 'spacer', 'rest', 'multimeasure', 'invisible-multimeasure', 'whole' ] }, |
|
|
text: { type: 'number', minimum: 1, maximum: 100, optional: true }, |
|
|
endTie: { type: 'boolean', Enum: [ true ], optional: true }, |
|
|
startTie: tieProperties |
|
|
}}, |
|
|
startBeam: { type: 'boolean', Enum: [ true ], prohibits: [ 'endBeam', 'beambr' ], optional: true }, |
|
|
startSlur: slurProperties, |
|
|
startTriplet: { type: 'number', minimum: 2, maximum: 9, optional: true }, |
|
|
tripletMultiplier: { type: 'number', minimum: .1, maximum: 9, optional: true }, |
|
|
tripletR: { type: 'number', minimum: .1, maximum: 9, optional: true }, |
|
|
stemConnectsToAbove: { type: 'boolean', Enum: [ true ], optional: true }, |
|
|
style: { type: 'string', Enum: ['normal', 'harmonic', 'rhythm', 'x', 'triangle'], optional: true } |
|
|
}; |
|
|
|
|
|
var keyProperties = { |
|
|
accidentals: { type: 'array', optional: true, output: "noindex", items: { |
|
|
type: 'object', properties: { |
|
|
acc: { type: 'string', Enum: [ 'flat', 'natural', 'sharp', 'dblsharp', 'dblflat', 'quarterflat', 'quartersharp' ] }, |
|
|
note: { type: 'string', Enum: [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'a', 'b', 'c', 'd', 'e', 'f', 'g' ] }, |
|
|
verticalPos: { type: 'number', minimum: 0, maximum: 13 } |
|
|
} |
|
|
} }, |
|
|
root: { type: 'string', Enum: [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'HP', 'Hp', 'none']}, |
|
|
acc: { type: 'string', Enum: ['', '#', 'b']}, |
|
|
mode: { type: 'string', Enum: ['', 'm', 'Dor', 'Mix', 'Loc', 'Phr', 'Lyd']} |
|
|
}; |
|
|
|
|
|
var meterProperties = { |
|
|
type: { type: 'string', Enum: [ 'common_time', 'cut_time', 'specified', 'tempus_perfectum', 'tempus_imperfectum', 'tempus_perfectum_prolatio', 'tempus_imperfectum_prolatio' ] }, |
|
|
|
|
|
value: { type: 'array', optional: true, output: 'noindex', |
|
|
items: { |
|
|
type: 'object', properties: { |
|
|
num: { type: 'string' }, |
|
|
den: { type: 'string', optional: true } |
|
|
} |
|
|
} |
|
|
}, |
|
|
beat_division: { type: 'array', optional: true, output: 'noindex', |
|
|
items: { |
|
|
type: 'object', properties: { |
|
|
num: { type: 'string' }, |
|
|
den: { type: 'string', optional: true } |
|
|
} |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
var midiProperties = { |
|
|
cmd: { type: 'string', Enum: [ |
|
|
"nobarlines", "barlines", "beataccents", "nobeataccents", "droneon", "droneoff", "noportamento", "channel", "c", |
|
|
"drumon", "drumoff", "fermatafixed", "fermataproportional", "gchordon", "gchordoff", "bassvol", "chordvol", "bassprog", "chordprog", |
|
|
"controlcombo", "temperamentnormal", "gchord", "ptstress", "beatmod", "deltaloudness", "drumbars", "pitchbend", |
|
|
"gracedivider", "makechordchannels", "randomchordattack", "chordattack", "stressmodel", "transpose", |
|
|
"rtranspose", "volinc", "program", "ratio", "snt", "bendvelocity", "control", "temperamentlinear", "beat", "beatstring", |
|
|
"drone", "bassprog", "chordprog", "drummap", "portamento", "expand", "grace", "trim", "drum", "chordname" |
|
|
]}, |
|
|
params: { type: 'array', output: 'join', |
|
|
items: { |
|
|
type: 'stringorinteger' |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
var voiceItem = { type: "union", |
|
|
field: "el_type", |
|
|
types: [ |
|
|
{ value: "clef", properties: appendPositioning(clefProperties) }, |
|
|
{ value: "color", properties: { color: {type: "string", optional: true } } }, |
|
|
{ value: "bar", properties: prependPositioning(barProperties) }, |
|
|
{ value: "gap", properties: { type: "number", optional: true } }, |
|
|
{ value: "key", properties: appendPositioning(keyProperties) }, |
|
|
{ value: "meter", properties: appendPositioning(meterProperties) }, |
|
|
{ value: "midi", properties: appendPositioning(midiProperties) }, |
|
|
{ value: "overlay", properties: { type: 'array', items: { |
|
|
type: prependPositioning(noteProperties)} } }, |
|
|
{ value: "part", properties: prependPositioning({ title: { type: 'string' } }) }, |
|
|
{ value: "scale", properties: { size: {type: "number", optional: true, minimum: 0.5, maximum: 2 } } }, |
|
|
{ value: 'stem', properties: { |
|
|
direction: { type: 'string', Enum: [ 'up', 'down', 'auto', 'none' ] } |
|
|
}}, |
|
|
{ value: 'style', properties: { |
|
|
head: { type: 'string', Enum: [ 'normal', 'harmonic', 'rhythm', 'x', 'triangle' ] } |
|
|
}}, |
|
|
{ value: 'tempo', properties: appendPositioning(tempoProperties) }, |
|
|
{ value: 'transpose', properties: { steps: { type: "number" } } }, |
|
|
{ value: "note", properties: prependPositioning(noteProperties) } |
|
|
] |
|
|
}; |
|
|
|
|
|
var textFieldProperties = { type: "stringorarray", optional: true, output: 'noindex', |
|
|
items: { |
|
|
type: 'object', properties: { |
|
|
endChar: { type: 'number', optional: true}, |
|
|
font: fontType, |
|
|
text: { type: 'string' }, |
|
|
center: { type: 'boolean', Enum: [ true ], optional: true }, |
|
|
startChar: { type: 'number', optional: true} |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
var drummapProps = { |
|
|
"C": { type: "number", optional: true }, |
|
|
"_C": { type: "number", optional: true }, |
|
|
"^C": { type: "number", optional: true }, |
|
|
"=C": { type: "number", optional: true }, |
|
|
"D": {type: "number", optional: true}, |
|
|
"_D": {type: "number", optional: true}, |
|
|
"^D": {type: "number", optional: true}, |
|
|
"=D": {type: "number", optional: true}, |
|
|
"E": {type: "number", optional: true}, |
|
|
"_E": {type: "number", optional: true}, |
|
|
"^E": {type: "number", optional: true}, |
|
|
"=E": {type: "number", optional: true}, |
|
|
"F": {type: "number", optional: true}, |
|
|
"_F": {type: "number", optional: true}, |
|
|
"^F": {type: "number", optional: true}, |
|
|
"=F": {type: "number", optional: true}, |
|
|
"G": {type: "number", optional: true}, |
|
|
"_G": {type: "number", optional: true}, |
|
|
"^G": {type: "number", optional: true}, |
|
|
"=G": {type: "number", optional: true}, |
|
|
"A": {type: "number", optional: true}, |
|
|
"_A": {type: "number", optional: true}, |
|
|
"^A": {type: "number", optional: true}, |
|
|
"=A": {type: "number", optional: true}, |
|
|
"B": {type: "number", optional: true}, |
|
|
"_B": {type: "number", optional: true}, |
|
|
"^B": {type: "number", optional: true}, |
|
|
"=B": {type: "number", optional: true}, |
|
|
"c": {type: "number", optional: true}, |
|
|
"_c": {type: "number", optional: true}, |
|
|
"^c": {type: "number", optional: true}, |
|
|
"=c": {type: "number", optional: true}, |
|
|
"d": {type: "number", optional: true}, |
|
|
"_d": {type: "number", optional: true}, |
|
|
"^d": {type: "number", optional: true}, |
|
|
"=d": {type: "number", optional: true}, |
|
|
"e": {type: "number", optional: true}, |
|
|
"_e": {type: "number", optional: true}, |
|
|
"^e": {type: "number", optional: true}, |
|
|
"=e": {type: "number", optional: true}, |
|
|
"f": {type: "number", optional: true}, |
|
|
"_f": {type: "number", optional: true}, |
|
|
"^f": {type: "number", optional: true}, |
|
|
"=f": {type: "number", optional: true}, |
|
|
"g": {type: "number", optional: true}, |
|
|
"_g": {type: "number", optional: true}, |
|
|
"^g": {type: "number", optional: true}, |
|
|
"=g": {type: "number", optional: true}, |
|
|
"a": {type: "number", optional: true}, |
|
|
"_a": {type: "number", optional: true}, |
|
|
"^a": {type: "number", optional: true}, |
|
|
"=a": {type: "number", optional: true}, |
|
|
}; |
|
|
|
|
|
var formattingProperties = { |
|
|
type:"object", |
|
|
properties: { |
|
|
accentAbove: { type: "boolean", optional: true }, |
|
|
alignbars: { type: "number", optional: true }, |
|
|
aligncomposer: { type: "string", Enum: [ 'left', 'center','right' ], optional: true }, |
|
|
annotationfont: fontType, |
|
|
auquality: { type: "string", optional: true }, |
|
|
bagpipes: { type: "boolean", optional: true }, |
|
|
barlabelfont: fontType, |
|
|
barnumberfont: fontType, |
|
|
botmargin: { type: "number", optional: true }, |
|
|
botspace: { type: "number", optional: true }, |
|
|
bstemdown: { type: "boolean", optional: true }, |
|
|
composerfont: fontType, |
|
|
composerspace: { type: "number", optional: true }, |
|
|
continueall: { type: "boolean", optional: true }, |
|
|
continuous: { type: "string", optional: true }, |
|
|
dynalign: { type: "boolean", optional: true }, |
|
|
exprabove: { type: "boolean", optional: true }, |
|
|
exprbelow: { type: "boolean", optional: true }, |
|
|
flatbeams: { type: "boolean", optional: true }, |
|
|
footer: { type: "string", optional: true }, |
|
|
footerfont: fontType, |
|
|
freegchord: { type: "boolean", optional: true }, |
|
|
gchordbox: { type: "boolean", optional: true }, |
|
|
gchordfont: fontType, |
|
|
graceSlurs: { type: "boolean", optional: true }, |
|
|
gracespacebefore: { type: "number", optional: true }, |
|
|
gracespaceinside: { type: "number", optional: true }, |
|
|
gracespaceafter: { type: "number", optional: true }, |
|
|
header: { type: "string", optional: true }, |
|
|
headerfont: fontType, |
|
|
historyfont: fontType, |
|
|
indent: { type: "number", optional: true }, |
|
|
infofont: fontType, |
|
|
infoline: { type: "boolean", optional: true }, |
|
|
infospace: { type: "number", optional: true }, |
|
|
|
|
|
jazzchords: { type: "boolean", optional: true }, |
|
|
germanAlphabet: { type: "boolean", optional: true }, |
|
|
leftmargin: { type: "number", optional: true }, |
|
|
linesep: { type: "number", optional: true }, |
|
|
lineskipfac: { type: "number", optional: true }, |
|
|
lineThickness: { type: "number", optional: true }, |
|
|
map: { type: "string", optional: true }, |
|
|
maxshrink: { type: "number", optional: true }, |
|
|
maxstaffsep: { type: "number", optional: true }, |
|
|
maxsysstaffsep: { type: "number", optional: true }, |
|
|
measurebox: { type: "boolean", optional: true }, |
|
|
measurefont: fontType, |
|
|
midi: { type: "object", optional: true, properties: { |
|
|
barlines: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
bassprog: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
bassvol: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
beat: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
beataccents: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
beatmod: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
beatstring: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
bendvelocity: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
c: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
channel: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
chordattack: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
chordname: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
chordprog: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
chordvol: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
control: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
controlcombo: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
deltaloudness: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
drone: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
droneoff: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
droneon: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
drum: { type: 'array', optional: true, output: 'join', items: { type: "stringorinteger" } }, |
|
|
drumbars: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
drummap: { type: 'object', optional: true, properties: drummapProps }, |
|
|
drumoff: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
drumon: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
expand: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
fermatafixed: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
fermataproportional: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
gchord: { type: 'array', optional: true, output: 'join', items: { type: "stringorinteger" } }, |
|
|
gchordon: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
gchordoff: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
grace: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
gracedivider: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
makechordchannels: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
nobarlines: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
nobeataccents: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
noportamento: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
pitchbend: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
program: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
portamento: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
ptstress: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
randomchordattack: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
ratio: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
rtranspose: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
snt: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
stressmodel: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
temperamentlinear: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
temperamentnormal: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
transpose: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
trim: { type: 'array', optional: true, output: 'join', items: { type: "number" } }, |
|
|
volinc: { type: 'array', optional: true, output: 'join', items: { type: "number" } } |
|
|
}}, |
|
|
musicspace: { type: "number", optional: true }, |
|
|
nobarcheck: { type: "string", optional: true }, |
|
|
notespacingfactor: { type: "number", optional: true }, |
|
|
pageheight: { type: "number" }, |
|
|
pagewidth: { type: "number" }, |
|
|
parskipfac: { type: "number", optional: true }, |
|
|
partsbox: { type: "boolean", optional: true }, |
|
|
partsfont: fontType, |
|
|
partsspace: { type: "number", optional: true }, |
|
|
percmap: {type: 'object', optional: true, properties: percMapProps}, |
|
|
playtempo: { type: "string", optional: true }, |
|
|
repeatfont: fontType, |
|
|
rightmargin: { type: "number", optional: true }, |
|
|
scale: { type: "number", optional: true }, |
|
|
score: { type: "string", optional: true }, |
|
|
slurheight: { type: "number", optional: true }, |
|
|
splittune: { type: "boolean", optional: true }, |
|
|
squarebreve: { type: "boolean", optional: true }, |
|
|
staffsep: { type: "number", optional: true }, |
|
|
staffwidth: { type: "number", optional: true }, |
|
|
stemheight: { type: "number", optional: true }, |
|
|
straightflags: { type: "boolean", optional: true }, |
|
|
stretchlast: {type: "number", optional: true, minimum: 0, maximum: 1 }, |
|
|
stretchstaff: { type: "boolean", optional: true }, |
|
|
subtitlefont: fontType, |
|
|
subtitlespace: { type: "number", optional: true }, |
|
|
sysstaffsep: { type: "number", optional: true }, |
|
|
systemsep: { type: "number", optional: true }, |
|
|
stafftopmargin: { type: "number", optional: true }, |
|
|
tabgracefont: fontType, |
|
|
tablabelfont: fontType, |
|
|
tabnumberfont: fontType, |
|
|
tempofont: fontType, |
|
|
textfont: fontType, |
|
|
textspace: { type: "number", optional: true }, |
|
|
titlefont: fontType, |
|
|
titleformat: { type: "string", optional: true }, |
|
|
titleleft: { type: "boolean", optional: true }, |
|
|
titlespace: { type: "number", optional: true }, |
|
|
topmargin: { type: "number", optional: true }, |
|
|
topspace: { type: "number", optional: true }, |
|
|
tripletfont: fontType, |
|
|
vocalabove: { type: "boolean", optional: true }, |
|
|
vocalfont: fontType, |
|
|
vocalspace: { type: "number", optional: true }, |
|
|
voicefont: fontType, |
|
|
wordsfont: fontType, |
|
|
wordsspace: { type: "number", optional: true } |
|
|
} |
|
|
}; |
|
|
|
|
|
var addProhibits = function(obj, arr) { |
|
|
var ret = Object.assign({},obj); |
|
|
ret.prohibits = arr; |
|
|
return ret; |
|
|
}; |
|
|
|
|
|
var lineProperties = { |
|
|
type:"array", |
|
|
description: "This is an array of horizontal elements. It is usually a staff of music. For multi-stave music, each staff is an element, just like single-staff. The difference is the connector properties.", |
|
|
items: { type: "object", |
|
|
properties: { |
|
|
columns: { type: 'array', optional: true, |
|
|
items: { type: 'object', |
|
|
properties: { |
|
|
formatting: formattingProperties, |
|
|
lines: lineProperties |
|
|
} |
|
|
} |
|
|
}, |
|
|
image: { type: 'string', optional: true }, |
|
|
newpage: { type: 'number', optional: true }, |
|
|
staffbreak: { type: 'number', optional: true }, |
|
|
separator: { type: 'object', optional: true, prohibits: [ 'staff', 'text', 'subtitle' ], |
|
|
properties: { |
|
|
endChar: { type: 'number'}, |
|
|
lineLength: { type: 'number', optional: true }, |
|
|
spaceAbove: { type: 'number', optional: true }, |
|
|
spaceBelow: { type: 'number', optional: true }, |
|
|
startChar: { type: 'number'} |
|
|
} |
|
|
}, |
|
|
subtitle: { type: "object", optional: true, prohibits: [ 'staff', 'text', 'separator' ], |
|
|
properties: { |
|
|
endChar: { type: 'number'}, |
|
|
startChar: { type: 'number'}, |
|
|
text: { type: 'string'} |
|
|
} |
|
|
}, |
|
|
text: { type: "object", optional: true, prohibits: [ 'staff', 'subtitle', 'separator' ], |
|
|
properties: { |
|
|
endChar: { type: 'number'}, |
|
|
startChar: { type: 'number'}, |
|
|
text: textFieldProperties |
|
|
} |
|
|
}, |
|
|
staff: { type: 'array', optional: true, prohibits: [ 'subtitle', 'text', 'separator' ], |
|
|
items: { type: 'object', |
|
|
properties: { |
|
|
barNumber: { type: 'number', optional: true }, |
|
|
brace: { type: 'string', optional: true, Enum: [ "start", "continue", "end" ] }, |
|
|
bracket: { type: 'string', optional: true, Enum: [ "start", "continue", "end" ] }, |
|
|
clef: { type: 'object', optional: true, properties: clefProperties }, |
|
|
connectBarLines: { type: 'string', optional: true, Enum: [ "start", "continue", "end" ] }, |
|
|
gchordfont: fontType, |
|
|
tripletfont: fontType, |
|
|
vocalfont: fontType, |
|
|
key: { type: 'object', optional: true, properties: keyProperties }, |
|
|
meter: { type: 'object', optional: true, properties: meterProperties }, |
|
|
spacingAbove: { type: 'number', optional: true }, |
|
|
spacingBelow: { type: 'number', optional: true }, |
|
|
stafflines: { type: 'number', optional: true, minimum: 0, maximum: 10 }, |
|
|
staffscale: { type: 'number', minimum: 0.5, maximum: 3, optional: true }, |
|
|
title: { type: 'array', optional: true, items: { type: 'string' } }, |
|
|
voices: { type: 'array', output: 'hidden', |
|
|
items: { |
|
|
type: "array", optional: true, output: "noindex", |
|
|
items: voiceItem |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}, |
|
|
vskip: { type: 'number', optional: true } |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
var musicSchema = { |
|
|
description:"ABC Internal Music Representation", |
|
|
type:"object", |
|
|
properties: { |
|
|
version: { type: "string", Enum: [ "1.1.0" ] }, |
|
|
media: { type: "string", Enum: [ "screen", "print" ] }, |
|
|
|
|
|
formatting: formattingProperties, |
|
|
lines: lineProperties, |
|
|
|
|
|
metaText: {type:"object", |
|
|
description: "There can only be one of these per tune", |
|
|
properties: { |
|
|
"abc-copyright": { type: "string", optional: true }, |
|
|
"abc-creator": { type: "string", optional: true }, |
|
|
"abc-version": { type: "string", optional: true }, |
|
|
"abc-charset": { type: "string", optional: true }, |
|
|
"abc-edited-by": { type: "string", optional: true }, |
|
|
author: { type: "string", optional: true }, |
|
|
book: { type: "string", optional: true }, |
|
|
composer: { type: "string", optional: true }, |
|
|
decorationPlacement: { type: '', Enum: [ 'above', 'below' ], optional: true }, |
|
|
discography: { type: "string", optional: true }, |
|
|
footer: { type: 'object', optional: true, |
|
|
properties: { |
|
|
left: { type: 'string' }, |
|
|
center: { type: 'string' }, |
|
|
right: { type: 'string' } |
|
|
} |
|
|
}, |
|
|
group: { type: "string", optional: true }, |
|
|
header: { type: 'object', optional: true, |
|
|
properties: { |
|
|
left: { type: 'string' }, |
|
|
center: { type: 'string' }, |
|
|
right: { type: 'string' } |
|
|
} |
|
|
}, |
|
|
history: { type: "string", optional: true }, |
|
|
instruction: { type: "string", optional: true }, |
|
|
measurebox: { type: 'boolean', Enum: [ true ], optional: true }, |
|
|
notes: { type: "string", optional: true }, |
|
|
origin: { type: "string", optional: true }, |
|
|
partOrder: { type: "string", optional: true }, |
|
|
rhythm: { type: "string", optional: true }, |
|
|
source: { type: "string", optional: true }, |
|
|
tempo: { type: "object", optional: true, properties: tempoProperties }, |
|
|
textBlock: { type: "string", optional: true }, |
|
|
title: { type: "string", optional: true }, |
|
|
transcription: { type: "string", optional: true }, |
|
|
unalignedWords: { type: 'array', optional: true, items: textFieldProperties }, |
|
|
url: { type: "string", optional: true } |
|
|
} |
|
|
}, |
|
|
metaTextInfo: {type:"object", |
|
|
description: "There can only be one of these per tune", |
|
|
properties: { |
|
|
"abc-copyright": { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
"abc-creator": { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
"abc-version": { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
"abc-charset": { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
"abc-edited-by": { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
author: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
book: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
composer: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
discography: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
footer: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
group: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
header: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
history: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
instruction: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
notes: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
origin: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
partOrder: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
rhythm: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
source: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
tempo: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
textBlock: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
title: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
transcription: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
unalignedWords: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
url: { type: "object", optional: true, properties: { startChar: { type: "number"}, endChar: { type: "number"}, } }, |
|
|
} |
|
|
}, |
|
|
} |
|
|
}; |
|
|
|
|
|
this.lint = function(tune, warnings) { |
|
|
var ret = JSONSchema.validate(tune, musicSchema); |
|
|
var err = ""; |
|
|
ret.errors.forEach(function(e) { |
|
|
err += e.property + ": " + e.message + "\n"; |
|
|
}); |
|
|
var out = ret.output.join("\n"); |
|
|
|
|
|
var warn = warnings === undefined ? "No errors" : warnings.join('\n'); |
|
|
warn = warn.replace(/<span style="text-decoration:underline;font-size:1.3em;font-weight:bold;">/g, '$$$$$$$$'); |
|
|
warn = warn.replace(/<\/span>/g, '$$$$$$$$'); |
|
|
return "Error:------\n" + err + "\nObj:-------\n" + out + "\nWarn:------\n" + warn; |
|
|
}; |
|
|
}; |
|
|
|
|
|
module.exports = ParserLint; |
|
|
|