]> git.donarmstrong.com Git - lilypond.git/blobdiff - scripts/lilypond-book.py
Merge branch 'master' of ssh+git://hanwen@git.sv.gnu.org/srv/git/lilypond
[lilypond.git] / scripts / lilypond-book.py
index 3ceb9c4518b99bdf4106e7396b752c932c17542d..6747a055e29df3f330ab564ad4571a72cc738505 100644 (file)
@@ -211,6 +211,7 @@ FILTER = 'filter'
 FRAGMENT = 'fragment'
 HTML = 'html'
 INDENT = 'indent'
+LANG = 'lang'
 LATEX = 'latex'
 LAYOUT = 'layout'
 LINE_WIDTH = 'line-width'
@@ -517,6 +518,7 @@ simple_options = [
     NOINDENT,
     PRINTFILENAME,
     TEXIDOC,
+    LANG,
     VERBATIM,
     FONTLOAD,
     FILENAME,
@@ -808,12 +810,18 @@ def verbatim_html (s):
                re.sub ('&', '&', s)))
 
 
+texinfo_lang_re = re.compile ('(?m)^@documentlanguage (.*?)( |$)')
 def set_default_options (source, default_ly_options, format):
     if LINE_WIDTH not in default_ly_options:
         if format == LATEX:
             textwidth = get_latex_textwidth (source)
             default_ly_options[LINE_WIDTH] = '%.0f\\pt' % textwidth
         elif format == TEXINFO:
+            m = texinfo_lang_re.search (source)
+            if m and not m.group (1).startswith ('en'):
+                default_ly_options[LANG] = m.group (1)
+            else:
+                default_ly_options[LANG] = ''
             for regex in texinfo_line_widths:
                 # FIXME: @layout is usually not in
                 # chunk #0:
@@ -910,8 +918,7 @@ class LilypondSnippet (Snippet):
             return self.compose_ly (s)
         return ''
 
