##// END OF EJS Templates
Tweak to notebook -> .py export, at Fernando's suggestion.
Thomas Kluyver -
Show More
@@ -1,150 +1,150 b''
1 """Read and write notebooks as regular .py files.
1 """Read and write notebooks as regular .py files.
2
2
3 Authors:
3 Authors:
4
4
5 * Brian Granger
5 * Brian Granger
6 """
6 """
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
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 new_code_cell, new_text_cell, new_worksheet, new_notebook
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Code
24 # Code
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 _encoding_declaration_re = re.compile(r"^#\s*coding[:=]\s*([-\w.]+)")
27 _encoding_declaration_re = re.compile(r"^#\s*coding[:=]\s*([-\w.]+)")
28
28
29 class PyReaderError(Exception):
29 class PyReaderError(Exception):
30 pass
30 pass
31
31
32
32
33 class PyReader(NotebookReader):
33 class PyReader(NotebookReader):
34
34
35 def reads(self, s, **kwargs):
35 def reads(self, s, **kwargs):
36 return self.to_notebook(s,**kwargs)
36 return self.to_notebook(s,**kwargs)
37
37
38 def to_notebook(self, s, **kwargs):
38 def to_notebook(self, s, **kwargs):
39 lines = s.splitlines()
39 lines = s.splitlines()
40 cells = []
40 cells = []
41 cell_lines = []
41 cell_lines = []
42 state = u'codecell'
42 state = u'codecell'
43 for line in lines:
43 for line in lines:
44 if line.startswith(u'# <nbformat>') or _encoding_declaration_re.match(line):
44 if line.startswith(u'# <nbformat>') or _encoding_declaration_re.match(line):
45 pass
45 pass
46 elif line.startswith(u'# <codecell>'):
46 elif line.startswith(u'# <codecell>'):
47 cell = self.new_cell(state, cell_lines)
47 cell = self.new_cell(state, cell_lines)
48 if cell is not None:
48 if cell is not None:
49 cells.append(cell)
49 cells.append(cell)
50 state = u'codecell'
50 state = u'codecell'
51 cell_lines = []
51 cell_lines = []
52 elif line.startswith(u'# <htmlcell>'):
52 elif line.startswith(u'# <htmlcell>'):
53 cell = self.new_cell(state, cell_lines)
53 cell = self.new_cell(state, cell_lines)
54 if cell is not None:
54 if cell is not None:
55 cells.append(cell)
55 cells.append(cell)
56 state = u'htmlcell'
56 state = u'htmlcell'
57 cell_lines = []
57 cell_lines = []
58 elif line.startswith(u'# <markdowncell>'):
58 elif line.startswith(u'# <markdowncell>'):
59 cell = self.new_cell(state, cell_lines)
59 cell = self.new_cell(state, cell_lines)
60 if cell is not None:
60 if cell is not None:
61 cells.append(cell)
61 cells.append(cell)
62 state = u'markdowncell'
62 state = u'markdowncell'
63 cell_lines = []
63 cell_lines = []
64 else:
64 else:
65 cell_lines.append(line)
65 cell_lines.append(line)
66 if cell_lines and state == u'codecell':
66 if cell_lines and state == u'codecell':
67 cell = self.new_cell(state, cell_lines)
67 cell = self.new_cell(state, cell_lines)
68 if cell is not None:
68 if cell is not None:
69 cells.append(cell)
69 cells.append(cell)
70 ws = new_worksheet(cells=cells)
70 ws = new_worksheet(cells=cells)
71 nb = new_notebook(worksheets=[ws])
71 nb = new_notebook(worksheets=[ws])
72 return nb
72 return nb
73
73
74 def new_cell(self, state, lines):
74 def new_cell(self, state, lines):
75 if state == u'codecell':
75 if state == u'codecell':
76 input = u'\n'.join(lines)
76 input = u'\n'.join(lines)
77 input = input.strip(u'\n')
77 input = input.strip(u'\n')
78 if input:
78 if input:
79 return new_code_cell(input=input)
79 return new_code_cell(input=input)
80 elif state == u'htmlcell':
80 elif state == u'htmlcell':
81 text = self._remove_comments(lines)
81 text = self._remove_comments(lines)
82 if text:
82 if text:
83 return new_text_cell(u'html',source=text)
83 return new_text_cell(u'html',source=text)
84 elif state == u'markdowncell':
84 elif state == u'markdowncell':
85 text = self._remove_comments(lines)
85 text = self._remove_comments(lines)
86 if text:
86 if text:
87 return new_text_cell(u'markdown',source=text)
87 return new_text_cell(u'markdown',source=text)
88
88
89 def _remove_comments(self, lines):
89 def _remove_comments(self, lines):
90 new_lines = []
90 new_lines = []
91 for line in lines:
91 for line in lines:
92 if line.startswith(u'#'):
92 if line.startswith(u'#'):
93 new_lines.append(line[2:])
93 new_lines.append(line[2:])
94 else:
94 else:
95 new_lines.append(line)
95 new_lines.append(line)
96 text = u'\n'.join(new_lines)
96 text = u'\n'.join(new_lines)
97 text = text.strip(u'\n')
97 text = text.strip(u'\n')
98 return text
98 return text
99
99
100 def split_lines_into_blocks(self, lines):
100 def split_lines_into_blocks(self, lines):
101 if len(lines) == 1:
101 if len(lines) == 1:
102 yield lines[0]
102 yield lines[0]
103 raise StopIteration()
103 raise StopIteration()
104 import ast
104 import ast
105 source = '\n'.join(lines)
105 source = '\n'.join(lines)
106 code = ast.parse(source)
106 code = ast.parse(source)
107 starts = [x.lineno-1 for x in code.body]
107 starts = [x.lineno-1 for x in code.body]
108 for i in range(len(starts)-1):
108 for i in range(len(starts)-1):
109 yield '\n'.join(lines[starts[i]:starts[i+1]]).strip('\n')
109 yield '\n'.join(lines[starts[i]:starts[i+1]]).strip('\n')
110 yield '\n'.join(lines[starts[-1]:]).strip('\n')
110 yield '\n'.join(lines[starts[-1]:]).strip('\n')
111
111
112
112
113 class PyWriter(NotebookWriter):
113 class PyWriter(NotebookWriter):
114
114
115 def writes(self, nb, **kwargs):
115 def writes(self, nb, **kwargs):
116 lines = []
116 lines = [u'# coding: utf-8']
117 lines.extend([u'# coding: utf-8', u'# <nbformat>2</nbformat>',''])
117 lines.extend([u'# <nbformat>2</nbformat>',''])
118 for ws in nb.worksheets:
118 for ws in nb.worksheets:
119 for cell in ws.cells:
119 for cell in ws.cells:
120 if cell.cell_type == u'code':
120 if cell.cell_type == u'code':
121 input = cell.get(u'input')
121 input = cell.get(u'input')
122 if input is not None:
122 if input is not None:
123 lines.extend([u'# <codecell>',u''])
123 lines.extend([u'# <codecell>',u''])
124 lines.extend(input.splitlines())
124 lines.extend(input.splitlines())
125 lines.append(u'')
125 lines.append(u'')
126 elif cell.cell_type == u'html':
126 elif cell.cell_type == u'html':
127 input = cell.get(u'source')
127 input = cell.get(u'source')
128 if input is not None:
128 if input is not None:
129 lines.extend([u'# <htmlcell>',u''])
129 lines.extend([u'# <htmlcell>',u''])
130 lines.extend([u'# ' + line for line in input.splitlines()])
130 lines.extend([u'# ' + line for line in input.splitlines()])
131 lines.append(u'')
131 lines.append(u'')
132 elif cell.cell_type == u'markdown':
132 elif cell.cell_type == u'markdown':
133 input = cell.get(u'source')
133 input = cell.get(u'source')
134 if input is not None:
134 if input is not None:
135 lines.extend([u'# <markdowncell>',u''])
135 lines.extend([u'# <markdowncell>',u''])
136 lines.extend([u'# ' + line for line in input.splitlines()])
136 lines.extend([u'# ' + line for line in input.splitlines()])
137 lines.append(u'')
137 lines.append(u'')
138 lines.append('')
138 lines.append('')
139 return unicode('\n'.join(lines))
139 return unicode('\n'.join(lines))
140
140
141
141
142 _reader = PyReader()
142 _reader = PyReader()
143 _writer = PyWriter()
143 _writer = PyWriter()
144
144
145 reads = _reader.reads
145 reads = _reader.reads
146 read = _reader.read
146 read = _reader.read
147 to_notebook = _reader.to_notebook
147 to_notebook = _reader.to_notebook
148 write = _writer.write
148 write = _writer.write
149 writes = _writer.writes
149 writes = _writer.writes
150
150
General Comments 0
You need to be logged in to leave comments. Login now