From 55aad8c485e14d29d78eddc0782a5e9901c6bf2c Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer Date: Mon, 22 Aug 2011 12:19:16 +0200 Subject: [PATCH] Lilypond-book: Auto-detect linewidth and exampleindent in texinfo mode 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 | 117 +++++++++++++++++++++++++++++++++------ scripts/lilypond-book.py | 5 ++ 2 files changed, 105 insertions(+), 17 deletions(-) diff --git a/python/book_texinfo.py b/python/book_texinfo.py index 5cfa95a687..779cf56674 100644 --- a/python/book_texinfo.py +++ b/python/book_texinfo.py @@ -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' diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py index cb3ff4de32..b1256529fd 100644 --- a/scripts/lilypond-book.py +++ b/scripts/lilypond-book.py @@ -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", -- 2.39.5