1 # -*- coding: utf-8 -*-
7 import book_base as BookBase
8 from book_snippets import *
12 progress = ly.progress
16 # Recognize special sequences in the input.
18 # (?P<name>regex) -- Assign result of REGEX to NAME.
19 # *? -- Match non-greedily.
20 # (?!...) -- Match if `...' doesn't match next (without consuming
23 # (?m) -- Multiline regex: Make ^ and $ match at each line.
24 # (?s) -- Make the dot match all characters including newline.
25 # (?x) -- Ignore whitespace in patterns.
27 # 'multiline_comment', 'verbatim', 'lilypond_block', 'singleline_comment',
28 # 'lilypond_file', 'include', 'lilypond', 'lilypondversion'
44 \s*(?P<options>.*?)\s*
53 \\begin\s*(?P<env>{lilypond}\s*)?(
55 \s*(?P<options>.*?)\s*
56 \])?(?(env)|\s*{lilypond})
59 \\end\s*{lilypond})''',
67 \s*(?P<options>.*?)\s*
78 \s*(?P<options>.*?)\s*
106 \\end\s*{verbatim}))''',
111 \\lilypondversion)[^a-zA-Z]''',
115 FILTER: r'''\begin{lilypond}[%(options)s]
122 \ifx\preLilyPondExample \undefined
124 \expandafter\preLilyPondExample
126 \def\lilypondbook{}%%
127 \input %(base)s-systems.tex
128 \ifx\postLilyPondExample \undefined
130 \expandafter\postLilyPondExample
134 PRINTFILENAME: '''\\texttt{%(filename)s}
137 QUOTE: r'''\begin{quote}
141 VERBATIM: r'''\noindent
142 \begin{verbatim}%(verb)s\end{verbatim}
145 VERSION: r'''%(program_version)s''',
153 # Retrieve dimensions from LaTeX
154 LATEX_INSPECTION_DOCUMENT = r'''
158 \typeout{textwidth=\the\textwidth}
159 \typeout{columnsep=\the\columnsep}
160 \makeatletter\if@twocolumn\typeout{columns=2}\fi\makeatother
164 # Do we need anything else besides `textwidth'?
165 def get_latex_textwidth (source, global_options):
166 m = re.search (r'''(?P<preamble>\\begin\s*{document})''', source)
168 warning (_ ("cannot find \\begin{document} in LaTeX document"))
170 ## what's a sensible default?
173 preamble = source[:m.start (0)]
174 latex_document = LATEX_INSPECTION_DOCUMENT % {'preamble': preamble}
176 (handle, tmpfile) = tempfile.mkstemp('.tex')
177 tmpfileroot = os.path.splitext (tmpfile)[0]
178 tmpfileroot = os.path.split (tmpfileroot)[1]
179 auxfile = tmpfileroot + '.aux'
180 logfile = tmpfileroot + '.log'
182 tmp_handle = os.fdopen (handle,'w')
183 tmp_handle.write (latex_document)
186 progress (_ ("Running `%s' on file `%s' to detect default page settings.\n")
187 % (global_options.latex_program, tmpfile));
188 cmd = '%s %s' % (global_options.latex_program, tmpfile);
189 proc = subprocess.Popen (cmd,
190 universal_newlines=True, shell=True,
191 stdout=subprocess.PIPE, stderr=subprocess.PIPE);
192 (parameter_string, error_string) = proc.communicate ()
193 if proc.returncode != 0:
194 warning (_ ("Unable to auto-detect default page settings:\n%s")
197 if os.path.exists (auxfile):
199 if os.path.exists (logfile):
200 parameter_string = file (logfile).read()
204 m = re.search ('columns=([0-9.]+)', parameter_string)
206 columns = int (m.group (1))
209 m = re.search ('columnsep=([0-9.]+)pt', parameter_string)
211 columnsep = float (m.group (1))
214 m = re.search ('textwidth=([0-9.]+)pt', parameter_string)
216 textwidth = float (m.group (1))
218 textwidth = (textwidth - columnsep) / columns
223 def modify_preamble (chunk):
224 str = chunk.replacement_text ()
225 if (re.search (r"\\begin *{document}", str)
226 and not re.search ("{graphic[sx]", str)):
227 str = re.sub (r"\\begin{document}",
228 r"\\usepackage{graphics}" + '\n'
229 + r"\\begin{document}",
231 chunk.override_text = str
238 class BookLatexOutputFormat (BookBase.BookOutputFormat):
240 BookBase.BookOutputFormat.__init__ (self)
241 self.format = "latex"
242 self.default_extension = ".tex"
243 self.snippet_res = Latex_snippet_res
244 self.output = Latex_output
245 self.handled_extensions = ['.latex', '.lytex', '.tex']
246 self.image_formats = "ps"
247 self.snippet_option_separator = '\s*,\s*'
249 def process_options (self, global_options):
250 self.process_options_pdfnotdefault (global_options)
252 def get_line_width (self, source):
253 textwidth = get_latex_textwidth (source, self.global_options)
254 return '%.0f\\pt' % textwidth
256 def input_fullname (self, input_filename):
257 # Use kpsewhich if available, otherwise fall back to the default:
258 if ly.search_exe_path ('kpsewhich'):
259 return os.popen ('kpsewhich ' + input_filename).read()[:-1]
261 return BookBase.BookOutputFormat.input_fullname (self, input_filename)
263 def process_chunks (self, chunks):
265 if (c.is_plain () and
266 re.search (r"\\begin *{document}", c.replacement_text())):
271 def snippet_output (self, basename, snippet):
273 rep = snippet.get_replacements ();
274 rep['base'] = basename
275 str += self.output_print_filename (basename, snippet)
276 if VERBATIM in snippet.option_dict:
277 rep['verb'] = snippet.verb_ly ()
278 str += self.output[VERBATIM] % rep
280 str += self.output[OUTPUT] % rep
282 ## todo: maintain breaks
284 breaks = snippet.ly ().count ("\n")
285 str += "".ljust (breaks, "\n").replace ("\n","%\n")
287 if QUOTE in snippet.option_dict:
288 str = self.output[QUOTE] % {'str': str}
294 BookBase.register_format (BookLatexOutputFormat ());