X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scripts%2Flilypond-book.py;h=ab4bc7b7960cb35703f6e5383061116075e49b04;hb=1d5869a8edc7148da22ef6981d68bd24e96bc741;hp=e9a133338e511b4a609acb71ce54f9839a0a7d75;hpb=5467e9976c3c1ed7994b8939308cb0ab5decddb2;p=lilypond.git diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py index e9a133338e..ab4bc7b796 100644 --- a/scripts/lilypond-book.py +++ b/scripts/lilypond-book.py @@ -103,18 +103,16 @@ global _;_=ly._ global re;re = ly.re # lilylib globals +program_version = '@TOPLEVEL_VERSION@' program_name = 'lilypond-book' verbose_p = 0 pseudo_filter_p = 0 original_dir = os.getcwd () -#temp_dir = os.path.join (original_dir, '%s.dir' % program_name) -#urg -temp_dir = '/tmp' -keep_temp_dir_p = 0 + + preview_resolution = 90 ## FIXME -## ly2dvi: silly name? ## do -P or -p by default? ##help_summary = _ ("Run LilyPond using LaTeX for titling") help_summary = _ ("Process LilyPond snippets in hybrid html, LaTeX or texinfo document") @@ -126,9 +124,9 @@ option_definitions = [ (_ ("DIM"), '', 'default-music-fontsize', _ ("default fontsize for music. DIM is assumed to be in points")), (_ ("DIM"), '', 'default-lilypond-fontsize', _ ("deprecated, use --default-music-fontsize")), (_ ("OPT"), '', 'extra-options', _ ("pass OPT quoted to the lilypond command line")), - (_ ("DIM"), '', 'force-music-fontsize', _ ("force fontsize for all inline lilypond. DIM is assumed be to in points")), + (_ ("DIM"), '', 'force-music-fontsize', _ ("force fontsize for all inline lilypond. DIM is assumed to be in points")), (_ ("DIM"), '', 'force-lilypond-fontsize', _ ("deprecated, use --force-music-fontsize")), - ('', 'h', 'help', _ ("this help")), + ('', 'h', 'help', _ ("print this help")), (_ ("DIR"), 'I', 'include', _ ("include path")), ('', 'M', 'dependencies', _ ("write dependencies")), (_ ("PREF"), '', 'dep-prefix', _ ("prepend PREF before each -M dependency")), @@ -139,7 +137,7 @@ option_definitions = [ (_ ("FILE"), '', 'outdir', _ ("where to place generated files")), (_ ('RES'), '', 'preview-resolution', _ ("set the resolution of the preview to RES")), - ('', 'V', 'verbose', _ ("verbose")), + ('', 'V', 'verbose', _ ("be verbose")), ('', 'v', 'version', _ ("print version information")), ('', 'w', 'warranty', _ ("show warranty and copyright")), ] @@ -150,14 +148,13 @@ option_definitions = [ include_path = [os.getcwd ()] - #lilypond_binary = 'valgrind --suppressions=/home/hanwen/usr/src/guile-1.6.supp --num-callers=10 /home/hanwen/usr/src/lilypond/lily/out/lilypond' -lilypond_binary = os.path.join ('@bindir@', 'lilypond') +lilypond_binary = os.path.join ('@bindir@', 'lilypond-bin') # only use installed binary when we're installed too. if '@bindir@' == ('@' + 'bindir@') or not os.path.exists (lilypond_binary): - lilypond_binary = 'lilypond' + lilypond_binary = 'lilypond-bin' @@ -221,7 +218,7 @@ class LatexPaper: cmd = "latex '\\nonstopmode \input %s'" % fname # Ugh. (La)TeX writes progress and error messages on stdout # Redirect to stderr - cmd += ' 1>/dev/stderr' + cmd = '(( %s >&2 ) >&- )' % cmd status = ly.system (cmd, ignore_error = 1) signal = 0xf & status exit_status = status >> 8 @@ -230,7 +227,7 @@ class LatexPaper: ly.error (_ ("LaTeX failed.")) ly.error (_ ("The error log is as follows:")) - #URG see ly2dvi + #URG see lilypond try: lns = open ('lily-tmp.log').readlines () except: @@ -378,18 +375,16 @@ output_dict= { ## inline music doesn't. ## possibly other center options? 'output-html': r''' -%(pageimages)s''', +%(htmlimages)s''', }, 'latex': { - 'output-lilypond-fragment' : r'''\begin[eps,singleline,%s]{lilypond} - \context Staff < + 'output-lilypond-fragment' : r'''\begin[singleline,%s]{lilypond} \context Voice{ %s } - > \end{lilypond}''', 'output-filename' : r'''\verb+%s+:\\ %% %s @@ -404,20 +399,22 @@ output_dict= { 'output-small-verbatim': r'''{\small\begin{verbatim} %s\end{verbatim}} ''', - 'output-default-post': "\\def\postLilypondExample{}\n", - 'output-default-pre': "\\def\preLilypondExample{}\n", + 'output-default-post': "\\def\postLilyPondExample{}\n", + 'output-default-pre': "\\def\preLilyPondExample{}\n", 'usepackage-graphics': '\\usepackage{graphics}\n', - 'output-eps': '\\noindent\\parbox{\\lilypondepswidth{%(fn)s.eps}}{\includegraphics{%(fn)s}}', + 'output-eps': '\\noindent\includegraphics{%(fn)s}', 'output-noinline': r''' %% generated: %(fn)s.eps ''', - 'output-latex-quoted': r'''{\preLilypondExample + 'output-latex-quoted': r'''{\preLilyPondExample +\def\lilypondbook{} \input %(fn)s.tex -\postLilypondExample}''', +\postLilyPondExample}''', 'output-latex-noquote': r'''{\parindent 0pt -\preLilypondExample +\preLilyPondExample +\def\lilypondbook{} \input %(fn)s.tex -\postLilypondExample}''', +\postLilyPondExample}''', 'pagebreak': r'\pagebreak', }, @@ -543,8 +540,8 @@ re_dict = { 'lilypond-file': r'(?m)^[^%\n]*?(?P\\lilypondfile\s*(\[(?P.*?)\])?\s*\{(?P.+)})', 'lilypond' : r'(?m)^[^%\n]*?(?P\\lilypond\s*(\[(?P.*?)\])?\s*{(?P.*?)})', 'lilypond-block': r"(?sm)^[^%\n]*?(?P\\begin\s*(\[(?P.*?)\])?\s*{lilypond}(?P.*?)\\end{lilypond})", - 'def-post-re': r"\\def\\postLilypondExample", - 'def-pre-re': r"\\def\\preLilypondExample", + 'def-post-re': r"\\def\\postLilyPondExample", + 'def-pre-re': r"\\def\\preLilyPondExample", 'usepackage-graphics': r"\usepackage\s*{graphics}", 'intertext': r',?\s*intertext=\".*?\"', 'multiline-comment': no_match, @@ -558,7 +555,7 @@ re_dict = { # why do we have distinction between @mbinclude and @include? 'texi': { - 'include': '(?m)^[^%\n]*?(?P@mbinclude[ \n\t]+(?P[^\t \n]*))', + 'include': '(?m)^[^%\n]*?(?P@mbinclude\s+(?P\S*))', 'input': no_match, 'header': no_match, 'preamble-end': no_match, @@ -635,7 +632,7 @@ def error (str): def compose_full_body (body, opts): - '''Construct the lilypond code to send to Lilypond. + '''Construct the lilypond code to send to LilyPond. Add stuff to BODY using OPTS as options.''' music_size = default_music_fontsize if g_force_music_fontsize: @@ -692,6 +689,7 @@ def compose_full_body (body, opts): } ''' + orig_name = '' for o in opts: m= re.search ('relative(.*)', o) v = 0 @@ -709,7 +707,10 @@ def compose_full_body (body, opts): pitch = pitch + '\'' * v body = '\\relative %s { %s }' % (pitch, body) - + m =re.search ("filename=(.*)", o) + if m: + orig_name = m.group (1) + if is_fragment: body = r''' \score { @@ -725,7 +726,8 @@ def compose_full_body (body, opts): body = r''' %% Generated automatically by: lilypond-book.py %% options are %s -\include "paper%d.ly" +#(set-global-staff-size %d) + \paper { %s %s @@ -733,6 +735,10 @@ def compose_full_body (body, opts): } ''' % (optstring, music_size, linewidth, indent, notime) + body + if orig_name: + body = '\\renameinput \"%s\"\n%s' % (orig_name, body) + + # ughUGH not original options return body @@ -753,7 +759,7 @@ def scan_latex_preamble (chunks): if not m: error ("Latex documents must start with a \documentclass command") if m.group (1): - options = re.split (',[\n \t]*', m.group (1)[1:-1]) + options = re.split (r',\s*', m.group (1)[1:-1]) else: options = [] if 'twocolumn' in options: @@ -902,7 +908,10 @@ def make_lilypond_file (m): options = [] (content, nm) = find_file (m.group ('filename')) options.append ("filename=%s" % nm) - + (path, base) = os.path.split (nm) + + if path not in include_path: + include_path.append (path) return [('lilypond', content, options)] @@ -1061,7 +1070,7 @@ def schedule_lilypond_block (chunk): taken_file_names[basename] = 0 else: taken_file_names[basename] = taken_file_names[basename] + 1 - basename = basename + "-%i" % taken_file_names[basename] + basename = basename + "-t%i" % taken_file_names[basename] update_file (file_body, os.path.join (g_outdir, basename) + '.ly') needed_filetypes = ['tex'] @@ -1072,20 +1081,31 @@ def schedule_lilypond_block (chunk): needed_filetypes.append ('eps') pathbase = os.path.join (g_outdir, basename) - def f (base, ext1, ext2): - a = os.path.isfile (base + ext2) - if (os.path.isfile (base + ext1) and - os.path.isfile (base + ext2) and - os.stat (base+ext1)[stat.ST_MTIME] > - os.stat (base+ext2)[stat.ST_MTIME]) or \ - not os.path.isfile (base + ext2): + def must_rebuild (base, ext1, ext2): + + f2 = base + ext2 + f1 = base + ext1 + fp2 = base + '-page1' + ext2 + + isfile2 = os.path.isfile (f2) + + if not isfile2 and os.path.isfile (fp2): + f2 = fp2 + isfile2 = os.path.isfile (fp2) + + if (os.path.isfile (f2) and isfile2 and + os.stat (f1)[stat.ST_MTIME] > + os.stat (f2)[stat.ST_MTIME]) or \ + not isfile2: + return 1 + todo = [] - if 'tex' in needed_filetypes and f (pathbase, '.ly', '.tex'): + if 'tex' in needed_filetypes and must_rebuild (pathbase, '.ly', '.tex'): todo.append ('tex') - if 'eps' in needed_filetypes and f (pathbase, '.tex', '.eps'): + if 'eps' in needed_filetypes and must_rebuild (pathbase, '.tex', '.eps'): todo.append ('eps') - if 'png' in needed_filetypes and f (pathbase, '.eps', '.png'): + if 'png' in needed_filetypes and must_rebuild (pathbase, '.eps', '.png'): todo.append ('png') return ('lilypond', body, opts, todo, basename) @@ -1141,13 +1161,12 @@ def format_lilypond_block (chunk): if 'noinline' in opts: s = 'output-noinline' elif format == 'latex': - if 'eps' in opts: + if 'quote' in opts: + s = 'output-latex-quoted' + elif 'eps' in opts: s = 'output-eps' else: - if 'quote' in opts: - s = 'output-latex-quoted' - else: - s = 'output-latex-noquote' + s = 'output-latex-noquote' elif format == 'texi': if 'quote' in opts: s = 'output-texi-quoted' @@ -1241,7 +1260,7 @@ linking to the menu. outname = base + '.ly' changed = update_file (content, outname) - preview = base + ".png" + preview = base + ".preview.png" preview_page = base + '-page1.png' if changed or not (os.path.isfile (preview) or @@ -1249,7 +1268,7 @@ linking to the menu. ly.system ('%s --preview --postscript --verbose %s ' % (ly2dvi_binary, base) ) - ly.make_ps_images (base) + ly.make_ps_images (base + '.ps') ly.system ('gzip -9 - < %s.ps > %s.ps.gz' % (base, base)) def size_str (fn): @@ -1272,7 +1291,7 @@ linking to the menu. menu = '' page_files = glob.glob ('%s-page*.png' % base) - for p in string.split (page_files, '\n'): + for p in page_files: p = p.strip() if os.path.isfile (p): sz = size_str (p) @@ -1310,7 +1329,7 @@ use scalable fonts and should look OK at any resolution.""" open (base + '.html','w'). write (separate_menu) - inline_menu = '

