]> git.donarmstrong.com Git - lilypond.git/commitdiff
* python/lilylib.py (make_page_images): add function.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Wed, 5 Mar 2003 17:37:14 +0000 (17:37 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Wed, 5 Mar 2003 17:37:14 +0000 (17:37 +0000)
* scripts/ly2dvi.py (run_latex): include title in preview image.

* scripts/lilypond-book.py (process_ly2dvi_blocks): call ly2dvi
from lilypond-book for <ly2dvifile> tags in HTML.

* scripts/ly2dvi.py (option_definitions): add --debug option to
print out environment.

ChangeLog
Documentation/user/appendices.itely
Documentation/user/invoking.itexi
Documentation/user/lilypond-book.itely
Documentation/user/refman.itely
Documentation/user/tutorial.itely
python/lilylib.py
scripts/lilypond-book.py
scripts/ly2dvi.py

index 5d9d85022620d6d7446e9a3a10d4f20ef06b30b1..0d136aa92afdbb7bd27aa11acd65a54e069f2ddd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2003-03-05  Han-Wen Nienhuys  <hanwen@cs.uu.nl>
 
+       * python/lilylib.py (make_page_images): add function.
+
+       * scripts/ly2dvi.py (run_latex): include title in preview image.
+
+       * scripts/lilypond-book.py (process_ly2dvi_blocks): call ly2dvi
+       from lilypond-book for <ly2dvifile> tags in HTML.
+
+       * scripts/ly2dvi.py (option_definitions): add --debug option to
+       print out environment.
+
        * input/regression/tie-chord-partial.ly: new file.
 
 2003-03-05  Heikki Junes <hjunes@cc.hut.fi>
index c151df2cc313c98b978b5f8844eb35de10891e6d..1f594e1593a6151e3b4c03da90f74b90c4b84af9 100644 (file)
@@ -97,7 +97,7 @@ rules.
 @section The Feta font
 The following symbols are available in the Feta font and may be
 accessed directly using text markup such as 
-@code{g^#'(music "scripts-segno")}, see @ref{Text markup}.
+@code{g^\markup @{ \musicglyph #"scripts-segno" @}}, see @ref{Text markup}.
 
 @lilypondfile[noquote,noindent]{feta16list.ly}
 
index ea699c3f1016e5be3cdf34f4d87d724b44166397..1f7275dcd77533c96720b1bdc91e3e3be8eea1ec 100644 (file)
@@ -214,7 +214,7 @@ developers, send a @emph{small} sample file.
 system libraries, whether you downloaded a binary release)
 
 @item If necessary, send a description of the bug itself.  If you
-include output a ly2dvi run, please use @code{--verbose} option of
+include output a ly2dvi run, please use @code{--debug} option of
 ly2dvi.
 
 @end itemize
@@ -277,8 +277,16 @@ through @code{ps2pdf} producing a PDF file.
 @code{\usepackage[latin1]@{inputenc@}} if you use any other
 non-anglosaxian characters.
 
-    @item --preview
+@item --preview
     Also generate a picture of the first system of the score.
+
+@cindex preview
+@cindex picture
+@cindex bitmap
+@cindex pixmap
+@cindex thumbnail
+@cindex screenshot
+    
 @item -s,--set=@var{key}=@var{val}
     Add @var{key}= @var{val} to the settings, overriding those specified
 in the files. Possible keys: @code{language}, @code{latexheaders},
@@ -286,9 +294,11 @@ in the files. Possible keys: @code{language}, @code{latexheaders},
 @code{pagenumber}, @code{linewidth}, @code{orientation},
 @code{textheight}.
 @item -v,--version
-Show version information 
+Show version information .
 @item -V,--verbose
-Be verbose
+Be verbose.
+@item --debug
+Print even more information. This is useful when generating bugreports.
 @item -w,--warranty
 Show the warranty with which GNU LilyPond comes. (It comes with 
 @strong{NO WARRANTY}!)
index cd3cd356a221fe2f5894e896e33fd35f8c45f11e..be091ae181d1175c22c92aa95c4a39c6c2160cc4 100644 (file)
@@ -206,12 +206,26 @@ For inline pictures, use @code{<lilypond ... />} syntax, eg.
 Some music in <lilypond a b c/> a line of text.
 @end example
 
+A special feature not (yet) available in other output formats, is the
+@code{<ly2dvifile>} tag, for example
+@example
+  <ly2dvifile>trip.ly</ly2dvifile>
+@end example
+This runs @file{trip.ly} through ly2dvi (See also @ref{Invoking
+ly2dvi}), and substitutes a preview image in the output. The image
+links to a separate HTML file, so clicking it will take the viewer to
+a menu, with links to images, midi and printouts.
+
+@cindex ly2dvi
+@cindex titling in THML
+@cindex preview image
+@cindex thumbnail
 
 @node Music fragment options
 @section Music fragment options
 
-The commands for lilypond-book have room to specify options.  These are
-all of the options:
+The commands for lilypond-book have room to specify options.  These
+are all of the options:
 
 @table @code
 @item eps
index 905b2d2436c7daa4b7cfab710be7fd9eb2a1f72d..6fa0bd454be655b87619e9a1c52489adad0616bb 100644 (file)
@@ -3646,10 +3646,11 @@ The @code{\mark} command can also be used to put signs like coda,
 segno and fermatas on a barline.  The trick is to use the text markup
 mechanism to access the fermata symbol.
 @lilypond[fragment,verbatim,relative=1]
-  c1 \mark #'(music "scripts-ufermata") 
+  c1 \mark \markup { \musicglyph #"scripts-ufermata" }
   c1
 @end lilypond
 
+
 The problem is that marks that occur at a line break are typeset only
 at the beginning of the next line, opposite to what you want for the
 fermata. This can be corrected by the following property setting
index 4350b8909e1e883c94c3d6140cbafcd046d0d0d9..59f147a1af6fb022b76bed753e49c25a23b08599 100644 (file)
@@ -2150,13 +2150,14 @@ a collision with the slur.  This could be achieved with
 works.  We insert an empty text between the 5 and the note. The empty
 text pushes the fingering instruction away:
 @example
-  a^" "^#'(finger "5")
+  a-)^" "^\markup { \finger "5" } 
 @end example
 
-Lilypond tries to put fingering instructions as close to the notes as
-possible.  To make sure that Lilypond doesn't do that, we disguise the
-fingering as text: @code{(finger "5")}.
-
+A fingering instruction, which would be entered as @code{^5}, is put
+as close to the notes as possible, closer than the space entered to 
+push away the 5. Hence, the 5 is entered as a normal text, formatting
+of fingering instructions.  
 @separate
 
 Normally one would specify all dynamics in the same voice, so that
index 3f0b0e7302c3a5db5bf7cc07214dc32846643e4e..49078c5ab2aeb13a45c428e9693d1c09e2173527 100644 (file)
@@ -99,7 +99,7 @@ underscore = _
 
 program_version = '@TOPLEVEL_VERSION@'
 if program_version == '@' + 'TOPLEVEL_VERSION' + '@':
-       program_version = '1.7.5'
+       program_version = '1.7.14'
 
 def identify (port):
        port.write ('%s (GNU LilyPond) %s\n' % (__main__.program_name, program_version))
@@ -421,8 +421,6 @@ def make_preview (name):
        cmd = r'''gs -g%dx%d -sDEVICE=pnggray  -dTextAlphaBits=4 -dGraphicsAlphaBits=4  -q -sOutputFile=%s -r%d -dNOPAUSE %s %s -c quit ''' % \
              (x, y, png, __main__.preview_resolution, trans_ps, preview_ps)
        
-       system (cmd)
-
        status = system (cmd)
        signal = 0xf & status
        exit_status = status >> 8
@@ -431,3 +429,14 @@ def make_preview (name):
                os.unlink (png)
                error (_ ("Removing output file"))
                exit (1)
+
+def make_page_images (name, resolution = 90):
+
+       """ Generate images for
+       all pages in the PS file NAME. NAME should be the basename
+       (not including the extension.).
+       """
+       
+       cmd = 'gs -sDEVICE=pnggray -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile="%s-page%%d.png" -r%d -dNOPAUSE %s -c quit'
+       cmd = cmd % (name, resolution, name + '.ps')
+       system (cmd)
index 4dbafe498dd6c08e428251fcb6aa556f5ff3b123..bb217b0b93a3462a53f79b87f8cab86c33810048 100644 (file)
 # 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 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.
+# 
+
+
 # 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
 #      chunks are written to the output file. Also 'include' and 'input'
 #      regex has to check if they are commented out.
 #
+
 #      Then it is scanned for 'lilypond', 'lilypond-file' and 'lilypond-block'.
 #      These three regex's has to check if they are on a commented line,
 #      % for latex, @c for texinfo.
@@ -140,7 +160,9 @@ default_music_fontsize = 16
 default_text_fontsize = 12
 paperguru = None
 
-
+################################################################
+# Dimension handling for LaTeX.
+# 
 class LatexPaper:
        def __init__ (self):
                self.m_document_preamble = []
@@ -297,6 +319,9 @@ html_linewidths = {
        'smallbook': {12: in2pt (5)},
        'letterpaper': {12: in2pt (6)}}
 
+
+################################################################
+# How to output various structures. 
 output_dict= {
 
 
@@ -460,7 +485,11 @@ def output_verbatim (body, small):
        return get_output (key) % body
 
 
-# Warning: This uses extended regular expressions.  Treat with care.
+################################################################
+# Recognize special sequences in the input 
+
+
+# Warning: This uses extended regular expressions.  Tread with care.
 #
 # legenda
 #
@@ -486,6 +515,7 @@ re_dict = {
                'singleline-comment': no_match,
                'numcols': no_match,
                'multicols': no_match,
+               'ly2dvi': r'(?m)(?P<match><ly2dvifile(?P<options>[^>]+)?>\s*(?P<filename>[^<]+)\s*</ly2dvifile>)',
                },
 
        'latex': {
@@ -507,6 +537,8 @@ re_dict = {
                'singleline-comment': r"(?m)^.*?(?P<match>(?P<code>^%.*$\n+))",
                'numcols': r"(?P<code>\\(?P<num>one|two)column)",
                'multicols': r"(?P<code>\\(?P<be>begin|end)\s*{multicols}({(?P<num>\d+)?})?)",
+               'ly2dvi': no_match,
+
                },
 
        # why do we have distinction between @mbinclude and @include?
@@ -528,6 +560,7 @@ re_dict = {
                'singleline-comment': r"(?m)^.*?(?P<match>(?P<code>@c.*$\n+))",
                'numcols': no_match,
                'multicols': no_match,
+               'ly2dvi': no_match,
                }
        }
 
@@ -859,6 +892,15 @@ def make_lilypond_file (m):
        return [('input', get_output ('output-lilypond') %
                        (options, content))]
 
+def make_ly2dvi_block (m):
+       '''
+
+       Find <ly2dvifile .. >
+       '''
+
+       return [('ly2dvi', m.group ('filename'), m.group ('options'))]
+
+
 def make_lilypond_block (m):
        if not g_do_music:
                return []
@@ -870,6 +912,7 @@ def make_lilypond_block (m):
        options = filter (lambda s: s != '', options)
        return [('lilypond', m.group ('code'), options)]
 
+
 def do_columns (m):
        global format
        if format != 'latex':
@@ -966,6 +1009,10 @@ def read_doc_file (filename):
 
 
 taken_file_names = {}
+
+def unique_file_name (body):
+       return 'lily-' + `abs (hash (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
@@ -982,7 +1029,7 @@ def schedule_lilypond_block (chunk):
        ## Hmm, we should hash only lilypond source, and skip the
        ## %options are ...
        ## comment line
-       basename = 'lily-' + `abs (hash (file_body))`
+       basename = unique_file_name (file_body)
        for o in opts:
                m = re.search ('filename="(.*?)"', o)
                if m:
@@ -1001,6 +1048,7 @@ def schedule_lilypond_block (chunk):
                needed_filetypes.append ('png')
        if 'eps' in opts and not ('eps' in needed_filetypes):
                needed_filetypes.append ('eps')
+
        pathbase = os.path.join (g_outdir, basename)
        def f (base, ext1, ext2):
                a = os.path.isfile (base + ext2)
@@ -1062,6 +1110,9 @@ def schedule_lilypond_block (chunk):
        newbody = newbody + get_output (s) % {'fn': basename }
        return ('lilypond', newbody, opts, todo, basename)
 
+
+
+
 def process_lilypond_blocks (chunks):#ugh rename
        newchunks = []
        # Count sections/chapters.
@@ -1075,6 +1126,106 @@ def process_lilypond_blocks (chunks):#ugh rename
                newchunks.append (c)
        return newchunks
 
+def process_ly2dvi_blocks (chunks):
+       
+       def process_ly2dvi_block (chunk):
+               """
+
+Run ly2dvi script on filename specified in CHUNK.
+This is only supported for HTML output.
+
+In HTML output it will leave a download menu with ps/pdf/midi etc.  in
+a separate HTML file, and a title + preview in the main html file,
+linking to the menu.
+
+               """
+               (tag, name, opts) = chunk
+               assert format == 'html'
+               (content, original_name) = find_file (name)
+
+               original_name = os.path.basename (original_name)
+               
+               base = unique_file_name (content)
+               outname = base + '.ly'
+               changed = update_file (content, outname)
+
+               preview = base + ".png"
+               if changed or not os.path.isfile (preview):
+                       ly.system ('ly2dvi --preview --postscript --verbose %s ' % base) 
+
+                       ly.make_page_images (base)
+                       ly.system ('gzip -9 - < %s.ps > %s.ps.gz' %  (base, base))
+                       
+               def size_str (fn):
+                       b = os.stat(fn)[stat.ST_SIZE]
+                       if b < 1024:
+                               return '%d bytes' % b
+                       elif b < (2 << 20):
+                               return '%d kb' % (b >> 10)
+                       else:
+                               return '%d mb' % (b >> 20)
+
+               exts = {
+                       'pdf' : "Print (PDF, %s)",
+                       'ps.gz' : "Print (gzipped PostScript, %s)",
+                       'png' : "View (PNG, %s)",
+                       'midi' : "Listen (MIDI, %s)",
+                       'ly' : "View source code (%s)", 
+                       }
+
+               menu = ''
+               page_files = ly.read_pipe ('ls --color=no -1 %s-page*.png' % base)
+
+               for p in string.split (page_files, '\n'):
+                       p = p.strip()
+                       if os.path.isfile (p):
+                               sz = size_str (p)
+                               page = re.sub ('.*page([0-9])+.*', 'View page \\1 (PNG picture, %s)\n', p)
+                               page = page % sz
+                               menu += '<li><a href="%s">%s</a>' % (p, page) 
+
+               ext_order = ['ly', 'pdf', 'ps.gz', 'midi']
+               for e in ext_order:
+                       fn =   base +  '.' + e
+                       print 'checking,' , fn
+                       if not os.path.isfile (fn):
+                               continue
+
+                       entry = exts[e] % size_str (fn)
+
+                       ## TODO: do something like
+                       ## this for texinfo/latex as well ?
+                       
+                       menu += '<li><a href="%s">%s</a>\n\n' % (fn, entry)
+
+
+               explanatory_para = """The pictures are 90dpi
+anti-aliased snapshots of the printed output, in PNG format. Both  PDF and PS
+use scalable fonts and should look OK at any resolution."""
+               
+               separate_menu =r'''
+<title>LilyPond example %s</title>
+
+<h1>%s</h1>
+<p><img src="%s">
+<p>%s
+<p>
+<ul>%s</ul>''' % (original_name,original_name, preview, explanatory_para, menu)
+               
+               open (base + '.html','w'). write (separate_menu)
+
+               inline_menu = '<p/><a href="%s.html"><img src="%s"><p/></a>' % (base, original_name, preview)
+
+               return ('ly2dvi', inline_menu)
+
+       newchunks = []
+       for c in chunks:
+               if c[0] == 'ly2dvi':
+                       c = process_ly2dvi_block (c)
+               newchunks.append (c)
+
+       return newchunks
+
 def compile_all_files (chunks):
        global foutn
        eps = []
@@ -1149,7 +1300,7 @@ def compile_all_files (chunks):
 
 def update_file (body, name):
        '''
-       write the body if it has changed
+       write the body if it has changed. Return whether BODY has changed.
        '''
        same = 0
        try:
@@ -1242,6 +1393,7 @@ foutn=""
 
 def do_file (input_filename):
        chunks = read_doc_file (input_filename)
+       chunks = chop_chunks (chunks, 'ly2dvi', make_ly2dvi_block, 1)
        chunks = chop_chunks (chunks, 'lilypond', make_lilypond, 1)
        chunks = chop_chunks (chunks, 'lilypond-file', make_lilypond_file, 1)
        chunks = chop_chunks (chunks, 'lilypond-block', make_lilypond_block, 1)
@@ -1254,7 +1406,8 @@ def do_file (input_filename):
        #sys.exit ()
        scan_preamble (chunks)
        chunks = process_lilypond_blocks (chunks)
-
+       chunks = process_ly2dvi_blocks (chunks)
+       
        # Do It.
        global g_run_lilypond
        if g_run_lilypond:
index 28cd50eebbf997422919e6bd095ab2d38305ebc6..7b8c519955223992db5600962d5e172d1aba07ad 100644 (file)
@@ -112,6 +112,7 @@ original_dir = os.getcwd ()
 temp_dir = os.path.join (original_dir,  '%s.dir' % program_name)
 keep_temp_dir_p = 0
 preview_resolution = 90
+debug_p = 0
 
 ## FIXME
 ## ly2dvi: silly name?
@@ -125,6 +126,7 @@ option_definitions = [
        ('', 'd', 'dependencies',
         _ ("write Makefile dependencies for every input file")),
        ('', 'h', 'help', _ ("this help")),
+       ('', '', 'debug', _ ("print even more output")),
        (_ ("DIR"), 'I', 'include', _ ("add DIR to LilyPond's search path")),
        ('', 'k', 'keep',
         _ ("keep all output, output to directory %s.dir") % program_name),
@@ -243,6 +245,8 @@ def run_lilypond (files, dep_prefix):
        global verbose_p
        if verbose_p:
                opts = opts + ' --verbose'
+
+       if debug_p:
                ly.print_environment ()
 
        cmd = string.join ((lilypond_cmd,opts, fs))
@@ -498,16 +502,14 @@ None
                # make a preview by rendering only the 1st line.
                preview_fn = outbase + '.preview.tex'
                f = open (preview_fn, 'w')
-               f.write (r'''
-%s
-\input lilyponddefs
-\pagestyle{empty}
-\begin{document}
-\def\interscoreline{\endinput}
-\input %s
-\end{document}
-''' % (global_latex_preamble (extra), outbase))
-
+               wfs = find_tex_files (files, extra)
+               s = global_latex_definition (wfs, extra)
+
+               s = re.sub ('thispagestyle{firstpage}', r'''thispagestyle{empty}%
+\\def\\interscoreline{\\endinput}''',s ) 
+               s = re.sub ('thispagestyle{lastpage}', r'''thispagestyle{empty}%
+\\def\\interscoreline{\\endinput}''',s ) 
+               f.write (s)
                f.close()
                cmd = '%s \\\\nonstopmode \\\\input %s' % (latex_cmd, preview_fn)
                ly.system (cmd)
@@ -545,8 +547,8 @@ None.
                        opts = opts + ' -Ppdf -G0 -u lilypond.map'
                else:
                        ly.warning (_ ('''Trying create PDF, but no PFA fonts found.
-Using bitmap fonts instead. This will look poorly.'''))
-               
+Using bitmap fonts instead. This will look bad.'''))
+
        cmd = 'dvips %s -o%s %s' % (opts, outbase + '.ps', outbase + '.dvi')
        ly.system (cmd)
 
@@ -634,6 +636,9 @@ for opt in options:
                targets.append ('PDF')
        elif o == '--keep' or o == '-k':
                keep_temp_dir_p = 1
+       elif o == '--debug':
+               verbose_p = 1
+               debug_p = 1 
        elif o == '--no-lily':
                lily_p = 0
        elif o == '--preview':