##// END OF EJS Templates
Created new notebook magic that can export/convert notebooks....
Brian E. Granger -
Show More
@@ -48,6 +48,7 b' from IPython.core.error import UsageError'
48 48 from IPython.core.fakemodule import FakeModule
49 49 from IPython.core.profiledir import ProfileDir
50 50 from IPython.core.macro import Macro
51 from IPython.core import magic_arguments
51 52 from IPython.core import page
52 53 from IPython.core.prefilter import ESC_MAGIC
53 54 from IPython.lib.pylabtools import mpl_runner
@@ -3495,4 +3496,68 b' Defaulting color scheme to \'NoColor\'"""'
3495 3496 ptformatter.float_precision = s
3496 3497 return ptformatter.float_format
3497 3498
3499
3500 @magic_arguments.magic_arguments()
3501 @magic_arguments.argument(
3502 '-e', '--export', action='store_true', default=False,
3503 help='Export IPython history as a notebook. The filename argument '
3504 'is used to specify the notebook name and format. For example '
3505 'a filename of notebook.ipynb will result in a notebook name '
3506 'of "notebook" and a format of "xml". Likewise using a ".json" '
3507 'or ".py" file extension will write the notebook in the json '
3508 'or py formats.'
3509 )
3510 @magic_arguments.argument(
3511 '-f', '--format',
3512 help='Convert an existing IPython notebook to a new format. This option '
3513 'specifies the new format and can have the values: xml, json, py. '
3514 'The target filename is choosen automatically based on the new '
3515 'format. The filename argument gives the name of the source file.'
3516 )
3517 @magic_arguments.argument(
3518 'filename', type=unicode,
3519 help='Notebook name or filename'
3520 )
3521 def magic_notebook(self, s):
3522 """Export and convert IPython notebooks.
3523
3524 This function can export the current IPython history to a notebook file
3525 or can convert an existing notebook file into a different format. For
3526 example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
3527 To export the history to "foo.py" do "%notebook -e foo.py". To convert
3528 "foo.ipynb" to "foo.json" do "%notebook -f json foo.ipynb". Possible
3529 formats include (xml/ipynb, json, py).
3530 """
3531 args = magic_arguments.parse_argstring(self.magic_notebook, s)
3532 print args
3533
3534 from IPython.nbformat import current
3535 if args.export:
3536 fname, name, format = current.parse_filename(args.filename)
3537 cells = []
3538 hist = list(self.history_manager.get_range())
3539 for session, prompt_number, input in hist[:-1]:
3540 cells.append(current.new_code_cell(prompt_number=prompt_number, input=input))
3541 worksheet = current.new_worksheet(cells=cells)
3542 nb = current.new_notebook(name=name,worksheets=[worksheet])
3543 with open(fname, 'w') as f:
3544 current.write(nb, f, format);
3545 elif args.format is not None:
3546 old_fname, old_name, old_format = current.parse_filename(args.filename)
3547 new_format = args.format
3548 if new_format == u'xml' or new_format == u'ipynb':
3549 new_fname = old_name + u'.ipynb'
3550 new_format = u'xml'
3551 elif new_format == u'py':
3552 new_fname = old_name + u'.py'
3553 elif new_format == u'json':
3554 new_fname = old_name + u'.json'
3555 else:
3556 raise ValueError('Invalid notebook format: %s' % newformat)
3557 with open(old_fname, 'r') as f:
3558 nb = current.read(f, old_format)
3559 with open(new_fname, 'w') as f:
3560 current.write(nb, f, new_format)
3561
3562
3498 3563 # end Magic
@@ -7,7 +7,8 b' from IPython.nbformat import v1'
7 7
8 8 from IPython.nbformat.v2 import (
9 9 NotebookNode,
10 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet
10 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
11 parse_filename
11 12 )
12 13
13 14
@@ -19,3 +19,39 b' from .nbpy import to_notebook as to_notebook_py'
19 19 from .convert import convert_to_this_nbformat
20 20
21 21
22 def parse_filename(fname):
23 """Parse a notebook filename.
24
25 This function takes a notebook filename and returns the notebook
26 format (xml/json/py) and the notebook name. This logic can be
27 summarized as follows:
28
29 * notebook.ipynb -> (notebook.ipynb, notebook, xml)
30 * notebook.json -> (notebook.json, notebook, json)
31 * notebook.py -> (notebook.py, notebook, py)
32 * notebook -> (notebook.ipynb, notebook, xml)
33
34 Parameters
35 ----------
36 fname : unicode
37 The notebook filename. The filename can use a specific filename
38 extention (.ipynb, .json, .py) or none, in which case .ipynb will
39 be assumed.
40
41 Returns
42 -------
43 (fname, name, format) : (unicode, unicode, unicode)
44 The filename, notebook name and format.
45 """
46 if fname.endswith(u'.ipynb'):
47 format = u'xml'
48 elif fname.endswith(u'.json'):
49 format = u'json'
50 elif fname.endswith(u'.py'):
51 format = u'py'
52 else:
53 fname = fname + u'.ipynb'
54 format = u'xml'
55 name = fname.split('.')[0]
56 return fname, name, format
57
@@ -19,15 +19,19 b' class PyReader(NotebookReader):'
19 19 cell_lines = []
20 20 code_cell = False
21 21 for line in lines:
22 if line.startswith(u'# <codecell>'):
22 if line.startswith(u'# <nbformat>'):
23 pass
24 elif line.startswith(u'# <codecell>'):
23 25 if code_cell:
24 26 raise PyReaderError('Unexpected <codecell>')
25 if cell_lines:
26 for block in self.split_lines_into_blocks(cell_lines):
27 cells.append(new_code_cell(input=block))
27 # We can't use the ast to split blocks because there can be
28 # IPython syntax in the files.
29 # if cell_lines:
30 # for block in self.split_lines_into_blocks(cell_lines):
31 # cells.append(new_code_cell(input=block))
28 32 cell_lines = []
29 33 code_cell = True
30 if line.startswith(u'# </codecell>'):
34 elif line.startswith(u'# </codecell>'):
31 35 if not code_cell:
32 36 raise PyReaderError('Unexpected </codecell>')
33 37 code = u'\n'.join(cell_lines)
@@ -37,14 +41,19 b' class PyReader(NotebookReader):'
37 41 code_cell = False
38 42 else:
39 43 cell_lines.append(line)
40 # For lines we were not able to process,
41 for block in self.split_lines_into_blocks(cell_lines):
42 cells.append(new_code_cell(input=block))
44 # We can't use the ast to split blocks because there can be
45 # IPython syntax in the files.
46 # if cell_lines:
47 # for block in self.split_lines_into_blocks(cell_lines):
48 # cells.append(new_code_cell(input=block))
43 49 ws = new_worksheet(cells=cells)
44 50 nb = new_notebook(worksheets=[ws])
45 51 return nb
46 52
47 53 def split_lines_into_blocks(self, lines):
54 if len(lines) == 1:
55 yield lines[0]
56 raise StopIteration()
48 57 import ast
49 58 source = '\n'.join(lines)
50 59 code = ast.parse(source)
General Comments 0
You need to be logged in to leave comments. Login now