##// END OF EJS Templates
Add argument parsing, and ability to convert an HTML file from command line
Anton I. Sipos -
Show More
@@ -24,6 +24,11 b' The latest development version of doctest is required. This can be installed via'
24 24 $ curl http://docutils.svn.sourceforge.net/viewvc/docutils/trunk/docutils/?view=tar > docutils.gz
25 25 $ pip install -U docutils.gz
26 26
27 For conversion to HTML, pygments is also required
28 ::
29
30 $ pip install pygments
31
27 32 Running Tests
28 33 =============
29 34 ::
@@ -13,7 +13,7 b' called nb_figure_NN.png.'
13 13 import os
14 14 import subprocess
15 15 import sys
16
16 import argparse
17 17 from IPython.nbformat import current as nbformat
18 18 from IPython.utils.text import indent
19 19
@@ -36,6 +36,7 b" def rst_directive(directive, text=''):"
36 36
37 37 # Converters for parts of a cell.
38 38
39
39 40 class ConversionException(Exception):
40 41 pass
41 42
@@ -43,9 +44,9 b' class ConversionException(Exception):'
43 44 class Converter(object):
44 45 default_encoding = 'utf-8'
45 46
46 def __init__(self, fname):
47 self.fname = fname
48 self.dirpath = os.path.dirname(fname)
47 def __init__(self, infile):
48 self.infile = infile
49 self.dirpath = os.path.dirname(infile)
49 50
50 51 @property
51 52 def extension(self):
@@ -66,25 +67,25 b' class Converter(object):'
66 67 return '\n'.join(lines)
67 68
68 69 def render(self):
69 "read, convert, and save self.fname"
70 "read, convert, and save self.infile"
70 71 self.read()
71 72 self.output = self.convert()
72 73 return self.save()
73 74
74 75 def read(self):
75 76 "read and parse notebook into NotebookNode called self.nb"
76 with open(self.fname) as f:
77 with open(self.infile) as f:
77 78 self.nb = nbformat.read(f, 'json')
78 79
79 def save(self, fname=None, encoding=None):
80 def save(self, infile=None, encoding=None):
80 81 "read and parse notebook into self.nb"
81 if fname is None:
82 fname = os.path.splitext(self.fname)[0] + '.' + self.extension
82 if infile is None:
83 infile = os.path.splitext(self.infile)[0] + '.' + self.extension
83 84 if encoding is None:
84 85 encoding = self.default_encoding
85 with open(fname, 'w') as f:
86 with open(infile, 'w') as f:
86 87 f.write(self.output.encode(encoding))
87 return fname
88 return infile
88 89
89 90 def render_heading(self, cell):
90 91 raise NotImplementedError
@@ -170,13 +171,13 b' class ConverterRST(Converter):'
170 171 lines = []
171 172
172 173 if 'png' in output:
173 fname = 'nb_figure_%s.png' % self.figures_counter
174 fullname = os.path.join(self.dirpath, fname)
174 infile = 'nb_figure_%s.png' % self.figures_counter
175 fullname = os.path.join(self.dirpath, infile)
175 176 with open(fullname, 'w') as f:
176 177 f.write(output.png.decode('base64'))
177 178
178 179 self.figures_counter += 1
179 lines.append('.. image:: %s' % fname)
180 lines.append('.. image:: %s' % infile)
180 181 lines.append('')
181 182
182 183 return lines
@@ -194,7 +195,7 b' class ConverterRST(Converter):'
194 195 return lines
195 196
196 197
197 def rst2simplehtml(fname):
198 def rst2simplehtml(infile):
198 199 """Convert a rst file to simplified html suitable for blogger.
199 200
200 201 This just runs rst2html with certain parameters to produce really simple
@@ -211,7 +212,7 b' def rst2simplehtml(fname):'
211 212 "--no-toc-backlinks --no-section-numbering "
212 213 "--strip-comments ")
213 214
214 cmd = "%s %s" % (cmd_template, fname)
215 cmd = "%s %s" % (cmd_template, infile)
215 216 proc = subprocess.Popen(cmd,
216 217 stdout=subprocess.PIPE,
217 218 stderr=subprocess.PIPE,
@@ -232,7 +233,7 b' def rst2simplehtml(fname):'
232 233 if line.startswith('<body>'):
233 234 break
234 235
235 newfname = os.path.splitext(fname)[0] + '.html'
236 newfname = os.path.splitext(infile)[0] + '.html'
236 237 with open(newfname, 'w') as f:
237 238 for line in walker:
238 239 if line.startswith('</body>'):
@@ -243,11 +244,27 b' def rst2simplehtml(fname):'
243 244 return newfname
244 245
245 246
246 def main(fname):
247 def main(infile, format='rst'):
247 248 """Convert a notebook to html in one step"""
248 converter = ConverterRST(fname)
249 converter.render()
249 if format == 'rst':
250 converter = ConverterRST(infile)
251 converter.render()
252 elif format == 'html':
253 #Currently, conversion to html is a 2 step process, nb->rst->html
254 converter = ConverterRST(infile)
255 rstfname = converter.render()
256 rst2simplehtml(rstfname)
250 257
251 258
252 259 if __name__ == '__main__':
253 main(sys.argv[1])
260 parser = argparse.ArgumentParser(description='nbconvert: Convert IPython notebooks to other formats')
261
262 # TODO: consider passing file like object around, rather than filenames
263 # would allow us to process stdin, or even http streams
264 #parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
265
266 #Require a filename as a positional argument
267 parser.add_argument('infile', nargs=1)
268 parser.add_argument('-f', '--format', default='rst')
269 args = parser.parse_args()
270 main(infile=args.infile[0], format=args.format)
@@ -13,6 +13,8 b' 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 map(os.remove, glob.glob("./tests/*.html"))
17
16 18
17 19 @nt.with_setup(clean_dir, clean_dir)
18 20 def test_simple():
@@ -20,6 +22,7 b' def test_simple():'
20 22 f = c.render()
21 23 nt.assert_true('rst' in f, 'changed file extension to rst')
22 24
25
23 26 @nt.with_setup(clean_dir, clean_dir)
24 27 def test_main():
25 28 """
@@ -28,14 +31,15 b' def test_main():'
28 31 main(fname)
29 32 nt.assert_true(os.path.exists(out_fname))
30 33
34
31 35 def test_render_heading():
32 36 """ Unit test for cell type "heading" """
33 37 # Generate and test heading cells level 1-6
34 for level in xrange(1,7):
38 for level in xrange(1, 7):
35 39 cell = {
36 40 'cell_type': 'heading',
37 41 'level' : level,
38 'source' : ['Test for heading type H{0}'.format(level)]
42 'source' : ['Test for heading type H{0}'.format(level)]
39 43 }
40 44 # Convert cell dictionaries to NotebookNode
41 45 cell_nb = nbformat.NotebookNode(cell)
@@ -48,10 +52,19 b' def test_render_heading():'
48 52 # Render to rst
49 53 c = ConverterRST('')
50 54 rst_list = c.render_heading(cell_nb)
51 nt.assert_true(isinstance(rst_list,list)) # render should return a list
55 nt.assert_true(isinstance(rst_list, list)) # render should return a list
52 56 rst_str = "".join(rst_list)
53 57 # Confirm rst content
54 heading_level = {1:'=', 2:'-', 3:'`', 4:'\'', 5:'.',6:'~'}
58 heading_level = {1: '=', 2: '-', 3: '`', 4: '\'', 5: '.', 6: '~'}
55 59 chk_str = "Test for heading type H{0}\n{1}\n".format(
56 level,heading_level[level]*24)
57 nt.assert_equal(rst_str,chk_str)
60 level, heading_level[level] * 24)
61 nt.assert_equal(rst_str, chk_str)
62
63
64 @nt.with_setup(clean_dir, clean_dir)
65 def test_main_html():
66 """
67 Test main entry point
68 """
69 main(fname, format='html')
70 nt.assert_true(os.path.exists('tests/test.html'))
General Comments 0
You need to be logged in to leave comments. Login now