]> git.donarmstrong.com Git - lilypond.git/blobdiff - scripts/mudela-book.py
release: 1.2.2
[lilypond.git] / scripts / mudela-book.py
index ce491b816e47380d3d2e9bc82aa003f77c97b1f1..0000a26aeabc04bb31fa7a63b35d824f22e81877 100644 (file)
-
-# python version of mudela-book.  WIP.
-
-#  TODO: center option
-
-# log:
-
-# 0.3:
-#   rewrite in Python.
+#!@PYTHON@
 
 import os
 import string
-import regex
+import re
 import getopt
 import sys
-import regsub
+import __main__
+
+outdir = 'out'
+initfile = ''
+program_version = '@TOPLEVEL_VERSION@'
+
+cwd = os.getcwd ()
+include_path = [cwd]
+
+# TODO: use splitting iso. \mudelagraphic.
+
+#
+default_music_fontsize = 16
+default_text_fontsize = 12
+
+# latex linewidths:
+# indices are no. of columns, papersize,  fontsize
+# Why can't this be calculated?
+latex_linewidths = {
+ 1: {'a4':{10: 345, 11: 360, 12: 390},
+        'a5':{10: 276, 11: 276, 12: 276},
+        'b5':{10: 345, 11: 356, 12: 356},
+        'letter':{10: 345, 11: 360, 12: 390},
+        'legal': {10: 345, 11: 360, 12: 390},
+        'executive':{10: 345, 11: 360, 12: 379}},
+ 2: {'a4':{10: 167, 11: 175, 12: 190},
+        'a5':{10: 133, 11: 133, 12: 133},
+        'b5':{10: 167, 11: 173, 12: 173},
+        'letter':{10: 167, 11: 175, 12: 190},
+        'legal':{10: 167, 11: 175, 12: 190},
+        'executive':{10: 167, 11: 175, 12: 184}}}
+
+
+options = [
+  ('', 'h', 'help', 'print help'),
+  ('EXT', 'f', 'format', 'set format.  EXT is one of texi and latex.'),
+  ('', 'v', 'version', 'print version information' ),
+  ('FILE', 'o', 'outname', 'prefix for filenames'),
+  ('DIM',  '', 'default-mudela-fontsize', 'default fontsize for music.  DIM is assumed to in points'),
+#  ('DIM', '', 'force-mudela-fontsize', 'force fontsize for all inline mudela. DIM is assumed to in points'),
+  ('', '', 'force-verbatim', 'make all mudela verbatim'),
+  ('', 'M', 'dependencies', 'write dependencies'),
+  ('DIR', 'I', 'include', 'include path'),
+  ('', '', 'init', 'mudela-book initfile')
+  ]
+
+format = 'latex'
+no_match = 'a\ba'
+
+# format specific strings, ie. regex-es for input, and % strings for output
+re_dict = {
+       'latex': {'input': '\\\\input{?([^}\t \n}]*)',
+                 'include': '\\\\include{([^}]+)}',
+                 'include-mudela':r"""\begin%s{mudela}
+%s
+\end{mudela}""",
+                 'header': r"""\\documentclass(\[.*?\])?""",
+                 'preamble-end': '\\\\begin{document}',
+                 'verbatim': r"""(?s)\\begin{verbatim}(.*?)\\end{verbatim}""",
+                 'verb': r"""\\verb(.)(.*?)\1""",
+                 'mudela-file': '\\\\mudelafile(\[[^\\]]+\])?{([^}]+)}',
+                 'mudela' : '\\\\mudela(\[.*?\])?{(.*?)}',
+                 'mudela-block': r"""(?s)\\begin(\[.*?\])?{mudela}(.*?)\\end{mudela}""",
+                 'interesting-cs': '\\\\(chapter|section|mudelagraphic|twocolumn|onecolumn)',
+                 'quote-verbatim': r"""\begin{verbatim}%s\end{verbatim}""",
+                 'def-post-re': r"""\\def\\postMudelaExample""",
+                 'def-pre-re': r"""\\def\\preMudelaExample""",           
+                 'default-post': r"""\def\postMudelaExample{}""",
+                 'default-pre': r"""\def\preMudelaExample{}""",
+                 'output-eps': '\\noindent\\parbox{\\mudelaepswidth{%s.eps}}{\includegraphics{%s.eps}}',
+                 'output-tex': '\\preMudelaExample \\input %s.tex \\postMudelaExample\n'
+                 },
+       'texi': {'input': '@include[ \n\t]+([^\t \n]*)',
+                'include': no_match,
+                'include-mudela': """@mudela[%s]
+%s
+@end mudela
+""",
+                'header': no_match,
+                'preamble-end': no_match,
+                'verbatim': r"""(?s)@example(.*?)@end example$""",
+                'verb': r"""@code{(.*?)}""",
+                'mudela-file': '@mudelafile(\[[^\\]]+\])?{([^}]+)}',
+                'mudela' : '@mudela(\[.*?\])?{(.*?)}',
+                'mudela-block': r"""(?s)@mudela(\[.*?\])?(.*?)@end mudela""",
+                'interesting-cs': r"""[\\@](node|mudelagraphic)""",
+                'quote-verbatim': r"""@example
+%s
+@end example""",
+                'output-all': r"""@tex
+\input %s.tex
+@end tex
+@html
+<img src=%s.png>
+@end html
+""",
+               }
+       }
+
+
+
+
+def get_re (name):
+       return  re_dict[format][name]
+
+
+def bounding_box_dimensions(fname):
+       try:
+               fd = open(fname)
+       except IOError:
+               error ("Error opening `%s'" % fname)
+       str = fd.read (-1)
+       s = re.search('%%BoundingBox: ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)', str)
+       if s:
+               return (int(s.group(3))-int(s.group(1)), 
+                       int(s.group(4))-int(s.group(2)))
+       else:
+               return (0,0)
+
+
+def find_file (name):
+       for a in include_path:
+               try:
+                       nm = os.path.join (a, name)
+                       f = open (nm)
+                       return nm
+               except IOError:
+                       pass
+       return ''
+
+def error (str):
+       sys.stderr.write (str + "\n  Exiting ... \n\n")
+       raise 'Exiting.'
+
+
+def compose_full_body (body, opts):
+       "Construct the text of an input file: add stuff to BODY using OPTS as options."
+       paper = 'a4'
+       music_size = default_music_fontsize
+       latex_size = default_text_fontsize
+
+       cols = 1
+       for o in opts:
+               m = re.search ('^(.*)paper$', o)
+               if m:
+                       paper = m.group (1)
+               
 
