]> git.donarmstrong.com Git - lilypond.git/blob - scripts/mudela-book.py
release: 1.2.4
[lilypond.git] / scripts / mudela-book.py
1 #!@PYTHON@
2
3 import os
4 import string
5 import re
6 import getopt
7 import sys
8 import __main__
9
10 outdir = 'out'
11 initfile = ''
12 program_version = '@TOPLEVEL_VERSION@'
13
14 cwd = os.getcwd ()
15 include_path = [cwd]
16
17 # TODO: Figure out clean set of options.
18
19 # BUG: does not handle \verb|\begin{verbatim}\end{verbatim}| correctly.
20 # Should make a joint RE for \verb and \begin, \end{verbatim}
21 #
22
23 default_music_fontsize = 16
24 default_text_fontsize = 12
25
26 # latex linewidths:
27 # indices are no. of columns, papersize,  fontsize
28 # Why can't this be calculated?
29 latex_linewidths = {
30  1: {'a4':{10: 345, 11: 360, 12: 390},
31          'a5':{10: 276, 11: 276, 12: 276},
32          'b5':{10: 345, 11: 356, 12: 356},
33          'letter':{10: 345, 11: 360, 12: 390},
34          'legal': {10: 345, 11: 360, 12: 390},
35          'executive':{10: 345, 11: 360, 12: 379}},
36  2: {'a4':{10: 167, 11: 175, 12: 190},
37          'a5':{10: 133, 11: 133, 12: 133},
38          'b5':{10: 167, 11: 173, 12: 173},
39          'letter':{10: 167, 11: 175, 12: 190},
40          'legal':{10: 167, 11: 175, 12: 190},
41          'executive':{10: 167, 11: 175, 12: 184}}}
42
43
44 options = [
45   ('DIM',  '', 'default-mudela-fontsize', 'default fontsize for music.  DIM is assumed to in points'),
46   ('EXT', 'f', 'format', 'set format.  EXT is one of texi and latex.'),
47   ('', 'h', 'help', 'print help'),
48   ('DIR', 'I', 'include', 'include path'),
49   ('', '', 'init', 'mudela-book initfile'),
50 #  ('DIM', '', 'force-mudela-fontsize', 'force fontsize for all inline mudela. DIM is assumed to in points'),
51   ('', '', 'force-verbatim', 'make all mudela verbatim'),
52   ('', 'M', 'dependencies', 'write dependencies'),
53   ('', 'n', 'no-lily', 'don\'t run lilypond'),
54   ('FILE', 'o', 'outname', 'prefix for filenames'),
55   ('', 'v', 'version', 'print version information' )
56   ]
57
58 format = ''
59 run_lilypond = 1
60 no_match = 'a\ba'
61
62 # format specific strings, ie. regex-es for input, and % strings for output
63 output_dict= {
64         'latex': {
65                 'output-mudela-fragment' : r"""\begin[eps,fragment%s]{mudela}
66   \context Staff <
67     \context Voice{
68       %s
69     }
70   >
71 \end{mudela}""", 
72                 'output-mudela':r"""\begin%s{mudela}
73 %s
74 \end{mudela}""",
75                 'output-verbatim': r"""\begin{verbatim}%s\end{verbatim}""",
76                 'output-default-post': r"""\def\postMudelaExample{}""",
77                 'output-default-pre': r"""\def\preMudelaExample{}""",
78                 'output-eps': '\\noindent\\parbox{\\mudelaepswidth{%s.eps}}{\includegraphics{%s.eps}}',
79                 'output-tex': '\\preMudelaExample \\input %s.tex \\postMudelaExample\n'
80                 },
81         'texi' : {'output-mudela': """@mudela[%s]
82 %s
83 @end mudela
84 """,
85                   'output-verbatim': r"""@example
86 %s
87 @end example
88 """,
89
90 # do some tweaking: @ is needed in some ps stuff.
91 # override EndLilyPondOutput, since @tex is done
92 # in a sandbox, you can't do \input lilyponddefs at the
93 # top of the document.
94                   'output-all': r"""@tex
95 \catcode`\@=12
96 \input lilyponddefs
97 \def\EndLilyPondOutput{}
98 \input %s.tex
99 \catcode`\@=0
100 @end tex
101 @html
102 <img src=%s.png>
103 @end html
104 """,
105                 }
106         }
107
108 def output_verbatim (body):
109         if __main__.format == 'texi':
110                 body = re.sub ('([@{}])', '@\\1', body)
111         return get_output ('output-verbatim') % body
112
113 re_dict = {
114         'latex': {'input': '\\\\input{?([^}\t \n}]*)',
115                   'include': '\\\\include{([^}]+)}',
116                  
117                   'comma-sep' : ', *',
118                   'header': r"""\\documentclass(\[.*?\])?""",
119                   'preamble-end': '\\\\begin{document}',
120                   'verbatim': r"""(?s)\\begin{verbatim}(.*?)\\end{verbatim}""",
121                   'verb': r"""\\verb(.)(.*?)\1""",
122                   'mudela-file': '\\\\mudelafile(\[[^\\]]+\])?{([^}]+)}',
123                   'mudela' : '\\\\mudela(\[.*?\])?{(.*?)}',
124                   'mudela-block': r"""(?s)\\begin(\[.*?\])?{mudela}(.*?)\\end{mudela}""",
125                   'interesting-cs': '\\\\(chapter|section|twocolumn|onecolumn)',
126                   'def-post-re': r"""\\def\\postMudelaExample""",
127                   'def-pre-re': r"""\\def\\preMudelaExample""",           
128                   },
129         'texi': {'input': '@include[ \n\t]+([^\t \n]*)',
130                  'include': no_match,
131                  'header': no_match,
132                  'preamble-end': no_match,
133                  'verbatim': r"""(?s)@example(.*?)@end example$""",
134                  'verb': r"""@code{(.*?)}""",
135                  'mudela-file': '@mudelafile(\[[^\\]]+\])?{([^}]+)}',
136                  'mudela' : '@mudela(\[.*?\])?{(.*?)}',
137                  'mudela-block': r"""(?s)@mudela(\[.*?\])?(.*?)@end mudela""",
138                  'interesting-cs': r"""[\\@](node|mudelagraphic)""",
139                   'comma-sep' : ', *',           
140                  }
141         }
142
143
144 for r in re_dict.keys ():
145         olddict = re_dict[r]
146         newdict = {}
147         for k in olddict.keys ():
148                 newdict[k] = re.compile (olddict[k])
149         re_dict[r] = newdict
150
151         
152 def uniq (list):
153         list.sort ()
154         s = list
155         list = []
156         for x in s:
157                 if x not in list:
158                         list.append (x)
159         return list
160                 
161
162 def get_output (name):
163         return  output_dict[format][name]
164
165 def get_re (name):
166         return  re_dict[format][name]
167
168
169 def bounding_box_dimensions(fname):
170         try:
171                 fd = open(fname)
172         except IOError:
173                 error ("Error opening `%s'" % fname)
174         str = fd.read (-1)
175         s = re.search('%%BoundingBox: ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)', str)
176         if s:
177                 return (int(s.group(3))-int(s.group(1)), 
178                         int(s.group(4))-int(s.group(2)))
179         else:
180                 return (0,0)
181
182
183 def find_file (name):
184         for a in include_path:
185                 try:
186                         nm = os.path.join (a, name)
187                         f = open (nm)
188                         return nm
189                 except IOError:
190                         pass
191         return ''
192
193 def error (str):
194         sys.stderr.write (str + "\n  Exiting ... \n\n")
195         raise 'Exiting.'
196
197
198 def compose_full_body (body, opts):
199         "Construct the text of an input file: add stuff to BODY using OPTS as options."
200         paper = 'a4'
201         music_size = default_music_fontsize
202         latex_size = default_text_fontsize
203
204         cols = 1
205         for o in opts:
206                 m = re.search ('^(.*)paper$', o)
207                 if m:
208                         paper = m.group (1)
209                 
210
211                 m = re.match ('([0-9]+)pt', o)
212                 if m:
213                         music_size = string.atoi(m.group (1))
214
215                 m = re.match ('latexfontsize=([0-9]+)pt', o)
216                 if m:
217                         latex_size = string.atoi (m.group (1))
218
219
220         if 'twocolumn' in opts:
221                 cols = 2
222                 
223
224         # urg: breaks on \include of full score
225         # Use nofly option if you want to \include full score.
226         if not 'nofly' in opts and not re.search ('\\\\score', body):
227                 opts.append ('fly')
228
229         if  'fragment' in opts or 'singleline' in opts:
230                 l = -1.0;
231         else:
232                 l = latex_linewidths[cols][paper][latex_size]
233
234
235         if 'fly' in opts:
236                 body = r"""\score { 
237   \notes\relative c {
238     %s
239   }
240   \paper { }  
241 }""" % body
242
243         opts = uniq (opts)
244         optstring = string.join (opts, ' ')
245         optstring = re.sub ('\n', ' ', optstring)
246                 
247         body = r"""
248 %% Generated by mudela-book.py; options are %s
249 \include "paper%d.ly"
250 \paper  { linewidth = %f \pt; } 
251 """ % (optstring, music_size, l) + body
252
253         return body
254
255 def find_inclusion_chunks (regex, surround, str):
256         chunks = []
257         while str:
258                 m = regex.search (str)
259
260                 if m == None:
261                         chunks.append (('input', str))
262                         str = ''
263                         break
264
265                 chunks.append (('input', str[: m.start (0)]))
266                 chunks.append (('input', surround))
267                 chunks = chunks + read_doc_file (m.group (1))
268                 chunks.append (('input', surround))
269
270                 str = str [m.end (0):]
271         return chunks
272
273 def find_include_chunks (str):
274         return find_inclusion_chunks (get_re ('include'), '\\newpage', str)
275
276 def find_input_chunks (str):
277         return find_inclusion_chunks (get_re ('input'), '', str)        
278
279 def read_doc_file (filename):
280         """Read the input file, substituting for \input, \include, \mudela{} and \mudelafile"""
281         str = ''
282         for ext in ['', '.tex', '.doc', '.tely']:
283                 try:
284                         f = open(filename+ ext)
285                         str = f.read (-1)
286                 except:
287                         pass
288                 
289
290         if not str:
291                 error ("File not found `%s'\n" % filename)
292
293         retdeps =  [filename]
294
295         if __main__.format == '':
296                 latex =  re.search ('\\\\document', str[:200])
297                 texinfo =  re.search ('@node', str[:200])
298                 if (texinfo and latex) or not (texinfo or latex):
299                         error("error: can't determine format, please specify")
300                 if texinfo:
301                         __main__.format = 'texi'
302                 else:
303                         __main__.format = 'latex'
304                         
305         chunks = [('input', str)]
306
307         for func in (find_verbatim_chunks, find_verb_chunks, find_include_chunks, find_input_chunks):
308                 newchunks = []
309                 for c in chunks:
310                         if c[0] == 'input':
311                                 ch = func (c[1])
312                                 newchunks = newchunks + ch
313                         else:
314                                 newchunks.append (c)
315                 chunks = newchunks
316         
317         return chunks
318
319
320
321 def scan_preamble (str):
322         options = []
323         m = get_re ('header').search( str)
324
325         # should extract paper & fontsz.
326         if m and m.group (1):
327                 options = options + re.split (',[\n \t]*', m.group(1)[1:-1])
328
329         def verbose_fontsize ( x):
330                 # o ??
331                 #if o.match('[0-9]+pt'):
332                 if re.match('[0-9]+pt', x):
333                         return 'latexfontsize=' + x
334                 else:
335                         return x 
336                         
337         options = map (verbose_fontsize, options)
338
339         return options
340
341
342 def completize_preamble (str):
343         m = get_re ('preamble-end').search( str)
344         if not m:
345                 return str
346         
347         preamble = str [:m.start (0)]
348         str = str [m.start(0):]
349         
350         if not get_re('def-post-re').search (preamble):
351                 preamble = preamble + get_output('output-default-post')
352         if not get_re ('def-pre-re').search(  preamble):
353                 preamble = preamble + get_output ('output-default-pre')
354
355         # UGH ! BUG!
356         #if  re.search ('\\\\includegraphics', str) and not re.search ('usepackage{graphics}',str):
357
358         preamble = preamble + '\\usepackage{graphics}\n'
359
360         return preamble + str
361
362 def find_verbatim_chunks (str):
363         """Chop STR into a list of tagged chunks, ie. tuples of form
364         (TYPE_STR, CONTENT_STR), where TYPE_STR is one of 'input' and 'verbatim'
365         """
366
367         chunks = []
368         while str:
369                 m = get_re ('verbatim').search( str)
370                 if m == None:
371                         chunks.append( ('input', str))
372                         str = ''
373                 else:
374                         chunks.append (('input', str[:m.start (0)]))
375                         chunks.append (('verbatim', m.group (0)))
376                 
377                         str = str [m.end(0):]
378                 
379         return chunks         
380
381 def find_verb_chunks (str):
382
383         chunks = []
384         while str:
385                 m = get_re ("verb").search(str)
386                 if  m == None:
387                         chunks.append (('input', str))
388                         str = ''
389                 else:
390                         chunks.append (('input', str[:m.start (0)]))
391                         chunks.append (('verbatim', m.group (0)))
392                         str = str [m.end(0):]
393
394         return chunks
395                         
396
397
398 def find_mudela_shorthand_chunks (str):
399         return [('input', find_mudela_shorthands(str))]
400         
401 def find_mudela_shorthands (b):
402         def mudela_short (match):
403                 "Find \mudela{}, and substitute appropriate \begin / \end blocks."
404                 opts = match.group (1)
405                 if opts:
406                         opts = ',' + opts[1:-1]
407                 else:
408                         opts = ''
409                 return get_output ('output-mudela-fragment')  % (opts, match.group (2))
410
411         def mudela_file (match):
412                 "Find \mudelafile, and substitute appropriate \begin / \end blocks."
413                 d = [] #, d = retdeps
414                 full_path = find_file (match.group (2))
415                 if not full_path:
416                         error("error: can't find file `%s'\n" % match.group(2))
417
418                 d.append (full_path)
419                 f = open (full_path)
420                 str = f.read (-1)
421                 opts = match.group (1)
422                 if opts:
423                         opts = re.split (',[ \n\t]*', opts[1:-1])
424                 else:
425                         opts = []
426
427                 if re.search ('.fly$', full_path):
428                         opts.append ('fly')
429                 elif re.search ('.sly$', full_path):
430                         opts = opts + [ 'fly','fragment']
431                 elif re.search ('.ly$', full_path):
432                         opts .append ('nofly')
433                         
434                 str_opts = string.join (opts, ',')
435                 if str_opts: str_opts = '[' + str_opts + ']'
436
437
438                 str = ("%% copied from file `%s'\n" % full_path) + str 
439                 return get_output ('output-mudela') % (str_opts, str)
440   
441         b = get_re('mudela-file').sub (mudela_file, b)
442         b = get_re('mudela').sub (mudela_short, b)
443         return b
444         
445 def find_mudela_chunks (str):
446         """Find mudela blocks, while watching for verbatim. Returns
447         (STR,MUDS) with \mudelagraphic substituted for the blocks in STR,
448         and the blocks themselves MUDS"""
449   
450         chunks = []
451         while str:
452                 m = get_re ("mudela-block").search( str)
453                 if not m:
454                         chunks.append (('input', str))
455                         str = ''
456                         break
457
458                 chunks.append (('input', str[:m.start (0)]))
459                 
460                 opts = m.group (1)
461                 if opts:
462                         opts = opts[1:-1]
463                 else:
464                         opts = ''
465                 optlist = get_re('comma-sep').split (opts)
466                 
467                 body = m.group (2)
468                 chunks.append (('mudela', body, optlist))
469   
470                 str = str [m.end (0):]
471   
472         return chunks
473   
474   
475   
476 def advance_counters (counter, opts, str):
477         """Advance chap/sect counters,
478         revise OPTS. Return the new counter tuple"""
479         
480         (chapter, section, count) = counter
481         done = ''
482         while str:
483                 m = get_re ('interesting-cs').search(str)
484                 if not m:
485                         done = done + str
486                         str = ''
487                         break
488                 
489                 done = done + str[:m.end (0)]
490                 str = str[m.end(0):]
491                 g = m.group (1)
492
493                 if g == 'twocolumn':
494                         opts.append ('twocolumn')
495                 elif g  == 'onecolumn':
496                         try:
497                                 current_opts.remove ('twocolumn')
498                         except IndexError:
499                                 pass
500                 elif g == 'chapter':
501                         (chapter, section, count)  = (chapter + 1, 0, 0)
502                 elif g == 'section' or g == 'node':
503                         (section, count)  = (section + 1, 0)
504                         
505
506         return (chapter, section, count)
507
508
509 def schedule_mudela_block (base, chunk, extra_opts):
510         """Take the body and options from CHUNK, figure out how the
511         real .ly should look, and what should be left MAIN_STR (meant
512         for the main file).  The .ly is written, and scheduled in
513         TODO.
514
515         Return: a chunk (TYPE_STR, MAIN_STR, OPTIONS, TODO)
516
517         TODO has format [basename, extension, extension, ... ]
518         
519         """
520
521         (type, body, opts) = chunk
522         assert type == 'mudela'
523         opts = opts +  extra_opts
524         
525         newbody = ''
526         if 'verbatim' in opts:
527                 newbody = output_verbatim (body)
528
529         file_body = compose_full_body (body, opts)
530         updated = update_file (file_body, base + '.ly')
531         todo = [base]                   # UGH.
532
533         if not os.path.isfile (base + '.tex') or updated:
534                 todo.append ('tex')
535                 updated = 1
536
537         for o in opts:
538                 m = re.search ('intertext="(.*?)"', o)
539                 if m:
540                         newbody = newbody  + m.group (1)
541
542         if format == 'texi':
543                 opts.append ('png')
544
545         if 'png' in opts:
546                 opts.append ('eps')
547
548         if 'eps' in opts and ('tex' in todo or
549                               not os.path.isfile (base + '.eps')):
550                 todo.append ('eps')
551
552         if 'png' in opts and ('eps' in todo or
553                               not os.path.isfile (base + '.png')):
554                 todo.append ('png')
555
556         if format == 'latex':
557                 if 'eps' in opts :
558                         newbody = newbody + get_output ('output-eps') %  (base, base)
559                 else:
560                         newbody = newbody + get_output ('output-tex') % base
561
562         elif format == 'texi':
563                 newbody = newbody + get_output ('output-all') % (base, base) 
564
565
566         
567         return ('mudela', newbody, opts, todo)
568
569 def find_eps_dims (match):
570         "Fill in dimensions of EPS files."
571         
572         fn =match.group (1)
573         dims = bounding_box_dimensions (fn)
574
575         return '%ipt' % dims[0]
576
577
578 def print_chunks (ch):
579         for c in ch:
580                 print '-->%s\n%s' % (c[0], c[1])
581                 if len (c) > 2:
582                         print '==>%s' % list (c[2:])
583         print foo
584
585
586 def transform_input_file (in_filename, out_filename):
587         """Read the input, and deliver a list of chunks
588         ready for writing.
589         """
590
591         chunks = read_doc_file (in_filename)
592
593         #.  Process \mudela and \mudelafile.
594         for func in [find_mudela_shorthand_chunks,
595                      find_mudela_chunks]:
596                 newchunks = []
597                 for c in chunks:
598                         if c[0] == 'input':
599                                 newchunks = newchunks + func (c[1])
600                         else:
601                                 newchunks.append (c)
602                 chunks = newchunks
603
604         opts = []
605         if chunks:
606                 opts = scan_preamble (chunks[0][1]) 
607         
608         (chap,sect,count) = (0,0,0)
609         newchunks = []
610         # Count sections/chapters.
611         for c in chunks:
612                 if c[0] == 'input':
613                         (chap,sect,count) = advance_counters((chap,sect,count), opts, c[1])
614                 elif c[0] == 'mudela':
615                         base = '%s-%d.%d.%d' % (out_filename, chap, sect, count)
616                         count = count + 1
617                         c = schedule_mudela_block (base, c, opts)
618                         
619                 newchunks.append (c)
620
621         chunks = newchunks
622         newchunks = []
623
624         # Do It.
625         if __main__.run_lilypond:
626                 compile_all_files (chunks)
627                 
628                 # finishing touch.
629                 for c in chunks:
630                         if c[0] == 'mudela' and 'eps' in c[2]:
631                                 body = re.sub (r"""\\mudelaepswidth{(.*?)}""", find_eps_dims, c[1])
632                                 newchunks.append (('mudela', body))
633                         else:
634                                 newchunks.append (c)
635                 chunks = newchunks
636                 
637         if chunks and chunks[0][0] == 'input':
638                 chunks[0] = ('input', completize_preamble (chunks[0][1]))
639
640         return chunks
641
642 def system (cmd):
643         sys.stderr.write ("invoking `%s'\n" % cmd)
644         st = os.system (cmd)
645         if st:
646                 error ('Error command exited with value %d\n' % st)
647         return st
648
649 def compile_all_files (chunks):
650         eps = []
651         tex = []
652         png = []
653
654         for c in chunks:
655                 if c[0] <> 'mudela':
656                         continue
657                 base  = c[3][0]
658                 exts = c[3][1:]
659                 for e in exts:
660                         if e == 'eps':
661                                 eps.append (base)
662                         elif e == 'tex':
663                                 tex.append (base + '.ly')
664                         elif e == 'png':
665                                 png.append (base)
666
667         if tex:
668                 lilyopts = map (lambda x:  '-I ' + x, include_path)
669                 lilyopts = string.join (lilyopts, ' ' )
670                 texfiles = string.join (tex, ' ')
671                 system ('lilypond %s %s' % (lilyopts, texfiles))
672
673         for e in eps:
674                 cmd = r"""tex %s; dvips -E -o %s %s""" % \
675                       (e, e + '.eps', e)
676                 system (cmd)
677
678         for g in png:
679                 cmd = r"""gs -sDEVICE=pgm  -dTextAlphaBits=4 -dGraphicsAlphaBits=4  -q -sOutputFile=- -r90 -dNOPAUSE %s -c quit | pnmcrop | pnmtopng > %s"""
680
681                 cmd = cmd % (g + '.eps', g + '.png')
682                 system (cmd)
683
684         
685 def update_file (body, name):
686         same = 0
687         try:
688                 f = open (name)
689                 fs = f.read (-1)
690                 same = (fs == body)
691         except:
692                 pass
693
694         if not same:
695                 f = open (name , 'w')
696                 f.write (body)
697                 f.close ()
698
699         
700         return not same
701
702
703
704 def getopt_args (opts):
705         "Construct arguments (LONG, SHORT) for getopt from  list of options."
706         short = ''
707         long = []
708         for o in opts:
709                 if o[1]:
710                         short = short + o[1]
711                         if o[0]:
712                                 short = short + ':'
713                 if o[2]:
714                         l = o[2]
715                         if o[0]:
716                                 l = l + '='
717                         long.append (l)
718         return (short, long)
719
720 def option_help_str (o):
721         "Transform one option description (4-tuple ) into neatly formatted string"
722         sh = '  '       
723         if o[1]:
724                 sh = '-%s' % o[1]
725
726         sep = ' '
727         if o[1] and o[2]:
728                 sep = ','
729                 
730         long = ''
731         if o[2]:
732                 long= '--%s' % o[2]
733
734         arg = ''
735         if o[0]:
736                 if o[2]:
737                         arg = '='
738                 arg = arg + o[0]
739         return '  ' + sh + sep + long + arg
740
741
742 def options_help_str (opts):
743         "Convert a list of options into a neatly formatted string"
744         w = 0
745         strs =[]
746         helps = []
747         for o in opts:
748                 s = option_help_str (o)
749                 strs.append ((s, o[3]))
750                 if len (s) > w:
751                         w = len (s)
752
753         str = ''
754         for s in strs:
755                 str = str + '%s%s%s\n' % (s[0], ' ' * (w - len(s[0])  + 3), s[1])
756         return str
757
758 def help():
759         sys.stdout.write("""Usage: mudela-book [options] FILE\n
760 Generate hybrid LaTeX input from Latex + mudela
761 Options:
762 """)
763         sys.stdout.write (options_help_str (options))
764         sys.stdout.write (r"""Warning all output is written in the CURRENT directory
765
766
767
768 Report bugs to bug-gnu-music@gnu.org.
769
770 Written by Tom Cato Amundsen <tomcato@xoommail.com> and
771 Han-Wen Nienhuys <hanwen@cs.uu.nl>
772 """)
773
774         sys.exit (0)
775
776
777 def write_deps (fn, target,  deps):
778         sys.stdout.write('writing `%s\'\n' % fn)
779
780         f = open (fn, 'w')
781         
782         target = target + '.latex'
783         f.write ('%s: %s\n'% (target, string.join (deps, ' ')))
784         f.close ()
785
786                 
787 def identify():
788         sys.stdout.write ('mudela-book (GNU LilyPond) %s\n' % program_version)
789
790 def print_version ():
791         identify()
792         sys.stdout.write (r"""Copyright 1998--1999
793 Distributed under terms of the GNU General Public License. It comes with
794 NO WARRANTY.
795 """)
796
797
798 def main():
799         global outdir, initfile, defined_mudela_cmd, defined_mudela_cmd_re
800         outname = ''
801         try:
802                 (sh, long) = getopt_args (__main__.options)
803                 (options, files) = getopt.getopt(sys.argv[1:], sh, long)
804         except getopt.error, msg:
805                 sys.stderr.write("error: %s" % msg)
806                 sys.exit(1)
807
808         do_deps = 0
809         for opt in options:     
810                 o = opt[0]
811                 a = opt[1]
812                 
813                 if o == '--include' or o == '-I':
814                         include_path.append (a)
815                 elif o == '--version':
816                         print_version ()
817                         sys.exit  (0)
818
819                 elif o == '--format' or o == '-o':
820                         __main__.format = a
821                 elif o == '--outname' or o == '-o':
822                         if len(files) > 1:
823                                 #HACK
824                                 sys.stderr.write("Mudela-book is confused by --outname on multiple files")
825                                 sys.exit(1)
826                         outname = a
827                 elif o == '--outdir' or o == '-d':
828                         outdir = a
829                 elif o == '--help' or o == '-h':
830                         help ()
831                 elif o == '--no-lily' or o == '-n':
832                         __main__.run_lilypond = 0
833                 elif o == '--dependencies':
834                         do_deps = 1
835                 elif o == '--default-mudela-fontsize':
836                         default_music_fontsize = string.atoi (a)
837                 elif o == '--init':
838                         initfile =  a
839         
840         identify()
841
842         for input_filename in files:
843                 file_settings = {}
844                 if outname:
845                         my_outname = outname
846                 else:
847                         my_outname = os.path.basename(os.path.splitext(input_filename)[0])
848                 my_depname = my_outname + '.dep'                
849
850                 chunks = transform_input_file (input_filename, my_outname)
851                 
852                 foutn = my_outname + '.' + format
853                 sys.stderr.write ("Writing `%s'\n" % foutn)
854                 fout = open (foutn, 'w')
855                 for c in chunks:
856                         fout.write (c[1])
857                 fout.close ()
858
859                 if do_deps:
860                         # write_deps (my_depname, my_outname, deps)
861                         sys.stderr.write ("--dependencies broken")
862
863 main()
864
865
866
867 #
868 # Petr, ik zou willen dat ik iets zinvoller deed,
869 # maar wat ik kan ik doen, het verandert toch niets?
870 #   --hwn 20/aug/99