X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scripts%2Fly2dvi.py;h=bdd9f4ac5a3fb8c18cfdac074862582b0dea21d3;hb=71cc3b4a5adf79c361d2af39f1a361a36a03f273;hp=2e54f3b792550bec56a4550e849227146cbe8eba;hpb=7572a9065b2f8f99ec3ca543afdd8e92568f2603;p=lilypond.git diff --git a/scripts/ly2dvi.py b/scripts/ly2dvi.py index 2e54f3b792..bdd9f4ac5a 100644 --- a/scripts/ly2dvi.py +++ b/scripts/ly2dvi.py @@ -50,9 +50,6 @@ TODO: ''' - - - import os import stat import string @@ -66,6 +63,11 @@ import tempfile import traceback +################################################################ +# lilylib.py -- options and stuff +# +# source file of the GNU LilyPond music typesetter + # Handle bug in Python 1.6-2.1 # # there are recursion limits for some patterns in Python 1.6 til 2.1. @@ -79,11 +81,14 @@ try: except ImportError: import re - -################################################################ -# lilylib.py -- options and stuff -# -# source file of the GNU LilyPond music typesetter +# Attempt to fix problems with limited stack size set by Python! +# Sets unlimited stack size. Note that the resource module only +# is available on UNIX. +try: + import resource + resource.setrlimit (resource.RLIMIT_STACK, (-1, -1)) +except: + pass try: import gettext @@ -96,7 +101,7 @@ except: program_version = '@TOPLEVEL_VERSION@' if program_version == '@' + 'TOPLEVEL_VERSION' + '@': - program_version = '1.5.17' + program_version = '1.5.54' def identify (): sys.stdout.write ('%s (GNU LilyPond) %s\n' % (program_name, program_version)) @@ -125,8 +130,6 @@ def user_error (s, e=1): sys.exit (e) def error (s): - - '''Report the error S. Exit by raising an exception. Please do not abuse by trying to catch this error. If you do not want a stack trace, write to the output directly. @@ -223,7 +226,7 @@ def setup_temp (): return temp_dir -def system (cmd, ignore_error = 0): +def system (cmd, ignore_error = 0, quiet =0): """Run CMD. If IGNORE_ERROR is set, don't complain when CMD returns non zero. RETURN VALUE @@ -233,12 +236,14 @@ def system (cmd, ignore_error = 0): if verbose_p: progress (_ ("Invoking `%s\'") % cmd) + st = os.system (cmd) if st: name = re.match ('[ \t]*([^ \t]*)', cmd).group (1) msg = name + ': ' + _ ("command exited with value %d") % st if ignore_error: - warning (msg + ' ' + _ ("(ignored)") + ' ') + if not quiet: + warning (msg + ' ' + _ ("(ignored)") + ' ') else: error (msg) @@ -258,19 +263,41 @@ def strip_extension (f, ext): e = '' return p + e -################################################################ -# END Library +def cp_to_dir (pattern, dir): + "Copy files matching re PATTERN from cwd to DIR" + # Duh. Python style portable: cp *.EXT OUTDIR + # system ('cp *.%s %s' % (ext, outdir), 1) + files = filter (lambda x, p=pattern: re.match (p, x), os.listdir ('.')) + map (lambda x, d=dir: shutil.copy2 (x, os.path.join (d, x)), files) +# Python < 1.5.2 compatibility +# +# On most platforms, this is equivalent to +#`normpath(join(os.getcwd()), PATH)'. *Added in Python version 1.5.2* +if os.path.__dict__.has_key ('abspath'): + abspath = os.path.abspath +else: + def abspath (path): + return os.path.normpath (os.path.join (os.getcwd (), path)) +if os.__dict__.has_key ('makedirs'): + makedirs = os.makedirs +else: + def makedirs (dir, mode=0777): + system ('mkdir -p %s' % dir) + + +def mkdir_p (dir, mode=0777): + if not os.path.isdir (dir): + makedirs (dir, mode) # if set, LILYPONDPREFIX must take prevalence # if datadir is not set, we're doing a build and LILYPONDPREFIX datadir = '@datadir@' - if os.environ.has_key ('LILYPONDPREFIX') : datadir = os.environ['LILYPONDPREFIX'] else: @@ -280,6 +307,12 @@ else: while datadir[-1] == os.sep: datadir= datadir[:-1] +sys.path.insert (0, os.path.join (datadir, 'python')) + +################################################################ +# END Library + + program_name = 'ly2dvi' original_dir = os.getcwd () @@ -287,24 +320,8 @@ temp_dir = os.path.join (original_dir, '%s.dir' % program_name) errorport = sys.stderr keep_temp_dir_p = 0 verbose_p = 0 - -try: - import gettext - gettext.bindtextdomain ('lilypond', '@localedir@') - gettext.textdomain ('lilypond') - _ = gettext.gettext -except: - def _ (s): - return s - -# Attempt to fix problems with limited stack size set by Python! -# Sets unlimited stack size. Note that the resource module only -# is available on UNIX. -try: - import resource - resource.setrlimit (resource.RLIMIT_STACK, (-1, -1)) -except: - pass +preview_p = 0 +preview_resolution = 90 help_summary = _ ("Generate .dvi with LaTeX for LilyPond") @@ -318,6 +335,8 @@ option_definitions = [ (_ ("FILE"), 'o', 'output', _ ("write ouput to FILE")), (_ ("FILE"), 'f', 'find-pfa', _ ("find pfa fonts used in FILE")), # why capital P? + ('', '', 'preview', _("Make a picture of the first system.")), + (_ ('RES'), '', 'preview-resolution', _("Set the resolution of the preview to RES.")), ('', 'P', 'postscript', _ ("generate PostScript output")), (_ ("KEY=VAL"), 's', 'set', _ ("change global setting KEY to VAL")), ('', 'V', 'verbose', _ ("verbose")), @@ -354,12 +373,9 @@ lily_p = 1 paper_p = 1 output_name = '' -targets = { - 'DVI' : 0, - 'LATEX' : 0, - 'MIDI' : 0, - 'TEX' : 0, - } + +## docme: what does this do? +targets = [ 'DVI', 'LATEX', 'MIDI', 'TEX'] track_dependencies_p = 0 dependency_files = [] @@ -371,7 +387,10 @@ kpse = re.sub('[ \t\n]+$','', kpse) type1_paths = os.popen ('kpsewhich -expand-path=\$T1FONTS').read () environment = { - ## todo: prevent multiple addition. + # TODO: * prevent multiple addition. + # * clean TEXINPUTS, MFINPUTS, TFMFONTS, + # as these take prevalence over $TEXMF + # and thus may break tex run? 'TEXMF' : "{%s,%s}" % (datadir, kpse) , 'GS_FONTPATH' : type1_paths, 'GS_LIB' : datadir + '/ps', @@ -386,10 +405,9 @@ non_path_environment = { def setup_environment (): # $TEXMF is special, previous value is already taken care of - if os.environ.has_key ('TEXM'): + if os.environ.has_key ('TEXMF'): del os.environ['TEXMF'] - for key in environment.keys (): val = environment[key] if os.environ.has_key (key): @@ -419,6 +437,14 @@ def print_environment (): for (k,v) in os.environ.items (): sys.stderr.write ("%s=\"%s\"\n" % (k,v)) +def quiet_system (cmd, name, ignore_error = 0): + if not verbose_p: + progress ( _("Running %s...") % name) + cmd = cmd + ' 1> /dev/null 2> /dev/null' + + return system (cmd, ignore_error, quiet = 1) + + def run_lilypond (files, outbase, dep_prefix): opts = '' # opts = opts + '--output=%s.tex' % outbase @@ -445,8 +471,22 @@ def run_lilypond (files, outbase, dep_prefix): # for better debugging! print_environment () - print opts, fs - system ('lilypond %s %s ' % (opts, fs)) + + cmd = 'lilypond %s %s ' % (opts, fs) + if verbose_p: + progress ("Invoking `%s'"% cmd) + status = os.system (cmd) + + signal = 0x0f & status + exit_status = status >> 8 + + # 2 == user interrupt. + if signal <> 2: + error("\n\nLilyPond crashed (signal %d). Please submit a bugreport to bug-lilypond@gnu.org\n" % signal) + + if status: + error ("\n\nLilyPond failed on the input file. (exit status %d)\n" % exit_status) + def analyse_lilypond_output (filename, extra): @@ -537,20 +577,18 @@ ly_paper_to_latexpaper = { 'letter' : 'letterpaper', } -def global_latex_definition (tfiles, extra): - - '''construct preamble from EXTRA, dump Latex stuff for each -lily output file in TFILES after that, and return the Latex file constructed. ''' - - +#TODO: should set textheight (enlarge) depending on papersize. +def global_latex_preamble (extra): + '''construct preamble from EXTRA,''' s = "" s = s + '% generation tag\n' options = '' + if extra['papersize']: try: - options = '%s' % ly_paper_to_latexpaper[extra['papersize'][0]] + options = ly_paper_to_latexpaper[extra['papersize'][0]] except KeyError: warning (_ ("invalid value: %s") % `extra['papersize'][0]`) pass @@ -604,7 +642,16 @@ lily output file in TFILES after that, and return the Latex file constructed. ' else: s = s + '\\pagestyle{empty}\n' - s = s + '\\begin{document}\n' + + return s + + +def global_latex_definition (tfiles, extra): + '''construct preamble from EXTRA, dump Latex stuff for each +lily output file in TFILES after that, and return the Latex file constructed. ''' + + + s = global_latex_preamble (extra) + '\\begin{document}\n' s = s + '\\thispagestyle{firstpage}\n' first = 1 @@ -637,12 +684,40 @@ None f.close () cmd = 'latex \\\\nonstopmode \\\\input %s' % latex_fn + status = quiet_system (cmd, 'LaTeX', ignore_error = 1) - if not verbose_p: - progress ( _("Running %s...") % 'LaTeX') - cmd = cmd + ' 1> /dev/null 2> /dev/null' + signal = 0xf & status + exit_stat = status >> 8 - system (cmd) + if exit_stat: + logstr = open (outbase + '.log').read() + m = re.search ("\n!", logstr) + start = m.start (0) + logstr = logstr[start:start+200] + + sys.stderr.write(_("""LaTeX failed on the output file. +The error log is as follows: +%s...\n""" % logstr)) + raise 'LaTeX error' + + if preview_p: + # make a preview by rendering only the 1st line. + preview_fn = outbase + '.preview.tex' + f = open(preview_fn, 'w') + f.write (r''' +%s +\input lilyponddefs +\pagestyle{empty} +\begin{document} +\def\interscoreline{\endinput} +\input %s +\end{document} +''' % (global_latex_preamble (extra), outbase)) + + f.close() + cmd = 'latex \\\\nonstopmode \\\\input %s' % preview_fn + quiet_system (cmd, "LaTeX for preview") + def run_dvips (outbase, extra): @@ -662,12 +737,49 @@ None. opts = opts + ' -tlandscape' cmd = 'dvips %s -o%s %s' % (opts, outbase + '.ps', outbase + '.dvi') + quiet_system (cmd, 'dvips') + + if preview_p: + cmd = 'dvips -E -o%s %s' % ( outbase + '.preview.ps', outbase + '.preview.dvi') + quiet_system (cmd, 'dvips for preview') + +def get_bbox (filename): + # cut & paste + system ('gs -sDEVICE=bbox -q -sOutputFile=- -dNOPAUSE %s -c quit > %s.bbox 2>&1 ' % (filename, filename)) + + box = open (filename + '.bbox').read() + m = re.match ('^%%BoundingBox: ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)', box) + gr = [] + if m: + gr = map (string.atoi, m.groups ()) - if not verbose_p: - progress ( _("Running %s...") % 'dvips') - cmd = cmd + ' 1> /dev/null 2> /dev/null' - - system (cmd) + return gr + +# +# cut & paste from lilypond-book. +# +def make_preview (name, extra): + bbox = get_bbox (name + '.preview.ps') + margin = 0 + fo = open (name + '.trans.eps' , 'w') + fo.write ('%d %d translate\n' % (-bbox[0]+margin, -bbox[1]+margin)) + fo.close () + + x = (2* margin + bbox[2] - bbox[0]) * preview_resolution / 72. + y = (2* margin + bbox[3] - bbox[1]) * preview_resolution / 72. + + cmd = r'''gs -g%dx%d -sDEVICE=pgm -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -q -sOutputFile=- -r%d -dNOPAUSE %s %s -c quit | pnmtopng > %s''' + + cmd = cmd % (x, y, preview_resolution, name + '.trans.eps', name + '.preview.ps',name + '.png') + quiet_system (cmd, 'gs') + + try: + status = system (cmd) + except: + os.unlink (name + '.png') + error ("Removing output file") + + def generate_dependency_file (depfile, outname): df = open (depfile, 'w') @@ -741,14 +853,18 @@ for opt in options: elif o == '--include' or o == '-I': include_path.append (a) elif o == '--postscript' or o == '-P': - targets['PS'] = 0 + targets.append ('PS') elif o == '--keep' or o == '-k': keep_temp_dir_p = 1 elif o == '--no-lily': lily_p = 0 + elif o == '--preview': + preview_p = 1 + targets.append ('PNG') + elif o == '--preview-resolution': + preview_resolution = string.atoi (a) elif o == '--no-paper' or o == '-m': - targets = {} - targets['MIDI'] = 0 + targets = ['MIDI'] paper_p = 0 elif o == '--output' or o == '-o': output_name = a @@ -769,34 +885,6 @@ for opt in options: sys.exit (0) - -def cp_to_dir (pattern, dir): - "Copy files matching re PATTERN from cwd to DIR" - # Duh. Python style portable: cp *.EXT OUTDIR - # system ('cp *.%s %s' % (ext, outdir), 1) - files = filter (lambda x, p=pattern: re.match (p, x), os.listdir ('.')) - map (lambda x, d=dir: shutil.copy2 (x, os.path.join (d, x)), files) - -# Python < 1.5.2 compatibility -# -# On most platforms, this is equivalent to -#`normpath(join(os.getcwd()), PATH)'. *Added in Python version 1.5.2* -if os.path.__dict__.has_key ('abspath'): - abspath = os.path.abspath -else: - def abspath (path): - return os.path.normpath (os.path.join (os.getcwd (), path)) - -if os.__dict__.has_key ('makedirs'): - makedirs = os.makedirs -else: - def makedirs (dir, mode=0777): - system ('mkdir -p %s' % dir) - -def mkdir_p (dir, mode=0777): - if not os.path.isdir (dir): - makedirs (dir, mode) - include_path = map (abspath, include_path) original_output = output_name @@ -835,7 +923,7 @@ if files and files[0] != '-': dep_prefix = 0 reldir = os.path.dirname (output_name) - if outdir != '.' and (track_dependencies_p or targets.keys ()): + if outdir != '.' and (track_dependencies_p or targets): mkdir_p (outdir, 0777) setup_environment () @@ -858,32 +946,40 @@ if files and files[0] != '-': # - init.ly setup failure # - parse error in .ly # - unexpected: assert/core dump - targets = {} + targets = [] traceback.print_exc () - if targets.has_key ('DVI') or targets.has_key ('PS'): + if 'PNG' in targets and 'PS' not in targets: + targets.append ('PS') + if 'PS' in targets and 'DVI' not in targets: + targets.append('DVI') + + if 'DVI' in targets: try: run_latex (files, outbase, extra_init) # unless: add --tex, or --latex? - del targets['TEX'] - del targets['LATEX'] + targets.remove ('TEX') + targets.remove('LATEX') except: # TODO: friendly message about TeX/LaTeX setup, # trying to run tex/latex by hand - if targets.has_key ('DVI'): - del targets['DVI'] - if targets.has_key ('PS'): - del targets['PS'] + if 'DVI' in targets: + targets.remove ('DVI') + if 'PS' in targets: + targets.remove ('PS') traceback.print_exc () - if targets.has_key ('PS'): + if 'PS' in targets: try: run_dvips (outbase, extra_init) except: - if targets.has_key ('PS'): - del targets['PS'] + if 'PS' in targets: + targets.remove ('PS') traceback.print_exc () + if 'PNG' in targets: + make_preview (outbase, extra_init) + # add DEP to targets? if track_dependencies_p: depfile = os.path.join (outdir, outbase + '.dep') @@ -892,7 +988,7 @@ if files and files[0] != '-': progress (_ ("dependencies output to `%s'...") % depfile) # Hmm, if this were a function, we could call it the except: clauses - for i in targets.keys (): + for i in targets: ext = string.lower (i) cp_to_dir ('.*\.%s$' % ext, outdir) outname = outbase + '.' + string.lower (i)