##// END OF EJS Templates
refactored nbconvert, nosetest pass...
Paul Ivanov -
Show More
@@ -0,0 +1,19 b''
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
@@ -27,20 +27,6 b' def unknown_cell(cell):'
27 return rst_directive('.. warning:: Unknown cell') + \
27 return rst_directive('.. warning:: Unknown cell') + \
28 [repr(cell)]
28 [repr(cell)]
29
29
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
44
30
45 def rst_directive(directive, text=''):
31 def rst_directive(directive, text=''):
46 out = [directive, '']
32 out = [directive, '']
@@ -48,96 +34,134 b" def rst_directive(directive, text=''):"
48 out.extend([indent(text), ''])
34 out.extend([indent(text), ''])
49 return out
35 return out
50
36
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
68 # Converters for parts of a cell.
37 # Converters for parts of a cell.
69 figures_counter = 1
38 figures_counter = 1
70
39
71 def out_display(output):
40 class ConversionException(Exception):
72 """convert display data from the output of a code cell to rst.
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
73
86
74 Returns list.
87 def render_heading(self,cell):
75 """
88 raise NotImplementedError
76 global figures_counter
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
77
97
78 lines = []
98 class ConverterRST(Converter):
99 extension = 'rst'
100 def render_heading(self,cell):
101 """convert a heading cell to rst
79
102
80 if 'png' in output:
103 Returns list."""
81 fname = 'nb_figure_%s.png' % figures_counter
104 heading_level = {1:'=', 2:'-', 3:'`', 4:'\'', 5:'.',6:'~'}
82 with open(fname, 'w') as f:
105 marker = heading_level[cell.level]
83 f.write(output.png.decode('base64'))
106 return ['{0}\n{1}\n'.format(cell.source, marker*len(cell.source))]
84
107
85 figures_counter += 1
108 def render_code(self,cell):
86 lines.append('.. image:: %s' % fname)
109 """Convert a code cell to rst
87 lines.append('')
88
89 return lines
90
110
91
111 Returns list."""
92 def out_pyout(output):
93 """convert pyout part of a code cell to rst
94
112
95 Returns list."""
113 if not cell.input:
114 return []
96
115
97 lines = ['Out[%s]:' % output.prompt_number, '']
116 lines = ['In[%s]:' % cell.prompt_number, '']
98
117 lines.extend(rst_directive('.. code:: python', cell.input))
99 if 'latex' in output:
100 lines.extend(rst_directive('.. math::', output.latex))
101
118
102 if 'text' in output:
119 for output in cell.outputs:
103 lines.extend(rst_directive('.. parsed-literal::', output.text))
120 conv_fn = self.dispatch(output.output_type)
121 lines.extend(conv_fn(output))
104
122
105 return lines
123 return lines
106
124
125 def render_markdown(self,cell):
126 """convert a markdown cell to rst
107
127
108 converters = dict(heading = heading_cell,
128 Returns list."""
109 code = code_cell,
129 return [cell.source]
110 markdown = markdown_cell,
111 pyout = out_pyout,
112 display_data = out_display,
113 )
114
130
131 def render_pyout(self,output):
132 """convert pyout part of a code cell to rst
115
133
134 Returns list."""
116
135
117 def convert_notebook(nb):
136 lines = ['Out[%s]:' % output.prompt_number, '']
118 lines = []
137
119 for cell in nb.worksheets[0].cells:
138 if 'latex' in output:
120 conv = converters.get(cell.cell_type, unknown_cell)
139 lines.extend(rst_directive('.. math::', output.latex))
121 lines.extend(conv(cell))
122 lines.append('')
123
124 return '\n'.join(lines)
125
140
141 if 'text' in output:
142 lines.extend(rst_directive('.. parsed-literal::', output.text))
126
143
127 def nb2rst(fname):
144 return lines
128 "Convert notebook to rst"
129
130 with open(fname) as f:
131 nb = nbformat.read(f, 'json')
132
145
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.
134
148
135 newfname = os.path.splitext(fname)[0] + '.rst'
149 Returns list.
136 with open(newfname, 'w') as f:
150 """
137 f.write(rst.encode('utf8'))
151 global figures_counter
138
152
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'))
140
159
160 figures_counter += 1
161 lines.append('.. image:: %s' % fname)
162 lines.append('')
163
164 return lines
141
165
142 def rst2simplehtml(fname):
166 def rst2simplehtml(fname):
143 """Convert a rst file to simplified html suitable for blogger.
167 """Convert a rst file to simplified html suitable for blogger.
@@ -191,7 +215,7 b' def rst2simplehtml(fname):'
191 def main(fname):
215 def main(fname):
192 """Convert a notebook to html in one step"""
216 """Convert a notebook to html in one step"""
193 newfname = nb2rst(fname)
217 newfname = nb2rst(fname)
194 rst2simplehtml(newfname)
218 #rst2simplehtml(newfname)
195
219
196
220
197 if __name__ == '__main__':
221 if __name__ == '__main__':
1 NO CONTENT: file renamed from test.ipynb to tests/test.ipynb
NO CONTENT: file renamed from test.ipynb to tests/test.ipynb
General Comments 0
You need to be logged in to leave comments. Login now