################################################################
def exit (i):
- if global_options.verbose:
+ if ly.is_verbose ():
raise Exception (_ ('Exiting (%d)...') % 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 ()
%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.")))
+
def get_option_parser ():
p = ly.get_option_parser (usage=_ ("%s [OPTION]... FILE") % 'lilypond-book',
description=help_summary,
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 "
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)
+ p.add_option ('--lily-loglevel',
+ help=_ ("Print lilypond log messages according to LOGLEVEL"),
+ metavar=_ ("LOGLEVEL"),
+ action='store', dest='lily_loglevel',
+ default=os.environ.get ("LILYPOND_LOGLEVEL", None))
+
p.add_option ('--lily-output-dir',
help=_ ("write lily-XXX files to DIR, link into --output dir"),
metavar=_ ("DIR"),
action='append', dest='custom_packages',
default=[])
+ p.add_option ("-l", "--loglevel",
+ help=_ ("Print log messages according to LOGLEVEL "
+ "(NONE, ERROR, WARNING, PROGRESS (default), DEBUG)"),
+ metavar=_ ("LOGLEVEL"),
+ action='callback',
+ callback=ly.handle_loglevel_option,
+ type='string')
+
p.add_option ("-o", '--output', help=_ ("write output to DIR"),
metavar=_ ("DIR"),
action='store', dest='output_dir',
default=False)
p.add_option ('-V', '--verbose', help=_ ("be verbose"),
- action="store_true",
- default=False,
- dest="verbose")
+ action="callback",
+ callback=ly.handle_loglevel_option,
+ callback_args=("DEBUG",))
p.version = "@TOPLEVEL_VERSION@"
p.add_option("--version",
metavar=_ ("PROG"),
action='store', dest='latex_program',
default='latex')
+ group.add_option ('--texinfo-program',
+ help=_ ("run executable PROG instead of texi2pdf"),
+ metavar=_ ("PROG"),
+ action='store', dest='texinfo_program',
+ default='texi2pdf')
group.add_option ('--pdf',
action="store_true",
dest="create_pdf",
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
current = os.getcwd()
os.chdir (directory)
- ly.system(cmd,
- be_verbose=global_options.verbose,
+ """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)
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)
-
def snippet_list_checksum (snippets):
return hash (' '.join([l.basename() for l in snippets]))
#(define output-empty-score-list #f)
#(ly:add-file-name-alist '(%s
))\n
-""" % '\n'.join(['("%s.ly" . "%s")\n' % (ly.basename (), name)
+""" % '\n'.join(['("%s.ly" . "%s")\n' % (ly.basename ().replace('\\','/'), name)
for ly in lys]))
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)]
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)
###
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
progress (_ ("Writing `%s'...") % file_name)
file (file_name, 'w').writelines (lines)
- progress ('\n')
def note_input_file (name, inputs=[]):
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])
try:
progress (_ ("Reading %s...") % input_fullname)
source = in_handle.read ()
- progress ('\n')
if not included:
global_options.formatter.init_default_snippet_options (source)
# 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,
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])
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,
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
(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))
- global_options.include_path = map (os.path.abspath, global_options.include_path)
+ 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.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:
def main ():
# FIXME: 85 lines of `main' macramee??
+ if (os.environ.has_key ("LILYPOND_BOOK_LOGLEVEL")):
+ ly.set_loglevel (os.environ["LILYPOND_BOOK_LOGLEVEL"])
files = do_options ()
basename = os.path.splitext (files[0])[0]
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])
global_options.formatter.process_options (global_options)
- if global_options.verbose:
- global_options.process_cmd += " --verbose "
+ if global_options.lily_loglevel:
+ ly.debug_output (_ ("Setting LilyPond's loglevel to %s") % global_options.lily_loglevel, True)
+ global_options.process_cmd += " --loglevel=%s" % global_options.lily_loglevel
+ elif ly.is_verbose ():
+ if os.environ.get ("LILYPOND_LOGLEVEL", None):
+ ly.debug_output (_ ("Setting LilyPond's loglevel to %s (from environment variable LILYPOND_LOGLEVEL)") % os.environ.get ("LILYPOND_LOGLEVEL", None), True)
+ global_options.process_cmd += " --loglevel=%s" % os.environ.get ("LILYPOND_LOGLEVEL", None)
+ else:
+ ly.debug_output (_ ("Setting LilyPond's output to --verbose, implied by lilypond-book's setting"), True)
+ global_options.process_cmd += " --verbose"
if global_options.padding_mm:
global_options.process_cmd += " -deps-box-padding=%f " % global_options.padding_mm
else:
global_options.lily_output_dir = os.path.abspath(global_options.output_dir)
+ relative_output_dir = global_options.output_dir
identify ()
try:
base_file_name = os.path.splitext (os.path.basename (files[0]))[0]
dep_file = os.path.join (global_options.output_dir, base_file_name + '.dep')
- final_output_file = os.path.join (global_options.output_dir,
- base_file_name
- + '.%s' % global_options.format)
+ final_output_file = os.path.join (relative_output_dir,
+ 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__':