]> git.donarmstrong.com Git - lilypond.git/commitdiff
Lilypond-book: Auto-detect linewidth and exampleindent in texinfo mode
authorReinhold Kainhofer <reinhold@kainhofer.com>
Mon, 22 Aug 2011 10:19:16 +0000 (12:19 +0200)
committerReinhold Kainhofer <reinhold@kainhofer.com>
Tue, 30 Aug 2011 19:49:29 +0000 (21:49 +0200)
Detection code basically copied from LaTeX and adjusted (texinfo is
just an awkward latex dialect with different active characters,
so we can extract the values in exactly the same way!)

python/book_texinfo.py
scripts/lilypond-book.py

index 5cfa95a687472364460229bb9770ce295ca2f481..779cf566740aa8498d8d2f88a80b79747052c657 100644 (file)
@@ -1,8 +1,13 @@
 # -*- coding: utf-8 -*-
 
 import re
+import tempfile
+import subprocess
 import book_base as BookBase
 from book_snippets import *
+import lilylib as ly
+global _;_=ly._
+
 
 # Recognize special sequences in the input.
 #
@@ -154,6 +159,97 @@ 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}
+
+@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 pathes, 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 = 'LC_ALL=C %s -c -o %s %s' % (global_options.texinfo_program, outfile, tmpfile);
+    if (global_options.verbose):
+        progress ("Executing: %s\n" % cmd);
+
+    proc = subprocess.Popen (cmd,
+        universal_newlines=True, 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}
+    if (global_options.verbose):
+        progress ("Auto-detected values are: %s\n" % retval);
+    return retval;
+
+
 
 texinfo_lang_re = re.compile ('(?m)^@documentlanguage (.*?)( |$)')
 
@@ -181,19 +277,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:
@@ -251,10 +338,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'
 
index cb3ff4de3269861c09f0e5d83bb46a2bbdd39ca4..b1256529fd247ae6193b906f7e7e7ce8ab15b6cc 100644 (file)
@@ -227,6 +227,11 @@ case --pdf option is set instead of pdflatex"),
               metavar=_ ("PROG"),
               action='store', dest='latex_program',
               default='latex')
+    group.add_option ('--texinfo-program',
+              help=_ ("run executable PROG instead of texi2pdf"),
+              metavar=_ ("PROG"),
+              action='store', dest='texinfo_program',
+              default='texi2pdf')
     group.add_option ('--pdf',
               action="store_true",
               dest="create_pdf",