##// END OF EJS Templates
Merge pull request #57 from maxalbert/cleanup...
Bussonnier Matthias -
r8738:fa0e3fea merge
parent child Browse files
Show More
@@ -1,74 +1,78 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """Convert IPython notebooks to other formats, such as ReST, and HTML.
2 """Convert IPython notebooks to other formats, such as ReST, and HTML.
3
3
4 Example:
4 Example:
5 ./nbconvert.py --format rst file.ipynb
5 ./nbconvert.py --format rst file.ipynb
6
6
7 Produces 'file.rst', along with auto-generated figure files
7 Produces 'file.rst', along with auto-generated figure files
8 called nb_figure_NN.png.
8 called nb_figure_NN.png.
9 """
9 """
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Imports
11 # Imports
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 from __future__ import print_function
13 from __future__ import print_function
14
14
15
16 # From IPython
15 # From IPython
17 from IPython.external import argparse
16 from IPython.external import argparse
18
17
19 # local
18 # local
20 from converters.html import ConverterHTML
19 from converters.html import ConverterHTML
21 from converters.markdown import ConverterMarkdown
20 from converters.markdown import ConverterMarkdown
22 from converters.bloggerhtml import ConverterBloggerHTML
21 from converters.bloggerhtml import ConverterBloggerHTML
23 from converters.rst import ConverterRST
22 from converters.rst import ConverterRST
24 from converters.latex import ConverterLaTeX
23 from converters.latex import ConverterLaTeX
25 from converters.notebook import ConverterNotebook
24 from converters.notebook import ConverterNotebook
26 from converters.python import ConverterPy
25 from converters.python import ConverterPy
27
26
28 known_formats = "rst (default), html, blogger-html, latex, markdown, py"
27
28 # When adding a new format, make sure to add it to the `converters`
29 # dictionary below. This is used to create the list of known formats,
30 # which gets printed in case an unknown format is encounteres, as well
31 # as in the help
32
33 converters = {
34 'rst': ConverterRST,
35 'markdown': ConverterMarkdown,
36 'html': ConverterHTML,
37 'blogger-html': ConverterBloggerHTML,
38 'latex': ConverterLaTeX,
39 'py': ConverterPy,
40 }
41
42 default_format = 'rst'
43
44 # Extract the list of known formats and mark the first format as the default.
45 known_formats = ', '.join([key + " (default)" if key == default_format else key
46 for key in converters])
47
29
48
30 def main(infile, format='rst'):
49 def main(infile, format='rst'):
31 """Convert a notebook to html in one step"""
50 """Convert a notebook to html in one step"""
32 # XXX: this is just quick and dirty for now. When adding a new format,
51
33 # make sure to add it to the `known_formats` string above, which gets
52 try:
34 # printed in in the catch-all else, as well as in the help
53 ConverterClass = converters[format]
35 if format == 'rst':
54 except KeyError:
36 converter = ConverterRST(infile)
37 converter.render()
38 elif format == 'markdown':
39 converter = ConverterMarkdown(infile)
40 converter.render()
41 elif format == 'html':
42 converter = ConverterHTML(infile)
43 converter.render()
44 elif format == 'blogger-html':
45 converter = ConverterBloggerHTML(infile)
46 converter.render()
47 elif format == 'latex':
48 converter = ConverterLaTeX(infile)
49 converter.render()
50 elif format == 'py':
51 converter = ConverterPy(infile)
52 converter.render()
53 else:
54 raise SystemExit("Unknown format '%s', " % format +
55 raise SystemExit("Unknown format '%s', " % format +
55 "known formats are: " + known_formats)
56 "known formats are: " + known_formats)
56
57
58 converter = ConverterClass(infile)
59 converter.render()
60
57 #-----------------------------------------------------------------------------
61 #-----------------------------------------------------------------------------
58 # Script main
62 # Script main
59 #-----------------------------------------------------------------------------
63 #-----------------------------------------------------------------------------
60
64
61 if __name__ == '__main__':
65 if __name__ == '__main__':
62 parser = argparse.ArgumentParser(description=__doc__,
66 parser = argparse.ArgumentParser(description=__doc__,
63 formatter_class=argparse.RawTextHelpFormatter)
67 formatter_class=argparse.RawTextHelpFormatter)
64 # TODO: consider passing file like object around, rather than filenames
68 # TODO: consider passing file like object around, rather than filenames
65 # would allow us to process stdin, or even http streams
69 # would allow us to process stdin, or even http streams
66 #parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
70 #parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
67
71
68 #Require a filename as a positional argument
72 #Require a filename as a positional argument
69 parser.add_argument('infile', nargs=1)
73 parser.add_argument('infile', nargs=1)
70 parser.add_argument('-f', '--format', default='rst',
74 parser.add_argument('-f', '--format', default='rst',
71 help='Output format. Supported formats: \n' +
75 help='Output format. Supported formats: \n' +
72 known_formats)
76 known_formats)
73 args = parser.parse_args()
77 args = parser.parse_args()
74 main(infile=args.infile[0], format=args.format)
78 main(infile=args.infile[0], format=args.format)
@@ -1,71 +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(f.endswith('.rst'), '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 # render should return a list
56 # render should return a list
57 nt.assert_true(isinstance(rst_list, list))
57 nt.assert_true(isinstance(rst_list, list))
58 rst_str = "".join(rst_list)
58 rst_str = "".join(rst_list)
59 # Confirm rst content
59 # Confirm rst content
60 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(
61 level, c.heading_level[level] * 24)
61 level, c.heading_level[level] * 24)
62 nt.assert_equal(rst_str, chk_str)
62 nt.assert_equal(rst_str, chk_str)
63
63
64
64
65 @nt.with_setup(clean_dir, clean_dir)
65 @nt.with_setup(clean_dir, clean_dir)
66 def test_main_html():
66 def test_main_html():
67 """
67 """
68 Test main entry point
68 Test main entry point
69 """
69 """
70 main(fname, format='html')
70 main(fname, format='html')
71 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