Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f1fa998

Browse files
committed
refactored nbconvert, nosetest pass
joint work with @jeremiahbuddha and @aisipos
1 parent 11a46b5 commit f1fa998

3 files changed

Lines changed: 125 additions & 82 deletions

File tree

nbconvert.py

Lines changed: 106 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -27,117 +27,141 @@ def unknown_cell(cell):
2727
return rst_directive('.. warning:: Unknown cell') + \
2828
[repr(cell)]
2929

30-
def heading_cell(cell):
31-
"""convert a heading cell to rst
32-
33-
Returns list."""
34-
heading_level = {1:'=', 2:'-', 3:'`', 4:'\'', 5:'.',6:'~'}
35-
marker = heading_level[cell.level]
36-
return ['{0}\n{1}\n'.format(cell.source, marker*len(cell.source))]
37-
38-
def markdown_cell(cell):
39-
"""convert a markdown cell to rst
40-
41-
Returns list."""
42-
return [cell.source]
43-
4430

4531
def rst_directive(directive, text=''):
4632
out = [directive, '']
4733
if text:
4834
out.extend([indent(text), ''])
4935
return out
5036

51-
def code_cell(cell):
52-
"""Convert a code cell to rst
53-
54-
Returns list."""
55-
56-
if not cell.input:
57-
return []
58-
59-
lines = ['In[%s]:' % cell.prompt_number, '']
60-
lines.extend(rst_directive('.. code:: python', cell.input))
61-
62-
for output in cell.outputs:
63-
conv = converters.get(output.output_type, unknown_cell)
64-
lines.extend(conv(output))
65-
66-
return lines
67-
6837
# Converters for parts of a cell.
6938
figures_counter = 1
7039

71-
def out_display(output):
72-
"""convert display data from the output of a code cell to rst.
40+
class ConversionException(Exception):
41+
pass
42+
43+
class Converter(object):
44+
default_encoding = 'utf-8'
45+
def __init__(self, fname):
46+
self.fname = fname
47+
48+
@property
49+
def extension(self):
50+
raise ConversionException("""extension must be defined in Converter
51+
subclass""")
52+
53+
def dispatch(self,cell_type):
54+
"""return cell_type dependent render method, for example render_code
55+
"""
56+
return getattr(self, 'render_'+cell_type, unknown_cell)
57+
58+
def convert(self):
59+
lines = []
60+
for cell in self.nb.worksheets[0].cells:
61+
conv_fn = self.dispatch(cell.cell_type)
62+
lines.extend(conv_fn(cell))
63+
lines.append('')
64+
return '\n'.join(lines)
65+
66+
def render(self):
67+
"read, convert, and save self.fname"
68+
self.read()
69+
self.output = self.convert()
70+
return self.save()
71+
72+
def read(self):
73+
"read and parse notebook into NotebookNode called self.nb"
74+
with open(self.fname) as f:
75+
self.nb = nbformat.read(f, 'json')
76+
77+
def save(self,fname=None, encoding=None):
78+
"read and parse notebook into self.nb"
79+
if fname is None:
80+
fname = os.path.splitext(self.fname)[0] + '.' + self.extension
81+
if encoding is None:
82+
encoding = self.default_encoding
83+
with open(fname, 'w') as f:
84+
f.write(self.output.encode(encoding))
85+
return fname
7386

74-
Returns list.
75-
"""
76-
global figures_counter
87+
def render_heading(self,cell):
88+
raise NotImplementedError
89+
def render_code(self,cell):
90+
raise NotImplementedError
91+
def render_markdown(self,cell):
92+
raise NotImplementedError
93+
def render_pyout(self,cell):
94+
raise NotImplementedError
95+
def render_display_data(self,cell):
96+
raise NotImplementedError
7797

78-
lines = []
98+
class ConverterRST(Converter):
99+
extension = 'rst'
100+
def render_heading(self,cell):
101+
"""convert a heading cell to rst
79102
80-
if 'png' in output:
81-
fname = 'nb_figure_%s.png' % figures_counter
82-
with open(fname, 'w') as f:
83-
f.write(output.png.decode('base64'))
103+
Returns list."""
104+
heading_level = {1:'=', 2:'-', 3:'`', 4:'\'', 5:'.',6:'~'}
105+
marker = heading_level[cell.level]
106+
return ['{0}\n{1}\n'.format(cell.source, marker*len(cell.source))]
84107

