]> git.donarmstrong.com Git - lilypond.git/blobdiff - python/book_texinfo.py
Release: bump Welcome versions.
[lilypond.git] / python / book_texinfo.py
index 5cfa95a687472364460229bb9770ce295ca2f481..1055615d67e413373510c133de43dd2c5aae9f43 100644 (file)
@@ -1,8 +1,14 @@
 # -*- coding: utf-8 -*-
 
 import re
+import tempfile
+import subprocess
+import sys
 import book_base as BookBase
 from book_snippets import *
+import lilylib as ly
+global _;_=ly._
+
 
 # Recognize special sequences in the input.
 #
@@ -108,7 +114,7 @@ TexInfo_output = {
 
     OUTPUTIMAGE: r'''@noindent
 @ifinfo
-@image{%(info_image_path)s,,,%(alt)s,%(ext)s}
+@image{%(info_image_path)s,,,%(alt)s,}
 @end ifinfo
 @html
 <p>
@@ -154,6 +160,120 @@ texinfo_line_widths = {
 }
 
 
+###
+# Retrieve dimensions from texinfo
+TEXINFO_INSPECTION_DOCUMENT = r'''
+\input texinfo
+@setfilename Texinfo_width_test
+@settitle Texinfo width test
+%(preamble)s
+
+@message{Global: textwidth=@the@hsize,exampleindent=@the@lispnarrowing}
+
+dummy
+
+@bye
+'''
+
+def get_texinfo_width_indent (source, global_options):
+    #TODO: Check for end of header command "@c %**end of header"
+    #      only use material before that comment ?
+
+    # extract all relevant papter settings from the input:
+    pagesize = None
+    texinfo_paper_size_regexp = r'''(@(?:afourpaper|afourwide|afourlatex|afivepaper|smallbook|letterpaper))''';
+    m = re.search (texinfo_paper_size_regexp, source);
+    if m:
+        pagesize = m.group (1)
+
+    relevant_settings_regexp = r'''(@(?:fonttextsize|pagesizes|cropmarks|exampleindent).*)\n''';
+    m = re.findall (relevant_settings_regexp, source);
+    if pagesize:
+        m.insert (0, pagesize);
+    # all relevant options to insert into the test document:
+    preamble = "\n".join (m);
+
+    texinfo_document = TEXINFO_INSPECTION_DOCUMENT % {'preamble': preamble}
+
+    (handle, tmpfile) = tempfile.mkstemp('.texi')
+    outfile = os.path.splitext (tmpfile)[0] + '.pdf'
+
+    tmp_handle = os.fdopen (handle,'w')
+    tmp_handle.write (texinfo_document)
+    tmp_handle.close ()
+
+    # Work around a texi2pdf bug: if LANG=C is not given, a broken regexp is
+    # used to detect relative/absolute paths, so the absolute path is not
+    # detected as such and this command fails:
+    progress (_ ("Running texi2pdf on file %s to detect default page settings.\n") % tmpfile);
+
+    # execute the command and pipe stdout to the parameter_string:
+    cmd = '%s -c -o %s %s' % (global_options.texinfo_program, outfile, tmpfile);
+    ly.debug_output ("Executing: %s\n" % cmd);
+    run_env = os.environ.copy()
+    run_env['LC_ALL'] = 'C'
+
+    ### unknown why this is necessary
+    universal_newlines = True
+    if sys.platform == 'mingw32':
+        universal_newlines = False
+        ### use os.system to avoid weird sleep() problems on
+        ### GUB's python 2.4.2 on mingw
+        # make file to write to
+        output_dir = tempfile.mkdtemp()
+        output_filename = os.path.join(output_dir, 'output.txt')
+        # call command
+        cmd += " > %s" % output_filename
+        returncode = os.system(cmd)
+        parameter_string = open(output_filename).read()
+        if returncode != 0:
+            warning (_ ("Unable to auto-detect default settings:\n"))
+        # clean up
+        os.remove(output_filename)
+        os.rmdir(output_dir)
+    else:
+        proc = subprocess.Popen (cmd,
+            env=run_env,
+            universal_newlines=universal_newlines,
+            shell=True,
+            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        (parameter_string, error_string) = proc.communicate ()
+        if proc.returncode != 0:
+            warning (_ ("Unable to auto-detect default settings:\n%s")
+                    % error_string)
+    os.unlink (tmpfile)
+    if os.path.exists(outfile):
+        os.unlink (outfile)
+
+    # Find textwidth and exampleindent and format it as \\mm or \\in
+    # Use defaults if they cannot be extracted
+    textwidth = 0
+    m = re.search ('textwidth=([0-9.]+)pt', parameter_string)
+    if m:
+        val = float (m.group (1))/72.27
+        if pagesize and pagesize.startswith ("@afour"):
+            textwidth = "%g\\mm" % round (val*25.4, 3);
+        else:
+            textwidth = "%g\\in" % round (val, 3);
+    else:
+        textwidth = texinfo_line_widths.get(pagesize, "6\\in")
+
+    exampleindent = 0
+    m = re.search ('exampleindent=([0-9.]+)pt', parameter_string)
+    if m:
+        val = float (m.group (1))/72.27
+        if pagesize and pagesize.startswith ("@afour"):
+            exampleindent = "%g\\mm" % round (val*25.4, 3);
+        else:
+            exampleindent = "%g\\in" % round (val, 3);
+    else:
+        exampleindent = "0.4\\in"
+
+    retval = {LINE_WIDTH: textwidth, EXAMPLEINDENT: exampleindent}
+    ly.debug_output ("Auto-detected values are: %s\n" % retval);
+    return retval;
+
+
 
 texinfo_lang_re = re.compile ('(?m)^@documentlanguage (.*?)( |$)')
 
@@ -181,19 +301,10 @@ class BookTexinfoOutputFormat (BookBase.BookOutputFormat):
         else:
             return ''
 
-    def get_line_width (self, source):
-        for regex in texinfo_line_widths:
-            # FIXME: @layout is usually not in
-            # chunk #0:
-            #
-            #  \input texinfo @c -*-texinfo-*-
-            #
-            # Bluntly search first K items of
-            # source.
-            # s = chunks[0].replacement_text ()
-            if re.search (regex, source[:1024]):
-                return texinfo_line_widths[regex]
-        return None
+    def init_default_snippet_options (self, source):
+        texinfo_defaults = get_texinfo_width_indent (source, self.global_options);
+        self.default_snippet_options.update (texinfo_defaults)
+        BookBase.BookOutputFormat.init_default_snippet_options (self, source)
 
     def adjust_snippet_command (self, cmd):
         if '--formats' not in cmd:
@@ -204,32 +315,30 @@ class BookTexinfoOutputFormat (BookBase.BookOutputFormat):
     def output_info (self, basename, snippet):
         str = ''
         rep = snippet.get_replacements ();
+        rep['base'] = basename
+        rep['filename'] = os.path.basename (snippet.filename)
+        rep['ext'] = snippet.ext
         for image in snippet.get_images ():
             rep1 = copy.copy (rep)
-            (rep1['base'], rep1['ext']) = os.path.splitext (image)
+            rep1['base'] = os.path.splitext (image)[0]
             rep1['image'] = image
-
-            # URG, makeinfo implicitly prepends dot to extension.
-            # Specifying no extension is most robust.
-            rep1['ext'] = ''
             rep1['alt'] = snippet.option_dict[ALT]
             rep1['info_image_path'] = os.path.join (self.global_options.info_images_dir, rep1['base'])
             str += self.output[OUTPUTIMAGE] % rep1
 
-        rep['base'] = basename
         str += self.output[OUTPUT] % rep
         return str
 
     def snippet_output (self, basename, snippet):
-        str = self.output_print_filename (basename, snippet)
+        str = ''
         base = basename
         if DOCTITLE in snippet.option_dict:
             doctitle = base + '.doctitle'
             translated_doctitle = doctitle + self.document_language
             if os.path.exists (translated_doctitle):
-                str += '@lydoctitle %s\n\n' % open (translated_doctitle).read ()
+                str += '\n@lydoctitle %s\n\n' % open (translated_doctitle).read ()
             elif os.path.exists (doctitle):
-                str += '@lydoctitle %s\n\n' % open (doctitle).read ()
+                str += '\n@lydoctitle %s\n\n' % open (doctitle).read ()
         if TEXIDOC in snippet.option_dict:
             texidoc = base + '.texidoc'
             translated_texidoc = texidoc + self.document_language
@@ -237,6 +346,7 @@ class BookTexinfoOutputFormat (BookBase.BookOutputFormat):
                 str += '@include %(translated_texidoc)s\n\n' % vars ()
             elif os.path.exists (texidoc):
                 str += '@include %(texidoc)s\n\n' % vars ()
+        str += self.output_print_filename (basename, snippet)
 
         substr = ''
         rep = snippet.get_replacements ();
@@ -251,10 +361,6 @@ class BookTexinfoOutputFormat (BookBase.BookOutputFormat):
             substr = self.output[QUOTE] % {'str': substr}
         str += substr
 
-#                str += ('@ifinfo\n' + self.output_info () + '\n@end ifinfo\n')
-#                str += ('@tex\n' + self.output_latex () + '\n@end tex\n')
-#                str += ('@html\n' + self.output_html () + '\n@end html\n')
-
         # need par after image
         str += '\n'