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 = []
def last_chord (self):
return self.chords[-1]
+
def add_chord (self, ch):
self.chords.append (ch)
self.entries.append (ch)
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' ,
'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())
self.instrument = 0
self.voice_idx = 0
self.number = None
+ self.key = 0
i = 0
for v in self.voices:
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):
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:
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
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
str = str[1:]
return str
-
+
+ def parse_key (self, str):
+ key = ""
+ #The key is changed by a string of the form K[+-]<num>[+-]<num>
+ #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:]
l = l[1:]
# dump path
- while ls[0][0] == '%':
- ls = ls[1:]
-
ls = ls[1:]
# dump more ?
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] == "//":
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 ()
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 <hanwen@cs.uu.nl>.
-Written by Han-Wen Nienhuys <hanwen@cs.uu.nl>
""")
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 <hanwen@cs.uu.nl>
+Copyright (c) 2000--2003 by Han-Wen Nienhuys <hanwen@cs.uu.nl>
""" % version)
def identify():
sys.stderr.write ("%s from LilyPond %s\n" % (program_name, version))