##// END OF EJS Templates
PEP8-ify rest of the repository.
David Warde-Farley -
Show More
@@ -1,183 +1,188 b''
1 1 from __future__ import absolute_import
2 2
3 3 from converters.base import Converter
4 4 from converters.utils import text_cell, output_container
5 5 from converters.utils import highlight, coalesce_streams, ansi2html
6 6
7 7 from IPython.utils import path
8 8 from markdown import markdown
9 9 import os
10 10 import io
11 11
12
12 13 class ConverterHTML(Converter):
13 14 extension = 'html'
14 15
15 16 def in_tag(self, tag, src, attrs=None):
16 17 """Return a list of elements bracketed by the given tag"""
17 18 attr_s = '' if attrs is None else \
18 ' '.join( "%s=%s" % (attr, value)
19 for attr, value in attrs.iteritems() )
19 ' '.join("%s=%s" % (attr, value)
20 for attr, value in attrs.iteritems())
20 21 return ['<%s %s>' % (tag, attr_s), src, '</%s>' % tag]
21
22
22 23 def _ansi_colored(self, text):
23 24 return ['<pre>%s</pre>' % ansi2html(text)]
24 25
25 26 def _stylesheet(self, fname):
26 27 with io.open(fname, encoding='utf-8') as f:
27 28 s = f.read()
28 29 return self.in_tag('style', s, dict(type='"text/css"'))
29 30
30 31 def _out_prompt(self, output):
31 32 if output.output_type == 'pyout':
32 n = output.prompt_number if output.prompt_number is not None else '&nbsp;'
33 n = (output.prompt_number if output.prompt_number is not None
34 else '&nbsp;')
33 35 content = 'Out[%s]:' % n
34 36 else:
35 37 content = ''
36 38 return ['<div class="prompt output_prompt">%s</div>' % content]
37 39
38 40 def header_body(self):
39 41 """Return the body of the header as a list of strings."""
40
42
41 43 from pygments.formatters import HtmlFormatter
42 44
43 45 header = []
44 46 static = os.path.join(path.get_ipython_package_dir(),
45 47 'frontend', 'html', 'notebook', 'static',
46 48 )
47 49 here = os.path.split(os.path.realpath(__file__))[0]
48 50 css = os.path.join(static, 'css')
49 51 for sheet in [
50 52 # do we need jquery and prettify?
51 # os.path.join(static, 'jquery', 'css', 'themes', 'base', 'jquery-ui.min.css'),
53 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
54 # 'jquery-ui.min.css'),
52 55 # os.path.join(static, 'prettify', 'prettify.css'),
53 56 os.path.join(css, 'boilerplate.css'),
54 57 os.path.join(css, 'fbm.css'),
55 58 os.path.join(css, 'notebook.css'),
56 59 os.path.join(css, 'renderedhtml.css'),
57 60 # our overrides:
58 os.path.join(here, '..','css', 'static_html.css'),
61 os.path.join(here, '..', 'css', 'static_html.css'),
59 62 ]:
60 63 header.extend(self._stylesheet(sheet))
61
64
62 65 # pygments css
63 66 pygments_css = HtmlFormatter().get_style_defs('.highlight')
64 67 header.extend(['<meta charset="UTF-8">'])
65 header.extend(self.in_tag('style', pygments_css, dict(type='"text/css"')))
66
68 header.extend(self.in_tag('style', pygments_css,
69 dict(type='"text/css"')))
70
67 71 # TODO: this should be allowed to use local mathjax:
68 header.extend(self.in_tag('script', '', {'type':'"text/javascript"',
69 'src': '"https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"',
72 header.extend(self.in_tag('script', '', {'type': '"text/javascript"',
73 'src': '"https://c328740.ssl.cf1.rackcdn.com/mathjax/'
74 'latest/MathJax.js?config=TeX-AMS_HTML"',
70 75 }))
71 with io.open(os.path.join(here, '..', 'js', 'initmathjax.js'),
76 with io.open(os.path.join(here, '..', 'js', 'initmathjax.js'),
72 77 encoding='utf-8') as f:
73 header.extend(self.in_tag('script', f.read(),
78 header.extend(self.in_tag('script', f.read(),
74 79 {'type': '"text/javascript"'}))
75 80 return header
76 81
77 82 def optional_header(self):
78 83 return ['<html>', '<head>'] + self.header_body() + \
79 84 ['</head>', '<body>']
80 85
81 86 def optional_footer(self):
82 87 return ['</body>', '</html>']
83 88
84 89 @text_cell
85 90 def render_heading(self, cell):
86 91 marker = cell.level
87 92 return [u'<h{1}>\n {0}\n</h{1}>'.format(cell.source, marker)]
88
93
89 94 def render_code(self, cell):
90 95 if not cell.input:
91 96 return []
92
97
93 98 lines = ['<div class="cell border-box-sizing code_cell vbox">']
94
99
95 100 lines.append('<div class="input hbox">')
96 n = cell.prompt_number if getattr(cell, 'prompt_number', None) is not None else '&nbsp;'
97 lines.append('<div class="prompt input_prompt">In&nbsp;[%s]:</div>' % n)
101 n = (cell.prompt_number
102 if getattr(cell, 'prompt_number', None) is not None
103 else '&nbsp;')
104 lines.append(
105 '<div class="prompt input_prompt">In&nbsp;[%s]:</div>' % n
106 )
98 107 lines.append('<div class="input_area box-flex1">')
99 108 lines.append(highlight(cell.input))
100 lines.append('</div>') # input_area
101 lines.append('</div>') # input
102
109 lines.append('</div>') # input_area
110 lines.append('</div>') # input
111
103 112 if cell.outputs:
104 113 lines.append('<div class="vbox output_wrapper">')
105 114 lines.append('<div class="output vbox">')
106
115
107 116 for output in coalesce_streams(cell.outputs):
108 117 conv_fn = self.dispatch(output.output_type)
109 118 lines.extend(conv_fn(output))
110
111 lines.append('</div>') # output
112 lines.append('</div>') # output_wrapper
113
114 lines.append('</div>') # cell
115
119
120 lines.append('</div>') # output
121 lines.append('</div>') # output_wrapper
122
123 lines.append('</div>') # cell
124
116 125 return lines
117 126
118 127 @text_cell
119 128 def render_markdown(self, cell):
120 129 return [markdown(cell.source)]
121 130
122 131 def render_raw(self, cell):
123 132 if self.raw_as_verbatim:
124 133 return self.in_tag('pre', cell.source)
125 134 else:
126 135 return [cell.source]
127 136
128 137 @output_container
129 138 def render_pyout(self, output):
130 139 for fmt in ['html', 'latex', 'png', 'jpeg', 'svg', 'text']:
131 140 if fmt in output:
132 141 conv_fn = self.dispatch_display_format(fmt)
133 142 return conv_fn(output)
134 143 return []
135 144
136 145 render_display_data = render_pyout
137 146
138 147 @output_container
139 148 def render_stream(self, output):
140 149 return self._ansi_colored(output.text)
141
142 150
143 151 @output_container
144 152 def render_pyerr(self, output):
145 153 # Note: a traceback is a *list* of frames.
146 154 # lines = []
147
148 # stb =
155
156 # stb =
149 157 return self._ansi_colored('\n'.join(output.traceback))
150 158
151 159 def _img_lines(self, img_file):
152 160 return ['<img src="%s">' % img_file, '</img>']
153 161
154 162 def _unknown_lines(self, data):
155 163 return ['<h2>Warning:: Unknown cell</h2>'] + self.in_tag('pre', data)
156 164
157
158 165 def render_display_format_png(self, output):
159 166 return ['<img src="data:image/png;base64,%s"></img>' % output.png]
160 167
161 168 def render_display_format_svg(self, output):
162 169 return [output.svg]
163 170
164 171 def render_display_format_jpeg(self, output):
165 172 return ['<img src="data:image/jpeg;base64,%s"></img>' % output.jpeg]
166 173
167 174 def render_display_format_text(self, output):
168 175 return self._ansi_colored(output.text)
169 176
170 177 def render_display_format_html(self, output):
171 178 return [output.html]
172 179
173 180 def render_display_format_latex(self, output):
174 181 return [output.latex]
175 182
176 183 def render_display_format_json(self, output):
177 184 # html ignores json
178 185 return []
179 186
180
181 187 def render_display_format_javascript(self, output):
182 188 return [output.javascript]
183
@@ -1,192 +1,191 b''
1 1 from converters.base import Converter
2 2 from converters.utils import markdown2latex, remove_ansi
3 import os, sys
3 import os
4 4 import subprocess
5
5 import sys
6 6
7 7 inkscape = 'inkscape'
8 8 if sys.platform == 'darwin':
9 9 inkscape = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape'
10 10 if not os.path.exists(inkscape):
11 11 inkscape = None
12 12
13
13 14 class ConverterLaTeX(Converter):
14 15 """Converts a notebook to a .tex file suitable for pdflatex.
15 16
16 17 Note: this converter *needs*:
17 18
18 19 - `pandoc`: for all conversion of markdown cells. If your notebook only
19 20 has Raw cells, pandoc will not be needed.
20
21
21 22 - `inkscape`: if your notebook has SVG figures. These need to be
22 23 converted to PDF before inclusion in the TeX file, as LaTeX doesn't
23 24 understand SVG natively.
24
25
25 26 You will in general obtain much better final PDF results if you configure
26 the matplotlib backend to create SVG output with
27 the matplotlib backend to create SVG output with
27 28
28 29 %config InlineBackend.figure_format = 'svg'
29 30
30 31 (or set the equivalent flag at startup or in your configuration profile).
31 32 """
32 33 inkscape = inkscape
33 34 extension = 'tex'
34 35 documentclass = 'article'
35 36 documentclass_options = '11pt,english'
36 37 heading_map = {1: r'\section',
37 38 2: r'\subsection',
38 39 3: r'\subsubsection',
39 40 4: r'\paragraph',
40 41 5: r'\subparagraph',
41 42 6: r'\subparagraph'}
42 43
43 44 def in_env(self, environment, lines):
44 45 """Return list of environment lines for input lines
45 46
46 47 Parameters
47 48 ----------
48 49 env : string
49 50 Name of the environment to bracket with begin/end.
50 51
51 52 lines: """
52 53 out = [ur'\begin{%s}' % environment]
53 54 if isinstance(lines, basestring):
54 55 out.append(lines)
55 56 else: # list
56 57 out.extend(lines)
57 58 out.append(ur'\end{%s}' % environment)
58 59 return out
59 60
60 def convert(self, *kwargs):
61 def convert(self, *args, **kwargs):
61 62 # The main body is done by the logic in the parent class, and that's
62 63 # all we need if preamble support has been turned off.
63 body = super(ConverterLaTeX, self).convert(*kwargs)
64 body = super(ConverterLaTeX, self).convert(*args, **kwargs)
64 65 if not self.with_preamble:
65 66 return body
66 67 # But if preamble is on, then we need to construct a proper, standalone
67 68 # tex file.
68
69
69 70 # Tag the document at the top and set latex class
70 final = [ r'%% This file was auto-generated by IPython, do NOT edit',
71 r'%% Conversion from the original notebook file:',
72 r'%% {0}'.format(self.infile),
73 r'%%',
74 r'\documentclass[%s]{%s}' % (self.documentclass_options,
75 self.documentclass),
76 '',
71 final = [r'%% This file was auto-generated by IPython, do NOT edit',
72 r'%% Conversion from the original notebook file:',
73 r'%% {0}'.format(self.infile),
74 r'%%',
75 r'\documentclass[%s]{%s}' % (self.documentclass_options,
76 self.documentclass),
77 '',
77 78 ]
78 79 # Load our own preamble, which is stored next to the main file. We
79 80 # need to be careful in case the script entry point is a symlink
80 81 myfile = os.path.realpath(__file__)
81 with open(os.path.join(os.path.dirname(myfile), '../preamble.tex')) as f:
82 preamble = '../preamble.tex'
83 with open(os.path.join(os.path.dirname(myfile), preamble)) as f:
82 84 final.append(f.read())
83
85
84 86 # Load any additional user-supplied preamble
85 87 if self.user_preamble:
86 88 final.extend(['', '%% Adding user preamble from file:',
87 89 '%% {0}'.format(self.user_preamble), ''])
88 90 with open(self.user_preamble) as f:
89 91 final.append(f.read())
90
92
91 93 # Include document body
92 final.extend([ r'\begin{document}', '',
93 body,
94 r'\end{document}', ''])
94 final.extend([r'\begin{document}', '',
95 body,
96 r'\end{document}', ''])
95 97 # Retun value must be a string
96 98 return '\n'.join(final)
97
99
98 100 def render_heading(self, cell):
99 101 marker = self.heading_map[cell.level]
100 return ['%s{%s}' % (marker, cell.source) ]
102 return ['%s{%s}' % (marker, cell.source)]
101 103
102 104 def render_code(self, cell):
103 105 if not cell.input:
104 106 return []
105 107
106 108 # Cell codes first carry input code, we use lstlisting for that
107 109 lines = [ur'\begin{codecell}']
108
110
109 111 lines.extend(self.in_env('codeinput',
110 112 self.in_env('lstlisting', cell.input)))
111 113
112 114 outlines = []
113 115 for output in cell.outputs:
114 116 conv_fn = self.dispatch(output.output_type)
115 117 outlines.extend(conv_fn(output))
116 118
117 119 # And then output of many possible types; use a frame for all of it.
118 120 if outlines:
119 121 lines.extend(self.in_env('codeoutput', outlines))
120 122
121 123 lines.append(ur'\end{codecell}')
122 124
123 125 return lines
124 126
125
126 127 def _img_lines(self, img_file):
127 128 return self.in_env('center',
128 129 [r'\includegraphics[width=6in]{%s}' % img_file, r'\par'])
129 130
130 131 def _svg_lines(self, img_file):
131 132 base_file = os.path.splitext(img_file)[0]
132 133 pdf_file = base_file + '.pdf'
133 subprocess.check_call([ self.inkscape, '--export-pdf=%s' % pdf_file,
134 subprocess.check_call([self.inkscape, '--export-pdf=%s' % pdf_file,
134 135 img_file])
135 136 return self._img_lines(pdf_file)
136 137
137 138 def render_markdown(self, cell):
138 139 return [markdown2latex(cell.source)]
139
140
140 141 def render_pyout(self, output):
141 142 lines = []
142 143
143 144 # output is a dictionary like object with type as a key
144 145 if 'latex' in output:
145 146 lines.extend(output.latex)
146 147
147 148 if 'text' in output:
148 149 lines.extend(self.in_env('verbatim', output.text))
149 150
150 151 return lines
151 152
152 153 def render_pyerr(self, output):
153 154 # Note: a traceback is a *list* of frames.
154 155 return self.in_env('traceback',
155 self.in_env('verbatim',
156 self.in_env('verbatim',
156 157 remove_ansi('\n'.join(output.traceback))))
157 158
158 159 def render_raw(self, cell):
159 160 if self.raw_as_verbatim:
160 161 return self.in_env('verbatim', cell.source)
161 162 else:
162 163 return [cell.source]
163 164
164 165 def _unknown_lines(self, data):
165 166 return [r'{\vspace{5mm}\bf WARNING:: unknown cell:}'] + \
166 167 self.in_env('verbatim', data)
167 168
168
169 169 def render_display_format_text(self, output):
170 170 lines = []
171 171
172 172 if 'text' in output:
173 173 lines.extend(self.in_env('verbatim', output.text.strip()))
174 174
175 175 return lines
176 176
177 177 def render_display_format_html(self, output):
178 178 return []
179 179
180 180 def render_display_format_latex(self, output):
181 181 if type(output.latex) == type([]):
182 182 return output.latex
183 183 return [output.latex]
184 184
185 185 def render_display_format_json(self, output):
186 186 # latex ignores json
187 187 return []
188 188
189
190 189 def render_display_format_javascript(self, output):
191 190 # latex ignores javascript
192 191 return []
@@ -1,23 +1,24 b''
1 1 #-----------------------------------------------------------------------------
2 2 # Imports
3 3 #-----------------------------------------------------------------------------
4 4
5 5 from pygments.lexers import PythonLexer, BashLexer
6 6 from pygments.lexer import bygroups, using
7 7 from pygments.token import Keyword, Operator, Text
8 8
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Classes
12 12 #-----------------------------------------------------------------------------
13 13
14 14 class IPythonLexer(PythonLexer):
15 15 name = 'IPython'
16 16 aliases = ['ip', 'ipython']
17 17 filenames = ['*.ipy']
18 18 tokens = PythonLexer.tokens.copy()
19 19 tokens['root'] = [
20 (r'(\%+)(\w+)\s+(\.*)(\n)', bygroups(Operator, Keyword, using(BashLexer), Text)),
20 (r'(\%+)(\w+)\s+(\.*)(\n)', bygroups(Operator, Keyword,
21 using(BashLexer), Text)),
21 22 (r'(\%+)(\w+)\b', bygroups(Operator, Keyword)),
22 23 (r'^(!)(.+)(\n)', bygroups(Operator, using(BashLexer), Text)),
23 24 ] + tokens['root']
@@ -1,90 +1,92 b''
1 1 from converters.base import Converter
2 2 from converters.utils import highlight, remove_ansi
3 3 from IPython.utils.text import indent
4 4
5
5 6 class ConverterMarkdown(Converter):
6 7 extension = 'md'
7 8
8 9 def __init__(self, infile, highlight_source=True, show_prompts=False,
9 10 inline_prompt=False):
10 11 super(ConverterMarkdown, self).__init__(infile)
11 12 self.highlight_source = highlight_source
12 13 self.show_prompts = show_prompts
13 14 self.inline_prompt = inline_prompt
14 15
15 16 def render_heading(self, cell):
16 return ['{0} {1}'.format('#'*cell.level, cell.source), '']
17 return ['{0} {1}'.format('#' * cell.level, cell.source), '']
17 18
18 19 def render_code(self, cell):
19 20 if not cell.input:
20 21 return []
21 22 lines = []
22 23 if self.show_prompts and not self.inline_prompt:
23 24 lines.extend(['*In[%s]:*' % cell.prompt_number, ''])
24 25 if self.show_prompts and self.inline_prompt:
25 26 prompt = 'In[%s]: ' % cell.prompt_number
26 27 input_lines = cell.input.split('\n')
27 src = prompt + input_lines[0] + '\n' + indent('\n'.join(input_lines[1:]), nspaces=len(prompt))
28 src = (prompt + input_lines[0] + '\n' +
29 indent('\n'.join(input_lines[1:]), nspaces=len(prompt)))
28 30 else:
29 31 src = cell.input
30 32 src = highlight(src) if self.highlight_source else indent(src)
31 33 lines.extend([src, ''])
32 34 if cell.outputs and self.show_prompts and not self.inline_prompt:
33 35 lines.extend(['*Out[%s]:*' % cell.prompt_number, ''])
34 36 for output in cell.outputs:
35 37 conv_fn = self.dispatch(output.output_type)
36 38 lines.extend(conv_fn(output))
37 39
38 40 #lines.append('----')
39 41 lines.append('')
40 42 return lines
41 43
42 44 def render_markdown(self, cell):
43 45 return [cell.source, '']
44 46
45 47 def render_raw(self, cell):
46 48 if self.raw_as_verbatim:
47 49 return [indent(cell.source), '']
48 50 else:
49 51 return [cell.source, '']
50 52
51 53 def render_pyout(self, output):
52 54 lines = []
53
55
54 56 ## if 'text' in output:
55 57 ## lines.extend(['*Out[%s]:*' % output.prompt_number, ''])
56 58
57 59 # output is a dictionary like object with type as a key
58 60 if 'latex' in output:
59 61 pass
60 62
61 63 if 'text' in output:
62 64 lines.extend(['<pre>', indent(output.text), '</pre>'])
63 65
64 66 lines.append('')
65 67 return lines
66 68
67 69 def render_pyerr(self, output):
68 70 # Note: a traceback is a *list* of frames.
69 71 return [indent(remove_ansi('\n'.join(output.traceback))), '']
70 72
71 73 def _img_lines(self, img_file):
72 74 return ['', '![](%s)' % img_file, '']
73
75
74 76 def render_display_format_text(self, output):
75 77 return [indent(output.text)]
76 78
77 79 def _unknown_lines(self, data):
78 80 return ['Warning: Unknown cell', data]
79 81
80 82 def render_display_format_html(self, output):
81 83 return [output.html]
82 84
83 85 def render_display_format_latex(self, output):
84 86 return ['LaTeX::', indent(output.latex)]
85 87
86 88 def render_display_format_json(self, output):
87 89 return ['JSON:', indent(output.json)]
88 90
89 91 def render_display_format_javascript(self, output):
90 92 return ['JavaScript:', indent(output.javascript)]
@@ -1,83 +1,83 b''
1 1 import os
2 2 from converters.base import Converter
3 3 from converters.utils import cell_to_lines
4 4 from shutil import rmtree
5 5 import json
6 6
7
7 8 class ConverterNotebook(Converter):
8 9 """
9 10 A converter that is essentially a null-op.
10 11 This exists so it can be subclassed
11 12 for custom handlers of .ipynb files
12 13 that create new .ipynb files.
13 14
14 15 What distinguishes this from JSONWriter is that
15 16 subclasses can specify what to do with each type of cell.
16 17
17 18 Writes out a notebook file.
18 19
19 20 """
20 21 extension = 'ipynb'
21 22
22 23 def __init__(self, infile, outbase):
23 24 Converter.__init__(self, infile)
24 25 self.outbase = outbase
25 26 rmtree(self.files_dir)
26 27
27 28 def convert(self):
28 return unicode(json.dumps(json.loads(Converter.convert(self, ',')), indent=1, sort_keys=True))
29 return unicode(json.dumps(json.loads(Converter.convert(self, ',')),
30 indent=1, sort_keys=True))
29 31
30 32 def optional_header(self):
31 33 s = \
32 34 """{
33 35 "metadata": {
34 36 "name": "%(name)s"
35 37 },
36 38 "nbformat": 3,
37 39 "worksheets": [
38 40 {
39 41 "cells": [""" % {'name': os.path.basename(self.outbase)}
40
41 42 return s.split('\n')
42 43
43 44 def optional_footer(self):
44 45 s = \
45 46 """]
46 47 }
47 48 ]
48 49 }"""
49 50 return s.split('\n')
50 51
51 52 def render_heading(self, cell):
52 53 return cell_to_lines(cell)
53 54
54 55 def render_code(self, cell):
55 56 return cell_to_lines(cell)
56 57
57 58 def render_markdown(self, cell):
58 59 return cell_to_lines(cell)
59 60
60 61 def render_raw(self, cell):
61 62 return cell_to_lines(cell)
62 63
63 64 def render_pyout(self, output):
64 65 return cell_to_lines(output)
65 66
66 67 def render_pyerr(self, output):
67 68 return cell_to_lines(output)
68 69
69 70 def render_display_format_text(self, output):
70 71 return [output.text]
71 72
72 73 def render_display_format_html(self, output):
73 74 return [output.html]
74 75
75 76 def render_display_format_latex(self, output):
76 77 return [output.latex]
77 78
78 79 def render_display_format_json(self, output):
79 80 return [output.json]
80 81
81
82 82 def render_display_format_javascript(self, output):
83 83 return [output.javascript]
@@ -1,99 +1,100 b''
1 1 from converters.base import Converter
2 2 from IPython.utils.text import indent
3 3 from converters.utils import remove_ansi
4 4
5
5 6 class ConverterPy(Converter):
6 7 """
7 8 A converter that takes a notebook and converts it to a .py file.
8 9
9 10 What distinguishes this from PyWriter and PyReader in IPython.nbformat is
10 11 that subclasses can specify what to do with each type of cell.
11 12 Additionally, unlike PyWriter, this does not preserve the '# <markdown>'
12 13 opening and closing comments style comments in favor of a cleaner looking
13 14 python program.
14 15
15 16 Note:
16 17 Even though this produces a .py file, it is not guaranteed to be valid
17 18 python file, since the notebook may be using magics and even cell
18 19 magics.
19 20 """
20 21 extension = 'py'
21 22
22 23 def __init__(self, infile, show_prompts=True, show_output=True):
23 24 super(ConverterPy, self).__init__(infile)
24 25 self.show_prompts = show_prompts
25 26 self.show_output = show_output
26 27
27 28 @staticmethod
28 29 def comment(input):
29 30 "returns every line in input as commented out"
30 return "# "+input.replace("\n", "\n# ")
31 return "# " + input.replace("\n", "\n# ")
31 32
32 33 def render_heading(self, cell):
33 return ['#{0} {1}'.format('#'*cell.level, cell.source), '']
34 return ['#{0} {1}'.format('#' * cell.level, cell.source), '']
34 35
35 36 def render_code(self, cell):
36 37 if not cell.input:
37 38 return []
38 39 lines = []
39 40 if self.show_prompts:
40 41 lines.extend(['# In[%s]:' % cell.prompt_number])
41 42 src = cell.input
42 43 lines.extend([src, ''])
43 44 if self.show_output:
44 if cell.outputs :
45 if cell.outputs:
45 46 lines.extend(['# Out[%s]:' % cell.prompt_number])
46 47 for output in cell.outputs:
47 48 conv_fn = self.dispatch(output.output_type)
48 49 lines.extend(conv_fn(output))
49 50 return lines
50 51
51 52 def render_markdown(self, cell):
52 53 return [self.comment(cell.source), '']
53 54
54 55 def render_raw(self, cell):
55 56 if self.raw_as_verbatim:
56 57 return [self.comment(indent(cell.source)), '']
57 58 else:
58 59 return [self.comment(cell.source), '']
59 60
60 61 def render_pyout(self, output):
61 62 lines = []
62 63
63 64 ## if 'text' in output:
64 65 ## lines.extend(['*Out[%s]:*' % output.prompt_number, ''])
65 66
66 67 # output is a dictionary like object with type as a key
67 68 if 'latex' in output:
68 69 pass
69 70
70 71 if 'text' in output:
71 72 lines.extend([self.comment(indent(output.text)), ''])
72 73
73 74 lines.append('')
74 75 return lines
75 76
76 77 def render_pyerr(self, output):
77 78 # Note: a traceback is a *list* of frames.
78 79 return [indent(remove_ansi('\n'.join(output.traceback))), '']
79 80
80 81 def _img_lines(self, img_file):
81 return [ self.comment('image file: %s' % img_file), '']
82 return [self.comment('image file: %s' % img_file), '']
82 83
83 84 def render_display_format_text(self, output):
84 85 return [self.comment(indent(output.text))]
85 86
86 87 def _unknown_lines(self, data):
87 return [self.comment('Warning: Unknown cell'+ str(data))]
88 return [self.comment('Warning: Unknown cell' + str(data))]
88 89
89 90 def render_display_format_html(self, output):
90 91 return [self.comment(output.html)]
91 92
92 93 def render_display_format_latex(self, output):
93 94 return []
94 95
95 96 def render_display_format_json(self, output):
96 97 return []
97 98
98 99 def render_display_format_javascript(self, output):
99 100 return []
@@ -1,27 +1,27 b''
1 1 """
2 2 This module gives a simple example of a custom notebook converter that only
3 3 captures display data and deletes the cell inputs.
4 4 """
5 5
6 6 import copy
7 7 import nbconvert as nb
8 8
9
9 10 class CustomNotebookConverter(nb.ConverterNotebook):
10 11
11 12 def render_code(self, cell):
12 13
13 14 captured_outputs = ['text', 'html', 'svg', 'latex', 'javascript']
14 15
15 16 cell = copy.deepcopy(cell)
16 17 cell['input'] = ''
17 18
18 19 for output in cell.outputs:
19 20 if output.output_type != 'display_data':
20 21 cell.outputs.remove(output)
21 22 return nb.ConverterNotebook.render_code(self, cell)
22 23
23 24 if __name__ == '__main__':
24 25 infile = 'tests/test_display.ipynb'
25 26 converter = CustomNotebookConverter(infile, 'test_only_display')
26 27 converter.render()
27
@@ -1,88 +1,97 b''
1 1 # dollarmath.py by Akihiro Uchida *public domain*
2 2 # the original one is written by Paul Kienzle
3 3 # and published as public domain in [sphinx-dev]: $math$ extension
4 4 r"""
5 5 Allow $math$ markup in text and docstrings, ignoring \$.
6 6
7 7 The $math$ markup should be separated from the surrounding text by spaces.
8 8 To embed markup within a word, place backslash-space before and after.
9 9 For convenience, the final $ can be followed by punctuation
10 10 (period, comma or semicolon).
11 11 """
12 12
13 13 import re
14 14
15 15 dollar_pat = r"(?:^|(?<=\s))[$]([^\n]*?)(?<![\\])[$](?:$|(?=\s|[.,;\\]))"
16 16 _dollar = re.compile(dollar_pat)
17 17 _notdollar = re.compile(r"\\[$]")
18 18
19
19 20 def replace_dollar(content):
20 21 content = _dollar.sub(r":math:`\1`", content)
21 22 content = _notdollar.sub("$", content)
22 23 return content
23 24
25
24 26 def rewrite_rst(app, docname, source):
25 27 source[0] = replace_dollar(source[0])
26 28
29
27 30 def rewrite_autodoc(app, what, name, obj, options, lines):
28 31 lines[:] = [replace_dollar(L) for L in lines]
29 32
33
30 34 def setup(app):
31 35 app.connect('source-read', rewrite_rst)
32 36 if 'autodoc-process-docstring' in app._events:
33 37 app.connect('autodoc-process-docstring', rewrite_autodoc)
34 38
39
35 40 def test_expr(expr, expect):
36 41 result = replace_dollar(expr)
37 42 print 'A math expression: %s' % expr
38 43 print 'A expected output: %s' % expect
39 44 if result == expect:
40 45 print 'OK: A result match expected one'
41 46 else:
42 47 print 'NG: A result %s does not match expected one!' % result
43 48
49
44 50 def test_dollar():
45 51 samples = {
46 52 u"no dollar": u"no dollar",
47 53 u"$only$": u":math:`only`",
48 54 u"$first$ is good": u":math:`first` is good",
49 55 u"so is $last$": u"so is :math:`last`",
50 56 u"and $mid$ too": u"and :math:`mid` too",
51 57 u"$first$, $mid$, $last$": u":math:`first`, :math:`mid`, :math:`last`",
52 58 u"dollar\$ escape": u"dollar$ escape",
53 59 u"dollar \$escape\$ too": u"dollar $escape$ too",
54 60 u"emb\ $ed$\ ed": u"emb\ :math:`ed`\ ed",
55 61 u"$first$a": u"$first$a",
56 62 u"a$last$": u"a$last$",
57 63 u"a $mid$dle a": u"a $mid$dle a",
58 64 }
59 65 for expr, expect in samples.items():
60 66 test_expr(expr, expect)
61 67
68
62 69 if __name__ == "__main__":
63 import sys, locale, codecs
70 import sys
71 import locale
72 import codecs
64 73 encoding = locale.getpreferredencoding()
65 74 sys.stdout = codecs.getwriter(encoding)(sys.stdout)
66 75 sys.stdin = codecs.getreader(encoding)(sys.stdin)
67 76
68 77 import optparse
69 78 parser = optparse.OptionParser(usage='usage: %prog [options]')
70 79 parser.add_option("-i", "--input", dest="expr", type="string",
71 80 help="input $math$ expression to test")
72 81 parser.add_option("-o", "--output", dest="expect", type="string",
73 82 help="output result you expect")
74 83
75 84 opts, args = parser.parse_args()
76 85 if opts.expr:
77 86 expression = unicode(opts.expr, encoding)
78 87 if opts.expect:
79 88 expected = unicode(opts.expect, encoding)
80 89 test_expr(expression, expected)
81 90 else:
82 91 print replace_dollar(expression)
83 92 else:
84 93 if opts.expect:
85 94 parser.print_help()
86 95 parser.error("output option requires input expression")
87 96 else:
88 97 test_dollar()
@@ -1,78 +1,79 b''
1 1 #!/usr/bin/env python
2 2 """Convert IPython notebooks to other formats, such as ReST, and HTML.
3 3
4 4 Example:
5 5 ./nbconvert.py --format rst file.ipynb
6 6
7 7 Produces 'file.rst', along with auto-generated figure files
8 8 called nb_figure_NN.png.
9 9 """
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13 from __future__ import print_function
14 14
15 15 # From IPython
16 16 from IPython.external import argparse
17 17
18 18 # local
19 19 from converters.html import ConverterHTML
20 20 from converters.markdown import ConverterMarkdown
21 21 from converters.bloggerhtml import ConverterBloggerHTML
22 22 from converters.rst import ConverterRST
23 23 from converters.latex import ConverterLaTeX
24 24 from converters.python import ConverterPy
25 25
26 26
27 27 # When adding a new format, make sure to add it to the `converters`
28 28 # dictionary below. This is used to create the list of known formats,
29 29 # which gets printed in case an unknown format is encounteres, as well
30 30 # as in the help
31 31
32 32 converters = {
33 33 'rst': ConverterRST,
34 34 'markdown': ConverterMarkdown,
35 35 'html': ConverterHTML,
36 36 'blogger-html': ConverterBloggerHTML,
37 37 'latex': ConverterLaTeX,
38 38 'py': ConverterPy,
39 39 }
40 40
41 41 default_format = 'rst'
42 42
43 43 # Extract the list of known formats and mark the first format as the default.
44 44 known_formats = ', '.join([key + " (default)" if key == default_format else key
45 45 for key in converters])
46 46
47 47
48 48
49 49 def main(infile, format='rst'):
50 50 """Convert a notebook to html in one step"""
51 51
52 52 try:
53 53 ConverterClass = converters[format]
54 54 except KeyError:
55 55 raise SystemExit("Unknown format '%s', " % format +
56 56 "known formats are: " + known_formats)
57 57
58 58 converter = ConverterClass(infile)
59 59 converter.render()
60 60
61 61 #-----------------------------------------------------------------------------
62 62 # Script main
63 63 #-----------------------------------------------------------------------------
64 64
65 65 if __name__ == '__main__':
66 66 parser = argparse.ArgumentParser(description=__doc__,
67 67 formatter_class=argparse.RawTextHelpFormatter)
68 68 # TODO: consider passing file like object around, rather than filenames
69 69 # would allow us to process stdin, or even http streams
70 #parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
70 #parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
71 # default=sys.stdin)
71 72
72 73 #Require a filename as a positional argument
73 74 parser.add_argument('infile', nargs=1)
74 75 parser.add_argument('-f', '--format', default='rst',
75 76 help='Output format. Supported formats: \n' +
76 77 known_formats)
77 78 args = parser.parse_args()
78 79 main(infile=args.infile[0], format=args.format)
@@ -1,124 +1,123 b''
1 1 """
2 2 Simple ipython notebook document tree Writer.
3 3
4 4 """
5 5
6 6 __docformat__ = 'reStructuredText'
7 7
8 8
9 9 import sys
10 10 import os
11 11 import os.path
12 12 import time
13 13 import re
14 14 import urllib
15 15 import docutils
16 16 from docutils import frontend, nodes, utils, writers, languages, io
17 17 from docutils.error_reporting import SafeString
18 18 from docutils.transforms import writer_aux
19 19 from docutils.math import unichar2tex, pick_math_environment
20 20 from docutils.math.latex2mathml import parse_latex_math
21 21 from docutils.math.math2html import math2html
22 22 from IPython.nbformat import current as nbformat
23 23
24 24
25 25 class Writer(writers.Writer):
26 26
27 27 supported = ('ipynb')
28 28 """Formats this writer supports."""
29 29
30 30 visitor_attributes = ()
31 31
32 32 def get_transforms(self):
33 33 return writers.Writer.get_transforms(self) + [writer_aux.Admonitions]
34 34
35 35 def __init__(self):
36 36 writers.Writer.__init__(self)
37 37 self.translator_class = IPYNBTranslator
38 38
39 39 def translate(self):
40 40 self.visitor = visitor = self.translator_class(self.document)
41 41 self.document.walkabout(visitor)
42 42 for attr in self.visitor_attributes:
43 43 setattr(self, attr, getattr(visitor, attr))
44 44 self.output = '{0}'.format(nbformat.writes(visitor.nb, 'ipynb'))
45 45
46 46
47 47 class IPYNBTranslator(nodes.GenericNodeVisitor):
48 48
49 49 """
50 50 """
51 51
52 52 def __init__(self, document):
53 53 nodes.NodeVisitor.__init__(self, document)
54 54 self.settings = settings = document.settings
55 55 lcode = settings.language_code
56 56 self.language = languages.get_language(lcode, document.reporter)
57 57 # A heterogenous stack used in conjunction with the tree traversal.
58 58 # Make sure that the pops correspond to the pushes:
59 59 self.context = []
60 60 self.body = []
61 61 self.section_level = 0
62 62 ws = nbformat.new_worksheet()
63 63 self.nb = nbformat.new_notebook(worksheets=[ws])
64 64
65 65 def astext(self):
66 66 return '{0}'.format(nbformat.writes(self.nb, 'ipynb'))
67 67
68 68 def is_ref_error_paragraph(self, p):
69 69 return p == "Unknown interpreted text role \"ref\"."
70 70
71 71 def add_cell(self, cell):
72 72 self.nb.worksheets[0].cells.append(cell)
73 73
74 74 def visit_literal_block(self, node):
75 75 raw_text = node.astext()
76 76 #only include lines that begin with >>>
77 77 #we want the example code and not the example output
78 78 processed_text = '\n'.join([line.split('>>>')[1][1:]
79 79 for line in raw_text.split('\n')
80 80 if line.startswith('>>>')])
81 81 c = nbformat.new_code_cell(input=processed_text)
82 82 self.add_cell(c)
83 83
84 84 def visit_paragraph(self, node):
85 85 text = node.astext()
86 86 # For every ref directive a paragraph contains
87 87 # docutils will generate a paragraph complaining
88 88 # "Unknown interpreted text role \"ref\"."
89 89 # this is because ref is a sphinx directive
90 90 # that does not exist in docutils
91 91 # looking for a better way to handle this
92 92 # for now filtering such pargraphs from the output
93 93
94 94 if not self.is_ref_error_paragraph(text):
95 95 p = nbformat.new_text_cell('markdown', source=text)
96 96 self.add_cell(p)
97 97
98
99 98 def visit_section(self, node):
100 99 self.section_level += 1
101 100 self.default_visit(node)
102 101
103 102 def depart_section(self, node):
104 103 self.section_level -= 1
105 104 self.default_departure(node)
106 105
107 106 def visit_title(self, node):
108 107 #make sure we have a valid heading level between 1 and 6
109 108 heading_level = min(self.section_level, 5) + 1
110 109 h = nbformat.new_heading_cell(source=node.astext(),
111 110 level=heading_level)
112 111 self.add_cell(h)
113 112
114 113 def default_visit(self, node):
115 114 node_class = node.__class__.__name__
116 115 #print '*default_visit', node_class
117 116 #if node_class in ['reference','paragraph','literal_block','title']:
118 117 if node_class in []:
119 118 print '*default_visit', node_class
120 119 print node.astext()
121 120
122 121 def default_departure(self, node):
123 122 #print '*default depart', node.__class__.__name__
124 123 pass
@@ -1,35 +1,33 b''
1 1 from nbconvert import ConverterNotebook
2 2 import nose.tools as nt
3 3 import os
4 4 import json
5 5 import shutil
6 6 import tempfile
7 7
8 8
9 9 # name = os.path.join(os.path.dirname(os.path.abspath(__file__), test.ipynb')
10 10 outbase1 = 'newtest1'
11 11 outbase2 = 'test' # will output to ./test.ipynb
12 12
13 13
14 14 def test_roundtrip():
15 15 directory = tempfile.mkdtemp()
16 16 out1 = os.path.join(directory, outbase1)
17 17 out2 = os.path.join(directory, outbase2)
18 18 fname = os.path.join(os.path.dirname(os.path.abspath(__file__)),
19 19 'test.ipynb')
20 20 converter = ConverterNotebook(fname, out1)
21 21 converter.render()
22
23 22 converter2 = ConverterNotebook(out1 + '.ipynb', out2)
24 23 converter2.render()
25 24
26 25 with open(out1 + '.ipynb', 'rb') as f:
27 26 s1 = f.read()
28 27 with open(out2 + '.ipynb', 'rb') as f:
29 28 s2 = f.read()
30 29
31 30 nt.assert_true(s1.replace(outbase1, outbase2) == s2)
32 31 shutil.rmtree(directory)
33
34 32 s0 = json.dumps(json.load(file(fname)), indent=1, sort_keys=True)
35 33 nt.assert_true(s0 == s2)
@@ -1,47 +1,47 b''
1 1 import io
2 2 import nose.tools as nt
3 from nbconvert import (
3 from nose.tools import nottest
4 from converts import (
4 5 ConverterLaTeX, ConverterMarkdown, ConverterPy, ConverterHTML
5 6 )
6 from nose.tools import nottest
7 7
8 8
9 9 def test_evens():
10 10 ######
11 11 # for now, we don't need to really run inkscape to extract svg
12 12 # from file, on unix, for test, we monkeypathc it to 'true'
13 13 # which does not fail as doing anything.
14 14 ####
15 15 ConverterLaTeX.inkscape = 'true'
16 16
17 17 # commenting rst for now as travis build
18 18 # fail because of pandoc version.
19 19 converters = [
20 #(ConverterRST,'rst'),
20 #(ConverterRST, 'rst'),
21 21 (ConverterMarkdown, 'md'),
22 22 (ConverterLaTeX, 'tex'),
23 23 (ConverterPy, 'py'),
24 24 (ConverterHTML, 'html')
25 25 ]
26 26 reflist = [
27 27 'tests/ipynbref/IntroNumPy.orig'
28 28 ]
29 29 for root in reflist:
30 30 for conv, ext in converters:
31 31 yield test_conversion, conv, root + '.ipynb', root + '.' + ext
32 32
33 33
34 34 @nottest
35 35 def compfiles(stra, strb):
36 36 nt.assert_equal(map(unicode.strip, stra.split('\n')),
37 37 map(unicode.strip, strb.split('\n')))
38 38
39 39
40 40 @nottest
41 41 def test_conversion(ConverterClass, ipynb, ref_file):
42 42 converter = ConverterClass(ipynb)
43 43 converter.read()
44 44 cv = converter.convert()
45 45 with io.open(ref_file) as ref:
46 46 value = ref.read()
47 47 compfiles(cv, value)
@@ -1,71 +1,71 b''
1 1 from nbconvert import ConverterRST, main
2 2 import nose.tools as nt
3 3
4 4 import os
5 5 import glob
6 6 from IPython.nbformat import current as nbformat
7 7
8 8 fname = 'tests/test.ipynb'
9 9 out_fname = 'tests/test.rst'
10 10
11 11
12 12 def clean_dir():
13 13 "Remove .rst files created during conversion"
14 14 map(os.remove, glob.glob("./tests/*.rst"))
15 15 map(os.remove, glob.glob("./tests/*.png"))
16 16 map(os.remove, glob.glob("./tests/*.html"))
17 17 map(os.remove, glob.glob("./tests/test_files/*"))
18 18
19 19
20 20 @nt.with_setup(clean_dir, clean_dir)
21 21 def test_simple():
22 22 c = ConverterRST(fname)
23 23 f = c.render()
24 24 nt.assert_true(f.endswith('.rst'), 'changed file extension to rst')
25 25
26 26
27 27 @nt.with_setup(clean_dir, clean_dir)
28 28 def test_main():
29 29 """
30 30 Test main entry point
31 31 """
32 32 main(fname)
33 33 nt.assert_true(os.path.exists(out_fname))
34 34
35 35
36 36 def test_render_heading():
37 37 """ Unit test for cell type "heading" """
38 38 # Generate and test heading cells level 1-6
39 39 for level in xrange(1, 7):
40 40 cell = {
41 41 'cell_type': 'heading',
42 42 'level': level,
43 'source': ['Test for heading type H{0}'.format(level)]
43 'source': ['Test for heading type H{0}'.format(level)]
44 44 }
45 45 # Convert cell dictionaries to NotebookNode
46 46 cell_nb = nbformat.NotebookNode(cell)
47 47 # Make sure "source" attribute is uniconde not list.
48 48 # For some reason, creating a NotebookNode manually like
49 49 # this isn't converting source to a string like using
50 50 # the create-from-file routine.
51 51 if type(cell_nb.source) is list:
52 52 cell_nb.source = '\n'.join(cell_nb.source)
53 53 # Render to rst
54 54 c = ConverterRST('')
55 55 rst_list = c.render_heading(cell_nb)
56 56 # render should return a list
57 57 nt.assert_true(isinstance(rst_list, list))
58 58 rst_str = "".join(rst_list)
59 59 # Confirm rst content
60 60 chk_str = "Test for heading type H{0}\n{1}\n".format(
61 61 level, c.heading_level[level] * 24)
62 62 nt.assert_equal(rst_str, chk_str)
63 63
64 64
65 65 @nt.with_setup(clean_dir, clean_dir)
66 66 def test_main_html():
67 67 """
68 68 Test main entry point
69 69 """
70 70 main(fname, format='html')
71 71 nt.assert_true(os.path.exists('tests/test.html'))
General Comments 0
You need to be logged in to leave comments. Login now