##// END OF EJS Templates
PEP8
David Warde-Farley -
Show More
@@ -1,323 +1,323 b''
1 from __future__ import print_function, absolute_import
1 from __future__ import print_function, absolute_import
2 from converters.utils import remove_fake_files_url
2 from converters.utils import remove_fake_files_url
3
3
4 # Stdlib
4 # Stdlib
5 import codecs
5 import codecs
6 import io
6 import io
7 import logging
7 import logging
8 import os
8 import os
9 import pprint
9 import pprint
10 from types import FunctionType
10 from types import FunctionType
11
11
12 # From IPython
12 # From IPython
13 from IPython.nbformat import current as nbformat
13 from IPython.nbformat import current as nbformat
14
14
15 # local
15 # local
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Class declarations
18 # Class declarations
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 class ConversionException(Exception):
21 class ConversionException(Exception):
22 pass
22 pass
23
23
24 class DocStringInheritor(type):
24 class DocStringInheritor(type):
25 """
25 """
26 This metaclass will walk the list of bases until the desired
26 This metaclass will walk the list of bases until the desired
27 superclass method is found AND if that method has a docstring and only
27 superclass method is found AND if that method has a docstring and only
28 THEN does it attach the superdocstring to the derived class method.
28 THEN does it attach the superdocstring to the derived class method.
29
29
30 Please use carefully, I just did the metaclass thing by following
30 Please use carefully, I just did the metaclass thing by following
31 Michael Foord's Metaclass tutorial
31 Michael Foord's Metaclass tutorial
32 (http://www.voidspace.org.uk/python/articles/metaclasses.shtml), I may
32 (http://www.voidspace.org.uk/python/articles/metaclasses.shtml), I may
33 have missed a step or two.
33 have missed a step or two.
34
34
35 source:
35 source:
36 http://groups.google.com/group/comp.lang.python/msg/26f7b4fcb4d66c95
36 http://groups.google.com/group/comp.lang.python/msg/26f7b4fcb4d66c95
37 by Paul McGuire
37 by Paul McGuire
38 """
38 """
39 def __new__(meta, classname, bases, classDict):
39 def __new__(meta, classname, bases, classDict):
40 newClassDict = {}
40 newClassDict = {}
41 for attributeName, attribute in classDict.items():
41 for attributeName, attribute in classDict.items():
42 if type(attribute) == FunctionType:
42 if type(attribute) == FunctionType:
43 # look through bases for matching function by name
43 # look through bases for matching function by name
44 for baseclass in bases:
44 for baseclass in bases:
45 if hasattr(baseclass, attributeName):
45 if hasattr(baseclass, attributeName):
46 basefn = getattr(baseclass, attributeName)
46 basefn = getattr(baseclass, attributeName)
47 if basefn.__doc__:
47 if basefn.__doc__:
48 attribute.__doc__ = basefn.__doc__
48 attribute.__doc__ = basefn.__doc__
49 break
49 break
50 newClassDict[attributeName] = attribute
50 newClassDict[attributeName] = attribute
51 return type.__new__(meta, classname, bases, newClassDict)
51 return type.__new__(meta, classname, bases, newClassDict)
52
52
53 class Converter(object):
53 class Converter(object):
54 __metaclass__ = DocStringInheritor
54 __metaclass__ = DocStringInheritor
55 default_encoding = 'utf-8'
55 default_encoding = 'utf-8'
56 extension = str()
56 extension = str()
57 figures_counter = 0
57 figures_counter = 0
58 infile = str()
58 infile = str()
59 infile_dir = str()
59 infile_dir = str()
60 infile_root = str()
60 infile_root = str()
61 files_dir = str()
61 files_dir = str()
62 with_preamble = True
62 with_preamble = True
63 user_preamble = None
63 user_preamble = None
64 output = unicode()
64 output = unicode()
65 raw_as_verbatim = False
65 raw_as_verbatim = False
66
66
67 def __init__(self, infile):
67 def __init__(self, infile):
68 self.infile = infile
68 self.infile = infile
69 self.infile_dir, infile_root = os.path.split(infile)
69 self.infile_dir, infile_root = os.path.split(infile)
70 infile_root = os.path.splitext(infile_root)[0]
70 infile_root = os.path.splitext(infile_root)[0]
71 files_dir = os.path.join(self.infile_dir, infile_root + '_files')
71 files_dir = os.path.join(self.infile_dir, infile_root + '_files')
72 if not os.path.isdir(files_dir):
72 if not os.path.isdir(files_dir):
73 os.mkdir(files_dir)
73 os.mkdir(files_dir)
74 self.infile_root = infile_root
74 self.infile_root = infile_root
75 self.files_dir = files_dir
75 self.files_dir = files_dir
76 self.outbase = os.path.join(self.infile_dir, infile_root)
76 self.outbase = os.path.join(self.infile_dir, infile_root)
77
77
78 def __del__(self):
78 def __del__(self):
79 if os.path.isdir(self.files_dir) and not os.listdir(self.files_dir):
79 if os.path.isdir(self.files_dir) and not os.listdir(self.files_dir):
80 os.rmdir(self.files_dir)
80 os.rmdir(self.files_dir)
81
81
82 def dispatch(self, cell_type):
82 def dispatch(self, cell_type):
83 """return cell_type dependent render method, for example render_code
83 """return cell_type dependent render method, for example render_code
84 """
84 """
85 return getattr(self, 'render_' + cell_type, self.render_unknown)
85 return getattr(self, 'render_' + cell_type, self.render_unknown)
86
86
87 def dispatch_display_format(self, format):
87 def dispatch_display_format(self, format):
88 """return output_type dependent render method, for example render_output_text
88 """return output_type dependent render method, for example render_output_text
89 """
89 """
90 return getattr(self, 'render_display_format_' + format, self.render_unknown_display)
90 return getattr(self, 'render_display_format_' + format, self.render_unknown_display)
91
91
92 def convert(self, cell_separator='\n'):
92 def convert(self, cell_separator='\n'):
93 """
93 """
94 Generic method to converts notebook to a string representation.
94 Generic method to converts notebook to a string representation.
95
95
96 This is accomplished by dispatching on the cell_type, so subclasses of
96 This is accomplished by dispatching on the cell_type, so subclasses of
97 Convereter class do not need to re-implement this method, but just
97 Convereter class do not need to re-implement this method, but just
98 need implementation for the methods that will be dispatched.
98 need implementation for the methods that will be dispatched.
99
99
100 Parameters
100 Parameters
101 ----------
101 ----------
102 cell_separator : string
102 cell_separator : string
103 Character or string to join cells with. Default is "\n"
103 Character or string to join cells with. Default is "\n"
104
104
105 Returns
105 Returns
106 -------
106 -------
107 out : string
107 out : string
108 """
108 """
109 lines = []
109 lines = []
110 lines.extend(self.optional_header())
110 lines.extend(self.optional_header())
111 lines.extend(self.main_body(cell_separator))
111 lines.extend(self.main_body(cell_separator))
112 lines.extend(self.optional_footer())
112 lines.extend(self.optional_footer())
113 return u'\n'.join(lines)
113 return u'\n'.join(lines)
114
114
115 def main_body(self, cell_separator='\n'):
115 def main_body(self, cell_separator='\n'):
116 converted_cells = []
116 converted_cells = []
117 for worksheet in self.nb.worksheets:
117 for worksheet in self.nb.worksheets:
118 for cell in worksheet.cells:
118 for cell in worksheet.cells:
119 #print(cell.cell_type) # dbg
119 #print(cell.cell_type) # dbg
120 conv_fn = self.dispatch(cell.cell_type)
120 conv_fn = self.dispatch(cell.cell_type)
121 if cell.cell_type in ('markdown', 'raw'):
121 if cell.cell_type in ('markdown', 'raw'):
122 remove_fake_files_url(cell)
122 remove_fake_files_url(cell)
123 converted_cells.append('\n'.join(conv_fn(cell)))
123 converted_cells.append('\n'.join(conv_fn(cell)))
124 cell_lines = cell_separator.join(converted_cells).split('\n')
124 cell_lines = cell_separator.join(converted_cells).split('\n')
125 return cell_lines
125 return cell_lines
126
126
127 def render(self):
127 def render(self):
128 "read, convert, and save self.infile"
128 "read, convert, and save self.infile"
129 if not hasattr(self, 'nb'):
129 if not hasattr(self, 'nb'):
130 self.read()
130 self.read()
131 self.output = self.convert()
131 self.output = self.convert()
132 assert(type(self.output) == unicode)
132 assert(type(self.output) == unicode)
133 return self.save()
133 return self.save()
134
134
135 def read(self):
135 def read(self):
136 "read and parse notebook into NotebookNode called self.nb"
136 "read and parse notebook into NotebookNode called self.nb"
137 with open(self.infile) as f:
137 with open(self.infile) as f:
138 self.nb = nbformat.read(f, 'json')
138 self.nb = nbformat.read(f, 'json')
139
139
140 def save(self, outfile=None, encoding=None):
140 def save(self, outfile=None, encoding=None):
141 "read and parse notebook into self.nb"
141 "read and parse notebook into self.nb"
142 if outfile is None:
142 if outfile is None:
143 outfile = self.outbase + '.' + self.extension
143 outfile = self.outbase + '.' + self.extension
144 if encoding is None:
144 if encoding is None:
145 encoding = self.default_encoding
145 encoding = self.default_encoding
146 with io.open(outfile, 'w', encoding=encoding) as f:
146 with io.open(outfile, 'w', encoding=encoding) as f:
147 f.write(self.output)
147 f.write(self.output)
148 return os.path.abspath(outfile)
148 return os.path.abspath(outfile)
149
149
150 def optional_header(self):
150 def optional_header(self):
151 """
151 """
152 Optional header to insert at the top of the converted notebook
152 Optional header to insert at the top of the converted notebook
153
153
154 Returns a list
154 Returns a list
155 """
155 """
156 return []
156 return []
157
157
158 def optional_footer(self):
158 def optional_footer(self):
159 """
159 """
160 Optional footer to insert at the end of the converted notebook
160 Optional footer to insert at the end of the converted notebook
161
161
162 Returns a list
162 Returns a list
163 """
163 """
164 return []
164 return []
165
165
166 def _new_figure(self, data, fmt):
166 def _new_figure(self, data, fmt):
167 """Create a new figure file in the given format.
167 """Create a new figure file in the given format.
168
168
169 Returns a path relative to the input file.
169 Returns a path relative to the input file.
170 """
170 """
171 figname = '%s_fig_%02i.%s' % (self.infile_root,
171 figname = '%s_fig_%02i.%s' % (self.infile_root,
172 self.figures_counter, fmt)
172 self.figures_counter, fmt)
173 self.figures_counter += 1
173 self.figures_counter += 1
174 fullname = os.path.join(self.files_dir, figname)
174 fullname = os.path.join(self.files_dir, figname)
175
175
176 # Binary files are base64-encoded, SVG is already XML
176 # Binary files are base64-encoded, SVG is already XML
177 if fmt in ('png', 'jpg', 'pdf'):
177 if fmt in ('png', 'jpg', 'pdf'):
178 data = data.decode('base64')
178 data = data.decode('base64')
179 fopen = lambda fname: open(fname, 'wb')
179 fopen = lambda fname: open(fname, 'wb')
180 else:
180 else:
181 fopen = lambda fname: codecs.open(fname, 'wb', self.default_encoding)
181 fopen = lambda fname: codecs.open(fname, 'wb', self.default_encoding)
182
182
183 with fopen(fullname) as f:
183 with fopen(fullname) as f:
184 f.write(data)
184 f.write(data)
185
185
186 return fullname
186 return fullname
187
187
188 def render_heading(self, cell):
188 def render_heading(self, cell):
189 """convert a heading cell
189 """convert a heading cell
190
190
191 Returns list."""
191 Returns list."""
192 raise NotImplementedError
192 raise NotImplementedError
193
193
194 def render_code(self, cell):
194 def render_code(self, cell):
195 """Convert a code cell
195 """Convert a code cell
196
196
197 Returns list."""
197 Returns list."""
198 raise NotImplementedError
198 raise NotImplementedError
199
199
200 def render_markdown(self, cell):
200 def render_markdown(self, cell):
201 """convert a markdown cell
201 """convert a markdown cell
202
202
203 Returns list."""
203 Returns list."""
204 raise NotImplementedError
204 raise NotImplementedError
205
205
206 def _img_lines(self, img_file):
206 def _img_lines(self, img_file):
207 """Return list of lines to include an image file."""
207 """Return list of lines to include an image file."""
208 # Note: subclasses may choose to implement format-specific _FMT_lines
208 # Note: subclasses may choose to implement format-specific _FMT_lines
209 # methods if they so choose (FMT in {png, svg, jpg, pdf}).
209 # methods if they so choose (FMT in {png, svg, jpg, pdf}).
210 raise NotImplementedError
210 raise NotImplementedError
211
211
212 def render_display_data(self, output):
212 def render_display_data(self, output):
213 """convert display data from the output of a code cell
213 """convert display data from the output of a code cell
214
214
215 Returns list.
215 Returns list.
216 """
216 """
217 lines = []
217 lines = []
218
218
219 for fmt in output.keys():
219 for fmt in output.keys():
220 if fmt in ['png', 'svg', 'jpg', 'pdf']:
220 if fmt in ['png', 'svg', 'jpg', 'pdf']:
221 img_file = self._new_figure(output[fmt], fmt)
221 img_file = self._new_figure(output[fmt], fmt)
222 # Subclasses can have format-specific render functions (e.g.,
222 # Subclasses can have format-specific render functions (e.g.,
223 # latex has to auto-convert all SVG to PDF first).
223 # latex has to auto-convert all SVG to PDF first).
224 lines_fun = getattr(self, '_%s_lines' % fmt, None)
224 lines_fun = getattr(self, '_%s_lines' % fmt, None)
225 if not lines_fun:
225 if not lines_fun:
226 lines_fun = self._img_lines
226 lines_fun = self._img_lines
227 lines.extend(lines_fun(img_file))
227 lines.extend(lines_fun(img_file))
228 elif fmt != 'output_type':
228 elif fmt != 'output_type':
229 conv_fn = self.dispatch_display_format(fmt)
229 conv_fn = self.dispatch_display_format(fmt)
230 lines.extend(conv_fn(output))
230 lines.extend(conv_fn(output))
231 return lines
231 return lines
232
232
233 def render_raw(self, cell):
233 def render_raw(self, cell):
234 """convert a cell with raw text
234 """convert a cell with raw text
235
235
236 Returns list."""
236 Returns list."""
237 raise NotImplementedError
237 raise NotImplementedError
238
238
239 def render_unknown(self, cell):
239 def render_unknown(self, cell):
240 """Render cells of unkown type
240 """Render cells of unkown type
241
241
242 Returns list."""
242 Returns list."""
243 data = pprint.pformat(cell)
243 data = pprint.pformat(cell)
244 logging.warning('Unknown cell: %s' % cell.cell_type)
244 logging.warning('Unknown cell: %s' % cell.cell_type)
245 return self._unknown_lines(data)
245 return self._unknown_lines(data)
246
246
247 def render_unknown_display(self, output, type):
247 def render_unknown_display(self, output, type):
248 """Render cells of unkown type
248 """Render cells of unkown type
249
249
250 Returns list."""
250 Returns list."""
251 data = pprint.pformat(output)
251 data = pprint.pformat(output)
252 logging.warning('Unknown output: %s' % output.output_type)
252 logging.warning('Unknown output: %s' % output.output_type)
253 return self._unknown_lines(data)
253 return self._unknown_lines(data)
254
254
255 def render_stream(self, output):
255 def render_stream(self, output):
256 """render the stream part of an output
256 """render the stream part of an output
257
257
258 Returns list.
258 Returns list.
259
259
260 Identical to render_display_format_text
260 Identical to render_display_format_text
261 """
261 """
262 return self.render_display_format_text(output)
262 return self.render_display_format_text(output)
263
263
264 def render_pyout(self, output):
264 def render_pyout(self, output):
265 """convert pyout part of a code cell
265 """convert pyout part of a code cell
266
266
267 Returns list."""
267 Returns list."""
268 raise NotImplementedError
268 raise NotImplementedError
269
269
270
270
271 def render_pyerr(self, output):
271 def render_pyerr(self, output):
272 """convert pyerr part of a code cell
272 """convert pyerr part of a code cell
273
273
274 Returns list."""
274 Returns list."""
275 raise NotImplementedError
275 raise NotImplementedError
276
276
277 def _unknown_lines(self, data):
277 def _unknown_lines(self, data):
278 """Return list of lines for an unknown cell.
278 """Return list of lines for an unknown cell.
279
279
280 Parameters
280 Parameters
281 ----------
281 ----------
282 data : str
282 data : str
283 The content of the unknown data as a single string.
283 The content of the unknown data as a single string.
284 """
284 """
285 raise NotImplementedError
285 raise NotImplementedError
286
286
287 # These are the possible format types in an output node
287 # These are the possible format types in an output node
288
288
289 def render_display_format_text(self, output):
289 def render_display_format_text(self, output):
290 """render the text part of an output
290 """render the text part of an output
291
291
292 Returns list.
292 Returns list.
293 """
293 """
294 raise NotImplementedError
294 raise NotImplementedError
295
295
296 def render_display_format_html(self, output):
296 def render_display_format_html(self, output):
297 """render the html part of an output
297 """render the html part of an output
298
298
299 Returns list.
299 Returns list.
300 """
300 """
301 raise NotImplementedError
301 raise NotImplementedError
302
302
303 def render_display_format_latex(self, output):
303 def render_display_format_latex(self, output):
304 """render the latex part of an output
304 """render the latex part of an output
305
305
306 Returns list.
306 Returns list.
307 """
307 """
308 raise NotImplementedError
308 raise NotImplementedError
309
309
310 def render_display_format_json(self, output):
310 def render_display_format_json(self, output):
311 """render the json part of an output
311 """render the json part of an output
312
312
313 Returns list.
313 Returns list.
314 """
314 """
315 raise NotImplementedError
315 raise NotImplementedError
316
316
317 def render_display_format_javascript(self, output):
317 def render_display_format_javascript(self, output):
318 """render the javascript part of an output
318 """render the javascript part of an output
319
319
320 Returns list.
320 Returns list.
321 """
321 """
322 raise NotImplementedError
322 raise NotImplementedError
323
323
@@ -1,82 +1,82 b''
1 from converters.base import Converter
1 from converters.base import Converter
2 from converters.utils import cell_to_lines
2 from converters.utils import cell_to_lines
3 from shutil import rmtree
3 from shutil import rmtree
4 import json
4 import json
5
5
6 class ConverterNotebook(Converter):
6 class ConverterNotebook(Converter):
7 """
7 """
8 A converter that is essentially a null-op.
8 A converter that is essentially a null-op.
9 This exists so it can be subclassed
9 This exists so it can be subclassed
10 for custom handlers of .ipynb files
10 for custom handlers of .ipynb files
11 that create new .ipynb files.
11 that create new .ipynb files.
12
12
13 What distinguishes this from JSONWriter is that
13 What distinguishes this from JSONWriter is that
14 subclasses can specify what to do with each type of cell.
14 subclasses can specify what to do with each type of cell.
15
15
16 Writes out a notebook file.
16 Writes out a notebook file.
17
17
18 """
18 """
19 extension = 'ipynb'
19 extension = 'ipynb'
20
20
21 def __init__(self, infile, outbase):
21 def __init__(self, infile, outbase):
22 Converter.__init__(self, infile)
22 Converter.__init__(self, infile)
23 self.outbase = outbase
23 self.outbase = outbase
24 rmtree(self.files_dir)
24 rmtree(self.files_dir)
25
25
26 def convert(self):
26 def convert(self):
27 return unicode(json.dumps(json.loads(Converter.convert(self, ',')), indent=1, sort_keys=True))
27 return unicode(json.dumps(json.loads(Converter.convert(self, ',')), indent=1, sort_keys=True))
28
28
29 def optional_header(self):
29 def optional_header(self):
30 s = \
30 s = \
31 """{
31 """{
32 "metadata": {
32 "metadata": {
33 "name": "%(name)s"
33 "name": "%(name)s"
34 },
34 },
35 "nbformat": 3,
35 "nbformat": 3,
36 "worksheets": [
36 "worksheets": [
37 {
37 {
38 "cells": [""" % {'name':self.outbase}
38 "cells": [""" % {'name':self.outbase}
39
39
40 return s.split('\n')
40 return s.split('\n')
41
41
42 def optional_footer(self):
42 def optional_footer(self):
43 s = \
43 s = \
44 """]
44 """]
45 }
45 }
46 ]
46 ]
47 }"""
47 }"""
48 return s.split('\n')
48 return s.split('\n')
49
49
50 def render_heading(self, cell):
50 def render_heading(self, cell):
51 return cell_to_lines(cell)
51 return cell_to_lines(cell)
52
52
53 def render_code(self, cell):
53 def render_code(self, cell):
54 return cell_to_lines(cell)
54 return cell_to_lines(cell)
55
55
56 def render_markdown(self, cell):
56 def render_markdown(self, cell):
57 return cell_to_lines(cell)
57 return cell_to_lines(cell)
58
58
59 def render_raw(self, cell):
59 def render_raw(self, cell):
60 return cell_to_lines(cell)
60 return cell_to_lines(cell)
61
61
62 def render_pyout(self, output):
62 def render_pyout(self, output):
63 return cell_to_lines(output)
63 return cell_to_lines(output)
64
64
65 def render_pyerr(self, output):
65 def render_pyerr(self, output):
66 return cell_to_lines(output)
66 return cell_to_lines(output)
67
67
68 def render_display_format_text(self, output):
68 def render_display_format_text(self, output):
69 return [output.text]
69 return [output.text]
70
70
71 def render_display_format_html(self, output):
71 def render_display_format_html(self, output):
72 return [output.html]
72 return [output.html]
73
73
74 def render_display_format_latex(self, output):
74 def render_display_format_latex(self, output):
75 return [output.latex]
75 return [output.latex]
76
76
77 def render_display_format_json(self, output):
77 def render_display_format_json(self, output):
78 return [output.json]
78 return [output.json]
79
79
80
80
81 def render_display_format_javascript(self, output):
81 def render_display_format_javascript(self, output):
82 return [output.javascript]
82 return [output.javascript]
@@ -1,46 +1,48 b''
1 import os
1 import os
2 import io
2 import io
3 import nose.tools as nt
3 import nose.tools as nt
4 from nbconvert import *
4 from nbconvert import (
5 ConverterLaTeX, ConverterMarkdown, ConverterPy, ConverterHTML
6 )
5 from nose.tools import nottest
7 from nose.tools import nottest
6
8
7
9
8 def test_evens():
10 def test_evens():
9 ######
11 ######
10 # for now, we don't need to really run inkscape to extract svg
12 # for now, we don't need to really run inkscape to extract svg
11 # from file, on unix, for test, we monkeypathc it to 'true'
13 # from file, on unix, for test, we monkeypathc it to 'true'
12 # which does not fail as doing anything.
14 # which does not fail as doing anything.
13 ####
15 ####
14 ConverterLaTeX.inkscape = 'true'
16 ConverterLaTeX.inkscape = 'true'
15
17
16 # commenting rst for now as travis build
18 # commenting rst for now as travis build
17 # fail because of pandoc version.
19 # fail because of pandoc version.
18 converters = [
20 converters = [
19 #(ConverterRST,'rst'),
21 #(ConverterRST,'rst'),
20 (ConverterMarkdown,'md'),
22 (ConverterMarkdown, 'md'),
21 (ConverterLaTeX,'tex'),
23 (ConverterLaTeX, 'tex'),
22 (ConverterPy,'py'),
24 (ConverterPy, 'py'),
23 (ConverterHTML,'html')
25 (ConverterHTML, 'html')
24 ]
26 ]
25 reflist = [
27 reflist = [
26 'tests/ipynbref/IntroNumPy.orig'
28 'tests/ipynbref/IntroNumPy.orig'
27 ]
29 ]
28 for root in reflist :
30 for root in reflist:
29 for conv,ext in converters:
31 for conv, ext in converters:
30 yield test_conversion, conv,root+'.ipynb',root+'.'+ext
32 yield test_conversion, conv, root + '.ipynb', root + '.' + ext
33
31
34
32 @nottest
35 @nottest
33 def compfiles(stra, strb):
36 def compfiles(stra, strb):
34 nt.assert_equal(map(unicode.strip,stra.split('\n')),map(unicode.strip,strb.split('\n')))
37 nt.assert_equal(map(unicode.strip, stra.split('\n')),
38 map(unicode.strip, strb.split('\n')))
39
35
40
36 @nottest
41 @nottest
37 def test_conversion(ConverterClass, ipynb, ref_file):
42 def test_conversion(ConverterClass, ipynb, ref_file):
38
39 converter = ConverterClass(ipynb)
43 converter = ConverterClass(ipynb)
40 converter.read()
44 converter.read()
41 cv =converter.convert()
45 cv = converter.convert()
42 with io.open(ref_file) as ref:
46 with io.open(ref_file) as ref:
43 value = ref.read()
47 value = ref.read()
44 compfiles(cv,value)
48 compfiles(cv, value)
45
46
@@ -1,70 +1,71 b''
1 from nbconvert import ConverterRST, main
1 from nbconvert import ConverterRST, main
2 import nose.tools as nt
2 import nose.tools as nt
3
3
4 import os
4 import os
5 import glob
5 import glob
6 from IPython.nbformat import current as nbformat
6 from IPython.nbformat import current as nbformat
7
7
8 fname = 'tests/test.ipynb'
8 fname = 'tests/test.ipynb'
9 out_fname = 'tests/test.rst'
9 out_fname = 'tests/test.rst'
10
10
11
11
12 def clean_dir():
12 def clean_dir():
13 "Remove .rst files created during conversion"
13 "Remove .rst files created during conversion"
14 map(os.remove, glob.glob("./tests/*.rst"))
14 map(os.remove, glob.glob("./tests/*.rst"))
15 map(os.remove, glob.glob("./tests/*.png"))
15 map(os.remove, glob.glob("./tests/*.png"))
16 map(os.remove, glob.glob("./tests/*.html"))
16 map(os.remove, glob.glob("./tests/*.html"))
17 map(os.remove, glob.glob("./tests/test_files/*"))
17 map(os.remove, glob.glob("./tests/test_files/*"))
18
18
19
19
20 @nt.with_setup(clean_dir, clean_dir)
20 @nt.with_setup(clean_dir, clean_dir)
21 def test_simple():
21 def test_simple():
22 c = ConverterRST(fname)
22 c = ConverterRST(fname)
23 f = c.render()
23 f = c.render()
24 nt.assert_true('rst' in f, 'changed file extension to rst')
24 nt.assert_true('rst' in f, 'changed file extension to rst')
25
25
26
26
27 @nt.with_setup(clean_dir, clean_dir)
27 @nt.with_setup(clean_dir, clean_dir)
28 def test_main():
28 def test_main():
29 """
29 """
30 Test main entry point
30 Test main entry point
31 """
31 """
32 main(fname)
32 main(fname)
33 nt.assert_true(os.path.exists(out_fname))
33 nt.assert_true(os.path.exists(out_fname))
34
34
35
35
36 def test_render_heading():
36 def test_render_heading():
37 """ Unit test for cell type "heading" """
37 """ Unit test for cell type "heading" """
38 # Generate and test heading cells level 1-6
38 # Generate and test heading cells level 1-6
39 for level in xrange(1, 7):
39 for level in xrange(1, 7):
40 cell = {
40 cell = {
41 'cell_type': 'heading',
41 'cell_type': 'heading',
42 'level' : level,
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 # Convert cell dictionaries to NotebookNode
45 # Convert cell dictionaries to NotebookNode
46 cell_nb = nbformat.NotebookNode(cell)
46 cell_nb = nbformat.NotebookNode(cell)
47 # Make sure "source" attribute is uniconde not list.
47 # Make sure "source" attribute is uniconde not list.
48 # For some reason, creating a NotebookNode manually like
48 # For some reason, creating a NotebookNode manually like
49 # this isn't converting source to a string like using
49 # this isn't converting source to a string like using
50 # the create-from-file routine.
50 # the create-from-file routine.
51 if type(cell_nb.source) is list:
51 if type(cell_nb.source) is list:
52 cell_nb.source = '\n'.join(cell_nb.source)
52 cell_nb.source = '\n'.join(cell_nb.source)
53 # Render to rst
53 # Render to rst
54 c = ConverterRST('')
54 c = ConverterRST('')
55 rst_list = c.render_heading(cell_nb)
55 rst_list = c.render_heading(cell_nb)
56 nt.assert_true(isinstance(rst_list, list)) # render should return a list
56 # render should return a list
57 nt.assert_true(isinstance(rst_list, list))
57 rst_str = "".join(rst_list)
58 rst_str = "".join(rst_list)
58 # Confirm rst content
59 # Confirm rst content
59 chk_str = "Test for heading type H{0}\n{1}\n".format(
60 chk_str = "Test for heading type H{0}\n{1}\n".format(
60 level, c.heading_level[level] * 24)
61 level, c.heading_level[level] * 24)
61 nt.assert_equal(rst_str, chk_str)
62 nt.assert_equal(rst_str, chk_str)
62
63
63
64
64 @nt.with_setup(clean_dir, clean_dir)
65 @nt.with_setup(clean_dir, clean_dir)
65 def test_main_html():
66 def test_main_html():
66 """
67 """
67 Test main entry point
68 Test main entry point
68 """
69 """
69 main(fname, format='html')
70 main(fname, format='html')
70 nt.assert_true(os.path.exists('tests/test.html'))
71 nt.assert_true(os.path.exists('tests/test.html'))
General Comments 0
You need to be logged in to leave comments. Login now