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 | 27 | return rst_directive('.. warning:: Unknown cell') + \ |
|
28 | 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 | 31 | def rst_directive(directive, text=''): |
|
46 | 32 | out = [directive, ''] |
@@ -48,96 +34,134 b" def rst_directive(directive, text=''):" | |||
|
48 | 34 | out.extend([indent(text), '']) |
|
49 | 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 | 37 | # Converters for parts of a cell. |
|
69 | 38 | figures_counter = 1 |
|
70 | 39 | |
|
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 | |
|
73 | 86 | |
|
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 | |
|
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: | |
|
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))] | |
|
84 | 107 | |
|
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 | |
|
90 | 110 |
|
|
91 | ||
|
92 | def out_pyout(output): | |
|
93 | """convert pyout part of a code cell to rst | |
|
111 | Returns list.""" | |
|
94 | 112 | |
|
95 | Returns list.""" | |
|
113 | if not cell.input: | |
|
114 | return [] | |
|
96 | 115 | |
|
97 |
lines = [' |
|
|
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)) | |
|
101 | 118 | |
|
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)) | |
|
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, | |
|
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] | |
|
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): | |
|
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)) | |
|
125 | 140 | |
|
141 | if 'text' in output: | |
|
142 | lines.extend(rst_directive('.. parsed-literal::', output.text)) | |
|
126 | 143 | |
|
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 | |
|
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' | |
|
136 | with open(newfname, 'w') as f: | |
|
137 | f.write(rst.encode('utf8')) | |
|
149 | Returns list. | |
|
150 | """ | |
|
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 | 166 | def rst2simplehtml(fname): |
|
143 | 167 | """Convert a rst file to simplified html suitable for blogger. |
@@ -191,7 +215,7 b' def rst2simplehtml(fname):' | |||
|
191 | 215 | def main(fname): |
|
192 | 216 | """Convert a notebook to html in one step""" |
|
193 | 217 | newfname = nb2rst(fname) |
|
194 | rst2simplehtml(newfname) | |
|
218 | #rst2simplehtml(newfname) | |
|
195 | 219 | |
|
196 | 220 | |
|
197 | 221 | if __name__ == '__main__': |
|
1 | 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