##// END OF EJS Templates
Added collapsed field to the code cell.
Brian E. Granger -
Show More
@@ -1,408 +1,421 b''
1 1
2 2 //============================================================================
3 3 // CodeCell
4 4 //============================================================================
5 5
6 6 var IPython = (function (IPython) {
7 7
8 8 var utils = IPython.utils;
9 9
10 10 var CodeCell = function (notebook) {
11 11 this.code_mirror = null;
12 12 this.input_prompt_number = ' ';
13 13 this.is_completing = false;
14 14 this.completion_cursor = null;
15 15 this.outputs = [];
16 this.collapsed = false;
16 17 IPython.Cell.apply(this, arguments);
17 18 };
18 19
19 20
20 21 CodeCell.prototype = new IPython.Cell();
21 22
22 23
23 24 CodeCell.prototype.create_element = function () {
24 25 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell vbox');
25 26 var input = $('<div></div>').addClass('input hbox');
26 27 input.append($('<div/>').addClass('prompt input_prompt'));
27 28 var input_area = $('<div/>').addClass('input_area box-flex1');
28 29 this.code_mirror = CodeMirror(input_area.get(0), {
29 30 indentUnit : 4,
30 31 mode: 'python',
31 32 theme: 'ipython',
32 33 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
33 34 });
34 35 input.append(input_area);
35 36 var output = $('<div></div>').addClass('output vbox');
36 37 cell.append(input).append(output);
37 38 this.element = cell;
38 39 this.collapse()
39 40 };
40 41
41 42
42 43 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
43 44 // This method gets called in CodeMirror's onKeyDown/onKeyPress handlers and
44 45 // is used to provide custom key handling. Its return value is used to determine
45 46 // if CodeMirror should ignore the event: true = ignore, false = don't ignore.
46 47 if (event.keyCode === 13 && event.shiftKey) {
47 48 // Always ignore shift-enter in CodeMirror as we handle it.
48 49 return true;
49 50 } else if (event.keyCode === 9) {
50 51 var cur = editor.getCursor();
51 52 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur).trim();
52 53 if (pre_cursor === "") {
53 54 // Don't autocomplete if the part of the line before the cursor is empty.
54 55 // In this case, let CodeMirror handle indentation.
55 56 return false;
56 57 } else {
57 58 // Autocomplete the current line.
58 59 event.stop();
59 60 var line = editor.getLine(cur.line);
60 61 this.is_completing = true;
61 62 this.completion_cursor = cur;
62 63 IPython.notebook.complete_cell(this, line, cur.ch);
63 64 return true;
64 65 }
65 66 } else if (event.keyCode === 8 && event.type == 'keydown') {
66 67 // If backspace and the line ends with 4 spaces, remove them.
67 68 var cur = editor.getCursor();
68 69 var line = editor.getLine(cur.line);
69 70 var ending = line.slice(-4);
70 71 if (ending === ' ') {
71 72 editor.replaceRange('',
72 73 {line: cur.line, ch: cur.ch-4},
73 74 {line: cur.line, ch: cur.ch}
74 75 );
75 76 event.stop();
76 77 return true;
77 78 } else {
78 79 return false;
79 80 };
80 81 } else {
81 82 if (this.is_completing && this.completion_cursor !== editor.getCursor()) {
82 83 this.is_completing = false;
83 84 this.completion_cursor = null;
84 85 }
85 86 return false;
86 87 };
87 88 };
88 89
89 90
90 91 CodeCell.prototype.finish_completing = function (matched_text, matches) {
91 92 if (!this.is_completing || matches.length === 0) {return;}
92 93 // console.log("Got matches", matched_text, matches);
93 94
94 95 var that = this;
95 96 var cur = this.completion_cursor;
96 97 var complete = $('<div/>').addClass('completions');
97 98 var select = $('<select/>').attr('multiple','true');
98 99 for (var i=0; i<matches.length; ++i) {
99 100 select.append($('<option/>').text(matches[i]));
100 101 }
101 102 select.children().first().attr('selected','true');
102 103 select.attr('size',Math.min(10,matches.length));
103 104 var pos = this.code_mirror.cursorCoords();
104 105 complete.css('left',pos.x+'px');
105 106 complete.css('top',pos.yBot+'px');
106 107 complete.append(select);
107 108
108 109 $('body').append(complete);
109 110 var done = false;
110 111
111 112 var insert = function (selected_text) {
112 113 that.code_mirror.replaceRange(
113 114 selected_text,
114 115 {line: cur.line, ch: (cur.ch-matched_text.length)},
115 116 {line: cur.line, ch: cur.ch}
116 117 );
117 118 };
118 119
119 120 var close = function () {
120 121 if (done) return;
121 122 done = true;
122 123 complete.remove();
123 124 that.is_completing = false;
124 125 that.completion_cursor = null;
125 126 };
126 127
127 128 var pick = function () {
128 129 insert(select.val()[0]);
129 130 close();
130 131 setTimeout(function(){that.code_mirror.focus();}, 50);
131 132 };
132 133
133 134 select.blur(close);
134 135 select.keydown(function (event) {
135 136 var code = event.which;
136 137 if (code === 13 || code === 32) {
137 138 // Pressing SPACE or ENTER will cause a pick
138 139 event.stopPropagation();
139 140 event.preventDefault();
140 141 pick();
141 142 } else if (code === 38 || code === 40) {
142 143 // We don't want the document keydown handler to handle UP/DOWN,
143 144 // but we want the default action.
144 145 event.stopPropagation();
145 146 } else {
146 147 // All other key presses simple exit completion.
147 148 event.stopPropagation();
148 149 event.preventDefault();
149 150 close();
150 151 that.code_mirror.focus();
151 152 }
152 153 });
153 154 // Double click also causes a pick.
154 155 select.dblclick(pick);
155 156 select.focus();
156 157 };
157 158
158 159
159 160 CodeCell.prototype.select = function () {
160 161 IPython.Cell.prototype.select.apply(this);
161 162 // Todo: this dance is needed because as of CodeMirror 2.12, focus is
162 163 // not causing the cursor to blink if the editor is empty initially.
163 164 // While this seems to fix the issue, this should be fixed
164 165 // in CodeMirror proper.
165 166 var s = this.code_mirror.getValue();
166 167 if (s === '') this.code_mirror.setValue('.');
167 168 this.code_mirror.focus();
168 169 if (s === '') this.code_mirror.setValue('');
169 170 };
170 171
171 172
172 173 CodeCell.prototype.append_output = function (json) {
173 174 this.expand();
174 175 if (json.output_type === 'pyout') {
175 176 this.append_pyout(json);
176 177 } else if (json.output_type === 'pyerr') {
177 178 this.append_pyerr(json);
178 179 } else if (json.output_type === 'display_data') {
179 180 this.append_display_data(json);
180 181 } else if (json.output_type === 'stream') {
181 182 this.append_stream(json);
182 183 };
183 184 this.outputs.push(json);
184 185 };
185 186
186 187
187 188 CodeCell.prototype.append_pyout = function (json) {
188 189 n = json.prompt_number || ' ';
189 190 var toinsert = $("<div/>").addClass("output_pyout hbox");
190 191 toinsert.append($('<div/>').
191 192 addClass('prompt output_prompt').
192 193 html('Out[' + n + ']:')
193 194 );
194 195 this.append_mime_type(json, toinsert).addClass('output_area');
195 196 toinsert.children().last().addClass("box_flex1 pyout_area");
196 197 this.element.find("div.output").append(toinsert);
197 198 // If we just output latex, typeset it.
198 199 if (json.latex !== undefined) {
199 200 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
200 201 };
201 202 };
202 203
203 204
204 205 CodeCell.prototype.append_pyerr = function (json) {
205 206 var tb = json.traceback;
206 207 if (tb !== undefined) {
207 208 var s = '';
208 209 var len = tb.length;
209 210 for (var i=0; i<len; i++) {
210 211 s = s + tb[i] + '\n';
211 212 }
212 213 s = s + '\n';
213 214 this.append_text(s).addClass('output_area');
214 215 };
215 216 };
216 217
217 218
218 219 CodeCell.prototype.append_stream = function (json) {
219 220 this.append_text(json.text).addClass('output_area');
220 221 };
221 222
222 223
223 224 CodeCell.prototype.append_display_data = function (json) {
224 225 this.append_mime_type(json).addClass('output_area');
225 226 };
226 227
227 228
228 229 CodeCell.prototype.append_mime_type = function (json, element) {
229 230 if (json.html !== undefined) {
230 231 this.append_html(json.html, element);
231 232 } else if (json.latex !== undefined) {
232 233 this.append_latex(json.latex, element);
233 234 // If it is undefined, then we just appended to div.output, which
234 235 // makes the latex visible and we can typeset it. The typesetting
235 236 // has to be done after the latex is on the page.
236 237 if (element === undefined) {
237 238 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
238 239 };
239 240 } else if (json.svg !== undefined) {
240 241 this.append_svg(json.svg, element);
241 242 } else if (json.png !== undefined) {
242 243 this.append_png(json.png, element);
243 244 } else if (json.jpeg !== undefined) {
244 245 this.append_jpeg(json.jpeg, element);
245 246 } else if (json.text !== undefined) {
246 247 this.append_text(json.text, element);
247 248 };
248 249 return element;
249 250 };
250 251
251 252
252 253 CodeCell.prototype.append_html = function (html, element) {
253 254 element = element || this.element.find("div.output");
254 255 var toinsert = $("<div/>").addClass("output_html");
255 256 toinsert.append(html);
256 257 element.append(toinsert);
257 258 return element;
258 259 }
259 260
260 261
261 262 CodeCell.prototype.append_text = function (data, element) {
262 263 element = element || this.element.find("div.output");
263 264 var toinsert = $("<div/>").addClass("output_stream");
264 265 toinsert.append($("<pre/>").html(utils.fixConsole(data)));
265 266 element.append(toinsert);
266 267 return element;
267 268 };
268 269
269 270
270 271 CodeCell.prototype.append_svg = function (svg, element) {
271 272 element = element || this.element.find("div.output");
272 273 var toinsert = $("<div/>").addClass("output_svg");
273 274 toinsert.append(svg);
274 275 element.append(toinsert);
275 276 return element;
276 277 };
277 278
278 279
279 280 CodeCell.prototype.append_png = function (png, element) {
280 281 element = element || this.element.find("div.output");
281 282 var toinsert = $("<div/>").addClass("output_png");
282 283 toinsert.append($("<img/>").attr('src','data:image/png;base64,'+png));
283 284 element.append(toinsert);
284 285 return element;
285 286 };
286 287
287 288
288 289 CodeCell.prototype.append_jpeg = function (jpeg, element) {
289 290 element = element || this.element.find("div.output");
290 291 var toinsert = $("<div/>").addClass("output_jpeg");
291 292 toinsert.append($("<img/>").attr('src','data:image/jpeg;base64,'+jpeg));
292 293 element.append(toinsert);
293 294 return element;
294 295 };
295 296
296 297
297 298 CodeCell.prototype.append_latex = function (latex, element) {
298 299 // This method cannot do the typesetting because the latex first has to
299 300 // be on the page.
300 301 element = element || this.element.find("div.output");
301 302 var toinsert = $("<div/>").addClass("output_latex");
302 303 toinsert.append(latex);
303 304 element.append(toinsert);
304 305 return element;
305 306 }
306 307
307 308
308 309 CodeCell.prototype.clear_output = function () {
309 310 this.element.find("div.output").html("");
310 311 this.outputs = [];
311 312 };
312 313
313 314
314 315 CodeCell.prototype.clear_input = function () {
315 316 this.code_mirror.setValue('');
316 317 };
317 318
318 319
319 320 CodeCell.prototype.collapse = function () {
320 this.element.find('div.output').hide();
321 if (!this.collapsed) {
322 this.element.find('div.output').hide();
323 this.collapsed = true;
324 };
321 325 };
322 326
323 327
324 328 CodeCell.prototype.expand = function () {
325 this.element.find('div.output').show();
329 if (this.collapsed) {
330 this.element.find('div.output').show();
331 this.collapsed = false;
332 };
326 333 };
327 334
328 335
329 336 CodeCell.prototype.set_input_prompt = function (number) {
330 337 var n = number || ' ';
331 338 this.input_prompt_number = n
332 339 this.element.find('div.input_prompt').html('In&nbsp;[' + n + ']:');
333 340 };
334 341
335 342
336 343 CodeCell.prototype.get_code = function () {
337 344 return this.code_mirror.getValue();
338 345 };
339 346
340 347
341 348 CodeCell.prototype.set_code = function (code) {
342 349 return this.code_mirror.setValue(code);
343 350 };
344 351
345 352
346 353 CodeCell.prototype.at_top = function () {
347 354 var cursor = this.code_mirror.getCursor();
348 355 if (cursor.line === 0) {
349 356 return true;
350 357 } else {
351 358 return false;
352 359 }
353 360 };
354 361
355 362
356 363 CodeCell.prototype.at_bottom = function () {
357 364 var cursor = this.code_mirror.getCursor();
358 365 if (cursor.line === (this.code_mirror.lineCount()-1)) {
359 366 return true;
360 367 } else {
361 368 return false;
362 369 }
363 370 };
364 371
365 372
366 373 CodeCell.prototype.fromJSON = function (data) {
367 374 // console.log('Import from JSON:', data);
368 375 if (data.cell_type === 'code') {
369 376 if (data.input !== undefined) {
370 377 this.set_code(data.input);
371 378 }
372 379 if (data.prompt_number !== undefined) {
373 380 this.set_input_prompt(data.prompt_number);
374 381 } else {
375 382 this.set_input_prompt();
376 383 };
377 384 var len = data.outputs.length;
378 385 for (var i=0; i<len; i++) {
379 386 this.append_output(data.outputs[i]);
380 387 };
388 if (data.collapsed !== undefined) {
389 if (data.collapsed) {
390 this.collapse();
391 };
392 };
381 393 };
382 394 };
383 395
384 396
385 397 CodeCell.prototype.toJSON = function () {
386 398 var data = {};
387 399 data.input = this.get_code();
388 400 data.cell_type = 'code';
389 401 if (this.input_prompt_number !== ' ') {
390 402 data.prompt_number = this.input_prompt_number
391 403 };
392 404 var outputs = [];
393 405 var len = this.outputs.length;
394 406 for (var i=0; i<len; i++) {
395 407 outputs[i] = this.outputs[i];
396 408 };
397 409 data.outputs = outputs;
398 410 data.language = 'python';
411 data.collapsed = this.collapsed;
399 412 // console.log('Export to JSON:',data);
400 413 return data;
401 414 };
402 415
403 416
404 417 IPython.CodeCell = CodeCell;
405 418
406 419 return IPython;
407 420 }(IPython));
408 421
@@ -1,108 +1,111 b''
1 1 """The basic dict based notebook format."""
2 2
3 3 import pprint
4 4 import uuid
5 5
6 6 from IPython.utils.ipstruct import Struct
7 7
8 8
9 9 class NotebookNode(Struct):
10 10 pass
11 11
12 12
13 13 def from_dict(d):
14 14 if isinstance(d, dict):
15 15 newd = NotebookNode()
16 16 for k,v in d.items():
17 17 newd[k] = from_dict(v)
18 18 return newd
19 19 elif isinstance(d, (tuple, list)):
20 20 return [from_dict(i) for i in d]
21 21 else:
22 22 return d
23 23
24 24
25 25 def new_output(output_type=None, output_text=None, output_png=None,
26 26 output_html=None, output_svg=None, output_latex=None, output_json=None,
27 27 output_javascript=None, output_jpeg=None, prompt_number=None):
28 28 """Create a new code cell with input and output"""
29 29 output = NotebookNode()
30 30 if output_type is not None:
31 31 output.output_type = unicode(output_type)
32 32 if output_text is not None:
33 33 output.text = unicode(output_text)
34 34 if output_png is not None:
35 35 output.png = bytes(output_png)
36 36 if output_jpeg is not None:
37 37 output.jpeg = bytes(output_jpeg)
38 38 if output_html is not None:
39 39 output.html = unicode(output_html)
40 40 if output_svg is not None:
41 41 output.svg = unicode(output_svg)
42 42 if output_latex is not None:
43 43 output.latex = unicode(output_latex)
44 44 if output_json is not None:
45 45 output.json = unicode(output_json)
46 46 if output_javascript is not None:
47 47 output.javascript = unicode(output_javascript)
48 48 if prompt_number is not None:
49 49 output.prompt_number = int(prompt_number)
50 50 return output
51 51
52 52
53 def new_code_cell(input=None, prompt_number=None, outputs=None, language=u'python'):
53 def new_code_cell(input=None, prompt_number=None, outputs=None,
54 language=u'python', collapsed=False):
54 55 """Create a new code cell with input and output"""
55 56 cell = NotebookNode()
56 57 cell.cell_type = u'code'
57 58 if language is not None:
58 59 cell.language = unicode(language)
59 60 if input is not None:
60 61 cell.input = unicode(input)
61 62 if prompt_number is not None:
62 63 cell.prompt_number = int(prompt_number)
63 64 if outputs is None:
64 65 cell.outputs = []
65 66 else:
66 67 cell.outputs = outputs
68 if collapsed is not None:
69 cell.collapsed = collapsed
67 70
68 71 return cell
69 72
70 73 def new_text_cell(cell_type, source=None, rendered=None):
71 74 """Create a new text cell."""
72 75 cell = NotebookNode()
73 76 if source is not None:
74 77 cell.source = unicode(source)
75 78 if rendered is not None:
76 79 cell.rendered = unicode(rendered)
77 80 cell.cell_type = cell_type
78 81 return cell
79 82
80 83
81 84 def new_worksheet(name=None, cells=None):
82 85 """Create a worksheet by name with with a list of cells."""
83 86 ws = NotebookNode()
84 87 if name is not None:
85 88 ws.name = unicode(name)
86 89 if cells is None:
87 90 ws.cells = []
88 91 else:
89 92 ws.cells = list(cells)
90 93 return ws
91 94
92 95
93 96 def new_notebook(name=None, id=None, worksheets=None):
94 97 """Create a notebook by name, id and a list of worksheets."""
95 98 nb = NotebookNode()
96 99 nb.nbformat = 2
97 100 if name is not None:
98 101 nb.name = unicode(name)
99 102 if id is None:
100 103 nb.id = unicode(uuid.uuid4())
101 104 else:
102 105 nb.id = unicode(id)
103 106 if worksheets is None:
104 107 nb.worksheets = []
105 108 else:
106 109 nb.worksheets = list(worksheets)
107 110 return nb
108 111
@@ -1,180 +1,199 b''
1 1 """Read and write notebook files as XML."""
2 2
3 3 from base64 import encodestring, decodestring
4 4 from xml.etree import ElementTree as ET
5 5
6 6 from .rwbase import NotebookReader, NotebookWriter
7 7 from .nbbase import (
8 8 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output
9 9 )
10 10
11 11 def indent(elem, level=0):
12 12 i = "\n" + level*" "
13 13 if len(elem):
14 14 if not elem.text or not elem.text.strip():
15 15 elem.text = i + " "
16 16 if not elem.tail or not elem.tail.strip():
17 17 elem.tail = i
18 18 for elem in elem:
19 19 indent(elem, level+1)
20 20 if not elem.tail or not elem.tail.strip():
21 21 elem.tail = i
22 22 else:
23 23 if level and (not elem.tail or not elem.tail.strip()):
24 24 elem.tail = i
25 25
26 26
27 27 def _get_text(e, tag):
28 28 sub_e = e.find(tag)
29 29 if sub_e is None:
30 30 return None
31 31 else:
32 32 return sub_e.text
33 33
34 34
35 35 def _set_text(nbnode, attr, parent, tag):
36 36 if attr in nbnode:
37 37 e = ET.SubElement(parent, tag)
38 38 e.text = nbnode[attr]
39 39
40 40
41 41 def _get_int(e, tag):
42 42 sub_e = e.find(tag)
43 43 if sub_e is None:
44 44 return None
45 45 else:
46 46 return int(sub_e.text)
47 47
48 48
49 49 def _set_int(nbnode, attr, parent, tag):
50 50 if attr in nbnode:
51 51 e = ET.SubElement(parent, tag)
52 52 e.text = unicode(nbnode[attr])
53 53
54 54
55 def _get_bool(e, tag):
56 sub_e = e.find(tag)
57 if sub_e is None:
58 return None
59 else:
60 return bool(int(sub_e.text))
61
62
63 def _set_bool(nbnode, attr, parent, tag):
64 if attr in nbnode:
65 e = ET.SubElement(parent, tag)
66 if nbnode[attr]:
67 e.text = u'1'
68 else:
69 e.text = u'0'
70
71
55 72 def _get_binary(e, tag):
56 73 sub_e = e.find(tag)
57 74 if sub_e is None:
58 75 return None
59 76 else:
60 77 return decodestring(sub_e.text)
61 78
62 79
63 80 def _set_binary(nbnode, attr, parent, tag):
64 81 if attr in nbnode:
65 82 e = ET.SubElement(parent, tag)
66 83 e.text = encodestring(nbnode[attr])
67 84
68 85
69 86 class XMLReader(NotebookReader):
70 87
71 88 def reads(self, s, **kwargs):
72 89 root = ET.fromstring(s)
73 90 return self.to_notebook(root, **kwargs)
74 91
75 92 def to_notebook(self, root, **kwargs):
76 93 nbname = _get_text(root,'name')
77 94 nbid = _get_text(root,'id')
78 95
79 96 worksheets = []
80 97 for ws_e in root.find('worksheets').getiterator('worksheet'):
81 98 wsname = _get_text(ws_e,'name')
82 99 cells = []
83 100 for cell_e in ws_e.find('cells').getiterator():
84 101 if cell_e.tag == 'codecell':
85 102 input = _get_text(cell_e,'input')
86 103 prompt_number = _get_int(cell_e,'prompt_number')
104 collapsed = _get_bool(cell_e,'collapsed')
87 105 language = _get_text(cell_e,'language')
88 106 outputs = []
89 107 for output_e in cell_e.find('outputs').getiterator('output'):
90 108 out_prompt_number = _get_int(output_e,'prompt_number')
91 109 output_type = _get_text(output_e,'output_type')
92 110 output_text = _get_text(output_e,'text')
93 111 output_png = _get_binary(output_e,'png')
94 112 output_jpeg = _get_binary(output_e,'jpeg')
95 113 output_svg = _get_text(output_e,'svg')
96 114 output_html = _get_text(output_e,'html')
97 115 output_latex = _get_text(output_e,'latex')
98 116 output_json = _get_text(output_e,'json')
99 117 output_javascript = _get_text(output_e,'javascript')
100 118 output = new_output(output_type=output_type,output_png=output_png,
101 119 output_text=output_text, output_svg=output_svg,
102 120 output_html=output_html, output_latex=output_latex,
103 121 output_json=output_json, output_javascript=output_javascript,
104 122 output_jpeg=output_jpeg, prompt_number=out_prompt_number
105 123 )
106 124 outputs.append(output)
107 125 cc = new_code_cell(input=input,prompt_number=prompt_number,
108 language=language,outputs=outputs)
126 language=language,outputs=outputs,collapsed=collapsed)
109 127 cells.append(cc)
110 128 if cell_e.tag == 'htmlcell':
111 129 source = _get_text(cell_e,'source')
112 130 rendered = _get_text(cell_e,'rendered')
113 131 cells.append(new_text_cell(u'html', source=source, rendered=rendered))
114 132 if cell_e.tag == 'markdowncell':
115 133 source = _get_text(cell_e,'source')
116 134 rendered = _get_text(cell_e,'rendered')
117 135 cells.append(new_text_cell(u'markdown', source=source, rendered=rendered))
118 136 ws = new_worksheet(name=wsname,cells=cells)
119 137 worksheets.append(ws)
120 138
121 139 nb = new_notebook(name=nbname,id=nbid,worksheets=worksheets)
122 140 return nb
123 141
124 142
125 143 class XMLWriter(NotebookWriter):
126 144
127 145 def writes(self, nb, **kwargs):
128 146 nb_e = ET.Element('notebook')
129 147 _set_text(nb,'name',nb_e,'name')
130 148 _set_text(nb,'id',nb_e,'id')
131 149 _set_int(nb,'nbformat',nb_e,'nbformat')
132 150 wss_e = ET.SubElement(nb_e,'worksheets')
133 151 for ws in nb.worksheets:
134 152 ws_e = ET.SubElement(wss_e, 'worksheet')
135 153 _set_text(ws,'name',ws_e,'name')
136 154 cells_e = ET.SubElement(ws_e,'cells')
137 155 for cell in ws.cells:
138 156 cell_type = cell.cell_type
139 157 if cell_type == 'code':
140 158 cell_e = ET.SubElement(cells_e, 'codecell')
141 159 _set_text(cell,'input',cell_e,'input')
142 160 _set_text(cell,'language',cell_e,'language')
143 161 _set_int(cell,'prompt_number',cell_e,'prompt_number')
162 _set_bool(cell,'collapsed',cell_e,'collapsed')
144 163 outputs_e = ET.SubElement(cell_e, 'outputs')
145 164 for output in cell.outputs:
146 165 output_e = ET.SubElement(outputs_e, 'output')
147 166 _set_int(output,'prompt_number',output_e,'prompt_number')
148 167 _set_text(output,'output_type',output_e,'output_type')
149 168 _set_text(output,'text',output_e,'text')
150 169 _set_binary(output,'png',output_e,'png')
151 170 _set_binary(output,'jpeg',output_e,'jpeg')
152 171 _set_text(output,'html',output_e,'html')
153 172 _set_text(output,'svg',output_e,'svg')
154 173 _set_text(output,'latex',output_e,'latex')
155 174 _set_text(output,'json',output_e,'json')
156 175 _set_text(output,'javascript',output_e,'javascript')
157 176 elif cell_type == 'html':
158 177 cell_e = ET.SubElement(cells_e, 'htmlcell')
159 178 _set_text(cell,'source',cell_e,'source')
160 179 _set_text(cell,'rendered',cell_e,'rendered')
161 180 elif cell_type == 'markdown':
162 181 cell_e = ET.SubElement(cells_e, 'markdowncell')
163 182 _set_text(cell,'source',cell_e,'source')
164 183 _set_text(cell,'rendered',cell_e,'rendered')
165 184
166 185 indent(nb_e)
167 186 txt = ET.tostring(nb_e, encoding="utf-8")
168 187 txt = '<?xml version="1.0" encoding="utf-8"?>\n' + txt
169 188 return txt
170 189
171 190
172 191 _reader = XMLReader()
173 192 _writer = XMLWriter()
174 193
175 194 reads = _reader.reads
176 195 read = _reader.read
177 196 to_notebook = _reader.to_notebook
178 197 write = _writer.write
179 198 writes = _writer.writes
180 199
@@ -1,85 +1,88 b''
1 1 from ..nbbase import (
2 2 NotebookNode,
3 3 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output
4 4 )
5 5
6 6
7 7
8 8 ws = new_worksheet(name='worksheet1')
9 9
10 10 ws.cells.append(new_text_cell(
11 11 u'html',
12 12 source='Some NumPy Examples',
13 13 rendered='Some NumPy Examples'
14 14 ))
15 15
16 16
17 17 ws.cells.append(new_code_cell(
18 18 input='import numpy',
19 prompt_number=1
19 prompt_number=1,
20 collapsed=False
20 21 ))
21 22
22 23 ws.cells.append(new_text_cell(
23 24 u'markdown',
24 25 source='Some NumPy Examples',
25 26 rendered='Some NumPy Examples'
26 27 ))
27 28
28 29 ws.cells.append(new_code_cell(
29 30 input='a = numpy.random.rand(100)',
30 prompt_number=2
31 prompt_number=2,
32 collapsed=True
31 33 ))
32 34
33 35 ws.cells.append(new_code_cell(
34 36 input='print a',
35 37 prompt_number=3,
38 collapsed=False,
36 39 outputs=[new_output(
37 40 output_type=u'pyout',
38 41 output_text=u'<array a>',
39 42 output_html=u'The HTML rep',
40 43 output_latex=u'$a$',
41 44 output_png=b'data',
42 45 output_jpeg=b'data',
43 46 output_svg=u'<svg>',
44 47 output_json=u'json data',
45 48 output_javascript=u'var i=0;',
46 49 prompt_number=3
47 50 ),new_output(
48 51 output_type=u'display_data',
49 52 output_text=u'<array a>',
50 53 output_html=u'The HTML rep',
51 54 output_latex=u'$a$',
52 55 output_png=b'data',
53 56 output_jpeg=b'data',
54 57 output_svg=u'<svg>',
55 58 output_json=u'json data',
56 59 output_javascript=u'var i=0;',
57 60 prompt_number=4
58 61 )]
59 62 ))
60 63
61 64 nb0 = new_notebook(
62 65 name='nb0',
63 66 worksheets=[ws, new_worksheet(name='worksheet2')]
64 67 )
65 68
66 69 nb0_py = """# <nbformat>2</nbformat>
67 70
68 71 # <codecell>
69 72
70 73 import numpy
71 74
72 75 # </codecell>
73 76 # <codecell>
74 77
75 78 a = numpy.random.rand(100)
76 79
77 80 # </codecell>
78 81 # <codecell>
79 82
80 83 print a
81 84
82 85 # </codecell>
83 86 """
84 87
85 88
@@ -1,15 +1,21 b''
1
1 import pprint
2 2 from unittest import TestCase
3 3
4 4 from ..nbjson import reads, writes
5 5 from .nbexamples import nb0
6 6
7 7
8 8 class TestJSON(TestCase):
9 9
10 10 def test_roundtrip(self):
11 11 s = writes(nb0)
12 # print
13 # print pprint.pformat(nb0,indent=2)
14 # print
15 # print pprint.pformat(reads(s),indent=2)
16 # print
17 # print s
12 18 self.assertEquals(reads(s),nb0)
13 19
14 20
15 21
@@ -1,79 +1,82 b''
1 1 from unittest import TestCase
2 2
3 3 from ..nbbase import (
4 4 NotebookNode,
5 5 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output
6 6 )
7 7
8 8 class TestCell(TestCase):
9 9
10 10 def test_empty_code_cell(self):
11 11 cc = new_code_cell()
12 12 self.assertEquals(cc.cell_type,'code')
13 13 self.assertEquals('input' not in cc, True)
14 14 self.assertEquals('prompt_number' not in cc, True)
15 15 self.assertEquals(cc.outputs, [])
16 self.assertEquals(cc.collapsed, False)
16 17
17 18 def test_code_cell(self):
18 cc = new_code_cell(input='a=10', prompt_number=0)
19 cc = new_code_cell(input='a=10', prompt_number=0, collapsed=True)
19 20 cc.outputs = [new_output(output_type='pyout',
20 21 output_svg='foo',output_text='10',prompt_number=0)]
21 22 self.assertEquals(cc.input, u'a=10')
22 23 self.assertEquals(cc.prompt_number, 0)
23 24 self.assertEquals(cc.language, u'python')
24 25 self.assertEquals(cc.outputs[0].svg, u'foo')
25 26 self.assertEquals(cc.outputs[0].text, u'10')
26 27 self.assertEquals(cc.outputs[0].prompt_number, 0)
28 self.assertEquals(cc.collapsed, True)
29
27 30
28 31 def test_empty_html_cell(self):
29 32 tc = new_text_cell(u'html')
30 33 self.assertEquals(tc.cell_type, u'html')
31 34 self.assertEquals('source' not in tc, True)
32 35 self.assertEquals('rendered' not in tc, True)
33 36
34 37 def test_html_cell(self):
35 38 tc = new_text_cell(u'html', 'hi', 'hi')
36 39 self.assertEquals(tc.source, u'hi')
37 40 self.assertEquals(tc.rendered, u'hi')
38 41
39 42 def test_empty_markdown_cell(self):
40 43 tc = new_text_cell(u'markdown')
41 44 self.assertEquals(tc.cell_type, u'markdown')
42 45 self.assertEquals('source' not in tc, True)
43 46 self.assertEquals('rendered' not in tc, True)
44 47
45 48 def test_markdown_cell(self):
46 49 tc = new_text_cell(u'markdown', 'hi', 'hi')
47 50 self.assertEquals(tc.source, u'hi')
48 51 self.assertEquals(tc.rendered, u'hi')
49 52
50 53
51 54 class TestWorksheet(TestCase):
52 55
53 56 def test_empty_worksheet(self):
54 57 ws = new_worksheet()
55 58 self.assertEquals(ws.cells,[])
56 59 self.assertEquals('name' not in ws, True)
57 60
58 61 def test_worksheet(self):
59 62 cells = [new_code_cell(), new_text_cell(u'html')]
60 63 ws = new_worksheet(cells=cells,name='foo')
61 64 self.assertEquals(ws.cells,cells)
62 65 self.assertEquals(ws.name,u'foo')
63 66
64 67 class TestNotebook(TestCase):
65 68
66 69 def test_empty_notebook(self):
67 70 nb = new_notebook()
68 71 self.assertEquals('id' in nb, True)
69 72 self.assertEquals(nb.worksheets, [])
70 73 self.assertEquals('name' not in nb, True)
71 74 self.assertEquals(nb.nbformat,2)
72 75
73 76 def test_notebook(self):
74 77 worksheets = [new_worksheet(),new_worksheet()]
75 78 nb = new_notebook(name='foo',worksheets=worksheets)
76 79 self.assertEquals(nb.name,u'foo')
77 80 self.assertEquals(nb.worksheets,worksheets)
78 81 self.assertEquals(nb.nbformat,2)
79 82
General Comments 0
You need to be logged in to leave comments. Login now