-outdir = 'out/'
-program_version = '0.3'
+               m = re.match ('([0-9]+)pt', o)
+               if m:
+                       music_size = string.atoi(m.group (1))
 
+               m = re.match ('latexfontsize=([0-9]+)pt', o)
+               if m:
+                       latex_size = string.atoi (m.group (1))
 
 
+       if 'twocolumn' in opts:
+               cols = 2
+               
+       if 'fragment' or 'singleline' in opts:
+               l = -1.0;
+       else:
+               l = latex_linewidths[cols][paper][latex_size]
 
-def file_exist_b(name):
-    try: 
-       f = open(name)
-    except IOError:
-       return 0
-    f.close ()
-    return 1
+       if not 'nofly' in opts and not re.search ('\\\\score', body):
+               opts.append ('fly')
 
-class CompileStatus:
-       pass
 
-def file_mtime (name):
-    return os.stat (name)[8] #mod time
+       if 'fly' in opts:
+               body = r"""\score { 
+  \notes\relative c {
+    %s
+  }
+  \paper { }  
+}""" % body
 
-def compile (command, infile, outfile):
-       indate = file_mtime (infile)
-       try:
-               outdate = file_mtime (outfile)
-               recompile = indate > outdate
+               
+       body = r"""
+%% Generated by mudela-book.py
+\include "paper%d.ly"
+\paper  { linewidth = %f \pt; } 
+""" % (music_size, l) + body
+
+       return body
+
+
+#
+# Petr, ik zou willen dat ik iets zinvoller deed,
+# maar wat ik kan ik doen, het verandert toch niets?
+#   --hwn 20/aug/99
+#
+
+
+def read_tex_file (filename):
+       """Read the input file, substituting for \input, \include, \mudela{} and \mudelafile"""
+       str = ''
+       for fn in [filename, filename+'.tex', filename+'.doc']:
+               try:
+                       f = open(fn)
+                       str = f.read (-1)
+               except:
+                       pass
+               
 
