Show More
@@ -0,0 +1,94 b'' | |||||
|
1 | %% This is the automatic preamble used by IPython. Note that it does *not* | |||
|
2 | %% include a documentclass declaration, that is added at runtime to the overall | |||
|
3 | %% document. | |||
|
4 | ||||
|
5 | \usepackage{amsmath} | |||
|
6 | \usepackage{amssymb} | |||
|
7 | \usepackage{graphicx} | |||
|
8 | ||||
|
9 | % needed for markdown enumerations to work | |||
|
10 | \usepackage{enumerate} | |||
|
11 | ||||
|
12 | % Slightly bigger margins than the latex defaults | |||
|
13 | \usepackage{geometry} | |||
|
14 | \geometry{verbose,tmargin=3cm,bmargin=3cm,lmargin=2.5cm,rmargin=2.5cm} | |||
|
15 | ||||
|
16 | % Define a few colors for use in code, links and cell shading | |||
|
17 | \usepackage{color} | |||
|
18 | \definecolor{orange}{cmyk}{0,0.4,0.8,0.2} | |||
|
19 | \definecolor{darkorange}{rgb}{.71,0.21,0.01} | |||
|
20 | \definecolor{darkgreen}{rgb}{.12,.54,.11} | |||
|
21 | \definecolor{myteal}{rgb}{.26, .44, .56} | |||
|
22 | \definecolor{gray}{gray}{0.45} | |||
|
23 | \definecolor{lightgray}{gray}{.95} | |||
|
24 | \definecolor{mediumgray}{gray}{.8} | |||
|
25 | \definecolor{inputbackground}{rgb}{.95, .95, .85} | |||
|
26 | \definecolor{outputbackground}{rgb}{.95, .95, .95} | |||
|
27 | \definecolor{traceback}{rgb}{1, .95, .95} | |||
|
28 | ||||
|
29 | % Framed environments for code cells (inputs, outputs, errors, ...). The | |||
|
30 | % various uses of \unskip (or not) at the end were fine-tuned by hand, so don't | |||
|
31 | % randomly change them unless you're sure of the effect it will have. | |||
|
32 | \usepackage{framed} | |||
|
33 | ||||
|
34 | % remove extraneous vertical space in boxes | |||
|
35 | \setlength\fboxsep{0pt} | |||
|
36 | ||||
|
37 | % codecell is the whole input+output set of blocks that a Code cell can | |||
|
38 | % generate. | |||
|
39 | \newenvironment{codecell}{% | |||
|
40 | \def\FrameCommand{\color{mediumgray} \vrule width 1pt \hspace{5pt}}% | |||
|
41 | \MakeFramed{\vspace{-0.5em}\FrameRestore}} | |||
|
42 | {\unskip\endMakeFramed} | |||
|
43 | ||||
|
44 | \newenvironment{codeinput}{% | |||
|
45 | \def\FrameCommand{\colorbox{inputbackground}}% | |||
|
46 | \MakeFramed{\advance\hsize-\width \FrameRestore}} | |||
|
47 | {\unskip\endMakeFramed} | |||
|
48 | ||||
|
49 | \newenvironment{codeoutput}{% | |||
|
50 | \def\FrameCommand{\colorbox{outputbackground}}% | |||
|
51 | \vspace{-1.4em} | |||
|
52 | \MakeFramed{\advance\hsize-\width \FrameRestore}} | |||
|
53 | {\unskip\medskip\endMakeFramed} | |||
|
54 | ||||
|
55 | \newenvironment{traceback}{% | |||
|
56 | \def\FrameCommand{\colorbox{traceback}}% | |||
|
57 | \MakeFramed{\advance\hsize-\width \FrameRestore}} | |||
|
58 | {\endMakeFramed} | |||
|
59 | ||||
|
60 | % Use and configure listings package for nicely formatted code | |||
|
61 | \usepackage{listings} | |||
|
62 | \lstset{ | |||
|
63 | language=python, | |||
|
64 | aboveskip=\smallskipamount, | |||
|
65 | belowskip=\smallskipamount, | |||
|
66 | %xleftmargin=3mm, | |||
|
67 | breaklines=true, | |||
|
68 | basicstyle=\small \ttfamily, | |||
|
69 | showstringspaces=false, | |||
|
70 | keywordstyle=\color{blue}\bfseries, | |||
|
71 | commentstyle=\color{myteal}, | |||
|
72 | stringstyle=\color{darkgreen}, | |||
|
73 | identifierstyle=\color{darkorange}, | |||
|
74 | } | |||
|
75 | ||||
|
76 | % The hyperref package gives us a pdf with properly built | |||
|
77 | % internal navigation ('pdf bookmarks' for the table of contents, | |||
|
78 | % internal cross-reference links, web links for URLs, etc.) | |||
|
79 | \usepackage{hyperref} | |||
|
80 | \hypersetup{ | |||
|
81 | breaklinks=true, % so long urls are correctly broken across lines | |||
|
82 | colorlinks=true, | |||
|
83 | urlcolor=blue, | |||
|
84 | linkcolor=darkorange, | |||
|
85 | citecolor=darkgreen, | |||
|
86 | } | |||
|
87 | ||||
|
88 | % hardcode size of all verbatim environments to be a bit smaller | |||
|
89 | \makeatletter | |||
|
90 | \g@addto@macro\@verbatim\small\topsep=0.5em\partopsep=0pt | |||
|
91 | \makeatother | |||
|
92 | ||||
|
93 | % Prevent overflowing lines due to urls and other hard-to-break entities. | |||
|
94 | \sloppy |
@@ -9,23 +9,82 b' called nb_figure_NN.png. To avoid the two-step process, ipynb -> rst -> html,' | |||||
9 | use '--format quick-html' which will do ipynb -> html, but won't look as |
|
9 | use '--format quick-html' which will do ipynb -> html, but won't look as | |
10 | pretty. |
|
10 | pretty. | |
11 | """ |
|
11 | """ | |
12 |
|
12 | #----------------------------------------------------------------------------- | ||
|
13 | # Imports | |||
|
14 | #----------------------------------------------------------------------------- | |||
|
15 | from __future__ import print_function | |||
|
16 | ||||
|
17 | # Stdlib | |||
|
18 | import codecs | |||
|
19 | import logging | |||
13 | import os |
|
20 | import os | |
|
21 | import pprint | |||
|
22 | import re | |||
14 | import subprocess |
|
23 | import subprocess | |
15 | import sys |
|
24 | import sys | |
|
25 | ||||
|
26 | inkscape = 'inkscape' | |||
|
27 | if sys.platform == 'darwin': | |||
|
28 | inkscape = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape' | |||
|
29 | if not os.path.exists(inkscape): | |||
|
30 | inkscape = None | |||
|
31 | ||||
|
32 | # From IPython | |||
16 | from IPython.external import argparse |
|
33 | from IPython.external import argparse | |
17 | from IPython.nbformat import current as nbformat |
|
34 | from IPython.nbformat import current as nbformat | |
18 | from IPython.utils.text import indent |
|
35 | from IPython.utils.text import indent | |
19 | from decorators import DocInherit |
|
36 | from decorators import DocInherit | |
20 |
|
37 | |||
21 | # Cell converters |
|
38 | #----------------------------------------------------------------------------- | |
|
39 | # Utility functions | |||
|
40 | #----------------------------------------------------------------------------- | |||
|
41 | ||||
|
42 | def remove_fake_files_url(cell): | |||
|
43 | """Remove from the cell source the /files/ pseudo-path we use. | |||
|
44 | """ | |||
|
45 | src = cell.source | |||
|
46 | cell.source = src.replace('/files/', '') | |||
|
47 | ||||
|
48 | ||||
|
49 | def remove_ansi(src): | |||
|
50 | """Strip all ANSI color escape sequences from input string. | |||
|
51 | ||||
|
52 | Parameters | |||
|
53 | ---------- | |||
|
54 | src : string | |||
22 |
|
|
55 | ||
23 | def unknown_cell(cell): |
|
56 | Returns | |
24 | """Default converter for cells of unknown type. |
|
57 | ------- | |
|
58 | string | |||
25 | """ |
|
59 | """ | |
|
60 | return re.sub(r'\033\[(0|\d;\d\d)m', '', src) | |||
26 |
|
61 | |||
27 | return rst_directive('.. warning:: Unknown cell') + \ |
|
62 | ||
28 | [repr(cell)] |
|
63 | # Pandoc-dependent code | |
|
64 | def markdown2latex(src): | |||
|
65 | """Convert a markdown string to LaTeX via pandoc. | |||
|
66 | ||||
|
67 | This function will raise an error if pandoc is not installed. | |||
|
68 | ||||
|
69 | Any error messages generated by pandoc are printed to stderr. | |||
|
70 | ||||
|
71 | Parameters | |||
|
72 | ---------- | |||
|
73 | src : string | |||
|
74 | Input string, assumed to be valid markdown. | |||
|
75 | ||||
|
76 | Returns | |||
|
77 | ------- | |||
|
78 | out : string | |||
|
79 | Output as returned by pandoc. | |||
|
80 | """ | |||
|
81 | p = subprocess.Popen('pandoc -f markdown -t latex'.split(), | |||
|
82 | stdin=subprocess.PIPE, stdout=subprocess.PIPE) | |||
|
83 | out, err = p.communicate(src) | |||
|
84 | if err: | |||
|
85 | print(err, file=sys.stderr) | |||
|
86 | #print('*'*20+'\n', out, '\n'+'*'*20) # dbg | |||
|
87 | return out | |||
29 |
|
88 | |||
30 |
|
89 | |||
31 | def rst_directive(directive, text=''): |
|
90 | def rst_directive(directive, text=''): | |
@@ -34,8 +93,9 b" def rst_directive(directive, text=''):" | |||||
34 | out.extend([indent(text), '']) |
|
93 | out.extend([indent(text), '']) | |
35 | return out |
|
94 | return out | |
36 |
|
95 | |||
37 | # Converters for parts of a cell. |
|
96 | #----------------------------------------------------------------------------- | |
38 |
|
97 | # Class declarations | ||
|
98 | #----------------------------------------------------------------------------- | |||
39 |
|
99 | |||
40 | class ConversionException(Exception): |
|
100 | class ConversionException(Exception): | |
41 | pass |
|
101 | pass | |
@@ -43,29 +103,43 b' class ConversionException(Exception):' | |||||
43 |
|
103 | |||
44 | class Converter(object): |
|
104 | class Converter(object): | |
45 | default_encoding = 'utf-8' |
|
105 | default_encoding = 'utf-8' | |
46 |
|
106 | extension = str() | ||
|
107 | figures_counter = 0 | |||
|
108 | infile = str() | |||
|
109 | infile_dir = str() | |||
|
110 | infile_root = str() | |||
|
111 | files_dir = str() | |||
|
112 | with_preamble = True | |||
|
113 | user_preamble = None | |||
|
114 | output = str() | |||
|
115 | raw_as_verbatim = False | |||
|
116 | ||||
47 | def __init__(self, infile): |
|
117 | def __init__(self, infile): | |
48 | self.infile = infile |
|
118 | self.infile = infile | |
49 |
self.dir |
|
119 | self.infile_dir = os.path.dirname(infile) | |
50 |
|
120 | infile_root = os.path.splitext(infile)[0] | ||
51 | @property |
|
121 | files_dir = infile_root + '_files' | |
52 | def extension(self): |
|
122 | if not os.path.isdir(files_dir): | |
53 | raise ConversionException("""extension must be defined in Converter |
|
123 | os.mkdir(files_dir) | |
54 | subclass""") |
|
124 | self.infile_root = infile_root | |
|
125 | self.files_dir = files_dir | |||
55 |
|
126 | |||
56 | def dispatch(self, cell_type): |
|
127 | def dispatch(self, cell_type): | |
57 | """return cell_type dependent render method, for example render_code |
|
128 | """return cell_type dependent render method, for example render_code | |
58 | """ |
|
129 | """ | |
59 | # XXX: unknown_cell here is RST specific - make it generic |
|
130 | return getattr(self, 'render_' + cell_type, self.render_unknown) | |
60 | return getattr(self, 'render_' + cell_type, unknown_cell) |
|
|||
61 |
|
131 | |||
62 | def convert(self): |
|
132 | def convert(self): | |
63 | lines = [] |
|
133 | lines = [] | |
64 | lines.extend(self.optional_header()) |
|
134 | lines.extend(self.optional_header()) | |
65 |
for |
|
135 | for worksheet in self.nb.worksheets: | |
66 | conv_fn = self.dispatch(cell.cell_type) |
|
136 | for cell in worksheet.cells: | |
67 | lines.extend(conv_fn(cell)) |
|
137 | #print(cell.cell_type) # dbg | |
68 | lines.append('') |
|
138 | conv_fn = self.dispatch(cell.cell_type) | |
|
139 | if cell.cell_type in ('markdown', 'raw'): | |||
|
140 | remove_fake_files_url(cell) | |||
|
141 | lines.extend(conv_fn(cell)) | |||
|
142 | lines.append('') | |||
69 | lines.extend(self.optional_footer()) |
|
143 | lines.extend(self.optional_footer()) | |
70 | return '\n'.join(lines) |
|
144 | return '\n'.join(lines) | |
71 |
|
145 | |||
@@ -83,12 +157,13 b' class Converter(object):' | |||||
83 | def save(self, infile=None, encoding=None): |
|
157 | def save(self, infile=None, encoding=None): | |
84 | "read and parse notebook into self.nb" |
|
158 | "read and parse notebook into self.nb" | |
85 | if infile is None: |
|
159 | if infile is None: | |
86 |
|
|
160 | outfile = os.path.basename(self.infile) | |
|
161 | outfile = os.path.splitext(outfile)[0] + '.' + self.extension | |||
87 | if encoding is None: |
|
162 | if encoding is None: | |
88 | encoding = self.default_encoding |
|
163 | encoding = self.default_encoding | |
89 |
with open( |
|
164 | with open(outfile, 'w') as f: | |
90 | f.write(self.output.encode(encoding)) |
|
165 | f.write(self.output.encode(encoding)) | |
91 |
return |
|
166 | return os.path.abspath(outfile) | |
92 |
|
167 | |||
93 | def optional_header(self): |
|
168 | def optional_header(self): | |
94 | return [] |
|
169 | return [] | |
@@ -96,6 +171,28 b' class Converter(object):' | |||||
96 | def optional_footer(self): |
|
171 | def optional_footer(self): | |
97 | return [] |
|
172 | return [] | |
98 |
|
173 | |||
|
174 | def _new_figure(self, data, fmt): | |||
|
175 | """Create a new figure file in the given format. | |||
|
176 | ||||
|
177 | Returns a path relative to the input file. | |||
|
178 | """ | |||
|
179 | figname = '%s_fig_%02i.%s' % (self.infile_root, | |||
|
180 | self.figures_counter, fmt) | |||
|
181 | self.figures_counter += 1 | |||
|
182 | fullname = os.path.join(self.files_dir, figname) | |||
|
183 | ||||
|
184 | # Binary files are base64-encoded, SVG is already XML | |||
|
185 | if fmt in ('png', 'jpg', 'pdf'): | |||
|
186 | data = data.decode('base64') | |||
|
187 | fopen = lambda fname: open(fname, 'wb') | |||
|
188 | else: | |||
|
189 | fopen = lambda fname: codecs.open(fname, 'wb', self.default_encoding) | |||
|
190 | ||||
|
191 | with fopen(fullname) as f: | |||
|
192 | f.write(data) | |||
|
193 | ||||
|
194 | return fullname | |||
|
195 | ||||
99 | def render_heading(self, cell): |
|
196 | def render_heading(self, cell): | |
100 | """convert a heading cell |
|
197 | """convert a heading cell | |
101 |
|
198 | |||
@@ -114,18 +211,43 b' class Converter(object):' | |||||
114 | Returns list.""" |
|
211 | Returns list.""" | |
115 | raise NotImplementedError |
|
212 | raise NotImplementedError | |
116 |
|
213 | |||
117 |
def render_pyout(self, |
|
214 | def render_pyout(self, output): | |
118 | """convert pyout part of a code cell |
|
215 | """convert pyout part of a code cell | |
119 |
|
216 | |||
120 | Returns list.""" |
|
217 | Returns list.""" | |
121 | raise NotImplementedError |
|
218 | raise NotImplementedError | |
122 |
|
219 | |||
123 | def render_display_data(self, cell): |
|
220 | ||
|
221 | def render_pyerr(self, output): | |||
|
222 | """convert pyerr part of a code cell | |||
|
223 | ||||
|
224 | Returns list.""" | |||
|
225 | raise NotImplementedError | |||
|
226 | ||||
|
227 | def _img_lines(self, img_file): | |||
|
228 | """Return list of lines to include an image file.""" | |||
|
229 | # Note: subclasses may choose to implement format-specific _FMT_lines | |||
|
230 | # methods if they so choose (FMT in {png, svg, jpg, pdf}). | |||
|
231 | raise NotImplementedError | |||
|
232 | ||||
|
233 | def render_display_data(self, output): | |||
124 | """convert display data from the output of a code cell |
|
234 | """convert display data from the output of a code cell | |
125 |
|
235 | |||
126 | Returns list. |
|
236 | Returns list. | |
127 | """ |
|
237 | """ | |
128 | raise NotImplementedError |
|
238 | lines = [] | |
|
239 | ||||
|
240 | for fmt in ['png', 'svg', 'jpg', 'pdf']: | |||
|
241 | if fmt in output: | |||
|
242 | img_file = self._new_figure(output[fmt], fmt) | |||
|
243 | # Subclasses can have format-specific render functions (e.g., | |||
|
244 | # latex has to auto-convert all SVG to PDF first). | |||
|
245 | lines_fun = getattr(self, '_%s_lines' % fmt, None) | |||
|
246 | if not lines_fun: | |||
|
247 | lines_fun = self._img_lines | |||
|
248 | lines.extend(lines_fun(img_file)) | |||
|
249 | ||||
|
250 | return lines | |||
129 |
|
251 | |||
130 | def render_stream(self, cell): |
|
252 | def render_stream(self, cell): | |
131 | """convert stream part of a code cell |
|
253 | """convert stream part of a code cell | |
@@ -133,16 +255,33 b' class Converter(object):' | |||||
133 | Returns list.""" |
|
255 | Returns list.""" | |
134 | raise NotImplementedError |
|
256 | raise NotImplementedError | |
135 |
|
257 | |||
136 |
def render_ |
|
258 | def render_raw(self, cell): | |
137 |
"""convert |
|
259 | """convert a cell with raw text | |
138 |
|
260 | |||
139 | Returns list.""" |
|
261 | Returns list.""" | |
140 | raise NotImplementedError |
|
262 | raise NotImplementedError | |
141 |
|
263 | |||
|
264 | def render_unknown(self, cell): | |||
|
265 | """Render cells of unkown type | |||
|
266 | ||||
|
267 | Returns list.""" | |||
|
268 | data = pprint.pformat(cell) | |||
|
269 | logging.warning('Unknown cell:\n%s' % data) | |||
|
270 | return self._unknown_lines(data) | |||
|
271 | ||||
|
272 | def _unknown_lines(self, data): | |||
|
273 | """Return list of lines for an unknown cell. | |||
|
274 | ||||
|
275 | Parameters | |||
|
276 | ---------- | |||
|
277 | data : str | |||
|
278 | The content of the unknown data as a single string. | |||
|
279 | """ | |||
|
280 | raise NotImplementedError | |||
|
281 | ||||
142 |
|
282 | |||
143 | class ConverterRST(Converter): |
|
283 | class ConverterRST(Converter): | |
144 | extension = 'rst' |
|
284 | extension = 'rst' | |
145 | figures_counter = 0 |
|
|||
146 | heading_level = {1: '=', 2: '-', 3: '`', 4: '\'', 5: '.', 6: '~'} |
|
285 | heading_level = {1: '=', 2: '-', 3: '`', 4: '\'', 5: '.', 6: '~'} | |
147 |
|
286 | |||
148 | @DocInherit |
|
287 | @DocInherit | |
@@ -169,8 +308,11 b' class ConverterRST(Converter):' | |||||
169 | return [cell.source] |
|
308 | return [cell.source] | |
170 |
|
309 | |||
171 | @DocInherit |
|
310 | @DocInherit | |
172 |
def render_ |
|
311 | def render_raw(self, cell): | |
173 | return [cell.source] |
|
312 | if self.raw_as_verbatim: | |
|
313 | return ['::', '', indent(cell.source), ''] | |||
|
314 | else: | |||
|
315 | return [cell.source] | |||
174 |
|
316 | |||
175 | @DocInherit |
|
317 | @DocInherit | |
176 | def render_pyout(self, output): |
|
318 | def render_pyout(self, output): | |
@@ -186,25 +328,15 b' class ConverterRST(Converter):' | |||||
186 | return lines |
|
328 | return lines | |
187 |
|
329 | |||
188 | @DocInherit |
|
330 | @DocInherit | |
189 |
def render_ |
|
331 | def render_pyerr(self, output): | |
190 | lines = [] |
|
332 | # Note: a traceback is a *list* of frames. | |
191 |
|
333 | return ['::', '', indent(remove_ansi('\n'.join(output.traceback))), ''] | ||
192 | if 'png' in output: |
|
|||
193 | # XXX: make the figures notebooks specific (i.e. self.infile) so |
|
|||
194 | # that multiple notebook conversions don't clobber each other's |
|
|||
195 | # figures |
|
|||
196 | infile = 'nb_figure_%s.png' % self.figures_counter |
|
|||
197 | fullname = os.path.join(self.dirpath, infile) |
|
|||
198 | with open(fullname, 'w') as f: |
|
|||
199 | f.write(output.png.decode('base64')) |
|
|||
200 |
|
||||
201 | self.figures_counter += 1 |
|
|||
202 | lines.append('.. image:: %s' % infile) |
|
|||
203 | lines.append('') |
|
|||
204 |
|
||||
205 | return lines |
|
|||
206 |
|
334 | |||
207 | @DocInherit |
|
335 | @DocInherit | |
|
336 | def _img_lines(self, img_file): | |||
|
337 | return ['.. image:: %s' % img_file, ''] | |||
|
338 | ||||
|
339 | @DocInherit | |||
208 | def render_stream(self, output): |
|
340 | def render_stream(self, output): | |
209 | lines = [] |
|
341 | lines = [] | |
210 |
|
342 | |||
@@ -213,9 +345,17 b' class ConverterRST(Converter):' | |||||
213 |
|
345 | |||
214 | return lines |
|
346 | return lines | |
215 |
|
347 | |||
|
348 | @DocInherit | |||
|
349 | def _unknown_lines(self, data): | |||
|
350 | return rst_directive('.. warning:: Unknown cell') + [data] | |||
|
351 | ||||
|
352 | ||||
216 | class ConverterQuickHTML(Converter): |
|
353 | class ConverterQuickHTML(Converter): | |
217 | extension = 'html' |
|
354 | extension = 'html' | |
218 | figures_counter = 0 |
|
355 | ||
|
356 | def in_tag(self, tag, src): | |||
|
357 | """Return a list of elements bracketed by the given tag""" | |||
|
358 | return ['<%s>' % tag, src, '</%s>' % tag] | |||
219 |
|
359 | |||
220 | def optional_header(self): |
|
360 | def optional_header(self): | |
221 | # XXX: inject the IPython standard CSS into here |
|
361 | # XXX: inject the IPython standard CSS into here | |
@@ -259,54 +399,226 b' class ConverterQuickHTML(Converter):' | |||||
259 |
|
399 | |||
260 | @DocInherit |
|
400 | @DocInherit | |
261 | def render_markdown(self, cell): |
|
401 | def render_markdown(self, cell): | |
262 |
return |
|
402 | return self.in_tag('pre', cell.source) | |
263 |
|
403 | |||
264 | @DocInherit |
|
404 | @DocInherit | |
265 |
def render_ |
|
405 | def render_raw(self, cell): | |
266 | return ["<pre>"+cell.source+"</pre>"] |
|
406 | if self.raw_as_verbatim: | |
|
407 | return self.in_tag('pre', cell.source) | |||
|
408 | else: | |||
|
409 | return [cell.source] | |||
267 |
|
410 | |||
268 | @DocInherit |
|
411 | @DocInherit | |
269 | def render_pyout(self, output): |
|
412 | def render_pyout(self, output): | |
270 |
lines = ['<tr><td><tt>Out[<b>%s</b>]:</tt></td></tr>' % |
|
413 | lines = ['<tr><td><tt>Out[<b>%s</b>]:</tt></td></tr>' % | |
|
414 | output.prompt_number, '<td>'] | |||
271 |
|
415 | |||
272 | # output is a dictionary like object with type as a key |
|
416 | # output is a dictionary like object with type as a key | |
273 | if 'latex' in output: |
|
417 | for out_type in ('text', 'latex'): | |
274 | lines.append("<pre>") |
|
418 | if out_type in output: | |
275 |
lines.extend(indent(output |
|
419 | lines.extend(self.in_tag('pre', indent(output[out_type]))) | |
276 | lines.append("</pre>") |
|
420 | ||
|
421 | return lines | |||
|
422 | ||||
|
423 | @DocInherit | |||
|
424 | def render_pyerr(self, output): | |||
|
425 | # Note: a traceback is a *list* of frames. | |||
|
426 | return self.in_tag('pre', remove_ansi('\n'.join(output.traceback))) | |||
|
427 | ||||
|
428 | @DocInherit | |||
|
429 | def _img_lines(self, img_file): | |||
|
430 | return ['<img src="%s">' % img_file, ''] | |||
|
431 | ||||
|
432 | @DocInherit | |||
|
433 | def render_stream(self, output): | |||
|
434 | lines = [] | |||
277 |
|
435 | |||
278 | if 'text' in output: |
|
436 | if 'text' in output: | |
279 |
lines.append( |
|
437 | lines.append(output.text) | |
280 | lines.extend(indent(output.text)) |
|
|||
281 | lines.append("</pre>") |
|
|||
282 |
|
438 | |||
283 | return lines |
|
439 | return lines | |
284 |
|
440 | |||
285 | @DocInherit |
|
441 | @DocInherit | |
286 | def render_display_data(self, output): |
|
442 | def _unknown_lines(self, data): | |
287 | lines = [] |
|
443 | return ['<h2>Warning:: Unknown cell</h2>'] + self.in_tag('pre', data) | |
|
444 | ||||
288 |
|
445 | |||
289 | if 'png' in output: |
|
446 | class ConverterLaTeX(Converter): | |
290 | infile = 'nb_figure_%s.png' % self.figures_counter |
|
447 | """Converts a notebook to a .tex file suitable for pdflatex. | |
291 | fullname = os.path.join(self.dirpath, infile) |
|
|||
292 | with open(fullname, 'w') as f: |
|
|||
293 | f.write(output.png.decode('base64')) |
|
|||
294 |
|
|
448 | ||
295 | self.figures_counter += 1 |
|
449 | Note: this converter *needs*: | |
296 | lines.append('<img src="%s">' % infile) |
|
450 | ||
297 | lines.append('') |
|
451 | - `pandoc`: for all conversion of markdown cells. If your notebook only | |
|
452 | has Raw cells, pandoc will not be needed. | |||
|
453 | ||||
|
454 | - `inkscape`: if your notebook has SVG figures. These need to be | |||
|
455 | converted to PDF before inclusion in the TeX file, as LaTeX doesn't | |||
|
456 | understand SVG natively. | |||
|
457 | ||||
|
458 | You will in general obtain much better final PDF results if you configure | |||
|
459 | the matplotlib backend to create SVG output with | |||
|
460 | ||||
|
461 | %config InlineBackend.figure_format = 'svg' | |||
|
462 | ||||
|
463 | (or set the equivalent flag at startup or in your configuration profile). | |||
|
464 | """ | |||
|
465 | extension = 'tex' | |||
|
466 | documentclass = 'article' | |||
|
467 | documentclass_options = '11pt,english' | |||
|
468 | heading_map = {1: r'\section', | |||
|
469 | 2: r'\subsection', | |||
|
470 | 3: r'\subsubsection', | |||
|
471 | 4: r'\paragraph', | |||
|
472 | 5: r'\subparagraph', | |||
|
473 | 6: r'\subparagraph'} | |||
|
474 | ||||
|
475 | def in_env(self, environment, lines): | |||
|
476 | """Return list of environment lines for input lines | |||
|
477 | ||||
|
478 | Parameters | |||
|
479 | ---------- | |||
|
480 | env : string | |||
|
481 | Name of the environment to bracket with begin/end. | |||
|
482 | ||||
|
483 | lines: """ | |||
|
484 | out = [r'\begin{%s}' % environment] | |||
|
485 | if isinstance(lines, basestring): | |||
|
486 | out.append(lines) | |||
|
487 | else: # list | |||
|
488 | out.extend(lines) | |||
|
489 | out.append(r'\end{%s}' % environment) | |||
|
490 | return out | |||
|
491 | ||||
|
492 | def convert(self): | |||
|
493 | # The main body is done by the logic in the parent class, and that's | |||
|
494 | # all we need if preamble support has been turned off. | |||
|
495 | body = super(ConverterLaTeX, self).convert() | |||
|
496 | if not self.with_preamble: | |||
|
497 | return body | |||
|
498 | # But if preamble is on, then we need to construct a proper, standalone | |||
|
499 | # tex file. | |||
|
500 | ||||
|
501 | # Tag the document at the top and set latex class | |||
|
502 | final = [ r'%% This file was auto-generated by IPython, do NOT edit', | |||
|
503 | r'%% Conversion from the original notebook file:', | |||
|
504 | r'%% {0}'.format(self.infile), | |||
|
505 | r'%%', | |||
|
506 | r'\documentclass[%s]{%s}' % (self.documentclass_options, | |||
|
507 | self.documentclass), | |||
|
508 | '', | |||
|
509 | ] | |||
|
510 | # Load our own preamble, which is stored next to the main file. We | |||
|
511 | # need to be careful in case the script entry point is a symlink | |||
|
512 | myfile = __file__ if not os.path.islink(__file__) else \ | |||
|
513 | os.readlink(__file__) | |||
|
514 | with open(os.path.join(os.path.dirname(myfile), 'preamble.tex')) as f: | |||
|
515 | final.append(f.read()) | |||
|
516 | ||||
|
517 | # Load any additional user-supplied preamble | |||
|
518 | if self.user_preamble: | |||
|
519 | final.extend(['', '%% Adding user preamble from file:', | |||
|
520 | '%% {0}'.format(self.user_preamble), '']) | |||
|
521 | with open(self.user_preamble) as f: | |||
|
522 | final.append(f.read()) | |||
|
523 | ||||
|
524 | # Include document body | |||
|
525 | final.extend([ r'\begin{document}', '', | |||
|
526 | body, | |||
|
527 | r'\end{document}', '']) | |||
|
528 | # Retun value must be a string | |||
|
529 | return '\n'.join(final) | |||
|
530 | ||||
|
531 | @DocInherit | |||
|
532 | def render_heading(self, cell): | |||
|
533 | marker = self.heading_map[cell.level] | |||
|
534 | return ['%s{%s}' % (marker, cell.source) ] | |||
|
535 | ||||
|
536 | @DocInherit | |||
|
537 | def render_code(self, cell): | |||
|
538 | if not cell.input: | |||
|
539 | return [] | |||
|
540 | ||||
|
541 | # Cell codes first carry input code, we use lstlisting for that | |||
|
542 | lines = [r'\begin{codecell}'] | |||
|
543 | ||||
|
544 | lines.extend(self.in_env('codeinput', | |||
|
545 | self.in_env('lstlisting', cell.input))) | |||
|
546 | ||||
|
547 | outlines = [] | |||
|
548 | for output in cell.outputs: | |||
|
549 | conv_fn = self.dispatch(output.output_type) | |||
|
550 | outlines.extend(conv_fn(output)) | |||
|
551 | ||||
|
552 | # And then output of many possible types; use a frame for all of it. | |||
|
553 | if outlines: | |||
|
554 | lines.extend(self.in_env('codeoutput', outlines)) | |||
|
555 | ||||
|
556 | lines.append(r'\end{codecell}') | |||
298 |
|
557 | |||
299 | return lines |
|
558 | return lines | |
300 |
|
559 | |||
|
560 | ||||
|
561 | @DocInherit | |||
|
562 | def _img_lines(self, img_file): | |||
|
563 | return self.in_env('center', | |||
|
564 | [r'\includegraphics[width=3in]{%s}' % img_file, r'\par']) | |||
|
565 | ||||
|
566 | def _svg_lines(self, img_file): | |||
|
567 | base_file = os.path.splitext(img_file)[0] | |||
|
568 | pdf_file = base_file + '.pdf' | |||
|
569 | subprocess.check_call([ inkscape, '--export-pdf=%s' % pdf_file, | |||
|
570 | img_file]) | |||
|
571 | return self._img_lines(pdf_file) | |||
|
572 | ||||
301 | @DocInherit |
|
573 | @DocInherit | |
302 | def render_stream(self, output): |
|
574 | def render_stream(self, output): | |
303 | lines = [] |
|
575 | lines = [] | |
304 |
|
576 | |||
305 | if 'text' in output: |
|
577 | if 'text' in output: | |
306 |
lines. |
|
578 | lines.extend(self.in_env('verbatim', output.text.strip())) | |
|
579 | ||||
|
580 | return lines | |||
|
581 | ||||
|
582 | @DocInherit | |||
|
583 | def render_markdown(self, cell): | |||
|
584 | return [markdown2latex(cell.source)] | |||
|
585 | ||||
|
586 | @DocInherit | |||
|
587 | def render_pyout(self, output): | |||
|
588 | lines = [] | |||
|
589 | ||||
|
590 | # output is a dictionary like object with type as a key | |||
|
591 | if 'latex' in output: | |||
|
592 | lines.extend(output.latex) | |||
|
593 | ||||
|
594 | if 'text' in output: | |||
|
595 | lines.extend(self.in_env('verbatim', output.text)) | |||
307 |
|
596 | |||
308 | return lines |
|
597 | return lines | |
309 |
|
598 | |||
|
599 | @DocInherit | |||
|
600 | def render_pyerr(self, output): | |||
|
601 | # Note: a traceback is a *list* of frames. | |||
|
602 | return self.in_env('traceback', | |||
|
603 | self.in_env('verbatim', | |||
|
604 | remove_ansi('\n'.join(output.traceback)))) | |||
|
605 | ||||
|
606 | @DocInherit | |||
|
607 | def render_raw(self, cell): | |||
|
608 | if self.raw_as_verbatim: | |||
|
609 | return self.in_env('verbatim', cell.source) | |||
|
610 | else: | |||
|
611 | return [cell.source] | |||
|
612 | ||||
|
613 | @DocInherit | |||
|
614 | def _unknown_lines(self, data): | |||
|
615 | return [r'{\vspace{5mm}\bf WARNING:: unknown cell:}'] + \ | |||
|
616 | self.in_env('verbatim', data) | |||
|
617 | ||||
|
618 | #----------------------------------------------------------------------------- | |||
|
619 | # Standalone conversion functions | |||
|
620 | #----------------------------------------------------------------------------- | |||
|
621 | ||||
310 | def rst2simplehtml(infile): |
|
622 | def rst2simplehtml(infile): | |
311 | """Convert a rst file to simplified html suitable for blogger. |
|
623 | """Convert a rst file to simplified html suitable for blogger. | |
312 |
|
624 | |||
@@ -355,7 +667,7 b' def rst2simplehtml(infile):' | |||||
355 |
|
667 | |||
356 | return newfname |
|
668 | return newfname | |
357 |
|
669 | |||
358 | known_formats = "rst (default), html, quick-html" |
|
670 | known_formats = "rst (default), html, quick-html, latex" | |
359 |
|
671 | |||
360 | def main(infile, format='rst'): |
|
672 | def main(infile, format='rst'): | |
361 | """Convert a notebook to html in one step""" |
|
673 | """Convert a notebook to html in one step""" | |
@@ -373,11 +685,16 b" def main(infile, format='rst'):" | |||||
373 | elif format == 'quick-html': |
|
685 | elif format == 'quick-html': | |
374 | converter = ConverterQuickHTML(infile) |
|
686 | converter = ConverterQuickHTML(infile) | |
375 | rstfname = converter.render() |
|
687 | rstfname = converter.render() | |
|
688 | elif format == 'latex': | |||
|
689 | converter = ConverterLaTeX(infile) | |||
|
690 | latexfname = converter.render() | |||
376 | else: |
|
691 | else: | |
377 | raise SystemExit("Unknown format '%s', " % format + |
|
692 | raise SystemExit("Unknown format '%s', " % format + | |
378 | "known formats are: " + known_formats) |
|
693 | "known formats are: " + known_formats) | |
379 |
|
694 | |||
380 |
|
695 | #----------------------------------------------------------------------------- | ||
|
696 | # Script main | |||
|
697 | #----------------------------------------------------------------------------- | |||
381 |
|
698 | |||
382 | if __name__ == '__main__': |
|
699 | if __name__ == '__main__': | |
383 | parser = argparse.ArgumentParser(description=__doc__, |
|
700 | parser = argparse.ArgumentParser(description=__doc__, |
@@ -51,15 +51,12 b'' | |||||
51 | { |
|
51 | { | |
52 | "cell_type": "markdown", |
|
52 | "cell_type": "markdown", | |
53 | "source": [ |
|
53 | "source": [ | |
54 | "A section heading", |
|
|||
55 | "=================", |
|
|||
56 | "", |
|
|||
57 | "A bit of text, with *important things*:", |
|
54 | "A bit of text, with *important things*:", | |
58 | "", |
|
55 | "", | |
59 | "* and", |
|
56 | "* and", | |
60 | "* more", |
|
57 | "* more that **are boldface**, as well as `verbatim`.", | |
61 | "", |
|
58 | "", | |
62 |
"Using |
|
59 | "Using markdown hyperlinks for [ipython](http://ipython.org)." | |
63 | ] |
|
60 | ] | |
64 | }, |
|
61 | }, | |
65 | { |
|
62 | { | |
@@ -67,21 +64,21 b'' | |||||
67 | "collapsed": false, |
|
64 | "collapsed": false, | |
68 | "input": [ |
|
65 | "input": [ | |
69 | "f = figure()", |
|
66 | "f = figure()", | |
70 | "plot([1])", |
|
67 | "plot([1,2,3])", | |
71 | "display(f)" |
|
68 | "display(f)" | |
72 | ], |
|
69 | ], | |
73 | "language": "python", |
|
70 | "language": "python", | |
74 | "outputs": [ |
|
71 | "outputs": [ | |
75 | { |
|
72 | { | |
76 | "output_type": "display_data", |
|
73 | "output_type": "display_data", | |
77 | "png": "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\n", |
|
74 | "png": "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\n", | |
78 | "text": [ |
|
75 | "text": [ | |
79 |
"<matplotlib.figure.Figure at 0x |
|
76 | "<matplotlib.figure.Figure at 0x981bccc>" | |
80 | ] |
|
77 | ] | |
81 | }, |
|
78 | }, | |
82 | { |
|
79 | { | |
83 | "output_type": "display_data", |
|
80 | "output_type": "display_data", | |
84 | "png": "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\n" |
|
81 | "png": "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\n" | |
85 | } |
|
82 | } | |
86 | ], |
|
83 | ], | |
87 | "prompt_number": 1 |
|
84 | "prompt_number": 1 | |
@@ -128,7 +125,8 b'' | |||||
128 | "output_type": "stream", |
|
125 | "output_type": "stream", | |
129 | "stream": "stdout", |
|
126 | "stream": "stdout", | |
130 | "text": [ |
|
127 | "text": [ | |
131 | "hello world" |
|
128 | "hello world", | |
|
129 | "" | |||
132 | ] |
|
130 | ] | |
133 | } |
|
131 | } | |
134 | ], |
|
132 | ], | |
@@ -141,17 +139,70 b'' | |||||
141 | ] |
|
139 | ] | |
142 | }, |
|
140 | }, | |
143 | { |
|
141 | { | |
144 |
"cell_type": " |
|
142 | "cell_type": "raw", | |
145 | "source": [ |
|
143 | "source": [ | |
146 | "plain text" |
|
144 | "plain text" | |
147 | ] |
|
145 | ] | |
148 | }, |
|
146 | }, | |
149 | { |
|
147 | { | |
150 | "cell_type": "code", |
|
148 | "cell_type": "code", | |
151 |
"collapsed": |
|
149 | "collapsed": false, | |
152 |
"input": [ |
|
150 | "input": [ | |
|
151 | "import sys", | |||
|
152 | "m = 'A message'", | |||
|
153 | "print m, 'to stdout'", | |||
|
154 | "print >> sys.stderr, m, 'to stderr'", | |||
|
155 | "m" | |||
|
156 | ], | |||
153 | "language": "python", |
|
157 | "language": "python", | |
154 |
"outputs": [ |
|
158 | "outputs": [ | |
|
159 | { | |||
|
160 | "output_type": "stream", | |||
|
161 | "stream": "stdout", | |||
|
162 | "text": [ | |||
|
163 | "A message to stdout", | |||
|
164 | "" | |||
|
165 | ] | |||
|
166 | }, | |||
|
167 | { | |||
|
168 | "output_type": "stream", | |||
|
169 | "stream": "stderr", | |||
|
170 | "text": [ | |||
|
171 | "A message to stderr", | |||
|
172 | "" | |||
|
173 | ] | |||
|
174 | }, | |||
|
175 | { | |||
|
176 | "output_type": "pyout", | |||
|
177 | "prompt_number": 5, | |||
|
178 | "text": [ | |||
|
179 | "'A message'" | |||
|
180 | ] | |||
|
181 | } | |||
|
182 | ], | |||
|
183 | "prompt_number": 5 | |||
|
184 | }, | |||
|
185 | { | |||
|
186 | "cell_type": "code", | |||
|
187 | "collapsed": false, | |||
|
188 | "input": [ | |||
|
189 | "# a traceback", | |||
|
190 | "1/0" | |||
|
191 | ], | |||
|
192 | "language": "python", | |||
|
193 | "outputs": [ | |||
|
194 | { | |||
|
195 | "ename": "ZeroDivisionError", | |||
|
196 | "evalue": "integer division or modulo by zero", | |||
|
197 | "output_type": "pyerr", | |||
|
198 | "traceback": [ | |||
|
199 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", | |||
|
200 | "\u001b[1;32m/home/fperez/ipython/nbconvert/tests/<ipython-input-6-03412a6702b7>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# a traceback\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;36m1\u001b[0m\u001b[1;33m/\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", | |||
|
201 | "\u001b[1;31mZeroDivisionError\u001b[0m: integer division or modulo by zero" | |||
|
202 | ] | |||
|
203 | } | |||
|
204 | ], | |||
|
205 | "prompt_number": 6 | |||
155 | } |
|
206 | } | |
156 | ] |
|
207 | ] | |
157 | } |
|
208 | } |
General Comments 0
You need to be logged in to leave comments.
Login now