]> git.donarmstrong.com Git - lilypond.git/blobdiff - scripts/lilypond-book.py
Add '-dcrop' option to ps and svg backends
[lilypond.git] / scripts / lilypond-book.py
index 2ede9caf21d5167f8228789a77e290a422ff645f..16f1241af0791fa9e36b327242d4ef16da712f62 100644 (file)
@@ -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
 
 
@@ -413,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)
 
@@ -439,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)]
@@ -465,12 +472,15 @@ def do_process_cmd (chunks, input_name, options):
     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)
+                                           abs_output_dir)
 
 
 ###
@@ -542,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])
 
@@ -609,6 +621,35 @@ def do_file (input_filename, included=False):
         progress (_ ("Removing `%s'") % output_filename)
         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
 
@@ -616,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:
@@ -664,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])
 
@@ -713,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__':