-       except os.error:
-               recompile = 1
+       if not str:
+               raise IOError
 
-       if recompile:
-               sys.stderr.write ('invoking `%s\'\n' % command)
-               
-               status = os.system (command)
-               if status:
-                       raise CompileStatus
+       retdeps =  [filename]
 
+       def inclusion_func (match, surround):
+               insert = match.group (0)
+               try:
+                       (insert, d) = read_tex_file (match.group(1))
+                       deps = deps + d
+                       insert = surround + insert + surround
+               except:
+                       sys.stderr.write("warning: can't find %s, let's hope latex will\n" % m.group(1))
 
-class Mudela_output:
-       def __init__ (self):
-               self.basename = ''
-               self.fragment = 0
-               self.size = 16
-               
-       def open (self, basename):
-               self.basename = basename
-               self.temp_file = "%s/%s" %(outdir, 'mudela-temp.ly')
-               self.file = open (self.temp_file, 'w')
-               self.file.write ('\\include \"paper%d.ly\"\n' % self.size)
-               if self.size == 16:
-                       s = 'sixteen'
+               return (insert, deps)
+       
+       def include_func (match, d = retdeps):
+               (s,d) = inclusion_func (match, '\\newpage ', retdeps)
+               retdeps = retdeps + d
+               return s
+
+       str = re.sub (get_re ('input'), include_func, str)
+
+       def input_func (match, d = retdeps):
+               (s,d) = inclusion_func (match, '', retdeps)
+               retdeps = retdeps + d
+               return s
+
+       str = re.sub (get_re ('include'), input_func, str)
+       
+       return (str, retdeps)
+
+def scan_preamble (str):
+       options = []
+       m = re.search (get_re ('header'), str)
+
+       # should extract paper & fontsz.
+       if m and m.group (1):
+               options = options + re.split (',[\n \t]*', m.group(1)[1:-1])
+
+       def verbose_fontsize ( x):
+               if o.match('[0-9]+pt'):
+                       return 'latexfontsize=' + x
                else:
-                       s = 'twenty'
+                       return x 
+                       
+       options = map (verbose_fontsize, options)
+
+       return options
 
-               self.file.write ('default_paper = \\paper { \\paper_%s\n linewidth = -15.\\cm; }\n' % s)
-               
-               if self.fragment:
-                       self.file.write ('\\score { \\melodic { ')
 
-       def write (self,s):
-               self.file.write (s)
+def completize_preamble (str):
+       m = re.search (get_re ('preamble-end'), str)
+       if not m:
+               return str
+       
+       preamble = str [:m.start (0)]
+       str = str [m.start(0):]
+       
+       if not re.search (get_re('def-post-re'), preamble):
+               preamble = preamble + get_re('default-post')
+       if not re.search (get_re ('def-pre-re'),  preamble):
+               preamble = preamble + get_re ('default-pre')
+
+       if  re.search ('\\\\includegraphics', str) and not re.search ('usepackage{graphics}',str):
+               preamble = preamble + '\\usepackage{graphics}\n'
+
+       return preamble + str
+       
+def find_mudela_sections (str):
+       """Find mudela blocks, while watching for verbatim. Returns
+       (STR,MUDS) with \mudelagraphic substituted for the blocks in STR,
+       and the blocks themselves MUDS"""
+       
+       mudelas = []
+       verbblocks = []
+       noverbblocks = []
 
-       def close (self):
-               if self.fragment:
-                       self.file.write (
-                               '}\n \\paper { linewidth = -1.0\\cm;\n' +
-                               'castingalgorithm = \\Wordwrap; } }\n')
+       while str:
+               m = re.search (get_re ('verbatim'), str)
+               m2 = re.search (get_re ("verb"), str)
 
+               if  m == None and m2 == None:
+                       noverbblocks.append (str)
+                       str = ''
+                       break
 
