##// END OF EJS Templates
More descriptive comment headers.
David Warde-Farley -
Show More
@@ -1,46 +1,46 b''
1 """Notebook export in Blogger-aware HTML.
1 """Notebook export in Blogger-aware HTML.
2
2
3 This file contains `ConverterBloggerHTML`, a subclass of `ConverterHTML` that
3 This file contains `ConverterBloggerHTML`, a subclass of `ConverterHTML` that
4 provides output suitable for easy pasting into a blog hosted on the Blogger
4 provides output suitable for easy pasting into a blog hosted on the Blogger
5 platform. See the class docstring for more information.
5 platform. See the class docstring for more information.
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2012, the IPython Development Team.
8 # Copyright (c) 2012, the IPython Development Team.
9 #
9 #
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11 #
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 # Stdlib imports
19 # Stdlib imports
20 import io
20 import io
21
21
22 # Our own imports
22 # Our own imports
23 from converters.html import ConverterHTML
23 from converters.html import ConverterHTML
24
24
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Classes and functions
27 # Classes declarations
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 class ConverterBloggerHTML(ConverterHTML):
30 class ConverterBloggerHTML(ConverterHTML):
31 """Convert a notebook to html suitable for easy pasting into Blogger.
31 """Convert a notebook to html suitable for easy pasting into Blogger.
32
32
33 It generates an html file that has *only* the pure HTML contents, and a
33 It generates an html file that has *only* the pure HTML contents, and a
34 separate file with `_header` appended to the name with all header contents.
34 separate file with `_header` appended to the name with all header contents.
35 Typically, the header file only needs to be used once when setting up a
35 Typically, the header file only needs to be used once when setting up a
36 blog, as the CSS for all posts is stored in a single location in Blogger.
36 blog, as the CSS for all posts is stored in a single location in Blogger.
37 """
37 """
38
38
39 def optional_header(self):
39 def optional_header(self):
40 with io.open(self.outbase + '_header.html', 'w',
40 with io.open(self.outbase + '_header.html', 'w',
41 encoding=self.default_encoding) as f:
41 encoding=self.default_encoding) as f:
42 f.write('\n'.join(self.header_body()))
42 f.write('\n'.join(self.header_body()))
43 return []
43 return []
44
44
45 def optional_footer(self):
45 def optional_footer(self):
46 return []
46 return []
@@ -1,213 +1,213 b''
1 """Implements conversion to ordinary HTML output.
1 """Implements conversion to ordinary HTML output.
2
2
3 This file implements a class that handles rendering IPython notebooks as
3 This file implements a class that handles rendering IPython notebooks as
4 HTML, suitable for posting to the web.
4 HTML, suitable for posting to the web.
5
5
6 Converters for more specific HTML generation needs (suitable for posting to
6 Converters for more specific HTML generation needs (suitable for posting to
7 a particular web service) can usefully subclass `ConverterHTML` and override
7 a particular web service) can usefully subclass `ConverterHTML` and override
8 certain methods. For output tuned to the Blogger blogging platform, see the
8 certain methods. For output tuned to the Blogger blogging platform, see the
9 `ConverterBloggerHTML` class.
9 `ConverterBloggerHTML` class.
10 """
10 """
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (c) 2012, the IPython Development Team.
12 # Copyright (c) 2012, the IPython Development Team.
13 #
13 #
14 # Distributed under the terms of the Modified BSD License.
14 # Distributed under the terms of the Modified BSD License.
15 #
15 #
16 # The full license is in the file COPYING.txt, distributed with this software.
16 # The full license is in the file COPYING.txt, distributed with this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 from __future__ import absolute_import
19 from __future__ import absolute_import
20
20
21 # Stdlib imports
21 # Stdlib imports
22 import io
22 import io
23 import os
23 import os
24
24
25 # Third-party imports
25 # Third-party imports
26 from markdown import markdown
26 from markdown import markdown
27
27
28 # IPython imports
28 # IPython imports
29 from IPython.utils import path
29 from IPython.utils import path
30
30
31 # Our own imports
31 # Our own imports
32 from converters.base import Converter
32 from converters.base import Converter
33 from converters.utils import text_cell, output_container
33 from converters.utils import text_cell, output_container
34 from converters.utils import highlight, coalesce_streams, ansi2html
34 from converters.utils import highlight, coalesce_streams, ansi2html
35
35
36
36
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 # Classes and functions
38 # Class declarations
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40 class ConverterHTML(Converter):
40 class ConverterHTML(Converter):
41 extension = 'html'
41 extension = 'html'
42 blank_symbol = ' '
42 blank_symbol = ' '
43
43
44 def in_tag(self, tag, src, attrs=None):
44 def in_tag(self, tag, src, attrs=None):
45 """Return a list of elements bracketed by the given tag"""
45 """Return a list of elements bracketed by the given tag"""
46 attr_s = '' if attrs is None else \
46 attr_s = '' if attrs is None else \
47 ' '.join("%s=%s" % (attr, value)
47 ' '.join("%s=%s" % (attr, value)
48 for attr, value in attrs.iteritems())
48 for attr, value in attrs.iteritems())
49 return ['<%s %s>' % (tag, attr_s), src, '</%s>' % tag]
49 return ['<%s %s>' % (tag, attr_s), src, '</%s>' % tag]
50
50
51 def _ansi_colored(self, text):
51 def _ansi_colored(self, text):
52 return ['<pre>%s</pre>' % ansi2html(text)]
52 return ['<pre>%s</pre>' % ansi2html(text)]
53
53
54 def _stylesheet(self, fname):
54 def _stylesheet(self, fname):
55 with io.open(fname, encoding='utf-8') as f:
55 with io.open(fname, encoding='utf-8') as f:
56 s = f.read()
56 s = f.read()
57 return self.in_tag('style', s, dict(type='"text/css"'))
57 return self.in_tag('style', s, dict(type='"text/css"'))
58
58
59 def _out_prompt(self, output):
59 def _out_prompt(self, output):
60 if output.output_type == 'pyout':
60 if output.output_type == 'pyout':
61 content = 'Out[%s]:' % self._get_prompt_number(output)
61 content = 'Out[%s]:' % self._get_prompt_number(output)
62 else:
62 else:
63 content = ''
63 content = ''
64 return ['<div class="prompt output_prompt">%s</div>' % content]
64 return ['<div class="prompt output_prompt">%s</div>' % content]
65
65
66 def header_body(self):
66 def header_body(self):
67 """Return the body of the header as a list of strings."""
67 """Return the body of the header as a list of strings."""
68
68
69 from pygments.formatters import HtmlFormatter
69 from pygments.formatters import HtmlFormatter
70
70
71 header = []
71 header = []
72 static = os.path.join(path.get_ipython_package_dir(),
72 static = os.path.join(path.get_ipython_package_dir(),
73 'frontend', 'html', 'notebook', 'static',
73 'frontend', 'html', 'notebook', 'static',
74 )
74 )
75 here = os.path.split(os.path.realpath(__file__))[0]
75 here = os.path.split(os.path.realpath(__file__))[0]
76 css = os.path.join(static, 'css')
76 css = os.path.join(static, 'css')
77 for sheet in [
77 for sheet in [
78 # do we need jquery and prettify?
78 # do we need jquery and prettify?
79 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
79 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
80 # 'jquery-ui.min.css'),
80 # 'jquery-ui.min.css'),
81 # os.path.join(static, 'prettify', 'prettify.css'),
81 # os.path.join(static, 'prettify', 'prettify.css'),
82 os.path.join(css, 'boilerplate.css'),
82 os.path.join(css, 'boilerplate.css'),
83 os.path.join(css, 'fbm.css'),
83 os.path.join(css, 'fbm.css'),
84 os.path.join(css, 'notebook.css'),
84 os.path.join(css, 'notebook.css'),
85 os.path.join(css, 'renderedhtml.css'),
85 os.path.join(css, 'renderedhtml.css'),
86 # our overrides:
86 # our overrides:
87 os.path.join(here, '..', 'css', 'static_html.css'),
87 os.path.join(here, '..', 'css', 'static_html.css'),
88 ]:
88 ]:
89 header.extend(self._stylesheet(sheet))
89 header.extend(self._stylesheet(sheet))
90
90
91 # pygments css
91 # pygments css
92 pygments_css = HtmlFormatter().get_style_defs('.highlight')
92 pygments_css = HtmlFormatter().get_style_defs('.highlight')
93 header.extend(['<meta charset="UTF-8">'])
93 header.extend(['<meta charset="UTF-8">'])
94 header.extend(self.in_tag('style', pygments_css,
94 header.extend(self.in_tag('style', pygments_css,
95 dict(type='"text/css"')))
95 dict(type='"text/css"')))
96
96
97 # TODO: this should be allowed to use local mathjax:
97 # TODO: this should be allowed to use local mathjax:
98 header.extend(self.in_tag('script', '', {'type': '"text/javascript"',
98 header.extend(self.in_tag('script', '', {'type': '"text/javascript"',
99 'src': '"https://c328740.ssl.cf1.rackcdn.com/mathjax/'
99 'src': '"https://c328740.ssl.cf1.rackcdn.com/mathjax/'
100 'latest/MathJax.js?config=TeX-AMS_HTML"',
100 'latest/MathJax.js?config=TeX-AMS_HTML"',
101 }))
101 }))
102 with io.open(os.path.join(here, '..', 'js', 'initmathjax.js'),
102 with io.open(os.path.join(here, '..', 'js', 'initmathjax.js'),
103 encoding='utf-8') as f:
103 encoding='utf-8') as f:
104 header.extend(self.in_tag('script', f.read(),
104 header.extend(self.in_tag('script', f.read(),
105 {'type': '"text/javascript"'}))
105 {'type': '"text/javascript"'}))
106 return header
106 return header
107
107
108 def optional_header(self):
108 def optional_header(self):
109 return ['<html>', '<head>'] + self.header_body() + \
109 return ['<html>', '<head>'] + self.header_body() + \
110 ['</head>', '<body>']
110 ['</head>', '<body>']
111
111
112 def optional_footer(self):
112 def optional_footer(self):
113 return ['</body>', '</html>']
113 return ['</body>', '</html>']
114
114
115 @text_cell
115 @text_cell
116 def render_heading(self, cell):
116 def render_heading(self, cell):
117 marker = cell.level
117 marker = cell.level
118 return [u'<h{1}>\n {0}\n</h{1}>'.format(cell.source, marker)]
118 return [u'<h{1}>\n {0}\n</h{1}>'.format(cell.source, marker)]
119
119
120 def render_code(self, cell):
120 def render_code(self, cell):
121 if not cell.input:
121 if not cell.input:
122 return []
122 return []
123
123
124 lines = ['<div class="cell border-box-sizing code_cell vbox">']
124 lines = ['<div class="cell border-box-sizing code_cell vbox">']
125
125
126 lines.append('<div class="input hbox">')
126 lines.append('<div class="input hbox">')
127 n = self._get_prompt_number(cell)
127 n = self._get_prompt_number(cell)
128 lines.append(
128 lines.append(
129 '<div class="prompt input_prompt">In&nbsp;[%s]:</div>' % n
129 '<div class="prompt input_prompt">In&nbsp;[%s]:</div>' % n
130 )
130 )
131 lines.append('<div class="input_area box-flex1">')
131 lines.append('<div class="input_area box-flex1">')
132 lines.append(highlight(cell.input) if self.highlight_source
132 lines.append(highlight(cell.input) if self.highlight_source
133 else cell.input)
133 else cell.input)
134 lines.append('</div>') # input_area
134 lines.append('</div>') # input_area
135 lines.append('</div>') # input
135 lines.append('</div>') # input
136
136
137 if cell.outputs:
137 if cell.outputs:
138 lines.append('<div class="vbox output_wrapper">')
138 lines.append('<div class="vbox output_wrapper">')
139 lines.append('<div class="output vbox">')
139 lines.append('<div class="output vbox">')
140
140
141 for output in coalesce_streams(cell.outputs):
141 for output in coalesce_streams(cell.outputs):
142 conv_fn = self.dispatch(output.output_type)
142 conv_fn = self.dispatch(output.output_type)
143 lines.extend(conv_fn(output))
143 lines.extend(conv_fn(output))
144
144
145 lines.append('</div>') # output
145 lines.append('</div>') # output
146 lines.append('</div>') # output_wrapper
146 lines.append('</div>') # output_wrapper
147
147
148 lines.append('</div>') # cell
148 lines.append('</div>') # cell
149
149
150 return lines
150 return lines
151
151
152 @text_cell
152 @text_cell
153 def render_markdown(self, cell):
153 def render_markdown(self, cell):
154 return [markdown(cell.source)]
154 return [markdown(cell.source)]
155
155
156 def render_raw(self, cell):
156 def render_raw(self, cell):
157 if self.raw_as_verbatim:
157 if self.raw_as_verbatim:
158 return self.in_tag('pre', cell.source)
158 return self.in_tag('pre', cell.source)
159 else:
159 else:
160 return [cell.source]
160 return [cell.source]
161
161
162 @output_container
162 @output_container
163 def render_pyout(self, output):
163 def render_pyout(self, output):
164 for fmt in ['html', 'latex', 'png', 'jpeg', 'svg', 'text']:
164 for fmt in ['html', 'latex', 'png', 'jpeg', 'svg', 'text']:
165 if fmt in output:
165 if fmt in output:
166 conv_fn = self.dispatch_display_format(fmt)
166 conv_fn = self.dispatch_display_format(fmt)
167 return conv_fn(output)
167 return conv_fn(output)
168 return []
168 return []
169
169
170 render_display_data = render_pyout
170 render_display_data = render_pyout
171
171
172 @output_container
172 @output_container
173 def render_stream(self, output):
173 def render_stream(self, output):
174 return self._ansi_colored(output.text)
174 return self._ansi_colored(output.text)
175
175
176 @output_container
176 @output_container
177 def render_pyerr(self, output):
177 def render_pyerr(self, output):
178 # Note: a traceback is a *list* of frames.
178 # Note: a traceback is a *list* of frames.
179 # lines = []
179 # lines = []
180
180
181 # stb =
181 # stb =
182 return self._ansi_colored('\n'.join(output.traceback))
182 return self._ansi_colored('\n'.join(output.traceback))
183
183
184 def _img_lines(self, img_file):
184 def _img_lines(self, img_file):
185 return ['<img src="%s">' % img_file, '</img>']
185 return ['<img src="%s">' % img_file, '</img>']
186
186
187 def _unknown_lines(self, data):
187 def _unknown_lines(self, data):
188 return ['<h2>Warning:: Unknown cell</h2>'] + self.in_tag('pre', data)
188 return ['<h2>Warning:: Unknown cell</h2>'] + self.in_tag('pre', data)
189
189
190 def render_display_format_png(self, output):
190 def render_display_format_png(self, output):
191 return ['<img src="data:image/png;base64,%s"></img>' % output.png]
191 return ['<img src="data:image/png;base64,%s"></img>' % output.png]
192
192
193 def render_display_format_svg(self, output):
193 def render_display_format_svg(self, output):
194 return [output.svg]
194 return [output.svg]
195
195
196 def render_display_format_jpeg(self, output):
196 def render_display_format_jpeg(self, output):
197 return ['<img src="data:image/jpeg;base64,%s"></img>' % output.jpeg]
197 return ['<img src="data:image/jpeg;base64,%s"></img>' % output.jpeg]
198
198
199 def render_display_format_text(self, output):
199 def render_display_format_text(self, output):
200 return self._ansi_colored(output.text)
200 return self._ansi_colored(output.text)
201
201
202 def render_display_format_html(self, output):
202 def render_display_format_html(self, output):
203 return [output.html]
203 return [output.html]
204
204
205 def render_display_format_latex(self, output):
205 def render_display_format_latex(self, output):
206 return [output.latex]
206 return [output.latex]
207
207
208 def render_display_format_json(self, output):
208 def render_display_format_json(self, output):
209 # html ignores json
209 # html ignores json
210 return []
210 return []
211
211
212 def render_display_format_javascript(self, output):
212 def render_display_format_javascript(self, output):
213 return [output.javascript]
213 return [output.javascript]
@@ -1,228 +1,228 b''
1 """Notebook export to LaTeX.
1 """Notebook export to LaTeX.
2
2
3 This file implements a converter class for rendering IPython notebooks as
3 This file implements a converter class for rendering IPython notebooks as
4 LaTeX, suitable for rendering by pdflatex.
4 LaTeX, suitable for rendering by pdflatex.
5 """
5 """
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2012, the IPython Development Team.
7 # Copyright (c) 2012, the IPython Development Team.
8 #
8 #
9 # Distributed under the terms of the Modified BSD License.
9 # Distributed under the terms of the Modified BSD License.
10 #
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # Stdlib imports
18 # Stdlib imports
19 import os
19 import os
20 import subprocess
20 import subprocess
21 import sys
21 import sys
22
22
23 # Our own imports
23 # Our own imports
24 from converters.base import Converter
24 from converters.base import Converter
25 from converters.utils import markdown2latex, remove_ansi
25 from converters.utils import markdown2latex, remove_ansi
26
26
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Globals and constants
29 # Globals and constants
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 # XXX: This is a hack that needs to be addressed in a more principled fashion.
32 # XXX: This is a hack that needs to be addressed in a more principled fashion.
33 inkscape = 'inkscape'
33 inkscape = 'inkscape'
34 if sys.platform == 'darwin':
34 if sys.platform == 'darwin':
35 inkscape = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape'
35 inkscape = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape'
36 if not os.path.exists(inkscape):
36 if not os.path.exists(inkscape):
37 inkscape = None
37 inkscape = None
38
38
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Classes and functions
41 # Class declarations
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44 class ConverterLaTeX(Converter):
44 class ConverterLaTeX(Converter):
45 """Converts a notebook to a .tex file suitable for pdflatex.
45 """Converts a notebook to a .tex file suitable for pdflatex.
46
46
47 Note: this converter *needs*:
47 Note: this converter *needs*:
48
48
49 - `pandoc`: for all conversion of markdown cells. If your notebook only
49 - `pandoc`: for all conversion of markdown cells. If your notebook only
50 has Raw cells, pandoc will not be needed.
50 has Raw cells, pandoc will not be needed.
51
51
52 - `inkscape`: if your notebook has SVG figures. These need to be
52 - `inkscape`: if your notebook has SVG figures. These need to be
53 converted to PDF before inclusion in the TeX file, as LaTeX doesn't
53 converted to PDF before inclusion in the TeX file, as LaTeX doesn't
54 understand SVG natively.
54 understand SVG natively.
55
55
56 You will in general obtain much better final PDF results if you configure
56 You will in general obtain much better final PDF results if you configure
57 the matplotlib backend to create SVG output with
57 the matplotlib backend to create SVG output with
58
58
59 %config InlineBackend.figure_format = 'svg'
59 %config InlineBackend.figure_format = 'svg'
60
60
61 (or set the equivalent flag at startup or in your configuration profile).
61 (or set the equivalent flag at startup or in your configuration profile).
62 """
62 """
63 inkscape = inkscape
63 inkscape = inkscape
64 extension = 'tex'
64 extension = 'tex'
65 documentclass = 'article'
65 documentclass = 'article'
66 documentclass_options = '11pt,english'
66 documentclass_options = '11pt,english'
67 heading_map = {1: r'\section',
67 heading_map = {1: r'\section',
68 2: r'\subsection',
68 2: r'\subsection',
69 3: r'\subsubsection',
69 3: r'\subsubsection',
70 4: r'\paragraph',
70 4: r'\paragraph',
71 5: r'\subparagraph',
71 5: r'\subparagraph',
72 6: r'\subparagraph'}
72 6: r'\subparagraph'}
73 user_preamble = None
73 user_preamble = None
74 exclude_cells = []
74 exclude_cells = []
75
75
76 def in_env(self, environment, lines):
76 def in_env(self, environment, lines):
77 """Return list of environment lines for input lines
77 """Return list of environment lines for input lines
78
78
79 Parameters
79 Parameters
80 ----------
80 ----------
81 env : string
81 env : string
82 Name of the environment to bracket with begin/end.
82 Name of the environment to bracket with begin/end.
83
83
84 lines: """
84 lines: """
85 out = [ur'\begin{%s}' % environment]
85 out = [ur'\begin{%s}' % environment]
86 if isinstance(lines, basestring):
86 if isinstance(lines, basestring):
87 out.append(lines)
87 out.append(lines)
88 else: # list
88 else: # list
89 out.extend(lines)
89 out.extend(lines)
90 out.append(ur'\end{%s}' % environment)
90 out.append(ur'\end{%s}' % environment)
91 return out
91 return out
92
92
93 def convert(self, *args, **kwargs):
93 def convert(self, *args, **kwargs):
94 # The main body is done by the logic in the parent class, and that's
94 # The main body is done by the logic in the parent class, and that's
95 # all we need if preamble support has been turned off.
95 # all we need if preamble support has been turned off.
96 body = super(ConverterLaTeX, self).convert(*args, **kwargs)
96 body = super(ConverterLaTeX, self).convert(*args, **kwargs)
97 if not self.with_preamble:
97 if not self.with_preamble:
98 return body
98 return body
99 # But if preamble is on, then we need to construct a proper, standalone
99 # But if preamble is on, then we need to construct a proper, standalone
100 # tex file.
100 # tex file.
101
101
102 # Tag the document at the top and set latex class
102 # Tag the document at the top and set latex class
103 final = [r'%% This file was auto-generated by IPython, do NOT edit',
103 final = [r'%% This file was auto-generated by IPython, do NOT edit',
104 r'%% Conversion from the original notebook file:',
104 r'%% Conversion from the original notebook file:',
105 r'%% {0}'.format(self.infile),
105 r'%% {0}'.format(self.infile),
106 r'%%',
106 r'%%',
107 r'\documentclass[%s]{%s}' % (self.documentclass_options,
107 r'\documentclass[%s]{%s}' % (self.documentclass_options,
108 self.documentclass),
108 self.documentclass),
109 '',
109 '',
110 ]
110 ]
111 # Load our own preamble, which is stored next to the main file. We
111 # Load our own preamble, which is stored next to the main file. We
112 # need to be careful in case the script entry point is a symlink
112 # need to be careful in case the script entry point is a symlink
113 myfile = os.path.realpath(__file__)
113 myfile = os.path.realpath(__file__)
114 preamble = '../preamble.tex'
114 preamble = '../preamble.tex'
115 with open(os.path.join(os.path.dirname(myfile), preamble)) as f:
115 with open(os.path.join(os.path.dirname(myfile), preamble)) as f:
116 final.append(f.read())
116 final.append(f.read())
117
117
118 # Load any additional user-supplied preamble
118 # Load any additional user-supplied preamble
119 if self.user_preamble:
119 if self.user_preamble:
120 final.extend(['', '%% Adding user preamble from file:',
120 final.extend(['', '%% Adding user preamble from file:',
121 '%% {0}'.format(self.user_preamble), ''])
121 '%% {0}'.format(self.user_preamble), ''])
122 with open(self.user_preamble) as f:
122 with open(self.user_preamble) as f:
123 final.append(f.read())
123 final.append(f.read())
124
124
125 # Include document body
125 # Include document body
126 final.extend([r'\begin{document}', '',
126 final.extend([r'\begin{document}', '',
127 body,
127 body,
128 r'\end{document}', ''])
128 r'\end{document}', ''])
129 # Retun value must be a string
129 # Retun value must be a string
130 return '\n'.join(final)
130 return '\n'.join(final)
131
131
132 def render_heading(self, cell):
132 def render_heading(self, cell):
133 marker = self.heading_map[cell.level]
133 marker = self.heading_map[cell.level]
134 return ['%s{%s}' % (marker, cell.source)]
134 return ['%s{%s}' % (marker, cell.source)]
135
135
136 def render_code(self, cell):
136 def render_code(self, cell):
137 if not cell.input:
137 if not cell.input:
138 return []
138 return []
139
139
140 # Cell codes first carry input code, we use lstlisting for that
140 # Cell codes first carry input code, we use lstlisting for that
141 lines = [ur'\begin{codecell}']
141 lines = [ur'\begin{codecell}']
142
142
143 if 'source' not in self.exclude_cells:
143 if 'source' not in self.exclude_cells:
144 lines.extend(self.in_env('codeinput',
144 lines.extend(self.in_env('codeinput',
145 self.in_env('lstlisting', cell.input)))
145 self.in_env('lstlisting', cell.input)))
146 else:
146 else:
147 # Empty output is still needed for LaTeX formatting
147 # Empty output is still needed for LaTeX formatting
148 lines.extend(self.in_env('codeinput', ''))
148 lines.extend(self.in_env('codeinput', ''))
149
149
150 outlines = []
150 outlines = []
151 if 'output' not in self.exclude_cells:
151 if 'output' not in self.exclude_cells:
152 for output in cell.outputs:
152 for output in cell.outputs:
153 conv_fn = self.dispatch(output.output_type)
153 conv_fn = self.dispatch(output.output_type)
154 outlines.extend(conv_fn(output))
154 outlines.extend(conv_fn(output))
155
155
156 # And then output of many possible types; use a frame for all of it.
156 # And then output of many possible types; use a frame for all of it.
157 if outlines:
157 if outlines:
158 lines.extend(self.in_env('codeoutput', outlines))
158 lines.extend(self.in_env('codeoutput', outlines))
159
159
160 lines.append(ur'\end{codecell}')
160 lines.append(ur'\end{codecell}')
161
161
162 return lines
162 return lines
163
163
164 def _img_lines(self, img_file):
164 def _img_lines(self, img_file):
165 return self.in_env('center',
165 return self.in_env('center',
166 [r'\includegraphics[width=6in]{%s}' % img_file, r'\par'])
166 [r'\includegraphics[width=6in]{%s}' % img_file, r'\par'])
167
167
168 def _svg_lines(self, img_file):
168 def _svg_lines(self, img_file):
169 base_file = os.path.splitext(img_file)[0]
169 base_file = os.path.splitext(img_file)[0]
170 pdf_file = base_file + '.pdf'
170 pdf_file = base_file + '.pdf'
171 subprocess.check_call([self.inkscape, '--export-pdf=%s' % pdf_file,
171 subprocess.check_call([self.inkscape, '--export-pdf=%s' % pdf_file,
172 img_file])
172 img_file])
173 return self._img_lines(pdf_file)
173 return self._img_lines(pdf_file)
174
174
175 def render_markdown(self, cell):
175 def render_markdown(self, cell):
176 return [markdown2latex(cell.source)]
176 return [markdown2latex(cell.source)]
177
177
178 def render_pyout(self, output):
178 def render_pyout(self, output):
179 lines = []
179 lines = []
180
180
181 # output is a dictionary like object with type as a key
181 # output is a dictionary like object with type as a key
182 if 'latex' in output:
182 if 'latex' in output:
183 lines.extend(output.latex)
183 lines.extend(output.latex)
184
184
185 if 'text' in output:
185 if 'text' in output:
186 lines.extend(self.in_env('verbatim', output.text))
186 lines.extend(self.in_env('verbatim', output.text))
187
187
188 return lines
188 return lines
189
189
190 def render_pyerr(self, output):
190 def render_pyerr(self, output):
191 # Note: a traceback is a *list* of frames.
191 # Note: a traceback is a *list* of frames.
192 return self.in_env('traceback',
192 return self.in_env('traceback',
193 self.in_env('verbatim',
193 self.in_env('verbatim',
194 remove_ansi('\n'.join(output.traceback))))
194 remove_ansi('\n'.join(output.traceback))))
195
195
196 def render_raw(self, cell):
196 def render_raw(self, cell):
197 if self.raw_as_verbatim:
197 if self.raw_as_verbatim:
198 return self.in_env('verbatim', cell.source)
198 return self.in_env('verbatim', cell.source)
199 else:
199 else:
200 return [cell.source]
200 return [cell.source]
201
201
202 def _unknown_lines(self, data):
202 def _unknown_lines(self, data):
203 return [r'{\vspace{5mm}\bf WARNING:: unknown cell:}'] + \
203 return [r'{\vspace{5mm}\bf WARNING:: unknown cell:}'] + \
204 self.in_env('verbatim', data)
204 self.in_env('verbatim', data)
205
205
206 def render_display_format_text(self, output):
206 def render_display_format_text(self, output):
207 lines = []
207 lines = []
208
208
209 if 'text' in output:
209 if 'text' in output:
210 lines.extend(self.in_env('verbatim', output.text.strip()))
210 lines.extend(self.in_env('verbatim', output.text.strip()))
211
211
212 return lines
212 return lines
213
213
214 def render_display_format_html(self, output):
214 def render_display_format_html(self, output):
215 return []
215 return []
216
216
217 def render_display_format_latex(self, output):
217 def render_display_format_latex(self, output):
218 if type(output.latex) == type([]):
218 if type(output.latex) == type([]):
219 return output.latex
219 return output.latex
220 return [output.latex]
220 return [output.latex]
221
221
222 def render_display_format_json(self, output):
222 def render_display_format_json(self, output):
223 # latex ignores json
223 # latex ignores json
224 return []
224 return []
225
225
226 def render_display_format_javascript(self, output):
226 def render_display_format_javascript(self, output):
227 # latex ignores javascript
227 # latex ignores javascript
228 return []
228 return []
@@ -1,38 +1,38 b''
1 """A custom pygments lexer for IPython code cells.
1 """A custom pygments lexer for IPython code cells.
2
2
3 Informs The pygments highlighting library of the quirks of IPython's superset
3 Informs The pygments highlighting library of the quirks of IPython's superset
4 of Python -- magic commands, !shell commands, etc.
4 of Python -- magic commands, !shell commands, etc.
5 """
5 """
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2012, the IPython Development Team.
7 # Copyright (c) 2012, the IPython Development Team.
8 #
8 #
9 # Distributed under the terms of the Modified BSD License.
9 # Distributed under the terms of the Modified BSD License.
10 #
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # Third-party imports
18 # Third-party imports
19 from pygments.lexers import PythonLexer, BashLexer
19 from pygments.lexers import PythonLexer, BashLexer
20 from pygments.lexer import bygroups, using
20 from pygments.lexer import bygroups, using
21 from pygments.token import Keyword, Operator, Text
21 from pygments.token import Keyword, Operator, Text
22
22
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Classes
25 # Class declarations
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 class IPythonLexer(PythonLexer):
28 class IPythonLexer(PythonLexer):
29 name = 'IPython'
29 name = 'IPython'
30 aliases = ['ip', 'ipython']
30 aliases = ['ip', 'ipython']
31 filenames = ['*.ipy']
31 filenames = ['*.ipy']
32 tokens = PythonLexer.tokens.copy()
32 tokens = PythonLexer.tokens.copy()
33 tokens['root'] = [
33 tokens['root'] = [
34 (r'(\%+)(\w+)\s+(\.*)(\n)', bygroups(Operator, Keyword,
34 (r'(\%+)(\w+)\s+(\.*)(\n)', bygroups(Operator, Keyword,
35 using(BashLexer), Text)),
35 using(BashLexer), Text)),
36 (r'(\%+)(\w+)\b', bygroups(Operator, Keyword)),
36 (r'(\%+)(\w+)\b', bygroups(Operator, Keyword)),
37 (r'^(!)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
37 (r'^(!)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
38 ] + tokens['root']
38 ] + tokens['root']
@@ -1,120 +1,120 b''
1 """Converter implementing Markdown export.
1 """Converter implementing Markdown export.
2
2
3 Implements a Converter that allows IPython notebooks to reasonably rendered
3 Implements a Converter that allows IPython notebooks to reasonably rendered
4 as a Markdown document.
4 as a Markdown document.
5 """
5 """
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2012, the IPython Development Team.
7 # Copyright (c) 2012, the IPython Development Team.
8 #
8 #
9 # Distributed under the terms of the Modified BSD License.
9 # Distributed under the terms of the Modified BSD License.
10 #
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # Our own imports
18 # Our own imports
19 from converters.base import Converter
19 from converters.base import Converter
20 from converters.utils import highlight, remove_ansi
20 from converters.utils import highlight, remove_ansi
21 from IPython.utils.text import indent
21 from IPython.utils.text import indent
22
22
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Classes and functions
25 # Class declarations
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 class ConverterMarkdown(Converter):
27 class ConverterMarkdown(Converter):
28 extension = 'md'
28 extension = 'md'
29 # show_prompts controls the display of In[} and Out[] prompts for code
29 # show_prompts controls the display of In[} and Out[] prompts for code
30 # cells.
30 # cells.
31 show_prompts = False
31 show_prompts = False
32 # If inline_prompt is False, display prompts on a separate line.
32 # If inline_prompt is False, display prompts on a separate line.
33 inline_prompt = False
33 inline_prompt = False
34
34
35 def __init__(self, infile, highlight_source=True, show_prompts=False,
35 def __init__(self, infile, highlight_source=True, show_prompts=False,
36 inline_prompt=False):
36 inline_prompt=False):
37 super(ConverterMarkdown, self).__init__(infile)
37 super(ConverterMarkdown, self).__init__(infile)
38 self.highlight_source = highlight_source
38 self.highlight_source = highlight_source
39 self.show_prompts = show_prompts
39 self.show_prompts = show_prompts
40 self.inline_prompt = inline_prompt
40 self.inline_prompt = inline_prompt
41
41
42 def render_heading(self, cell):
42 def render_heading(self, cell):
43 return ['{0} {1}'.format('#' * cell.level, cell.source), '']
43 return ['{0} {1}'.format('#' * cell.level, cell.source), '']
44
44
45 def render_code(self, cell):
45 def render_code(self, cell):
46 if not cell.input:
46 if not cell.input:
47 return []
47 return []
48 lines = []
48 lines = []
49 n = self._get_prompt_number(cell)
49 n = self._get_prompt_number(cell)
50 if self.show_prompts:
50 if self.show_prompts:
51 if not self.inline_prompt:
51 if not self.inline_prompt:
52 lines.extend(['*In[%s]:*' % n, ''])
52 lines.extend(['*In[%s]:*' % n, ''])
53 else:
53 else:
54 prompt = 'In[%s]: ' % n
54 prompt = 'In[%s]: ' % n
55 input_lines = cell.input.split('\n')
55 input_lines = cell.input.split('\n')
56 src = (prompt + input_lines[0] + '\n' +
56 src = (prompt + input_lines[0] + '\n' +
57 indent('\n'.join(input_lines[1:]), nspaces=len(prompt)))
57 indent('\n'.join(input_lines[1:]), nspaces=len(prompt)))
58 else:
58 else:
59 src = cell.input
59 src = cell.input
60 src = highlight(src) if self.highlight_source else indent(src)
60 src = highlight(src) if self.highlight_source else indent(src)
61 lines.extend([src, ''])
61 lines.extend([src, ''])
62 if cell.outputs and self.show_prompts and not self.inline_prompt:
62 if cell.outputs and self.show_prompts and not self.inline_prompt:
63 lines.extend(['*Out[%s]:*' % n, ''])
63 lines.extend(['*Out[%s]:*' % n, ''])
64 for output in cell.outputs:
64 for output in cell.outputs:
65 conv_fn = self.dispatch(output.output_type)
65 conv_fn = self.dispatch(output.output_type)
66 lines.extend(conv_fn(output))
66 lines.extend(conv_fn(output))
67
67
68 #lines.append('----')
68 #lines.append('----')
69 lines.append('')
69 lines.append('')
70 return lines
70 return lines
71
71
72 def render_markdown(self, cell):
72 def render_markdown(self, cell):
73 return [cell.source, '']
73 return [cell.source, '']
74
74
75 def render_raw(self, cell):
75 def render_raw(self, cell):
76 if self.raw_as_verbatim:
76 if self.raw_as_verbatim:
77 return [indent(cell.source), '']
77 return [indent(cell.source), '']
78 else:
78 else:
79 return [cell.source, '']
79 return [cell.source, '']
80
80
81 def render_pyout(self, output):
81 def render_pyout(self, output):
82 lines = []
82 lines = []
83
83
84 ## if 'text' in output:
84 ## if 'text' in output:
85 ## lines.extend(['*Out[%s]:*' % self._get_prompt_number(cell), ''])
85 ## lines.extend(['*Out[%s]:*' % self._get_prompt_number(cell), ''])
86
86
87 # output is a dictionary like object with type as a key
87 # output is a dictionary like object with type as a key
88 if 'latex' in output:
88 if 'latex' in output:
89 pass
89 pass
90
90
91 if 'text' in output:
91 if 'text' in output:
92 lines.extend(['<pre>', indent(output.text), '</pre>'])
92 lines.extend(['<pre>', indent(output.text), '</pre>'])
93
93
94 lines.append('')
94 lines.append('')
95 return lines
95 return lines
96
96
97 def render_pyerr(self, output):
97 def render_pyerr(self, output):
98 # Note: a traceback is a *list* of frames.
98 # Note: a traceback is a *list* of frames.
99 return [indent(remove_ansi('\n'.join(output.traceback))), '']
99 return [indent(remove_ansi('\n'.join(output.traceback))), '']
100
100
101 def _img_lines(self, img_file):
101 def _img_lines(self, img_file):
102 return ['', '![](%s)' % img_file, '']
102 return ['', '![](%s)' % img_file, '']
103
103
104 def render_display_format_text(self, output):
104 def render_display_format_text(self, output):
105 return [indent(output.text)]
105 return [indent(output.text)]
106
106
107 def _unknown_lines(self, data):
107 def _unknown_lines(self, data):
108 return ['Warning: Unknown cell', data]
108 return ['Warning: Unknown cell', data]
109
109
110 def render_display_format_html(self, output):
110 def render_display_format_html(self, output):
111 return [output.html]
111 return [output.html]
112
112
113 def render_display_format_latex(self, output):
113 def render_display_format_latex(self, output):
114 return ['LaTeX::', indent(output.latex)]
114 return ['LaTeX::', indent(output.latex)]
115
115
116 def render_display_format_json(self, output):
116 def render_display_format_json(self, output):
117 return ['JSON:', indent(output.json)]
117 return ['JSON:', indent(output.json)]
118
118
119 def render_display_format_javascript(self, output):
119 def render_display_format_javascript(self, output):
120 return ['JavaScript:', indent(output.javascript)]
120 return ['JavaScript:', indent(output.javascript)]
@@ -1,107 +1,107 b''
1 """Base class for doing notebook-to-notebook transformations.
1 """Base class for doing notebook-to-notebook transformations.
2
2
3 This implements a converter class that turns an IPython notebook into another
3 This implements a converter class that turns an IPython notebook into another
4 IPython notebook, mainly so that it can be subclassed to perform more useful
4 IPython notebook, mainly so that it can be subclassed to perform more useful
5 and sophisticated transformations.
5 and sophisticated transformations.
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2011, the IPython Development Team.
8 # Copyright (c) 2011, the IPython Development Team.
9 #
9 #
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11 #
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 # Stdlib imports
19 # Stdlib imports
20 import json
20 import json
21 import os
21 import os
22 from shutil import rmtree
22 from shutil import rmtree
23
23
24 # Our own imports
24 # Our own imports
25 from converters.base import Converter
25 from converters.base import Converter
26 from converters.utils import cell_to_lines
26 from converters.utils import cell_to_lines
27
27
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Classes and functions
30 # Class declarations
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 class ConverterNotebook(Converter):
32 class ConverterNotebook(Converter):
33 """
33 """
34 A converter that is essentially a null-op.
34 A converter that is essentially a null-op.
35 This exists so it can be subclassed
35 This exists so it can be subclassed
36 for custom handlers of .ipynb files
36 for custom handlers of .ipynb files
37 that create new .ipynb files.
37 that create new .ipynb files.
38
38
39 What distinguishes this from JSONWriter is that
39 What distinguishes this from JSONWriter is that
40 subclasses can specify what to do with each type of cell.
40 subclasses can specify what to do with each type of cell.
41
41
42 Writes out a notebook file.
42 Writes out a notebook file.
43
43
44 """
44 """
45 extension = 'ipynb'
45 extension = 'ipynb'
46
46
47 def __init__(self, infile, outbase):
47 def __init__(self, infile, outbase):
48 Converter.__init__(self, infile)
48 Converter.__init__(self, infile)
49 self.outbase = outbase
49 self.outbase = outbase
50 rmtree(self.files_dir)
50 rmtree(self.files_dir)
51
51
52 def convert(self):
52 def convert(self):
53 return unicode(json.dumps(json.loads(Converter.convert(self, ',')),
53 return unicode(json.dumps(json.loads(Converter.convert(self, ',')),
54 indent=1, sort_keys=True))
54 indent=1, sort_keys=True))
55
55
56 def optional_header(self):
56 def optional_header(self):
57 s = \
57 s = \
58 """{
58 """{
59 "metadata": {
59 "metadata": {
60 "name": "%(name)s"
60 "name": "%(name)s"
61 },
61 },
62 "nbformat": 3,
62 "nbformat": 3,
63 "worksheets": [
63 "worksheets": [
64 {
64 {
65 "cells": [""" % {'name': os.path.basename(self.outbase)}
65 "cells": [""" % {'name': os.path.basename(self.outbase)}
66 return s.split('\n')
66 return s.split('\n')
67
67
68 def optional_footer(self):
68 def optional_footer(self):
69 s = \
69 s = \
70 """]
70 """]
71 }
71 }
72 ]
72 ]
73 }"""
73 }"""
74 return s.split('\n')
74 return s.split('\n')
75
75
76 def render_heading(self, cell):
76 def render_heading(self, cell):
77 return cell_to_lines(cell)
77 return cell_to_lines(cell)
78
78
79 def render_code(self, cell):
79 def render_code(self, cell):
80 return cell_to_lines(cell)
80 return cell_to_lines(cell)
81
81
82 def render_markdown(self, cell):
82 def render_markdown(self, cell):
83 return cell_to_lines(cell)
83 return cell_to_lines(cell)
84
84
85 def render_raw(self, cell):
85 def render_raw(self, cell):
86 return cell_to_lines(cell)
86 return cell_to_lines(cell)
87
87
88 def render_pyout(self, output):
88 def render_pyout(self, output):
89 return cell_to_lines(output)
89 return cell_to_lines(output)
90
90
91 def render_pyerr(self, output):
91 def render_pyerr(self, output):
92 return cell_to_lines(output)
92 return cell_to_lines(output)
93
93
94 def render_display_format_text(self, output):
94 def render_display_format_text(self, output):
95 return [output.text]
95 return [output.text]
96
96
97 def render_display_format_html(self, output):
97 def render_display_format_html(self, output):
98 return [output.html]
98 return [output.html]
99
99
100 def render_display_format_latex(self, output):
100 def render_display_format_latex(self, output):
101 return [output.latex]
101 return [output.latex]
102
102
103 def render_display_format_json(self, output):
103 def render_display_format_json(self, output):
104 return [output.json]
104 return [output.json]
105
105
106 def render_display_format_javascript(self, output):
106 def render_display_format_javascript(self, output):
107 return [output.javascript]
107 return [output.javascript]
@@ -1,125 +1,125 b''
1 """Notebook export to .py source code files.
1 """Notebook export to .py source code files.
2
2
3 Since Python export is provided in the notebook itself (provided by classes
3 Since Python export is provided in the notebook itself (provided by classes
4 in `IPython.nbformat`), this class serves mainly as a base class for other
4 in `IPython.nbformat`), this class serves mainly as a base class for other
5 converters that may wish to implement cell-type-specific behaviors.
5 converters that may wish to implement cell-type-specific behaviors.
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2012, the IPython Development Team.
8 # Copyright (c) 2012, the IPython Development Team.
9 #
9 #
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11 #
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 # IPython imports
19 # IPython imports
20 from IPython.utils.text import indent
20 from IPython.utils.text import indent
21
21
22 # Our own imports
22 # Our own imports
23 from converters.base import Converter
23 from converters.base import Converter
24 from converters.utils import remove_ansi
24 from converters.utils import remove_ansi
25
25
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Classes and functions
28 # Class declarations
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 class ConverterPy(Converter):
30 class ConverterPy(Converter):
31 """
31 """
32 A converter that takes a notebook and converts it to a .py file.
32 A converter that takes a notebook and converts it to a .py file.
33
33
34 What distinguishes this from PyWriter and PyReader in IPython.nbformat is
34 What distinguishes this from PyWriter and PyReader in IPython.nbformat is
35 that subclasses can specify what to do with each type of cell.
35 that subclasses can specify what to do with each type of cell.
36 Additionally, unlike PyWriter, this does not preserve the '# <markdown>'
36 Additionally, unlike PyWriter, this does not preserve the '# <markdown>'
37 opening and closing comments style comments in favor of a cleaner looking
37 opening and closing comments style comments in favor of a cleaner looking
38 python program.
38 python program.
39
39
40 Note:
40 Note:
41 Even though this produces a .py file, it is not guaranteed to be valid
41 Even though this produces a .py file, it is not guaranteed to be valid
42 python file, since the notebook may be using magics and even cell
42 python file, since the notebook may be using magics and even cell
43 magics.
43 magics.
44 """
44 """
45 extension = 'py'
45 extension = 'py'
46
46
47 def __init__(self, infile, show_prompts=True, show_output=True):
47 def __init__(self, infile, show_prompts=True, show_output=True):
48 super(ConverterPy, self).__init__(infile)
48 super(ConverterPy, self).__init__(infile)
49 self.show_prompts = show_prompts
49 self.show_prompts = show_prompts
50 self.show_output = show_output
50 self.show_output = show_output
51
51
52 @staticmethod
52 @staticmethod
53 def comment(input):
53 def comment(input):
54 "returns every line in input as commented out"
54 "returns every line in input as commented out"
55 return "# " + input.replace("\n", "\n# ")
55 return "# " + input.replace("\n", "\n# ")
56
56
57 def render_heading(self, cell):
57 def render_heading(self, cell):
58 return ['#{0} {1}'.format('#' * cell.level, cell.source), '']
58 return ['#{0} {1}'.format('#' * cell.level, cell.source), '']
59
59
60 def render_code(self, cell):
60 def render_code(self, cell):
61 n = self._get_prompt_number(cell)
61 n = self._get_prompt_number(cell)
62 if not cell.input:
62 if not cell.input:
63 return []
63 return []
64 lines = []
64 lines = []
65 if self.show_prompts:
65 if self.show_prompts:
66 lines.extend(['# In[%s]:' % n])
66 lines.extend(['# In[%s]:' % n])
67 src = cell.input
67 src = cell.input
68 lines.extend([src, ''])
68 lines.extend([src, ''])
69 if self.show_output:
69 if self.show_output:
70 if cell.outputs:
70 if cell.outputs:
71 lines.extend(['# Out[%s]:' % n])
71 lines.extend(['# Out[%s]:' % n])
72 for output in cell.outputs:
72 for output in cell.outputs:
73 conv_fn = self.dispatch(output.output_type)
73 conv_fn = self.dispatch(output.output_type)
74 lines.extend(conv_fn(output))
74 lines.extend(conv_fn(output))
75 return lines
75 return lines
76
76
77 def render_markdown(self, cell):
77 def render_markdown(self, cell):
78 return [self.comment(cell.source), '']
78 return [self.comment(cell.source), '']
79
79
80 def render_raw(self, cell):
80 def render_raw(self, cell):
81 if self.raw_as_verbatim:
81 if self.raw_as_verbatim:
82 return [self.comment(indent(cell.source)), '']
82 return [self.comment(indent(cell.source)), '']
83 else:
83 else:
84 return [self.comment(cell.source), '']
84 return [self.comment(cell.source), '']
85
85
86 def render_pyout(self, output):
86 def render_pyout(self, output):
87 lines = []
87 lines = []
88
88
89 ## if 'text' in output:
89 ## if 'text' in output:
90 ## lines.extend(['*Out[%s]:*' % self._get_prompt_number(cell), ''])
90 ## lines.extend(['*Out[%s]:*' % self._get_prompt_number(cell), ''])
91
91
92 # output is a dictionary like object with type as a key
92 # output is a dictionary like object with type as a key
93 if 'latex' in output:
93 if 'latex' in output:
94 pass
94 pass
95
95
96 if 'text' in output:
96 if 'text' in output:
97 lines.extend([self.comment(indent(output.text)), ''])
97 lines.extend([self.comment(indent(output.text)), ''])
98
98
99 lines.append('')
99 lines.append('')
100 return lines
100 return lines
101
101
102 def render_pyerr(self, output):
102 def render_pyerr(self, output):
103 # Note: a traceback is a *list* of frames.
103 # Note: a traceback is a *list* of frames.
104 return [indent(remove_ansi('\n'.join(output.traceback))), '']
104 return [indent(remove_ansi('\n'.join(output.traceback))), '']
105
105
106 def _img_lines(self, img_file):
106 def _img_lines(self, img_file):
107 return [self.comment('image file: %s' % img_file), '']
107 return [self.comment('image file: %s' % img_file), '']
108
108
109 def render_display_format_text(self, output):
109 def render_display_format_text(self, output):
110 return [self.comment(indent(output.text))]
110 return [self.comment(indent(output.text))]
111
111
112 def _unknown_lines(self, data):
112 def _unknown_lines(self, data):
113 return [self.comment('Warning: Unknown cell' + str(data))]
113 return [self.comment('Warning: Unknown cell' + str(data))]
114
114
115 def render_display_format_html(self, output):
115 def render_display_format_html(self, output):
116 return [self.comment(output.html)]
116 return [self.comment(output.html)]
117
117
118 def render_display_format_latex(self, output):
118 def render_display_format_latex(self, output):
119 return []
119 return []
120
120
121 def render_display_format_json(self, output):
121 def render_display_format_json(self, output):
122 return []
122 return []
123
123
124 def render_display_format_javascript(self, output):
124 def render_display_format_javascript(self, output):
125 return []
125 return []
@@ -1,96 +1,96 b''
1 """Notebook export to reStructuredText (rST).
1 """Notebook export to reStructuredText (rST).
2
2
3 This file provides a converter class for rendering IPython notebooks as valid
3 This file provides a converter class for rendering IPython notebooks as valid
4 reStructuredText, suitable for inclusion in e.g. Sphinx documentation.
4 reStructuredText, suitable for inclusion in e.g. Sphinx documentation.
5 """
5 """
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2012, the IPython Development Team.
7 # Copyright (c) 2012, the IPython Development Team.
8 #
8 #
9 # Distributed under the terms of the Modified BSD License.
9 # Distributed under the terms of the Modified BSD License.
10 #
10 #
11 # The full license is in the file COPYING.txt, distributed with this software.
11 # The full license is in the file COPYING.txt, distributed with this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # IPython imports
18 # IPython imports
19 from IPython.utils.text import indent
19 from IPython.utils.text import indent
20
20
21 # Our own imports
21 # Our own imports
22 from converters.base import Converter
22 from converters.base import Converter
23 from converters.utils import markdown2rst, rst_directive, remove_ansi
23 from converters.utils import markdown2rst, rst_directive, remove_ansi
24
24
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Classes and functions
27 # Class declarations
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 class ConverterRST(Converter):
29 class ConverterRST(Converter):
30 extension = 'rst'
30 extension = 'rst'
31 heading_level = {1: '=', 2: '-', 3: '`', 4: '\'', 5: '.', 6: '~'}
31 heading_level = {1: '=', 2: '-', 3: '`', 4: '\'', 5: '.', 6: '~'}
32
32
33 def render_heading(self, cell):
33 def render_heading(self, cell):
34 marker = self.heading_level[cell.level]
34 marker = self.heading_level[cell.level]
35 return ['{0}\n{1}\n'.format(cell.source, marker * len(cell.source))]
35 return ['{0}\n{1}\n'.format(cell.source, marker * len(cell.source))]
36
36
37 def render_code(self, cell):
37 def render_code(self, cell):
38 # Note: cell has type 'IPython.nbformat.v3.nbbase.NotebookNode'
38 # Note: cell has type 'IPython.nbformat.v3.nbbase.NotebookNode'
39 if not cell.input:
39 if not cell.input:
40 return []
40 return []
41
41
42 lines = ['In[%s]:' % self._get_prompt_number(cell), '']
42 lines = ['In[%s]:' % self._get_prompt_number(cell), '']
43 lines.extend(rst_directive('.. code:: python', cell.input))
43 lines.extend(rst_directive('.. code:: python', cell.input))
44
44
45 for output in cell.outputs:
45 for output in cell.outputs:
46 conv_fn = self.dispatch(output.output_type)
46 conv_fn = self.dispatch(output.output_type)
47 lines.extend(conv_fn(output))
47 lines.extend(conv_fn(output))
48
48
49 return lines
49 return lines
50
50
51 def render_markdown(self, cell):
51 def render_markdown(self, cell):
52 #return [cell.source]
52 #return [cell.source]
53 return [markdown2rst(cell.source)]
53 return [markdown2rst(cell.source)]
54
54
55 def render_raw(self, cell):
55 def render_raw(self, cell):
56 if self.raw_as_verbatim:
56 if self.raw_as_verbatim:
57 return ['::', '', indent(cell.source), '']
57 return ['::', '', indent(cell.source), '']
58 else:
58 else:
59 return [cell.source]
59 return [cell.source]
60
60
61 def render_pyout(self, output):
61 def render_pyout(self, output):
62 lines = ['Out[%s]:' % self._get_prompt_number(output), '']
62 lines = ['Out[%s]:' % self._get_prompt_number(output), '']
63
63
64 # output is a dictionary like object with type as a key
64 # output is a dictionary like object with type as a key
65 if 'latex' in output:
65 if 'latex' in output:
66 lines.extend(rst_directive('.. math::', output.latex))
66 lines.extend(rst_directive('.. math::', output.latex))
67
67
68 if 'text' in output:
68 if 'text' in output:
69 lines.extend(rst_directive('.. parsed-literal::', output.text))
69 lines.extend(rst_directive('.. parsed-literal::', output.text))
70
70
71 return lines
71 return lines
72
72
73 def render_pyerr(self, output):
73 def render_pyerr(self, output):
74 # Note: a traceback is a *list* of frames.
74 # Note: a traceback is a *list* of frames.
75 return ['::', '', indent(remove_ansi('\n'.join(output.traceback))), '']
75 return ['::', '', indent(remove_ansi('\n'.join(output.traceback))), '']
76
76
77 def _img_lines(self, img_file):
77 def _img_lines(self, img_file):
78 return ['.. image:: %s' % img_file, '']
78 return ['.. image:: %s' % img_file, '']
79
79
80 def render_display_format_text(self, output):
80 def render_display_format_text(self, output):
81 return rst_directive('.. parsed-literal::', output.text)
81 return rst_directive('.. parsed-literal::', output.text)
82
82
83 def _unknown_lines(self, data):
83 def _unknown_lines(self, data):
84 return rst_directive('.. warning:: Unknown cell') + [data]
84 return rst_directive('.. warning:: Unknown cell') + [data]
85
85
86 def render_display_format_html(self, output):
86 def render_display_format_html(self, output):
87 return rst_directive('.. raw:: html', output.html)
87 return rst_directive('.. raw:: html', output.html)
88
88
89 def render_display_format_latex(self, output):
89 def render_display_format_latex(self, output):
90 return rst_directive('.. math::', output.latex)
90 return rst_directive('.. math::', output.latex)
91
91
92 def render_display_format_json(self, output):
92 def render_display_format_json(self, output):
93 return rst_directive('.. raw:: json', output.json)
93 return rst_directive('.. raw:: json', output.json)
94
94
95 def render_display_format_javascript(self, output):
95 def render_display_format_javascript(self, output):
96 return rst_directive('.. raw:: javascript', output.javascript)
96 return rst_directive('.. raw:: javascript', output.javascript)
General Comments 0
You need to be logged in to leave comments. Login now