]> git.donarmstrong.com Git - lilypond.git/blobdiff - python/book_texinfo.py
resolve merge
[lilypond.git] / python / book_texinfo.py
diff --git a/python/book_texinfo.py b/python/book_texinfo.py
new file mode 100644 (file)
index 0000000..03f7237
--- /dev/null
@@ -0,0 +1,266 @@
+# -*- coding: utf-8 -*-
+
+import re
+import book_base as BookBase
+from book_snippets import *
+
+# Recognize special sequences in the input.
+#
+#   (?P<name>regex) -- Assign result of REGEX to NAME.
+#   *? -- Match non-greedily.
+#   (?!...) -- Match if `...' doesn't match next (without consuming
+#              the string).
+#
+#   (?m) -- Multiline regex: Make ^ and $ match at each line.
+#   (?s) -- Make the dot match all characters including newline.
+#   (?x) -- Ignore whitespace in patterns.
+# Possible keys are:
+#     'multiline_comment', 'verbatim', 'lilypond_block', 'singleline_comment',
+#     'lilypond_file', 'include', 'lilypond', 'lilypondversion'
+TexInfo_snippet_res = {
+    'include': r'''(?mx)
+          ^(?P<match>
+          @include\s+
+           (?P<filename>\S+))''',
+
+    'lilypond': r'''(?smx)
+          ^[^\n]*?(?!@c\s+)[^\n]*?
+          (?P<match>
+          @lilypond\s*(
+          \[
+           \s*(?P<options>.*?)\s*
+          \])?\s*{
+           (?P<code>.*?)
+          })''',
+
+    'lilypond_block': r'''(?msx)
+          ^(?P<match>
+          @lilypond\s*(
+          \[
+           \s*(?P<options>.*?)\s*
+          \])?\s+?
+          ^(?P<code>.*?)
+          ^@end\s+lilypond)\s''',
+
+    'lilypond_file': r'''(?mx)
+          ^(?P<match>
+          @lilypondfile\s*(
+          \[
+           \s*(?P<options>.*?)\s*
+          \])?\s*{
+           (?P<filename>\S+)
+          })''',
+
+    'multiline_comment': r'''(?smx)
+          ^(?P<match>
+           (?P<code>
+           @ignore\s
+            .*?
+           @end\s+ignore))\s''',
+
+    'singleline_comment': r'''(?mx)
+          ^.*
+          (?P<match>
+           (?P<code>
+           @c([ \t][^\n]*|)\n))''',
+
+    # Don't do this: It interferes with @code{@{}.
+    #        'verb': r'''(?P<code>@code{.*?})''',
+
+    'verbatim': r'''(?sx)
+          (?P<match>
+           (?P<code>
+           @example
+            \s.*?
+           @end\s+example\s))''',
+
+    'lilypondversion': r'''(?mx)
+         [^@](?P<match>
+          @lilypondversion)[^a-zA-Z]''',
+
+}
+
+
+TexInfo_output = {
+    ADDVERSION: r'''@example
+\version @w{"@version{}"}
+@end example
+''',
+
+    FILTER: r'''@lilypond[%(options)s]
+%(code)s
+@lilypond''',
+
+    OUTPUT: r'''
+@iftex
+@include %(base)s-systems.texi
+@end iftex
+''',
+
+    OUTPUTIMAGE: r'''@noindent
+@ifinfo
+@image{%(info_image_path)s,,,%(alt)s,%(ext)s}
+@end ifinfo
+@html
+<p>
+ <a href="%(base)s.ly">
+  <img align="middle"
+       border="0"
+       src="%(image)s"
+       alt="%(alt)s">
+ </a>
+</p>
+@end html
+''',
+
+    PRINTFILENAME: '''
+@html
+<a href="%(base)s.ly">
+@end html
+@file{%(filename)s}
+@html
+</a>
+@end html
+    ''',
+
+    QUOTE: r'''@quotation
+%(str)s@end quotation
+''',
+
+    NOQUOTE: r'''@format
+%(str)s@end format
+''',
+
+    VERBATIM: r'''@exampleindent 0
+%(version)s@verbatim
+%(verb)s@end verbatim
+''',
+
+    VERSION: r'''%(program_version)s''',
+}
+
+
+texinfo_line_widths = {
+    '@afourpaper': '160\\mm',
+    '@afourwide': '6.5\\in',
+    '@afourlatex': '150\\mm',
+    '@smallbook': '5\\in',
+    '@letterpaper': '6\\in',
+}
+
+
+
+texinfo_lang_re = re.compile ('(?m)^@documentlanguage (.*?)( |$)')
+
+class BookTexinfoOutputFormat (BookBase.BookOutputFormat):
+    def __init__ (self):
+        BookBase.BookOutputFormat.__init__ (self)
+        self.format = "texinfo"
+        self.default_extension = ".texi"
+        self.snippet_res = TexInfo_snippet_res
+        self.output = TexInfo_output
+        self.handled_extensions = ['.itely', '.tely', '.texi', '.texinfo']
+        self.snippet_option_separator = '\s*,\s*'
+
+    def can_handle_format (self, format):
+        return (BookBase.BookOutputFormat.can_handle_format (self, format) or
+               (format in ['texi-html', 'texi']))
+
+    def process_options (self, global_options):
+        self.process_options_pdfnotdefault (global_options)
+
+    def get_document_language (self, source):
+        m = texinfo_lang_re.search (source)
+        if m and not m.group (1).startswith ('en'):
+            return m.group (1)
+        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 adjust_snippet_command (self, cmd):
+        if '--formats' not in cmd:
+            return cmd + ' --formats=png '
+        else:
+            return cmd
+
+    def output_info (self, basename, snippet):
+        str = ''
+        rep = snippet.get_replacements ();
+        for image in snippet.get_images ():
+            rep1 = copy.copy (rep)
+            (rep1['base'], rep1['ext']) = os.path.splitext (image)
+            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)
+        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 ()
+            elif os.path.exists (doctitle):
+                str += '@lydoctitle %s\n\n' % open (doctitle).read ()
+        if TEXIDOC in snippet.option_dict:
+            texidoc = base + '.texidoc'
+            translated_texidoc = texidoc + self.document_language
+            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 = ''
+        rep = snippet.get_replacements ();
+        if VERBATIM in snippet.option_dict:
+            rep['version'] = ''
+            if ADDVERSION in snippet.option_dict:
+                rep['version'] = self.output[ADDVERSION]
+            rep['verb'] = snippet.verb_ly ()
+            substr = self.output[VERBATIM] % rep
+        substr += self.output_info (basename, snippet)
+        if LILYQUOTE in snippet.option_dict:
+            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')
+
+        if QUOTE in snippet.option_dict:
+            str = self.output[QUOTE] % {'str': str}
+
+        # need par after image
+        str += '\n'
+
+        return str
+
+    def required_files (self, snippet, base, full, required_files):
+        return self.required_files_png (snippet, base, full, required_files)
+
+
+
+BookBase.register_format (BookTexinfoOutputFormat ());