]> git.donarmstrong.com Git - lilypond.git/commitdiff
(Module): remove.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Wed, 1 Mar 2006 22:57:26 +0000 (22:57 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Wed, 1 Mar 2006 22:57:26 +0000 (22:57 +0000)
scripts/mup2ly.py [deleted file]

diff --git a/scripts/mup2ly.py b/scripts/mup2ly.py
deleted file mode 100644 (file)
index def6830..0000000
+++ /dev/null
@@ -1,1295 +0,0 @@
-#!@PYTHON@
-# mup2ly.py -- mup input converter
-# 
-# source file of the GNU LilyPond music typesetter
-#
-# (c) 2001
-
-'''
-TODO:
-   LOTS: we get all notes out now, rest after 1.4
-
-   * lyrics (partly done)
-   * bars
-   * slurs,ties
-   * staff settings
-   * tuplets
-   * grace
-   * ornaments
-   * midi settings
-   * titling
-   * chords entry mode
-   * repeats, percent repeats
-   
-'''
-
-import os
-import fnmatch
-import stat
-import string
-import re
-import getopt
-import sys
-import __main__
-import operator
-import tempfile
-
-
-# if set, LILYPONDPREFIX must take prevalence
-# if datadir is not set, we're doing a build and LILYPONDPREFIX 
-datadir = '@local_lilypond_datadir@'
-if os.environ.has_key ('LILYPONDPREFIX') \
-   or '@local_lilypond_datadir@' == '@' + 'local_lilypond_datadir' + '@':
-       datadir = os.environ['LILYPONDPREFIX']
-else:
-       datadir = '@local_lilypond_datadir@'
-
-sys.path.append (os.path.join (datadir, 'python'))
-sys.path.append (os.path.join (datadir, 'python/out'))
-
-program_name = sys.argv[0]
-program_version = '@TOPLEVEL_VERSION@'
-original_dir = os.getcwd ()
-temp_dir = os.path.join (original_dir,  '%s.dir' % program_name)
-errorport = sys.stderr
-keep_temp_dir_p = 0
-verbose_p = 0
-
-localedir = '@localedir@'
-try:
-       import gettext
-       gettext.bindtextdomain ('lilypond', localedir)
-       gettext.textdomain ('lilypond')
-       _ = gettext.gettext
-except:
-       def _ (s):
-               return s
-
-
-program_name = 'mup2ly'
-help_summary = _ ("Convert mup to LilyPond source.")
-
-option_definitions = [
-       ('', 'd', 'debug', _ ("debug")),
-       ('NAME[=EXP]', 'D', 'define', _ ("define macro NAME [optional expansion EXP]")),
-       ('', 'h', 'help', _ ("print this help")),
-       ('FILE', 'o', 'output', _ ("write output to FILE")),
-       ('', 'E', 'pre-process', _ ("only pre-process")),
-       ('', 'V', 'verbose', _ ("be verbose")),
-       ('', 'v', 'version', _ ("print version number")),
-       ('', 'w', 'warranty', _ ("show warranty and copyright")),
-       ]
-
-
-################################################################
-# lilylib.py -- options and stuff
-# 
-# source file of the GNU LilyPond music typesetter
-
-try:
-       import gettext
-       gettext.bindtextdomain ('lilypond', localedir)
-       gettext.textdomain ('lilypond')
-       _ = gettext.gettext
-except:
-       def _ (s):
-               return s
-
-program_version = '@TOPLEVEL_VERSION@'
-if program_version == '@' + 'TOPLEVEL_VERSION' + '@':
-       program_version = '1.5.54'
-
-def identify ():
-       sys.stdout.write ('%s (GNU LilyPond) %s\n' % (program_name, program_version))
-
-def warranty ():
-       identify ()
-       sys.stdout.write ('\n')
-       sys.stdout.write (_ ('Copyright (c) %s by') % '2001--2006')
-       sys.stdout.write ('\n')
-       sys.stdout.write ('  Han-Wen Nienhuys')
-       sys.stdout.write ('  Jan Nieuwenhuizen')
-       sys.stdout.write ('\n\n')
-       sys.stdout.write (_ ("Distributed under terms of the GNU General Public License."))
-       sys.stdout.write (_ ("It comes with NO WARRANTY."))
-       sys.stdout.write ('\n')
-
-def progress (s):
-       errorport.write (s + '\n')
-
-def warning (s):
-       progress (_ ("warning: ") + s)
-
-def user_error (s, e=1):
-       errorport.write (program_name + ":" + _ ("error: ") + s + '\n')
-       sys.exit (e)
-       
-def error (s):
-       '''Report the error S.  Exit by raising an exception. Please
-       do not abuse by trying to catch this error. If you do not want
-       a stack trace, write to the output directly.
-
-       RETURN VALUE
-
-       None
-       
-       '''
-       
-       progress (_ ("error: ") + s)
-       raise _ ("Exiting ... ")
-
-def getopt_args (opts):
-       '''Construct arguments (LONG, SHORT) for getopt from  list of options.'''
-       short = ''
-       long = []
-       for o in opts:
-               if o[1]:
-                       short = short + o[1]
-                       if o[0]:
-                               short = short + ':'
-               if o[2]:
-                       l = o[2]
-                       if o[0]:
-                               l = l + '='
-                       long.append (l)
-       return (short, long)
-
-def option_help_str (o):
-       '''Transform one option description (4-tuple ) into neatly formatted string'''
-       sh = '  '       
-       if o[1]:
-               sh = '-%s' % o[1]
-
-       sep = '  '
-       if o[1] and o[2]:
-               sep = ', '
-               
-       long = ''
-       if o[2]:
-               long= '--%s' % o[2]
-
-       arg = ''
-       if o[0]:
-               if o[2]:
-                       arg = '='
-               arg = arg + o[0]
-       return '  ' + sh + sep + long + arg
-
-
-def options_help_str (opts):
-       '''Convert a list of options into a neatly formatted string'''
-       w = 0
-       strs =[]
-       helps = []
-
-       for o in opts:
-               s = option_help_str (o)
-               strs.append ((s, o[3]))
-               if len (s) > w:
-                       w = len (s)
-
-       str = ''
-       for s in strs:
-               str = str + '%s%s%s\n' % (s[0], ' ' * (w - len(s[0])  + 3), s[1])
-       return str
-
-def help ():
-       ls = [(_ ("Usage: %s [OPTIONS]... FILE") % program_name),
-             ('\n\n'),
-             (help_summary),
-             ('\n\n'),
-             (_ ("Options:")),
-             ('\n'),
-             (options_help_str (option_definitions)),
-             ('\n\n'),
-             (_ ("Report bugs to %s.") %
-             "http://post.gmane.org/post.php?group=gmane.comp.gnu.lilypond.bugs"),
-             ('\n')]
-       map (sys.stdout.write, ls)
-       
-def setup_temp ():
-       """
-       Create a temporary directory, and return its name.
-       """
-       
-       global temp_dir
-       if not keep_temp_dir_p:
-               temp_dir = tempfile.mktemp (program_name)
-       try:
-               os.mkdir (temp_dir, 0777)
-       except OSError:
-               pass
-
-       return temp_dir
-
-
-def system (cmd, ignore_error = 0, quiet =0):
-       """Run CMD. If IGNORE_ERROR is set, don't complain when CMD returns non zero.
-
-       RETURN VALUE
-
-       Exit status of CMD
-       """
-       
-       if verbose_p:
-               progress (_ ("Invoking `%s\'") % cmd)
-
-       st = os.system (cmd)
-       if st:
-               name = re.match ('[ \t]*([^ \t]*)', cmd).group (1)
-               msg = name + ': ' + _ ("command exited with value %d") % st
-               if ignore_error:
-                       if not quiet:
-                               warning (msg + ' ' + _ ("(ignored)") + ' ')
-               else:
-                       error (msg)
-
-       return st
-
-
-def cleanup_temp ():
-       if not keep_temp_dir_p:
-               if verbose_p:
-                       progress (_ ("Cleaning %s...") % temp_dir)
-               shutil.rmtree (temp_dir)
-
-
-def strip_extension (f, ext):
-       (p, e) = os.path.splitext (f)
-       if e == ext:
-               e = ''
-       return p + e
-
-
-def cp_to_dir (pattern, dir):
-       "Copy files matching re PATTERN from cwd to DIR"
-       # Duh.  Python style portable: cp *.EXT OUTDIR
-       # system ('cp *.%s %s' % (ext, outdir), 1)
-       files = filter (lambda x, p=pattern: re.match (p, x), os.listdir ('.'))
-       map (lambda x, d=dir: shutil.copy2 (x, os.path.join (d, x)), files)
-
-
-def mkdir_p (dir, mode=0777):
-       if not os.path.isdir (dir):
-               makedirs (dir, mode)
-
-
-# if set, LILYPONDPREFIX must take prevalence
-# if datadir is not set, we're doing a build and LILYPONDPREFIX 
-datadir = '@local_lilypond_datadir@'
-
-if os.environ.has_key ('LILYPONDPREFIX') :
-       datadir = os.environ['LILYPONDPREFIX']
-else:
-       datadir = '@local_lilypond_datadir@'
-
-
-while datadir[-1] == os.sep:
-       datadir= datadir[:-1]
-
-sys.path.insert (0, os.path.join (datadir, 'python'))
-
-################################################################
-# END Library
-
-
-output = 0
-
-#
-# PMX cut and paste
-#
-
-def encodeint (i):
-       return chr (i  + ord ('A'))
-
-       
-actab = {-2: 'eses', -1: 'es', 0 : '', 1: 'is', 2:'isis'}
-
-def pitch_to_lily_string (tup):
-       (o,n,a) = tup
-
-        nm = chr((n + 2) % 7 + ord ('a'))
-       nm = nm + actab[a]
-       if o > 0:
-               nm = nm + "'" * o
-       elif o < 0:
-               nm = nm + "," * -o
-       return nm
-
-def gcd (a,b):
-       if b == 0:
-               return a
-       c = a
-       while c: 
-               c = a % b
-               a = b
-               b = c
-       return a
-
-def rat_simplify (r):
-       (n,d) = r
-       if d < 0:
-               d = -d
-               n = -n
-       if n == 0:
-               return (0,1)
-       else:
-               g = gcd (n, d)
-               return (n/g, d/g)
-       
-def rat_multiply (a,b):
-       (x,y) = a
-       (p,q) = b
-
-       return rat_simplify ((x*p, y*q))
-
-def rat_divide (a,b):
-       (p,q) = b
-       return rat_multiply (a, (q,p))
-
-tuplet_table = {
-       2: 3,
-       3: 2,
-       5: 4
-}
-
-
-def rat_add (a,b):
-       (x,y) = a
-       (p,q) = b
-
-       return rat_simplify ((x*q + p*y, y*q))
-
-def rat_neg (a):
-       (p,q) = a
-       return (-p,q)
-
-
-def rat_larger (a,b):
-       return rat_subtract (a, b )[0] > 0
-
-def rat_subtract (a,b ):
-       return rat_add (a, rat_neg (b))
-
-def rat_to_duration (frac):
-       log = 1
-       d = (1,1)
-       while rat_larger (d, frac):
-               d = rat_multiply (d, (1,2))
-               log = log << 1
-
-       frac = rat_subtract (frac, d)
-       dots = 0
-       if frac == rat_multiply (d, (1,2)):
-               dots = 1
-       elif frac == rat_multiply (d, (3,4)):
-               dots = 2
-       return (log, dots)      
-
-
-class Barcheck :
-       def __init__ (self):
-               pass
-       def dump (self):
-               return '|\n'
-
-
-class Meter :
-       def __init__ (self,nums):
-               self.nums = nums
-       def dump (self):
-               return ' %{ FIXME: meter change %} '
-               
-class Beam:
-       def __init__ (self, ch):
-               self.char = ch
-       def dump (self):
-               return self.char
-
-class Slur:
-       def __init__ (self,id):
-               self.id = id
-               self.start_chord = None
-               self.end_chord = None
-               
-       def calculate (self):
-               s =self.start_chord
-               e= self.end_chord
-
-               if e and s:
-                       s.note_suffix = s.note_suffix + '-('
-                       e.note_prefix = e.note_suffix + "-)"
-               else:
-                       sys.stderr.write ("\nOrphaned slur")
-                       
-class Voice:
-       def __init__ (self, n):
-                self.number = n
-               self.entries = []
-               self.chords = []
-               self.staff = None
-               self.current_slurs = []
-               self.slurs = []
-                
-       def toggle_slur (self, id):
-               
-               for s in self.current_slurs:
-                       if s.id == id:
-                               self.current_slurs.remove (s)
-                               s.end_chord = self.chords[-1]
-                               return
-               s = Slur (id)
-               s.start_chord = self.chords[-1]
-               self.current_slurs.append (s)
-               self.slurs.append (s)
-               
-       def last_chord (self):
-                if len (self.chords):
-                        return self.chords[-1]
-                else:
-                        ch = Chord ()
-                        ch.basic_duration = 4
-                        return ch
-                
-       def add_chord (self, ch):
-               self.chords.append (ch)
-               self.entries.append (ch)
-                
-       def add_nonchord (self, nch):
-               self.entries.append (nch)
-
-       def idstring (self):
-               return 'staff%svoice%s ' % (encodeint (self.staff.number) , encodeint(self.number))
-        
-       def dump (self):
-               str = ''
-                #if not self.entries:
-                #        #return '\n'
-                #        #ugh ugh
-                #        return '\n%s = {}\n\n' % self.idstring ()
-                ln = '  '
-                one_two = ("One", "Two")
-                if self.staff.voices [1 - self.number].entries:
-                        ln = ln + '\\voice%s\n  ' % one_two[self.number]
-               for e in self.entries:
-                       next = e.dump ()
-                       if next[-1] == '\n':
-                               str  = str + ln + next + ' '
-                               ln = '  '
-                               continue
-                       
-                       if len (ln) +len (next) > 72:
-                               str = str+ ln + '\n'
-                               ln = '  '
-                       ln = ln + next + ' '
-                       
-                       
-               str = str  + ln
-               id = self.idstring ()
-                       
-               str = '''%s = \\context Voice = %s {
-%s
-}
-
-'''% (id, id, str)
-               return str
-        
-       def calculate_graces (self):
-               lastgr = 0
-               lastc = None
-               for c in self.chords:
-                       if c.grace and  not lastgr:
-                               c.chord_prefix = c.chord_prefix + '\\grace { '
-                       elif not c.grace and lastgr:
-                               lastc.chord_suffix = lastc.chord_suffix + ' } '
-                       lastgr = c.grace
-                       lastc = c
-                        
-       def calculate (self):
-               self.calculate_graces ()
-               for s in self.slurs:
-                       s.calculate ()
-
-class Clef:
-       def __init__ (self, cl):
-               self.type = cl
-               
-       def dump (self):
-               return '\\clef %s' % self.type
-
-key_sharps = ('c', 'g', 'd', 'a', 'e', 'b', 'fis')
-key_flats = ('BUG', 'f', 'bes', 'es', 'as', 'des', 'ges')
-
-class Key:
-       def __init__ (self, sharps, flats):
-               self.flats = flats
-               self.sharps = sharps
-               
-       def dump (self):
-               if self.sharps and self.flats:
-                       k = '\\keysignature %s ' % 'TODO'
-               elif self.sharps:
-                       k = '\\key %s \major' % key_sharps[self.sharps]
-               elif self.flats:
-                       k = '\\key %s \major' % key_flats[self.flats]
-               return k
-
-class Time:
-       def __init__ (self, frac):
-               self.frac = frac
-               
-       def dump (self):
-               return '\\time %d/%d' % (self.frac[0], self.frac[1])
-       
-
-clef_table = {
-       'b':'bass'  ,
-       'r':'baritone',
-       'n':'tenor',
-       'a':'alto',
-       'm':'mezzosoprano',
-       's':'soprano',
-       't':'treble',
-       'f':'frenchviolin',
-       }
-
-class Staff:
-       def __init__ (self, n):
-                # ugh
-               self.voices = (Voice (0), Voice (1))
-                
-               self.clef = None
-               self.time = None
-               self.key = None
-               self.instrument = 0
-               self.number = n
-               
-               i = 0
-               for v in self.voices:
-                       v.staff = self
-                       v.number = i
-                       i = i+1
-                        
-       #def set_clef (self, letter):
-       #       clstr = clef_table[letter]
-       #       self.voices[0].add_nonchord (Clef (clstr))
-               
-       def calculate (self):
-               for v in self.voices:
-                       v.calculate ()
-                        
-       def idstring (self):
-               return 'staff%s' % encodeint (self.number)
-
-       def dump (self):
-               str = ''
-
-               refs = ''
-               for v in self.voices:
-                       if v.entries:
-                               # urg
-                               if v == self.voices[0]:
-                                       if self.clef:
-                                               refs = refs + self.clef.dump ()
-                                       if self.time:
-                                               refs = refs + self.time.dump ()
-                                       if self.key:
-                                               refs = refs + self.key.dump ()
-                                       if refs:
-                                               refs = '\n  ' + refs
-                               str = str + v.dump()
-                               refs = refs + '\n  \\' + v.idstring ()
-               str = str + '''
-%s = \context Staff = %s <<%s
->>
-
-''' % (self.idstring (), self.idstring (), refs)
-               return str
-
-class Tuplet:
-       def __init__ (self, number, base, dots):
-               self.chords = []
-               self.number = number
-               self.replaces = tuplet_table[number]
-               self.base = base
-               self.dots = dots
-               
-               length = (1,base)
-               if dots == 1:
-                       length = rat_multiply (length, (3,2))
-               elif dots == 2:
-                       length = rat_multiply (length, (7,4))
-
-               length = rat_multiply (length, (1,self.replaces))
-
-               (nb,nd) =rat_to_duration (length)
-
-               self.note_base = nb
-               self.note_dots = nd
-
-       def add_chord (self, ch):
-               ch.dots = self.note_dots
-               ch.basic_duration = self.note_base
-               self.chords.append (ch)
-
-               if len (self.chords) == 1:
-                       ch.chord_prefix = '\\times %d/%d { ' % (self.replaces, self.number)
-               elif len (self.chords) == self.number:
-                       ch.chord_suffix = ' }' 
-               
-class Chord:
-       def __init__ (self):
-               self.pitches = []
-               self.multimeasure = 0
-               self.dots = 0
-               self.basic_duration = 0
-               self.scripts = []
-               self.grace = 0
-               self.chord_prefix = ''
-               self.chord_suffix = ''
-               self.note_prefix = ''
-               self.note_suffix = ''
-
-        # maybe use import copy?
-       def copy (self):
-               ch = Chord ()
-               #for i in self.pitches:
-               #       ch.pitches.append (i)
-               ch.pitches = self.pitches[:]
-               ch.multimeasure = self.multimeasure
-               ch.dots = self.dots
-               ch.basic_duration = self.basic_duration
-               #for i in self.scripts:
-               #       ch.scripts.append (i)
-               ch.scripts = self.scripts[:]
-               ch.grace = self.grace
-
-               ch.chord_prefix = self.chord_prefix
-               ch.chord_suffix = self.chord_suffix
-               ch.note_prefix = self.note_prefix
-               ch.note_suffix = self.note_suffix
-               return ch
-
-               
-       def dump (self):
-               str = ''
-
-               sd = ''
-               if self.basic_duration == 0.5:
-                       sd = '\\breve'
-               else:
-                       sd = '%d' % self.basic_duration
-               sd = sd + '.' * self.dots 
-               for p in self.pitches:
-                       if str:
-                               str = str + ' ' 
-                       str = str + pitch_to_lily_string (p)
-
-
-               str = self.note_prefix +str  + self.note_suffix
-               
-               if len (self.pitches) > 1:
-                       str = '<%s>' % str
-               elif self.multimeasure:
-                       str = 'R'
-               elif len (self.pitches) == 0:
-                       str = 'r'
-
-               str = str + sd
-               for s in self.scripts:
-                       str = str + '-' + s
-
-               str = self.chord_prefix + str + self.chord_suffix
-               
-               return str
-               
-SPACE=' \t\n'
-DIGITS ='0123456789'
-basicdur_table = {
-       9: 0.5,
-       0: 0 ,
-       2: 2 ,
-       4: 4 ,
-       8: 8 ,
-       1: 16,
-       3: 32,
-       6: 64
-       }
-
-
-ornament_table = {
-       't': '\\prall',
-       'm': '\\mordent',
-       'x': '"x"',
-       '+': '+',
-       'u': '"pizz"',
-       'p': '|',
-       '(': '"paren"',
-       ')': '"paren"',
-       'g': '"segno"',
-       '.': '.',
-       'fd': '\\fermata',
-       'f': '\\fermata',
-       '_': '-',
-       'T': '\\trill',
-       '>': '>',
-       '^': '^',
-       }
-
-# http://www.arkkra.com/doc/uguide/contexts.html
-
-contexts = (
-       'header', 
-       'footer', 
-       'header2', 
-       'footer2', 
-       'score', 
-       'staff',
-       'voice',
-       'grids', 
-       'music',
-       )
-
-class Parser:
-       def __init__ (self, lines):
-               self.parse_function = self.parse_context_music
-               self.staffs = []
-                self.current_voices = []
-               self.forced_duration = None
-               self.last_name = 0
-               self.last_oct = 0               
-               self.tuplets_expected = 0
-               self.tuplets = []
-               self.clef = None
-               self.time = None
-               self.key = None
-               
-               self.parse (lines)
-               
-        def parse_compound_location (self, line):
-               colon = string.index (line, ':')
-                s = line[:colon]
-                debug (s)
-                line = line[colon + 1:]
-                debug (line)
-                self.current_voices = []
-                ##self.current_staffs = []
-                map (self.parse_location, string.split (s, '&'))
-                return line
-
-        def parse_location (self, line):
-               m = re.match ('^([-,0-9]+) *([-,0-9]*)', string.lstrip (line))
-                
-                def range_list_to_idxs (s):
-                        
-                        # duh
-                        def flatten (l):
-                                f = []
-                                for i in l:
-                                        for j in i:
-                                                f.append (j)
-                                return f
-                                         
-                        def range_to_list (s):
-                                if string.find (s, '-') >= 0:
-                                        debug ('s: ' + s)
-                                        l = map (string.lstrip,
-                                                 string.split (s, '-'))
-                                        r = range (string.atoi (l[0]) - 1,
-                                                   string.atoi (l[1]))
-                                else:
-                                        r = (string.atoi (s) - 1,)
-                                return r
-                        
-                        ranges = string.split (s, ',')
-                        l = flatten (map (range_to_list, ranges))
-                        l.sort ()
-                        return l
-                
-                staff_idxs = range_list_to_idxs (m.group (1))
-                if m.group (2):
-                        voice_idxs = range_list_to_idxs (m.group (2))
-                else:
-                        voice_idxs = [0]
-                for s in staff_idxs:
-                        while s > len (self.staffs) - 1:
-                                self.staffs.append (Staff (s))
-                        for v in voice_idxs:
-                                self.current_voices.append (self.staffs[s].voices[v])
-                        
-       def parse_note (self, line):
-                # FIXME: 1?
-                oct = 1
-                name = (ord (line[0]) - ord ('a') + 5) % 7
-                # FIXME: does key play any role in this?
-               alteration = 0
-               debug ('NOTE: ' + `line`)
-                line = string.lstrip (line[1:])
-               while line:
-                        if len (line) > 1 and line[:2] == '//':
-                                line = 0
-                                break
-                       elif line[0] == '#':
-                               alteration = alteration + 1
-                       elif line[0] == '&':
-                               alteration = alteration - 1
-                       elif line[0] == '+':
-                                oct = oct + 1 
-                       elif line[0] == '-':
-                                oct = oct - 1
-                        else:
-                                skipping (line[0])
-                       line = string.lstrip (line[1:])
-               return (oct, name, alteration)
-                       
-       def parse_chord (self, line):
-               debug ('CHORD: ' + line)
-               line = string.lstrip (line)
-               ch = Chord ()
-               if not line:
-                       #ch = self.current_voices[0].last_chord ()
-                       ch = self.last_chord.copy ()
-               else:
-                       m = re.match ('^([0-9]+)([.]*)', line)
-                       if m:
-                               ch.basic_duration = string.atoi (m.group (1))
-                               line = line[len (m.group (1)):]
-                               if m.group (2):
-                                       ch.dots = len (m.group (2))
-                                       line = line[len (m.group (2)):]
-                        else:
-                                #ch.basic_duration = self.current_voices[0].last_chord ().basic_duration
-                                ch.basic_duration = self.last_chord.basic_duration
-                                
-                        line = string.lstrip (line)
-                        if len (line) > 1 and line[:2] == '//':
-                                line = 0
-                        #ugh
-                        if not line:
-                               debug ('nline: ' + line)
-                                #ch = self.current_voices[0].last_chord ()
-                               n = self.last_chord.copy ()
-                               n.basic_duration = ch.basic_duration
-                               n.dots = ch.dots
-                                ch = n
-                               debug ('ch.pitsen:' + `ch.pitches`)
-                               debug ('ch.dur:' + `ch.basic_duration`)
-                       else:
-                               debug ('eline: ' + line)
-                               
-                       while line:
-                                if len (line) > 1 and line[:2] == '//':
-                                        line = 0
-                                        break
-                                elif line[:1] == 'mr':
-                                       ch.multimeasure = 1
-                                        line = line[2:]
-                                elif line[:1] == 'ms':
-                                       ch.multimeasure = 1
-                                        line = line[2:]
-                               elif line[0] in 'rs':
-                                        line = line[1:]
-                                        pass
-                               elif line[0] in 'abcdefg':
-                                       m = re.match ('([a-g][-#&+]*)', line)
-                                       l = len (m.group (1))
-                                       pitch = self.parse_note (line[:l])
-                                        debug ('PITCH: ' + `pitch`)
-                                       ch.pitches.append (pitch)
-                                       line = line[l:]
-                                        break
-                               else:
-                                       skipping (line[0])
-                                       line = line[1:]
-                                line = string.lstrip (line)
-               debug ('CUR-VOICES: ' + `self.current_voices`)
-               map (lambda x, ch=ch: x.add_chord (ch), self.current_voices)
-               self.last_chord = ch
-
-       def parse_lyrics_location (self, line):
-               line = line.lstrip (line)
-               addition = 0
-               m = re.match ('^(between[ \t]+)', line)
-               if m:
-                       line = line[len (m.group (1)):]
-                       addition = 0.5
-               else:
-                       m = re.match ('^(above [ \t]+)', line)
-                       if m:
-                               line = line[len (m.group (1)):]
-                               addition = -0.5
-                       else:
-                               addlyrics = 1
-               
-       def parse_voice (self, line):
-               line = string.lstrip (line)
-               # `;' is not a separator, chords end with ';'
-               chords = string.split (line, ';')[:-1]
-               # mup resets default duration and pitch each bar
-               self.last_chord = Chord ()
-               self.last_chord.basic_duration = 4
-               map (self.parse_chord, chords)
-
-       def init_context_header (self, line):
-               self.parse_function = self.parse_context_header
-                                       
-       def parse_context_header (self, line):
-               debug ('header: ' + line)
-               skipping (line)
-               
-       def init_context_footer (self, line):
-               self.parse_function = self.parse_context_footer
-
-       def parse_context_footer (self, line):
-               debug ('footer: ' + line)
-               skipping (line)
-
-       def init_context_header2 (self, line):
-               self.parse_function = self.parse_context_header2
-
-       def parse_context_header2 (self, line):
-               debug ('header2: ' + line)
-               skipping (line)
-
-       def init_context_footer2 (self, line):
-               self.parse_function = self.parse_context_footer2
-
-       def parse_context_footer2 (self, line):
-               debug ('footer2: ' + line)
-               skipping (line)
-
-       def init_context_score (self, line):
-               self.parse_function = self.parse_context_score
-
-       def parse_context_score (self, line):
-               debug ('score: ' + line)
-               line = string.lstrip (line)
-               # ugh: these (and lots more) should also be parsed in
-               # context staff.  we should have a class Staff_properties
-               # and parse/set all those.
-               m = re.match ('^(time[ \t]*=[ \t]*([0-9]+)[ \t]*/[ \t]*([0-9]+))', line)
-               if m:
-                       line = line[len (m.group (1)):]
-                       self.time = Time ((string.atoi (m.group (2)),
-                                          string.atoi (m.group (3))))
-
-               m = re.match ('^(key[ \t]*=[ \t]*([0-9]+)[ \t]*(#|@))', line)
-               if m:
-                       line = line[len (m.group (1)):]
-                       n = string.atoi (m.group (2))
-                       if m.group (3) == '#':
-                               self.key = Key (n, 0)
-                       else:
-                               self.key = Key (0, n)
-               skipping (line)
-
-       def init_context_staff (self, line):
-               self.parse_function = self.parse_context_staff
-
-       def parse_context_staff (self, line):
-               debug ('staff: ' + line)
-               skipping (line)
-
-       def init_context_voice (self, line):
-               self.parse_function = self.parse_context_voice
-
-       def parse_context_voice (self, line):
-               debug ('voice: ' + line)
-               skipping (line)
-
-       def init_context_grids (self, line):
-               self.parse_function = self.parse_context_grids
-
-       def parse_context_grids (self, line):
-               debug ('grids: ' + line)
-               skipping (line)
-
-       def init_context_music (self, line):
-               self.parse_function = self.parse_context_music
-
-       def parse_context_music (self, line):
-               debug ('music: ' + line)
-                line = string.lstrip (line)
-                if line and line[0] in '0123456789':
-                        line = self.parse_compound_location (line)
-                        self.parse_voice (line)
-               else:
-                       m = re.match ('^(TODOlyrics[ \t]+)', line)
-                       if m:
-                               line = line[len (m.group (1)):]
-                               self.parse_lyrics_location (line[7:])
-                               self.parse_lyrics (line)
-                       else:
-                               skipping (line)
-
-       def parse (self, lines):
-               # shortcut: set to official mup maximum (duh)
-               # self.set_staffs (40)
-               for line in lines:
-                        debug ('LINE: ' + `line`)
-                       m = re.match ('^([a-z]+2?)', line)
-                       
-                       if m:
-                               word = m.group (1)
-                               if word in contexts:
-                                       eval ('self.init_context_%s (line)' % word)
-                                       continue
-                                else:
-                                        warning (_ ("no such context: %s") % word)
-                                        skipping (line)
-                       else:
-                                debug ('FUNC: ' + `self.parse_function`)
-                               self.parse_function (line)
-                               
-               for c in self.staffs:
-                       # hmm
-                       if not c.clef and self.clef:
-                               c.clef = self.clef
-                       if not c.time and self.time:
-                               c.time = self.time
-                       if not c.key and self.key:
-                               c.key = self.key
-                       c.calculate ()
-
-       def dump (self):
-               str = ''
-
-               refs = ''
-               for s in self.staffs:
-                       str = str +  s.dump ()
-                       refs = refs + '\n    \\' + s.idstring ()
-
-               str = str + '''
-
-\score {
-  <<%s
-  >>
-  \layout {}
-  \midi {}
-}
-''' % refs 
-               return str
-
-
-class Pre_processor:
-       def __init__ (self, raw_lines):
-               self.lines = []
-               self.active = [1]
-               self.process_function = self.process_line
-               self.macro_name = ''
-               self.macro_body = ''
-               self.process (raw_lines)
-
-       def process_line (self, line):
-               global macros
-               m = re.match ('^([ \t]*([a-zA-Z]+))', line)
-               s = line
-               if m:
-                       word = m.group (2)
-                       debug ('MACRO?: ' + `word`)
-                       if word in pre_processor_commands:
-                               line = line[len (m.group (1)):]
-                               eval ('self.process_macro_%s (line)' % word)
-                               s = ''
-                       else:
-                               if macros.has_key (word):
-                                       s = macros[word] + line[len (m.group (1)):]
-               if not self.active [-1]:
-                       s = ''
-               return s
-
-       def process_macro_body (self, line):
-               global macros
-               # dig this: mup allows ifdefs inside macro bodies
-               s = self.process_line (line)
-               m = re.match ('(.*[^\\\\])(@)(.*)', s)
-               if m:
-                       self.macro_body = self.macro_body + '\n' + m.group (1)
-                       macros[self.macro_name] = self.macro_body
-                       debug ('MACROS: ' + `macros`)
-                       # don't do nested multi-line defines
-                       self.process_function = self.process_line
-                       if m.group (3):
-                               s = m.group (3)
-                       else:
-                               s = ''
-               else:
-                       self.macro_body = self.macro_body + '\n' + s
-                       s = ''
-               return s
-
-       # duh: mup is strictly line-based, except for `define',
-       # which is `@' terminated and may span several lines
-       def process_macro_define (self, line):
-               global macros
-               # don't define new macros in unactive areas
-               if not self.active[-1]:
-                       return
-               m = re.match ('^[ \t]*([a-zA-Z][a-zA-Z1-9_]*)(([^@]*)|(\\\\@))(@)?', line)
-               n = m.group (1)
-               if m.group (5):
-                       if m.group (2):
-                               e = m.group (2)
-                       else:
-                               e = ''
-                       macros[n] = e
-                       debug ('MACROS: ' + `macros`)
-               else:
-                       # To support nested multi-line define's
-                       # process_function and macro_name, macro_body
-                       # should become lists (stacks)
-                       # The mup manual is undetermined on this
-                       # and I haven't seen examples doing it.
-                       #
-                       # don't do nested multi-line define's
-                       if m.group (2):
-                               self.macro_body = m.group (2)
-                       else:
-                               self.macro_body = ''
-                       self.macro_name = n
-                       self.process_function = self.process_macro_body
-               
-       def process_macro_ifdef (self, line):
-               m = re.match ('^[ \t]*([a-zA-Z][a-zA-Z1-9_]*)', line)
-               if m:
-                       
-                       active = self.active[-1] and macros.has_key (m.group (1))
-                       debug ('ACTIVE: %d' % active)
-                       self.active.append (active)
-
-       def process_macro_ifndef (self, line):
-               m = re.match ('^[ \t]*([a-zA-Z][a-zA-Z1-9_]*)', line)
-               if m:
-                       active = self.active[-1] and not macros.has_key (m.group (1))
-                       self.active.append (active)
-
-       def process_macro_else (self, line):
-               debug ('ELSE')
-               self.active[-1] = not self.active[-1]
-               
-       def process_macro_endif (self, line):
-               self.active = self.active[:-1]
-                       
-       def process (self, raw_lines):
-               s = ''
-               for line in raw_lines:
-                       ls = string.split (self.process_function (line), '\n')
-                       for i in ls:
-                               if i:
-                                       s = s + string.rstrip (i)
-                                       if s and s[-1] == '\\':
-                                               s = string.rstrip (s[:-1])
-                                       elif s:
-                                               self.lines.append (s)
-                                               s = ''
-
-
-debug_p = 0
-only_pre_process_p = 0
-def debug (s):
-        if debug_p:
-                progress ('DEBUG: ' + s)
-
-def skipping (s):
-       if verbose_p or debug_p:
-                progress ('SKIPPING: ' + s)
-
-(sh, long) = getopt_args (__main__.option_definitions)
-try:
-       (options, files) = getopt.getopt (sys.argv[1:], sh, long)
-except:
-       help ()
-       sys.exit (2)
-
-macros = {}
-pre_processor_commands = (
-       'define',
-       'else',
-       'endif',
-       'ifdef',
-       'ifndef',
-       )
-
-for opt in options:
-       o = opt[0]
-       a = opt[1]
-        if 0:
-                pass
-       elif o== '--debug' or o == '-d':
-                debug_p = 1
-       elif o== '--define' or o == '-D':
-               if string.find (a, '=') >= 0:
-                       (n, e) = string.split (a, '=')
-               else:
-                       n = a
-                       e = ''
-               macros[n] = e
-       elif o== '--pre-process' or o == '-E':
-               only_pre_process_p = 1
-       elif o== '--help' or o == '-h':
-               help ()
-               sys.exit (0)
-       elif o== '--verbose' or o == '-V':
-                verbose_p = 1
-       elif o == '--version' or o == '-v':
-               identify ()
-               sys.exit (0)
-       elif o == '--output' or o == '-o':
-               output = a
-       else:
-               print o
-               raise getopt.error
-
-# writes to stdout for help2man
-# don't call 
-# identify ()
-# sys.stdout.flush ()
-
-# handy emacs testing
-# if not files:
-#      files = ['template.mup']
-
-if not files:
-       files = ['-']
-       
-for f in files:
-       h = None
-       if f == '-':
-               h = sys.stdin
-       elif f and not os.path.isfile (f):
-               f = strip_extension (f, '.mup') + '.mup'
-               
-       h = open (f)
-       progress ( _("Processing `%s'..." % f))
-       raw_lines = h.readlines ()
-       p = Pre_processor (raw_lines)
-       if only_pre_process_p:
-               if not output:
-                       output = os.path.basename (re.sub ('(?i).mup$', '.mpp', f))
-       else:
-               e = Parser (p.lines)
-               if not output:
-                       output = os.path.basename (re.sub ('(?i).mup$', '.ly', f))
-               if output == f:
-                       output = os.path.basename (f + '.ly')
-                       
-       if f == '-':
-               output = '-'
-               out_h = sys.stdout
-       else:
-               out_h = open (output, 'w')
-
-       progress (_ ("Writing `%s'...") % output)
-
-       tag = '%% Lily was here -- automatically converted by %s from %s' % ( program_name, f)
-       if only_pre_process_p:
-               # duh
-               ly = string.join (p.lines, '\n')
-       else:
-               ly = tag + '\n\n' + e.dump ()
-
-       out_h.write (ly)
-       out_h.close ()
-       if debug_p:
-               print (ly)
-