]> git.donarmstrong.com Git - lilypond.git/commitdiff
* scripts/lilypond-book.py (Substring.__init__): new class.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 7 Feb 2004 12:49:07 +0000 (12:49 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 7 Feb 2004 12:49:07 +0000 (12:49 +0000)
(Snippet.output_texinfo): add texidoc option.
(Include_snippet.replacement_text): new class.
(Lilypond_snippet.__init__): new class
(Lilypond_snippet.get_hash): bugfix: use full body for hashing.

* Documentation/user/refman.itely (Sound):
note about number of channels.

ChangeLog
Documentation/user/lilypond-book.itely
Documentation/user/refman.itely
buildscripts/lys-to-tely.py
input/template/GNUmakefile
scripts/lilypond-book.py

index 8d9c36a5918800bc2efae8b72e39108a374c0c99..9cc323a603ab05038b62a2c2efb725319e707a8a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2004-02-07  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
+       * scripts/lilypond-book.py (Substring.__init__): new class.
+       (Snippet.output_texinfo): add texidoc option.
+       (Include_snippet.replacement_text): new class.
+       (Lilypond_snippet.__init__): new class
+       (Lilypond_snippet.get_hash): bugfix: use full body for hashing.
+
        * Documentation/user/refman.itely (Sound): 
        note about number of channels.
 
index 220796f7f013039521727d7400fa0f30f96fe13c..e0ad3a271e8ade88734490bd4d58e6ead53ca0d3 100644 (file)
@@ -307,8 +307,9 @@ For example
 sets indentation of the first music system to zero.  This option
 affects LilyPond, not the text layout.
 
-@item notexidoc
-prevents including @code{texidoc}. This is only for Texinfo output.
+@item texidoc
+Includes the @code{texidoc} field, if defined in the file. This is
+only for Texinfo output.
 
 In Texinfo, the music fragment is normally preceded by the
 @code{texidoc} field from the @code{\header}. The LilyPond test
index 7cbd118c57eec917c71d43862eb713e948682937..edab5ee2c3a12bd46c289bebd8231e6de1c8713c 100644 (file)
@@ -8703,7 +8703,7 @@ Since slurs are not interpreted, @code{\lyricsto} and
 
 The MIDI output allocates a channel for each Staff, and one for global
 settings.  Hence, the MIDI file should not have more than 15 staves
-(or 14 if you do not use drums). 
+(or 14 if you do not use drums).
 
 
 @menu
index 8069deaba8a8de86f1fae9a9e8ef0e8a08fc2cfb..1fd82e4cd2331586eb9f5e91fd14c658a1959d1f 100644 (file)
@@ -62,11 +62,12 @@ if files:
        s = '''\input texinfo
 @setfilename %s.info
 @settitle %s
-@finalout @c we do not want black boxes.
 
 @iftex
 @afourpaper
 @end iftex
+
+@finalout @c we do not want black boxes.
   
 @c fool ls-latex
 @ignore
@@ -87,7 +88,7 @@ if files:
 @end ifhtml
 """ % n
                
-               s += "\n\n@lilypondfile[printfilename]{%s}" % n
+               s += "\n\n@lilypondfile[printfilename,texidoc]{%s}" % n
                return s
        files.sort ()
        s = s + string.join (map (lambda x: name2line (x), files), "\n")
index 5e769a12648dce656ee3aa38b1339a00ee8ee6d4..f9d3238951c656bd9131b54bd62e42ad7e320cd8 100644 (file)
@@ -1,7 +1,7 @@
 depth = ../..
 
 STEPMAKE_TEMPLATES=documentation texinfo tex
-LILYPOND_BOOK_FLAGS = --process="lilypond-bin -I $(srcdir)/input/regression -e '(ly:set-option (quote internal-type-checking) \#t)'"
+LILYPOND_BOOK_FLAGS = --process="lilypond-bin -H texidoc -I $(srcdir)/input/regression -e '(ly:set-option (quote internal-type-checking) \#t)'"
 LOCALSTEPMAKE_TEMPLATES=lilypond ly lysdoc
 EXTRA_DIST_FILES=README
 
@@ -9,3 +9,5 @@ include $(depth)/make/stepmake.make
 
 TITLE=LilyPond Template Files
 
+
+.PRECIOUS: $(outdir)/collated-files.texi
index e2b09713d9bc30fdc04bc18094569d1556599f30..1bbfa86dc05a89fc3bfffee89642418b3ce73b04 100644 (file)
@@ -234,6 +234,9 @@ border="0" src="%(base)s.png" alt="[picture of music]">''',
        },
        
        TEXINFO :       {
+       PRINTFILENAME: '''@file{%(filename)s}
+
+       ''',
        BEFORE: '',
        AFTER: '',
        VERBATIM: r'''@example
@@ -257,6 +260,12 @@ FRAGMENT_LY = r'''\score{
 }'''
 FULL_LY = '%(code)s'
 
+texi_linewidths = { 'afourpaper': '160 \\mm',
+                   'afourwide': '6.5\\in',
+                   'afourlatex': '150 \\mm',
+                   'smallbook': '5 \\in' ,
+                   'letterpaper': '6\\in'}
+
 def classic_lilypond_book_compatibility (o):
        if o == 'singleline':
                return 'raggedright'
@@ -280,7 +289,7 @@ def compose_ly (code, options):
        
        options += default_ly_options.keys ()
        vars ().update (default_ly_options)
-       
+
        m = re.search (r'''\\score''', code)
        if not m and (not options \
                      or not 'nofragment' in options \
@@ -319,7 +328,7 @@ def compose_ly (code, options):
                elif key in ly_options[PAPER].keys ():
                        paper_options.append (ly_options[PAPER][key])
                elif key not in ('fragment', 'nofragment', 'printfilename',
-                                'relative', 'verbatim'):
+                                'relative', 'verbatim', 'texidoc'):
                        ly.warning (_("ignoring unknown ly option: %s") % i)
 
        relative_quotes = (",,,", ",,", ",", "", "'", "''", "'''")[relative-3]
@@ -365,18 +374,28 @@ def split_options (option_string):
        return re.split (format_res[format]['option-sep'], option_string)
 
 
-class Snippet:
-       def __init__ (self, type, match):
+class Chunk:
+       def replacement_text (self):
+               return ''
+
+
+class Substring (Chunk):
+       def __init__ (self, source, start, end):
+               self.source = source
+               self.start = start
+               self.end = end
+       def replacement_text (self):
+               return self.source [self.start:self.end]
+       def outdated_p (self):
+               return 0
+       
+class Snippet (Chunk):
+       def __init__ (self, type, match, format):
                self.type = type
                self.match = match
                self.hash = 0
                self.options = []
-               try:
-                       os = match.group ('options')
-                       if os:
-                               self.options = split_options (os)
-               except IndexError:
-                       pass
+               self.format = format
 
        def start (self, s):
                return self.match.start (s)
@@ -386,15 +405,31 @@ class Snippet:
 
        def substring (self, s):
                return self.match.group (s)
+       def filter_code (self):
+               pass # todo
+
+class Include_snippet (Snippet):
+       def replacement_text (self):
+               s = self.match.group (0)
+               f = self.substring ('filename')
+               nf = os.path.splitext (f)[0] + format2ext[format]
+               
+               return re.sub (f, nf, s)
+
+class Lilypond_snippet (Snippet):
+       def __init__ (self, type, match, format):
+               Snippet.__init__ (self, type, match, format)
+               os = match.group ('options')
+               if os:
+                       self.options = split_options (os)
+                       
 
        def ly (self):
-               s = ''
                if self.type == 'lilypond_block' or self.type == 'lilypond':
-                       s = self.substring ('code')
-               elif self.type == 'lilypond_file':
+                       return self.substring ('code')
+               else:
                        name = self.substring ('filename')
-                       s = open (find_file (name)).read ()
-               return s
+                       return open (find_file (name)).read ()
                
        def full_ly (self):
                s = self.ly ()
@@ -404,7 +439,7 @@ class Snippet:
        
        def get_hash (self):
                if not self.hash:
-                       self.hash = abs (hash (self.ly ()))
+                       self.hash = abs (hash (self.full_ly ()))
                return self.hash
 
        def basename (self):
@@ -418,21 +453,21 @@ class Snippet:
                        outf = open (self.basename () + '.ly', 'w')
                        outf.write (self.full_ly ())
 
-       def replacement_text (self, format):
-               if self.type in ['lilypond_file',
-                                'lilypond_block',
-                                'lilypond']:
-                       
-                       func = Snippet.__dict__ ['output_' + format]
-                       return func (self)
-               elif self.type == 'include':
-                       s = self.match.group (0)
-                       f = self.substring ('filename')
-                       nf = os.path.splitext (f)[0] + format2ext[format]
-                       
-                       return re.sub (f, nf, s)
-               else:
-                       return self.match.group (0)
+       def outdated_p (self):
+               base = self.basename ()
+               if os.path.exists (base + '.ly') \
+                  and os.path.exists (base + '.tex') \
+                  and (use_hash_p \
+                       or self.ly () == open (base + '.ly').read ()):
+                       # TODO: something smart with target formats
+                       # (ps, png) and m/ctimes
+                       return None
+               
+               return self
+       
+       def replacement_text (self):
+               func = Lilypond_snippet.__dict__ ['output_' + self.format]
+               return func (self)
        
        def output_html (self):
                base = self.basename ()
@@ -440,25 +475,27 @@ class Snippet:
                if VERBATIM in self.options and format == HTML:
                        verb = verbatim_html (self.substring ('code'))
                        str  += write (output[HTML][VERBATIM] % vars ())
-               return (str + output[HTML][BEFORE] 
+               str += (output[HTML][BEFORE] 
                        + (output[HTML][OUTPUT] % vars ())
                        + output[HTML][AFTER])
+
+               return str
                        
        def output_latex (self):
 
                str = self.output_print_filename (LATEX)
                        
                base = self.basename ()
-               str +=  (output[LATEX][BEFORE]
-                        + (output[LATEX][OUTPUT] % vars ())
-                        + output[LATEX][AFTER])
-
-               
                if  VERBATIM in self.options\
                   and format == LATEX:
                        verb = self.substring ('code')
                        str += (output[LATEX][VERBATIM] % vars ())
 
+               str +=  (output[LATEX][BEFORE]
+                        + (output[LATEX][OUTPUT] % vars ())
+                        + output[LATEX][AFTER])
+
+               
                return str
 
        def output_print_filename (self,format):
@@ -474,13 +511,26 @@ class Snippet:
                str = ''
 
                ##  Ugh, this breaks texidoc.
+               str = self.output_print_filename (TEXINFO)
+
+               base = self.basename ()
+
+               str = ""
+               if 'texidoc' in self.options :
+                       texidoc = base + '.texidoc'
+                       if os.path.exists (texidoc):
+                               str += '@include %s\n' % texidoc
                
                str += '\n@tex\n'
-               str += self.output_latex ()
+               str +=  (output[LATEX][BEFORE]
+                        + (output[LATEX][OUTPUT] % vars ())
+                        + output[LATEX][AFTER])
                str += ('\n@end tex\n')
                
                str += ('\n@html\n')
-               str += self.output_html ()
+               str += (output[HTML][BEFORE] 
+                       + (output[HTML][OUTPUT] % vars ())
+                       + output[HTML][AFTER])
                str += ('\n@end html\n')
 
                
@@ -490,25 +540,16 @@ class Snippet:
                
                return str
                        
-       def outdated_p (self):
-               if self.type != 'lilypond_block' and self.type != 'lilypond'\
-                      and self.type != 'lilypond_file':
-                       return None
-               base = self.basename ()
-               if os.path.exists (base + '.ly') \
-                  and os.path.exists (base + '.tex') \
-                  and (use_hash_p \
-                       or self.ly () == open (base + '.ly').read ()):
-                       # TODO: something smart with target formats
-                       # (ps, png) and m/ctimes
-                       return None
-               return self
 
-       def filter_code (self):
-               pass # todo
+snippet_type_to_class = {
+       'lilypond_file' : Lilypond_snippet,
+       'lilypond_block' : Lilypond_snippet,
+       'lilypond' : Lilypond_snippet,
+       'include' : Include_snippet
+       }
        
 
-def find_toplevel_snippets (infile, outfile, types):
+def find_toplevel_snippets (infile, types):
        s = infile.read ()
         res = {}
         for i in types:
@@ -536,25 +577,28 @@ def find_toplevel_snippets (infile, outfile, types):
                                 found[type] = None
                                 m = res[type].search (s[index:endex])
                                 if m:
-                                        found[type] = Snippet (type, m)
-
+                                       cl = Snippet
+                                       if snippet_type_to_class.has_key (type):
+                                               cl = snippet_type_to_class[type]
+                                               
+                                        found[type] = cl (type, m, format)
                         if found[type] \
                                and (first == None \
                                     or found[type].start (0) < found[first].start (0)):
                                
                                 first = type
                                 endex = found[first].start (0)
-                               
+
                 if not first:
-                        break
+                       snippets.append (Substring (s, index, len (s)))
+                       break
                
-                snippets.append (found[first])
+               snip = found[first]
+               snippets.append (Substring (s, index, index + snip.start (0)))
+               snippets.append (snip)
+                index += snip.end (0)
 
-               outfile.write (s[index:index + found[first].start (0)])
-               outfile.write (found[first].replacement_text (format))
                
-                index += found[first].end (0)
-
         return snippets
 
 
@@ -592,7 +636,7 @@ def run_filter (s):
        return filter_pipe (s, filter_cmd)
 
 def process_snippets (cmd, snippets):
-       names = filter (lambda x:x, map (Snippet.basename, snippets))
+       names = filter (lambda x:x, [y.basename () for y in  snippets])
        if names:
                ly.system (string.join ([cmd] + names))
 
@@ -705,23 +749,29 @@ def do_file (input_filename):
                os.chdir (output_name)
 
                
-       snippets = find_toplevel_snippets (ih, output_file, snippet_types)
+       chunks = find_toplevel_snippets (ih, snippet_types)
        ly.progress ('\n')
 
-
        global default_ly_options
        textwidth = 0
-       if format == LATEX and LINEWIDTH not in default_ly_options.keys ():
-               textwidth = get_latex_textwidth (source)
-               default_ly_options[LINEWIDTH] = '''%.0f\pt''' % textwidth
+       if LINEWIDTH not in default_ly_options.keys ():
+               if format == LATEX:
+                       textwidth = get_latex_textwidth (source)
+                       default_ly_options[LINEWIDTH] = '''%.0f\\pt''' % textwidth
+               elif format == TEXINFO:
+                       for (k,v) in texi_linewidths.items ():
+                               s = chunks[0].replacement_text()
+                               if re.search (k, s):
+                                       default_ly_options[LINEWIDTH] = v
+                                       break
 
        if filter_cmd:
                pass # todo
        elif process_cmd:
-               outdated = filter (lambda x:x,
-                                  map (Snippet.outdated_p, snippets))
+               outdated = filter (lambda x: x.__class__ == Lilypond_snippet and x.outdated_p (),
+                                  chunks)
                ly.progress (_ ("Writing snippets..."))
-               map (Snippet.write_ly, snippets)
+               map (Lilypond_snippet.write_ly, outdated)
                ly.progress ('\n')
                
                if outdated:
@@ -741,7 +791,13 @@ def do_file (input_filename):
                ly.progress ('\n')
                do_file (name)
 
-       map (process_include, filter (lambda x: x.type == 'include', snippets))
+                       
+               
+       output_file.writelines ([s.replacement_text () for s in chunks])
+
+       ## UGH. how do you do dynamic_cast/typecheck in Python?
+       map (process_include, filter (lambda x: x.__class__ == Snippet
+                                     and x.type == 'include', chunks))
 
 def do_options ():
        global format, output_name