##// END OF EJS Templates
Embed LaTeX output from pyout into equation* environment
jakobgager -
Show More
@@ -1,198 +1,198 b''
1 1 from converters.base import Converter
2 2 from converters.utils import markdown2latex, remove_ansi
3 3 import os
4 4 import subprocess
5 5 import sys
6 6
7 7 inkscape = 'inkscape'
8 8 if sys.platform == 'darwin':
9 9 inkscape = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape'
10 10 if not os.path.exists(inkscape):
11 11 inkscape = None
12 12
13 13
14 14 class ConverterLaTeX(Converter):
15 15 """Converts a notebook to a .tex file suitable for pdflatex.
16 16
17 17 Note: this converter *needs*:
18 18
19 19 - `pandoc`: for all conversion of markdown cells. If your notebook only
20 20 has Raw cells, pandoc will not be needed.
21 21
22 22 - `inkscape`: if your notebook has SVG figures. These need to be
23 23 converted to PDF before inclusion in the TeX file, as LaTeX doesn't
24 24 understand SVG natively.
25 25
26 26 You will in general obtain much better final PDF results if you configure
27 27 the matplotlib backend to create SVG output with
28 28
29 29 %config InlineBackend.figure_format = 'svg'
30 30
31 31 (or set the equivalent flag at startup or in your configuration profile).
32 32 """
33 33 inkscape = inkscape
34 34 extension = 'tex'
35 35 documentclass = 'article'
36 36 documentclass_options = '11pt,english'
37 37 heading_map = {1: r'\section',
38 38 2: r'\subsection',
39 39 3: r'\subsubsection',
40 40 4: r'\paragraph',
41 41 5: r'\subparagraph',
42 42 6: r'\subparagraph'}
43 43 user_preamble = None
44 44 exclude_cells = []
45 45
46 46 def in_env(self, environment, lines):
47 47 """Return list of environment lines for input lines
48 48
49 49 Parameters
50 50 ----------
51 51 env : string
52 52 Name of the environment to bracket with begin/end.
53 53
54 54 lines: """
55 55 out = [ur'\begin{%s}' % environment]
56 56 if isinstance(lines, basestring):
57 57 out.append(lines)
58 58 else: # list
59 59 out.extend(lines)
60 60 out.append(ur'\end{%s}' % environment)
61 61 return out
62 62
63 63 def convert(self, *args, **kwargs):
64 64 # The main body is done by the logic in the parent class, and that's
65 65 # all we need if preamble support has been turned off.
66 66 body = super(ConverterLaTeX, self).convert(*args, **kwargs)
67 67 if not self.with_preamble:
68 68 return body
69 69 # But if preamble is on, then we need to construct a proper, standalone
70 70 # tex file.
71 71
72 72 # Tag the document at the top and set latex class
73 73 final = [r'%% This file was auto-generated by IPython, do NOT edit',
74 74 r'%% Conversion from the original notebook file:',
75 75 r'%% {0}'.format(self.infile),
76 76 r'%%',
77 77 r'\documentclass[%s]{%s}' % (self.documentclass_options,
78 78 self.documentclass),
79 79 '',
80 80 ]
81 81 # Load our own preamble, which is stored next to the main file. We
82 82 # need to be careful in case the script entry point is a symlink
83 83 myfile = os.path.realpath(__file__)
84 84 preamble = '../preamble.tex'
85 85 with open(os.path.join(os.path.dirname(myfile), preamble)) as f:
86 86 final.append(f.read())
87 87
88 88 # Load any additional user-supplied preamble
89 89 if self.user_preamble:
90 90 final.extend(['', '%% Adding user preamble from file:',
91 91 '%% {0}'.format(self.user_preamble), ''])
92 92 with open(self.user_preamble) as f:
93 93 final.append(f.read())
94 94
95 95 # Include document body
96 96 final.extend([r'\begin{document}', '',
97 97 body,
98 98 r'\end{document}', ''])
99 99 # Retun value must be a string
100 100 return '\n'.join(final)
101 101
102 102 def render_heading(self, cell):
103 103 marker = self.heading_map[cell.level]
104 104 return ['%s{%s}' % (marker, cell.source)]
105 105
106 106 def render_code(self, cell):
107 107 if not cell.input:
108 108 return []
109 109
110 110 # Cell codes first carry input code, we use lstlisting for that
111 111 lines = [ur'\begin{codecell}']
112 112
113 113 if 'source' not in self.exclude_cells:
114 114 lines.extend(self.in_env('codeinput',
115 115 self.in_env('lstlisting', cell.input)))
116 116 else:
117 117 # Empty output is still needed for LaTeX formatting
118 118 lines.extend(self.in_env('codeinput', ''))
119 119
120 120 outlines = []
121 121 if 'output' not in self.exclude_cells:
122 122 for output in cell.outputs:
123 123 conv_fn = self.dispatch(output.output_type)
124 124 outlines.extend(conv_fn(output))
125 125
126 126 # And then output of many possible types; use a frame for all of it.
127 127 if outlines:
128 128 lines.extend(self.in_env('codeoutput', outlines))
129 129
130 130 lines.append(ur'\end{codecell}')
131 131
132 132 return lines
133 133
134 134 def _img_lines(self, img_file):
135 135 return self.in_env('center',
136 136 [r'\includegraphics[width=6in]{%s}' % img_file, r'\par'])
137 137
138 138 def _svg_lines(self, img_file):
139 139 base_file = os.path.splitext(img_file)[0]
140 140 pdf_file = base_file + '.pdf'
141 141 subprocess.check_call([self.inkscape, '--export-pdf=%s' % pdf_file,
142 142 img_file])
143 143 return self._img_lines(pdf_file)
144 144
145 145 def render_markdown(self, cell):
146 146 return [markdown2latex(cell.source)]
147 147
148 148 def render_pyout(self, output):
149 149 lines = []
150 150
151 151 # output is a dictionary like object with type as a key
152 152 if 'latex' in output:
153 lines.extend(output.latex)
153 lines.extend(self.in_env('equation*', output.latex.lstrip('$$').rstrip('$$')))
154 154
155 155 if 'text' in output:
156 156 lines.extend(self.in_env('verbatim', output.text))
157 157
158 158 return lines
159 159
160 160 def render_pyerr(self, output):
161 161 # Note: a traceback is a *list* of frames.
162 162 return self.in_env('traceback',
163 163 self.in_env('verbatim',
164 164 remove_ansi('\n'.join(output.traceback))))
165 165
166 166 def render_raw(self, cell):
167 167 if self.raw_as_verbatim:
168 168 return self.in_env('verbatim', cell.source)
169 169 else:
170 170 return [cell.source]
171 171
172 172 def _unknown_lines(self, data):
173 173 return [r'{\vspace{5mm}\bf WARNING:: unknown cell:}'] + \
174 174 self.in_env('verbatim', data)
175 175
176 176 def render_display_format_text(self, output):
177 177 lines = []
178 178
179 179 if 'text' in output:
180 180 lines.extend(self.in_env('verbatim', output.text.strip()))
181 181
182 182 return lines
183 183
184 184 def render_display_format_html(self, output):
185 185 return []
186 186
187 187 def render_display_format_latex(self, output):
188 188 if type(output.latex) == type([]):
189 189 return output.latex
190 190 return [output.latex]
191 191
192 192 def render_display_format_json(self, output):
193 193 # latex ignores json
194 194 return []
195 195
196 196 def render_display_format_javascript(self, output):
197 197 # latex ignores javascript
198 198 return []
General Comments 0
You need to be logged in to leave comments. Login now