Show More
@@ -11,7 +11,7 b' import requests' | |||
|
11 | 11 | from IPython.html.utils import url_path_join |
|
12 | 12 | from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error |
|
13 | 13 | from IPython.nbformat.current import (new_notebook, write, |
|
14 |
new_ |
|
|
14 | new_markdown_cell, new_code_cell, | |
|
15 | 15 | new_output) |
|
16 | 16 | |
|
17 | 17 | from IPython.testing.decorators import onlyif_cmds_exist |
@@ -55,7 +55,7 b' class APITest(NotebookTestBase):' | |||
|
55 | 55 | |
|
56 | 56 | nb = new_notebook() |
|
57 | 57 | |
|
58 |
nb.cells.append(new_ |
|
|
58 | nb.cells.append(new_markdown_cell(u'Created by test Β³')) | |
|
59 | 59 | cc1 = new_code_cell(source=u'print(2*6)') |
|
60 | 60 | cc1.outputs.append(new_output(output_type="stream", text=u'12')) |
|
61 | 61 | cc1.outputs.append(new_output(output_type="execute_result", |
@@ -255,7 +255,7 b' class FileContentsManager(ContentsManager):' | |||
|
255 | 255 | try: |
|
256 | 256 | nb = current.read(f, u'json') |
|
257 | 257 | except Exception as e: |
|
258 |
raise web.HTTPError(400, u"Unreadable Notebook: %s % |
|
|
258 | raise web.HTTPError(400, u"Unreadable Notebook: %s %r" % (os_path, e)) | |
|
259 | 259 | self.mark_trusted_cells(nb, name, path) |
|
260 | 260 | model['content'] = nb |
|
261 | 261 | model['format'] = 'json' |
@@ -16,7 +16,7 b' from IPython.html.utils import url_path_join, url_escape' | |||
|
16 | 16 | from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error |
|
17 | 17 | from IPython.nbformat import current |
|
18 | 18 | from IPython.nbformat.current import (new_notebook, write, read, |
|
19 |
new_ |
|
|
19 | new_markdown_cell, to_notebook_json) | |
|
20 | 20 | from IPython.nbformat import v2 |
|
21 | 21 | from IPython.utils import py3compat |
|
22 | 22 | from IPython.utils.data import uniq_stable |
@@ -415,7 +415,7 b' class APITest(NotebookTestBase):' | |||
|
415 | 415 | resp = self.api.read('a.ipynb', 'foo') |
|
416 | 416 | nbcontent = json.loads(resp.text)['content'] |
|
417 | 417 | nb = to_notebook_json(nbcontent) |
|
418 |
nb.cells.append(new_ |
|
|
418 | nb.cells.append(new_markdown_cell(u'Created by test Β³')) | |
|
419 | 419 | |
|
420 | 420 | nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'} |
|
421 | 421 | resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) |
@@ -452,7 +452,7 b' class APITest(NotebookTestBase):' | |||
|
452 | 452 | # Modify it |
|
453 | 453 | nbcontent = json.loads(resp.text)['content'] |
|
454 | 454 | nb = to_notebook_json(nbcontent) |
|
455 |
hcell = new_ |
|
|
455 | hcell = new_markdown_cell('Created by test') | |
|
456 | 456 | nb.cells.append(hcell) |
|
457 | 457 | # Save |
|
458 | 458 | nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'} |
@@ -139,12 +139,6 b' define([' | |||
|
139 | 139 | .append($('<option/>').attr('value','code').text('Code')) |
|
140 | 140 | .append($('<option/>').attr('value','markdown').text('Markdown')) |
|
141 | 141 | .append($('<option/>').attr('value','raw').text('Raw NBConvert')) |
|
142 | .append($('<option/>').attr('value','heading1').text('Heading 1')) | |
|
143 | .append($('<option/>').attr('value','heading2').text('Heading 2')) | |
|
144 | .append($('<option/>').attr('value','heading3').text('Heading 3')) | |
|
145 | .append($('<option/>').attr('value','heading4').text('Heading 4')) | |
|
146 | .append($('<option/>').attr('value','heading5').text('Heading 5')) | |
|
147 | .append($('<option/>').attr('value','heading6').text('Heading 6')) | |
|
148 | 142 | ); |
|
149 | 143 | }; |
|
150 | 144 | |
@@ -190,24 +184,18 b' define([' | |||
|
190 | 184 | |
|
191 | 185 | this.element.find('#cell_type').change(function () { |
|
192 | 186 | var cell_type = $(this).val(); |
|
193 |
|
|
|
187 | switch (cell_type) { | |
|
188 | case 'code': | |
|
194 | 189 | that.notebook.to_code(); |
|
195 | } else if (cell_type === 'markdown') { | |
|
190 | break; | |
|
191 | case 'markdown': | |
|
196 | 192 | that.notebook.to_markdown(); |
|
197 | } else if (cell_type === 'raw') { | |
|
193 | break; | |
|
194 | case 'raw': | |
|
198 | 195 | that.notebook.to_raw(); |
|
199 | } else if (cell_type === 'heading1') { | |
|
200 | that.notebook.to_heading(undefined, 1); | |
|
201 | } else if (cell_type === 'heading2') { | |
|
202 | that.notebook.to_heading(undefined, 2); | |
|
203 | } else if (cell_type === 'heading3') { | |
|
204 | that.notebook.to_heading(undefined, 3); | |
|
205 | } else if (cell_type === 'heading4') { | |
|
206 | that.notebook.to_heading(undefined, 4); | |
|
207 | } else if (cell_type === 'heading5') { | |
|
208 | that.notebook.to_heading(undefined, 5); | |
|
209 | } else if (cell_type === 'heading6') { | |
|
210 | that.notebook.to_heading(undefined, 6); | |
|
196 | break; | |
|
197 | default: | |
|
198 | console.log("unrecognized cell type:", cell_type); | |
|
211 | 199 | } |
|
212 | 200 | }); |
|
213 | 201 | this.events.on('selected_cell_type_changed.Notebook', function (event, data) { |
@@ -824,7 +824,7 b' define([' | |||
|
824 | 824 | * Index will be brought back into the accessible range [0,n] |
|
825 | 825 | * |
|
826 | 826 | * @method insert_cell_at_index |
|
827 |
* @param [type] {string} in ['code','markdown', |
|
|
827 | * @param [type] {string} in ['code','markdown', 'raw'], defaults to 'code' | |
|
828 | 828 | * @param [index] {int} a valid index where to insert cell |
|
829 | 829 | * |
|
830 | 830 | * @return cell {cell|null} created cell or null |
@@ -860,15 +860,19 b' define([' | |||
|
860 | 860 | notebook: this, |
|
861 | 861 | tooltip: this.tooltip, |
|
862 | 862 | }; |
|
863 |
|
|
|
863 | switch(type) { | |
|
864 | case 'code': | |
|
864 | 865 | cell = new codecell.CodeCell(this.kernel, cell_options); |
|
865 | 866 | cell.set_input_prompt(); |
|
866 | } else if (type === 'markdown') { | |
|
867 | break; | |
|
868 | case 'markdown': | |
|
867 | 869 | cell = new textcell.MarkdownCell(cell_options); |
|
868 | } else if (type === 'raw') { | |
|
870 | break; | |
|
871 | case 'raw': | |
|
869 | 872 | cell = new textcell.RawCell(cell_options); |
|
870 | } else if (type === 'heading') { | |
|
871 | cell = new textcell.HeadingCell(cell_options); | |
|
873 | break; | |
|
874 | default: | |
|
875 | console.log("invalid cell type: ", type); | |
|
872 | 876 | } |
|
873 | 877 | |
|
874 | 878 | if(this._insert_element_at_index(cell.element,index)) { |
@@ -1090,10 +1094,10 b' define([' | |||
|
1090 | 1094 | if (this.is_valid_cell_index(i)) { |
|
1091 | 1095 | var source_cell = this.get_cell(i); |
|
1092 | 1096 | var target_cell = null; |
|
1093 |
if (source_cell instanceof textcell. |
|
|
1094 | source_cell.set_level(level); | |
|
1097 | if (source_cell instanceof textcell.MarkdownCell) { | |
|
1098 | source_cell.set_heading_level(level); | |
|
1095 | 1099 | } else { |
|
1096 |
target_cell = this.insert_cell_below(' |
|
|
1100 | target_cell = this.insert_cell_below('markdown',i); | |
|
1097 | 1101 | var text = source_cell.get_text(); |
|
1098 | 1102 | if (text === source_cell.placeholder) { |
|
1099 | 1103 | text = ''; |
@@ -1101,9 +1105,9 b' define([' | |||
|
1101 | 1105 | //metadata |
|
1102 | 1106 | target_cell.metadata = source_cell.metadata; |
|
1103 | 1107 | // We must show the editor before setting its contents |
|
1104 | target_cell.set_level(level); | |
|
1105 | 1108 | target_cell.unrender(); |
|
1106 | 1109 | target_cell.set_text(text); |
|
1110 | target_cell.set_heading_level(level); | |
|
1107 | 1111 | // make this value the starting point, so that we can only undo |
|
1108 | 1112 | // to this state, instead of a blank cell |
|
1109 | 1113 | target_cell.code_mirror.clearHistory(); |
@@ -1117,7 +1121,7 b' define([' | |||
|
1117 | 1121 | } |
|
1118 | 1122 | this.set_dirty(true); |
|
1119 | 1123 | this.events.trigger('selected_cell_type_changed.Notebook', |
|
1120 |
{'cell_type':' |
|
|
1124 | {'cell_type':'markdown',level:level} | |
|
1121 | 1125 | ); |
|
1122 | 1126 | } |
|
1123 | 1127 | }; |
@@ -1526,8 +1530,8 b' define([' | |||
|
1526 | 1530 | } |
|
1527 | 1531 | this.codemirror_mode = newmode; |
|
1528 | 1532 | codecell.CodeCell.options_default.cm_config.mode = newmode; |
|
1529 | modename = newmode.mode || newmode.name || newmode | |
|
1530 | ||
|
1533 | modename = newmode.mode || newmode.name || newmode; | |
|
1534 | ||
|
1531 | 1535 | that = this; |
|
1532 | 1536 | utils.requireCodeMirrorMode(modename, function () { |
|
1533 | 1537 | $.map(that.get_cells(), function(cell, i) { |
@@ -1539,7 +1543,7 b' define([' | |||
|
1539 | 1543 | cell.cm_config.mode = newmode; |
|
1540 | 1544 | } |
|
1541 | 1545 | }); |
|
1542 | }) | |
|
1546 | }); | |
|
1543 | 1547 | }; |
|
1544 | 1548 | |
|
1545 | 1549 | // Session related things |
@@ -2383,13 +2387,13 b' define([' | |||
|
2383 | 2387 | Notebook.prototype.load_notebook_error = function (xhr, status, error) { |
|
2384 | 2388 | this.events.trigger('notebook_load_failed.Notebook', [xhr, status, error]); |
|
2385 | 2389 | utils.log_ajax_error(xhr, status, error); |
|
2386 | var msg; | |
|
2390 | var msg = $("<div>"); | |
|
2387 | 2391 | if (xhr.status === 400) { |
|
2388 |
msg |
|
|
2392 | msg.text(utils.ajax_error_msg(xhr)); | |
|
2389 | 2393 | } else if (xhr.status === 500) { |
|
2390 |
msg |
|
|
2394 | msg.text("An unknown error occurred while loading this notebook. " + | |
|
2391 | 2395 | "This version can load notebook formats " + |
|
2392 | "v" + this.nbformat + " or earlier. See the server log for details."; | |
|
2396 | "v" + this.nbformat + " or earlier. See the server log for details."); | |
|
2393 | 2397 | } |
|
2394 | 2398 | dialog.modal({ |
|
2395 | 2399 | notebook: this, |
@@ -222,6 +222,26 b' define([' | |||
|
222 | 222 | |
|
223 | 223 | MarkdownCell.prototype = Object.create(TextCell.prototype); |
|
224 | 224 | |
|
225 | MarkdownCell.prototype.set_heading_level = function (level) { | |
|
226 | // make a markdown cell a heading | |
|
227 | level = level || 1; | |
|
228 | var source = this.get_text(); | |
|
229 | // \s\S appears to be the js version of multi-line dot-all | |
|
230 | var match = source.match(/(#*)\s*([\s\S]*)/); | |
|
231 | // strip the leading `#` if it's already there | |
|
232 | if (match) { | |
|
233 | source = match[2]; | |
|
234 | } | |
|
235 | // add `#` markdown heading prefix | |
|
236 | var new_text = new Array(level + 1).join('#') + ' ' + source; | |
|
237 | ||
|
238 | this.set_text(new_text); | |
|
239 | this.refresh(); | |
|
240 | if (this.rendered) { | |
|
241 | this.render(); | |
|
242 | } | |
|
243 | }; | |
|
244 | ||
|
225 | 245 | /** |
|
226 | 246 | * @method render |
|
227 | 247 | */ |
@@ -238,6 +258,19 b' define([' | |||
|
238 | 258 | html = mathjaxutils.replace_math(html, math); |
|
239 | 259 | html = security.sanitize_html(html); |
|
240 | 260 | html = $($.parseHTML(html)); |
|
261 | // add anchors to headings | |
|
262 | // console.log(html); | |
|
263 | html.find(":header").addBack(":header").each(function (i, h) { | |
|
264 | h = $(h); | |
|
265 | var hash = h.text().replace(/ /g, '-'); | |
|
266 | h.attr('id', hash); | |
|
267 | h.append( | |
|
268 | $('<a/>') | |
|
269 | .addClass('anchor-link') | |
|
270 | .attr('href', '#' + hash) | |
|
271 | .text('ΒΆ') | |
|
272 | ); | |
|
273 | }) | |
|
241 | 274 | // links in markdown cells should open in new tabs |
|
242 | 275 | html.find("a[href]").not('[href^="#"]').attr("target", "_blank"); |
|
243 | 276 | this.set_rendered(html); |
@@ -305,121 +338,15 b' define([' | |||
|
305 | 338 | return cont; |
|
306 | 339 | }; |
|
307 | 340 | |
|
308 | ||
|
309 | var HeadingCell = function (options) { | |
|
310 | // Constructor | |
|
311 | // | |
|
312 | // Parameters: | |
|
313 | // options: dictionary | |
|
314 | // Dictionary of keyword arguments. | |
|
315 | // events: $(Events) instance | |
|
316 | // config: dictionary | |
|
317 | // keyboard_manager: KeyboardManager instance | |
|
318 | // notebook: Notebook instance | |
|
319 | options = options || {}; | |
|
320 | var config = utils.mergeopt(HeadingCell, options.config); | |
|
321 | TextCell.apply(this, [$.extend({}, options, {config: config})]); | |
|
322 | ||
|
323 | this.level = 1; | |
|
324 | this.cell_type = 'heading'; | |
|
325 | }; | |
|
326 | ||
|
327 | HeadingCell.options_default = { | |
|
328 | cm_config: { | |
|
329 | theme: 'heading-1' | |
|
330 | }, | |
|
331 | placeholder: "Type Heading Here" | |
|
332 | }; | |
|
333 | ||
|
334 | HeadingCell.prototype = Object.create(TextCell.prototype); | |
|
335 | ||
|
336 | /** @method fromJSON */ | |
|
337 | HeadingCell.prototype.fromJSON = function (data) { | |
|
338 | if (data.level !== undefined){ | |
|
339 | this.level = data.level; | |
|
340 | } | |
|
341 | TextCell.prototype.fromJSON.apply(this, arguments); | |
|
342 | this.code_mirror.setOption("theme", "heading-"+this.level); | |
|
343 | }; | |
|
344 | ||
|
345 | ||
|
346 | /** @method toJSON */ | |
|
347 | HeadingCell.prototype.toJSON = function () { | |
|
348 | var data = TextCell.prototype.toJSON.apply(this); | |
|
349 | data.level = this.get_level(); | |
|
350 | return data; | |
|
351 | }; | |
|
352 | ||
|
353 | /** | |
|
354 | * Change heading level of cell, and re-render | |
|
355 | * @method set_level | |
|
356 | */ | |
|
357 | HeadingCell.prototype.set_level = function (level) { | |
|
358 | this.level = level; | |
|
359 | this.code_mirror.setOption("theme", "heading-"+level); | |
|
360 | ||
|
361 | if (this.rendered) { | |
|
362 | this.rendered = false; | |
|
363 | this.render(); | |
|
364 | } | |
|
365 | }; | |
|
366 | ||
|
367 | /** The depth of header cell, based on html (h1 to h6) | |
|
368 | * @method get_level | |
|
369 | * @return {integer} level - for 1 to 6 | |
|
370 | */ | |
|
371 | HeadingCell.prototype.get_level = function () { | |
|
372 | return this.level; | |
|
373 | }; | |
|
374 | ||
|
375 | ||
|
376 | HeadingCell.prototype.get_rendered = function () { | |
|
377 | var r = this.element.find("div.text_cell_render"); | |
|
378 | return r.children().first().html(); | |
|
379 | }; | |
|
380 | ||
|
381 | HeadingCell.prototype.render = function () { | |
|
382 | var cont = TextCell.prototype.render.apply(this); | |
|
383 | if (cont) { | |
|
384 | var text = this.get_text(); | |
|
385 | var math = null; | |
|
386 | // Markdown headings must be a single line | |
|
387 | text = text.replace(/\n/g, ' '); | |
|
388 | if (text === "") { text = this.placeholder; } | |
|
389 | text = new Array(this.level + 1).join("#") + " " + text; | |
|
390 | var text_and_math = mathjaxutils.remove_math(text); | |
|
391 | text = text_and_math[0]; | |
|
392 | math = text_and_math[1]; | |
|
393 | var html = marked.parser(marked.lexer(text)); | |
|
394 | html = mathjaxutils.replace_math(html, math); | |
|
395 | html = security.sanitize_html(html); | |
|
396 | var h = $($.parseHTML(html)); | |
|
397 | // add id and linkback anchor | |
|
398 | var hash = h.text().trim().replace(/ /g, '-'); | |
|
399 | h.attr('id', hash); | |
|
400 | h.append( | |
|
401 | $('<a/>') | |
|
402 | .addClass('anchor-link') | |
|
403 | .attr('href', '#' + hash) | |
|
404 | .text('ΒΆ') | |
|
405 | ); | |
|
406 | this.set_rendered(h); | |
|
407 | this.typeset(); | |
|
408 | } | |
|
409 | return cont; | |
|
410 | }; | |
|
411 | ||
|
412 | 341 | // Backwards compatability. |
|
413 | 342 | IPython.TextCell = TextCell; |
|
414 | 343 | IPython.MarkdownCell = MarkdownCell; |
|
415 | 344 | IPython.RawCell = RawCell; |
|
416 | IPython.HeadingCell = HeadingCell; | |
|
417 | 345 | |
|
418 | 346 | var textcell = { |
|
419 |
|
|
|
420 |
|
|
|
421 |
|
|
|
422 | 'HeadingCell': HeadingCell, | |
|
347 | TextCell: TextCell, | |
|
348 | MarkdownCell: MarkdownCell, | |
|
349 | RawCell: RawCell, | |
|
423 | 350 | }; |
|
424 | 351 | return textcell; |
|
425 | 352 | }); |
@@ -189,12 +189,6 b' class="notebook_app"' | |||
|
189 | 189 | <li id="to_raw" |
|
190 | 190 | title="Contents will pass through nbconvert unmodified"> |
|
191 | 191 | <a href="#">Raw NBConvert</a></li> |
|
192 | <li id="to_heading1"><a href="#">Heading 1</a></li> | |
|
193 | <li id="to_heading2"><a href="#">Heading 2</a></li> | |
|
194 | <li id="to_heading3"><a href="#">Heading 3</a></li> | |
|
195 | <li id="to_heading4"><a href="#">Heading 4</a></li> | |
|
196 | <li id="to_heading5"><a href="#">Heading 5</a></li> | |
|
197 | <li id="to_heading6"><a href="#">Heading 6</a></li> | |
|
198 | 192 | </ul> |
|
199 | 193 | </li> |
|
200 | 194 | <li class="divider"></li> |
@@ -52,12 +52,12 b' casper.notebook_test(function () {' | |||
|
52 | 52 | |
|
53 | 53 | this.then(function () { |
|
54 | 54 | this.select_cell(2); |
|
55 |
this.trigger_keydown(' |
|
|
56 |
this.test.assertEquals(this.get_cell(2).cell_type, ' |
|
|
55 | this.trigger_keydown('y'); // switch it to code for the next test | |
|
56 | this.test.assertEquals(this.get_cell(2).cell_type, 'code', 'test cell is code'); | |
|
57 | 57 | this.trigger_keydown('b'); // new cell below |
|
58 |
this.test.assertEquals(this.get_cell(3).cell_type, ' |
|
|
58 | this.test.assertEquals(this.get_cell(3).cell_type, 'code', 'b; inserts a code cell below code cell'); | |
|
59 | 59 | this.trigger_keydown('a'); // new cell above |
|
60 |
this.test.assertEquals(this.get_cell(3).cell_type, ' |
|
|
60 | this.test.assertEquals(this.get_cell(3).cell_type, 'code', 'a; inserts a code cell below code cell'); | |
|
61 | 61 | }); |
|
62 | 62 | |
|
63 | 63 | this.thenEvaluate(function() { |
@@ -4,25 +4,38 b'' | |||
|
4 | 4 | casper.notebook_test(function () { |
|
5 | 5 | this.then(function () { |
|
6 | 6 | // Cell mode change |
|
7 | this.select_cell(0); | |
|
7 | var index = 0; | |
|
8 | this.select_cell(index); | |
|
9 | var a = 'hello\nmulti\nline'; | |
|
10 | this.set_cell_text(index, a); | |
|
8 | 11 | this.trigger_keydown('esc','r'); |
|
9 |
this.test.assertEquals(this.get_cell( |
|
|
12 | this.test.assertEquals(this.get_cell(index).cell_type, 'raw', 'r; cell is raw'); | |
|
10 | 13 | this.trigger_keydown('1'); |
|
11 |
this.test.assertEquals(this.get_cell( |
|
|
12 |
this.test.assertEquals(this.get_cell( |
|
|
14 | this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '1; cell is markdown'); | |
|
15 | this.test.assertEquals(this.get_cell_text(index), '# ' + a, '1; markdown heading'); | |
|
13 | 16 | this.trigger_keydown('2'); |
|
14 |
this.test.assertEquals(this.get_cell( |
|
|
17 | this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '2; cell is markdown'); | |
|
18 | this.test.assertEquals(this.get_cell_text(index), '## ' + a, '2; markdown heading'); | |
|
15 | 19 | this.trigger_keydown('3'); |
|
16 |
this.test.assertEquals(this.get_cell( |
|
|
20 | this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '3; cell is markdown'); | |
|
21 | this.test.assertEquals(this.get_cell_text(index), '### ' + a, '3; markdown heading'); | |
|
17 | 22 | this.trigger_keydown('4'); |
|
18 |
this.test.assertEquals(this.get_cell( |
|
|
23 | this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '4; cell is markdown'); | |
|
24 | this.test.assertEquals(this.get_cell_text(index), '#### ' + a, '4; markdown heading'); | |
|
19 | 25 | this.trigger_keydown('5'); |
|
20 |
this.test.assertEquals(this.get_cell( |
|
|
26 | this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '5; cell is markdown'); | |
|
27 | this.test.assertEquals(this.get_cell_text(index), '##### ' + a, '5; markdown heading'); | |
|
21 | 28 | this.trigger_keydown('6'); |
|
22 |
this.test.assertEquals(this.get_cell( |
|
|
29 | this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '6; cell is markdown'); | |
|
30 | this.test.assertEquals(this.get_cell_text(index), '###### ' + a, '6; markdown heading'); | |
|
23 | 31 | this.trigger_keydown('m'); |
|
24 |
this.test.assertEquals(this.get_cell( |
|
|
32 | this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', 'm; cell is markdown'); | |
|
33 | this.test.assertEquals(this.get_cell_text(index), '###### ' + a, 'm; still markdown heading'); | |
|
25 | 34 | this.trigger_keydown('y'); |
|
26 |
this.test.assertEquals(this.get_cell( |
|
|
35 | this.test.assertEquals(this.get_cell(index).cell_type, 'code', 'y; cell is code'); | |
|
36 | this.test.assertEquals(this.get_cell_text(index), '###### ' + a, 'y; still has hashes'); | |
|
37 | this.trigger_keydown('1'); | |
|
38 | this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '1; cell is markdown'); | |
|
39 | this.test.assertEquals(this.get_cell_text(index), '# ' + a, '1; markdown heading'); | |
|
27 | 40 | }); |
|
28 | 41 | }); No newline at end of file |
@@ -10,38 +10,53 b' casper.notebook_test(function () {' | |||
|
10 | 10 | cell.render(); |
|
11 | 11 | return cell.get_rendered(); |
|
12 | 12 | }); |
|
13 |
this.test.assertEquals(output.trim(), '<h1 id=\" |
|
|
13 | this.test.assertEquals(output.trim(), '<h1 id=\"Foo\">Foo<a class=\"anchor-link\" href=\"#Foo\">ΒΆ</a></h1>', 'Markdown JS API works.'); | |
|
14 | 14 | |
|
15 | 15 | // Test menubar entries. |
|
16 | 16 | output = this.evaluate(function () { |
|
17 | 17 | $('#to_code').mouseenter().click(); |
|
18 | 18 | $('#to_markdown').mouseenter().click(); |
|
19 | 19 | var cell = IPython.notebook.get_selected_cell(); |
|
20 |
cell.set_text(' |
|
|
20 | cell.set_text('**Bar**'); | |
|
21 | 21 | $('#run_cell').mouseenter().click(); |
|
22 | 22 | return cell.get_rendered(); |
|
23 | 23 | }); |
|
24 |
this.test.assertEquals(output.trim(), '< |
|
|
24 | this.test.assertEquals(output.trim(), '<p><strong>Bar</strong></p>', 'Markdown menubar items work.'); | |
|
25 | 25 | |
|
26 | 26 | // Test toolbar buttons. |
|
27 | 27 | output = this.evaluate(function () { |
|
28 | 28 | $('#cell_type').val('code').change(); |
|
29 | 29 | $('#cell_type').val('markdown').change(); |
|
30 | 30 | var cell = IPython.notebook.get_selected_cell(); |
|
31 |
cell.set_text(' |
|
|
31 | cell.set_text('*Baz*'); | |
|
32 | 32 | $('#run_b').click(); |
|
33 | 33 | return cell.get_rendered(); |
|
34 | 34 | }); |
|
35 |
this.test.assertEquals(output.trim(), '< |
|
|
35 | this.test.assertEquals(output.trim(), '<p><em>Baz</em></p>', 'Markdown toolbar items work.'); | |
|
36 | 36 | |
|
37 | // Test JavaScript models. | |
|
38 | var output = this.evaluate(function () { | |
|
37 | // Test markdown headings | |
|
39 | 38 | |
|
39 | var text = 'multi\nline'; | |
|
40 | ||
|
41 | this.evaluate(function (text) { | |
|
40 | 42 | var cell = IPython.notebook.insert_cell_at_index('markdown', 0); |
|
41 |
cell.set_text( |
|
|
42 | cell.render(); | |
|
43 | return cell.get_rendered(); | |
|
44 | }); | |
|
45 | this.test.assertEquals(output.trim(), '<h1 id=\"qux\">Qux</h1>', 'Markdown JS API works.'); | |
|
43 | cell.set_text(text); | |
|
44 | }, {text: text}); | |
|
45 | ||
|
46 | var set_level = function (level) { | |
|
47 | return casper.evaluate(function (level) { | |
|
48 | var cell = IPython.notebook.get_cell(0); | |
|
49 | cell.set_heading_level(level); | |
|
50 | return cell.get_text(); | |
|
51 | }, {level: level}); | |
|
52 | }; | |
|
46 | 53 | |
|
54 | var level_text; | |
|
55 | var levels = [ 1, 2, 3, 4, 5, 6, 2, 1 ]; | |
|
56 | for (var idx=0; idx < levels.length; idx++) { | |
|
57 | var level = levels[idx]; | |
|
58 | level_text = set_level(level); | |
|
59 | hashes = new Array(level + 1).join('#'); | |
|
60 | this.test.assertEquals(level_text, hashes + ' ' + text, 'markdown set_heading_level ' + level); | |
|
61 | } | |
|
47 | 62 | }); |
@@ -1,11 +1,10 b'' | |||
|
1 | 1 | { |
|
2 | 2 | "cells": [ |
|
3 | 3 | { |
|
4 |
"cell_type": " |
|
|
5 | "level": 1, | |
|
4 | "cell_type": "markdown", | |
|
6 | 5 | "metadata": {}, |
|
7 | 6 | "source": [ |
|
8 | "NumPy and Matplotlib examples" | |
|
7 | "# NumPy and Matplotlib examples" | |
|
9 | 8 | ] |
|
10 | 9 | }, |
|
11 | 10 | { |
@@ -8,6 +8,7 b' import json' | |||
|
8 | 8 | from .base import ExportersTestsBase |
|
9 | 9 | from ..notebook import NotebookExporter |
|
10 | 10 | |
|
11 | from IPython.nbformat.current import validate | |
|
11 | 12 | from IPython.testing.tools import assert_big_text_equal |
|
12 | 13 | |
|
13 | 14 | class TestNotebookExporter(ExportersTestsBase): |
@@ -29,7 +30,7 b' class TestNotebookExporter(ExportersTestsBase):' | |||
|
29 | 30 | exporter = self.exporter_class(nbformat_version=3) |
|
30 | 31 | (output, resources) = exporter.from_filename(self._get_notebook()) |
|
31 | 32 | nb = json.loads(output) |
|
32 | self.assertEqual(nb['nbformat'], 3) | |
|
33 | validate(nb) | |
|
33 | 34 | |
|
34 | 35 | def test_downgrade_2(self): |
|
35 | 36 | exporter = self.exporter_class(nbformat_version=2) |
@@ -21,6 +21,7 b' from pygments.formatters import HtmlFormatter' | |||
|
21 | 21 | from pygments.util import ClassNotFound |
|
22 | 22 | |
|
23 | 23 | # IPython imports |
|
24 | from IPython.nbconvert.filters.strings import add_anchor | |
|
24 | 25 | from IPython.nbconvert.utils.pandoc import pandoc |
|
25 | 26 | from IPython.nbconvert.utils.exceptions import ConversionException |
|
26 | 27 | from IPython.utils.decorators import undoc |
@@ -146,6 +147,10 b' class IPythonRenderer(mistune.Renderer):' | |||
|
146 | 147 | formatter = HtmlFormatter() |
|
147 | 148 | return highlight(code, lexer, formatter) |
|
148 | 149 | |
|
150 | def header(self, text, level, raw=None): | |
|
151 | html = super(IPythonRenderer, self).header(text, level, raw=raw) | |
|
152 | return add_anchor(html) | |
|
153 | ||
|
149 | 154 | # Pass math through unaltered - mathjax does the rendering in the browser |
|
150 | 155 | def block_math(self, text): |
|
151 | 156 | return '$$%s$$' % text |
@@ -4,17 +4,9 b'' | |||
|
4 | 4 | Contains a collection of useful string manipulation filters for use in Jinja |
|
5 | 5 | templates. |
|
6 | 6 | """ |
|
7 | #----------------------------------------------------------------------------- | |
|
8 | # Copyright (c) 2013, the IPython Development Team. | |
|
9 | # | |
|
10 | # Distributed under the terms of the Modified BSD License. | |
|
11 | # | |
|
12 | # The full license is in the file COPYING.txt, distributed with this software. | |
|
13 | #----------------------------------------------------------------------------- | |
|
14 | 7 | |
|
15 | #----------------------------------------------------------------------------- | |
|
16 | # Imports | |
|
17 | #----------------------------------------------------------------------------- | |
|
8 | # Copyright (c) IPython Development Team. | |
|
9 | # Distributed under the terms of the Modified BSD License. | |
|
18 | 10 | |
|
19 | 11 | import os |
|
20 | 12 | import re |
@@ -28,9 +20,6 b' from xml.etree import ElementTree' | |||
|
28 | 20 | from IPython.core.interactiveshell import InteractiveShell |
|
29 | 21 | from IPython.utils import py3compat |
|
30 | 22 | |
|
31 | #----------------------------------------------------------------------------- | |
|
32 | # Functions | |
|
33 | #----------------------------------------------------------------------------- | |
|
34 | 23 | |
|
35 | 24 | __all__ = [ |
|
36 | 25 | 'wrap_text', |
@@ -88,9 +77,9 b' def html2text(element):' | |||
|
88 | 77 | |
|
89 | 78 | |
|
90 | 79 | def add_anchor(html): |
|
91 |
"""Add an anchor-link to an html header |
|
|
80 | """Add an anchor-link to an html header | |
|
92 | 81 | |
|
93 |
For use |
|
|
82 | For use on markdown headings | |
|
94 | 83 | """ |
|
95 | 84 | try: |
|
96 | 85 | h = ElementTree.fromstring(py3compat.cast_bytes_py2(html, encoding='utf-8')) |
@@ -1,3 +1,4 b'' | |||
|
1 | # coding: utf-8 | |
|
1 | 2 | """Tests for conversions from markdown to other formats""" |
|
2 | 3 | |
|
3 | 4 | # Copyright (c) IPython Development Team. |
@@ -26,7 +27,8 b' class TestMarkdown(TestsBase):' | |||
|
26 | 27 | '#test', |
|
27 | 28 | '##test', |
|
28 | 29 | 'test\n----', |
|
29 |
'test [link](https://google.com/)' |
|
|
30 | 'test [link](https://google.com/)', | |
|
31 | ] | |
|
30 | 32 | |
|
31 | 33 | tokens = [ |
|
32 | 34 | '*test', |
@@ -39,7 +41,8 b' class TestMarkdown(TestsBase):' | |||
|
39 | 41 | 'test', |
|
40 | 42 | 'test', |
|
41 | 43 | 'test', |
|
42 |
('test', 'https://google.com/') |
|
|
44 | ('test', 'https://google.com/'), | |
|
45 | ] | |
|
43 | 46 | |
|
44 | 47 | |
|
45 | 48 | @dec.onlyif_cmds_exist('pandoc') |
@@ -87,6 +90,17 b' class TestMarkdown(TestsBase):' | |||
|
87 | 90 | for index, test in enumerate(self.tests): |
|
88 | 91 | self._try_markdown(markdown2html, test, self.tokens[index]) |
|
89 | 92 | |
|
93 | def test_markdown2html_heading_anchors(self): | |
|
94 | for md, tokens in [ | |
|
95 | ('# test', | |
|
96 | ('<h1', '>test', 'id="test"', u'¶</a>', "anchor-link") | |
|
97 | ), | |
|
98 | ('###test head space', | |
|
99 | ('<h3', '>test head space', 'id="test-head-space"', u'¶</a>', "anchor-link") | |
|
100 | ) | |
|
101 | ]: | |
|
102 | self._try_markdown(markdown2html, md, tokens) | |
|
103 | ||
|
90 | 104 | def test_markdown2html_math(self): |
|
91 | 105 | # Mathematical expressions should be passed through unaltered |
|
92 | 106 | cases = [("\\begin{equation*}\n" |
@@ -79,17 +79,6 b' In [ ]:' | |||
|
79 | 79 | </div> |
|
80 | 80 | {%- endblock markdowncell %} |
|
81 | 81 | |
|
82 | {% block headingcell scoped %} | |
|
83 | <div class="cell border-box-sizing text_cell rendered"> | |
|
84 | {{ self.empty_in_prompt() }} | |
|
85 | <div class="inner_cell"> | |
|
86 | <div class="text_cell_render border-box-sizing rendered_html"> | |
|
87 | {{ ("#" * cell.level + cell.source) | replace('\n', ' ') | markdown2html | strip_files_prefix | add_anchor }} | |
|
88 | </div> | |
|
89 | </div> | |
|
90 | </div> | |
|
91 | {% endblock headingcell %} | |
|
92 | ||
|
93 | 82 | {% block unknowncell scoped %} |
|
94 | 83 | unknown type {{ cell.type }} |
|
95 | 84 | {% endblock unknowncell %} |
@@ -185,27 +185,6 b' This template does not define a docclass, the inheriting class must define this.' | |||
|
185 | 185 | ((*- endblock figure -*)) |
|
186 | 186 | ((*- endmacro *)) |
|
187 | 187 | |
|
188 | % Draw heading cell. Explicitly map different cell levels. | |
|
189 | ((* block headingcell scoped *)) | |
|
190 | ||
|
191 | ((* if cell.level == 1 -*)) | |
|
192 | ((* block h1 -*))\section((* endblock h1 -*)) | |
|
193 | ((* elif cell.level == 2 -*)) | |
|
194 | ((* block h2 -*))\subsection((* endblock h2 -*)) | |
|
195 | ((* elif cell.level == 3 -*)) | |
|
196 | ((* block h3 -*))\subsubsection((* endblock h3 -*)) | |
|
197 | ((* elif cell.level == 4 -*)) | |
|
198 | ((* block h4 -*))\paragraph((* endblock h4 -*)) | |
|
199 | ((* elif cell.level == 5 -*)) | |
|
200 | ((* block h5 -*))\subparagraph((* endblock h5 -*)) | |
|
201 | ((* elif cell.level == 6 -*)) | |
|
202 | ((* block h6 -*))\\*\textit((* endblock h6 -*)) | |
|
203 | ((*- endif -*)) | |
|
204 | {((( cell.source | replace('\n', ' ') | citation2latex | strip_files_prefix | prevent_list_blocks | markdown2latex(markup='markdown_strict+tex_math_dollars') )))} | |
|
205 | ||
|
206 | ||
|
207 | ((* endblock headingcell *)) | |
|
208 | ||
|
209 | 188 | % Redirect execute_result to display data priority. |
|
210 | 189 | ((* block execute_result scoped *)) |
|
211 | 190 | ((* block data_priority scoped *)) |
@@ -75,9 +75,6 b' consider calling super even if it is a leave block, we might insert more blocks ' | |||
|
75 | 75 | ((*- elif cell.cell_type in ['markdown'] -*)) |
|
76 | 76 | ((*- block markdowncell scoped-*)) |
|
77 | 77 | ((*- endblock markdowncell -*)) |
|
78 | ((*- elif cell.cell_type in ['heading'] -*)) | |
|
79 | ((*- block headingcell scoped-*)) | |
|
80 | ((*- endblock headingcell -*)) | |
|
81 | 78 | ((*- elif cell.cell_type in ['raw'] -*)) |
|
82 | 79 | ((*- block rawcell scoped -*)) |
|
83 | 80 | ((* if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) *)) |
@@ -58,11 +58,6 b'' | |||
|
58 | 58 | {{ cell.source }} |
|
59 | 59 | {% endblock markdowncell %} |
|
60 | 60 | |
|
61 | ||
|
62 | {% block headingcell scoped %} | |
|
63 | {{ '#' * cell.level }} {{ cell.source | replace('\n', ' ') }} | |
|
64 | {% endblock headingcell %} | |
|
65 | ||
|
66 | 61 | {% block unknowncell scoped %} |
|
67 | 62 | unknown type {{ cell.type }} |
|
68 | 63 | {% endblock unknowncell %} No newline at end of file |
@@ -15,7 +15,3 b'' | |||
|
15 | 15 | {% block markdowncell scoped %} |
|
16 | 16 | {{ cell.source | comment_lines }} |
|
17 | 17 | {% endblock markdowncell %} |
|
18 | ||
|
19 | {% block headingcell scoped %} | |
|
20 | {{ '#' * cell.level }}{{ cell.source | replace('\n', ' ') | comment_lines }} | |
|
21 | {% endblock headingcell %} |
@@ -71,9 +71,6 b' consider calling super even if it is a leave block, we might insert more blocks ' | |||
|
71 | 71 | {%- elif cell.cell_type in ['markdown'] -%} |
|
72 | 72 | {%- block markdowncell scoped-%} |
|
73 | 73 | {%- endblock markdowncell -%} |
|
74 | {%- elif cell.cell_type in ['heading'] -%} | |
|
75 | {%- block headingcell scoped-%} | |
|
76 | {%- endblock headingcell -%} | |
|
77 | 74 | {%- elif cell.cell_type in ['raw'] -%} |
|
78 | 75 | {%- block rawcell scoped -%} |
|
79 | 76 | {% if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) %} |
@@ -1,11 +1,10 b'' | |||
|
1 | 1 | { |
|
2 | 2 | "cells": [ |
|
3 | 3 | { |
|
4 |
"cell_type": " |
|
|
5 | "level": 1, | |
|
4 | "cell_type": "markdown", | |
|
6 | 5 | "metadata": {}, |
|
7 | 6 | "source": [ |
|
8 | "A simple SymPy example" | |
|
7 | "# A simple SymPy example" | |
|
9 | 8 | ] |
|
10 | 9 | }, |
|
11 | 10 | { |
@@ -1,11 +1,10 b'' | |||
|
1 | 1 | { |
|
2 | 2 | "cells": [ |
|
3 | 3 | { |
|
4 |
"cell_type": " |
|
|
5 | "level": 1, | |
|
4 | "cell_type": "markdown", | |
|
6 | 5 | "metadata": {}, |
|
7 | 6 | "source": [ |
|
8 | "NumPy and Matplotlib examples" | |
|
7 | "# NumPy and Matplotlib examples" | |
|
9 | 8 | ] |
|
10 | 9 | }, |
|
11 | 10 | { |
@@ -157,11 +156,10 b'' | |||
|
157 | 156 | ] |
|
158 | 157 | }, |
|
159 | 158 | { |
|
160 |
"cell_type": " |
|
|
161 | "level": 2, | |
|
159 | "cell_type": "markdown", | |
|
162 | 160 | "metadata": {}, |
|
163 | 161 | "source": [ |
|
164 | "Here is a very long heading that pandoc will wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap" | |
|
162 | "## Here is a very long heading that pandoc will wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap" | |
|
165 | 163 | ] |
|
166 | 164 | }, |
|
167 | 165 | { |
@@ -1,145 +1,306 b'' | |||
|
1 | 1 | { |
|
2 | "metadata": { | |
|
3 | "name": 0 | |
|
4 | }, | |
|
5 | "nbformat": 3, | |
|
6 | "nbformat_minor": 0, | |
|
7 | "worksheets": [ | |
|
2 | "cells": [ | |
|
8 | 3 | { |
|
9 | "cells": [ | |
|
10 | { | |
|
11 | "cell_type": "heading", | |
|
12 | "level": 1, | |
|
13 | "source": [ | |
|
14 | "nbconvert latex test" | |
|
15 | ] | |
|
16 | }, | |
|
17 |
|
|
|
18 | "cell_type": "markdown", | |
|
19 | "metadata": {}, | |
|
20 | "source": [ | |
|
21 | "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis." | |
|
22 | ] | |
|
23 | }, | |
|
24 | { | |
|
25 | "cell_type": "heading", | |
|
26 | "level": 2, | |
|
27 | "metadata": {}, | |
|
28 | "source": [ | |
|
29 | "Printed Using Python" | |
|
30 | ] | |
|
31 | }, | |
|
32 |
|
|
|
33 | "cell_type": "code", | |
|
34 | "collapsed": false, | |
|
35 | "input": [ | |
|
36 | "print(\"hello\")" | |
|
37 | ], | |
|
38 | "language": "python", | |
|
39 | "outputs": [ | |
|
40 | { | |
|
41 | "output_type": "stream", | |
|
42 | "stream": "stdout", | |
|
43 | "text": [ | |
|
44 | "hello\n" | |
|
45 | ] | |
|
46 | } | |
|
47 | ], | |
|
48 | "prompt_number": 1 | |
|
49 | }, | |
|
4 | "cell_type": "markdown", | |
|
5 | "metadata": {} | |
|
6 | }, | |
|
7 | { | |
|
8 | "cell_type": "markdown", | |
|
9 | "metadata": {}, | |
|
10 | "source": [ | |
|
11 | "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis." | |
|
12 | ] | |
|
13 | }, | |
|
14 | { | |
|
15 | "cell_type": "heading", | |
|
16 | "level": 2, | |
|
17 | "metadata": {}, | |
|
18 | "source": [ | |
|
19 | "Printed Using Python" | |
|
20 | ] | |
|
21 | }, | |
|
22 | { | |
|
23 | "cell_type": "code", | |
|
24 | "execution_count": 1, | |
|
25 | "metadata": { | |
|
26 | "collapsed": false | |
|
27 | }, | |
|
28 | "outputs": [ | |
|
50 | 29 | { |
|
51 | "cell_type": "heading", | |
|
52 | "level": 1000, | |
|
53 |
" |
|
|
54 | "source": [ | |
|
55 | "Pyout" | |
|
30 | "name": "stdout", | |
|
31 | "output_type": "bad stream", | |
|
32 | "text": [ | |
|
33 | "hello\n" | |
|
56 | 34 | ] |
|
57 |
} |
|
|
35 | } | |
|
36 | ], | |
|
37 | "source": [ | |
|
38 | "print(\"hello\")" | |
|
39 | ] | |
|
40 | }, | |
|
41 | { | |
|
42 | "cell_type": "markdown", | |
|
43 | "metadata": {}, | |
|
44 | "source": [ | |
|
45 | "## Pyout" | |
|
46 | ] | |
|
47 | }, | |
|
48 | { | |
|
49 | "cell_type": "code", | |
|
50 | "execution_count": 3, | |
|
51 | "metadata": { | |
|
52 | "collapsed": false | |
|
53 | }, | |
|
54 | "outputs": [ | |
|
58 | 55 | { |
|
59 | "cell_type": "code", | |
|
60 | "collapsed": false, | |
|
61 | "input": [ | |
|
62 | "from IPython.display import HTML\n", | |
|
63 | "HTML(\"\"\"\n", | |
|
64 | "<script>\n", | |
|
65 | "console.log(\"hello\");\n", | |
|
66 | "</script>\n", | |
|
67 | "<b>HTML</b>\n", | |
|
68 | "\"\"\")" | |
|
69 |
] |
|
|
70 | "language": "python", | |
|
56 | "data": { | |
|
57 | "text/html": [ | |
|
58 | "\n", | |
|
59 | "<script>\n", | |
|
60 | "console.log(\"hello\");\n", | |
|
61 | "</script>\n", | |
|
62 | "<b>HTML</b>\n" | |
|
63 | ], | |
|
64 | "text/plain": [ | |
|
65 | "<IPython.core.display.HTML at 0x1112757d0>" | |
|
66 | ] | |
|
67 | }, | |
|
68 | "execution_count": 3, | |
|
71 | 69 | "metadata": {}, |
|
72 | "outputs": [ | |
|
73 |
|
|
|
74 | "html": [ | |
|
75 | "\n", | |
|
76 | "<script>\n", | |
|
77 | "console.log(\"hello\");\n", | |
|
78 |
|
|
|
79 | "<b>HTML</b>\n" | |
|
80 | ], | |
|
81 | "metadata": {}, | |
|
82 | "output_type": "pyout", | |
|
83 | "prompt_number": 3, | |
|
84 | "text": [ | |
|
85 | "<IPython.core.display.HTML at 0x1112757d0>" | |
|
86 | ] | |
|
87 | } | |
|
88 | ], | |
|
89 | "prompt_number": 3 | |
|
90 |
|
|
|
70 | "output_type": "execute_result" | |
|
71 | } | |
|
72 | ], | |
|
73 | "source": [ | |
|
74 | "from IPython.display import HTML\n", | |
|
75 | "HTML(\"\"\"\n", | |
|
76 | "<script>\n", | |
|
77 | "console.log(\"hello\");\n", | |
|
78 | "</script>\n", | |
|
79 | "<b>HTML</b>\n", | |
|
80 | "\"\"\")" | |
|
81 | ] | |
|
82 | }, | |
|
83 | { | |
|
84 | "cell_type": "code", | |
|
85 | "execution_count": 7, | |
|
86 | "metadata": { | |
|
87 | "collapsed": false | |
|
88 | }, | |
|
89 | "outputs": [ | |
|
91 | 90 | { |
|
92 | "cell_type": "code", | |
|
93 | "collapsed": false, | |
|
94 | "input": [ | |
|
95 | "%%javascript\n", | |
|
96 | "console.log(\"hi\");" | |
|
97 | ], | |
|
98 | "language": "python", | |
|
91 | "data": { | |
|
92 | "application/javascript": [ | |
|
93 | "console.log(\"hi\");" | |
|
94 | ], | |
|
95 | "text/plain": [ | |
|
96 | "<IPython.core.display.Javascript at 0x1112b4b50>" | |
|
97 | ] | |
|
98 | }, | |
|
99 | 99 | "metadata": {}, |
|
100 | "outputs": [ | |
|
101 |
|
|
|
102 | "javascript": [ | |
|
103 | "console.log(\"hi\");" | |
|
104 | ], | |
|
105 | "metadata": {}, | |
|
106 | "output_type": "display_data", | |
|
107 | "text": [ | |
|
108 | "<IPython.core.display.Javascript at 0x1112b4b50>" | |
|
109 | ] | |
|
110 | } | |
|
111 | ], | |
|
112 | "prompt_number": 7 | |
|
113 |
|
|
|
114 | { | |
|
115 | "cell_type": "heading", | |
|
116 | "level": 3, | |
|
117 | "metadata": {} | |
|
118 | }, | |
|
100 | "output_type": "display_data" | |
|
101 | } | |
|
102 | ], | |
|
103 | "source": [ | |
|
104 | "%%javascript\n", | |
|
105 | "console.log(\"hi\");" | |
|
106 | ] | |
|
107 | }, | |
|
108 | { | |
|
109 | "cell_type": "markdown", | |
|
110 | "metadata": {}, | |
|
111 | "source": [ | |
|
112 | "### Image" | |
|
113 | ] | |
|
114 | }, | |
|
115 | { | |
|
116 | "cell_type": "code", | |
|
117 | "execution_count": 6, | |
|
118 | "metadata": { | |
|
119 | "collapsed": false | |
|
120 | }, | |
|
121 | "outputs": [ | |
|
119 | 122 | { |
|
120 | "cell_type": "code", | |
|
121 | "collapsed": false, | |
|
122 | "input": [ | |
|
123 | "from IPython.display import Image\n", | |
|
124 | "Image(\"http://ipython.org/_static/IPy_header.png\")" | |
|
125 | ], | |
|
126 | "language": "python", | |
|
123 | "data": { | |
|
124 | "image/png": [ | |
|
125 | "iVBORw0KGgoAAAANSUhEUgAAAggAAABDCAYAAAD5/P3lAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n", | |
|
126 | "AAAH3AAAB9wBYvxo6AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURB\n", | |
|
127 | "VHic7Z15uBxF1bjfugkJhCWBsCSAJGACNg4QCI3RT1lEAVE+UEBNOmwCDcjHT1wQgU+WD3dFxA1o\n", | |
|
128 | "CAikAZFFVlnCjizpsCUjHQjBIAkQlpCFJGS79fvjdGf69vTsc2fuza33eeaZmeqq6jM9vZw6dc4p\n", | |
|
129 | "BUwC+tE+fqW1fqmRDpRSHjCggS40sBxYDCxKvL8KzNBaL21EPoPB0DPIWVY/4NlE0ffzYfhgu+Qx\n", | |
|
130 | "GHoy/YFjaK+CcB3QkIIAHAWs3wRZsuhUSs0CXgQeBm7UWi/spn0Z+jA5yxpEfYruqnwYllRic5a1\n", | |
|
131 | "MaWv8U5gaT4M19Sx396IAnZLfB/SLkEMhp5O/3YL0AvoAHaKXl8HLlZK3QZcpbWe0lbJDOsaHuDU\n", | |
|
132 | "0e4u4JAy2wPk/C1JzrKWArOQ0fUtwH35MOysQxaDwbCO0NFuAXoh6wPjgQeUUvcqpUa0WyCDoQls\n", | |
|
133 | "CIwBjgfuAV7KWdY+7RWpmJxlXZezrEdylvXxdstiMKzrGAtCYxwI/EspdZbW+g/tFsbQ67kQuBHY\n", | |
|
134 | "FNgseh9FV6vCbUAeWBC9PgBeq2EfS6J2MQOBrRDTe5KdgAdzlvW1fBjeUUP/3UbOsoYBE6OvG7VT\n", | |
|
135 | "FoOhL9Af+BUwFLkZpV+DaY6V4UPkRpb1+ncT+m8nGwK/V0oN01qf025hDL2XfBi+DLycLMtZVo6u\n", | |
|
136 | "CsKfGnSq8/NheEpqHwOBEcDBwJnAsGhTP2ByzrJG5cPwnQb22Sy+0G4BDIa+RH+t9dmlNiqlFKIk\n", | |
|
137 | "JJWGi+jq5JPmq8BbJJQArfXqpkncczlbKbVQa/3rdgtiMNRCPgxXAK8Ar+Qs63LgXmDvaPPGwPeA\n", | |
|
138 | "H7VJvCRfbLcABkNfouwUg9ZaAwuj178BlFLvVejzgR4WFviM1npcuQpKqf6IyXIjxLS7GzAWuUnu\n", | |
|
139 | "XsO+fqWUellr3ZBJdq/jr9+BDn1uve07O9Rz0y6f8PtGZGgWe53oT6SBkZ/q1/nHZy47aloTRTKU\n", | |
|
140 | "IR+Gy3OWNR6Zxtg0Kv4KRkEwGPocxgcBiCwcsSI0F5iOhF+ilPok8C3gVGS+thK/VErdrbWuO2ys\n", | |
|
141 | "s/+aLZTuOKbe9krrIUCPUBB0B+PQ1P1bdKe6EzAKQgvJh+GbOct6gkJkxM45y+qXDIWMHBhjBWJe\n", | |
|
142 | "PgyDWvaRs6zPIVObAG/nw/DpEvUGAp8E9gGGJzbtl7Os7cvs4skqp0V0Yl8jgcOBjyMDhbmIZeWl\n", | |
|
143 | "fBg+UUVfReQsayhwELAnsAXi6/E28BxwTz4MP6iyn92RaSCA+/NhuCwqXx9R4MYhU0MfRTK/AjyW\n", | |
|
144 | "D8MFGd0ZDFVhFIQKaK3/BXxfKXUlklTq0xWafAI4Driyu2UzGLqRlygoCArYHJif2H4gcFb0+Z2c\n", | |
|
145 | "ZW2bD8NV1XScs6yNgH8g/jsAPwCeTmzfFPgjYsnbiez71MUVdnMQcF8V4nyUs6whwB8QX4+0s2Ys\n", | |
|
146 | "0yPAt/NhGFbRZ/wbzgO+DaxXotqqnGX9GbigCkXhf5CBCsDngYdzljURGQhsWqLN+znL+iFwdT4M\n", | |
|
147 | "dYk6BkNJTJhjlWitQ2Bf4P4qqv848t8wGHor6Yd9+ruHJFkC2BI4rIa+D6egHKwmstYlGAxMQCwH\n", | |
|
148 | "rRjEPI5ER5S7ZvcFXsxZ1phKneUsawSi8HyH0soB0bbvAM9Ebaplt5xlnYkct1LKAYiFZhJwSQ19\n", | |
|
149 | "GwxrMRaEGtBar1RKfRX4JxIzXortou3PN1mE+YgJsSwaeoLHOQCqUy3QSr9eqZ6G/gq2aYVMhqrY\n", | |
|
150 | "OfF5FeJwvJZ8GM7JWdY/gC9HRS7wtyr7Pjrx+e6MqYC3KLbU7Qhck/h+FJIKvRRVjfSREXicU8EH\n", | |
|
151 | "pgAvIIqLBZwGfC7avl5Uf29KkLOsTZCMq8npj9sQx89no37HIlaAODplNPBIzrJ2z4dhNVlaT0HC\n", | |
|
152 | "XwFmIkrAC4if2PaIz8/3KCgn385Z1pX5MJxeRd8Gw1qMglAjWutlSqnTgUcqVP0SzVYQtP5mcMXE\n", | |
|
153 | "SvvtUUy9YsK5QEWHy7EnTB6lOtSsFohkqEDOsgYAdqJoagkT9Z8pKAj75yzr4/kwnF2h748ho/GY\n", | |
|
154 | "q9J1oqiKLj4JOctKK8Yz8mH4Yrl9VcnHkXVYTsyHoZ8WJWdZNyPThbF5/3M5yzowH4alpi9+T0E5\n", | |
|
155 | "WA18Nx+Gf0zVeRG4KmdZ90R9bwCMRKwyX69C5h2j91uA4/JhuCSxbTYwJWdZtwNPIFbifsAFSISZ\n", | |
|
156 | "wVA1ZoqhDrTWjyIjjXIc3ApZDIZu4ELgY4nvt5Wody8wJ/qsgBOr6HsihfvOfCRrY7v5dYZyAECk\n", | |
|
157 | "GP0ISEZmZYZ55yxrB8SyEXNxhnKQ7Pt64H8TRUfmLGuXKmWeC4xPKQfJvp9CLCJlZTYYymEUhPq5\n", | |
|
158 | "tcL2XVsihcHQJHKWtU3Osi5GnAZj5iKWgiKitRouTxQdl7OscnPu0HV64dp8GLY7R8pyxEGxJPkw\n", | |
|
159 | "fBcZ9ceUSvN8IoV76upK/UZcgawcG3NKqYopfleFU+gDic/b5SzLWIwNNWFOmPqp5CG9sVJqPa11\n", | |
|
160 | "VZ7dBkOL2D1nWcmcBkOR8MFtgM/QdTXJZcCR+TBcXqa/SYj5egAFZ8VMX4ScZe2FRPnEXF2z9M3n\n", | |
|
161 | "3nwYVsrtAmK6/0z0uVR4ZXLtivvzYfhGpU7zYbgkZ1k3ACdHRQdWIQsUO3ZmkUzB3Q/xjaolLbeh\n", | |
|
162 | "j2MUhDrRWr+mlFpJ+eV5hyIxz4YWs98Fj/Rf8uZbozo0/ZYt7D8rf9ORK9stUw/hU9GrEnMAp1R+\n", | |
|
163 | "gph8GL4bzdNPiIpOorSzYtJ68FS1IYPdTLWp3hcnPm+Q3pizrA7E+TCmFn+aZN0dcpY1LB+G5e4b\n", | |
|
164 | "y6rM8bA49X39GmQyGMwUQ4NUGnkMrbDd0A3sdeLk4z6cN+89pTtDTWd+gyErF+7pTv5eu+XqJbyK\n", | |
|
165 | "TDHsmg/DJ6tsc2ni8+dzljUqXSGaevhmoqjIObFNVBzlV8kQug4W5tbQNl13WGatAv+poW+DoW6M\n", | |
|
166 | "BaExPgC2LrO9nHWhpSilDqI4NPMhrfXUJvS9M/DfqeJXtdY3N9p3rex50uQ9lFKT6BrTvoFCXbTX\n", | |
|
167 | "yZNfmnrZxHtbLVMP4xng74nvK5DzeD7wfIWRayb5MHwiZ1kzgF0oOCuemar2ZQoK8zLgr7Xup5t4\n", | |
|
168 | "s0n9DEl9b0RBSPeV5q0a+jYY6sYoCI1RacnZ91siRXUMAH6eKnsYicdulDOAY1NlpzWh35pRqG9R\n", | |
|
169 | "IuGN7uw4AfG878s8nw/DX3RDv5dScGY8NmdZP86HYXJaJzm9cHMp7/s2UHdK9BTpKaxBNbRN163k\n", | |
|
170 | "t9Rux05DH8FMMTTGZhW2v9sSKarjbopNk/sqpUY30qlSahCSGS/JCuD6RvqtF6UpMm/HaHTJbYaG\n", | |
|
171 | "mQzED/0umRVzlrUZhXwJ0HOmF5pJOlXyxzJrZbNt6rtZP8HQIzAKQp0opTZAlsItxTKtdTnv75YS\n", | |
|
172 | "LR7lpYqrjV0vx2EUH4fbtdZtucnpMqOrDjPy6jYii8DkRFHSYnAEhem22cBjrZKrVeTDcCldTf/p\n", | |
|
173 | "h345ksrEGprnF2EwNIRREOrnMxW2z2uJFLVxJcXmy2OVUo34ShydUda+EaIq7T2u0SZTY/eSdFY8\n", | |
|
174 | "MGdZm0efk86J6/LCQUnFp5pIkZjkcvQz8mH4YZPkMRgawigI9VNp7v7BlkhRA1rr+RQneNqC2hba\n", | |
|
175 | "WYtSajiS9z3JXLomaGktq/VllLIUdKqSWe0MjZMPwxlIel8Q/6Zv5CxrGIX8AJ10XU+hFtIRQ+UW\n", | |
|
176 | "KWoXyYyTu+Qsa79KDXKWNRpJyx5zZ9OlMhjqxCgIdaCU6g98o0K1npBCNotLM8rcOvuagCRgSXKN\n", | |
|
177 | "1rozq3IrCCZNfFkrfRjotWsCaJinUBODK51/tkuuPkTy/DoYOIDCfeb+fBjW4t2/lqhdcmRdbUri\n", | |
|
178 | "VnILXS2HZ1WRvfAcCk61K4A/dYdgBkM9GAWhPr5F6XSrIBf6Qy2SpSaidSReShV/XilV7veUIj29\n", | |
|
179 | "oOkB2fGmXT7x7sCbOGpFf7VZx4A1m0/znG2nehMyc+0bms7NFJxzxwH7J7Y1OvWUPG9/mLOsLRvs\n", | |
|
180 | "r6lEaaOT0TtfBB5ITLWsJWdZg3KWdRNwTKL4wnwYzu9mMQ2GqjFhjjWilBqBpJYtx51a66UV6rST\n", | |
|
181 | "S+maJz52VvxRdvVilFK7UbzexGNa67Kr+bWS6X+ekPYs79HkLGt34JOI+Xyz6D2d1vfMnGUdini6\n", | |
|
182 | "L0C851/Oh2HD+SyaQT4MV+YsaxJyLm1Gwf9gAXBHg93/JNHHtsArOcuajCztPBDYCkkytBXg5sOw\n", | |
|
183 | "5QmF8mF4W86yLgK+HxXtC8zKWVaALMm8CslHsicS7RFzL8VhyAZDWzEKQg0opbYE7qd8prPVdF2h\n", | |
|
184 | "rSdyLfALYMNE2XFKqR/XsHbEURll62L4Wiv5PuBUqPPF6JXkLuCQbpGoPi4HfohYKGMHWD9axrlu\n", | |
|
185 | "8mF4Z7RuwfioaDBwaonqRemQW0U+DH+Qs6xFwHnIFNwQsv+3mMnA8dHiVwZDj8FMMVSJUuow4DkK\n", | |
|
186 | "a7GX4gqt9cstEKlutNaL6boULMho5tBq2iul+lH8IFuCmJcNfZx8GM6hOCFVU5THfBhOQHxfylkH\n", | |
|
187 | "3gY+asb+6iUfhhcCewC3l5BlFbJk/P75MDwqlVTKYOgRKK1rizhSSk2h67ximo1abV5XSi2n9EIk\n", | |
|
188 | "z2itx5XYVqnfQcjI7DiqW2XtfeCTUbRA3ex50nWfUrqjeJEcrfcLrpj4SCN9xyilxgDPp4of0Fof\n", | |
|
189 | "UEXbg4B/pIqv1FrXnVNh7AmTR3V0qIwwRH1E4E28pd5+De0hZ1m/Bb4bfX0+H4Z7dMM+hgGjkDwC\n", | |
|
190 | "S5FpjFk9bR4/Z1mDkGmF4VHR20g4Y3oxJYOhR9EXphg6lFLlVjFbH0mZvDGwCTAayCFe0ntTOZ1y\n", | |
|
191 | "zDLgkEaVg1ahtX5BKfUU8OlE8ReUUjtorSstCduzch8YehSR5/6ERFG3nBvRuhE9frXUfBguA6pd\n", | |
|
192 | "+Mpg6DH0BQXBBro7o+Ea4Bta66e6eT/N5lK6KggKOAE4u1QDpdTGFOdNmNkLf7uh+zgYcRQEMa+3\n", | |
|
193 | "Je22wWBoDOOD0DhLgYla67vaLUgd3ETxglLHRXkeSnEExQ5gbQ9tNPQokis5TsqHoVlbwGDohRgF\n", | |
|
194 | "oTECYHet9Y3tFqQetNYrKDb/DqN46eYk6emF1UhUhMFAzrImUEhDvgr4VRvFMRgMDWAUhPpYAvwf\n", | |
|
195 | "8Bmte31+/8uQBEdJMjMrKqW2o5A2N+YfWusePw9s6F5yltWRs6zxwKRE8RXtyEVgMBiaQ1/wQWgm\n", | |
|
196 | "eWTe/jqtdU9Zz74htNavKaXuAw5KFB+glBqptZ6Tqj6RQlrYGDO90AfJWdY5wNeQFQwHIAmetk5U\n", | |
|
197 | "eZFCsiCDwdALMQpCed5AphEC4NF12BHvUroqCAoJ7TwvVS+d++BdJEmPoe+xKRLnn0UeODwfhm3N\n", | |
|
198 | "RWAwGBqjLygIbwN/LbNdI1MGH6ReL/eWkMUmcDeSeGa7RNlRSqnzdZQoQym1C7Bzqt11NWReNKxb\n", | |
|
199 | "zEMU6GHAesBiYCaSLOviaF0Cg8HQi+kLCsLrWuvT2y1ET0ZrvUYp5SG57mO2Bz4LPB59/2ZRQ5P7\n", | |
|
200 | "oM+SD8OLgYvbLYfBYOg+jJOiIeZKxOs8STJiIb28daC1/lf3imQwGAyGdmEUBAMA0XTKraniI5VS\n", | |
|
201 | "A6O0zOnloI31wGAwGNZhjIJgSHJp6vtgJBNlehW65cANLZHIYDAYDG3BKAiGtWitHwVeShV/muLF\n", | |
|
202 | "uW7VWi9qjVQGg8FgaAd9wUnRUBuXAn9IfN8f+FyqTo/OfbDnSX8brDpXnqEUe2ropzQvdtDx66ev\n", | |
|
203 | "GN9XolIMPQDb9T8LrBd4zsPtlsXQe7Bd/0BgQeA5QbtlMQqCIc21wC+ADaPv6WWu5wAPtVKgWtjt\n", | |
|
204 | "6Os2XG/9jhdQjIzTQ2rFF9bQecy4E2/I9UQlwXb9LYDDK1R7K/Cc21shj6FxbNcfDjwGKNv1Rwae\n", | |
|
205 | "83q7ZWo2tusPBb6ELGW9BbAICX99Gngs8Jx0hlZDBWzXHwvcC6ywXX9o4DlL2ymPURAMXdBaL1ZK\n", | |
|
206 | "+ZRItwz8Jc6N0BMZMFB9GxiZsWnzTjrPAH7QWomqYgTF/h9pngC6RUGwXf+XwC2B50ztjv57M7br\n", | |
|
207 | "XwJMCjxneo1NP0SWgAfJq7LOYLv+esAFwOkUL9wWM912/d0Dz+lsnWQ9A9v1BwEXAT8PPKfWVOML\n", | |
|
208 | "kPVt3kNWQm0rxgfBkEWph5UG/tJCOWqnQ40ttUkrvWcrRamWwHOmAZsguSfGAi9Hmy5AUhgPAz7f\n", | |
|
209 | "Hfu2XX8k8ENgx+7ovzdju/4uwP9D/peaCDxnCbANsF3gOYubLVu7sF1/AHAHcBaiHDwI/C+ywNsE\n", | |
|
210 | "4KfA68BdfVE5iNgbOBmxqtRE4Dn/BoYDnwg8Z02zBasVY0EwFKG1fkEp9RTioJjkIa11zzaVarYq\n", | |
|
211 | "vVFt2TpBaiN6oCwB5tiu/2FUPCvwnLTTaLM5oJv77800dGwCz1kXHXkvRNKydwI/Cjzn1+kKtuuf\n", | |
|
212 | "i2TX7Ks0et681yxBGsUoCIZSBBQrCL0h98EbdW7rddiuPwoYFJu/bdffFNgL2BZ4DZgWKR5ZbRWS\n", | |
|
213 | "2+KIqGiE7fpjUtXmlrtZRdaHscBAYDowM/CckimWbdffFfgw8JzXou/9kfUccojV5MXAcz4s0XYw\n", | |
|
214 | "sCsymu8PzAVmBJ7zVqn9pdoPRVKF7wSsAN4EgqzRve36HcAoZDEqgO0zjs3rged8kGo3gOJ05ADT\n", | |
|
215 | "s0bTkan+k9HXGaVGjNFxykVf81nH2Hb9Ich/MRJJeT291H9fL7brj6CwANfPspQDgOi3rijRx/rI\n", | |
|
216 | "b8kB7wPPBZ4zL6Ne/JvfCDzn/WhufhvgvsBzVkR1dgN2AR4JPGduom38P7wXeM7c6FzfCfgU4iMR\n", | |
|
217 | "lFLebNfPIefXzMBzikz8tusPQyx676bljmTeCfhyVLST7frp//TV9Dluu/6GwOhUvTWB58zIkjFq\n", | |
|
218 | "sykyNfmfwHMW2K7fLzoWeyDTFPnAc14t1T7qYwNgT+Rc/wi5ZyT/N20UBEMRSqn+wNdTxQspTqTU\n", | |
|
219 | "41BaP6yVOipzGzzSYnG6m6uBz0YPv7OQm3dytc35tuuflHZutF3/BuArwEaJ4p/QNdU2wGnAH9M7\n", | |
|
220 | "jRSTG5CbS5LQdv2joymTLKYBzwHjbNc/DomW2TCxfbXt+sMCz3k/sa8RwM+Qh/X6qf5W2q4/CTit\n", | |
|
221 | "zMN1OPB7CopQktW2658YeM5fEvXvRKZzBiXqZaWUPha4JlW2NfB8Rt0hiANfmjWIuf5jiLPfvVm/\n", | |
|
222 | "AfmvbgNmB54zKrkheuD+Bjg11Wap7fpnBJ5TybelFk4E+iE+Fb+ptbHt+scg//nGqfJbgeMDz1mY\n", | |
|
223 | "KN4UOZYX2q7fSWHhuNdt198ZOBc4MypbbLv+5wPPeTb6PiJqe5ft+ichx3WXRN8rbdc/OfCcrGis\n", | |
|
224 | "R4ChiHKSlSn2f4BzkOvitMRvCKJ9DEzU9TPafwGZlkkyBvExSrKUrtdnmoOBycA5tus/iCyat3li\n", | |
|
225 | "u7Zd/0rk2ihS1mzXPwT4E3LulaLTKAiGLL6EaMlJbtBat91pphIjFw289t9DVh4N7Jva9EKnWnpJ\n", | |
|
226 | "G0RqBXcjCa08YCqy/PJE4L8A33b9HQPPeTNR/0bgvujzGchoywPSq5U+nd6R7fp7IDfRjYDrEE99\n", | |
|
227 | "DeyHrPb5lO364xI36zTb2q4/AUnt/SSyLHQHMvJZklQOIhYChyCLid2FWBoGIQrDfwGnAP8Gskzd\n", | |
|
228 | "VvSbBgPvIMdpJjLHuxdikXgg1ewa4Jbo84+BHRAFI/3gT9/QQZa+/iIy9zwccVQrSeA5nbbrX4s8\n", | |
|
229 | "cI6htIIQK7xdFJLIAvEEYjmYBlyP/E4LeXj92Xb94YHnnFtOjhrYJ3q/vtbpE9v1fwqcjYxUL0GO\n", | |
|
230 | "51bI//g1YIzt+mNTSgJIivfNEIXgBOThfx0ySv8Nct7vgzgfj0+1HQf8E5iPKM/vI+vLHA9cZbs+\n", | |
|
231 | "JZSEevgDBZ++3yIKzgVI1FeSrCnD6ci0zebAJxCfjmoZjxzXPPBL5By0gW8jCt3sqHwtkYL1N0RB\n", | |
|
232 | "/R2ymOG2yHE5CLFAHAu8ahQEQxbfyijrDdML3HTTkWvUBRfsb88bPb6TzjEK+oHKL184YHL+Jmdl\n", | |
|
233 | "u+XrJsYBhwaec0dcYLu+hzw0dkcu/AvjbUmLgu36DqIgPB54zuQq9nURMgI8LjnyBibZrj8z2s/l\n", | |
|
234 | "tuvvVcJJbWvkXDoi8JzbKu0s8JxFtut/IqXgAPzOdv0/IiPnb5KhICAjpMGIEjAhPV1iu35HWsbA\n", | |
|
235 | "c25ObD8ZURAeqibENBqpTYnark8FBSHiakRBOMx2/cHpB29kSv4KooSlLRYnIcrBHcBXk7/Fdv0b\n", | |
|
236 | "gReAM23Xvz7wnJlVyFIJK3qfXUsj2/U/jiiiq4B9ktEytuv/Fhlpfx2xEnw31XxHYLfAc6bbrv8k\n", | |
|
237 | "cny/Bnwz8Jy/2q6/DTLd9F8Zu94ceXAeEHhOvM7MNbbrT0UU4vNs15+c2FY3gedcm/hNP0EUhDvL\n", | |
|
238 | "KMrJtkuIFPboWNWiIOSAO4HDE7/Dj67FSxEn21+m2pyOWDpuCDxn7fG2Xf8e4F1EIVsceE5oohgM\n", | |
|
239 | "XVBKjURuSEke11qXMhv3OPR553VO9Sb407yJZwTexO8FnnNV/qYj11XlAOCfSeUA1s4D/y36mp7f\n", | |
|
240 | "rAvb9fdGLDMzU8pBzMXIg2wsMhLKQiFhgxWVg5gM5SDm+uh9VHqD7fr7IlaNFcAJWb4UPcHLPvCc\n", | |
|
241 | "2YgVZn3gyIwq30AsQg8lQ+aiefUfR1/PzlB08sD9Udusfmsi2t+Q6GutjspnIE6L16dDaSN/irMR\n", | |
|
242 | "p8dTbddPOxK/nwgxTZr8747e30SsEkNL7PvXGQrAVYgvwggK/gK9mXMyfuON0fvWkY9Dkp2i97uT\n", | |
|
243 | "hYHnLKNgURsDxknRUMz5FJ8XP22DHIbqSc9pxsSOW8ObtJ89ovdXbNcvpQC8j4zcdiTbnAoy4q2b\n", | |
|
244 | "6Ia3CYV5/Y0zqsXOf4/WEYveaq5GQuOOQaZekhydqJNkW2BLZF2UzhL/R+xE2XAIa+A52nb9lUho\n", | |
|
245 | "Y63hd7GD5d1ZGwPPmW27/iuIUrkLXc/n9xP13rZd/yNgVezoF8n1NjAyyyKETGGl97fGdv1/IlaL\n", | |
|
246 | "3h7e+06WM2PgOQtt11+GTMcNo6vVJ1aWsyK+4nvFQjAKgiGBUmoshfnOmGe11vdl1Tf0GOaUKI9v\n", | |
|
247 | "lqrE9lqJb6b/Hb3KsU2Zba/VslPb9bdDfA0ORLz0N62iWWxVqMkc3iZuRuawP2u7/g6JKI9RSCTR\n", | |
|
248 | "YoodhOP/YgNKK2Ix2zZJzjnINMN2NbaL/4uiaIUE/0EUhB3pqiCkMwl2IscjXZZFJ/B2iW1xRtWR\n", | |
|
249 | "ZWTqDcwps63U9f8Q0TSN7fp/iK0PtuvviPjmrCHyR1qrICilNkTmHjZDLsDke/JzOtwnzY1KqXcR\n", | |
|
250 | "R4cFiBab9XlRT87I19dQSo1GNPz0tJOxHvR8mhrOVobB0XuAOBiWo1zmwaqdXW3X3x+4BzGVv4SM\n", | |
|
251 | "pN9AnPEg21McxMIArTs2dRN4zoe26/8NOA6xGJwfbYqV9b8GnrM81Sz+Lz5A0qOXo2y4Ww3MoT4F\n", | |
|
252 | "IY4+KTfNF58TaXN4VthstVNDitLKcdxvOjKmEj0tv0M953fs87E3Eul0B2JliBflOzfwnFcA+iul\n", | |
|
253 | "5iEmwQFNEBaK569L0amUWggcqrXO8gg2FKHG2CdW4Uem9XvBlUflu7RUaiByU3lPa92ZKN8cSav8\n", | |
|
254 | "fUQBTHKr1rrqueIsxp18/eg1azrLjSYB6NfRsY3G6Is9nDjDYxh4zundvbMotvtm5N50duA5P09t\n", | |
|
255 | "T0faJIkfirU+zNrF1YiC4FBQECZE73/JqB//F+u14r+ImIVEOB1iu/6ZNfhwzEamp7YuU2e7RN1m\n", | |
|
256 | "oZBnW5YVIfZ1qNWfotw51yuIph++hET0bAkcikwpTAEuCjxnSly3PzIP0a8NcnYgD6SBlSoaIhQX\n", | |
|
257 | "V2UtVup24LBU6S7IyG+NUuodZP52awojrTSvIjeshlij9XdQKh2jXYRRDtpGfOCruQfEpmzbdn0V\n", | |
|
258 | "dP9iPLsgjnEryI67Lzd/PCt6/5Tt+v3LJXAqQ/z7ut2ZO/Ccx23XfxUYZbt+7D8xCngl8Jwsa80s\n", | |
|
259 | "ZBS8ke36O7cg4ybA5UgegJ0QE/XN5auvZRaiIMQRF12wXX8TCv9ls6eERpOtIMR+EXNS5YsRh8dS\n", | |
|
260 | "To/V+CzUck21i6uR5++4wHNeKFXJRDH0PfoR5fqmtHKwDDhCa73O5JA3lCSeF04v6Z3FPRTMzBO7\n", | |
|
261 | "S6AE8Q12PbomgYn5Xpm29yMPhu2RUK96iKMn9q6zfa38JXo/NHoly7oQeM5K4Iro60+jKINuJVJC\n", | |
|
262 | "Yu/439uuX805A4VkWyfbrp+V/MdFnOmeCmpfFKsSRYMc2/U/DeyG3OfSjpOx5WmfVHmcuXFcFfus\n", | |
|
263 | "5ZpqObbrb45EtswqpxyAcVI0FDMbOFxrXeT9a+heopvnEArzolvashT0wmbEapdgGpIU5XDb9R9F\n", | |
|
264 | "YqrXQyyL8wPPeTeuGHjOMtv1T0VuqldH6W//jigNmyHOcAcBgwPPcZog20xkRLcJ8DPb9S9CRqM7\n", | |
|
265 | "I7kDvoDE1hfdxwLPWWy7/plI7oCLbNffHXm4zUQeRtsjGRP/EXhOKSfcABkpj49i5+9G/putgHmB\n", | |
|
266 | "5yxIN4iSF21C14V6Rtiu/yYSW15uHv4a4P8oKAedlPcvOAv4KmItfCTKKfAS8v8NR1ILHwnsl5GA\n", | |
|
267 | "qF7ORdYaGA48HGWyfBqYgViDRwCfQR72PkDgOU9E2TvHI4m0TgeeRczb30DyH2iKcyA0ymrgWNv1\n", | |
|
268 | "FyDK1NvIQ3tStN3LCH+9HUl29UPb9echFo8BUbtLEKfJtJ9EmgA59ifbrj8bCR3cGDlvZqdTLcPa\n", | |
|
269 | "9NCbUMhs2GFLKvPFSAKxZl7/CxEL8pgoA+QMxD+kE3HenAHcHnjOGmNB6Dt8iGjHWSFKK4HHkcQr\n", | |
|
270 | "OxvloLXYrr+77fqrEIejNyiE6P0WccZbabv+lFLtG+Ry5AY/BHkYfRDtR9M79QAAA3FJREFUcwYS\n", | |
|
271 | "NdCFwHPuQR6a7wHfAR5GMhk+i9xcT6G6KIOKBJ6zFBn9r0GUmBlIWN9ziHf/5yjO/phsfy2yqt4i\n", | |
|
272 | "xOJxF3INTI9k/Q7ZoV4xv0PC5LZCci4sQm6g08kYHdquvxy5lt4DwsSmF5EENCts1//Idv3M9LbR\n", | |
|
273 | "egJTkEx4NvBA1joFifqLIjkeR6wcfwdeQfIFTEEcjHNU79RXkShvw95Ixs5+yOj/KuSh+ATiAHcq\n", | |
|
274 | "xb4fxwOXRfJMQc6zlxGF6B3g4MBznmmWnBFzEUfP0xDFcCGiAG+JHKushESXIdanjRBF4l3EInAj\n", | |
|
275 | "8vuOqWK/5yNRGaOQFNkfIhkOX6CQgwAA2/W3jkI3V0T7ejjatAFyXb2PXP/LbVnroWGi6bbzo697\n", | |
|
276 | "IlaWk5Br93wkk+jztusP7o94Lna7eaoMZU0cVXIAped7eqGZfP2ZqmPFl+ptrVf3n19UpvVMYLRS\n", | |
|
277 | "agBywxuEjLwWAe9qrTMXV2mUzs7OP/Xrp+6qt33Hmn5Zue3XNeZTOVoky5nqKiQkrNT883Qk3WvJ\n", | |
|
278 | "sMLAc1bbrv9Z5AH6KWRkOB+5wRWlWo7a3Ga7/mOIomAho/GFyI30YeDREru7ELlOq07TG3jONbbr\n", | |
|
279 | "T0Nu9KOQm+i/gFsDz3nTdv2fI2FbpdpfHnlpH4LcnHdAlIz5yLErqXgFnvOR7fo28lDYE7lu3kKO\n", | |
|
280 | "TdZ9K52xrhTl7knnUVB6SqVeTsr4apQU6lDEbG4hCsFbROsRBE1ebjrwnNB2/XGIGf5gRBkYhPyv\n", | |
|
281 | "7yDpjR9MtVkOnGK7/vWIgrFrVPcF4O8ZKbaXIuduWkH6KfL/JbkEsWClfWK2CDzHt10/jzhXjkGO\n", | |
|
282 | "yzNIZEiRD00ga3ocaLv+kUh2xo8hSuVURKmIUyiXVGYCWVzKQlJD7xrJNg85b9LX8RLgF6X6SpFU\n", | |
|
283 | "9Cpe28gaJgORqEEAbNffDLlvHIQoAndR8NEYilwjExD/nwuUiTQ0GAwGw7qC7fqjEUvKqsBzmhWd\n", | |
|
284 | "t05gu/5pyNoifw48J9N5PForxQeeNFMMBoPBYDD0DWL/llvK1In9jt4zCoLBYDAYDH2DePo5MwrJ\n", | |
|
285 | "dv0hFPwTnjBRDAaDwWAw9A3+hPgOHRPl25iK+FhsiuR4OARx0Lwf+J1REAwGg8Fg6AMEnvNklL78\n", | |
|
286 | "HMRRca/E5hVINNIVwI2B56z6/3ExLRI31pXNAAAAAElFTkSuQmCC\n" | |
|
287 | ], | |
|
288 | "text/plain": [ | |
|
289 | "<IPython.core.display.Image at 0x111275490>" | |
|
290 | ] | |
|
291 | }, | |
|
292 | "execution_count": 6, | |
|
127 | 293 | "metadata": {}, |
|
128 | "outputs": [ | |
|
129 | { | |
|
130 | "metadata": {}, | |
|
131 | "output_type": "pyout", | |
|
132 | "png": "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\n", | |
|
133 | "prompt_number": 6, | |
|
134 | "text": [ | |
|
135 | "<IPython.core.display.Image at 0x111275490>" | |
|
136 | ] | |
|
137 | } | |
|
138 | ], | |
|
139 | "prompt_number": 6 | |
|
294 | "output_type": "execute_result" | |
|
140 | 295 | } |
|
141 | 296 | ], |
|
142 | "metadata": {} | |
|
297 | "source": [ | |
|
298 | "from IPython.display import Image\n", | |
|
299 | "Image(\"http://ipython.org/_static/IPy_header.png\")" | |
|
300 | ] | |
|
143 | 301 | } |
|
144 | ] | |
|
145 | } | |
|
302 | ], | |
|
303 | "metadata": {}, | |
|
304 | "nbformat": 4, | |
|
305 | "nbformat_minor": 0 | |
|
306 | } No newline at end of file |
@@ -1,11 +1,10 b'' | |||
|
1 | 1 | { |
|
2 | 2 | "cells": [ |
|
3 | 3 | { |
|
4 |
"cell_type": " |
|
|
5 | "level": 1, | |
|
4 | "cell_type": "markdown", | |
|
6 | 5 | "metadata": {}, |
|
7 | 6 | "source": [ |
|
8 | "nbconvert latex test" | |
|
7 | "# nbconvert latex test" | |
|
9 | 8 | ] |
|
10 | 9 | }, |
|
11 | 10 | { |
@@ -16,11 +15,10 b'' | |||
|
16 | 15 | ] |
|
17 | 16 | }, |
|
18 | 17 | { |
|
19 |
"cell_type": " |
|
|
20 | "level": 2, | |
|
18 | "cell_type": "markdown", | |
|
21 | 19 | "metadata": {}, |
|
22 | 20 | "source": [ |
|
23 | "Printed Using Python" | |
|
21 | "## Printed Using Python" | |
|
24 | 22 | ] |
|
25 | 23 | }, |
|
26 | 24 | { |
@@ -43,11 +41,10 b'' | |||
|
43 | 41 | ] |
|
44 | 42 | }, |
|
45 | 43 | { |
|
46 |
"cell_type": " |
|
|
47 | "level": 2, | |
|
44 | "cell_type": "markdown", | |
|
48 | 45 | "metadata": {}, |
|
49 | 46 | "source": [ |
|
50 | "Pyout" | |
|
47 | "## Pyout" | |
|
51 | 48 | ] |
|
52 | 49 | }, |
|
53 | 50 | { |
@@ -111,11 +108,10 b'' | |||
|
111 | 108 | ] |
|
112 | 109 | }, |
|
113 | 110 | { |
|
114 |
"cell_type": " |
|
|
115 | "level": 3, | |
|
111 | "cell_type": "markdown", | |
|
116 | 112 | "metadata": {}, |
|
117 | 113 | "source": [ |
|
118 | "Image" | |
|
114 | "### Image" | |
|
119 | 115 | ] |
|
120 | 116 | }, |
|
121 | 117 | { |
@@ -28,7 +28,7 b' class TestValidator(TestsBase):' | |||
|
28 | 28 | self.assertEqual(isvalid(nb), True) |
|
29 | 29 | |
|
30 | 30 | def test_nb4(self): |
|
31 |
"""Test that a v |
|
|
31 | """Test that a v4 notebook passes validation""" | |
|
32 | 32 | with self.fopen(u'test4.ipynb', u'r') as f: |
|
33 | 33 | nb = read(f, u'json') |
|
34 | 34 | validate(nb) |
@@ -37,9 +37,9 b' class TestValidator(TestsBase):' | |||
|
37 | 37 | def test_invalid(self): |
|
38 | 38 | """Test than an invalid notebook does not pass validation""" |
|
39 | 39 | # this notebook has a few different errors: |
|
40 | # - the name is an integer, rather than a string | |
|
41 | 40 | # - one cell is missing its source |
|
42 |
# - |
|
|
41 | # - invalid cell type | |
|
42 | # - invalid output_type | |
|
43 | 43 | with self.fopen(u'invalid.ipynb', u'r') as f: |
|
44 | 44 | nb = read(f, u'json') |
|
45 | 45 | with self.assertRaises(ValidationError): |
@@ -6,7 +6,7 b'' | |||
|
6 | 6 | from .nbbase import ( |
|
7 | 7 | NotebookNode, from_dict, |
|
8 | 8 | nbformat, nbformat_minor, nbformat_schema, |
|
9 |
new_code_cell |
|
|
9 | new_code_cell, new_markdown_cell, new_notebook, | |
|
10 | 10 | new_output, output_from_msg, |
|
11 | 11 | ) |
|
12 | 12 |
@@ -4,6 +4,7 b'' | |||
|
4 | 4 | # Distributed under the terms of the Modified BSD License. |
|
5 | 5 | |
|
6 | 6 | import json |
|
7 | import re | |
|
7 | 8 | |
|
8 | 9 | from .nbbase import ( |
|
9 | 10 | nbformat, nbformat_minor, |
@@ -72,6 +73,7 b' def upgrade(nb, from_version=3, from_minor=0):' | |||
|
72 | 73 | def upgrade_cell(cell): |
|
73 | 74 | """upgrade a cell from v3 to v4 |
|
74 | 75 | |
|
76 | heading cell -> markdown heading | |
|
75 | 77 | code cell: |
|
76 | 78 | - remove language metadata |
|
77 | 79 | - cell.input -> cell.source |
@@ -82,9 +84,16 b' def upgrade_cell(cell):' | |||
|
82 | 84 | if cell.cell_type == 'code': |
|
83 | 85 | cell.pop('language', '') |
|
84 | 86 | cell.metadata.collapsed = cell.pop('collapsed') |
|
85 | cell.source = cell.pop('input') | |
|
87 | cell.source = cell.pop('input', '') | |
|
86 | 88 | cell.execution_count = cell.pop('prompt_number', None) |
|
87 | 89 | cell.outputs = upgrade_outputs(cell.outputs) |
|
90 | elif cell.cell_type == 'heading': | |
|
91 | cell.cell_type = 'markdown' | |
|
92 | level = cell.pop('level', 1) | |
|
93 | cell.source = '{hashes} {single_line}'.format( | |
|
94 | hashes='#' * level, | |
|
95 | single_line = ' '.join(cell.get('source', '').splitlines()), | |
|
96 | ) | |
|
88 | 97 | elif cell.cell_type == 'html': |
|
89 | 98 | # Technically, this exists. It will never happen in practice. |
|
90 | 99 | cell.cell_type = 'markdown' |
@@ -98,6 +107,8 b' def downgrade_cell(cell):' | |||
|
98 | 107 | - cell.input <- cell.source |
|
99 | 108 | - cell.prompt_number <- cell.execution_count |
|
100 | 109 | - update outputs |
|
110 | markdown cell: | |
|
111 | - single-line heading -> heading cell | |
|
101 | 112 | """ |
|
102 | 113 | if cell.cell_type == 'code': |
|
103 | 114 | cell.language = 'python' |
@@ -105,6 +116,13 b' def downgrade_cell(cell):' | |||
|
105 | 116 | cell.prompt_number = cell.pop('execution_count', None) |
|
106 | 117 | cell.collapsed = cell.metadata.pop('collapsed', False) |
|
107 | 118 | cell.outputs = downgrade_outputs(cell.outputs) |
|
119 | elif cell.cell_type == 'markdown': | |
|
120 | source = cell.get('source', '') | |
|
121 | if '\n' not in source and source.startswith('#'): | |
|
122 | prefix, text = re.match(r'(#+)\s*(.*)', source).groups() | |
|
123 | cell.cell_type = 'heading' | |
|
124 | cell.source = text | |
|
125 | cell.level = len(prefix) | |
|
108 | 126 | return cell |
|
109 | 127 | |
|
110 | 128 | _mime_map = { |
@@ -121,16 +121,6 b" def new_markdown_cell(source='', **kwargs):" | |||
|
121 | 121 | validate(cell, 'markdown_cell') |
|
122 | 122 | return cell |
|
123 | 123 | |
|
124 | def new_heading_cell(source='', **kwargs): | |
|
125 | """Create a new heading cell""" | |
|
126 | cell = NotebookNode(cell_type='heading', source=source) | |
|
127 | cell.update(from_dict(kwargs)) | |
|
128 | cell.setdefault('metadata', NotebookNode()) | |
|
129 | cell.setdefault('level', 1) | |
|
130 | ||
|
131 | validate(cell, 'heading_cell') | |
|
132 | return cell | |
|
133 | ||
|
134 | 124 | def new_raw_cell(source='', **kwargs): |
|
135 | 125 | """Create a new raw cell""" |
|
136 | 126 | cell = NotebookNode(cell_type='raw', source=source) |
@@ -59,7 +59,6 b'' | |||
|
59 | 59 | "oneOf": [ |
|
60 | 60 | {"$ref": "#/definitions/raw_cell"}, |
|
61 | 61 | {"$ref": "#/definitions/markdown_cell"}, |
|
62 | {"$ref": "#/definitions/heading_cell"}, | |
|
63 | 62 | {"$ref": "#/definitions/code_cell"} |
|
64 | 63 | ] |
|
65 | 64 | } |
@@ -118,34 +117,6 b'' | |||
|
118 | 117 | } |
|
119 | 118 | }, |
|
120 | 119 | |
|
121 | "heading_cell": { | |
|
122 | "description": "Notebook heading cell.", | |
|
123 | "type": "object", | |
|
124 | "additionalProperties": false, | |
|
125 | "required": ["cell_type", "metadata", "source", "level"], | |
|
126 | "properties": { | |
|
127 | "cell_type": { | |
|
128 | "description": "String identifying the type of cell.", | |
|
129 | "enum": ["heading"] | |
|
130 | }, | |
|
131 | "metadata": { | |
|
132 | "description": "Cell-level metadata.", | |
|
133 | "type": "object", | |
|
134 | "properties": { | |
|
135 | "name": {"$ref": "#/definitions/misc/metadata_name"}, | |
|
136 | "tags": {"$ref": "#/definitions/misc/metadata_tags"} | |
|
137 | }, | |
|
138 | "additionalProperties": true | |
|
139 | }, | |
|
140 | "source": {"$ref": "#/definitions/misc/source"}, | |
|
141 | "level": { | |
|
142 | "description": "Level of heading cells.", | |
|
143 | "type": "integer", | |
|
144 | "minimum": 1 | |
|
145 | } | |
|
146 | } | |
|
147 | }, | |
|
148 | ||
|
149 | 120 | "code_cell": { |
|
150 | 121 | "description": "Notebook code cell.", |
|
151 | 122 | "type": "object", |
@@ -44,14 +44,15 b' def rejoin_lines(nb):' | |||
|
44 | 44 | for cell in nb.cells: |
|
45 | 45 | if 'source' in cell and isinstance(cell.source, list): |
|
46 | 46 | cell.source = _join_lines(cell.source) |
|
47 | if cell.cell_type == 'code': | |
|
48 | for output in cell.outputs: | |
|
49 | if output.output_type in {'execute_result', 'display_data'}: | |
|
50 | for key, value in output.data.items(): | |
|
47 | if cell.get('cell_type', None) == 'code': | |
|
48 | for output in cell.get('outputs', []): | |
|
49 | output_type = output.get('output_type', '') | |
|
50 | if output_type in {'execute_result', 'display_data'}: | |
|
51 | for key, value in output.get('data', {}).items(): | |
|
51 | 52 | if key != 'application/json' and isinstance(value, list): |
|
52 | 53 | output.data[key] = _join_lines(value) |
|
53 |
elif |
|
|
54 | if isinstance(output.text, list): | |
|
54 | elif output_type: | |
|
55 | if isinstance(output.get('text', ''), list): | |
|
55 | 56 | output.text = _join_lines(output.text) |
|
56 | 57 | return nb |
|
57 | 58 |
@@ -4,7 +4,7 b' import os' | |||
|
4 | 4 | from base64 import encodestring |
|
5 | 5 | |
|
6 | 6 | from ..nbbase import ( |
|
7 |
new_code_cell |
|
|
7 | new_code_cell, new_markdown_cell, new_notebook, | |
|
8 | 8 | new_output, new_raw_cell |
|
9 | 9 | ) |
|
10 | 10 | |
@@ -31,9 +31,8 b' cells.append(new_raw_cell(' | |||
|
31 | 31 | source='A random array', |
|
32 | 32 | )) |
|
33 | 33 | |
|
34 |
cells.append(new_ |
|
|
35 | source=u'My Heading', | |
|
36 | level=2, | |
|
34 | cells.append(new_markdown_cell( | |
|
35 | source=u'## My Heading', | |
|
37 | 36 | )) |
|
38 | 37 | |
|
39 | 38 | cells.append(new_code_cell( |
@@ -1,10 +1,13 b'' | |||
|
1 | 1 | import copy |
|
2 | 2 | |
|
3 | import nose.tools as nt | |
|
4 | ||
|
3 | 5 | from IPython.nbformat.current import validate |
|
4 | 6 | from .. import convert |
|
5 | 7 | |
|
6 | 8 | from . import nbexamples |
|
7 | 9 | from IPython.nbformat.v3.tests import nbexamples as v3examples |
|
10 | from IPython.nbformat import v3, v4 | |
|
8 | 11 | |
|
9 | 12 | def test_upgrade_notebook(): |
|
10 | 13 | nb03 = copy.deepcopy(v3examples.nb0) |
@@ -17,3 +20,48 b' def test_downgrade_notebook():' | |||
|
17 | 20 | validate(nb04) |
|
18 | 21 | nb03 = convert.downgrade(nb04) |
|
19 | 22 | validate(nb03) |
|
23 | ||
|
24 | def test_upgrade_heading(): | |
|
25 | v3h = v3.new_heading_cell | |
|
26 | v4m = v4.new_markdown_cell | |
|
27 | for v3cell, expected in [ | |
|
28 | ( | |
|
29 | v3h(source='foo', level=1), | |
|
30 | v4m(source='# foo'), | |
|
31 | ), | |
|
32 | ( | |
|
33 | v3h(source='foo\nbar\nmulti-line\n', level=4), | |
|
34 | v4m(source='#### foo bar multi-line'), | |
|
35 | ), | |
|
36 | ]: | |
|
37 | upgraded = convert.upgrade_cell(v3cell) | |
|
38 | nt.assert_equal(upgraded, expected) | |
|
39 | ||
|
40 | def test_downgrade_heading(): | |
|
41 | v3h = v3.new_heading_cell | |
|
42 | v4m = v4.new_markdown_cell | |
|
43 | v3m = lambda source: v3.new_text_cell('markdown', source) | |
|
44 | for v4cell, expected in [ | |
|
45 | ( | |
|
46 | v4m(source='# foo'), | |
|
47 | v3h(source='foo', level=1), | |
|
48 | ), | |
|
49 | ( | |
|
50 | v4m(source='#foo'), | |
|
51 | v3h(source='foo', level=1), | |
|
52 | ), | |
|
53 | ( | |
|
54 | v4m(source='#\tfoo'), | |
|
55 | v3h(source='foo', level=1), | |
|
56 | ), | |
|
57 | ( | |
|
58 | v4m(source='# \t foo'), | |
|
59 | v3h(source='foo', level=1), | |
|
60 | ), | |
|
61 | ( | |
|
62 | v4m(source='# foo\nbar'), | |
|
63 | v3m(source='# foo\nbar'), | |
|
64 | ), | |
|
65 | ]: | |
|
66 | downgraded = convert.downgrade_cell(v4cell) | |
|
67 | nt.assert_equal(downgraded, expected) |
@@ -6,7 +6,7 b' import nose.tools as nt' | |||
|
6 | 6 | from IPython.nbformat.validator import isvalid, validate, ValidationError |
|
7 | 7 | from ..nbbase import ( |
|
8 | 8 | NotebookNode, nbformat, |
|
9 |
new_code_cell |
|
|
9 | new_code_cell, new_markdown_cell, new_notebook, | |
|
10 | 10 | new_output, new_raw_cell, |
|
11 | 11 | ) |
|
12 | 12 | |
@@ -34,17 +34,6 b' def test_raw_cell():' | |||
|
34 | 34 | cell = new_raw_cell('hi') |
|
35 | 35 | nt.assert_equal(cell.source, u'hi') |
|
36 | 36 | |
|
37 | def test_empty_heading_cell(): | |
|
38 | cell = new_heading_cell() | |
|
39 | nt.assert_equal(cell.cell_type, u'heading') | |
|
40 | nt.assert_equal(cell.source, '') | |
|
41 | nt.assert_equal(cell.level, 1) | |
|
42 | ||
|
43 | def test_heading_cell(): | |
|
44 | cell = new_heading_cell(u'hi', level=2) | |
|
45 | nt.assert_equal(cell.source, u'hi') | |
|
46 | nt.assert_equal(cell.level, 2) | |
|
47 | ||
|
48 | 37 | def test_empty_code_cell(): |
|
49 | 38 | cell = new_code_cell('hi') |
|
50 | 39 | nt.assert_equal(cell.cell_type, 'code') |
@@ -12,7 +12,7 b' from IPython.nbformat.validator import validate, ValidationError' | |||
|
12 | 12 | from ..nbjson import reads |
|
13 | 13 | from ..nbbase import ( |
|
14 | 14 | nbformat, |
|
15 |
new_code_cell |
|
|
15 | new_code_cell, new_markdown_cell, new_notebook, | |
|
16 | 16 | new_output, new_raw_cell, |
|
17 | 17 | ) |
|
18 | 18 | |
@@ -73,31 +73,6 b' def test_invalid_markdown_cell():' | |||
|
73 | 73 | with nt.assert_raises(ValidationError): |
|
74 | 74 | validate4(cell, 'markdown_cell') |
|
75 | 75 | |
|
76 | def test_invalid_heading_cell(): | |
|
77 | cell = new_heading_cell() | |
|
78 | ||
|
79 | cell['source'] = 5 | |
|
80 | with nt.assert_raises(ValidationError): | |
|
81 | validate4(cell, 'heading_cell') | |
|
82 | ||
|
83 | cell = new_heading_cell() | |
|
84 | del cell['metadata'] | |
|
85 | ||
|
86 | with nt.assert_raises(ValidationError): | |
|
87 | validate4(cell, 'heading_cell') | |
|
88 | ||
|
89 | cell = new_heading_cell() | |
|
90 | del cell['source'] | |
|
91 | ||
|
92 | with nt.assert_raises(ValidationError): | |
|
93 | validate4(cell, 'heading_cell') | |
|
94 | ||
|
95 | cell = new_heading_cell() | |
|
96 | del cell['cell_type'] | |
|
97 | ||
|
98 | with nt.assert_raises(ValidationError): | |
|
99 | validate4(cell, 'heading_cell') | |
|
100 | ||
|
101 | 76 | def test_invalid_raw_cell(): |
|
102 | 77 | cell = new_raw_cell() |
|
103 | 78 |
@@ -82,24 +82,9 b' as defined in `GitHub-flavored markdown`_, and implemented in marked_.' | |||
|
82 | 82 | "source" : ["some *markdown*"], |
|
83 | 83 | } |
|
84 | 84 | |
|
85 | .. versionchanged:: 4.0 | |
|
85 | 86 | |
|
86 | Heading cells | |
|
87 | ------------- | |
|
88 | ||
|
89 | Heading cells are single lines describing a section header (mapping onto h1-h6 tags in HTML). | |
|
90 | These cells indicate structure of the document, | |
|
91 | and are used for things like outline-views and automatically generating HTML anchors | |
|
92 | within the page for quick navigation. | |
|
93 | They have a ``level`` field, with an integer value from 1-6 (inclusive). | |
|
94 | ||
|
95 | .. sourcecode:: python | |
|
96 | ||
|
97 | { | |
|
98 | "cell_type" : "markdown", | |
|
99 | "metadata" : {}, | |
|
100 | "level" : 1, # An integer on [1-6] | |
|
101 | "source" : ["A simple heading"], | |
|
102 | } | |
|
87 | Heading cells have been removed, in favor of simple headings in markdown. | |
|
103 | 88 | |
|
104 | 89 | |
|
105 | 90 | Code cells |
General Comments 0
You need to be logged in to leave comments.
Login now