]> git.donarmstrong.com Git - lilypond.git/blob - python/book_texinfo.py
Imported Upstream version 2.14.2
[lilypond.git] / python / book_texinfo.py
1 # -*- coding: utf-8 -*-
2
3 import re
4 import book_base as BookBase
5 from book_snippets import *
6
7 # Recognize special sequences in the input.
8 #
9 #   (?P<name>regex) -- Assign result of REGEX to NAME.
10 #   *? -- Match non-greedily.
11 #   (?!...) -- Match if `...' doesn't match next (without consuming
12 #              the string).
13 #
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.
17 # Possible keys are:
18 #     'multiline_comment', 'verbatim', 'lilypond_block', 'singleline_comment',
19 #     'lilypond_file', 'include', 'lilypond', 'lilypondversion'
20 TexInfo_snippet_res = {
21     'include': r'''(?mx)
22           ^(?P<match>
23           @include\s+
24            (?P<filename>\S+))''',
25
26     'lilypond': r'''(?smx)
27           ^[^\n]*?(?!@c\s+)[^\n]*?
28           (?P<match>
29           @lilypond\s*(
30           \[
31            \s*(?P<options>.*?)\s*
32           \])?\s*{
33            (?P<code>.*?)
34           })''',
35
36     'lilypond_block': r'''(?msx)
37           ^(?P<match>
38           @lilypond\s*(
39           \[
40            \s*(?P<options>.*?)\s*
41           \])?\s+?
42           ^(?P<code>.*?)
43           ^@end\s+lilypond)\s''',
44
45     'lilypond_file': r'''(?mx)
46           ^(?P<match>
47           @lilypondfile\s*(
48           \[
49            \s*(?P<options>.*?)\s*
50           \])?\s*{
51            (?P<filename>\S+)
52           })''',
53
54     'multiline_comment': r'''(?smx)
55           ^(?P<match>
56            (?P<code>
57            @ignore\s
58             .*?
59            @end\s+ignore))\s''',
60
61     'singleline_comment': r'''(?mx)
62           ^.*
63           (?P<match>
64            (?P<code>
65            @c([ \t][^\n]*|)\n))''',
66
67     # Don't do this: It interferes with @code{@{}.
68     #        'verb': r'''(?P<code>@code{.*?})''',
69
70     'verbatim': r'''(?sx)
71           (?P<match>
72            (?P<code>
73            @example
74             \s.*?
75            @end\s+example\s))''',
76
77     'lilypondversion': r'''(?mx)
78          [^@](?P<match>
79           @lilypondversion)[^a-zA-Z]''',
80
81 }
82
83
84 TexInfo_output = {
85     ADDVERSION: r'''@example
86 \version @w{"@version{}"}
87 @end example
88 ''',
89
90     FILTER: r'''@lilypond[%(options)s]
91 %(code)s
92 @lilypond''',
93
94     OUTPUT: r'''
95 @iftex
96 @include %(base)s-systems.texi
97 @end iftex
98 ''',
99
100     OUTPUTIMAGE: r'''@noindent
101 @ifinfo
102 @image{%(info_image_path)s,,,%(alt)s,%(ext)s}
103 @end ifinfo
104 @html
105 <p>
106  <a href="%(base)s.ly">
107   <img align="middle"
108        border="0"
109        src="%(image)s"
110        alt="%(alt)s">
111  </a>
112 </p>
113 @end html
114 ''',
115
116     PRINTFILENAME: '''
117 @html
118 <a href="%(base)s.ly">
119 @end html
120 @file{%(filename)s}
121 @html
122 </a>
123 @end html
124     ''',
125
126     QUOTE: r'''@quotation
127 %(str)s@end quotation
128 ''',
129
130     NOQUOTE: r'''@format
131 %(str)s@end format
132 ''',
133
134     VERBATIM: r'''@exampleindent 0
135 %(version)s@verbatim
136 %(verb)s@end verbatim
137 ''',
138
139     VERSION: r'''%(program_version)s''',
140 }
141
142
143 texinfo_line_widths = {
144     '@afourpaper': '160\\mm',
145     '@afourwide': '6.5\\in',
146     '@afourlatex': '150\\mm',
147     '@smallbook': '5\\in',
148     '@letterpaper': '6\\in',
149 }
150
151
152
153 texinfo_lang_re = re.compile ('(?m)^@documentlanguage (.*?)( |$)')
154
155 class BookTexinfoOutputFormat (BookBase.BookOutputFormat):
156     def __init__ (self):
157         BookBase.BookOutputFormat.__init__ (self)
158         self.format = "texinfo"
159         self.default_extension = ".texi"
160         self.snippet_res = TexInfo_snippet_res
161         self.output = TexInfo_output
162         self.handled_extensions = ['.itely', '.tely', '.texi', '.texinfo']
163         self.snippet_option_separator = '\s*,\s*'
164
165     def can_handle_format (self, format):
166         return (BookBase.BookOutputFormat.can_handle_format (self, format) or
167                (format in ['texi-html', 'texi']))
168
169     def process_options (self, global_options):
170         self.process_options_pdfnotdefault (global_options)
171
172     def get_document_language (self, source):
173         m = texinfo_lang_re.search (source)
174         if m and not m.group (1).startswith ('en'):
175             return m.group (1)
176         else:
177             return ''
178
179     def get_line_width (self, source):
180         for regex in texinfo_line_widths:
181             # FIXME: @layout is usually not in
182             # chunk #0:
183             #
184             #  \input texinfo @c -*-texinfo-*-
185             #
186             # Bluntly search first K items of
187             # source.
188             # s = chunks[0].replacement_text ()
189             if re.search (regex, source[:1024]):
190                 return texinfo_line_widths[regex]
191         return None
192
193     def adjust_snippet_command (self, cmd):
194         if '--formats' not in cmd:
195             return cmd + ' --formats=png '
196         else:
197             return cmd
198
199     def output_info (self, basename, snippet):
200         str = ''
201         rep = snippet.get_replacements ();
202         for image in snippet.get_images ():
203             rep1 = copy.copy (rep)
204             (rep1['base'], rep1['ext']) = os.path.splitext (image)
205             rep1['image'] = image
206
207             # URG, makeinfo implicitly prepends dot to extension.
208             # Specifying no extension is most robust.
209             rep1['ext'] = ''
210             rep1['alt'] = snippet.option_dict[ALT]
211             rep1['info_image_path'] = os.path.join (self.global_options.info_images_dir, rep1['base'])
212             str += self.output[OUTPUTIMAGE] % rep1
213
214         rep['base'] = basename
215         str += self.output[OUTPUT] % rep
216         return str
217
218     def snippet_output (self, basename, snippet):
219         str = self.output_print_filename (basename, snippet)
220         base = basename
221         if DOCTITLE in snippet.option_dict:
222             doctitle = base + '.doctitle'
223             translated_doctitle = doctitle + self.document_language
224             if os.path.exists (translated_doctitle):
225                 str += '@lydoctitle %s\n\n' % open (translated_doctitle).read ()
226             elif os.path.exists (doctitle):
227                 str += '@lydoctitle %s\n\n' % open (doctitle).read ()
228         if TEXIDOC in snippet.option_dict:
229             texidoc = base + '.texidoc'
230             translated_texidoc = texidoc + self.document_language
231             if os.path.exists (translated_texidoc):
232                 str += '@include %(translated_texidoc)s\n\n' % vars ()
233             elif os.path.exists (texidoc):
234                 str += '@include %(texidoc)s\n\n' % vars ()
235
236         substr = ''
237         rep = snippet.get_replacements ();
238         if VERBATIM in snippet.option_dict:
239             rep['version'] = ''
240             if ADDVERSION in snippet.option_dict:
241                 rep['version'] = self.output[ADDVERSION]
242             rep['verb'] = snippet.verb_ly ()
243             substr = self.output[VERBATIM] % rep
244         substr += self.output_info (basename, snippet)
245         if LILYQUOTE in snippet.option_dict:
246             substr = self.output[QUOTE] % {'str': substr}
247         str += substr
248
249 #                str += ('@ifinfo\n' + self.output_info () + '\n@end ifinfo\n')
250 #                str += ('@tex\n' + self.output_latex () + '\n@end tex\n')
251 #                str += ('@html\n' + self.output_html () + '\n@end html\n')
252
253         if QUOTE in snippet.option_dict:
254             str = self.output[QUOTE] % {'str': str}
255
256         # need par after image
257         str += '\n'
258
259         return str
260
261     def required_files (self, snippet, base, full, required_files):
262         return self.required_files_png (snippet, base, full, required_files)
263
264
265
266 BookBase.register_format (BookTexinfoOutputFormat ());