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 |
|
|
12 | ||
13 |
|
|
13 | # print pprint.pformat(nb0,indent=2) | |
14 |
|
|
14 | ||
15 |
|
|
15 | # print pprint.pformat(reads(s),indent=2) | |
16 |
|
|
16 | ||
17 |
|
|
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