]> git.donarmstrong.com Git - lilypond.git/blob - scripts/mudela-book.py
patch::: 1.1.15.tca1
[lilypond.git] / scripts / mudela-book.py
1 #!@PYTHON@
2 #
3 # The bugs you find are made by Tom Cato Amundsen <tomcato@xoommail.com>
4 # Send patches/questions/bugreports to a mailinglist:
5 #  gnu-music-discuss@gnu.org
6 #  bug-gnu-music@gnu.org
7 #  help-gnu-music@gnu.org
8 #
9 # All non-english comments are NOT in swedish, they are norwegian!
10 #  TODO:
11 # * center option (??)
12 # * make mudela-book understand usepackage{geometry}
13 # * check that linewidth set in \paper is not wider than actual linewidth?
14 # * the following fails because mudelabook doesn't care that the
15 #   last } after \end{mudela} finishes the marginpar:
16 #     \marginpar{
17 #     \begin{mudela}
18 #        c d e f g
19 #     \end{mudela}}
20 # * force-verbatim is maybe not that useful since latex fails with footnotes,
21 #   marginpars and others
22 # log:
23 # 0.3:
24 #   rewrite in Python.
25 # 0.4:
26 #   much rewritten by new author. I think the work has been split more
27 #   logical between different classes.
28 # 0.4.1:
29 #   - cleanup
30 #   - speedup, do all mudela parsing at the same time to avoid multiple
31 #     guile startup that takes some seconds on my computer
32 # 0.4.2:
33 #   - fixed default latex fontsize, it should be 10pt not 11pt
34 #   - verbatim option no longer visible
35 #   - mudela-book produces .dvi output
36 #   - change to use castingalgorithm = \Gourlay instead of \Wordwrap. It gives
37 #     better result on small linewidths.
38 #   - mudela-book-doc.doc rewritten
39 # 0.5:
40 #   - junked floating and fragment options, added eps option
41 #   - mudela-book will scan the mudela code to find out if it has to add
42 #     paper-definition and \score{\notes{...}}
43 #   - possible to define commands that look like this: \mudela{ c d e }
44 #   - don't produce .dvi output, it was a silly idea...
45 # 0.5.1:
46 #   - removed init/mudela-book-defs.py, \mudela is defined inside mudela-book
47 #   - fragment and nonfragment options will override autodetection of type of
48 #     in mudela-block (voice contents or complete code)
49 # 0.5.2:
50 #   - fixed verbatim option behaviour: don't show \begin{mudela} \end{mudela}
51 #     and show both mudela code and music
52 #   - veryverbatim option, same as verbatim but show \begin{mudela}
53 #     and \end{mudela}. (saves keystrokes in mudela-book-doc.doc)
54 #   - intertext="bla bla bla" option
55 #   - mudela-book now understand latex \begin{verbatim}
56
57 import os
58 import string
59 import re
60 import getopt
61 import sys
62
63 outdir = 'out'
64 initfile = ''
65 program_version = '0.5.2'
66
67 out_files = []
68
69 fontsize_i2a = {11:'eleven', 13:'thirteen', 16:'sixteen',
70                 20:'twenty', 26:'twentysix'}
71 fontsize_pt2i = {'11pt':11, '13pt':13, '16pt':16, '20pt':20, '26pt':26}
72
73 begin_mudela_re = re.compile ('^ *\\\\begin{mudela}')
74 begin_verbatim_re = re.compile ('^ *\\\\begin{verbatim}')
75 end_verbatim_re = re.compile ('^ *\\\\end{verbatim}')
76 extract_papersize_re = re.compile('\\\\documentclass[\[, ]*(\w*)paper[\w ,]*\]\{\w*\}')
77 extract_fontsize_re = re.compile('[ ,\[]*([0-9]*)pt')
78 begin_mudela_opts_re = re.compile('\[[^\]]*\]')
79 end_mudela_re = re.compile ('^ *\\\\end{mudela}')
80 section_re = re.compile ('\\\\section')
81 chapter_re = re.compile ('\\\\chapter')
82 input_re = re.compile ('^\\\\input{([^}]*)')
83 include_re = re.compile ('^\\\\include{([^}]*)')
84 begin_document_re = re.compile ('^ *\\\\begin{document}')
85 documentclass_re = re.compile('\\\\documentclass')
86 twocolumn_re = re.compile('\\\\twocolumn')
87 onecolumn_re = re.compile('\\\\onecolumn')
88 preMudelaExample_re = re.compile('\\\\def\\\\preMudelaExample')
89 postMudelaExample_re = re.compile('\\\\def\\\\postMudelaExample')
90 boundingBox_re = re.compile('%%BoundingBox: ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)')
91 intertext_re = re.compile("intertext=\"([^\"]*)\"")
92
93 def file_exist_b(name):
94     try: 
95         f = open(name)
96     except IOError:
97         return 0
98     f.close ()
99     return 1
100
101 def ps_dimention(fname):
102     fd = open(fname)
103     lines = fd.readlines()
104     for line in lines:
105         s = boundingBox_re.search(line)
106         if s:
107             break
108     return (int(s.groups()[2])-int(s.groups()[0]), 
109             int(s.groups()[3])-int(s.groups()[1]))
110
111
112 class CompileStatus:
113     pass
114 class SomethingIsSeriouslyBroken:
115     pass
116
117 def file_mtime (name):
118     return os.stat (name)[8] #mod time
119
120 def need_recompile_b(infile, outfile):
121     indate = file_mtime (infile)
122     try:
123         outdate = file_mtime (outfile)
124         return indate > outdate
125     except os.error:
126         return 1
127
128 #
129 # executes os.system(command) if infile is newer than
130 # outfile or outfile don't exist
131 #
132 def compile (command, workingdir, infile, outfile):
133     "Test if infile is newer than outfile. If so, cd to workingdir"
134     "and execute command"
135     indate = file_mtime (workingdir+infile)
136     try:
137         outdate = file_mtime (workingdir+outfile)
138         recompile = indate > outdate
139
140     except os.error:
141         recompile = 1
142
143     if recompile:
144         sys.stderr.write ('invoking `%s\'\n' % command)
145         if workingdir == '':
146             status = os.system (command)
147         else:
148             status = os.system ('cd %s; %s' %(workingdir, command))
149         if status:
150             raise CompileStatus
151
152 class Properties:
153     #
154     # init
155     #
156     def __init__(self):
157         self.__linewidth = {
158             1: {'a4':{10: 345, 11: 360, 12: 390},
159                 'a5':{10: 276, 11: 276, 12: 276},
160                 'b5':{10: 345, 11: 356, 12: 356},
161                 'letter':{10: 345, 11: 360, 12: 390},
162                 'legal': {10: 345, 11: 360, 12: 390},
163                 'executive':{10: 345, 11: 360, 12: 379}},
164             2: {'a4':{10: 167, 11: 175, 12: 190},
165                 'a5':{10: 133, 11: 133, 12: 133},
166                 'b5':{10: 167, 11: 173, 12: 173},
167                 'letter':{10: 167, 11: 175, 12: 190},
168                 'legal':{10: 167, 11: 175, 12: 190},
169                 'executive':{10: 167, 11: 175, 12: 184}}}
170         # >0 --> force all mudela to this pt size
171         self.force_mudela_fontsize = 0
172         self.force_verbatim_b = 0
173         self.__data = {
174             'mudela-fontsize' : {'init': 16},
175             'papersize' : {'init': 'a4'},
176             'num-column' : {'init': 1},
177             'tex-fontsize' : {'init': 10}
178             }
179     def clear_for_new_file(self):
180         for var in self.__data.keys():
181             self.__data[var] = {'init': self.__data[var]['init']}
182     def clear_for_new_block(self):
183         for var in self.__data.keys():
184             if self.__data[var].has_key('block'):
185                 del self.__data[var]['block']
186     def __get_variable(self, var):
187         if self.__data[var].has_key('block'):
188             return self.__data[var]['block']
189         elif self.__data[var].has_key('file'):
190             return self.__data[var]['file']
191         else:
192             return self.__data[var]['init']
193     def setPapersize(self, size, requester):
194         self.__data['papersize'][requester] = size
195     def getPapersize(self):
196         return self.__get_variable('papersize')
197     def setMudelaFontsize(self, size, requester):
198         self.__data['mudela-fontsize'][requester] = size
199     def getMudelaFontsize(self):
200         if self.force_mudela_fontsize:
201             return self.force_mudela_fontsize
202         return self.__get_variable('mudela-fontsize')
203     def setTexFontsize(self, size, requester):
204         self.__data['tex-fontsize'][requester] = size
205     def getTexFontsize(self):
206         return self.__get_variable('tex-fontsize')
207     def setNumColumn(self, num, requester):
208         self.__data['num-column'][requester] = num
209     def getNumColumn(self):
210         return self.__get_variable('num-column')
211     def getLineWidth(self):
212         return self.__linewidth[self.getNumColumn()][self.getPapersize()][self.getTexFontsize()]
213
214
215 class Mudela_output:
216     def __init__ (self, basename):
217         self.basename = basename
218         self.temp_filename = "%s/%s" %(outdir, 'mudela-temp.ly')
219         self.file = open (self.temp_filename, 'w')
220         self.__lines = []
221         # 'tex' or 'eps'
222         self.graphic_type = 'tex'
223         self.code_type = 'unknown'
224         self.code_type_override = None
225     def write (self, line):
226         # match only if there is nothing but whitespace before \begin HACK
227         if re.search('^\s*\\\\begin{mudela}', line):
228             self.scan_begin_statement(line)
229         else:
230             if self.code_type == 'unknown':
231                 if re.search('^\s*\\\\score', line) or \
232                    re.search('^\s*\\\\paper', line) or \
233                    re.search('^\s*\\\\header', line) or \
234                    re.search('^\s*[A-Za-z]*\s*=', line):
235                     self.code_type = 'ly'
236             self.__lines.append(line)
237     def scan_begin_statement(self, line):
238         r  = begin_mudela_opts_re.search(line)
239         if r:
240             o = r.group()[1:-1]
241             optlist =  re.compile('[\s,]*').split(o)
242         else:
243             optlist = []
244         if 'fragment' in optlist:
245             self.code_type_override = 'fly'
246         if 'nonfragment' in optlist:
247             self.code_type_override = 'ly'
248         if 'eps' in optlist:
249             self.graphic_type = 'eps'
250         for pt in fontsize_pt2i.keys():
251             if pt in optlist:
252                 Props.setMudelaFontsize(fontsize_pt2i[pt], 'block')
253     def write_red_tape(self):
254         self.file.write ('\\include \"paper%d.ly\"\n' \
255                          % Props.getMudelaFontsize())
256                          
257         s = fontsize_i2a[Props.getMudelaFontsize()]
258         if self.code_type == 'fly':
259             linewidth_str = 'linewidth = -1.\cm;'
260         else:
261             linewidth_str = 'linewidth = %i.\\pt;' % Props.getLineWidth()
262         self.file.write("\\paper {"
263                         + "\\paper_%s " % s
264                         + linewidth_str
265                         + "castingalgorithm = \Gourlay; \n}")
266                         #+ "castingalgorithm = \Wordwrap; indent = 2.\cm; \n}")
267         if self.code_type == 'fly':
268             self.file.write('\\score{\n\\notes{')
269     def close (self):
270         if self.code_type == 'unknown':
271             self.code_type = 'fly'
272         if self.code_type_override:
273             self.code_type = self.code_type_override
274         self.write_red_tape()
275         for l in self.__lines:
276             self.file.write(l)
277         if self.code_type == 'fly':
278             self.file.write('}}')
279             
280         self.file.close()
281
282         inf = outdir + self.basename + '.ly'
283         outf = outdir + self.basename + '.tex'
284         if not os.path.isfile(inf):
285             status = 1
286         else:
287             status = os.system ('diff -q %s %s' % (self.temp_filename, inf))
288         if status:
289             os.rename (self.temp_filename, inf)
290         if need_recompile_b(inf, outf):
291             out_files.append((self.graphic_type, inf))
292     def insert_me_string(self):
293         "Returns a string that can be used directly in latex."
294         if self.graphic_type == 'tex':
295             return ['tex', self.basename]
296         elif self.graphic_type == 'eps':
297             return ['eps', self.basename]
298         else:
299             raise SomethingIsSeriouslyBroken
300
301 class Tex_output:
302     def __init__ (self, name):
303         self.output_fn = '%s/%s' % (outdir, name)
304         self.__lines = []
305     def open_verbatim (self, line, level):
306         self.__lines.append('\\begin{verbatim}\n')
307         if level == 2:
308             s = re.sub('veryverbatim[\s,]*', '', line)
309             s = re.sub('intertext=\"([^\"]*)\"[\s,]*', '', s)
310             s = re.sub(',\s*\]', ']', s)
311             s = re.sub('\[\]', '', s)
312             self.__lines.append(s);
313     def close_verbatim (self):
314         self.__lines.append('\\end{verbatim}\n')
315     def write (self, s):
316         self.__lines.append(s)
317     def create_graphics(self):
318         s = ''
319         g_vec = []
320         for line in self.__lines:
321             if type(line)==type([]):
322                 g_vec.append(line)
323         for g in g_vec:
324             if need_recompile_b(outdir+g[1]+'.ly', outdir+g[1]+'.tex'):
325                     s = s + ' ' + g[1]+'.ly'
326         if s != '':
327             e = os.system('cd %s; lilypond %s' %(outdir, s))
328             if e:
329                 print "error: lilypond exited with value", e
330                 sys.exit(e)
331         for g in g_vec:
332             if g[0] == 'eps':
333                 compile('tex %s' % g[1]+'.tex', outdir, g[1]+'.tex', g[1]+'.dvi')
334                 compile('dvips -E -o %s %s' %(g[1]+'.eps', g[1]+'.dvi'), outdir,
335                         g[1]+'.dvi', g[1]+'.eps')
336     def write_outfile(self):
337         file = open(self.output_fn+'.latex', 'w')
338         file.write('% Created by mudela-book\n')
339         for line in self.__lines:
340             if type(line)==type([]):
341                 if line[0] == 'tex':
342                     file.write('\\preMudelaExample\\input %s\n\postMudelaExample '\
343                                # TeX applies the prefix of the main source automatically.
344                                % (line[1]+'.tex'))
345 #                               % (outdir+line[1]+'.tex'))
346                 if line[0] == 'eps':
347                     ps_dim = ps_dimention(outdir+line[1]+'.eps')
348                     file.write('\\parbox{%ipt}{\includegraphics{%s}}\n' \
349                                % (ps_dim[0], line[1]+'.eps'))
350 #                               % (ps_dim[0], outdir+line[1]+'.eps'))
351             else:
352                 file.write(line)
353         file.close()
354
355 class Tex_input:
356     def __init__ (self, filename):
357         for fn in [filename, filename+'.tex', filename+'.doc']:
358             try:
359                 self.infile = open (fn)
360                 self.filename = fn
361                 return
362             except:
363                 continue
364         raise IOError
365     def get_lines (self):
366         lines = self.infile.readlines ()
367         (retlines, retdeps) = ([],[self.filename])
368         for line in lines:
369             r_inp = input_re.search (line)
370             r_inc = include_re.search (line)
371
372             # Filename rules for \input :
373             # input: no .tex ext
374             # 1. will search for file with exact that name (tex-input.my will be found)
375             # 2. will search for file with .tex ext, (tex-input.my
376             #    will find tex-input.my.tex)
377             # input: with .tex ext
378             # 1. will find exact match
379             
380             # Filename rules for \include :
381             # 1. will only find files with name given to \include + .tex ext
382             if r_inp:
383                 try:
384                     t = Tex_input (r_inp.groups()[0])
385                     ls = t.get_lines ()
386                     retlines = retlines + ls[0]
387                     retdeps = retdeps + ls[1]
388                 except:
389                     print "warning: can't find %s, let's hope latex will" \
390                           % r_inp.groups()[0]
391                     retlines.append (line)
392             elif r_inc:
393                 try:
394                     t = Tex_input (r_inc.groups()[0]+'.tex')
395                     ls =t.get_lines ()
396                     ls[0].insert(0, '\\newpage\n')
397                     ls[0].append('\\newpage\n')
398                     retlines = retlines + ls[0]
399                     retdeps = retdeps + ls[1]
400                 except:
401                     print "warning: can't find %s, let's hope latex will" \
402                           % r_inc.groups()[0]
403                     retlines.append (line)
404             else:
405                 r_mud = defined_mudela_cmd_re.search(line)
406                 if r_mud:
407                     ss = "\\\\verb(?P<xx>[^a-zA-Z])\s*\\\\%s\s*(?P=xx)" \
408                          % re.escape(r_mud.group()[1:])
409                     if re.search(ss, line):
410                         retlines.append(line)
411                         continue
412                     while 1:
413                         opts = r_mud.groups()[2]
414                         if opts == None:
415                             opts = ''
416                         else:
417                             opts = ', '+opts
418                         (start, rest) = string.split(line, r_mud.group(), 1)
419                         retlines.append(start)#+'\n')
420                         v = string.split(defined_mudela_cmd[r_mud.groups()[0]], '\n')
421                         for l in v[1:-1]:
422                             l = re.sub(r'\\fontoptions', opts, l)
423                             l = re.sub(r'\\maininput', r_mud.groups()[3], l)
424                             retlines.append(l)
425                         r_mud = defined_mudela_cmd_re.search(rest)
426                         if not r_mud:
427                             retlines.append(rest)
428                             break;
429                         line = rest
430                 else:
431                     retlines.append (line)
432         else:
433             return (retlines, retdeps)
434
435
436 class Main_tex_input(Tex_input):
437     def __init__ (self, name, outname):
438
439         Tex_input.__init__ (self, name) # ugh
440         self.outname = outname
441         self.chapter = 0
442         self.section = 0
443         self.fine_count =0
444         self.mudtex = Tex_output (self.outname)
445         self.mudela = None
446         self.deps = []
447         self.verbatim = 0
448         # set to 'mudela' when we are processing mudela code,
449         # both verbatim and graphic-to-be
450         self.mode = 'latex'
451     def set_sections (self, l):
452         if section_re.search (l):
453             self.section = self.section + 1
454         if chapter_re.search (l):
455             self.section = 0
456             self.chapter = self.chapter + 1
457
458     def gen_basename (self):
459         return '%s-%d.%d.%d' % (self.outname, self.chapter,
460                                 self.section, self.fine_count)
461     def extract_papersize_from_documentclass(self, line):
462         pre = extract_papersize_re.search(line)
463         if not pre:
464             return None
465         return pre.groups()[0]
466     def extract_fontsize_from_documentclass(self, line):
467         r = extract_fontsize_re.search(line)
468         if r:
469             return int(r.groups()[0])
470     def do_it(self):
471         preMudelaDef = postMudelaDef = 0
472         (lines, self.deps) = self.get_lines ()
473         #HACK
474         latex_verbatim = 0
475         for line in lines:
476             if documentclass_re.search (line):
477                 p = self.extract_papersize_from_documentclass (line)
478                 if p:
479                     Props.setPapersize(p, 'file')
480                 f = self.extract_fontsize_from_documentclass (line)
481                 if f:
482                     Props.setTexFontsize (f, 'file')
483             elif twocolumn_re.search (line):
484                 Props.setNumColumn (2, 'file')
485             elif onecolumn_re.search (line):
486                 Props.setNumColumn (1, 'file')
487             elif preMudelaExample_re.search (line):
488                 preMudelaDef = 1
489             elif postMudelaExample_re.search (line):
490                 postMudelaDef = 1
491             elif begin_verbatim_re.search (line):
492                 latex_verbatim = 1
493             elif end_verbatim_re.search (line):
494                 latex_verbatim = 0
495             elif begin_document_re.search (line):
496                 if not preMudelaDef:
497                     self.mudtex.write ('\\def\\preMudelaExample{}\n')
498                 if not postMudelaDef:
499                     self.mudtex.write ('\\def\\postMudelaExample{}\n')
500             elif begin_mudela_re.search (line) and not latex_verbatim:
501                 Props.clear_for_new_block()
502                 if __debug__:
503                     if self.mode == 'mudela':
504                         raise AssertionError
505                 self.mode = 'mudela'
506                 r  = begin_mudela_opts_re.search (line)
507                 if r:
508                     o = r.group()[1:][:-1]
509                     optlist =  re.compile('[ ,]*').split(o)
510                     m = intertext_re.search(r.group())
511                     if m:
512                         self.intertext = m.groups()[0]
513                     else:
514                         self.intertext = None
515                 else:
516                     optlist = []
517                 if ('veryverbatim' in optlist):
518                     self.verbatim = 2
519                 elif ('verbatim' in optlist) or (Props.force_verbatim_b):
520                     self.verbatim = 1
521                 else:
522                     self.verbatim = 0
523                 if self.verbatim:
524                     self.mudtex.open_verbatim (line, self.verbatim)
525                 self.mudela = Mudela_output (self.gen_basename ())
526                 self.mudela.write (line)
527                 continue
528             elif end_mudela_re.search (line) and not latex_verbatim:
529                 if __debug__:
530                     if self.mode != 'mudela':
531                         raise AssertionError
532
533                 if self.verbatim:
534                     if self.verbatim == 2:
535                         self.mudtex.write (line)
536                     self.mudtex.close_verbatim ()
537                 self.mudela.close ()
538                 if self.verbatim and self.intertext:
539                     self.mudtex.write(self.intertext)
540                 self.mudtex.write (self.mudela.insert_me_string())
541                 del self.mudela
542                 self.mudela = None
543                 self.fine_count = self.fine_count + 1
544                 self.mode = 'latex'
545                 continue
546
547             if self.mode == 'mudela':
548                 self.mudela.write (line)
549                 if self.verbatim:
550                     self.mudtex.write (line)
551             else:
552                 self.mudtex.write (line)
553                 self.set_sections(line)
554         self.mudtex.create_graphics()
555         self.mudtex.write_outfile()
556         del self.mudtex
557                 
558
559 def help():
560     sys.stdout.write("""Usage: mudela-book [options] FILE\n
561 Generate hybrid LaTeX input from Latex + mudela
562 Options:\n
563   -h, --help                     print this help
564   -d, --outdir=DIR               directory to put generated files
565   -o, --outname=FILE             prefix for filenames
566   --default-mudela-fontsize=??pt default fontsize for music
567   --force-mudela-fontsize=??pt   force fontsize for all inline mudela
568   --force-verbatim               make all mudela verbatim\n
569   --dependencies                 write dependencies
570   --init                         mudela-book initfile
571   """
572                      )
573     sys.exit (0)
574
575
576 def write_deps (fn, out,  deps):
577         out_fn = outdir + '/' + fn
578         print '`writing `%s\'\n\'' % out_fn
579         
580         f = open (out_fn, 'w')
581         f.write ('%s: %s\n'% (outdir + '/' + out + '.dvi',
582                               reduce (lambda x,y: x + ' '+ y, deps)))
583         f.close ()
584
585 def identify():
586     sys.stderr.write ('This is %s version %s\n' % ('mudela-book', program_version))
587
588 def main():
589     global outdir, initfile, defined_mudela_cmd, defined_mudela_cmd_re
590     outname = ''
591     try:
592         (options, files) = getopt.getopt(
593             sys.argv[1:], 'hd:o:', ['outdir=', 'outname=',
594                                     'default-mudela-fontsize=',
595                                     'force-mudela-fontsize=',
596                                     'help', 'dependencies',
597                                     'force-verbatim', 'init='])
598     except getopt.error, msg:
599         print "error:", msg
600         sys.exit(1)
601         
602     do_deps = 0
603     for opt in options:    
604         o = opt[0]
605         a = opt[1]
606         if o == '--outname' or o == '-o':
607             if len(files) > 1:
608                 #HACK
609                 print "Mudela-book is confused by --outname on multiple files"
610                 sys.exit(1)
611             outname = a
612         if o == '--outdir' or o == '-d':
613             outdir = a
614         if o == '--help' or o == '-h':
615             help ()
616         if o == '--dependencies':
617             do_deps = 1
618         if o == '--default-mudela-fontsize':
619             if not fontsize_pt2i.has_key(a):
620                 print "Error: illegal fontsize:", a
621                 print " accepted fontsizes are: 11pt, 13pt, 16pt, 20pt, 26pt"
622                 sys.exit()
623             Props.setMudelaFontsize(fontsize_pt2i[a], 'init')
624         if o == '--force-mudela-fontsize':
625             if not fontsize_pt2i.has_key(a):
626                 print "Error: illegal fontsize:", a
627                 print " accepted fontsizes are: 11pt, 13pt, 16pt, 20pt, 26pt"
628                 sys.exit()
629             Props.force_mudela_fontsize = fontsize_pt2i[a]
630         if o == '--force-verbatim':
631             Props.force_verbatim_b = 1
632         if o == '--init':
633             initfile =  a
634     if outdir[-1:] != '/':
635         outdir = outdir + '/'
636
637     defined_mudela_cmd = {'mudela': r"""
638 \begin{mudela}[eps \fontoptions]
639     \maininput
640 \end{mudela}
641 """}
642     if initfile != '':
643         f = open(initfile)
644         s = f.read()
645         f.close()
646         d = eval(s)
647         for i in d.keys():
648             defined_mudela_cmd[i] = d[i]
649         del d
650     c = defined_mudela_cmd.keys()[0]
651     for x in defined_mudela_cmd.keys()[1:]:
652         c = c + '|'+x
653     defined_mudela_cmd_re = re.compile("\\\\(%s)(\[(\d*pt)\])*{([^}]*)}" %c)
654
655     if not os.path.isdir(outdir):
656         os.system('mkdir %s' % outdir)
657
658     for input_filename in files:
659         Props.clear_for_new_file()
660         if outname:
661             my_outname = outname
662         else:
663             my_outname = os.path.basename(os.path.splitext(input_filename)[0])
664         my_depname = my_outname + '.dep'        
665         inp = Main_tex_input (input_filename, my_outname)
666         inp.do_it ()
667 #        os.system('latex %s/%s.latex' % (outdir, my_outname))
668         if do_deps:
669             write_deps (my_depname, my_outname, inp.deps)
670
671 identify()
672 Props = Properties()
673 main()