-               self.file.close ()
+               if m == None:
+                       m = m2
 
-               inf=self.basename + '.ly'
-               outf = self.basename + '.tex'           
-               if not file_exist_b (inf):
-                       status = 1
+               if m2 and m2.start (0) < m.start (0):
+                       m = m2
+                       
+               noverbblocks.append (str[:m.start (0)])
+               verbblocks.append (m.group (0))
+               str = str [m.end(0):]
+
+       def mudela_short (match):
+               "Find \mudela{}, and substitute appropriate \begin / \end blocks."
+               opts = match.group (1)
+               if opts:
+                       opts = ',' + opts[1:-1]
+               else:
+                       opts = ''
+               return r"""\begin[eps,fragment%s]{mudela}
+  \context Staff <
+    \context Voice{
+      %s
+    }
+  >
+\end{mudela}""" % (opts, match.group (2))
+
+       def mudela_file (match):
+               "Find \mudelafile, and substitute appropriate \begin / \end blocks."
+               d = [] #, d = retdeps
+               full_path = find_file (match.group (2))
+               if not full_path:
+                       error("error: can't find file `%s'\n" % match.group(2))
+
+               d.append (full_path)
+               f = open (full_path)
+               str = f.read (-1)
+               opts = match.group (1)
+               if opts:
+                       opts = re.split (',[ \n\t]*', opts[1:-1])
                else:
-#                      print 'invoking %s' %('diff %s %s' % (self.temp_file, inf))
-                       status = os.system ('diff -q %s %s' % (self.temp_file, inf))
-#                      print 'status %d' % status
+                       opts = []
+
+               if re.search ('.fly$', full_path):
+                       opts.append ('fly')
+               elif re.search ('.sly$', full_path):
+                       opts = opts + [ 'fly','fragment']
+               elif re.search ('.ly$', full_path):
+                       opts .append ('nofly')
+                       
+               str_opts = string.join (opts, ',')
+               if str_opts: str_opts = '[' + str_opts + ']'
+
+
+               str = "%% copied from %s" % full_path + str 
+               return get_re ('include-mudela') % (str_opts, str)
+
+
+       def find_one_mudela_block (match,muds =mudelas):
+               "extract body and options from a mudela block, and append into MUDELAS"
+               opts = match.group (1)
+               if opts:
+                       opts = opts[1:-1]
+               else:
+                       opts = ''
+                       
+               body = match.group (2)
+               optlist = re.split (', *', opts)
+               muds.append ((body, optlist))
+
+               return '\\mudelagraphic\n'#  UGH.
+
+       doneblocks = []
+       for b in noverbblocks:
+               b = re.sub (get_re('mudela-file'),  mudela_file, b)
+               b = re.sub (get_re('mudela'), mudela_short, b)
+               b = re.sub (get_re ("mudela-block"),  find_one_mudela_block, b)
+               doneblocks.append (b)
+
+       allblocks = []
+       verbblocks.append ('')
+       while doneblocks:
+               allblocks = allblocks + doneblocks[0:1] +  verbblocks[0:1]
+               verbblocks = verbblocks[1:]
+               doneblocks =doneblocks[1:]
+
+       str = string.join (allblocks,'')
+
+       return (str, mudelas)
+
+
+def eps_file_cs (base):
+       if format == 'latex':
+               return
+       els
+
+def tex_file_cs (base):
+       return 
 
-               if status:
-                       os.rename (self.temp_file, inf)
 
-               compile ('lilypond  -o %s %s'%  (self.basename, inf), inf, outf)
-#                      os.rename (self.basename + '.tex', outdir  +)
+
+
+def make_files (str, mudelas, filename):       
+       (chapter, section, count) = (0,0,0)
+       total = 0
+       done = ''
+
+       # number them.
+       numbering = []
+       current_opts = []
+       while str:
+               m = re.search (get_re ('interesting-cs'), str)
+               if not m:
+                       done = done + str
+                       str = ''
+                       break
                
