X-Git-Url: https://git.donarmstrong.com/?p=lilypond.git;a=blobdiff_plain;f=scripts%2Flilypond-book.py;h=16f1241af0791fa9e36b327242d4ef16da712f62;hp=69156d715e7f4c100f64dd628354a2bbb19adb49;hb=HEAD;hpb=1ec4c90a6700825a7a126fe1ea7ea224c820c48b diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py index 69156d715e..16f1241af0 100644 --- a/scripts/lilypond-book.py +++ b/scripts/lilypond-book.py @@ -96,13 +96,12 @@ def exit (i): else: sys.exit (i) -def identify (): - ly.encoded_write (sys.stdout, '%s (GNU LilyPond) %s\n' % (ly.program_name, ly.program_version)) - progress = ly.progress warning = ly.warning error = ly.error +def identify (): + progress('%s (GNU LilyPond) %s' % (ly.program_name, ly.program_version)) def warranty (): identify () @@ -113,7 +112,7 @@ def warranty (): %s %s -''' % ( _ ('Copyright (c) %s by') % '2001--2011', +''' % ( _ ('Copyright (c) %s by') % '2001--2015', '\n '.join (authors), _ ("Distributed under terms of the GNU General Public License."), _ ("It comes with NO WARRANTY."))) @@ -143,7 +142,7 @@ def get_option_parser (): p.add_option ("-I", '--include', help=_ ("add DIR to include path"), metavar=_ ("DIR"), action='append', dest='include_path', - default=[os.path.abspath (os.getcwd ())]) + default=[]) p.add_option ('--info-images-dir', help=_ ("format Texinfo output so that Info will " @@ -155,7 +154,7 @@ def get_option_parser (): p.add_option ('--left-padding', metavar=_ ("PAD"), dest="padding_mm", - help=_ ("pad left side of music to align music inspite of uneven bar numbers (in mm)"), + help=_ ("pad left side of music to align music in spite of uneven bar numbers (in mm)"), type="float", default=3.0) @@ -278,6 +277,11 @@ if 'bindir' in globals () and bindir: if '@bindir@' == ('@' + 'bindir@') or not os.path.exists (lilypond_binary): lilypond_binary = 'lilypond' +# Need to shell-quote, issue 3468 + +import pipes +lilypond_binary = pipes.quote (lilypond_binary) + global_options = None @@ -380,11 +384,19 @@ def system_in_directory (cmd, directory, logfile): current = os.getcwd() os.chdir (directory) - ly.system(cmd, + """NB - ignore_error is deliberately set to the same value + as redirect_output - this is not a typo.""" + retval = ly.system(cmd, be_verbose=ly.is_verbose (), redirect_output=global_options.redirect_output, log_file=logfile, - progress_p=1) + progress_p=1, + ignore_error=global_options.redirect_output) + if retval != 0: + print ("Error trapped by lilypond-book") + print ("\nPlease see " + logfile + ".log\n") + sys.exit(1) + os.chdir (current) @@ -405,7 +417,7 @@ def process_snippets (cmd, snippets, logfile = name.replace('.ly', '') file (name, 'wb').write (contents) - system_in_directory (' '.join ([cmd, ly.mkarg (name)]), + system_in_directory (' '.join ([cmd, ly.mkarg (name.replace (os.path.sep, '/'))]), lily_output_dir, logfile) @@ -431,7 +443,10 @@ def split_output_files(directory): Return value is a set of strings. """ files = [] - for subdir in glob.glob (os.path.join (directory, '[a-f0-9][a-f0-9]')): + def globquote(x): + return re.sub ("[][*?]", r"[\g<0>]", x) + for subdir in glob.glob (os.path.join (globquote (directory), + '[a-f0-9][a-f0-9]')): base_subdir = os.path.split (subdir)[1] sub_files = [os.path.join (base_subdir, name) for name in os.listdir (subdir)] @@ -448,25 +463,24 @@ def do_process_cmd (chunks, input_name, options): progress (_ ("Writing snippets...")) for snippet in outdated: snippet.write_ly() - progress ('\n') if outdated: progress (_ ("Processing...")) - progress ('\n') process_snippets (options.process_cmd, outdated, options.formatter, options.lily_output_dir) else: progress (_ ("All snippets are up to date...")) - if options.lily_output_dir != options.output_dir: - output_files = split_output_files (options.lily_output_dir) + progress (_ ("Linking files...")) + abs_lily_output_dir = os.path.join (options.original_dir, options.lily_output_dir) + abs_output_dir = os.path.join (options.original_dir, options.output_dir) + if abs_lily_output_dir != abs_output_dir: + output_files = split_output_files (abs_lily_output_dir) for snippet in snippets: - snippet.link_all_output_files (options.lily_output_dir, + snippet.link_all_output_files (abs_lily_output_dir, output_files, - options.output_dir) - - progress ('\n') + abs_output_dir) ### @@ -488,7 +502,6 @@ def write_if_updated (file_name, lines): new_str = ''.join (lines) if oldstr == new_str: progress (_ ("%s is up to date.") % file_name) - progress ('\n') # this prevents make from always rerunning lilypond-book: # output file must be touched in order to be up to date @@ -503,7 +516,6 @@ def write_if_updated (file_name, lines): progress (_ ("Writing `%s'...") % file_name) file (file_name, 'w').writelines (lines) - progress ('\n') def note_input_file (name, inputs=[]): @@ -540,10 +552,12 @@ def do_file (input_filename, included=False): in_handle = file (input_fullname) if input_filename == '-': + global_options.input_dir = os.getcwd () input_base = 'stdin' elif included: input_base = os.path.splitext (input_filename)[0] else: + global_options.input_dir = os.path.split (input_absname)[0] input_base = os.path.basename ( os.path.splitext (input_filename)[0]) @@ -569,7 +583,6 @@ def do_file (input_filename, included=False): try: progress (_ ("Reading %s...") % input_fullname) source = in_handle.read () - progress ('\n') if not included: global_options.formatter.init_default_snippet_options (source) @@ -580,7 +593,6 @@ def do_file (input_filename, included=False): # Let the formatter modify the chunks before further processing chunks = global_options.formatter.process_chunks (chunks) - progress ('\n') if global_options.filter_cmd: write_if_updated (output_filename, @@ -588,7 +600,6 @@ def do_file (input_filename, included=False): elif global_options.process_cmd: do_process_cmd (chunks, input_fullname, global_options) progress (_ ("Compiling %s...") % output_filename) - progress ('\n') write_if_updated (output_filename, [s.replacement_text () for s in chunks]) @@ -597,7 +608,6 @@ def do_file (input_filename, included=False): os.chdir (original_dir) name = snippet.substring ('filename') progress (_ ("Processing include: %s") % name) - progress ('\n') return do_file (name, included=True) include_chunks = map (process_include, @@ -609,9 +619,37 @@ def do_file (input_filename, included=False): except BookSnippet.CompileError: os.chdir (original_dir) progress (_ ("Removing `%s'") % output_filename) - progress ('\n') raise BookSnippet.CompileError +def adjust_include_path (path, outpath): + """Rewrite an include path relative to the dir where lilypond is launched. + Always use forward slashes since this is what lilypond expects.""" + path = os.path.expanduser (path) + path = os.path.expandvars (path) + path = os.path.normpath (path) + if os.path.isabs (outpath): + return os.path.abspath (path).replace (os.path.sep, '/') + if os.path.isabs (path): + return path.replace (os.path.sep, '/') + return os.path.join (inverse_relpath (original_dir, outpath), path).replace (os.path.sep, '/') + +def inverse_relpath (path, relpath): + """Given two paths, the second relative to the first, + return the first path relative to the second. + Always use forward slashes since this is what lilypond expects.""" + if os.path.isabs (relpath): + return os.path.abspath (path).replace (os.path.sep, '/') + relparts = [''] + parts = os.path.normpath (path).split (os.path.sep) + for part in os.path.normpath (relpath).split (os.path.sep): + if part == '..': + relparts.append (parts[-1]) + parts.pop () + else: + relparts.append ('..') + parts.append (part) + return '/'.join (relparts[::-1]) + def do_options (): global global_options @@ -619,15 +657,28 @@ def do_options (): (global_options, args) = opt_parser.parse_args () global_options.information = {'program_version': ly.program_version, 'program_name': ly.program_name } + global_options.original_dir = original_dir + + if global_options.lily_output_dir: + global_options.lily_output_dir = os.path.expanduser (global_options.lily_output_dir) + for i, path in enumerate(global_options.include_path): + global_options.include_path[i] = adjust_include_path (path, global_options.lily_output_dir) + global_options.include_path.insert (0, inverse_relpath (original_dir, global_options.lily_output_dir)) + + elif global_options.output_dir: + global_options.output_dir = os.path.expanduser (global_options.output_dir) + for i, path in enumerate(global_options.include_path): + global_options.include_path[i] = adjust_include_path (path, global_options.output_dir) + global_options.include_path.insert (0, inverse_relpath (original_dir, global_options.output_dir)) - global_options.include_path = map (os.path.abspath, global_options.include_path) + global_options.include_path.insert (0, "./") # Load the python packages (containing e.g. custom formatter classes) # passed on the command line nr = 0 for i in global_options.custom_packages: nr += 1 - print imp.load_source ("book_custom_package%s" % nr, i) + progress (str(imp.load_source ("book_custom_package%s" % nr, i))) if global_options.warranty: @@ -667,10 +718,6 @@ def main (): if global_options.process_cmd: includes = global_options.include_path - if global_options.lily_output_dir: - # This must be first, so lilypond prefers to read .ly - # files in the other lybookdb dir. - includes = [os.path.abspath(global_options.lily_output_dir)] + includes global_options.process_cmd += ' '.join ([' -I %s' % ly.mkarg (p) for p in includes]) @@ -716,7 +763,7 @@ def main (): base_file_name + global_options.formatter.default_extension) os.chdir (original_dir) - file (dep_file, 'w').write ('%s: %s' + file (dep_file, 'w').write ('%s: %s\n' % (final_output_file, ' '.join (inputs))) if __name__ == '__main__':