1 # -*- coding: utf-8 -*-
4 import book_base as BookBase
5 from book_snippets import *
7 # Recognize special sequences in the input.
9 # (?P<name>regex) -- Assign result of REGEX to NAME.
10 # *? -- Match non-greedily.
11 # (?!...) -- Match if `...' doesn't match next (without consuming
14 # (?m) -- Multiline regex: Make ^ and $ match at each line.
15 # (?s) -- Make the dot match all characters including newline.
16 # (?x) -- Ignore whitespace in patterns.
18 # 'multiline_comment', 'verbatim', 'lilypond_block', 'singleline_comment',
19 # 'lilypond_file', 'include', 'lilypond', 'lilypondversion'
20 TexInfo_snippet_res = {
24 (?P<filename>\S+))''',
26 'lilypond': r'''(?smx)
27 ^[^\n]*?(?!@c\s+)[^\n]*?
31 \s*(?P<options>.*?)\s*
36 'lilypond_block': r'''(?msx)
40 \s*(?P<options>.*?)\s*
43 ^@end\s+lilypond)\s''',
45 'lilypond_file': r'''(?mx)
49 \s*(?P<options>.*?)\s*
54 'multiline_comment': r'''(?smx)
61 'musicxml_file': r'''(?mx)
65 \s*(?P<options>.*?)\s*
70 'singleline_comment': r'''(?mx)
74 @c([ \t][^\n]*|)\n))''',
76 # Don't do this: It interferes with @code{@{}.
77 # 'verb': r'''(?P<code>@code{.*?})''',
84 @end\s+example\s))''',
86 'lilypondversion': r'''(?mx)
88 @lilypondversion)[^a-zA-Z]''',
94 ADDVERSION: r'''@example
95 \version @w{"@version{}"}
99 FILTER: r'''@lilypond[%(options)s]
105 @include %(base)s-systems.texi
109 OUTPUTIMAGE: r'''@noindent
111 @image{%(info_image_path)s,,,%(alt)s,%(ext)s}
115 <a href="%(base)s%(ext)s">
127 <a href="%(base)s%(ext)s">
135 QUOTE: r'''@quotation
136 %(str)s@end quotation
139 VERBATIM: r'''@exampleindent 0
141 %(verb)s@end verbatim
144 VERSION: r'''%(program_version)s''',
148 texinfo_line_widths = {
149 '@afourpaper': '160\\mm',
150 '@afourwide': '6.5\\in',
151 '@afourlatex': '150\\mm',
152 '@smallbook': '5\\in',
153 '@letterpaper': '6\\in',
158 texinfo_lang_re = re.compile ('(?m)^@documentlanguage (.*?)( |$)')
160 class BookTexinfoOutputFormat (BookBase.BookOutputFormat):
162 BookBase.BookOutputFormat.__init__ (self)
163 self.format = "texinfo"
164 self.default_extension = ".texi"
165 self.snippet_res = TexInfo_snippet_res
166 self.output = TexInfo_output
167 self.handled_extensions = ['.itely', '.tely', '.texi', '.texinfo']
168 self.snippet_option_separator = '\s*,\s*'
170 def can_handle_format (self, format):
171 return (BookBase.BookOutputFormat.can_handle_format (self, format) or
172 (format in ['texi-html', 'texi']))
174 def process_options (self, global_options):
175 self.process_options_pdfnotdefault (global_options)
177 def get_document_language (self, source):
178 m = texinfo_lang_re.search (source)
179 if m and not m.group (1).startswith ('en'):
184 def get_line_width (self, source):
185 for regex in texinfo_line_widths:
186 # FIXME: @layout is usually not in
189 # \input texinfo @c -*-texinfo-*-
191 # Bluntly search first K items of
193 # s = chunks[0].replacement_text ()
194 if re.search (regex, source[:1024]):
195 return texinfo_line_widths[regex]
198 def adjust_snippet_command (self, cmd):
199 if '--formats' not in cmd:
200 return cmd + ' --formats=png '
204 def output_info (self, basename, snippet):
206 rep = snippet.get_replacements ();
207 for image in snippet.get_images ():
208 rep1 = copy.copy (rep)
209 (rep1['base'], rep1['ext']) = os.path.splitext (image)
210 rep1['image'] = image
212 # URG, makeinfo implicitly prepends dot to extension.
213 # Specifying no extension is most robust.
215 rep1['alt'] = snippet.option_dict[ALT]
216 rep1['info_image_path'] = os.path.join (self.global_options.info_images_dir, rep1['base'])
217 str += self.output[OUTPUTIMAGE] % rep1
219 rep['base'] = basename
220 str += self.output[OUTPUT] % rep
223 def snippet_output (self, basename, snippet):
224 str = self.output_print_filename (basename, snippet)
226 if DOCTITLE in snippet.option_dict:
227 doctitle = base + '.doctitle'
228 translated_doctitle = doctitle + self.document_language
229 if os.path.exists (translated_doctitle):
230 str += '@lydoctitle %s\n\n' % open (translated_doctitle).read ()
231 elif os.path.exists (doctitle):
232 str += '@lydoctitle %s\n\n' % open (doctitle).read ()
233 if TEXIDOC in snippet.option_dict:
234 texidoc = base + '.texidoc'
235 translated_texidoc = texidoc + self.document_language
236 if os.path.exists (translated_texidoc):
237 str += '@include %(translated_texidoc)s\n\n' % vars ()
238 elif os.path.exists (texidoc):
239 str += '@include %(texidoc)s\n\n' % vars ()
242 rep = snippet.get_replacements ();
243 if VERBATIM in snippet.option_dict:
245 if ADDVERSION in snippet.option_dict:
246 rep['version'] = self.output[ADDVERSION]
247 rep['verb'] = snippet.verb_ly ()
248 substr = self.output[VERBATIM] % rep
249 substr += self.output_info (basename, snippet)
250 if LILYQUOTE in snippet.option_dict:
251 substr = self.output[QUOTE] % {'str': substr}
254 # str += ('@ifinfo\n' + self.output_info () + '\n@end ifinfo\n')
255 # str += ('@tex\n' + self.output_latex () + '\n@end tex\n')
256 # str += ('@html\n' + self.output_html () + '\n@end html\n')
258 if QUOTE in snippet.option_dict:
259 str = self.output[QUOTE] % {'str': str}
261 # need par after image
266 def required_files (self, snippet, base, full, required_files):
267 return self.required_files_png (snippet, base, full, required_files)
271 BookBase.register_format (BookTexinfoOutputFormat ());