+               done = done + str[:m.end (0)]
+               str = str[m.end(0):]
+               g = m.group (1)
+
+               if g == 'twocolumn':
+                       current_opts.append ('twocolumn')
+               elif g  == 'onecolumn':
+                       try:
+                               current_opts.remove ('twocolumn')
+                       except IndexError:
+                               pass
+               if g == 'mudelagraphic':
+                       numbering.append ((chapter, section, count, current_opts[:]))
+                       count = count + 1
+               elif g == 'chapter':
+                       (chapter, section, count)  = (chapter + 1, 0, 0)
+               elif g == 'section' or g == 'node':
+                       (section, count)  = (section + 1, 0)
+                       
+
+       todo = []
+       str = done
        
 
-class Tex_output:
-       def __init__ (self, name):
-               self.output_fn = '%s/%s' % (outdir, name)
-               self.mudela = 0
-               self.file = open (self.output_fn , 'w')
-               self.verbatim = 0               
-       def open_mudela (self, basename):
-
-               self.mudela_basename =basename
-               if self.verbatim:
-                       self.file.write ('\\begin{verbatim}\n')
-               self.mudela = 1
-
-       def write (self, s):
-               self.file.write (s)
+       done = ''
+       while str:
+               m = re.search ('\\\\mudelagraphic', str)
+               if not m:
+                       done = done + str;
+                       str = ''
+                       break
+
+               done = done + str[:m.start(0)]
+               str = str[m.end(0):]
+               
+               (c1,c2,c3, file_opts) = numbering[0]
+               (body, opts) = mudelas[0]
+               numbering = numbering[1:]
+               mudelas = mudelas[1:]
+               
+               opts = opts + file_opts
+
+               base = '%s-%d.%d.%d'  % (filename, c1, c2,c3)
+               if 'verbatim' in opts:
+                       done = done + get_re ('quote-verbatim') % body
                        
-       def write_mudela (self, s):
-               if self.verbatim:
-                       self.file.write (s)
+
+               body = compose_full_body (body, opts)
+               updated = update_file (body, base + '.ly')
+               def is_updated (extension, t = todo):
+                       for x in t:
+                               if t[0] == extension:
+                                       return 1
+                       return 0
+
+               if not os.path.isfile (base + '.tex') or updated:
+                       todo.append (('tex', base, opts))
+                       updated = 1
+
+               for o in opts:
+                       m = re.search ('intertext="(.*?)"', o)
+                       if m:
+                               done = done  + m.group (1)
+
+               if format == 'texi':
+                       opts.append ('png')
                        
-       def close_mudela (self):
-               if self.verbatim:
-                       self.file.write ('\\end{verbatim}\n')
-                       self.verbatim = 0
+               if 'png' in opts:
+                       opts.append ('eps')
+
+               if 'eps' in opts and (is_updated ('tex') or
+                                     not os.path.isfile (base + '.eps')):
+                       todo.append (('eps', base, opts))
+
+               if 'png' in opts and (is_updated ('eps') or
+                                     not os.path.isfile (base + '.png')):
+                       todo.append (('png', base, opts))
+                       
+               if format == 'latex':
+                       if 'eps' in opts :
+                               done = done + get_re ('output-eps') %  (base, base )
+                       else:
+                               done = done + get_re ('output-tex') % base
+               elif format == 'texi':
+                       done = done + get_re ('output-all') % (base, base) 
+
+
+       compile_all_files (todo)
+
+       def find_eps_dims (match):
+               "Fill in dimensions of EPS files."
+               fn =match.group (1)
+               dims = bounding_box_dimensions (fn)
                
-               self.file.write (
-                   '\\preMudelaExample\\input %s\n\postMudelaExample' %(self.mudela_basename))
-               self.mudela = 0
+               return '%ipt' % dims[0]
 
+       done = re.sub (r"""\\mudelaepswidth{(.*?)}""", find_eps_dims, done)
 
+       return done 
 
+def system (cmd):
+       sys.stderr.write ("invoking `%s'\n" % cmd)
+       st = os.system (cmd)
+       if st:
+               sys.stderr.write ('Error command exited with value %d\n' % st)
+       return st
 