' % (base, original_name, preview) + inline_menu = '

%s

' % (base, original_name, preview) return ('ly2dvi', inline_menu) @@ -1363,6 +1382,9 @@ def compile_all_files (chunks): texfiles = string.join (tex) cmd = string.join ((lilypond_binary, lilyopts, g_extra_opts, texfiles)) + + ly.lilypond_version_check (lilypond_binary, '@TOPLEVEL_VERSION@') + ly.system (cmd, ignore_error = 0, progress_p = 1) # @@ -1386,12 +1408,14 @@ def compile_all_files (chunks): cmd = r"latex '\nonstopmode \input %s'" % file # Ugh. (La)TeX writes progress and error messages on stdout # Redirect to stderr - cmd += ' 1>/dev/stderr' + cmd = '(( %s >&2 ) >&- )' % cmd + ly.system (cmd) - ly.system ("dvips -E -o %s.eps %s" % (file, file)) + ly.system ("dvips -Ppdf -u+lilypond.map -E -o %s.eps %s" % (file, file)) map (to_eps, eps) - map (ly.make_ps_images, map (lambda x: x + '.eps', png)) + for p in png: + ly.make_ps_images (p + '.eps', resolution=110) os.chdir (d) @@ -1443,7 +1467,7 @@ def check_texidoc (chunks): pathbase = os.path.join (g_outdir, basename) if os.path.isfile (pathbase + '.texidoc') \ and 'notexidoc' not in opts: - n.append( ('input', '\n@include %s.texidoc\n' % basename)) + n.append( ('input', '\n@include %s.texidoc\n\n' % basename)) n.append (c) return n @@ -1568,7 +1592,7 @@ for opt in options: elif o == '--outname' or o == '-o': if len (files) > 1: #HACK - sys.stderr.write ("Lilypond-book is confused by --outname on multiple files") + sys.stderr.write ("lilypond-book is confused by --outname on multiple files") sys.exit (1) outname = a elif o == '--help' or o == '-h':