X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scripts%2Fpmx2ly.py;h=1e3a26f0a0dd413c0e752e0dca049a1bae5c4a3d;hb=7437506ec4b53da278664cfc97f77acb3099166d;hp=b8d289b861612497507797b70ed512dd57e8dc3c;hpb=5d5ca8642dca9169ddf78949c41381e5f1380975;p=lilypond.git diff --git a/scripts/pmx2ly.py b/scripts/pmx2ly.py index b8d289b861..1e3a26f0a0 100644 --- a/scripts/pmx2ly.py +++ b/scripts/pmx2ly.py @@ -136,10 +136,11 @@ class Slur: if e and s: s.note_suffix = s.note_suffix + '(' - e.note_prefix = ')' + e.note_prefix + e.note_prefix = e.note_suffix + ')' else: sys.stderr.write ("\nOrphaned slur") - + + class Voice: def __init__ (self): self.entries = [] @@ -161,6 +162,7 @@ class Voice: def last_chord (self): return self.chords[-1] + def add_chord (self, ch): self.chords.append (ch) self.entries.append (ch) @@ -209,7 +211,13 @@ class Clef: def __init__ (self, cl): self.type = cl def dump(self): - return '\\clef %s;' % self.type + return '\\clef %s' % self.type + +class Key: + def __init__ (self, key): + self.type = key + def dump(self): + return '\\key %s' % self.type clef_table = { 'b':'bass' , @@ -220,7 +228,22 @@ clef_table = { 's':'soprano', 't':'treble', 'f':'frenchviolin', - } + } +key_table = { + '+0':'c \major', + '+1':'g \major', + '+2':'d \major', + '+3':'a \major', + '+4':'e \major', + '+5':'b \major', + '+6':'fis \major', + '-1':'f \major', + '-2':'bes \major', + '-3':'ees \major', + '-4':'aes \major', + '-5':'des \major', + '-6':'ges \major' + } class Staff: def __init__ (self): self.voices = (Voice (), Voice()) @@ -228,6 +251,7 @@ class Staff: self.instrument = 0 self.voice_idx = 0 self.number = None + self.key = 0 i = 0 for v in self.voices: @@ -235,9 +259,12 @@ class Staff: v.number = i i = i+1 def set_clef (self, letter): - clstr = clef_table[letter] - self.voices[0].add_nonchord (Clef (clstr)) - + if clef_table.has_key (letter): + clstr = clef_table[letter] + self.voices[0].add_nonchord (Clef (clstr)) + else: + sys.stderr.write ("Clef type `%c' unknown\n" % letter) + def current_voice (self): return self.voices[self.voice_idx] def next_voice (self): @@ -256,7 +283,7 @@ class Staff: str = str + v.dump() refs = refs + '\\' + v.idstring ()+ ' ' - str = str + '\n\n%s = \\context Staff = %s \n < \n %s >\n\n\n'% (self.idstring (), self.idstring (), refs) + str = str + '\n\n%s = \\context Staff = %s \n << \n %s >>\n\n\n'% (self.idstring (), self.idstring (), refs) return str class Tuplet: @@ -314,18 +341,18 @@ class Chord: for p in self.pitches: if str: str = str + ' ' - str = str + pitch_to_lily_string (p) + sd - - for s in self.scripts: - str = str + '-' + s + str = str + pitch_to_lily_string (p) - str = self.note_prefix +str + self.note_suffix - if len (self.pitches) > 1: str = '<%s>' % str elif len (self.pitches) == 0: - str = 'r' + sd + str = 'r' + + str = str + sd + for s in self.scripts: + str = str + '-' + s + str = self.note_prefix + str + self.note_suffix str = self.chord_prefix + str + self.chord_suffix return str @@ -407,7 +434,9 @@ class Parser: str = str[1:] else: ch = Chord () - self.current_voice().add_chord (ch) + self.current_voice().add_chord (ch) + + # what about 's'? if str[0] <> 'r': name = (ord (str[0]) - ord('a') + 5) % 7 @@ -529,47 +558,62 @@ Huh? expected duration, found %d Left was `%s'""" % (durdigit, str[:20])) str = str[1:] return str - + + def parse_key (self, str): + key = "" + #The key is changed by a string of the form K[+-][+-] + #where the first number is the transposition and the second number is the + #new key signature. For now, we won't bother with the transposition. + if str[2] != '0': + sys.stderr.write("Transposition not implemented yet: ") + while str[0] in '+-0123456789': + str = str[1:] + else: + str=str[3:] + key = '' + while str[0] in '+-0123456789': + key=key + str[0] + str=str[1:] + keystr = key_table[key] + self.current_voice().add_nonchord (Key(keystr)) + return(str) + def parse_header (self, ls): - while ls[0][0] == '%': - ls = ls[1:] + def atonum(a): + if re.search('\\.', a): + return string.atof (a) + else: + return string.atoi (a) - opening = ls[0] - ls = ls[1:] - - opening = re.sub ('^[ \t]+', '', opening) - opening = re.sub ('[ \t]+$', '', opening) - opening = re.split ('[\t ]+', opening) - - (no_staffs, no_instruments, timesig_num,timesig_den, ptimesig_num, - ptimesig_den, pickup_beats,keysig_number) = opening - (no_staffs, no_instruments, timesig_num, timesig_den, ptimesig_num, ptimesig_den, keysig_number) = tuple (map (string.atoi , [no_staffs, no_instruments, timesig_num, timesig_den, ptimesig_num, ptimesig_den, keysig_number])) - try: - pickup_beats = string.atoi (pickup_beats) - except ValueError: - pickup_beats = string.atof (pickup_beats) - + number_count = 12 + numbers = [] - while ls[0][0] == '%': + while len (numbers) < number_count: + opening = ls[0] ls = ls[1:] - - opening = ls[0] - ls = ls[1:] + + opening = re.sub ('[ \t\n]+', ' ', opening) + opening = re.sub ('^ ', '', opening) + opening = re.sub (' $', '', opening) + if opening == '': + continue + opening = string.split (opening, ' ') + + numbers = numbers + map (atonum, opening) + + (no_staffs, no_instruments, timesig_num, timesig_den, ptimesig_num, + esig_den, pickup_beats,keysig_number) = tuple (numbers[0:8]) + (no_pages,no_systems, musicsize, fracindent) = tuple (numbers[8:]) # ignore this. # opening = map (string.atoi, re.split ('[\t ]+', opening)) - # (no_pages,no_systems, musicsize, fracindent) = tuple (opening) - + instruments = [] while len (instruments) < no_instruments: instruments.append (ls[0]) ls = ls[1:] - - while ls[0][0] == '%': - ls = ls[1:] - l = ls[0] ls = ls[1:] @@ -580,9 +624,6 @@ Huh? expected duration, found %d Left was `%s'""" % (durdigit, str[:20])) l = l[1:] # dump path - while ls[0][0] == '%': - ls = ls[1:] - ls = ls[1:] # dump more ? @@ -689,6 +730,11 @@ Huh? expected duration, found %d Left was `%s'""" % (durdigit, str[:20])) left = self.parse_ornament (left) elif c == 'x': left = self.parsex (left) + elif c == 'C': + self.current_staff().set_clef(str(left[1])) + left = left[2:] + elif c == 'K': + left = self.parse_key (left) elif c in "[]": left = self.parse_beams (left) elif left[:2] == "//": @@ -714,16 +760,21 @@ Huh? Unknown directive `%s', before `%s'""" % (c, left[:20] )) str = str + s.dump () refs = '\\' + s.idstring() + refs - str = str + "\n\n\\score { <\n %s\n > }" % refs + str = str + "\n\n\\score { <<\n %s\n >> }" % refs return str def parse (self,fn): ls = open (fn).readlines () + def subst(s): + return re.sub ('%.*$', '', s) + + ls = map (subst, ls) + ls = filter (lambda x: x <> '\n', ls) ls = self.parse_header (ls) left = string.join (ls, ' ') - print left +# print left self.parse_body (left) for c in self.staffs: c.calculate () @@ -734,21 +785,22 @@ Huh? Unknown directive `%s', before `%s'""" % (c, left[:20] )) def help (): sys.stdout.write ( -"""Usage: pmx2ly [OPTION]... PMX-FILE +"""Usage: pmx2ly [OPTIONS]... PMX-FILE Convert PMX to LilyPond. Options: - -h, --help this help + -h, --help print this help -o, --output=FILE set output filename to FILE - -v, --version version information + -v, --version shown version information PMX is a Musixtex preprocessor written by Don Simons, see -http://www.gmd.de/Misc/Music/musixtex/software/pmx/ +http://www.gmd.de/Misc/Music/musixtex/software/pmx/. + +Report bugs to bug-lilypond@gnu.org. -Report bugs to bug-gnu-music@gnu.org. +Written by Han-Wen Nienhuys . -Written by Han-Wen Nienhuys """) @@ -759,7 +811,7 @@ This is free software. It is covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Invoke as `midi2ly --warranty' for more information. -Copyright (c) 2000 by Han-Wen Nienhuys +Copyright (c) 2000--2003 by Han-Wen Nienhuys """ % version) def identify(): sys.stderr.write ("%s from LilyPond %s\n" % (program_name, version))