+def compile_all_files ( list):
+       eps = []
+       tex = []
+       gif = []
+       for l in list:
+               if l[0] == 'eps':
+                       eps.append (l[1])
+               elif l[0] == 'tex':
+                       tex.append (l[1] + '.ly')
+               elif l[0] == 'png':
+                       gif.append (l[1])
 
-begin_mudela_re = regex.compile ('^ *\\\\begin{mudela}')
-begin_mudela_opts_re = regex.compile ('^ *\\\\begin{mudela}\[\(.*\)\]')
-end_mudela_re = regex.compile ('^ *\\\\end{mudela}')
-section_re = regex.compile ('\\\\section')
-chapter_re = regex.compile ('\\\\chapter')
+       if tex:
+               lilyopts = map (lambda x:  '-I ' + x, include_path)
+               texfiles = string.join (tex, ' ')
+               lilyopts = string.join (lilyopts, ' ' )
+               system ('lilypond %s %s' % (lilyopts, texfiles))
 
 
-class Tex_input:
-       def __init__ (self, name, outname):
-               self.infile = open (name)
-               self.outname = outname
-               self.chapter = 0
-               self.section = 0
-               self.fine_count =0
-               self.mudtex = Tex_output (self.outname)
-               self.mudela = None
-       def set_sections (self, l):
-               if section_re.search (l) <> -1:
-                       self.section = self.section + 1
-               if chapter_re.search (l) <> -1:
-                       self.section = 0
-                       self.chapter = self.chapter + 1
+       for e in eps:
+               cmd = r"""tex %s; dvips -E -o %s %s""" % \
+                     (e, e + '.eps', e)
+               system (cmd)
 
-                       
-       def gulp_mudela (self):
+       for g in gif:
+               cmd = r"""gs -sDEVICE=pgm  -dTextAlphaBits=4 -dGraphicsAlphaBits=4  -q -sOutputFile=- -r90 -dNOPAUSE %s -c quit | pnmcrop | pnmtopng > %s"""
+
+               cmd = cmd % (g + '.eps', g + '.png')
+               system (cmd)
+
+       
+def update_file (body, name):
+       same = 0
+       try:
+               f = open (name)
+               fs = f.read (-1)
+               same = (fs == body)
+       except:
                pass
 
-       def gen_basename (self):
-               return '%s/%s-%d.%d.%d' % (outdir, self.outname,self.chapter,self.section,self.fine_count)
-       def do_it(self):
-               lines = self.infile.readlines ()
-               for line in lines:
-                       if begin_mudela_re.search (line) <> -1:
-                               if begin_mudela_opts_re.search (line) <> -1:
-                                       opts = begin_mudela_opts_re.group (1)
-                               else:
-                                       opts = ''
-                               optlist = string.split (opts, ',')
-                               self.mudela = Mudela_output ()
-                               if 'fragment' in optlist:
-                                       self.mudela.fragment = 1
-                               if '16pt' in optlist:
-                                       self.mudela.size = 16
-                               if '20pt' in optlist:
-                                       self.mudela.size = 20
-                               
-                               if 'verbatim' in optlist:
-                                       self.mudtex.verbatim = 1
-
-                               b = self.gen_basename ()
-                               self.mudtex.open_mudela (b)
-                               self.mudela.open (b)
-
-
-                               continue
-                       elif end_mudela_re.search (line) <> -1:
-                               self.mudela.close ()
-                               self.mudtex.close_mudela ()
-                               self.mudela = None
-                               self.fine_count = self.fine_count + 1
-                               continue
-                           
-                       if self.mudela:
-                               self.mudela.write (line)
-                               self.mudtex.write_mudela (line)
-                       else:
-                               self.mudtex.write (line)
-                       self.set_sections(line)
-               del self.mudtex
+       if not same:
+               f = open (name , 'w')
+               f.write (body)
+               f.close ()
+
+       
+       return not same
+
+
+
+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):
+       "Transform 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():
-    sys.stdout.write("Usage: mudela-book [options] FILE\n"
-                + "Generate hybrid LaTeX input from Latex + mudela"
-                + "Options:\n"
-                + "  -h, --help             print this help\n"
-                + "  -d, --outdir=DIR       prefix directory\n" 
-                + "  -o, --outname=FILE     prefix for filenames\n"
-                    )
-    sys.exit (0)
-
-
-
-sys.stderr.write ('This is %s version %s\n' % ('mudela-book', program_version))
-
-outname = ''
-(options, files) = getopt.getopt(
-       sys.argv[1:], 'hd:o:', [ 'outdir=', 'outname=', 'help'])
-for opt in options:
-       o = opt[0]
-       a = opt[1]
-       if o == '--outname' or o == '-o':
-               outname = a
-       if o == '--outdir' or o == '-d':
-               outdir = a
-       if o == '--help' or o == '-h':
-               help ()
-
-
-for f in files:
-    my_outname = outname
-    if not my_outname:
-       my_outname = regsub.sub ('\\(.*\\)\\.doc', '\\1', f)
-
-    inp = Tex_input (f, my_outname)
-    inp.do_it ()
+       sys.stdout.write("""Usage: mudela-book [options] FILE\n
+Generate hybrid LaTeX input from Latex + mudela
+Options:
+""")
+       sys.stdout.write (options_help_str (options))
+       sys.stdout.write (r"""Warning all output is written in the CURRENT directory
+
+
+
+Report bugs to bug-gnu-music@gnu.org.
+
+Written by Tom Cato Amundsen <tomcato@xoommail.com> and
+Han-Wen Nienhuys <hanwen@cs.uu.nl>
+""")
+
+       sys.exit (0)
+
+
+def write_deps (fn, target,  deps):
+       sys.stdout.write('writing `%s\'\n' % fn)
+
+       f = open (fn, 'w')
        
