##// END OF EJS Templates
FIXED, latex characters not escaped properly in nbconvert
Jonathan Frederic -
Show More
@@ -1,115 +1,115 b''
1 1 """Latex filters.
2 2
3 3 Module of useful filters for processing Latex within Jinja latex templates.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 import re
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Globals and constants
20 20 #-----------------------------------------------------------------------------
21 21
22 22 #Latex substitutions for escaping latex.
23 23 LATEX_SUBS = (
24 24 (re.compile('\033\[[0-9;]+m'),''), # handle console escapes
25 (re.compile(r'\\'), r'\\textbackslash'),
25 (re.compile(r'\\'), r'{\\textbackslash}'),
26 26 (re.compile(r'([{}_#%&$])'), r'\\\1'),
27 27 (re.compile(r'~'), r'\~{}'),
28 28 (re.compile(r'\^'), r'\^{}'),
29 29 (re.compile(r'"'), r"''"),
30 30 (re.compile(r'\.\.\.+'), r'\\ldots'),
31 31 )
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Functions
35 35 #-----------------------------------------------------------------------------
36 36
37 37 __all__ = [
38 38 'escape_latex',
39 39 'strip_math_space'
40 40 ]
41 41
42 42
43 43 def escape_latex(text):
44 44 """
45 45 Escape characters that may conflict with latex.
46 46
47 47 Parameters
48 48 ----------
49 49 text : str
50 50 Text containing characters that may conflict with Latex
51 51 """
52 52 return_text = text
53 53 for pattern, replacement in LATEX_SUBS:
54 54 return_text = pattern.sub(replacement, return_text)
55 55 return return_text
56 56
57 57
58 58 def strip_math_space(text):
59 59 """
60 60 Remove the space between latex math commands and enclosing $ symbols.
61 61 This filter is important because latex isn't as flexible as the notebook
62 62 front end when it comes to flagging math using ampersand symbols.
63 63
64 64 Parameters
65 65 ----------
66 66 text : str
67 67 Text to filter.
68 68 """
69 69
70 70 # First, scan through the markdown looking for $. If
71 71 # a $ symbol is found, without a preceding \, assume
72 72 # it is the start of a math block. UNLESS that $ is
73 73 # not followed by another within two math_lines.
74 74 math_regions = []
75 75 math_lines = 0
76 76 within_math = False
77 77 math_start_index = 0
78 78 ptext = ''
79 79 last_character = ""
80 80 skip = False
81 81 for index, char in enumerate(text):
82 82
83 83 #Make sure the character isn't preceeded by a backslash
84 84 if (char == "$" and last_character != "\\"):
85 85
86 86 # Close the math region if this is an ending $
87 87 if within_math:
88 88 within_math = False
89 89 skip = True
90 90 ptext = ptext+'$'+text[math_start_index+1:index].strip()+'$'
91 91 math_regions.append([math_start_index, index+1])
92 92 else:
93 93
94 94 # Start a new math region
95 95 within_math = True
96 96 math_start_index = index
97 97 math_lines = 0
98 98
99 99 # If we are in a math region, count the number of lines parsed.
100 100 # Cancel the math region if we find two line breaks!
101 101 elif char == "\n":
102 102 if within_math:
103 103 math_lines += 1
104 104 if math_lines > 1:
105 105 within_math = False
106 106 ptext = ptext+text[math_start_index:index]
107 107
108 108 # Remember the last character so we can easily watch
109 109 # for backslashes
110 110 last_character = char
111 111 if not within_math and not skip:
112 112 ptext = ptext+char
113 113 if skip:
114 114 skip = False
115 115 return ptext
@@ -1,469 +1,469 b''
1 1 ((= NBConvert Sphinx-Latex Template
2 2
3 3 Purpose: Allow export of PDF friendly Latex inspired by Sphinx. Most of the
4 4 template is derived directly from Sphinx source.
5 5
6 6 Inheritance: null>display_priority
7 7
8 8 Note: For best display, use latex syntax highlighting. =))
9 9
10 10 ((*- extends 'display_priority.tplx' -*))
11 11
12 12
13 13 \nonstopmode
14 14
15 15 %==============================================================================
16 16 % Declarations
17 17 %==============================================================================
18 18
19 19 % In order to make sure that the input/output header follows the code it
20 20 % preceeds, the needspace package is used to request that a certain
21 21 % amount of lines (specified by this variable) are reserved. If those
22 22 % lines aren't available on the current page, the documenter will break
23 23 % to the next page and the header along with accomanying lines will be
24 24 % rendered together. This value specifies the number of lines that
25 25 % the header will be forced to group with without a page break.
26 26 ((*- set min_header_lines = 4 -*))
27 27
28 28 % This is the number of characters that are permitted per line. It's
29 29 % important that this limit is set so characters do not run off the
30 30 % edges of latex pages (since latex does not always seem smart enough
31 31 % to prevent this in some cases.) This is only applied to textual output
32 32 ((* if resources.sphinx.outputstyle == 'simple' *))
33 33 ((*- set wrap_size = 85 -*))
34 34 ((* elif resources.sphinx.outputstyle == 'notebook' *))
35 35 ((*- set wrap_size = 70 -*))
36 36 ((* endif *))
37 37
38 38 %==============================================================================
39 39 % Header
40 40 %==============================================================================
41 41 ((* block header *))
42 42
43 43 % Header, overrides base
44 44
45 45 % Make sure that the sphinx doc style knows who it inherits from.
46 46 \def\sphinxdocclass{(((parentdocumentclass)))}
47 47
48 48 % Declare the document class
49 49 \documentclass[letterpaper,10pt,english]{((( resources.sphinx.texinputs | posix_path )))/sphinx(((documentclass)))}
50 50
51 51 % Imports
52 52 \usepackage[utf8]{inputenc}
53 53 \DeclareUnicodeCharacter{00A0}{\\nobreakspace}
54 54 \usepackage[T1]{fontenc}
55 55 \usepackage{babel}
56 56 \usepackage{times}
57 57 \usepackage{import}
58 58 \usepackage[((( resources.sphinx.chapterstyle )))]{((( resources.sphinx.texinputs | posix_path )))/fncychap}
59 59 \usepackage{longtable}
60 60 \usepackage{((( resources.sphinx.texinputs | posix_path )))/sphinx}
61 61 \usepackage{multirow}
62 62
63 63 \usepackage{amsmath}
64 64 \usepackage{amssymb}
65 65 \usepackage{ucs}
66 66 \usepackage{enumerate}
67 67
68 68 % Used to make the Input/Output rules follow around the contents.
69 69 \usepackage{needspace}
70 70
71 71 % Pygments requirements
72 72 \usepackage{fancyvrb}
73 73 \usepackage{color}
74 74 % ansi colors additions
75 75 \definecolor{darkgreen}{rgb}{.12,.54,.11}
76 76 \definecolor{lightgray}{gray}{.95}
77 77 \definecolor{brown}{rgb}{0.54,0.27,0.07}
78 78 \definecolor{purple}{rgb}{0.5,0.0,0.5}
79 79 \definecolor{darkgray}{gray}{0.25}
80 80 \definecolor{lightred}{rgb}{1.0,0.39,0.28}
81 81 \definecolor{lightgreen}{rgb}{0.48,0.99,0.0}
82 82 \definecolor{lightblue}{rgb}{0.53,0.81,0.92}
83 83 \definecolor{lightpurple}{rgb}{0.87,0.63,0.87}
84 84 \definecolor{lightcyan}{rgb}{0.5,1.0,0.83}
85 85
86 86 % Needed to box output/input
87 87 \usepackage{tikz}
88 88 \usetikzlibrary{calc,arrows,shadows}
89 89 \usepackage[framemethod=tikz]{mdframed}
90 90
91 91 \usepackage{alltt}
92 92
93 93 % Used to load and display graphics
94 94 \usepackage{graphicx}
95 95 \graphicspath{ {figs/} }
96 96 \usepackage[Export]{adjustbox} % To resize
97 97
98 98 % used so that images for notebooks which have spaces in the name can still be included
99 99 \usepackage{grffile}
100 100
101 101
102 102 % For formatting output while also word wrapping.
103 103 \usepackage{listings}
104 104 \lstset{breaklines=true}
105 105 \lstset{basicstyle=\small\ttfamily}
106 106 \def\smaller{\fontsize{9.5pt}{9.5pt}\selectfont}
107 107
108 108 %Pygments definitions
109 109 ((( resources.sphinx.pygment_definitions )))
110 110
111 111 %Set pygments styles if needed...
112 112 ((* if resources.sphinx.outputstyle == 'notebook' *))
113 113 \definecolor{nbframe-border}{rgb}{0.867,0.867,0.867}
114 114 \definecolor{nbframe-bg}{rgb}{0.969,0.969,0.969}
115 115 \definecolor{nbframe-in-prompt}{rgb}{0.0,0.0,0.502}
116 116 \definecolor{nbframe-out-prompt}{rgb}{0.545,0.0,0.0}
117 117
118 118 \newenvironment{ColorVerbatim}
119 119 {\begin{mdframed}[%
120 120 roundcorner=1.0pt, %
121 121 backgroundcolor=nbframe-bg, %
122 122 userdefinedwidth=1\linewidth, %
123 123 leftmargin=0.1\linewidth, %
124 124 innerleftmargin=0pt, %
125 125 innerrightmargin=0pt, %
126 126 linecolor=nbframe-border, %
127 127 linewidth=1pt, %
128 128 usetwoside=false, %
129 129 everyline=true, %
130 130 innerlinewidth=3pt, %
131 131 innerlinecolor=nbframe-bg, %
132 132 middlelinewidth=1pt, %
133 133 middlelinecolor=nbframe-bg, %
134 134 outerlinewidth=0.5pt, %
135 135 outerlinecolor=nbframe-border, %
136 136 needspace=0pt
137 137 ]}
138 138 {\end{mdframed}}
139 139
140 140 \newenvironment{InvisibleVerbatim}
141 141 {\begin{mdframed}[leftmargin=0.1\linewidth,innerleftmargin=3pt,innerrightmargin=3pt, userdefinedwidth=1\linewidth, linewidth=0pt, linecolor=white, usetwoside=false]}
142 142 {\end{mdframed}}
143 143
144 144 \renewenvironment{Verbatim}[1][\unskip]
145 145 {\begin{alltt}\smaller}
146 146 {\end{alltt}}
147 147 ((* endif *))
148 148
149 149 % Help prevent overflowing lines due to urls and other hard-to-break
150 150 % entities. This doesn't catch everything...
151 151 \sloppy
152 152
153 153 % Document level variables
154 154 \title{((( resources.metadata.name | escape_latex )))}
155 155 \date{((( resources.sphinx.date | escape_latex )))}
156 156 \release{((( resources.sphinx.version | escape_latex )))}
157 157 \author{((( resources.sphinx.author | escape_latex )))}
158 158 \renewcommand{\releasename}{((( resources.sphinx.release | escape_latex )))}
159 159
160 160 % TODO: Add option for the user to specify a logo for his/her export.
161 161 \newcommand{\sphinxlogo}{}
162 162
163 163 % Make the index page of the document.
164 164 \makeindex
165 165
166 166 % Import sphinx document type specifics.
167 167 ((* block sphinxheader *))((* endblock sphinxheader *))
168 168 ((* endblock header *))
169 169
170 170 %==============================================================================
171 171 % Body
172 172 %==============================================================================
173 173 ((* block body *))
174 174 ((* block bodyBegin *))
175 175 % Body
176 176
177 177 % Start of the document
178 178 \begin{document}
179 179
180 180 ((* if resources.sphinx.header *))
181 181 \maketitle
182 182 ((* endif *))
183 183
184 184 ((* block toc *))
185 185 \tableofcontents
186 186 ((* endblock toc *))
187 187
188 188 ((* endblock bodyBegin *))
189 189 ((( super() )))
190 190 ((* block bodyEnd *))
191 191
192 192 \renewcommand{\indexname}{Index}
193 193 \printindex
194 194
195 195 % End of document
196 196 \end{document}
197 197 ((* endblock bodyEnd *))
198 198 ((* endblock body *))
199 199
200 200 %==============================================================================
201 201 % Footer
202 202 %==============================================================================
203 203 ((* block footer *))
204 204 ((* endblock footer *))
205 205
206 206 %==============================================================================
207 207 % Headings
208 208 %
209 209 % Purpose: Format pynb headers as sphinx headers. Depending on the Sphinx
210 210 % style that is active, this will change. Thus sphinx styles will
211 211 % override the values here.
212 212 %==============================================================================
213 213 ((* block headingcell -*))
214 214 \
215 215 ((*- if cell.level == 1 -*))
216 216 ((* block h1 -*))part((* endblock h1 -*))
217 217 ((*- elif cell.level == 2 -*))
218 218 ((* block h2 -*))chapter((* endblock h2 -*))
219 219 ((*- elif cell.level == 3 -*))
220 220 ((* block h3 -*))section((* endblock h3 -*))
221 221 ((*- elif cell.level == 4 -*))
222 222 ((* block h4 -*))subsection((* endblock h4 -*))
223 223 ((*- elif cell.level == 5 -*))
224 224 ((* block h5 -*))subsubsection((* endblock h5 -*))
225 225 ((*- elif cell.level == 6 -*))
226 226 ((* block h6 -*))paragraph((* endblock h6 -*))
227 227
228 228 ((= It's important to make sure that underscores (which tend to be common
229 229 in IPYNB file titles) do not make their way into latex. Sometimes this
230 230 causes latex to barf. =))
231 231 ((*- endif -*))
232 232 {((( cell.source | markdown2latex )))}
233 233 ((*- endblock headingcell *))
234 234
235 235 %==============================================================================
236 236 % Markdown
237 237 %
238 238 % Purpose: Convert markdown to latex. Here markdown2latex is explicitly
239 239 % called since we know we want latex output.
240 240 %==============================================================================
241 241 ((*- block markdowncell scoped-*))
242 242 ((( cell.source | markdown2latex )))
243 243 ((*- endblock markdowncell -*))
244 244
245 245 %==============================================================================
246 246 % Rawcell
247 247 %
248 248 % Purpose: Raw text cells allow the user to manually inject document code that
249 249 % will not get touched by the templating system.
250 250 %==============================================================================
251 251 ((*- block rawcell *))
252 252 ((( cell.source | wrap_text(wrap_size) )))
253 253 ((* endblock rawcell -*))
254 254
255 255 %==============================================================================
256 256 % Unknowncell
257 257 %
258 258 % Purpose: This is the catch anything unhandled. To display this data, we
259 259 % remove all possible latex conflicts and wrap the characters so they
260 260 % can't flow off of the page.
261 261 %==============================================================================
262 262 ((* block unknowncell scoped*))
263 263 % Unsupported cell type, no formatting
264 264 ((( cell.source | wrap_text | escape_latex )))
265 265 ((* endblock unknowncell *))
266 266
267 267 %==============================================================================
268 268 % Input
269 269 %==============================================================================
270 270 ((* block input *))
271 271
272 272 % Make sure that atleast 4 lines are below the HR
273 273 \needspace{((( min_header_lines )))\baselineskip}
274 274
275 275 ((* if resources.sphinx.outputstyle == 'simple' *))
276 276
277 277 % Add a horizantal break, along with break title.
278 278 \vspace{10pt}
279 279 {\scriptsize Input}\\*
280 280 \rule[10pt]{\linewidth}{0.5pt}
281 281 \vspace{-25pt}
282 282
283 283 % Add contents below.
284 284 ((( cell.input | highlight2latex )))
285 285
286 286 ((* elif resources.sphinx.outputstyle == 'notebook' *))
287 287 \vspace{6pt}
288 288 ((( write_prompt("In", cell.prompt_number, "nbframe-in-prompt") )))
289 289 \vspace{-2.65\baselineskip}
290 290 \begin{ColorVerbatim}
291 291 \vspace{-0.7\baselineskip}
292 292 ((( cell.input | highlight2latex )))
293 293 ((* if cell.input == None or cell.input == '' *))
294 294 \vspace{0.3\baselineskip}
295 295 ((* else *))
296 296 \vspace{-0.2\baselineskip}
297 297 ((* endif *))
298 298 \end{ColorVerbatim}
299 299 ((* endif *))
300 300 ((* endblock input *))
301 301
302 302 %==============================================================================
303 303 % Output_Group
304 304 %
305 305 % Purpose: Make sure that only one header bar only attaches to the output
306 306 % once. By keeping track of when an input group is started
307 307 %==============================================================================
308 308 ((* block output_group *))
309 309 ((* if cell.outputs.__len__() > 0 *))
310 310
311 311 % If the first block is an image, minipage the image. Else
312 312 % request a certain amount of space for the input text.
313 313 ((( iff_figure(cell.outputs[0], "\\begin{minipage}{1.0\\textwidth}", "\\needspace{" ~ min_header_lines ~ "\\baselineskip}") )))
314 314
315 315 ((* if resources.sphinx.outputstyle == 'simple' *))
316 316
317 317 % Add a horizantal break, along with break title.
318 318 \vspace{10pt}
319 319 {\scriptsize Output}\\*
320 320 \rule[10pt]{\linewidth}{0.5pt}
321 321 \vspace{-20pt}
322 322
323 323 % Add the contents of the first block.
324 324 ((( render_output(cell.outputs[0]) )))
325 325
326 326 % Close the minipage.
327 327 ((( iff_figure(cell.outputs[0], "\\end{minipage}", "") )))
328 328
329 329 % Add remainer of the document contents below.
330 330 ((* for output in cell.outputs[1:] *))
331 331 ((( render_output(output, cell.prompt_number) )))
332 332 ((* endfor *))
333 333 ((* elif resources.sphinx.outputstyle == 'notebook' *))
334 334
335 335 % Add document contents.
336 336 ((* for output in cell.outputs *))
337 337 ((( render_output(output, cell.prompt_number) )))
338 338 ((* endfor *))
339 339 ((* endif *))
340 340 ((* endif *))
341 341 ((* endblock *))
342 342
343 343 %==============================================================================
344 344 % Additional formating
345 345 %==============================================================================
346 346 ((* block data_text *))
347 347 ((( custom_verbatim(output.text) | ansi2latex )))
348 348 ((* endblock *))
349 349
350 350 ((* block traceback_line *))
351 351 ((( conditionally_center_output( line | indent| strip_ansi ) )))
352 352 ((* endblock traceback_line *))
353 353
354 354 %==============================================================================
355 355 % Supported image formats
356 356 %==============================================================================
357 357 ((*- block data_png -*))
358 358 ((( conditionally_center_output(insert_graphics(output.png_filename | posix_path)) )))
359 359 ((*- endblock -*))
360 360
361 361 ((*- block data_jpg -*))
362 362 ((( conditionally_center_output(insert_graphics(output.jpg_filename | posix_path)) )))
363 363 ((*- endblock -*))
364 364
365 365 ((*- block data_svg -*))
366 366 ((( conditionally_center_output(insert_graphics(output.svg_filename | posix_path)) )))
367 367 ((*- endblock -*))
368 368
369 369 ((*- block data_pdf -*))
370 370 ((( conditionally_center_output(insert_graphics(output.pdf_filename | posix_path)) )))
371 371 ((*- endblock -*))
372 372
373 373 ((*- block data_latex *))
374 374 ((* if resources.sphinx.centeroutput *))
375 375 \begin{center}
376 376 ((* endif -*))
377 377 ((( output.latex | strip_math_space )))
378 378 ((*- if resources.sphinx.centeroutput *))
379 379 \end{center}
380 380 ((* endif -*))
381 381 ((*- endblock -*))
382 382
383 383 %==============================================================================
384 384 % Support Macros
385 385 %==============================================================================
386 386
387 387 % Name: write_prompt
388 388 % Purpose: Renders an output/input prompt for notebook style pdfs
389 389 ((* macro write_prompt(prompt, number, color) -*))
390 390 \makebox[0.1\linewidth]{\smaller\hfill\tt\color{((( color )))}((( prompt )))\hspace{4pt}{[}((( number ))){]}:\hspace{4pt}}\\*
391 391 ((*- endmacro *))
392 392
393 393 % Name: render_output
394 394 % Purpose: Renders an output block appropriately.
395 395 ((* macro render_output(output, prompt_number) -*))
396 396 ((*- if output.output_type == 'pyerr' -*))
397 397 ((*- block pyerr scoped *))
398 398 ((( custom_verbatim(super()) )))
399 399 ((* endblock pyerr -*))
400 400 ((*- else -*))
401 401
402 402 ((* if resources.sphinx.outputstyle == 'notebook' *))
403 403 ((*- if output.output_type == 'pyout' -*))
404 404 ((( write_prompt("Out", prompt_number, "nbframe-out-prompt") )))
405 405 \vspace{-2.55\baselineskip}
406 406 ((*- endif -*))
407 407
408 408 \begin{InvisibleVerbatim}
409 409 \vspace{-0.5\baselineskip}
410 410 ((*- endif -*))
411 411
412 412 ((*- block display_data scoped -*))
413 413 ((( super() )))
414 414 ((*- endblock display_data -*))
415 415
416 416 ((* if resources.sphinx.outputstyle == 'notebook' *))
417 417 \end{InvisibleVerbatim}
418 418 ((*- endif -*))
419 419 ((*- endif -*))
420 420 ((*- endmacro *))
421 421
422 422 % Name: iff_figure
423 423 % Purpose: If the output block provided is a figure type, the 'true_content'
424 424 % parameter will be returned. Else, the 'false_content'.
425 425 ((* macro iff_figure(output, true_content, false_content) -*))
426 426 ((*- set is_figure = false -*))
427 427 ((*- for type in output | filter_data_type -*))
428 428 ((*- if type in ['pdf', 'svg', 'png', 'jpeg','html']*))
429 429 ((*- set is_figure = true -*))
430 430 ((*- endif -*))
431 431 ((*- endfor -*))
432 432
433 433 ((* if is_figure -*))
434 434 ((( true_content )))
435 435 ((*- else -*))
436 436 ((( false_content )))
437 437 ((*- endif *))
438 438 ((*- endmacro *))
439 439
440 440 % Name: custom_verbatim
441 441 % Purpose: This macro creates a verbatim style block that fits the existing
442 442 % sphinx style more readily than standard verbatim blocks.
443 443 ((* macro custom_verbatim(text) -*))
444 444 \begin{alltt}
445 445 ((*- if resources.sphinx.centeroutput *))\begin{center} ((* endif -*))
446 ((( text | wrap_text(wrap_size) )))
446 ((( text | wrap_text(wrap_size) | escape_latex )))
447 447 ((*- if resources.sphinx.centeroutput *))\end{center}((* endif -*))
448 448 \end{alltt}
449 449 ((*- endmacro *))
450 450
451 451 % Name: conditionally_center_output
452 452 % Purpose: This macro centers the output if the output centering is enabled.
453 453 ((* macro conditionally_center_output(text) -*))
454 454 ((* if resources.sphinx.centeroutput *))
455 455 {\centering
456 456 ((* endif *))
457 457 ((( text )))
458 458 ((* if resources.sphinx.centeroutput *))}
459 459 ((* endif *))
460 460 ((*- endmacro *))
461 461
462 462 % Name: insert_graphics
463 463 % Purpose: This macro will insert an image in the latex document given a path.
464 464 ((* macro insert_graphics(path) -*))
465 465 \begin{center}
466 466 \includegraphics[max size={\textwidth}{\textheight}]{((( path )))}
467 467 \par
468 468 \end{center}
469 469 ((*- endmacro *))
General Comments 0
You need to be logged in to leave comments. Login now