mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 11:14:00 +00:00
Better error propagation
This commit is contained in:
parent
2ac1ed067c
commit
d530d4ae38
|
@ -3,45 +3,20 @@
|
|||
# VLLilypondType.reader - Import lilypond files
|
||||
#
|
||||
|
||||
DEBUG = false
|
||||
|
||||
require File.dirname($0)+'/plistWriter'
|
||||
require File.dirname($0)+'/vl'
|
||||
|
||||
OUTPUT = {'measures' => []}
|
||||
|
||||
#
|
||||
# Lex
|
||||
#
|
||||
tokens = []
|
||||
INFILE.each do |line|
|
||||
line.chomp!.sub!(/%.*/, "")
|
||||
line.scan(%r$\G\s*(\{|\}|\(|\)|\||=|~|<<|>>|--|#'|#\(|##t|##f|\\\w+|\".*?\"|\w[-+\w\d.',:*/]+|.)$) do |token|
|
||||
tokens.push(token[0])
|
||||
end
|
||||
end
|
||||
#
|
||||
# Parse
|
||||
#
|
||||
nestLevel = 0
|
||||
block = nil
|
||||
level = -1
|
||||
stack = []
|
||||
repeats = []
|
||||
chords = []
|
||||
notes = []
|
||||
lyrics = []
|
||||
stanzas = []
|
||||
lastDur = 1
|
||||
tied = false
|
||||
repeat = 0
|
||||
timeNum = 4
|
||||
timeDenom = 4
|
||||
key = 0
|
||||
mode = 'minor'
|
||||
lyricFlags= 0
|
||||
CHORDS = []
|
||||
NOTES = []
|
||||
STANZAS= []
|
||||
MEAS = []
|
||||
|
||||
$RELPITCH = 0
|
||||
$timeNum = 4
|
||||
$timeDenom= 4
|
||||
$key = 0
|
||||
$mode = '\major'
|
||||
|
||||
PITCH = {
|
||||
?c => 0,
|
||||
|
@ -202,7 +177,32 @@ def lySteps(steps)
|
|||
return s
|
||||
end
|
||||
|
||||
while tokens.length > 0
|
||||
def parseLilypond
|
||||
#
|
||||
# Lex
|
||||
#
|
||||
tokens = []
|
||||
INFILE.each do |line|
|
||||
line.chomp!.sub!(/%.*/, "")
|
||||
line.scan(%r$\G\s*(\{|\}|\(|\)|\||=|~|<<|>>|--|#'|#\(|##t|##f|\\\w+|\".*?\"|\w[-+\w\d.',:*/]+|.)$) do |token|
|
||||
tokens.push(token[0])
|
||||
end
|
||||
end
|
||||
#
|
||||
# Parse
|
||||
#
|
||||
nestLevel = 0
|
||||
block = nil
|
||||
level = -1
|
||||
stack = []
|
||||
repeats = []
|
||||
lyrics = []
|
||||
lastDur = 1
|
||||
tied = false
|
||||
repeat = 0
|
||||
lyricFlags= 0
|
||||
|
||||
while tokens.length > 0
|
||||
token = tokens.shift
|
||||
#
|
||||
# Title, composer, etc.
|
||||
|
@ -249,8 +249,8 @@ while tokens.length > 0
|
|||
|
||||
chord = {'pitch' => pitch, 'root' => root, 'steps' => ext,
|
||||
'durNum'=> d[0], 'durDenom' => d[1]}
|
||||
p token, chord if DEBUG
|
||||
chords.push(chord)
|
||||
p token, chord if $DEBUG
|
||||
CHORDS.push(chord)
|
||||
redo
|
||||
end
|
||||
when 'voice'
|
||||
|
@ -273,12 +273,12 @@ while tokens.length > 0
|
|||
|
||||
note = {'pitch' => pitch, 'durNum'=> d[0], 'durDenom' => d[1]}
|
||||
note['tied'] = VL::TiedWithPrev if tied
|
||||
p token, note if DEBUG
|
||||
notes.push(note)
|
||||
p token, note if $DEBUG
|
||||
NOTES.push(note)
|
||||
tied = false
|
||||
redo
|
||||
elsif token == '~'
|
||||
if note = notes.last
|
||||
if note = NOTES.last
|
||||
note['tied'] ||= 0
|
||||
note['tied'] |= VL::TiedWithNext
|
||||
end
|
||||
|
@ -289,7 +289,7 @@ while tokens.length > 0
|
|||
level = nestLevel
|
||||
repeats.push(repeat)
|
||||
repeat = tokens[1].to_i
|
||||
notes.push({'begin-repeat' => true, 'times' => repeat})
|
||||
NOTES.push({'begin-repeat' => true, 'times' => repeat})
|
||||
tokens[0..1] = nil
|
||||
redo
|
||||
elsif token == '\alternative'
|
||||
|
@ -298,7 +298,7 @@ while tokens.length > 0
|
|||
level = nestLevel+1
|
||||
voltas = 0
|
||||
curVoltas = nil
|
||||
notes.push({'begin-ending' => true})
|
||||
NOTES.push({'begin-ending' => true})
|
||||
elsif token == '\times' && tokens[0] =~ %r|^(\d+)/(\d+)|
|
||||
$timesNum = $1.to_i
|
||||
$timesDen = $2.to_i
|
||||
|
@ -310,22 +310,22 @@ while tokens.length > 0
|
|||
lyrics.last[1] |= VL::TiedWithNext if lyrics.size > 0
|
||||
lyricFlags = VL::TiedWithPrev
|
||||
elsif token == '\skip'
|
||||
p ["", 0] if DEBUG
|
||||
p ["", 0] if $DEBUG
|
||||
lyrics.push ["", 0]
|
||||
lyricFlags = 0
|
||||
if tokens[0] =~ /\d+/
|
||||
tokens[0..0] = nil
|
||||
end
|
||||
elsif token =~ /\\skip\d+/
|
||||
p ["", 0] if DEBUG
|
||||
p ["", 0] if $DEBUG
|
||||
lyrics.push ["", 0]
|
||||
lyricFlags = 0
|
||||
elsif token =~ /"(.*)"/
|
||||
p [$1, lyricFlags] if DEBUG
|
||||
p [$1, lyricFlags] if $DEBUG
|
||||
lyrics.push [$1, lyricFlags]
|
||||
lyricFlags = 0
|
||||
elsif token =~ /^\w.*/
|
||||
p [token, lyricFlags] if DEBUG
|
||||
p [token, lyricFlags] if $DEBUG
|
||||
lyrics.push [token, lyricFlags]
|
||||
lyricFlags = 0
|
||||
end
|
||||
|
@ -350,7 +350,7 @@ while tokens.length > 0
|
|||
end
|
||||
if type == "repeat"
|
||||
if tokens[0] != '\alternative'
|
||||
notes.push({'end-repeat' => true})
|
||||
NOTES.push({'end-repeat' => true})
|
||||
repeat = repeats.pop
|
||||
end
|
||||
elsif type == "endings"
|
||||
|
@ -363,14 +363,14 @@ while tokens.length > 0
|
|||
curVoltas <<= 1
|
||||
end
|
||||
end
|
||||
notes.push({'end-ending' => true, 'volta' => curVoltas,
|
||||
NOTES.push({'end-ending' => true, 'volta' => curVoltas,
|
||||
'last'=>last})
|
||||
voltas |= curVoltas
|
||||
curVoltas = 0
|
||||
if last
|
||||
repeat = repeats.pop
|
||||
else
|
||||
notes.push({'begin-ending' => true})
|
||||
NOTES.push({'begin-ending' => true})
|
||||
stack.push([block, level, "endings"])
|
||||
level = nestLevel
|
||||
end
|
||||
|
@ -383,7 +383,7 @@ while tokens.length > 0
|
|||
stack.push([block, level, ""])
|
||||
block = token
|
||||
level = nestLevel
|
||||
stanzas.push(lyrics= []) if block == '\lyricmode'
|
||||
STANZAS.push(lyrics= []) if block == '\lyricmode'
|
||||
when '\chordmode'
|
||||
stack.push([block, level, ""])
|
||||
block = '\chords'
|
||||
|
@ -395,7 +395,7 @@ while tokens.length > 0
|
|||
stack.push([block, level, ""])
|
||||
block = '\lyricmode'
|
||||
level = nestLevel
|
||||
stanzas.push(lyrics= [])
|
||||
STANZAS.push(lyrics= [])
|
||||
tokens[0..0] = nil
|
||||
end
|
||||
when '\relative'
|
||||
|
@ -410,8 +410,8 @@ while tokens.length > 0
|
|||
level = nestLevel
|
||||
when '\time'
|
||||
if tokens[0] =~ %r{(\d+)/(\d+)}
|
||||
timeNum = $1.to_i
|
||||
timeDenom = $2.to_i
|
||||
$timeNum = $1.to_i
|
||||
$timeDenom = $2.to_i
|
||||
tokens[0..0] = nil
|
||||
end
|
||||
if block != 'voice'
|
||||
|
@ -421,8 +421,8 @@ while tokens.length > 0
|
|||
end
|
||||
when '\key'
|
||||
p = lyPitch(tokens[0], 0)
|
||||
mode = tokens[1]
|
||||
key = mode == '\minor' ? MINORKEY[p] : MAJORKEY[p]
|
||||
$mode = tokens[1]
|
||||
$key = $mode == '\minor' ? MINORKEY[p] : MAJORKEY[p]
|
||||
tokens[0..1] = nil
|
||||
if block != 'voice'
|
||||
stack.push([block, level, ""])
|
||||
|
@ -433,38 +433,39 @@ while tokens.length > 0
|
|||
tokens[0..1] = nil
|
||||
when '\alternative'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
measureLen = VL::Fract.new(timeNum, timeDenom)
|
||||
|
||||
#
|
||||
# Make measures
|
||||
#
|
||||
measCount= -1
|
||||
measures = []
|
||||
|
||||
def peek(where, what)
|
||||
return where.first && where.first[what]
|
||||
end
|
||||
|
||||
while notes.size > 0 || chords.size > 0
|
||||
def makeMeasures
|
||||
measureLen = VL::Fract.new($timeNum, $timeDenom)
|
||||
|
||||
#
|
||||
# Make measures
|
||||
#
|
||||
measCount= -1
|
||||
|
||||
while NOTES.size > 0 || CHORDS.size > 0
|
||||
measCount += 1
|
||||
meas = {}
|
||||
meas['measure'] = measCount
|
||||
meas['properties'] = 0
|
||||
if peek(notes, 'begin-repeat')
|
||||
rep = notes.shift
|
||||
if peek(NOTES, 'begin-repeat')
|
||||
rep = NOTES.shift
|
||||
meas['begin-repeat'] = {'times' => rep['times']}
|
||||
end
|
||||
if peek(notes, 'begin-ending')
|
||||
notes.shift
|
||||
if peek(NOTES, 'begin-ending')
|
||||
NOTES.shift
|
||||
meas['begin-ending'] = {}
|
||||
end
|
||||
if chords.size > 0
|
||||
if CHORDS.size > 0
|
||||
mchords = []
|
||||
len = VL::Fract.new(0, 1)
|
||||
while len < measureLen && chords.size > 0
|
||||
chord = chords.shift
|
||||
while len < measureLen && CHORDS.size > 0
|
||||
chord = CHORDS.shift
|
||||
chordLen = VL::Fract.new(chord['durNum'], chord['durDenom'])
|
||||
if len+chordLen > measureLen
|
||||
remLen = len+chordLen-measureLen
|
||||
|
@ -472,18 +473,18 @@ while notes.size > 0 || chords.size > 0
|
|||
remChord = chord.dup
|
||||
remChord['durNum'] = remLen.num
|
||||
remChord['durDenom'] = remLen.denom
|
||||
chords.unshift(remChord)
|
||||
CHORDS.unshift(remChord)
|
||||
end
|
||||
mchords.push(chord)
|
||||
len += chordLen
|
||||
end
|
||||
meas['chords'] = mchords
|
||||
end
|
||||
if notes.size > 0
|
||||
if NOTES.size > 0
|
||||
mnotes = []
|
||||
len = VL::Fract.new(0, 1)
|
||||
while len < measureLen && notes.size > 0
|
||||
note = notes.shift
|
||||
while len < measureLen && NOTES.size > 0
|
||||
note = NOTES.shift
|
||||
noteLen = VL::Fract.new(note['durNum'], note['durDenom'])
|
||||
if len+noteLen > measureLen
|
||||
remLen = len+noteLen-measureLen
|
||||
|
@ -493,14 +494,14 @@ while notes.size > 0 || chords.size > 0
|
|||
remNote['durDenom'] = remLen.denom
|
||||
remNote['tied'] = (remNote['tied'] || 0) | VL::TiedWithPrev
|
||||
note['tied'] = (note['tied'] || 0) | VL::TiedWithNext
|
||||
notes.unshift(remNote)
|
||||
NOTES.unshift(remNote)
|
||||
end
|
||||
if note['pitch'] != VL::NoPitch &&
|
||||
(!note['tied'] || (note['tied'] & VL::TiedWithPrev) == 0)
|
||||
ly = []
|
||||
stanza = 0
|
||||
stanzas.each_index do |i|
|
||||
lyrics = stanzas[i]
|
||||
STANZAS.each_index do |i|
|
||||
lyrics = STANZAS[i]
|
||||
if lyrics.size > 0
|
||||
stanza = i+1
|
||||
syll = lyrics.shift
|
||||
|
@ -519,26 +520,34 @@ while notes.size > 0 || chords.size > 0
|
|||
end
|
||||
meas['melody'] = mnotes
|
||||
end
|
||||
if peek(notes, 'end-ending')
|
||||
ending = notes.shift
|
||||
if peek(NOTES, 'end-ending')
|
||||
ending = NOTES.shift
|
||||
meas['end-ending'] = {'last' => ending['last'], 'volta' => ending['volta']}
|
||||
end
|
||||
if peek(notes, 'end-repeat')
|
||||
notes.shift
|
||||
if peek(NOTES, 'end-repeat')
|
||||
NOTES.shift
|
||||
meas['end-repeat'] = {}
|
||||
end
|
||||
measures.push(meas)
|
||||
MEAS.push(meas)
|
||||
end
|
||||
end
|
||||
|
||||
OUTPUT['measures'] = measures
|
||||
OUTPUT['properties'] = [{
|
||||
'key' => key,
|
||||
'mode' => mode == '\minor' ? -1 : 1,
|
||||
'timeNum' => timeNum,
|
||||
'timeDenom' => timeDenom
|
||||
}]
|
||||
begin
|
||||
parseLilypond
|
||||
makeMeasures
|
||||
|
||||
writePlist($stdout, OUTPUT)
|
||||
OUTPUT['measures'] = MEAS
|
||||
OUTPUT['properties'] = [{
|
||||
'key' => $key,
|
||||
'mode' => $mode == '\minor' ? -1 : 1,
|
||||
'timeNum' => $timeNum,
|
||||
'timeDenom' => $timeDenom
|
||||
}]
|
||||
|
||||
writePlist($stdout, OUTPUT)
|
||||
rescue => except
|
||||
$stderr.print except.message, "\n", except.backtrace.join("\n"), "\n"
|
||||
end
|
||||
|
||||
# Local Variables:
|
||||
# mode:ruby
|
||||
|
|
Loading…
Reference in New Issue
Block a user