+       target = target + '.latex'
+       f.write ('%s: %s\n'% (target, string.join (deps, ' ')))
+       f.close ()
+
+               
+def identify():
+       sys.stdout.write ('mudela-book (GNU LilyPond) %s\n' % program_version)
+
+def print_version ():
+       identify()
+       sys.stdout.write (r"""Copyright 1998--1999
+Distributed under terms of the GNU General Public License. It comes with
+NO WARRANTY.
+""")
+
+
+def main():
+       global outdir, initfile, defined_mudela_cmd, defined_mudela_cmd_re
+       outname = ''
+       try:
+               (sh, long) = getopt_args (__main__.options)
+               (options, files) = getopt.getopt(sys.argv[1:], sh, long)
+       except getopt.error, msg:
+               sys.stderr.write("error: %s" % msg)
+               sys.exit(1)
+
+       do_deps = 0
+       for opt in options:     
+               o = opt[0]
+               a = opt[1]
+               
+               if o == '--include' or o == '-I':
+                       include_path.append (a)
+               elif o == '--version':
+                       print_version ()
+                       sys.exit  (0)
+
+               elif o == '--format' or o == '-o':
+                       __main__.format = a
+               elif o == '--outname' or o == '-o':
+                       if len(files) > 1:
+                               #HACK
+                               sys.stderr.write("Mudela-book is confused by --outname on multiple files")
+                               sys.exit(1)
+                       outname = a
+               elif o == '--outdir' or o == '-d':
+                       outdir = a
+               elif o == '--help' or o == '-h':
+                       help ()
+               elif o == '--dependencies':
+                       do_deps = 1
+               elif o == '--default-mudela-fontsize':
+                       default_music_fontsize = string.atoi (a)
+               elif o == '--init':
+                       initfile =  a
+       
+       identify()
+
+       for input_filename in files:
+               file_settings = {}
+               if outname:
+                       my_outname = outname
+               else:
+                       my_outname = os.path.basename(os.path.splitext(input_filename)[0])
+               my_depname = my_outname + '.dep'                
+
+               (input, deps) = read_tex_file (input_filename)
+               (input, muds) = find_mudela_sections (input)
+               output = make_files  (input, muds, my_outname)
+               output = completize_preamble (output)
+
+               foutn = my_outname + '.' + format
+               sys.stderr.write ("Writing `%s'\n" % foutn)
+               fout = open (foutn, 'w')
+
+               fout.write (output)
+               fout.close ()
 
+               if do_deps:
+                       write_deps (my_depname, my_outname, deps)
 
+main()