]> git.donarmstrong.com Git - lilypond.git/blobdiff - scripts/lilypond-book.py
* scripts/convert-ly.py (FatalConversionError.conv): conversion
[lilypond.git] / scripts / lilypond-book.py
index fea9750d4c8575155364660b543aba56d42758ff..fa1c65f8bc609fd055163ea93c609a483ff42854 100644 (file)
@@ -1,40 +1,54 @@
 #!@PYTHON@
 # vim: set noexpandtab:
-# TODO:
-# * junk --outdir for--output
-# * Figure out clean set of options.
-# *
-# * texinfo: add support for @pagesize
 
-# todo: dimension handling (all the x2y) is clumsy. (tca: Thats
-#       because the values are taken directly from texinfo.tex,
-#       geometry.sty and article.cls. Give me a hint, and I'll
-#       fix it.)
+"""
 
-#
-# TODO: magnification support should also work for texinfo -> html: eg. add as option to dvips.
-#
+  TODO:
+  * junk --outdir for--output
+  * Figure out clean set of options.
+  *
+  * texinfo: add support for @pagesize
 
+  todo: dimension handling (all the x2y) is clumsy. (tca: Thats
+        because the values are taken directly from texinfo.tex,
+        geometry.sty and article.cls. Give me a hint, and I'll
+        fix it.)
 
-#
-# This is a slightly hairy program. The general approach is as follows 
-# The input string is chopped up in chunks, i.e. ,  a list of tuples
-#
-#   with the format  (TAG_STR, MAIN_STR, OPTIONS, TODO, BASE)
-#
-# This list is build step by step: first ignore and verbatim commands are handled,
-# delivering a list of chunks.
-# 
-# then all chunks containing lilypnod commands are chopped up
-#
-# when all chunks have their final form, all bodies from lilypond blocks are 
-# extracted, and if applicable, written do disk and run through lilypond.
-# 
 
+  TODO: magnification support should also work for texinfo -> html: eg. add as option to dvips.
+
+
+
+  This is a slightly hairy program. The general approach is as follows 
+  The input string is chopped up in chunks, i.e. ,  a list of tuples
+
+    with the format  (TAG_STR, MAIN_STR, OPTIONS, TODO, BASE)
+
+  This list is built step by step: first ignore and verbatim commands
+  are handled, delivering a list of chunks.
+  
+  then all chunks containing lilypond commands are chopped up
+
+  when all chunks have their final form, all bodies from lilypond blocks are 
+  extracted, and if applicable, written do disk and run through lilypond.
+  
+
+tags supported
+
+  ignore
+  lilypond
+  input
+  verb
+  verbatim
+  multicols
+  numcols
+  
 
-# This is was the idea for handling of comments:
 
 
+"""
+
+#  This is was the idea for handling of comments:
 #      Multiline comments, @ignore .. @end ignore is scanned for
 #      in read_doc_file, and the chunks are marked as 'ignore', so
 #      lilypond-book will not touch them any more. The content of the
