##// END OF EJS Templates
New .py notebook format implemented.
Brian E. Granger -
Show More
@@ -66,7 +66,7 def new_code_cell(input=None, prompt_number=None, outputs=None,
66 else:
66 else:
67 cell.outputs = outputs
67 cell.outputs = outputs
68 if collapsed is not None:
68 if collapsed is not None:
69 cell.collapsed = collapsed
69 cell.collapsed = bool(collapsed)
70
70
71 return cell
71 return cell
72
72
@@ -93,7 +93,8 def new_worksheet(name=None, cells=None):
93 return ws
93 return ws
94
94
95
95
96 def new_notebook(name=None, id=None, worksheets=None):
96 def new_notebook(name=None, id=None, worksheets=None, author=None, email=None,
97 created=None, saved=None, license=None):
97 """Create a notebook by name, id and a list of worksheets."""
98 """Create a notebook by name, id and a list of worksheets."""
98 nb = NotebookNode()
99 nb = NotebookNode()
99 nb.nbformat = 2
100 nb.nbformat = 2
@@ -107,5 +108,15 def new_notebook(name=None, id=None, worksheets=None):
107 nb.worksheets = []
108 nb.worksheets = []
108 else:
109 else:
109 nb.worksheets = list(worksheets)
110 nb.worksheets = list(worksheets)
111 if author is not None:
112 nb.author = unicode(author)
113 if email is not None:
114 nb.email = unicode(email)
115 if created is not None:
116 nb.created = unicode(created)
117 if saved is not None:
118 nb.saved = unicode(saved)
119 if license is not None:
120 nb.license = unicode(license)
110 return nb
121 return nb
111
122
@@ -1,7 +1,7
1 """Read and write notebooks as regular .py files."""
1 """Read and write notebooks as regular .py files."""
2
2
3 from .rwbase import NotebookReader, NotebookWriter
3 from .rwbase import NotebookReader, NotebookWriter
4 from .nbbase import new_code_cell, new_worksheet, new_notebook
4 from .nbbase import new_code_cell, new_text_cell, new_worksheet, new_notebook
5
5
6
6
7 class PyReaderError(Exception):
7 class PyReaderError(Exception):
@@ -17,39 +17,64 class PyReader(NotebookReader):
17 lines = s.splitlines()
17 lines = s.splitlines()
18 cells = []
18 cells = []
19 cell_lines = []
19 cell_lines = []
20 code_cell = False
20 state = u'codecell'
21 for line in lines:
21 for line in lines:
22 if line.startswith(u'# <nbformat>'):
22 if line.startswith(u'# <nbformat>'):
23 pass
23 pass
24 elif line.startswith(u'# <codecell>'):
24 elif line.startswith(u'# <codecell>'):
25 if code_cell:
25 cell = self.new_cell(state, cell_lines)
26 raise PyReaderError('Unexpected <codecell>')
26 if cell is not None:
27 # We can't use the ast to split blocks because there can be
27 cells.append(cell)
28 # IPython syntax in the files.
28 state = u'codecell'
29 # if cell_lines:
29 cell_lines = []
30 # for block in self.split_lines_into_blocks(cell_lines):
30 elif line.startswith(u'# <htmlcell>'):
31 # cells.append(new_code_cell(input=block))
31 cell = self.new_cell(state, cell_lines)
32 if cell is not None:
33 cells.append(cell)
34 state = u'htmlcell'
35 cell_lines = []
36 elif line.startswith(u'# <markdowncell>'):
37 cell = self.new_cell(state, cell_lines)
38 if cell is not None:
39 cells.append(cell)
40 state = u'markdowncell'
32 cell_lines = []
41 cell_lines = []
33 code_cell = True
34 elif line.startswith(u'# </codecell>'):
35 if not code_cell:
36 raise PyReaderError('Unexpected </codecell>')
37 code = u'\n'.join(cell_lines)
38 code = code.strip(u'\n')
39 if code:
40 cells.append(new_code_cell(input=code))
41 code_cell = False
42 else:
42 else:
43 cell_lines.append(line)
43 cell_lines.append(line)
44 # We can't use the ast to split blocks because there can be
44 if cell_lines and state == u'codecell':
45 # IPython syntax in the files.
45 cell = self.new_cell(state, cell_lines)
46 # if cell_lines:
46 if cell is not None:
47 # for block in self.split_lines_into_blocks(cell_lines):
47 cells.append(cell)
48 # cells.append(new_code_cell(input=block))
49 ws = new_worksheet(cells=cells)
48 ws = new_worksheet(cells=cells)
50 nb = new_notebook(worksheets=[ws])
49 nb = new_notebook(worksheets=[ws])
51 return nb
50 return nb
52
51
52 def new_cell(self, state, lines):
53 if state == u'codecell':
54 input = u'\n'.join(lines)
55 input = input.strip(u'\n')
56 if input:
57 return new_code_cell(input=input)
58 elif state == u'htmlcell':
59 text = self._remove_comments(lines)
60 if text:
61 return new_text_cell(u'html',source=text)
62 elif state == u'markdowncell':
63 text = self._remove_comments(lines)
64 if text:
65 return new_text_cell(u'markdown',source=text)
66
67 def _remove_comments(self, lines):
68 new_lines = []
69 for line in lines:
70 if line.startswith(u'#'):
71 new_lines.append(line[2:])
72 else:
73 new_lines.append(line)
74 text = u'\n'.join(new_lines)
75 text = text.strip(u'\n')
76 return text
77
53 def split_lines_into_blocks(self, lines):
78 def split_lines_into_blocks(self, lines):
54 if len(lines) == 1:
79 if len(lines) == 1:
55 yield lines[0]
80 yield lines[0]
@@ -67,15 +92,27 class PyWriter(NotebookWriter):
67
92
68 def writes(self, nb, **kwargs):
93 def writes(self, nb, **kwargs):
69 lines = []
94 lines = []
70 lines.extend(['# <nbformat>2</nbformat>',''])
95 lines.extend([u'# <nbformat>2</nbformat>',''])
71 for ws in nb.worksheets:
96 for ws in nb.worksheets:
72 for cell in ws.cells:
97 for cell in ws.cells:
73 if cell.cell_type == 'code':
98 if cell.cell_type == u'code':
74 input = cell.get('input')
99 input = cell.get(u'input')
75 if input is not None:
100 if input is not None:
76 lines.extend([u'# <codecell>',u''])
101 lines.extend([u'# <codecell>',u''])
77 lines.extend(input.splitlines())
102 lines.extend(input.splitlines())
78 lines.extend([u'',u'# </codecell>'])
103 lines.append(u'')
104 elif cell.cell_type == u'html':
105 input = cell.get(u'source')
106 if input is not None:
107 lines.extend([u'# <htmlcell>',u''])
108 lines.extend([u'# ' + line for line in input.splitlines()])
109 lines.append(u'')
110 elif cell.cell_type == u'markdown':
111 input = cell.get(u'source')
112 if input is not None:
113 lines.extend([u'# <markdowncell>',u''])
114 lines.extend([u'# ' + line for line in input.splitlines()])
115 lines.append(u'')
79 lines.append('')
116 lines.append('')
80 return unicode('\n'.join(lines))
117 return unicode('\n'.join(lines))
81
118
@@ -92,6 +92,11 class XMLReader(NotebookReader):
92 def to_notebook(self, root, **kwargs):
92 def to_notebook(self, root, **kwargs):
93 nbname = _get_text(root,'name')
93 nbname = _get_text(root,'name')
94 nbid = _get_text(root,'id')
94 nbid = _get_text(root,'id')
95 nbauthor = _get_text(root,'author')
96 nbemail = _get_text(root,'email')
97 nblicense = _get_text(root,'license')
98 nbcreated = _get_text(root,'created')
99 nbsaved = _get_text(root,'saved')
95
100
96 worksheets = []
101 worksheets = []
97 for ws_e in root.find('worksheets').getiterator('worksheet'):
102 for ws_e in root.find('worksheets').getiterator('worksheet'):
@@ -136,7 +141,8 class XMLReader(NotebookReader):
136 ws = new_worksheet(name=wsname,cells=cells)
141 ws = new_worksheet(name=wsname,cells=cells)
137 worksheets.append(ws)
142 worksheets.append(ws)
138
143
139 nb = new_notebook(name=nbname,id=nbid,worksheets=worksheets)
144 nb = new_notebook(name=nbname,id=nbid,worksheets=worksheets,author=nbauthor,
145 email=nbemail,license=nblicense,saved=nbsaved,created=nbcreated)
140 return nb
146 return nb
141
147
142
148
@@ -146,6 +152,11 class XMLWriter(NotebookWriter):
146 nb_e = ET.Element('notebook')
152 nb_e = ET.Element('notebook')
147 _set_text(nb,'name',nb_e,'name')
153 _set_text(nb,'name',nb_e,'name')
148 _set_text(nb,'id',nb_e,'id')
154 _set_text(nb,'id',nb_e,'id')
155 _set_text(nb,'author',nb_e,'author')
156 _set_text(nb,'email',nb_e,'email')
157 _set_text(nb,'license',nb_e,'license')
158 _set_text(nb,'created',nb_e,'created')
159 _set_text(nb,'saved',nb_e,'saved')
149 _set_int(nb,'nbformat',nb_e,'nbformat')
160 _set_int(nb,'nbformat',nb_e,'nbformat')
150 wss_e = ET.SubElement(nb_e,'worksheets')
161 wss_e = ET.SubElement(nb_e,'worksheets')
151 for ws in nb.worksheets:
162 for ws in nb.worksheets:
@@ -22,8 +22,8 ws.cells.append(new_code_cell(
22
22
23 ws.cells.append(new_text_cell(
23 ws.cells.append(new_text_cell(
24 u'markdown',
24 u'markdown',
25 source='Some NumPy Examples',
25 source='A random array',
26 rendered='Some NumPy Examples'
26 rendered='A random array'
27 ))
27 ))
28
28
29 ws.cells.append(new_code_cell(
29 ws.cells.append(new_code_cell(
@@ -63,26 +63,36 ws.cells.append(new_code_cell(
63
63
64 nb0 = new_notebook(
64 nb0 = new_notebook(
65 name='nb0',
65 name='nb0',
66 worksheets=[ws, new_worksheet(name='worksheet2')]
66 worksheets=[ws, new_worksheet(name='worksheet2')],
67 author='Bart Simpson',
68 email='bsimple@fox.com',
69 saved='ISO8601_goes_here',
70 created='ISO8601_goes_here',
71 license='BSD'
67 )
72 )
68
73
69 nb0_py = """# <nbformat>2</nbformat>
74 nb0_py = """# <nbformat>2</nbformat>
70
75
76 # <htmlcell>
77
78 # Some NumPy Examples
79
71 # <codecell>
80 # <codecell>
72
81
73 import numpy
82 import numpy
74
83
75 # </codecell>
84 # <markdowncell>
85
86 # A random array
87
76 # <codecell>
88 # <codecell>
77
89
78 a = numpy.random.rand(100)
90 a = numpy.random.rand(100)
79
91
80 # </codecell>
81 # <codecell>
92 # <codecell>
82
93
83 print a
94 print a
84
95
85 # </codecell>
86 """
96 """
87
97
88
98
General Comments 0
You need to be logged in to leave comments. Login now