]> git.donarmstrong.com Git - lilypond.git/blob - scripts/ly2dvi.py
patch::: 1.3.150.jcn3
[lilypond.git] / scripts / ly2dvi.py
1 #!@PYTHON@
2 # Run lilypond, latex, dvips.
3 #
4 # This is the third incarnation of ly2dvi.
5 #
6 # Earlier incarnations of ly2dvi were written by
7 # Jeffrey B. Reed<daboys@austin.rr.com> (Python version)
8 # Jan Arne Fagertun <Jan.A.Fagertun@@energy.sintef.no> (Bourne shell script)
9 #
10
11
12 # Note: gettext work best if we use ' for docstrings and "
13 # for gettextable strings
14
15 '''
16 TODO:
17
18   * figure out which set of command line options should make ly2dvi:
19
20       na: create tex only?  
21       na: create latex only? 
22       na: create tex and latex
23       default: create dvi only
24       na: create tex, latex and dvi
25       -P: create dvi and ps
26       na: * create ps only
27
28      etc.
29
30      for foo.ly, rename ly2dvi.dir to out-ly2dvi, foo.ly2dvi, foo.dir ?
31      
32   * move versatile taglines, 
33   
34      \header {
35         beginfooter=\mutopiaPD
36         endfooter=\tagline  -> 'lily was here <version>'
37      }
38
39      lilytagline (->lily was here), usertagline, copyright etc.
40
41   * head/header tagline/endfooter
42
43   * dvi from lilypond .tex output?  This is hairy, because we create dvi
44     from lilypond .tex *and* header output.
45
46   * multiple \score blocks?
47   
48 '''
49
50
51 import os
52 import stat
53 import string
54 import re
55 import getopt
56 import sys
57 import shutil
58 import __main__
59 import operator
60 import tempfile
61
62 datadir = '@datadir@'
63 sys.path.append (datadir + '/python')
64 try:
65         import gettext
66         gettext.bindtextdomain ('lilypond', '@localedir@')
67         gettext.textdomain('lilypond')
68         _ = gettext.gettext
69 except:
70         def _ (s):
71                 return s
72
73
74 layout_fields = ['title', 'subtitle', 'subsubtitle', 'footer', 'head',
75           'composer', 'arranger', 'instrument', 'opus', 'piece', 'metre',
76           'meter', 'poet']
77
78
79 # init to empty; values here take precedence over values in the file 
80 extra_init = {
81         'language' : [],
82         'latexheaders' : [],
83         'latexpackages' :  ['geometry'],
84         'latexoptions' : [],
85         'papersize' : [],
86         'pagenumber' : [1],
87         'textheight' : [], 
88         'linewidth' : [],
89         'orientation' : []
90 }
91
92 extra_fields = extra_init.keys ()
93
94 fields = layout_fields + extra_fields
95 program_name = 'ly2dvi'
96 help_summary = _ ("Generate .dvi with LaTeX for LilyPond")
97
98 include_path = ['.']
99 lily_p = 1
100 paper_p = 1
101
102 output_name = ''
103 targets = {
104         'DVI' : 0,
105         'LATEX' : 0,
106         'MIDI' : 0,
107         'TEX' : 0,
108         }
109
110 track_dependencies_p = 0
111 dependency_files = []
112
113
114 # lily_py.py -- options and stuff
115
116 # source file of the GNU LilyPond music typesetter
117
118 # BEGIN Library for these?
119 # cut-n-paste from ly2dvi
120
121 program_version = '@TOPLEVEL_VERSION@'
122 if program_version == '@' + 'TOPLEVEL_VERSION' + '@':
123         program_version = '1.3.148'
124
125
126 original_dir = os.getcwd ()
127 temp_dir = '%s.dir' % program_name
128 keep_temp_dir_p = 0
129 verbose_p = 0
130
131 #
132 # Try to cater for bad installations of LilyPond, that have
133 # broken TeX setup.  Just hope this doesn't hurt good TeX
134 # setups.  Maybe we should check if kpsewhich can find
135 # feta16.{afm,mf,tex,tfm}, and only set env upon failure.
136 #
137 environment = {
138         'MFINPUTS' : datadir + '/mf:',
139         'TEXINPUTS': datadir + '/tex:' + datadir + '/ps:.:',
140         'TFMFONTS' : datadir + '/tfm:',
141         'GS_FONTPATH' : datadir + '/afm:' + datadir + '/pfa',
142         'GS_LIB' : datadir + '/ps',
143 }
144
145 def setup_environment ():
146         for key in environment.keys ():
147                 val = environment[key]
148                 if os.environ.has_key (key):
149                         val = val + os.pathsep + os.environ[key]
150                 os.environ[key] = val
151
152 def identify ():
153         sys.stdout.write ('%s (GNU LilyPond) %s\n' % (program_name, program_version))
154
155 def warranty ():
156         identify ()
157         sys.stdout.write ('\n')
158         sys.stdout.write (_ ('Copyright (c) %s by' % ' 2001'))
159         sys.stdout.write ('\n')
160         sys.stdout.write ('  Han-Wen Nienhuys')
161         sys.stdout.write ('  Jan Nieuwenhuizen')
162         sys.stdout.write ('\n')
163         sys.stdout.write (_ (r'''
164 Distributed under terms of the GNU General Public License. It comes with
165 NO WARRANTY.'''))
166         sys.stdout.write ('\n')
167
168 if ( os.name == 'posix' ):
169         errorport=sys.stderr
170 else:
171         errorport=sys.stdout
172
173 def progress (s):
174         errorport.write (s + '\n')
175
176 def warning (s):
177         progress (_ ("warning: ") + s)
178                 
179 def error (s):
180
181
182         """Report the error S.  Exit by raising an exception. Please
183         do not abuse by trying to catch this error. If you donn't want
184         a stack trace, write to the output directly.
185
186         RETURN VALUE
187
188         None
189         
190         """
191         
192         progress (_ ("error: ") + s)
193         raise _ ("Exiting ... ")
194
195 def getopt_args (opts):
196         '''Construct arguments (LONG, SHORT) for getopt from  list of options.'''
197         short = ''
198         long = []
199         for o in opts:
200                 if o[1]:
201                         short = short + o[1]
202                         if o[0]:
203                                 short = short + ':'
204                 if o[2]:
205                         l = o[2]
206                         if o[0]:
207                                 l = l + '='
208                         long.append (l)
209         return (short, long)
210
211 def option_help_str (o):
212         '''Transform one option description (4-tuple ) into neatly formatted string'''
213         sh = '  '       
214         if o[1]:
215                 sh = '-%s' % o[1]
216
217         sep = ' '
218         if o[1] and o[2]:
219                 sep = ','
220                 
221         long = ''
222         if o[2]:
223                 long= '--%s' % o[2]
224
225         arg = ''
226         if o[0]:
227                 if o[2]:
228                         arg = '='
229                 arg = arg + o[0]
230         return '  ' + sh + sep + long + arg
231
232
233 def options_help_str (opts):
234         '''Convert a list of options into a neatly formatted string'''
235         w = 0
236         strs =[]
237         helps = []
238
239         for o in opts:
240                 s = option_help_str (o)
241                 strs.append ((s, o[3]))
242                 if len (s) > w:
243                         w = len (s)
244
245         str = ''
246         for s in strs:
247                 str = str + '%s%s%s\n' % (s[0], ' ' * (w - len(s[0])  + 3), s[1])
248         return str
249
250 def help ():
251         ls = [(_ ("Usage: %s [OPTION]... FILE") % program_name),
252                 ('\n\n'),
253                 (help_summary),
254                 ('\n\n'),
255                 (_ ("Options:")),
256                 ('\n'),
257                 (options_help_str (option_definitions)),
258                 ('\n\n'),
259                 (_ ("Report bugs to %s") % 'bug-gnu-music@gnu.org'),
260                 ('\n')]
261         map (sys.stdout.write, ls)
262         
263 def setup_temp ():
264         global temp_dir
265         if not keep_temp_dir_p:
266                 temp_dir = tempfile.mktemp (program_name)
267         try:
268                 os.mkdir (temp_dir, 0777)
269         except OSError:
270                 pass
271         os.chdir (temp_dir)
272
273
274 def system (cmd, ignore_error = 0):
275         """Run CMD. If IGNORE_ERROR is set, don't complain when CMD returns non zero.
276
277         RETURN VALUE
278
279         Exit status of CMD
280         """
281         
282         if ( os.name != 'posix' ):
283                 cmd = re.sub (r'''\\''', r'''\\\\\\''', cmd)
284                 cmd = "sh -c \'%s\'" % cmd
285         if verbose_p:
286                 progress (_ ("Invoking `%s\'") % cmd)
287         st = os.system (cmd) >> 8
288         if st:
289                 name = re.match ('[ \t]*([^ \t]*)', cmd).group (1)
290                 msg = name + ': ' + _ ("command exited with value %d") % st
291                 if ignore_error:
292                         warning (msg + ' ' + _ ("(ignored)") + ' ')
293                 else:
294                         error (msg)
295
296         return st
297
298
299 def cleanup_temp ():
300         if not keep_temp_dir_p:
301                 if verbose_p:
302                         progress (_ ("Cleaning %s...") % temp_dir)
303                 shutil.rmtree (temp_dir)
304
305
306 #what a name.
307 def set_setting (dict, key, val):
308         try:
309                 val = string.atof (val)
310         except ValueError:
311                 #warning (_ ("invalid value: %s") % `val`)
312                 pass
313
314         try:
315                 dict[key].append (val)
316         except KeyError:
317                 warning (_ ("no such setting: %s") % `key`)
318                 dict[key] = [val]
319
320
321 def strip_extension (f, ext):
322         (p, e) = os.path.splitext (f)
323         if e == ext:
324                 e = ''
325         return p + e
326
327 # END Library
328
329 option_definitions = [
330         ('', 'd', 'dependencies', _ ("write Makefile dependencies for every input file")),
331         ('', 'h', 'help', _ ("this help")),
332         (_ ("DIR"), 'I', 'include', _ ("add DIR to LilyPond's search path")),
333         ('', 'k', 'keep', _ ("keep all output, and name the directory %s.dir") % program_name),
334         ('', '', 'no-lily', _ ("don't run LilyPond")),
335         ('', 'm', 'no-paper', _ ("produce MIDI output only")),
336         (_ ("FILE"), 'o', 'output', _ ("write ouput to FILE")),
337         # why capital P?
338         ('', 'P', 'postscript', _ ("generate PostScript output")),
339         (_ ("KEY=VAL"), 's', 'set', _ ("change global setting KEY to VAL")),
340         ('', 'V', 'verbose', _ ("verbose")),
341         ('', 'v', 'version', _ ("print version number")),
342         ('', 'w', 'warranty', _ ("show warranty and copyright")),
343         ]
344
345 def run_lilypond (files, outbase, dep_prefix):
346         opts = ''
347 #       opts = opts + '--output=%s.tex' % outbase
348         opts = opts + ' ' + string.join (map (lambda x : '-I ' + x,
349                                               include_path))
350         if paper_p:
351                 opts = opts + ' ' + string.join (map (lambda x : '-H ' + x,
352                                                       fields))
353         else:
354                 opts = opts + ' --no-paper'
355                 
356         if track_dependencies_p:
357                 opts = opts + " --dependencies"
358                 if dep_prefix:
359                         opts = opts + ' --dep-prefix=%s' % dep_prefix
360
361         fs = string.join (files)
362
363         if not verbose_p:
364                 progress ( _("Running %s...") % 'LilyPond')
365                 # cmd = cmd + ' 1> /dev/null 2> /dev/null'
366         else:
367                 opts = opts + ' --verbose'
368         
369         system ('lilypond %s %s ' % (opts, fs))
370
371 def analyse_lilypond_output (filename, extra):
372         
373         # urg
374         '''Grep FILENAME for interesting stuff, and
375         put relevant info into EXTRA.'''
376         filename = filename+'.tex'
377         progress (_ ("Analyzing %s...") % filename)
378         s = open (filename).read ()
379
380         # search only the first 10k
381         s = s[:10240]
382         for x in ('textheight', 'linewidth', 'papersize', 'orientation'):
383                 m = re.search (r'\\def\\lilypondpaper%s{([^}]*)}'%x, s)
384                 if m:
385                         set_setting (extra, x, m.group (1))
386
387 def find_tex_files_for_base (base, extra):
388
389         """
390         Find the \header fields dumped from BASE.
391         """
392         
393         headerfiles = {}
394         for f in layout_fields:
395                 if os.path.exists (base + '.' + f):
396                         headerfiles[f] = base+'.'+f
397
398         if os.path.exists (base  +'.dep'):
399                 dependency_files.append (base + '.dep')
400
401         for f in extra_fields:
402                 if os.path.exists (base + '.' + f):
403                         extra[f].append (open (base + '.' + f).read ())
404         
405         return (base  +'.tex',headerfiles)
406          
407
408 def find_tex_files (files, extra):
409         """
410         Find all .tex files whose prefixes start with some name in FILES. 
411
412         """
413         
414         tfiles = []
415         
416         for f in files:
417                 x = 0
418                 while 1:
419                         fname = os.path.basename (f)
420                         fname = strip_extension (fname, '.ly')
421                         if x:
422                                 fname = fname + '-%d' % x
423
424                         if os.path.exists (fname + '.tex'):
425                                 tfiles.append (find_tex_files_for_base (fname, extra))
426                                 analyse_lilypond_output (fname, extra)
427                         else:
428                                 break
429
430                         x = x + 1
431         if not x:
432                 fstr = string.join (files, ', ')
433                 warning (_ ("no lilypond output found for %s") % fstr)
434         return tfiles
435
436 def one_latex_definition (defn, first):
437         s = '\n'
438         for (k,v) in defn[1].items ():
439                 val = open (v).read ()
440                 if (string.strip (val)):
441                         s = s + r'''\def\lilypond%s{%s}''' % (k, val)
442                 else:
443                         s = s + r'''\let\lilypond%s\relax''' % k
444                 s = s + '\n'
445
446         if first:
447                 s = s + '\\def\\mustmakelilypondtitle{}\n'
448         else:
449                 s = s + '\\def\\mustmakelilypondpiecetitle{}\n'
450                 
451         s = s + '\\input %s' % defn[0]
452         return s
453
454
455 ly_paper_to_latexpaper =  {
456         'a4' : 'a4paper',
457         'letter' : 'letterpaper', 
458 }
459
460 def global_latex_definition (tfiles, extra):
461
462         '''construct preamble from EXTRA, dump Latex stuff for each
463 lily output file in TFILES after that, and return the Latex file constructed.  '''
464
465
466         s = ""
467         s = s + '% generation tag\n'
468
469         options = ''
470
471         if extra['papersize']:
472                 try:
473                         options = '%s' % ly_paper_to_latexpaper[extra['papersize'][0]]
474                 except KeyError:
475                         warning (_ ("invalid value: %s") % `extra['papersize'][0]`)
476                         pass
477
478         if extra['latexoptions']:
479                 options = options + ',' + extra['latexoptions'][-1]
480
481         s = s + '\\documentclass[%s]{article}\n' % options
482
483         if extra['language']:
484                 s = s + r'\usepackage[%s]{babel}\n' % extra['language'][-1]
485
486
487         s = s + '\\usepackage{%s}\n' \
488                 % string.join (extra['latexpackages'], ',')
489
490         if extra['latexheaders']:
491                 s = s + '\\include{%s}\n' \
492                         % string.join (extra['latexheaders'], '}\n\\include{')
493
494         textheight = ''
495         if extra['textheight']:
496                 textheight = ',textheight=%fpt' % extra['textheight'][0]
497
498         orientation = 'portrait'
499         if extra['orientation']:
500                 orientation = extra['orientation'][0]
501
502         # set sane geometry width (a4-width) for linewidth = -1.
503         if not extra['linewidth'] or extra['linewidth'][0] < 0:
504                 linewidth = 597
505         else:
506                 linewidth = extra['linewidth'][0]
507         s = s + '\geometry{width=%spt%s,headheight=2mm,headsep=12pt,footskip=2mm,%s}\n' % (linewidth, textheight, orientation)
508
509         if extra['latexoptions']:
510                 s = s + '\geometry{twosideshift=4mm}\n'
511
512         s = s + r'''
513 \usepackage[latin1]{inputenc}
514 \input{titledefs}
515 \makeatletter
516 \renewcommand{\@oddfoot}{\parbox{\textwidth}{\mbox{}\thefooter}}%
517 \renewcommand{\@evenfoot}{\parbox{\textwidth}{\mbox{}\thefooter}}%
518 '''
519         
520         if extra['pagenumber'] and extra['pagenumber'][-1] and extra['pagenumber'][-1] != 'no':
521                 s = s + r'''
522 \renewcommand{\@evenhead}{\hbox to\textwidth{\textbf{\thepage}\hfill{\small\theheader}}}
523 \renewcommand{\@oddhead}{\hbox to \textwidth{{\small\theheader}\hfill\textbf{\thepage}}}
524 '''
525         else:
526                 s = s + '\\pagestyle{empty}\n'
527
528         s = s + '\\makeatother\n'
529         s = s + '\\begin{document}\n'
530
531
532         first = 1
533         for t in tfiles:
534                 s = s + one_latex_definition (t, first)
535                 first = 0
536
537         s = s + r'''
538 %% I do not see why we want to clobber the footer here
539 %% \vfill\hfill\parbox{\textwidth}{\mbox{}\makelilypondtagline}
540 %% Well, maybe you don't submit music to mutopia?
541 %% I would not object to this kind of change, but I don't know how
542 %% to get the last mutopia tagline right (ie: no footer on last page)
543 %% Please check that mutopia footers and endfooter are OK before changing
544 %% this again. -- jcn
545 \makeatletter
546 \renewcommand{\@oddfoot}{\parbox{\textwidth}{\makelilypondtagline}}%
547 \makeatother
548 '''
549         s = s + '\\end{document}'
550
551         return s
552
553 def run_latex (files, outbase, extra):
554
555         """Construct latex file, for FILES and EXTRA, dump it into
556 OUTBASE.latex. Run LaTeX on it.
557
558 RETURN VALUE
559
560 None
561         """
562         latex_fn = outbase + '.latex'
563         
564         wfs = find_tex_files (files, extra)
565         s = global_latex_definition (wfs, extra)
566
567         f = open (latex_fn, 'w')
568         f.write (s)
569         f.close ()
570
571         cmd = 'latex \\\\nonstopmode \\\\input %s' % latex_fn
572
573         if not verbose_p and os.name == 'posix':
574                 progress ( _("Running %s...") % 'LaTeX')
575                 cmd = cmd + ' 1> /dev/null 2> /dev/null'
576
577         system (cmd)
578
579 def run_dvips (outbase, extra):
580
581
582         """Run dvips using the correct options taken from EXTRA,
583 leaving a PS file in OUTBASE.ps
584
585 RETURN VALUE
586
587 None.
588 """
589         opts = ''
590         if extra['papersize']:
591                 opts = opts + ' -t%s' % extra['papersize'][0]
592
593         if extra['orientation'] and extra['orientation'][0] == 'landscape':
594                 opts = opts + ' -tlandscape'
595
596         cmd = 'dvips %s -o%s %s' % (opts, outbase + '.ps', outbase + '.dvi')
597         
598         if not verbose_p and os.name == 'posix':
599                 progress ( _("Running %s...") % 'dvips')
600                 cmd = cmd + ' 1> /dev/null 2> /dev/null'
601                 
602         system (cmd)
603
604 def generate_dependency_file (depfile, outname):
605         df = open (depfile, 'w')
606         df.write (outname + ':' )
607         
608         for d in dependency_files:
609                 s = open (d).read ()
610                 s = re.sub ('#[^\n]*\n', '', s)
611                 s = re.sub (r'\\\n', ' ', s)
612                 m = re.search ('.*:(.*)\n', s)
613
614                 # ugh. Different targets?
615                 if m:
616                         df.write ( m.group (1)  + ' ' )
617
618         df.write ('\n')
619         df.close ();
620
621 (sh, long) = getopt_args (__main__.option_definitions)
622 try:
623         (options, files) = getopt.getopt(sys.argv[1:], sh, long)
624 except getopt.error, s: 
625         errorport.write ("\nerror: getopt says `%s\'\n\n" % s)
626         help ()
627         sys.exit (2)
628         
629 for opt in options:     
630         o = opt[0]
631         a = opt[1]
632
633         if 0:
634                 pass
635         elif o == '--help' or o == '-h':
636                 help ()
637                 sys.exit (0)
638         elif o == '--include' or o == '-I':
639                 include_path.append (a)
640         elif o == '--postscript' or o == '-P':
641                 targets['PS'] = 0
642         elif o == '--keep' or o == '-k':
643                 keep_temp_dir_p = 1
644         elif o == '--no-lily':
645                 lily_p = 0
646         elif o == '--no-paper' or o == '-m':
647                 targets = {}
648                 targets['MIDI'] = 0
649                 paper_p = 0
650         elif o == '--output' or o == '-o':
651                 output_name = a
652         elif o == '--set' or o == '-s':
653                 ss = string.split (a, '=')
654                 set_setting (extra_init, ss[0], ss[1])
655         elif o == '--dependencies' or o == '-d':
656                 track_dependencies_p = 1
657         elif o == '--verbose' or o == '-V':
658                 verbose_p = 1
659         elif o == '--version' or o == '-v':
660                 identify ()
661                 sys.exit (0)
662         elif o == '--warranty' or o == '-w':
663                 status = system ('lilypond -w', ignore_error = 1)
664                 if status:
665                         warranty ()
666
667                 sys.exit (0)
668
669
670 def cp_to_dir (pattern, dir):
671         "Copy files matching re PATTERN from cwd to DIR"
672         # Duh.  Python style portable: cp *.EXT OUTDIR
673         # system ('cp *.%s %s' % (ext, outdir), 1)
674         files = filter (lambda x, p=pattern: re.match (p, x), os.listdir ('.'))
675         map (lambda x, d=dir: shutil.copy2 (x, os.path.join (d, x)), files)
676
677 # Python < 1.5.2 compatibility
678 #
679 # On most platforms, this is equivalent to
680 #`normpath(join(os.getcwd()), PATH)'.  *Added in Python version 1.5.2*
681 if os.path.__dict__.has_key ('abspath'):
682         abspath = os.path.abspath
683 else:
684         def abspath (path):
685                 return os.path.normpath (os.path.join (os.getcwd (), path))
686
687 if os.__dict__.has_key ('makedirs'):
688         makedirs = os.makedirs
689 else:
690         def makedirs (dir, mode=0777):
691                 system ('mkdir -p %s' % dir)
692
693 def mkdir_p (dir, mode=0777):
694         if not os.path.isdir (dir):
695                 makedirs (dir, mode)
696
697 include_path = map (abspath, include_path)
698
699 original_output = output_name
700
701 if files and files[0] != '-':
702
703         files = map (lambda x: strip_extension (x, '.ly'), files)
704
705         if not output_name:
706                 output_name = os.path.basename (files[0])
707
708         for i in ('.dvi', '.latex', '.ly', '.ps', '.tex'):
709                 output_name = strip_extension (output_name, i)
710
711         files = map (abspath, files) 
712
713         if os.path.dirname (output_name) != '.':
714                 dep_prefix = os.path.dirname (output_name)
715         else:
716                 dep_prefix = 0
717
718         reldir = os.path.dirname (output_name)
719         (outdir, outbase) = os.path.split (abspath (output_name))
720         
721         setup_environment ()
722         setup_temp ()
723         
724         extra = extra_init
725         
726         if lily_p:
727 ##              try:
728                         run_lilypond (files, outbase, dep_prefix)
729 ## #            except:
730 ##                      # TODO: friendly message about LilyPond setup/failing?
731 ##                      #
732 ##                      # TODO: lilypond should fail with different
733 ##                      # error codes for:
734 ##                      #   - guile setup/startup failure
735 ##                      #   - font setup failure
736 ##                      #   - init.ly setup failure
737 ##                      #   - parse error in .ly
738 ##                      #   - unexpected: assert/core dump
739 ## #                    targets = {}
740
741         if targets.has_key ('DVI') or targets.has_key ('PS'):
742 #               try:
743                         run_latex (files, outbase, extra)
744                         # unless: add --tex, or --latex?
745                         del targets['TEX']
746                         del targets['LATEX']
747 #               except Foobar:
748 #                       # TODO: friendly message about TeX/LaTeX setup,
749 #                       # trying to run tex/latex by hand
750 #                       if targets.has_key ('DVI'):
751 #                               del targets['DVI']
752 #                       if targets.has_key ('PS'):
753 #                               del targets['PS']
754
755         # TODO: does dvips ever fail?
756         if targets.has_key ('PS'):
757                 run_dvips (outbase, extra)
758
759         if outdir != '.' and (track_dependencies_p or targets.keys ()):
760                 mkdir_p (outdir, 0777)
761
762         # add DEP to targets?
763         if track_dependencies_p:
764                 depfile = os.path.join (outdir, outbase + '.dep')
765                 generate_dependency_file (depfile, depfile)
766                 if os.path.isfile (depfile):
767                         progress (_ ("dependencies output to %s...") % depfile)
768
769         for i in targets.keys ():
770                 ext = string.lower (i)
771                 cp_to_dir ('.*\.%s$' % ext, outdir)
772                 outname = outbase + '.' + string.lower (i)
773                 abs = os.path.join (outdir, outname)
774                 if reldir != '.':
775                         outname = os.path.join (reldir, outname)
776                 if os.path.isfile (abs):
777                         progress (_ ("%s output to %s...") % (i, outname))
778                 elif verbose_p:
779                         warning (_ ("can't find file: `%s'") % outname)
780
781         os.chdir (original_dir)
782         cleanup_temp ()
783         
784 else:
785         # FIXME
786         help ()
787         errorport.write ("ly2dvi: error: " + _ ("no files specified on command line.\n"))
788         sys.exit (2)
789
790
791