-    @staticmethod
-    def split_options (option_string):
+    def split_options (self, option_string):
         if option_string:
             if self.format == HTML:
                 options = re.findall('[\w\.-:]+(?:\s*=\s*(?:"[^"]*"|\'[^\']*\'|\S+))?',
@@ -927,7 +934,7 @@ class LilypondSnippet (Snippet):
     def do_options (self, option_string, type):
         self.option_dict = {}
 
-        options = split_options (option_string)
+        options = self.split_options (option_string)
 
         for option in options:
             if '=' in option:
@@ -1132,82 +1139,56 @@ class LilypondSnippet (Snippet):
 
         
     def all_output_files (self, output_dir_files):
-        """Return all files generated in lily_output_dir.
+        """Return all files generated in lily_output_dir, a set.
 
         output_dir_files is the list of files in the output directory.
         """
-        base = os.path.basename(self.basename())
-        result = set()
-        for required in [base + '.ly',
-                         base + '.txt']:
-            result.add (required)
+        class Missing(Exception):
+            pass
         
+        result = set()
+        base = os.path.basename(self.basename())
         def consider_file (name):
             if name in output_dir_files:
                 result.add (name)
 
-        map (consider_file, [base + '.tex',
-                             base + '.eps',
-                             base + '-systems.count',
-                             base + '-systems.texi',
-                             base + '-systems.tex',
-                             base + '-systems.pdftexi'])
-
-        if base + '.eps' in result:
-            page_count = ps_page_count (self.basename() + '.eps')
-            if page_count <= 1:
-                consider_file (base + '.png')
-            else:
-                for page in range (1, page_count + 1):
-                    consider_file (base + '-page%d.png' % page)
+        def require_file (name):
+            if name not in output_dir_files:
+                raise Missing
+            result.add (name)
+
+        try:
+            for required in [base + '.ly',
+                             base + '.txt',
+                             base + '-systems.count']:
+                require_file (required)
+
+            map (consider_file, [base + '.tex',
+                                 base + '.eps',
+                                 base + '-systems.texi',
+                                 base + '-systems.tex',
+                                 base + '-systems.pdftexi'])
+
+            if base + '.eps' in result and self.format in (HTML, TEXINFO):
+                page_count = ps_page_count (self.basename() + '.eps')
+                if page_count <= 1:
+                    require_file (base + '.png')
+                else:
+                    for page in range (1, page_count + 1):
+                        require_file (base + '-page%d.png' % page)
 
-        if (base + '-systems.count') in result:
             system_count = int(file (self.basename () + '-systems.count').read())
             for number in range(1, system_count + 1):
                 systemfile = '%s-%d' % (base, number)
-                consider_file (systemfile + '.eps')
+                require_file (systemfile + '.eps')
                 consider_file (systemfile + '.pdf')
+        except Missing:
+            return None
         
         return result
-             
-    def ly_is_outdated (self):
-        base = self.basename ()
-        ly_file = find_file (base + '.ly', raise_error=False)
-        tex_file = find_file (base + '.tex', raise_error=False)
-        systems_file = find_file (base + '-systems.tex', raise_error=False)
-
-        if (not os.path.exists (ly_file)
-            or not os.path.exists (systems_file)):
-            return True
-
-        lines = file (systems_file).readlines ()
-        if not lines:
-            return True
-
-        if not re.match ('% eof', lines[-1]):
-            return true
-        
-        return False
-
-    def png_is_outdated (self):
-        base = self.basename ()
-        eps_file = find_file (base + '.eps', raise_error=False)
-        png_file = find_file (base + '.png', raise_error=False)
-        if self.ly_is_outdated ():
-            return True
-        
-        if (self.format in (HTML, TEXINFO)
-            and os.path.exists (eps_file)):
-            page_count = ps_page_count (eps_file)
-            if page_count <= 1:
-                return not os.path.exists (png_file)
-            else:
-                for page in range (1, page_count + 1):
-                    if not find_file (base + '-page%d.png' % page,
-                                      raise_error=False):
-                        return True
-                
-        return False
+    
+    def is_outdated (self, current_files):
+        return self.all_output_files (current_files) is None
     
     def filter_text (self):
         """Run snippet bodies through a command (say: convert-ly).
@@ -1329,7 +1310,10 @@ class LilypondSnippet (Snippet):
         base = self.basename ()
         if TEXIDOC in self.option_dict:
             texidoc = base + '.texidoc'
-            if os.path.exists (texidoc):
+            translated_texidoc = texidoc + default_ly_options[LANG]
+            if os.path.exists (translated_texidoc):
+                str += '@include %(translated_texidoc)s\n\n' % vars ()
+            elif os.path.exists (texidoc):
                 str += '@include %(texidoc)s\n\n' % vars ()
 
         substr = ''
@@ -1460,7 +1444,7 @@ def find_toplevel_snippets (input_string, format, types):
                 endex = found[first][0]
 
         if not first:
-            snippets.append (Substring (input_string, index, len (s), line_start_idx))
+            snippets.append (Substring (input_string, index, len (input_string), line_start_idx))
             break
 
         while (start > line_starts[line_start_idx+1]):
@@ -1639,8 +1623,10 @@ def write_file_map (lys, name):
 
 def do_process_cmd (chunks, input_name, options):
     snippets = [c for c in chunks if isinstance (c, LilypondSnippet)]
-    outdated = [c for c in snippets
-                if (c.ly_is_outdated () or c.png_is_outdated ())]
+
+
+    output_files = set(os.listdir(options.lily_output_dir))
+    outdated = [c for c in snippets if c.is_outdated (output_files)]
     
     write_file_map (outdated, input_name)    
     progress (_ ("Writing snippets..."))
@@ -1818,8 +1804,8 @@ def do_file (input_filename):
             return do_file (name)
 
         include_chunks = map (process_include,
-                   filter (lambda x: isinstance (x, IncludeSnippet),
-                       chunks))
+                              filter (lambda x: isinstance (x, IncludeSnippet),
+                                      chunks))
 
         return chunks + reduce (lambda x, y: x + y, include_chunks, [])