@@ -364,9 +378,7 @@ output_dict= {
                ## inline music doesn't.
                ## possibly other center options?
                'output-html': r'''
-<a href="%(fn)s.ly">
-<img align="center" valign="center" border="0" src="%(fn)s.png" alt="[picture of music]"></a>
-''',
+%(pageimages)s''',
                },
 
 
@@ -413,7 +425,8 @@ output_dict= {
        'texi' : {
 
 
-               'output-filename' : r'''@ifnothtml
+               'output-filename' : r'''
+@ifnothtml
 @file{%s}:@*
 @end ifnothtml
 @ifhtml
@@ -446,9 +459,8 @@ output_dict= {
 \catcode`\@=0
 @end tex
 @html
-<p><a href="%(fn)s.ly">
-<img border=0 src="%(fn)s.png" alt="[picture of music]">
-</a><p>
+<p>%(htmlimages)s
+<p>
 @end html
 ''',
                'output-texi-quoted': r'''@quotation
@@ -459,9 +471,8 @@ output_dict= {
 \catcode`\@=0
 @end tex
 @html
-<a href="%(fn)s.ly">
-<img border=0 src="%(fn)s.png" alt="[picture of music]">
-</a>
+<p>%(htmlimages)s
+<p>
 @end html
 @end quotation
 ''',
@@ -892,7 +903,9 @@ def make_lilypond_file (m):
        (content, nm) = find_file (m.group ('filename'))
        options.append ("filename=%s" % nm)
 
+
        return [('lilypond', content, options)]
+       
 
 def make_ly2dvi_block (m):
        '''
@@ -958,6 +971,12 @@ def chop_chunks (chunks, re_name, func, use_match=0):
        return newchunks
 
 def determine_format (str):
+       """
+
+       SIDE EFFECT! This sets FORMAT and PAPERGURU
+
+       """
+       
        global format
        if format == '':
                html = re.search ('(?i)<[dh]tml', str[:200])
@@ -1017,14 +1036,16 @@ def unique_file_name (body):
 
 def schedule_lilypond_block (chunk):
        '''Take the body and options from CHUNK, figure out how the
-       real .ly should look, and what should be left MAIN_STR (meant
-       for the main file).  The .ly is written, and scheduled in
+       real .ly should look.  The .ly is written, and scheduled in
        TODO.
 
-       Return: a chunk (TYPE_STR, MAIN_STR, OPTIONS, TODO, BASE)
+       Return: a single chunk.
 
-       TODO has format [basename, extension, extension, ... ]
+       The chunk pertaining to the lilypond output
+       has the format (TYPE_STR, MAIN_STR, OPTIONS, TODO, BASE), 
+       where TODO has format [basename, extension, extension, ... ]
        '''
+
        (type, body, opts) = chunk
        assert type == 'lilypond'
        file_body = compose_full_body (body, opts)
@@ -1066,20 +1087,46 @@ def schedule_lilypond_block (chunk):
                todo.append ('eps')
        if 'png' in needed_filetypes and f (pathbase, '.eps', '.png'):
                todo.append ('png')
-       newbody = ''
 
+       return ('lilypond', body, opts, todo, basename)
+
+def format_lilypond_block (chunk):
+       """
+       
+       Figure out  what should be left MAIN_STR (meant
+       for the main file) from a lilypond chunk: process
+       verbatim, and other options. Return: multiple chunks.
+
+       
+       """
+
+       
+       return_chunks = []
+
+       (type, body, opts, todo, basename) = chunk
+       assert type == 'lilypond'
+
+
+       newbody = ''
+       filename_chunk = None 
        if 'printfilename' in opts:
                for o in opts:
                        m= re.match ("filename=(.*)", o)
                        if m:
-                               newbody = newbody + get_output ("output-filename") % (m.group (1), basename + '.ly', m.group (1))
+                               template = get_output ("output-filename")
+                               b =  basename + '.ly'
+                               human_base = os.path.basename (m.group (1))
+                                                 
+                               ## todo: include path, but strip 
+                               ## first part of the path.
+                               filename_chunk = ('input',  template % (human_base, b,human_base))
                                break
 
 
        if 'smallverbatim' in opts:
-               newbody = newbody + output_verbatim (body, 1)
+               newbody += output_verbatim (body, 1)
        elif 'verbatim' in opts:
-               newbody = newbody + output_verbatim (body, 0)
+               newbody += output_verbatim (body, 0)
 
        for o in opts:
                m = re.search ('intertext="(.*?)"', o)
@@ -1108,9 +1155,43 @@ def schedule_lilypond_block (chunk):
                        s = 'output-texi-noquote'
        else: # format == 'html'
                s = 'output-html'
-       newbody = newbody + get_output (s) % {'fn': basename }
-       return ('lilypond', newbody, opts, todo, basename)
 
+       def html_pages (basename):
+               files =  glob.glob ("%s-page*.png"%  basename)
+
+               template = '''<img align="center" valign="center"
+               border="0" src="%s" alt="[picture of music]">'''
+
+               str = ''
+               if not files:
+                       files = [basename+'.png' ]
+               for  f in  files:
+                       str += template % f
+
+               str = '<a href="%s.ly">%s</a>' % (basename, str)
+               return str
+
+       newbody = newbody + get_output (s) % {'fn': basename,
+                                             'htmlimages': html_pages(basename)
+                                             }
+
+       if filename_chunk:
+               return_chunks += [filename_chunk]
+       
+       return_chunks += [('lilypond', newbody, opts, todo, basename)]
+       
+       return return_chunks
+
+def format_lilypond_output_bodies (chunks):
+       newchunks = []
+       for c in chunks:
+
+               if c[0] == 'lilypond':
+                       newchunks += format_lilypond_block (c)
+               else:
+                       newchunks.append (c)
+
+       return newchunks
 
 
 
@@ -1124,7 +1205,9 @@ def process_lilypond_blocks (chunks):#ugh rename
                        paperguru.m_num_cols = c[2]
                elif c[0] == 'multicols':
                        paperguru.m_multicols = c[2]
+                       
                newchunks.append (c)
+               
        return newchunks
 
 def process_ly2dvi_blocks (chunks):
@@ -1155,7 +1238,7 @@ linking to the menu.
                        
                        ly.system ('%s --preview --postscript --verbose %s ' % (ly2dvi_binary, base) ) 
 
-                       ly.make_page_images (base)
+                       ly.make_ps_images (base)
                        ly.system ('gzip -9 - < %s.ps > %s.ps.gz' %  (base, base))
                        
                def size_str (fn):
@@ -1237,6 +1320,7 @@ def compile_all_files (chunks):
        for c in chunks:
                if c[0] != 'lilypond':
                        continue
+
                base  = c[4]
                exts = c[3]
                for e in exts:
@@ -1296,7 +1380,7 @@ def compile_all_files (chunks):
                ly.system ("dvips -E -o %s.eps %s" % (file, file))
        map (to_eps, eps)
 
-       map (ly.make_preview, png)
+       map (ly.make_ps_images, map (lambda x: x + '.eps', png))
        os.chdir (d)
 
 
@@ -1339,6 +1423,8 @@ def write_deps (fn, target, chunks):
        read_files = []
 
 def check_texidoc (chunks):
+       ## TODO: put file name in front of texidoc. 
+       ##
        n = []
         for c in chunks:
                if c[0] == 'lilypond':
@@ -1392,9 +1478,7 @@ def do_file (input_filename):
        chunks = chop_chunks (chunks, 'preamble-end', do_preamble_end)
        chunks = chop_chunks (chunks, 'numcols', do_columns)
        chunks = chop_chunks (chunks, 'multicols', do_multicols)
-       #print "-" * 50
-       #for c in chunks: print "c:", c;
-       #sys.exit ()
+       
        scan_preamble (chunks)
        chunks = process_lilypond_blocks (chunks)
        chunks = process_ly2dvi_blocks (chunks)
@@ -1409,6 +1493,9 @@ def do_file (input_filename):
        if format == 'texi':
                chunks = check_texidoc (chunks)
 
+       chunks = format_lilypond_output_bodies (chunks)
+
+
        x = 0
        chunks = completize_preamble (chunks)
 
@@ -1524,6 +1611,7 @@ if not files:
 
 ly.setup_environment ()
 
+
 for input_filename in files:
        do_file (input_filename)