##// END OF EJS Templates
Adding rst and heading cells to the notebook format.
Brian Granger -
Show More
@@ -119,6 +119,16 b' def new_text_cell(cell_type, source=None, rendered=None):'
119 return cell
119 return cell
120
120
121
121
122 def new_heading_cell(source=None, level=1):
123 """Create a new section cell with a given integer level."""
124 cell = NotebookNode()
125 cell.cell_type = u'heading'
126 if source is not None:
127 cell.source = unicode(source)
128 cell.level = int(level)
129 return cell
130
131
122 def new_worksheet(name=None, cells=None):
132 def new_worksheet(name=None, cells=None):
123 """Create a worksheet by name with with a list of cells."""
133 """Create a worksheet by name with with a list of cells."""
124 ws = NotebookNode()
134 ws = NotebookNode()
@@ -18,7 +18,10 b' Authors:'
18
18
19 import re
19 import re
20 from .rwbase import NotebookReader, NotebookWriter
20 from .rwbase import NotebookReader, NotebookWriter
21 from .nbbase import new_code_cell, new_text_cell, new_worksheet, new_notebook
21 from .nbbase import (
22 new_code_cell, new_text_cell, new_worksheet,
23 new_notebook, new_heading_cell
24 )
22
25
23 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
24 # Code
27 # Code
@@ -39,28 +42,53 b' class PyReader(NotebookReader):'
39 lines = s.splitlines()
42 lines = s.splitlines()
40 cells = []
43 cells = []
41 cell_lines = []
44 cell_lines = []
45 kwargs = {}
42 state = u'codecell'
46 state = u'codecell'
43 for line in lines:
47 for line in lines:
44 if line.startswith(u'# <nbformat>') or _encoding_declaration_re.match(line):
48 if line.startswith(u'# <nbformat>') or _encoding_declaration_re.match(line):
45 pass
49 pass
46 elif line.startswith(u'# <codecell>'):
50 elif line.startswith(u'# <codecell>'):
47 cell = self.new_cell(state, cell_lines)
51 cell = self.new_cell(state, cell_lines, **kwargs)
48 if cell is not None:
52 if cell is not None:
49 cells.append(cell)
53 cells.append(cell)
50 state = u'codecell'
54 state = u'codecell'
51 cell_lines = []
55 cell_lines = []
56 kwargs = {}
52 elif line.startswith(u'# <htmlcell>'):
57 elif line.startswith(u'# <htmlcell>'):
53 cell = self.new_cell(state, cell_lines)
58 cell = self.new_cell(state, cell_lines, **kwargs)
54 if cell is not None:
59 if cell is not None:
55 cells.append(cell)
60 cells.append(cell)
56 state = u'htmlcell'
61 state = u'htmlcell'
57 cell_lines = []
62 cell_lines = []
63 kwargs = {}
58 elif line.startswith(u'# <markdowncell>'):
64 elif line.startswith(u'# <markdowncell>'):
59 cell = self.new_cell(state, cell_lines)
65 cell = self.new_cell(state, cell_lines, **kwargs)
60 if cell is not None:
66 if cell is not None:
61 cells.append(cell)
67 cells.append(cell)
62 state = u'markdowncell'
68 state = u'markdowncell'
63 cell_lines = []
69 cell_lines = []
70 kwargs = {}
71 elif line.startswith(u'# <rstcell>'):
72 cell = self.new_cell(state, cell_lines, **kwargs)
73 if cell is not None:
74 cells.append(cell)
75 state = u'rstcell'
76 cell_lines = []
77 kwargs = {}
78 elif line.startswith(u'# <headingcell'):
79 cell = self.new_cell(state, cell_lines, **kwargs)
80 if cell is not None:
81 cells.append(cell)
82 cell_lines = []
83 m = re.match(r'# <headingcell level=(?P<level>\d)>',line)
84 if m is not None:
85 state = u'headingcell'
86 kwargs = {}
87 kwargs['level'] = int(m.group('level'))
88 else:
89 state = u'codecell'
90 kwargs = {}
91 cell_lines = []
64 else:
92 else:
65 cell_lines.append(line)
93 cell_lines.append(line)
66 if cell_lines and state == u'codecell':
94 if cell_lines and state == u'codecell':
@@ -71,7 +99,7 b' class PyReader(NotebookReader):'
71 nb = new_notebook(worksheets=[ws])
99 nb = new_notebook(worksheets=[ws])
72 return nb
100 return nb
73
101
74 def new_cell(self, state, lines):
102 def new_cell(self, state, lines, **kwargs):
75 if state == u'codecell':
103 if state == u'codecell':
76 input = u'\n'.join(lines)
104 input = u'\n'.join(lines)
77 input = input.strip(u'\n')
105 input = input.strip(u'\n')
@@ -85,6 +113,15 b' class PyReader(NotebookReader):'
85 text = self._remove_comments(lines)
113 text = self._remove_comments(lines)
86 if text:
114 if text:
87 return new_text_cell(u'markdown',source=text)
115 return new_text_cell(u'markdown',source=text)
116 elif state == u'rstcell':
117 text = self._remove_comments(lines)
118 if text:
119 return new_text_cell(u'rst',source=text)
120 elif state == u'headingcell':
121 text = self._remove_comments(lines)
122 level = kwargs.get('level',1)
123 if text:
124 return new_heading_cell(source=text,level=level)
88
125
89 def _remove_comments(self, lines):
126 def _remove_comments(self, lines):
90 new_lines = []
127 new_lines = []
@@ -135,6 +172,19 b' class PyWriter(NotebookWriter):'
135 lines.extend([u'# <markdowncell>',u''])
172 lines.extend([u'# <markdowncell>',u''])
136 lines.extend([u'# ' + line for line in input.splitlines()])
173 lines.extend([u'# ' + line for line in input.splitlines()])
137 lines.append(u'')
174 lines.append(u'')
175 elif cell.cell_type == u'rst':
176 input = cell.get(u'source')
177 if input is not None:
178 lines.extend([u'# <rstcell>',u''])
179 lines.extend([u'# ' + line for line in input.splitlines()])
180 lines.append(u'')
181 elif cell.cell_type == u'heading':
182 input = cell.get(u'source')
183 level = cell.get(u'level',1)
184 if input is not None:
185 lines.extend([u'# <headingcell level=%s>' % level,u''])
186 lines.extend([u'# ' + line for line in input.splitlines()])
187 lines.append(u'')
138 lines.append('')
188 lines.append('')
139 return unicode('\n'.join(lines))
189 return unicode('\n'.join(lines))
140
190
@@ -64,6 +64,8 b' def rejoin_lines(nb):'
64 item = output.get(key, None)
64 item = output.get(key, None)
65 if isinstance(item, list):
65 if isinstance(item, list):
66 output[key] = u'\n'.join(item)
66 output[key] = u'\n'.join(item)
67 elif cell.cell_type == 'heading':
68 pass
67 else: # text cell
69 else: # text cell
68 for key in ['source', 'rendered']:
70 for key in ['source', 'rendered']:
69 item = cell.get(key, None)
71 item = cell.get(key, None)
@@ -90,6 +92,8 b' def split_lines(nb):'
90 item = output.get(key, None)
92 item = output.get(key, None)
91 if isinstance(item, basestring):
93 if isinstance(item, basestring):
92 output[key] = item.splitlines()
94 output[key] = item.splitlines()
95 elif cell.cell_type == 'heading':
96 pass
93 else: # text cell
97 else: # text cell
94 for key in ['source', 'rendered']:
98 for key in ['source', 'rendered']:
95 item = cell.get(key, None)
99 item = cell.get(key, None)
@@ -4,7 +4,7 b' from base64 import encodestring'
4 from ..nbbase import (
4 from ..nbbase import (
5 NotebookNode,
5 NotebookNode,
6 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
6 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
7 new_metadata, new_author
7 new_metadata, new_author, new_heading_cell
8 )
8 )
9
9
10 # some random base64-encoded *bytes*
10 # some random base64-encoded *bytes*
@@ -32,6 +32,16 b' ws.cells.append(new_text_cell('
32 rendered='A random array'
32 rendered='A random array'
33 ))
33 ))
34
34
35 ws.cells.append(new_text_cell(
36 u'rst',
37 source='A random array',
38 ))
39
40 ws.cells.append(new_heading_cell(
41 u'My Heading',
42 level=2
43 ))
44
35 ws.cells.append(new_code_cell(
45 ws.cells.append(new_code_cell(
36 input='a = numpy.random.rand(100)',
46 input='a = numpy.random.rand(100)',
37 prompt_number=2,
47 prompt_number=2,
@@ -96,6 +106,14 b' import numpy'
96
106
97 # A random array
107 # A random array
98
108
109 # <rstcell>
110
111 # A random array
112
113 # <headingcell level=2>
114
115 # My Heading
116
99 # <codecell>
117 # <codecell>
100
118
101 a = numpy.random.rand(100)
119 a = numpy.random.rand(100)
@@ -9,12 +9,12 b' class TestJSON(TestCase):'
9
9
10 def test_roundtrip(self):
10 def test_roundtrip(self):
11 s = writes(nb0)
11 s = writes(nb0)
12 # print
12 # print
13 # print pprint.pformat(nb0,indent=2)
13 # print pprint.pformat(nb0,indent=2)
14 # print
14 # print
15 # print pprint.pformat(reads(s),indent=2)
15 # print pprint.pformat(reads(s),indent=2)
16 # print
16 # print
17 # print s
17 # print s
18 self.assertEquals(reads(s),nb0)
18 self.assertEquals(reads(s),nb0)
19
19
20 def test_roundtrip_nosplit(self):
20 def test_roundtrip_nosplit(self):
@@ -3,7 +3,7 b' from unittest import TestCase'
3 from ..nbbase import (
3 from ..nbbase import (
4 NotebookNode,
4 NotebookNode,
5 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
5 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
6 new_author, new_metadata
6 new_author, new_metadata, new_heading_cell
7 )
7 )
8
8
9 class TestCell(TestCase):
9 class TestCell(TestCase):
@@ -59,6 +59,27 b' class TestCell(TestCase):'
59 self.assertEquals(tc.source, u'hi')
59 self.assertEquals(tc.source, u'hi')
60 self.assertEquals(tc.rendered, u'hi')
60 self.assertEquals(tc.rendered, u'hi')
61
61
62 def test_empty_rst_cell(self):
63 tc = new_text_cell(u'rst')
64 self.assertEquals(tc.cell_type, u'rst')
65 self.assertEquals(u'source' not in tc, True)
66 self.assertEquals(u'rendered' not in tc, True)
67
68 def test_rst_cell(self):
69 tc = new_text_cell(u'rst', 'hi', 'hi')
70 self.assertEquals(tc.source, u'hi')
71 self.assertEquals(tc.rendered, u'hi')
72
73 def test_empty_heading_cell(self):
74 tc = new_heading_cell()
75 self.assertEquals(tc.cell_type, u'heading')
76 self.assertEquals(u'source' not in tc, True)
77
78 def test_heading_cell(self):
79 tc = new_heading_cell(u'My Heading', level=2)
80 self.assertEquals(tc.source, u'My Heading')
81 self.assertEquals(tc.level, 2)
82
62
83
63 class TestWorksheet(TestCase):
84 class TestWorksheet(TestCase):
64
85
General Comments 0
You need to be logged in to leave comments. Login now