]> git.donarmstrong.com Git - lilypond.git/blob - python/book_texinfo.py
Lilypond-book: Get rid of lilyquote option, use quote instead
[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     'musicxml_file': r'''(?mx)
62           ^(?P<match>
63           @musicxmlfile\s*(
64           \[
65            \s*(?P<options>.*?)\s*
66           \])?\s*{
67            (?P<filename>\S+)
68           })''',
69
70     'singleline_comment': r'''(?mx)
71           ^.*
72           (?P<match>
73            (?P<code>
74            @c([ \t][^\n]*|)\n))''',
75
76     # Don't do this: It interferes with @code{@{}.
77     #        'verb': r'''(?P<code>@code{.*?})''',
78
79     'verbatim': r'''(?sx)
80           (?P<match>
81            (?P<code>
82            @example
83             \s.*?
84            @end\s+example\s))''',
85
86     'lilypondversion': r'''(?mx)
87          [^@](?P<match>
88           @lilypondversion)[^a-zA-Z]''',
89
90 }
91
92
93 TexInfo_output = {
94     ADDVERSION: r'''@example
95 \version @w{"@version{}"}
96 @end example
97 ''',
98
99     FILTER: r'''@lilypond[%(options)s]
100 %(code)s
101 @lilypond''',
102
103     OUTPUT: r'''
104 @iftex
105 @include %(base)s-systems.texi
106 @end iftex
107 ''',
108
109     OUTPUTIMAGE: r'''@noindent
110 @ifinfo
111 @image{%(info_image_path)s,,,%(alt)s,%(ext)s}
112 @end ifinfo
113 @html
114 <p>
115  <a href="%(base)s%(ext)s">
116   <img align="middle"
117        border="0"
118        src="%(image)s"
119        alt="%(alt)s">
120  </a>
121 </p>
122 @end html
123 ''',
124
125     PRINTFILENAME: '''
126 @html
127 <a href="%(base)s%(ext)s">
128 @end html
129 @file{%(filename)s}
130 @html
131 </a>
132 @end html
133     ''',
134
135     QUOTE: r'''@quotation
136 %(str)s@end quotation
137 ''',
138
139     VERBATIM: r'''@exampleindent 0
140 %(version)s@verbatim
141 %(verb)s@end verbatim
142 ''',
143
144     VERSION: r'''%(program_version)s''',
145 }
146
147
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',
154 }
155
156
157
158 texinfo_lang_re = re.compile ('(?m)^@documentlanguage (.*?)( |$)')
159
160 class BookTexinfoOutputFormat (BookBase.BookOutputFormat):
161     def __init__ (self):
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*'
169
170     def can_handle_format (self, format):
171         return (BookBase.BookOutputFormat.can_handle_format (self, format) or
172                (format in ['texi-html', 'texi']))
173
174     def process_options (self, global_options):
175         self.process_options_pdfnotdefault (global_options)
176
177     def get_document_language (self, source):
178         m = texinfo_lang_re.search (source)
179         if m and not m.group (1).startswith ('en'):
180             return m.group (1)
181         else:
182             return ''
183
184     def get_line_width (self, source):
185         for regex in texinfo_line_widths:
186             # FIXME: @layout is usually not in
187             # chunk #0:
188             #
189             #  \input texinfo @c -*-texinfo-*-
190             #
191             # Bluntly search first K items of
192             # source.
193             # s = chunks[0].replacement_text ()
194             if re.search (regex, source[:1024]):
195                 return texinfo_line_widths[regex]
196         return None
197
198     def adjust_snippet_command (self, cmd):
199         if '--formats' not in cmd:
200             return cmd + ' --formats=png '
201         else:
202             return cmd
203
204     def output_info (self, basename, snippet):
205         str = ''
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
211
212             # URG, makeinfo implicitly prepends dot to extension.
213             # Specifying no extension is most robust.
214             rep1['ext'] = ''
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
218
219         rep['base'] = basename
220         str += self.output[OUTPUT] % rep
221         return str
222
223     def snippet_output (self, basename, snippet):
224         str = self.output_print_filename (basename, snippet)
225         base = basename
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 ()
240
241         substr = ''
242         rep = snippet.get_replacements ();
243         if VERBATIM in snippet.option_dict:
244             rep['version'] = ''
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 (QUOTE in snippet.option_dict):
251             substr = self.output[QUOTE] % {'str': substr}
252         str += substr
253
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')
257
258         # need par after image
259         str += '\n'
260
261         return str
262
263     def required_files (self, snippet, base, full, required_files):
264         return self.required_files_png (snippet, base, full, required_files)
265
266
267
268 BookBase.register_format (BookTexinfoOutputFormat ());