X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scripts%2Flilypond-book.py;h=74db6adb28d4b9ac83958c0e9934f043ee28ab27;hb=dd8c9c17123e9e01399b64ac134fba5eea4e895c;hp=75c5c14c81cf953ce0ef41da42f65356b619c1bd;hpb=115da674d3223d2e71e8f3222000a114e0cec47b;p=lilypond.git diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py index 75c5c14c81..74db6adb28 100644 --- a/scripts/lilypond-book.py +++ b/scripts/lilypond-book.py @@ -17,7 +17,7 @@ TODO: * this script is too complex. Modularize. * ly-options: intertext? - * --linewidth? + * --line-width? * eps in latex / eps by lilypond -b ps? * check latex parameters, twocolumn, multicolumn? * use --png --ps --pdf for making images? @@ -28,12 +28,13 @@ TODO: ''' -import __main__ -import glob import stat import string import tempfile import commands +import os +import sys +import re # Users of python modules should include this snippet # and customize variables below. @@ -43,37 +44,49 @@ import commands # If set, LILYPONDPREFIX must take prevalence. # if datadir is not set, we're doing a build and LILYPONDPREFIX. -import getopt, os, sys + +################ +# RELOCATION +################ + datadir = '@local_lilypond_datadir@' if not os.path.isdir (datadir): datadir = '@lilypond_datadir@' + +sys.path.insert (0, os.path.join (datadir, 'python')) + if os.environ.has_key ('LILYPONDPREFIX'): datadir = os.environ['LILYPONDPREFIX'] while datadir[-1] == os.sep: datadir= datadir[:-1] datadir = os.path.join (datadir, "share/lilypond/current/") - sys.path.insert (0, os.path.join (datadir, 'python')) -# Customize these. -#if __name__ == '__main__': +# dynamic relocation, for GUB binaries. +bindir = os.path.split (sys.argv[0])[0] + + +for prefix_component in ['share', 'lib']: + datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % prefix_component) + sys.path.insert (0, datadir) + import lilylib as ly import fontextract global _;_=ly._ -global re;re = ly.re + # Lilylib globals. program_version = '@TOPLEVEL_VERSION@' program_name = os.path.basename (sys.argv[0]) -verbose_p = 0 -pseudo_filter_p = 0 + original_dir = os.getcwd () backend = 'ps' help_summary = _ ( '''Process LilyPond snippets in hybrid HTML, LaTeX, or texinfo document. + Example usage: lilypond-book --filter="tr '[a-z]' '[A-Z]'" BOOK @@ -81,51 +94,98 @@ Example usage: lilypond-book --process='lilypond -I include' BOOK ''') -copyright = ('Jan Nieuwenhuizen ', +authors = ('Jan Nieuwenhuizen ', 'Han-Wen Nienhuys ') -option_definitions = [ - (_ ("FMT"), 'f', 'format', - _ ('''use output format FMT (texi [default], texi-html, - latex, html)''')), - (_ ("FILTER"), 'F', 'filter', - _ ("pipe snippets through FILTER [convert-ly -n -]")), - ('', 'h', 'help', - _ ("print this help")), - (_ ("DIR"), 'I', 'include', - _ ("add DIR to include path")), - (_ ("DIR"), 'o', 'output', - _ ("write output to DIR")), - (_ ("COMMAND"), 'P', 'process', - _ ("process ly_files using COMMAND FILE...")), - ('', '', 'psfonts', - _ ('''extract all PostScript fonts into INPUT.psfonts for LaTeX - must use this with dvips -h INPUT.psfonts''')), - ('', '', 'keep-line-breaks', - _ ('''do not alter the number of newline characters in output - .tex files. Useful when the LaTeX package srcltx is used''')), - ('', 'V', 'verbose', - _ ("be verbose")), - ('', 'v', 'version', - _ ("print version information")), - ('', 'w', 'warranty', - _ ("show warranty and copyright")), -] + +################################################################ +def exit (i): + if global_options.verbose: + raise _ ('Exiting (%d)...') % i + else: + sys.exit (i) + +def identify (): + sys.stdout.write ('%s (GNU LilyPond) %s\n' % (program_name, program_version)) + +def progress (s): + sys.stderr.write (s) + +def warning (s): + sys.stderr.write (program_name + ": " + _ ("warning: %s") % s + '\n') + +def error (s): + sys.stderr.write (program_name + ": " + _ ("error: %s") % s + '\n') + +def warranty (): + identify () + sys.stdout.write (''' +%s + +%s + +%s +%s +''' % ( _('Copyright (c) %s by') % '2001--2006', + ' '.join (authors), + _('Distributed under terms of the GNU General Public License.'), + _('It comes with NO WARRANTY.'))) + + +def get_option_parser (): + p = ly.get_option_parser (usage='lilypond-book [OPTIONS] FILE', + version="@TOPLEVEL_VERSION@", + description=help_summary) + + p.add_option ('-F', '--filter', metavar=_ ("FILTER"), + action="store", + dest="filter_cmd", + help=_ ("pipe snippets through FILTER [convert-ly -n -]"), + default=None) + p.add_option ('-f', '--format', help=_('''use output format FORMAT (texi [default], texi-html, latex, html)'''), + action='store') + p.add_option ("-I", '--include', help=_('add DIR to include path'), + metavar="DIR", + action='append', dest='include_path', + default=[os.path.abspath (os.getcwd ())]) + + p.add_option ("-o", '--output', help=_('write output to DIR'), + metavar="DIR", + action='store', dest='output_name', default=None) + p.add_option ('-P', '--process', metavar=_("COMMAND"), + help = _ ("process ly_files using COMMAND FILE..."), + action='store', + dest='process_cmd', default='lilypond -b eps') + + p.add_option ('', '--psfonts', action="store_true", dest="psfonts", + help=_ ('''extract all PostScript fonts into INPUT.psfonts for LaTeX''' + '''must use this with dvips -h INPUT.psfonts'''), + default=None) + p.add_option ('-V', '--verbose', help=_("be verbose"), + action="store_true", + default=False, + dest="verbose") + + p.add_option ('-w', '--warranty', + help=_("show warranty and copyright"), + action='store_true') + + + p.add_option_group ('bugs', + description='''Report bugs via http://post.gmane.org/post.php''' + '''?group=gmane.comp.gnu.lilypond.bugs\n''') + + return p -include_path = [os.path.abspath (os.getcwd ())] lilypond_binary = os.path.join ('@bindir@', 'lilypond') # Only use installed binary when we are installed too. if '@bindir@' == ('@' + 'bindir@') or not os.path.exists (lilypond_binary): lilypond_binary = 'lilypond' -psfonts_p = 0 -srcltx_p = 0 -use_hash_p = 1 -format = 0 -output_name = '' -filter_cmd = 0 -process_cmd = '' +global_options = None + + default_ly_options = { 'alt': "[image of music]" } # @@ -140,7 +200,7 @@ HTML = 'html' INDENT = 'indent' LATEX = 'latex' LAYOUT = 'layout' -LINEWIDTH = 'linewidth' +LINE_WIDTH = 'line-width' NOFRAGMENT = 'nofragment' NOINDENT = 'noindent' NOQUOTE = 'noquote' @@ -153,7 +213,7 @@ PAPER = 'paper' PREAMBLE = 'preamble' PRINTFILENAME = 'printfilename' QUOTE = 'quote' -RAGGEDRIGHT = 'raggedright' +RAGGED_RIGHT = 'ragged-right' RELATIVE = 'relative' STAFFSIZE = 'staffsize' TEXIDOC = 'texidoc' @@ -374,6 +434,9 @@ snippet_res = { }, } + + + format_res = { HTML: { 'intertext': r',?\s*intertext=\".*?\"', @@ -415,11 +478,11 @@ ly_options = { PAPER: { INDENT: r'''indent = %(indent)s''', - LINEWIDTH: r'''linewidth = %(linewidth)s''', + LINE_WIDTH: r'''line-width = %(line-width)s''', - QUOTE: r'''linewidth = %(linewidth)s - 2.0 * %(exampleindent)s''', + QUOTE: r'''line-width = %(line-width)s - 2.0 * %(exampleindent)s''', - RAGGEDRIGHT: r'''raggedright = ##t''', + RAGGED_RIGHT: r'''ragged-right = ##t''', PACKED: r'''packed = ##t''', }, @@ -475,21 +538,21 @@ output = { ## LATEX: { - OUTPUT: r'''{ -\parindent 0pt -\catcode`\@=12 -\ifx\preLilyPondExample \undefined - \relax -\else - \preLilyPondExample -\fi -\def\lilypondbook{} -\input %(base)s-systems.tex -\ifx\postLilyPondExample \undefined - \relax -\else - \postLilyPondExample -\fi + OUTPUT: r'''{%% +\parindent 0pt%% +\catcode`\@=12%% +\ifx\preLilyPondExample \undefined%% + \relax%% +\else%% + \preLilyPondExample%% +\fi%% +\def\lilypondbook{}%% +\input %(base)s-systems.tex%% +\ifx\postLilyPondExample \undefined%% + \relax%% +\else%% + \postLilyPondExample%% +\fi%% }''', PRINTFILENAME: '''\\texttt{%(filename)s} @@ -544,19 +607,32 @@ output = { ''', VERBATIM: r'''@exampleindent 0 -@example -%(verb)s@end example +@verbatim +%(verb)s@end verbatim ''', }, } -PREAMBLE_LY = r'''%%%% Generated by %(program_name)s +# +# Maintain line numbers. +# + +## TODO +if 0: + for f in [HTML, LATEX]: + for s in (QUOTE, VERBATIM): + output[f][s] = output[f][s].replace("\n"," ") + + +PREAMBLE_LY = '''%%%% Generated by %(program_name)s %%%% Options: [%(option_string)s] #(set! toplevel-score-handler print-score-with-defaults) -#(set! toplevel-music-handler (lambda (p m) - (print-score-with-defaults - p (scorify-music m p)))) +#(set! toplevel-music-handler + (lambda (p m) + (if (not (eq? (ly:music-property m \'void) #t)) + (print-score-with-defaults + p (scorify-music m p))))) #(ly:set-option (quote no-point-and-click)) #(define inside-lilypond-book #t) @@ -614,7 +690,7 @@ FULL_LY = ''' %% **************************************************************** ''' -texinfo_linewidths = { +texinfo_line_widths = { '@afourpaper': '160\\mm', '@afourwide': '6.5\\in', '@afourlatex': '150\\mm', @@ -624,7 +700,7 @@ texinfo_linewidths = { def classic_lilypond_book_compatibility (key, value): if key == 'singleline' and value == None: - return (RAGGEDRIGHT, None) + return (RAGGED_RIGHT, None) m = re.search ('relative\s*([-0-9])', key) if m: @@ -634,7 +710,7 @@ def classic_lilypond_book_compatibility (key, value): if m: return ('staffsize', m.group (1)) - if key == 'indent' or key == 'linewidth': + if key == 'indent' or key == 'line-width': m = re.match ('([-.0-9]+)(cm|in|mm|pt|staffspace)', value) if m: f = float (m.group (1)) @@ -643,12 +719,13 @@ def classic_lilypond_book_compatibility (key, value): return (None, None) def find_file (name): - for i in include_path: + for i in global_options.include_path: full = os.path.join (i, name) if os.path.exists (full): return full - ly.error (_ ("file not found: %s") % name + '\n') - ly.exit (1) + + error (_ ("file not found: %s") % name + '\n') + exit (1) return '' def verbatim_html (s): @@ -656,35 +733,27 @@ def verbatim_html (s): re.sub ('<', '<', re.sub ('&', '&', s))) -def verbatim_texinfo (s): - return re.sub ('{', '@{', - re.sub ('}', '@}', - re.sub ('@', '@@', s))) - def split_options (option_string): if option_string: - if format == HTML: + if global_options.format == HTML: options = re.findall('[\w\.-:]+(?:\s*=\s*(?:"[^"]*"|\'[^\']*\'|\S+))?',option_string) for i in range(len(options)): options[i] = re.sub('^([^=]+=\s*)(?P["\'])(.*)(?P=q)','\g<1>\g<3>',options[i]) return options else: - return re.split (format_res[format]['option_sep'], + return re.split (format_res[global_options.format]['option_sep'], option_string) return [] -def invokes_lilypond (): - return re.search ('^[\'\"0-9A-Za-z/]*lilypond', process_cmd) - def set_default_options (source): global default_ly_options - if not default_ly_options.has_key (LINEWIDTH): - if format == LATEX: + if not default_ly_options.has_key (LINE_WIDTH): + if global_options.format == LATEX: textwidth = get_latex_textwidth (source) - default_ly_options[LINEWIDTH] = \ + default_ly_options[LINE_WIDTH] = \ '''%.0f\\pt''' % textwidth - elif format == TEXINFO: - for (k, v) in texinfo_linewidths.items (): + elif global_options.format == TEXINFO: + for (k, v) in texinfo_line_widths.items (): # FIXME: @layout is usually not in # chunk #0: # @@ -694,7 +763,7 @@ def set_default_options (source): # source. # s = chunks[0].replacement_text () if re.search (k, source[:1024]): - default_ly_options[LINEWIDTH] = v + default_ly_options[LINE_WIDTH] = v break class Chunk: @@ -751,7 +820,7 @@ class Snippet (Chunk): class Include_snippet (Snippet): def processed_filename (self): f = self.substring ('filename') - return os.path.splitext (f)[0] + format2ext[format] + return os.path.splitext (f)[0] + format2ext[global_options.format] def replacement_text (self): s = self.match.group ('match') @@ -790,42 +859,42 @@ class Lilypond_snippet (Snippet): else: self.option_dict[i] = None - has_linewidth = self.option_dict.has_key (LINEWIDTH) - no_linewidth_value = 0 + has_line_width = self.option_dict.has_key (LINE_WIDTH) + no_line_width_value = 0 - # If LINEWIDTH is used without parameter, set it to default. - if has_linewidth and self.option_dict[LINEWIDTH] == None: - no_linewidth_value = 1 - del self.option_dict[LINEWIDTH] + # If LINE_WIDTH is used without parameter, set it to default. + if has_line_width and self.option_dict[LINE_WIDTH] == None: + no_line_width_value = 1 + del self.option_dict[LINE_WIDTH] for i in default_ly_options.keys (): if i not in self.option_dict.keys (): self.option_dict[i] = default_ly_options[i] - if not has_linewidth: + if not has_line_width: if type == 'lilypond' or FRAGMENT in self.option_dict.keys (): - self.option_dict[RAGGEDRIGHT] = None + self.option_dict[RAGGED_RIGHT] = None if type == 'lilypond': - if LINEWIDTH in self.option_dict.keys (): - del self.option_dict[LINEWIDTH] + if LINE_WIDTH in self.option_dict.keys (): + del self.option_dict[LINE_WIDTH] else: - if RAGGEDRIGHT in self.option_dict.keys (): - if LINEWIDTH in self.option_dict.keys (): - del self.option_dict[LINEWIDTH] + if RAGGED_RIGHT in self.option_dict.keys (): + if LINE_WIDTH in self.option_dict.keys (): + del self.option_dict[LINE_WIDTH] if QUOTE in self.option_dict.keys () or type == 'lilypond': - if LINEWIDTH in self.option_dict.keys (): - del self.option_dict[LINEWIDTH] + if LINE_WIDTH in self.option_dict.keys (): + del self.option_dict[LINE_WIDTH] if not INDENT in self.option_dict.keys (): self.option_dict[INDENT] = '0\\mm' - # The QUOTE pattern from ly_options only emits the `linewidth' + # The QUOTE pattern from ly_options only emits the `line-width' # keyword. - if has_linewidth and QUOTE in self.option_dict.keys (): - if no_linewidth_value: - del self.option_dict[LINEWIDTH] + if has_line_width and QUOTE in self.option_dict.keys (): + if no_line_width_value: + del self.option_dict[LINE_WIDTH] else: del self.option_dict[QUOTE] @@ -862,7 +931,7 @@ class Lilypond_snippet (Snippet): # To set @exampleindent locally to zero, we use the @format # environment for non-quoted snippets. override[EXAMPLEINDENT] = r'0.4\in' - override[LINEWIDTH] = texinfo_linewidths['@smallbook'] + override[LINE_WIDTH] = texinfo_line_widths['@smallbook'] override.update (default_ly_options) option_list = [] @@ -883,17 +952,17 @@ class Lilypond_snippet (Snippet): classic_lilypond_book_compatibility (key, value) if c_key: if c_value: - ly.warning \ + warning \ (_ ("deprecated ly-option used: %s=%s" \ % (key, value))) - ly.warning \ + warning \ (_ ("compatibility mode translation: %s=%s" \ % (c_key, c_value))) else: - ly.warning \ + warning \ (_ ("deprecated ly-option used: %s" \ % key)) - ly.warning \ + warning \ (_ ("compatibility mode translation: %s" \ % c_key)) @@ -913,11 +982,11 @@ class Lilypond_snippet (Snippet): break if not found and key not in simple_options: - ly.warning (_ ("ignoring unknown ly option: %s") % key) + warning (_ ("ignoring unknown ly option: %s") % key) # URGS if RELATIVE in override.keys () and override[RELATIVE]: - relative = string.atoi (override[RELATIVE]) + relative = int (override[RELATIVE]) relative_quotes = '' @@ -927,8 +996,6 @@ class Lilypond_snippet (Snippet): elif relative > 0: relative_quotes += "'" * relative - program_name = __main__.program_name - paper_string = string.join (compose_dict[PAPER], '\n ') % override layout_string = string.join (compose_dict[LAYOUT], @@ -937,12 +1004,14 @@ class Lilypond_snippet (Snippet): '\n ') % vars () preamble_string = string.join (compose_dict[PREAMBLE], '\n ') % override - + font_dump_setting = '' if FONTLOAD in self.option_dict: font_dump_setting = '#(define-public force-eps-font-include #t)\n' - return (PREAMBLE_LY + body) % vars () + d = globals().copy() + d.update (locals()) + return (PREAMBLE_LY + body) % d # TODO: Use md5? def get_hash (self): @@ -953,7 +1022,7 @@ class Lilypond_snippet (Snippet): def basename (self): if FILENAME in self.option_dict: return self.option_dict[FILENAME] - if use_hash_p: + if global_options.use_hash: return 'lily-%d' % self.get_hash () raise 'to be done' @@ -974,7 +1043,7 @@ class Lilypond_snippet (Snippet): and os.path.exists (system_file)\ and os.stat (system_file)[stat.ST_SIZE] \ and re.match ('% eof', open (system_file).readlines ()[-1]) - if ok and (not use_hash_p or FILENAME in self.option_dict): + if ok and (not global_options.use_hash or FILENAME in self.option_dict): ok = (self.full_ly () == open (ly_file).read ()) if ok: # TODO: Do something smart with target formats @@ -985,7 +1054,7 @@ class Lilypond_snippet (Snippet): def png_is_outdated (self): base = self.basename () ok = self.ly_is_outdated () - if format == HTML or format == TEXINFO: + if global_options.format in (HTML, TEXINFO): ok = ok and os.path.exists (base + '.eps') page_count = 0 @@ -1041,11 +1110,11 @@ class Lilypond_snippet (Snippet): def output_html (self): str = '' base = self.basename () - if format == HTML: + if global_options.format == HTML: str += self.output_print_filename (HTML) if VERBATIM in self.option_dict: verb = verbatim_html (self.substring ('code')) - str += write (output[HTML][VERBATIM] % vars ()) + str += output[HTML][VERBATIM] % vars () if QUOTE in self.option_dict: str = output[HTML][QUOTE] % vars () @@ -1069,21 +1138,25 @@ class Lilypond_snippet (Snippet): str += output[TEXINFO][OUTPUTIMAGE] % vars () base = self.basename () - str += output[format][OUTPUT] % vars () + str += output[global_options.format][OUTPUT] % vars () return str def output_latex (self): str = '' base = self.basename () - if format == LATEX: + if global_options.format == LATEX: str += self.output_print_filename (LATEX) if VERBATIM in self.option_dict: verb = self.substring ('code') str += (output[LATEX][VERBATIM] % vars ()) - elif srcltx_p: - breaks = self.substring ('code').count ("\n") - str += "".ljust (breaks, "\n").replace("\n","%\n") + str += (output[LATEX][OUTPUT] % vars ()) + + ## todo: maintain breaks + if 0: + breaks = self.ly ().count ("\n") + str += "".ljust (breaks, "\n").replace ("\n","%\n") + if QUOTE in self.option_dict: str = output[LATEX][QUOTE] % vars () return str @@ -1093,7 +1166,7 @@ class Lilypond_snippet (Snippet): if PRINTFILENAME in self.option_dict: base = self.basename () filename = self.substring ('filename') - str = output[format][PRINTFILENAME] % vars () + str = output[global_options.format][PRINTFILENAME] % vars () return str @@ -1113,7 +1186,7 @@ class Lilypond_snippet (Snippet): str += '@include %(texidoc)s\n\n' % vars () if VERBATIM in self.option_dict: - verb = verbatim_texinfo (self.substring ('code')) + verb = self.substring ('code') str += (output[TEXINFO][VERBATIM] % vars ()) if not QUOTE in self.option_dict: str = output[TEXINFO][NOQUOTE] % vars () @@ -1164,7 +1237,7 @@ def find_linestarts (s): def find_toplevel_snippets (s, types): res = {} for i in types: - res[i] = ly.re.compile (snippet_res[format][i]) + res[i] = ly.re.compile (snippet_res[global_options.format][i]) snippets = [] index = 0 @@ -1190,6 +1263,7 @@ def find_toplevel_snippets (s, types): for type in types: if not found[type] or found[type][0] < index: found[type] = None + m = res[type].search (s[index:endex]) if not m: continue @@ -1205,7 +1279,8 @@ def find_toplevel_snippets (s, types): line_number += 1 line_number += 1 - snip = cl (type, m, format, line_number) + snip = cl (type, m, global_options.format, line_number) + found[type] = (start, snip) if found[type] \ @@ -1241,8 +1316,8 @@ def find_toplevel_snippets (s, types): return snippets def filter_pipe (input, cmd): - if verbose_p: - ly.progress (_ ("Opening filter `%s'") % cmd) + if global_options.verbose: + progress (_ ("Opening filter `%s'") % cmd) (stdin, stdout, stderr) = os.popen3 (cmd) stdin.write (input) @@ -1259,19 +1334,19 @@ def filter_pipe (input, cmd): signal = 0x0f & status if status or (not output and error): exit_status = status >> 8 - ly.error (_ ("`%s' failed (%d)") % (cmd, exit_status)) - ly.error (_ ("The error log is as follows:")) + error (_ ("`%s' failed (%d)") % (cmd, exit_status)) + error (_ ("The error log is as follows:")) sys.stderr.write (error) sys.stderr.write (stderr.read ()) - ly.exit (status) + exit (status) - if verbose_p: - ly.progress ('\n') + if global_options.verbose: + progress ('\n') return output def run_filter (s): - return filter_pipe (s, filter_cmd) + return filter_pipe (s, global_options.filter_cmd) def is_derived_class (cl, baseclass): if cl == baseclass: @@ -1295,13 +1370,13 @@ def process_snippets (cmd, ly_snippets, texstr_snippets, png_snippets): ignore_error = 1, progress_p = 1) if status: - ly.error ('Process %s exited unsuccessfully.' % cmd) + error ('Process %s exited unsuccessfully.' % cmd) raise Compile_error # UGH # the --process=CMD switch is a bad idea # it is too generic for lilypond-book. - if texstr_names and invokes_lilypond: + if texstr_names: my_system (string.join ([cmd, '--backend texstr', 'snippet-map.ly'] + texstr_names)) for l in texstr_names: @@ -1325,30 +1400,30 @@ def get_latex_textwidth (source): m = re.search (r'''(?P\\begin\s*{document})''', source) preamble = source[:m.start (0)] latex_document = LATEX_INSPECTION_DOCUMENT % vars () - # Workaround problems with unusable $TMP on Cygwin: - tempfile.tempdir = '' - tmpfile = tempfile.mktemp('.tex') + + (handle, tmpfile) = tempfile.mkstemp('.tex') logfile = os.path.splitext (tmpfile)[0] + '.log' open (tmpfile,'w').write (latex_document) ly.system ('latex %s' % tmpfile) parameter_string = open (logfile).read() + os.unlink (tmpfile) os.unlink (logfile) columns = 0 m = re.search ('columns=([0-9.]*)', parameter_string) if m: - columns = string.atoi (m.group (1)) + columns = int (m.group (1)) columnsep = 0 m = re.search ('columnsep=([0-9.]*)pt', parameter_string) if m: - columnsep = string.atof (m.group (1)) + columnsep = float (m.group (1)) textwidth = 0 m = re.search ('textwidth=([0-9.]*)pt', parameter_string) if m: - textwidth = string.atof (m.group (1)) + textwidth = float (m.group (1)) if columns: textwidth = (textwidth - columnsep) / columns @@ -1425,17 +1500,17 @@ def do_process_cmd (chunks, input_name): and x.png_is_outdated (), chunks) - ly.progress (_ ("Writing snippets...")) + progress (_ ("Writing snippets...")) map (Lilypond_snippet.write_ly, ly_outdated) - ly.progress ('\n') + progress ('\n') if ly_outdated: - ly.progress (_ ("Processing...")) - ly.progress ('\n') - process_snippets (process_cmd, ly_outdated, texstr_outdated, png_outdated) + progress (_ ("Processing...")) + progress ('\n') + process_snippets (global_options.process_cmd, ly_outdated, texstr_outdated, png_outdated) else: - ly.progress (_ ("All snippets are up to date...")) - ly.progress ('\n') + progress (_ ("All snippets are up to date...")) + progress ('\n') def guess_format (input_filename): format = None @@ -1444,9 +1519,9 @@ def guess_format (input_filename): # FIXME format = ext2format[e] else: - ly.error (_ ("can't determine format for: %s" \ + error (_ ("can't determine format for: %s" \ % input_filename)) - ly.exit (1) + exit (1) return format def write_if_updated (file_name, lines): @@ -1455,15 +1530,20 @@ def write_if_updated (file_name, lines): oldstr = f.read () new_str = string.join (lines, '') if oldstr == new_str: - ly.progress (_ ("%s is up to date.") % file_name) - ly.progress ('\n') + progress (_ ("%s is up to date.") % file_name) + progress ('\n') return except: pass - ly.progress (_ ("Writing `%s'...") % file_name) + progress (_ ("Writing `%s'...") % file_name) open (file_name, 'w').writelines (lines) - ly.progress ('\n') + progress ('\n') + +def note_input_file (name, inputs=[]): + ## hack: inputs is mutable! + inputs.append (name) + return inputs def do_file (input_filename): # Ugh. @@ -1473,12 +1553,12 @@ def do_file (input_filename): else: if os.path.exists (input_filename): input_fullname = input_filename - elif format == LATEX and ly.search_exe_path ('kpsewhich'): - # urg python interface to libkpathsea? - input_fullname = ly.read_pipe ('kpsewhich ' - + input_filename)[:-1] + elif global_options.format == LATEX and ly.search_exe_path ('kpsewhich'): + input_fullname = os.read_pipe ('kpsewhich ' + input_filename).read()[:-1] else: input_fullname = find_file (input_filename) + + note_input_file (input_fullname) in_handle = open (input_fullname) if input_filename == '-': @@ -1488,28 +1568,28 @@ def do_file (input_filename): (os.path.splitext (input_filename)[0]) # Only default to stdout when filtering. - if output_name == '-' or (not output_name and filter_cmd): + if global_options.output_name == '-' or (not global_options.output_name and global_options.filter_cmd): output_filename = '-' output_file = sys.stdout else: - # don't complain when output_name is existing - output_filename = input_base + format2ext[format] - if output_name: - if not os.path.isdir (output_name): - os.mkdir (output_name, 0777) - os.chdir (output_name) + # don't complain when global_options.output_name is existing + output_filename = input_base + format2ext[global_options.format] + if global_options.output_name: + if not os.path.isdir (global_options.output_name): + os.mkdir (global_options.output_name, 0777) + os.chdir (global_options.output_name) else: if os.path.exists (input_filename) \ and os.path.exists (output_filename) \ and os.path.samefile (output_filename, input_fullname): - ly.error ( + error ( _ ("Output would overwrite input file; use --output.")) - ly.exit (2) + exit (2) try: - ly.progress (_ ("Reading %s...") % input_fullname) + progress (_ ("Reading %s...") % input_fullname) source = in_handle.read () - ly.progress ('\n') + progress ('\n') set_default_options (source) @@ -1526,24 +1606,24 @@ def do_file (input_filename): 'include', 'lilypond', ) - ly.progress (_ ("Dissecting...")) + progress (_ ("Dissecting...")) chunks = find_toplevel_snippets (source, snippet_types) - if format == LATEX: + if global_options.format == LATEX: for c in chunks: if (c.is_plain () and re.search (r"\\begin *{document}", c.replacement_text())): modify_preamble (c) break - ly.progress ('\n') + progress ('\n') - if filter_cmd: + if global_options.filter_cmd: write_if_updated (output_filename, [c.filter_text () for c in chunks]) - elif process_cmd: + elif global_options.process_cmd: do_process_cmd (chunks, input_fullname) - ly.progress (_ ("Compiling %s...") % output_filename) - ly.progress ('\n') + progress (_ ("Compiling %s...") % output_filename) + progress ('\n') write_if_updated (output_filename, [s.replacement_text () for s in chunks]) @@ -1551,8 +1631,8 @@ def do_file (input_filename): def process_include (snippet): os.chdir (original_dir) name = snippet.substring ('filename') - ly.progress (_ ("Processing include: %s") % name) - ly.progress ('\n') + progress (_ ("Processing include: %s") % name) + progress ('\n') return do_file (name) include_chunks = map (process_include, @@ -1565,128 +1645,101 @@ def do_file (input_filename): except Compile_error: os.chdir (original_dir) - ly.progress (_ ("Removing `%s'") % output_filename) - ly.progress ('\n') + progress (_ ("Removing `%s'") % output_filename) + progress ('\n') raise Compile_error def do_options (): - global format, output_name, psfonts_p, srcltx_p - global filter_cmd, process_cmd, verbose_p - (sh, long) = ly.getopt_args (option_definitions) - try: - (options, files) = getopt.getopt (sys.argv[1:], sh, long) - except getopt.error, s: - sys.stderr.write ('\n') - ly.error (_ ("getopt says: `%s'" % s)) - sys.stderr.write ('\n') - ly.help () - ly.exit (2) - - for opt in options: - o = opt[0] - a = opt[1] + global global_options - if 0: - pass - elif o == '--filter' or o == '-F': - filter_cmd = a - process_cmd = 0 - elif o == '--format' or o == '-f': - format = a - if a == 'texi-html' or a == 'texi': - format = TEXINFO - elif o == '--tex-backend ': - backend = 'tex' - elif o == '--help' or o == '-h': - ly.help () - sys.exit (0) - elif o == '--include' or o == '-I': - include_path.append (os.path.join (original_dir, - os.path.abspath (a))) - elif o == '--output' or o == '-o': - output_name = a - elif o == '--process' or o == '-P': - process_cmd = a - filter_cmd = 0 - elif o == '--version' or o == '-v': - ly.identify (sys.stdout) - sys.exit (0) - elif o == '--verbose' or o == '-V': - verbose_p = 1 - elif o == '--psfonts': - psfonts_p = 1 - elif o == '--keep-line-breaks': - srcltx_p = 1 - for s in (OUTPUT, QUOTE, VERBATIM): - output[LATEX][s] = output[LATEX][s].replace("\n"," ") - elif o == '--warranty' or o == '-w': - if 1 or status: - ly.warranty () - sys.exit (0) - return files + opt_parser = get_option_parser() + (global_options, args) = opt_parser.parse_args () + + if global_options.format in ('texi-html', 'texi'): + global_options.format = TEXINFO + global_options.use_hash = True + + global_options.include_path = map (os.path.abspath, global_options.include_path) + + if global_options.warranty: + warranty () + exit (0) + if not args or len (args) > 1: + opt_parser.print_help () + exit (2) + + return args def main (): files = do_options () - if not files or len (files) > 1: - ly.help () - ly.exit (2) file = files[0] basename = os.path.splitext (file)[0] basename = os.path.split (basename)[1] - global process_cmd, format - if not format: - format = guess_format (files[0]) + if not global_options.format: + global_options.format = guess_format (files[0]) formats = 'ps' - if format == TEXINFO or format == HTML: + if global_options.format in (TEXINFO, HTML): formats += ',png' - if process_cmd == '': - process_cmd = lilypond_binary \ + if global_options.process_cmd == '': + global_options.process_cmd = lilypond_binary \ + ' --formats=%s --backend eps ' % formats - if process_cmd: - process_cmd += string.join ([(' -I %s' % commands.mkarg (p)) - for p in include_path]) + if global_options.process_cmd: + global_options.process_cmd += string.join ([(' -I %s' % commands.mkarg (p)) + for p in global_options.include_path]) - ly.identify (sys.stderr) + identify () try: chunks = do_file (file) - if psfonts_p and invokes_lilypond (): - fontextract.verbose = verbose_p + if global_options.psfonts: + fontextract.verbose = global_options.verbose snippet_chunks = filter (lambda x: is_derived_class (x.__class__, Lilypond_snippet), chunks) psfonts_file = basename + '.psfonts' - if not verbose_p: - ly.progress (_ ("Writing fonts to %s...") % psfonts_file) + if not global_options.verbose: + progress (_ ("Writing fonts to %s...") % psfonts_file) fontextract.extract_fonts (psfonts_file, [x.basename() + '.eps' for x in snippet_chunks]) - if not verbose_p: - ly.progress ('\n') + if not global_options.verbose: + progress ('\n') except Compile_error: - ly.exit (1) + exit (1) - if format == TEXINFO or format == LATEX: - if not psfonts_p: - ly.warning (_ ("option --psfonts not used")) - ly.warning (_ ("processing with dvips will have no fonts")) + if global_options.format in (TEXINFO, LATEX): + if not global_options.psfonts: + warning (_ ("option --psfonts not used")) + warning (_ ("processing with dvips will have no fonts")) - psfonts_file = os.path.join (output_name, basename + '.psfonts') - output = os.path.join (output_name, basename + '.dvi' ) + psfonts_file = os.path.join (global_options.output_name, basename + '.psfonts') + output = os.path.join (global_options.output_name, basename + '.dvi' ) - ly.progress ('\n') - ly.progress (_ ("DVIPS usage:")) - ly.progress ('\n') - ly.progress (" dvips -h %(psfonts_file)s %(output)s" % vars ()) - ly.progress ('\n') + progress ('\n') + progress (_ ("DVIPS usage:")) + progress ('\n') + progress (" dvips -h %(psfonts_file)s %(output)s" % vars ()) + progress ('\n') + + inputs = note_input_file ('') + inputs.pop () + + base_file_name = os.path.splitext (os.path.basename (file))[0] + dep_file = os.path.join (global_options.output_name, base_file_name + '.dep') + final_output_file = os.path.join (global_options.output_name, + base_file_name + + '.%s' % global_options.format) + + os.chdir (original_dir) + open (dep_file, 'w').write ('%s: %s' % (final_output_file, ' '.join (inputs))) if __name__ == '__main__': main ()