85-
figures_counter += 1
86-
lines.append('.. image:: %s' % fname)
87-
lines.append('')
88-
89-
return lines
108+
def render_code(self,cell):
109+
"""Convert a code cell to rst
90110
91-
92-
def out_pyout(output):
93-
"""convert pyout part of a code cell to rst
111+
Returns list."""
94112

95-
Returns list."""
113+
if not cell.input:
114+
return []
96115

97-
lines = ['Out[%s]:' % output.prompt_number, '']
98-
99-
if 'latex' in output:
100-
lines.extend(rst_directive('.. math::', output.latex))
116+
lines = ['In[%s]:' % cell.prompt_number, '']
117+
lines.extend(rst_directive('.. code:: python', cell.input))
101118

102-
if 'text' in output:
103-
lines.extend(rst_directive('.. parsed-literal::', output.text))
119+
for output in cell.outputs:
120+
conv_fn = self.dispatch(output.output_type)
121+
lines.extend(conv_fn(output))
104122

105-
return lines
123+
return lines
106124

125+
def render_markdown(self,cell):
126+
"""convert a markdown cell to rst
107127
108-
converters = dict(heading = heading_cell,
109-
code = code_cell,
110-
markdown = markdown_cell,
111-
pyout = out_pyout,
112-
display_data = out_display,
113-
)
128+
Returns list."""
129+
return [cell.source]
114130

131+
def render_pyout(self,output):
132+
"""convert pyout part of a code cell to rst
115133
134+
Returns list."""
116135

117-
def convert_notebook(nb):
118-
lines = []
119-
for cell in nb.worksheets[0].cells:
120-
conv = converters.get(cell.cell_type, unknown_cell)
121-
lines.extend(conv(cell))
122-
lines.append('')
123-
124-
return '\n'.join(lines)
136+
lines = ['Out[%s]:' % output.prompt_number, '']
137+
138+
if 'latex' in output:
139+
lines.extend(rst_directive('.. math::', output.latex))
125140

141+
if 'text' in output:
142+
lines.extend(rst_directive('.. parsed-literal::', output.text))
126143

127-
def nb2rst(fname):
128-
"Convert notebook to rst"
129-
130-
with open(fname) as f:
131-
nb = nbformat.read(f, 'json')
144+
return lines
132145

133-
rst = convert_notebook(nb)
146+
def render_display_data(self,output):
147+
"""convert display data from the output of a code cell to rst.
134148
135-
newfname = os.path.splitext(fname)[0] + '.rst'
136-
with open(newfname, 'w') as f:
137-
f.write(rst.encode('utf8'))
149+
Returns list.
150+
"""
151+
global figures_counter
138152

139-
return newfname
153+
lines = []
154+
155+
if 'png' in output:
156+
fname = 'nb_figure_%s.png' % figures_counter
157+
with open(fname, 'w') as f:
158+
f.write(output.png.decode('base64'))
140159

160+
figures_counter += 1
161+
lines.append('.. image:: %s' % fname)
162+
lines.append('')
163+
164+
return lines
141165

142166
def rst2simplehtml(fname):
143167
"""Convert a rst file to simplified html suitable for blogger.
@@ -191,7 +215,7 @@ def rst2simplehtml(fname):
191215
def main(fname):
192216
"""Convert a notebook to html in one step"""
193217
newfname = nb2rst(fname)
194-
rst2simplehtml(newfname)
218+
#rst2simplehtml(newfname)
195219

196220

197221
if __name__ == '__main__':
File renamed without changes.

tests/test_simple.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from nbconvert import ConverterRST
2+
import nose.tools as nt
3+
4+
import os
5+
import glob
6+
7+
def clean_dir():
8+
"Remove .rst files created during conversion"
9+
map(os.remove, glob.glob("*.rst"))
10+
map(os.remove, glob.glob("*.png"))
11+
12+
13+
@nt.with_setup(clean_dir, clean_dir)
14+
def test_simple():
15+
fname = 'test.ipynb'
16+
c = ConverterRST(fname)
17+
f = c.render()
18+
nt.assert_true('rst' in f, 'changed file extension to rst')
19+

0 commit comments

Comments
 (0)