Show More
@@ -11,7 +11,7 b' import requests' | |||||
11 | from IPython.html.utils import url_path_join |
|
11 | from IPython.html.utils import url_path_join | |
12 | from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error |
|
12 | from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error | |
13 | from IPython.nbformat.current import (new_notebook, write, |
|
13 | from IPython.nbformat.current import (new_notebook, write, | |
14 |
new_ |
|
14 | new_markdown_cell, new_code_cell, | |
15 | new_output) |
|
15 | new_output) | |
16 |
|
16 | |||
17 | from IPython.testing.decorators import onlyif_cmds_exist |
|
17 | from IPython.testing.decorators import onlyif_cmds_exist | |
@@ -55,7 +55,7 b' class APITest(NotebookTestBase):' | |||||
55 |
|
55 | |||
56 | nb = new_notebook() |
|
56 | nb = new_notebook() | |
57 |
|
57 | |||
58 |
nb.cells.append(new_ |
|
58 | nb.cells.append(new_markdown_cell(u'Created by test Β³')) | |
59 | cc1 = new_code_cell(source=u'print(2*6)') |
|
59 | cc1 = new_code_cell(source=u'print(2*6)') | |
60 | cc1.outputs.append(new_output(output_type="stream", text=u'12')) |
|
60 | cc1.outputs.append(new_output(output_type="stream", text=u'12')) | |
61 | cc1.outputs.append(new_output(output_type="execute_result", |
|
61 | cc1.outputs.append(new_output(output_type="execute_result", |
@@ -255,7 +255,7 b' class FileContentsManager(ContentsManager):' | |||||
255 | try: |
|
255 | try: | |
256 | nb = current.read(f, u'json') |
|
256 | nb = current.read(f, u'json') | |
257 | except Exception as e: |
|
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 | self.mark_trusted_cells(nb, name, path) |
|
259 | self.mark_trusted_cells(nb, name, path) | |
260 | model['content'] = nb |
|
260 | model['content'] = nb | |
261 | model['format'] = 'json' |
|
261 | model['format'] = 'json' |
@@ -16,7 +16,7 b' from IPython.html.utils import url_path_join, url_escape' | |||||
16 | from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error |
|
16 | from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error | |
17 | from IPython.nbformat import current |
|
17 | from IPython.nbformat import current | |
18 | from IPython.nbformat.current import (new_notebook, write, read, |
|
18 | from IPython.nbformat.current import (new_notebook, write, read, | |
19 |
new_ |
|
19 | new_markdown_cell, to_notebook_json) | |
20 | from IPython.nbformat import v2 |
|
20 | from IPython.nbformat import v2 | |
21 | from IPython.utils import py3compat |
|
21 | from IPython.utils import py3compat | |
22 | from IPython.utils.data import uniq_stable |
|
22 | from IPython.utils.data import uniq_stable | |
@@ -415,7 +415,7 b' class APITest(NotebookTestBase):' | |||||
415 | resp = self.api.read('a.ipynb', 'foo') |
|
415 | resp = self.api.read('a.ipynb', 'foo') | |
416 | nbcontent = json.loads(resp.text)['content'] |
|
416 | nbcontent = json.loads(resp.text)['content'] | |
417 | nb = to_notebook_json(nbcontent) |
|
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 | nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'} |
|
420 | nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'} | |
421 | resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) |
|
421 | resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) | |
@@ -452,7 +452,7 b' class APITest(NotebookTestBase):' | |||||
452 | # Modify it |
|
452 | # Modify it | |
453 | nbcontent = json.loads(resp.text)['content'] |
|
453 | nbcontent = json.loads(resp.text)['content'] | |
454 | nb = to_notebook_json(nbcontent) |
|
454 | nb = to_notebook_json(nbcontent) | |
455 |
hcell = new_ |
|
455 | hcell = new_markdown_cell('Created by test') | |
456 | nb.cells.append(hcell) |
|
456 | nb.cells.append(hcell) | |
457 | # Save |
|
457 | # Save | |
458 | nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'} |
|
458 | nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'} |
@@ -139,12 +139,6 b' define([' | |||||
139 | .append($('<option/>').attr('value','code').text('Code')) |
|
139 | .append($('<option/>').attr('value','code').text('Code')) | |
140 | .append($('<option/>').attr('value','markdown').text('Markdown')) |
|
140 | .append($('<option/>').attr('value','markdown').text('Markdown')) | |
141 | .append($('<option/>').attr('value','raw').text('Raw NBConvert')) |
|
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 | this.element.find('#cell_type').change(function () { |
|
185 | this.element.find('#cell_type').change(function () { | |
192 | var cell_type = $(this).val(); |
|
186 | var cell_type = $(this).val(); | |
193 |
|
|
187 | switch (cell_type) { | |
|
188 | case 'code': | |||
194 | that.notebook.to_code(); |
|
189 | that.notebook.to_code(); | |
195 | } else if (cell_type === 'markdown') { |
|
190 | break; | |
|
191 | case 'markdown': | |||
196 | that.notebook.to_markdown(); |
|
192 | that.notebook.to_markdown(); | |
197 | } else if (cell_type === 'raw') { |
|
193 | break; | |
|
194 | case 'raw': | |||
198 | that.notebook.to_raw(); |
|
195 | that.notebook.to_raw(); | |
199 | } else if (cell_type === 'heading1') { |
|
196 | break; | |
200 | that.notebook.to_heading(undefined, 1); |
|
197 | default: | |
201 | } else if (cell_type === 'heading2') { |
|
198 | console.log("unrecognized cell type:", cell_type); | |
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); |
|
|||
211 | } |
|
199 | } | |
212 | }); |
|
200 | }); | |
213 | this.events.on('selected_cell_type_changed.Notebook', function (event, data) { |
|
201 | this.events.on('selected_cell_type_changed.Notebook', function (event, data) { |
@@ -824,7 +824,7 b' define([' | |||||
824 | * Index will be brought back into the accessible range [0,n] |
|
824 | * Index will be brought back into the accessible range [0,n] | |
825 | * |
|
825 | * | |
826 | * @method insert_cell_at_index |
|
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 | * @param [index] {int} a valid index where to insert cell |
|
828 | * @param [index] {int} a valid index where to insert cell | |
829 | * |
|
829 | * | |
830 | * @return cell {cell|null} created cell or null |
|
830 | * @return cell {cell|null} created cell or null | |
@@ -860,15 +860,19 b' define([' | |||||
860 | notebook: this, |
|
860 | notebook: this, | |
861 | tooltip: this.tooltip, |
|
861 | tooltip: this.tooltip, | |
862 | }; |
|
862 | }; | |
863 |
|
|
863 | switch(type) { | |
|
864 | case 'code': | |||
864 | cell = new codecell.CodeCell(this.kernel, cell_options); |
|
865 | cell = new codecell.CodeCell(this.kernel, cell_options); | |
865 | cell.set_input_prompt(); |
|
866 | cell.set_input_prompt(); | |
866 | } else if (type === 'markdown') { |
|
867 | break; | |
|
868 | case 'markdown': | |||
867 | cell = new textcell.MarkdownCell(cell_options); |
|
869 | cell = new textcell.MarkdownCell(cell_options); | |
868 | } else if (type === 'raw') { |
|
870 | break; | |
|
871 | case 'raw': | |||
869 | cell = new textcell.RawCell(cell_options); |
|
872 | cell = new textcell.RawCell(cell_options); | |
870 | } else if (type === 'heading') { |
|
873 | break; | |
871 | cell = new textcell.HeadingCell(cell_options); |
|
874 | default: | |
|
875 | console.log("invalid cell type: ", type); | |||
872 | } |
|
876 | } | |
873 |
|
877 | |||
874 | if(this._insert_element_at_index(cell.element,index)) { |
|
878 | if(this._insert_element_at_index(cell.element,index)) { | |
@@ -1090,10 +1094,10 b' define([' | |||||
1090 | if (this.is_valid_cell_index(i)) { |
|
1094 | if (this.is_valid_cell_index(i)) { | |
1091 | var source_cell = this.get_cell(i); |
|
1095 | var source_cell = this.get_cell(i); | |
1092 | var target_cell = null; |
|
1096 | var target_cell = null; | |
1093 |
if (source_cell instanceof textcell. |
|
1097 | if (source_cell instanceof textcell.MarkdownCell) { | |
1094 | source_cell.set_level(level); |
|
1098 | source_cell.set_heading_level(level); | |
1095 | } else { |
|
1099 | } else { | |
1096 |
target_cell = this.insert_cell_below(' |
|
1100 | target_cell = this.insert_cell_below('markdown',i); | |
1097 | var text = source_cell.get_text(); |
|
1101 | var text = source_cell.get_text(); | |
1098 | if (text === source_cell.placeholder) { |
|
1102 | if (text === source_cell.placeholder) { | |
1099 | text = ''; |
|
1103 | text = ''; | |
@@ -1101,9 +1105,9 b' define([' | |||||
1101 | //metadata |
|
1105 | //metadata | |
1102 | target_cell.metadata = source_cell.metadata; |
|
1106 | target_cell.metadata = source_cell.metadata; | |
1103 | // We must show the editor before setting its contents |
|
1107 | // We must show the editor before setting its contents | |
1104 | target_cell.set_level(level); |
|
|||
1105 | target_cell.unrender(); |
|
1108 | target_cell.unrender(); | |
1106 | target_cell.set_text(text); |
|
1109 | target_cell.set_text(text); | |
|
1110 | target_cell.set_heading_level(level); | |||
1107 | // make this value the starting point, so that we can only undo |
|
1111 | // make this value the starting point, so that we can only undo | |
1108 | // to this state, instead of a blank cell |
|
1112 | // to this state, instead of a blank cell | |
1109 | target_cell.code_mirror.clearHistory(); |
|
1113 | target_cell.code_mirror.clearHistory(); | |
@@ -1117,7 +1121,7 b' define([' | |||||
1117 | } |
|
1121 | } | |
1118 | this.set_dirty(true); |
|
1122 | this.set_dirty(true); | |
1119 | this.events.trigger('selected_cell_type_changed.Notebook', |
|
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 | this.codemirror_mode = newmode; |
|
1531 | this.codemirror_mode = newmode; | |
1528 | codecell.CodeCell.options_default.cm_config.mode = newmode; |
|
1532 | codecell.CodeCell.options_default.cm_config.mode = newmode; | |
1529 | modename = newmode.mode || newmode.name || newmode |
|
1533 | modename = newmode.mode || newmode.name || newmode; | |
1530 |
|
1534 | |||
1531 | that = this; |
|
1535 | that = this; | |
1532 | utils.requireCodeMirrorMode(modename, function () { |
|
1536 | utils.requireCodeMirrorMode(modename, function () { | |
1533 | $.map(that.get_cells(), function(cell, i) { |
|
1537 | $.map(that.get_cells(), function(cell, i) { | |
@@ -1539,7 +1543,7 b' define([' | |||||
1539 | cell.cm_config.mode = newmode; |
|
1543 | cell.cm_config.mode = newmode; | |
1540 | } |
|
1544 | } | |
1541 | }); |
|
1545 | }); | |
1542 | }) |
|
1546 | }); | |
1543 | }; |
|
1547 | }; | |
1544 |
|
1548 | |||
1545 | // Session related things |
|
1549 | // Session related things | |
@@ -2383,13 +2387,13 b' define([' | |||||
2383 | Notebook.prototype.load_notebook_error = function (xhr, status, error) { |
|
2387 | Notebook.prototype.load_notebook_error = function (xhr, status, error) { | |
2384 | this.events.trigger('notebook_load_failed.Notebook', [xhr, status, error]); |
|
2388 | this.events.trigger('notebook_load_failed.Notebook', [xhr, status, error]); | |
2385 | utils.log_ajax_error(xhr, status, error); |
|
2389 | utils.log_ajax_error(xhr, status, error); | |
2386 | var msg; |
|
2390 | var msg = $("<div>"); | |
2387 | if (xhr.status === 400) { |
|
2391 | if (xhr.status === 400) { | |
2388 |
msg |
|
2392 | msg.text(utils.ajax_error_msg(xhr)); | |
2389 | } else if (xhr.status === 500) { |
|
2393 | } else if (xhr.status === 500) { | |
2390 |
msg |
|
2394 | msg.text("An unknown error occurred while loading this notebook. " + | |
2391 | "This version can load notebook formats " + |
|
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 | dialog.modal({ |
|
2398 | dialog.modal({ | |
2395 | notebook: this, |
|
2399 | notebook: this, |
@@ -222,6 +222,26 b' define([' | |||||
222 |
|
222 | |||
223 | MarkdownCell.prototype = Object.create(TextCell.prototype); |
|
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 | * @method render |
|
246 | * @method render | |
227 | */ |
|
247 | */ | |
@@ -238,6 +258,19 b' define([' | |||||
238 | html = mathjaxutils.replace_math(html, math); |
|
258 | html = mathjaxutils.replace_math(html, math); | |
239 | html = security.sanitize_html(html); |
|
259 | html = security.sanitize_html(html); | |
240 | html = $($.parseHTML(html)); |
|
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 | // links in markdown cells should open in new tabs |
|
274 | // links in markdown cells should open in new tabs | |
242 | html.find("a[href]").not('[href^="#"]').attr("target", "_blank"); |
|
275 | html.find("a[href]").not('[href^="#"]').attr("target", "_blank"); | |
243 | this.set_rendered(html); |
|
276 | this.set_rendered(html); | |
@@ -305,121 +338,15 b' define([' | |||||
305 | return cont; |
|
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 | // Backwards compatability. |
|
341 | // Backwards compatability. | |
413 | IPython.TextCell = TextCell; |
|
342 | IPython.TextCell = TextCell; | |
414 | IPython.MarkdownCell = MarkdownCell; |
|
343 | IPython.MarkdownCell = MarkdownCell; | |
415 | IPython.RawCell = RawCell; |
|
344 | IPython.RawCell = RawCell; | |
416 | IPython.HeadingCell = HeadingCell; |
|
|||
417 |
|
345 | |||
418 | var textcell = { |
|
346 | var textcell = { | |
419 |
|
|
347 | TextCell: TextCell, | |
420 |
|
|
348 | MarkdownCell: MarkdownCell, | |
421 |
|
|
349 | RawCell: RawCell, | |
422 | 'HeadingCell': HeadingCell, |
|
|||
423 | }; |
|
350 | }; | |
424 | return textcell; |
|
351 | return textcell; | |
425 | }); |
|
352 | }); |
@@ -189,12 +189,6 b' class="notebook_app"' | |||||
189 | <li id="to_raw" |
|
189 | <li id="to_raw" | |
190 | title="Contents will pass through nbconvert unmodified"> |
|
190 | title="Contents will pass through nbconvert unmodified"> | |
191 | <a href="#">Raw NBConvert</a></li> |
|
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 | </ul> |
|
192 | </ul> | |
199 | </li> |
|
193 | </li> | |
200 | <li class="divider"></li> |
|
194 | <li class="divider"></li> |
@@ -52,12 +52,12 b' casper.notebook_test(function () {' | |||||
52 |
|
52 | |||
53 | this.then(function () { |
|
53 | this.then(function () { | |
54 | this.select_cell(2); |
|
54 | this.select_cell(2); | |
55 |
this.trigger_keydown(' |
|
55 | this.trigger_keydown('y'); // switch it to code for the next test | |
56 |
this.test.assertEquals(this.get_cell(2).cell_type, ' |
|
56 | this.test.assertEquals(this.get_cell(2).cell_type, 'code', 'test cell is code'); | |
57 | this.trigger_keydown('b'); // new cell below |
|
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 | this.trigger_keydown('a'); // new cell above |
|
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 | this.thenEvaluate(function() { |
|
63 | this.thenEvaluate(function() { |
@@ -4,25 +4,38 b'' | |||||
4 | casper.notebook_test(function () { |
|
4 | casper.notebook_test(function () { | |
5 | this.then(function () { |
|
5 | this.then(function () { | |
6 | // Cell mode change |
|
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 | this.trigger_keydown('esc','r'); |
|
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 | this.trigger_keydown('1'); |
|
13 | this.trigger_keydown('1'); | |
11 |
this.test.assertEquals(this.get_cell( |
|
14 | this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '1; cell is markdown'); | |
12 |
this.test.assertEquals(this.get_cell( |
|
15 | this.test.assertEquals(this.get_cell_text(index), '# ' + a, '1; markdown heading'); | |
13 | this.trigger_keydown('2'); |
|
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 | this.trigger_keydown('3'); |
|
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 | this.trigger_keydown('4'); |
|
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 | this.trigger_keydown('5'); |
|
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 | this.trigger_keydown('6'); |
|
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 | this.trigger_keydown('m'); |
|
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 | this.trigger_keydown('y'); |
|
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 | }); No newline at end of file |
|
41 | }); |
@@ -10,38 +10,53 b' casper.notebook_test(function () {' | |||||
10 | cell.render(); |
|
10 | cell.render(); | |
11 | return cell.get_rendered(); |
|
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 | // Test menubar entries. |
|
15 | // Test menubar entries. | |
16 | output = this.evaluate(function () { |
|
16 | output = this.evaluate(function () { | |
17 | $('#to_code').mouseenter().click(); |
|
17 | $('#to_code').mouseenter().click(); | |
18 | $('#to_markdown').mouseenter().click(); |
|
18 | $('#to_markdown').mouseenter().click(); | |
19 | var cell = IPython.notebook.get_selected_cell(); |
|
19 | var cell = IPython.notebook.get_selected_cell(); | |
20 |
cell.set_text(' |
|
20 | cell.set_text('**Bar**'); | |
21 | $('#run_cell').mouseenter().click(); |
|
21 | $('#run_cell').mouseenter().click(); | |
22 | return cell.get_rendered(); |
|
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 | // Test toolbar buttons. |
|
26 | // Test toolbar buttons. | |
27 | output = this.evaluate(function () { |
|
27 | output = this.evaluate(function () { | |
28 | $('#cell_type').val('code').change(); |
|
28 | $('#cell_type').val('code').change(); | |
29 | $('#cell_type').val('markdown').change(); |
|
29 | $('#cell_type').val('markdown').change(); | |
30 | var cell = IPython.notebook.get_selected_cell(); |
|
30 | var cell = IPython.notebook.get_selected_cell(); | |
31 |
cell.set_text(' |
|
31 | cell.set_text('*Baz*'); | |
32 | $('#run_b').click(); |
|
32 | $('#run_b').click(); | |
33 | return cell.get_rendered(); |
|
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. |
|
37 | // Test markdown headings | |
38 | var output = this.evaluate(function () { |
|
|||
39 |
|
38 | |||
|
39 | var text = 'multi\nline'; | |||
|
40 | ||||
|
41 | this.evaluate(function (text) { | |||
40 | var cell = IPython.notebook.insert_cell_at_index('markdown', 0); |
|
42 | var cell = IPython.notebook.insert_cell_at_index('markdown', 0); | |
41 |
cell.set_text( |
|
43 | cell.set_text(text); | |
42 | cell.render(); |
|
44 | }, {text: text}); | |
43 | return cell.get_rendered(); |
|
45 | ||
44 | }); |
|
46 | var set_level = function (level) { | |
45 | this.test.assertEquals(output.trim(), '<h1 id=\"qux\">Qux</h1>', 'Markdown JS API works.'); |
|
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 | "cells": [ |
|
2 | "cells": [ | |
3 | { |
|
3 | { | |
4 |
"cell_type": " |
|
4 | "cell_type": "markdown", | |
5 | "level": 1, |
|
|||
6 | "metadata": {}, |
|
5 | "metadata": {}, | |
7 | "source": [ |
|
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 | from .base import ExportersTestsBase |
|
8 | from .base import ExportersTestsBase | |
9 | from ..notebook import NotebookExporter |
|
9 | from ..notebook import NotebookExporter | |
10 |
|
10 | |||
|
11 | from IPython.nbformat.current import validate | |||
11 | from IPython.testing.tools import assert_big_text_equal |
|
12 | from IPython.testing.tools import assert_big_text_equal | |
12 |
|
13 | |||
13 | class TestNotebookExporter(ExportersTestsBase): |
|
14 | class TestNotebookExporter(ExportersTestsBase): | |
@@ -29,7 +30,7 b' class TestNotebookExporter(ExportersTestsBase):' | |||||
29 | exporter = self.exporter_class(nbformat_version=3) |
|
30 | exporter = self.exporter_class(nbformat_version=3) | |
30 | (output, resources) = exporter.from_filename(self._get_notebook()) |
|
31 | (output, resources) = exporter.from_filename(self._get_notebook()) | |
31 | nb = json.loads(output) |
|
32 | nb = json.loads(output) | |
32 | self.assertEqual(nb['nbformat'], 3) |
|
33 | validate(nb) | |
33 |
|
34 | |||
34 | def test_downgrade_2(self): |
|
35 | def test_downgrade_2(self): | |
35 | exporter = self.exporter_class(nbformat_version=2) |
|
36 | exporter = self.exporter_class(nbformat_version=2) |
@@ -21,6 +21,7 b' from pygments.formatters import HtmlFormatter' | |||||
21 | from pygments.util import ClassNotFound |
|
21 | from pygments.util import ClassNotFound | |
22 |
|
22 | |||
23 | # IPython imports |
|
23 | # IPython imports | |
|
24 | from IPython.nbconvert.filters.strings import add_anchor | |||
24 | from IPython.nbconvert.utils.pandoc import pandoc |
|
25 | from IPython.nbconvert.utils.pandoc import pandoc | |
25 | from IPython.nbconvert.utils.exceptions import ConversionException |
|
26 | from IPython.nbconvert.utils.exceptions import ConversionException | |
26 | from IPython.utils.decorators import undoc |
|
27 | from IPython.utils.decorators import undoc | |
@@ -146,6 +147,10 b' class IPythonRenderer(mistune.Renderer):' | |||||
146 | formatter = HtmlFormatter() |
|
147 | formatter = HtmlFormatter() | |
147 | return highlight(code, lexer, formatter) |
|
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 | # Pass math through unaltered - mathjax does the rendering in the browser |
|
154 | # Pass math through unaltered - mathjax does the rendering in the browser | |
150 | def block_math(self, text): |
|
155 | def block_math(self, text): | |
151 | return '$$%s$$' % text |
|
156 | return '$$%s$$' % text |
@@ -4,17 +4,9 b'' | |||||
4 | Contains a collection of useful string manipulation filters for use in Jinja |
|
4 | Contains a collection of useful string manipulation filters for use in Jinja | |
5 | templates. |
|
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 | #----------------------------------------------------------------------------- |
|
8 | # Copyright (c) IPython Development Team. | |
16 | # Imports |
|
9 | # Distributed under the terms of the Modified BSD License. | |
17 | #----------------------------------------------------------------------------- |
|
|||
18 |
|
10 | |||
19 | import os |
|
11 | import os | |
20 | import re |
|
12 | import re | |
@@ -28,9 +20,6 b' from xml.etree import ElementTree' | |||||
28 | from IPython.core.interactiveshell import InteractiveShell |
|
20 | from IPython.core.interactiveshell import InteractiveShell | |
29 | from IPython.utils import py3compat |
|
21 | from IPython.utils import py3compat | |
30 |
|
22 | |||
31 | #----------------------------------------------------------------------------- |
|
|||
32 | # Functions |
|
|||
33 | #----------------------------------------------------------------------------- |
|
|||
34 |
|
23 | |||
35 | __all__ = [ |
|
24 | __all__ = [ | |
36 | 'wrap_text', |
|
25 | 'wrap_text', | |
@@ -88,9 +77,9 b' def html2text(element):' | |||||
88 |
|
77 | |||
89 |
|
78 | |||
90 | def add_anchor(html): |
|
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 | try: |
|
84 | try: | |
96 | h = ElementTree.fromstring(py3compat.cast_bytes_py2(html, encoding='utf-8')) |
|
85 | h = ElementTree.fromstring(py3compat.cast_bytes_py2(html, encoding='utf-8')) |
@@ -1,3 +1,4 b'' | |||||
|
1 | # coding: utf-8 | |||
1 | """Tests for conversions from markdown to other formats""" |
|
2 | """Tests for conversions from markdown to other formats""" | |
2 |
|
3 | |||
3 | # Copyright (c) IPython Development Team. |
|
4 | # Copyright (c) IPython Development Team. | |
@@ -26,7 +27,8 b' class TestMarkdown(TestsBase):' | |||||
26 | '#test', |
|
27 | '#test', | |
27 | '##test', |
|
28 | '##test', | |
28 | 'test\n----', |
|
29 | 'test\n----', | |
29 |
'test [link](https://google.com/)' |
|
30 | 'test [link](https://google.com/)', | |
|
31 | ] | |||
30 |
|
32 | |||
31 | tokens = [ |
|
33 | tokens = [ | |
32 | '*test', |
|
34 | '*test', | |
@@ -39,7 +41,8 b' class TestMarkdown(TestsBase):' | |||||
39 | 'test', |
|
41 | 'test', | |
40 | 'test', |
|
42 | 'test', | |
41 | 'test', |
|
43 | 'test', | |
42 |
('test', 'https://google.com/') |
|
44 | ('test', 'https://google.com/'), | |
|
45 | ] | |||
43 |
|
46 | |||
44 |
|
47 | |||
45 | @dec.onlyif_cmds_exist('pandoc') |
|
48 | @dec.onlyif_cmds_exist('pandoc') | |
@@ -87,6 +90,17 b' class TestMarkdown(TestsBase):' | |||||
87 | for index, test in enumerate(self.tests): |
|
90 | for index, test in enumerate(self.tests): | |
88 | self._try_markdown(markdown2html, test, self.tokens[index]) |
|
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 | def test_markdown2html_math(self): |
|
104 | def test_markdown2html_math(self): | |
91 | # Mathematical expressions should be passed through unaltered |
|
105 | # Mathematical expressions should be passed through unaltered | |
92 | cases = [("\\begin{equation*}\n" |
|
106 | cases = [("\\begin{equation*}\n" |
@@ -79,17 +79,6 b' In [ ]:' | |||||
79 | </div> |
|
79 | </div> | |
80 | {%- endblock markdowncell %} |
|
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 | {% block unknowncell scoped %} |
|
82 | {% block unknowncell scoped %} | |
94 | unknown type {{ cell.type }} |
|
83 | unknown type {{ cell.type }} | |
95 | {% endblock unknowncell %} |
|
84 | {% endblock unknowncell %} |
@@ -185,27 +185,6 b' This template does not define a docclass, the inheriting class must define this.' | |||||
185 | ((*- endblock figure -*)) |
|
185 | ((*- endblock figure -*)) | |
186 | ((*- endmacro *)) |
|
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 | % Redirect execute_result to display data priority. |
|
188 | % Redirect execute_result to display data priority. | |
210 | ((* block execute_result scoped *)) |
|
189 | ((* block execute_result scoped *)) | |
211 | ((* block data_priority scoped *)) |
|
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 | ((*- elif cell.cell_type in ['markdown'] -*)) |
|
75 | ((*- elif cell.cell_type in ['markdown'] -*)) | |
76 | ((*- block markdowncell scoped-*)) |
|
76 | ((*- block markdowncell scoped-*)) | |
77 | ((*- endblock markdowncell -*)) |
|
77 | ((*- endblock markdowncell -*)) | |
78 | ((*- elif cell.cell_type in ['heading'] -*)) |
|
|||
79 | ((*- block headingcell scoped-*)) |
|
|||
80 | ((*- endblock headingcell -*)) |
|
|||
81 | ((*- elif cell.cell_type in ['raw'] -*)) |
|
78 | ((*- elif cell.cell_type in ['raw'] -*)) | |
82 | ((*- block rawcell scoped -*)) |
|
79 | ((*- block rawcell scoped -*)) | |
83 | ((* if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) *)) |
|
80 | ((* if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) *)) |
@@ -58,11 +58,6 b'' | |||||
58 | {{ cell.source }} |
|
58 | {{ cell.source }} | |
59 | {% endblock markdowncell %} |
|
59 | {% endblock markdowncell %} | |
60 |
|
60 | |||
61 |
|
||||
62 | {% block headingcell scoped %} |
|
|||
63 | {{ '#' * cell.level }} {{ cell.source | replace('\n', ' ') }} |
|
|||
64 | {% endblock headingcell %} |
|
|||
65 |
|
||||
66 | {% block unknowncell scoped %} |
|
61 | {% block unknowncell scoped %} | |
67 | unknown type {{ cell.type }} |
|
62 | unknown type {{ cell.type }} | |
68 | {% endblock unknowncell %} No newline at end of file |
|
63 | {% endblock unknowncell %} |
@@ -15,7 +15,3 b'' | |||||
15 | {% block markdowncell scoped %} |
|
15 | {% block markdowncell scoped %} | |
16 | {{ cell.source | comment_lines }} |
|
16 | {{ cell.source | comment_lines }} | |
17 | {% endblock markdowncell %} |
|
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 | {%- elif cell.cell_type in ['markdown'] -%} |
|
71 | {%- elif cell.cell_type in ['markdown'] -%} | |
72 | {%- block markdowncell scoped-%} |
|
72 | {%- block markdowncell scoped-%} | |
73 | {%- endblock markdowncell -%} |
|
73 | {%- endblock markdowncell -%} | |
74 | {%- elif cell.cell_type in ['heading'] -%} |
|
|||
75 | {%- block headingcell scoped-%} |
|
|||
76 | {%- endblock headingcell -%} |
|
|||
77 | {%- elif cell.cell_type in ['raw'] -%} |
|
74 | {%- elif cell.cell_type in ['raw'] -%} | |
78 | {%- block rawcell scoped -%} |
|
75 | {%- block rawcell scoped -%} | |
79 | {% if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) %} |
|
76 | {% if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) %} |
@@ -1,11 +1,10 b'' | |||||
1 | { |
|
1 | { | |
2 | "cells": [ |
|
2 | "cells": [ | |
3 | { |
|
3 | { | |
4 |
"cell_type": " |
|
4 | "cell_type": "markdown", | |
5 | "level": 1, |
|
|||
6 | "metadata": {}, |
|
5 | "metadata": {}, | |
7 | "source": [ |
|
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 | "cells": [ |
|
2 | "cells": [ | |
3 | { |
|
3 | { | |
4 |
"cell_type": " |
|
4 | "cell_type": "markdown", | |
5 | "level": 1, |
|
|||
6 | "metadata": {}, |
|
5 | "metadata": {}, | |
7 | "source": [ |
|
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": " |
|
159 | "cell_type": "markdown", | |
161 | "level": 2, |
|
|||
162 | "metadata": {}, |
|
160 | "metadata": {}, | |
163 | "source": [ |
|
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": { |
|
2 | "cells": [ | |
3 | "name": 0 |
|
|||
4 | }, |
|
|||
5 | "nbformat": 3, |
|
|||
6 | "nbformat_minor": 0, |
|
|||
7 | "worksheets": [ |
|
|||
8 | { |
|
3 | { | |
9 | "cells": [ |
|
4 | "cell_type": "markdown", | |
10 | { |
|
5 | "metadata": {} | |
11 | "cell_type": "heading", |
|
6 | }, | |
12 | "level": 1, |
|
7 | { | |
13 | "source": [ |
|
8 | "cell_type": "markdown", | |
14 | "nbconvert latex test" |
|
9 | "metadata": {}, | |
15 | ] |
|
10 | "source": [ | |
16 | }, |
|
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." | |
17 |
|
|
12 | ] | |
18 | "cell_type": "markdown", |
|
13 | }, | |
19 | "metadata": {}, |
|
14 | { | |
20 | "source": [ |
|
15 | "cell_type": "heading", | |
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." |
|
16 | "level": 2, | |
22 | ] |
|
17 | "metadata": {}, | |
23 | }, |
|
18 | "source": [ | |
24 | { |
|
19 | "Printed Using Python" | |
25 | "cell_type": "heading", |
|
20 | ] | |
26 | "level": 2, |
|
21 | }, | |
27 | "metadata": {}, |
|
22 | { | |
28 | "source": [ |
|
23 | "cell_type": "code", | |
29 | "Printed Using Python" |
|
24 | "execution_count": 1, | |
30 | ] |
|
25 | "metadata": { | |
31 | }, |
|
26 | "collapsed": false | |
32 |
|
|
27 | }, | |
33 | "cell_type": "code", |
|
28 | "outputs": [ | |
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 | }, |
|
|||
50 | { |
|
29 | { | |
51 | "cell_type": "heading", |
|
30 | "name": "stdout", | |
52 | "level": 1000, |
|
31 | "output_type": "bad stream", | |
53 |
" |
|
32 | "text": [ | |
54 | "source": [ |
|
33 | "hello\n" | |
55 | "Pyout" |
|
|||
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", |
|
56 | "data": { | |
60 | "collapsed": false, |
|
57 | "text/html": [ | |
61 | "input": [ |
|
58 | "\n", | |
62 | "from IPython.display import HTML\n", |
|
59 | "<script>\n", | |
63 | "HTML(\"\"\"\n", |
|
60 | "console.log(\"hello\");\n", | |
64 | "<script>\n", |
|
61 | "</script>\n", | |
65 | "console.log(\"hello\");\n", |
|
62 | "<b>HTML</b>\n" | |
66 | "</script>\n", |
|
63 | ], | |
67 | "<b>HTML</b>\n", |
|
64 | "text/plain": [ | |
68 | "\"\"\")" |
|
65 | "<IPython.core.display.HTML at 0x1112757d0>" | |
69 |
] |
|
66 | ] | |
70 | "language": "python", |
|
67 | }, | |
|
68 | "execution_count": 3, | |||
71 | "metadata": {}, |
|
69 | "metadata": {}, | |
72 | "outputs": [ |
|
70 | "output_type": "execute_result" | |
73 |
|
|
71 | } | |
74 | "html": [ |
|
72 | ], | |
75 | "\n", |
|
73 | "source": [ | |
76 | "<script>\n", |
|
74 | "from IPython.display import HTML\n", | |
77 | "console.log(\"hello\");\n", |
|
75 | "HTML(\"\"\"\n", | |
78 |
|
|
76 | "<script>\n", | |
79 | "<b>HTML</b>\n" |
|
77 | "console.log(\"hello\");\n", | |
80 | ], |
|
78 | "</script>\n", | |
81 | "metadata": {}, |
|
79 | "<b>HTML</b>\n", | |
82 | "output_type": "pyout", |
|
80 | "\"\"\")" | |
83 | "prompt_number": 3, |
|
81 | ] | |
84 | "text": [ |
|
82 | }, | |
85 | "<IPython.core.display.HTML at 0x1112757d0>" |
|
83 | { | |
86 | ] |
|
84 | "cell_type": "code", | |
87 | } |
|
85 | "execution_count": 7, | |
88 | ], |
|
86 | "metadata": { | |
89 | "prompt_number": 3 |
|
87 | "collapsed": false | |
90 |
|
|
88 | }, | |
|
89 | "outputs": [ | |||
91 | { |
|
90 | { | |
92 | "cell_type": "code", |
|
91 | "data": { | |
93 | "collapsed": false, |
|
92 | "application/javascript": [ | |
94 | "input": [ |
|
93 | "console.log(\"hi\");" | |
95 | "%%javascript\n", |
|
94 | ], | |
96 | "console.log(\"hi\");" |
|
95 | "text/plain": [ | |
97 | ], |
|
96 | "<IPython.core.display.Javascript at 0x1112b4b50>" | |
98 | "language": "python", |
|
97 | ] | |
|
98 | }, | |||
99 | "metadata": {}, |
|
99 | "metadata": {}, | |
100 | "outputs": [ |
|
100 | "output_type": "display_data" | |
101 |
|
|
101 | } | |
102 | "javascript": [ |
|
102 | ], | |
103 | "console.log(\"hi\");" |
|
103 | "source": [ | |
104 | ], |
|
104 | "%%javascript\n", | |
105 | "metadata": {}, |
|
105 | "console.log(\"hi\");" | |
106 | "output_type": "display_data", |
|
106 | ] | |
107 | "text": [ |
|
107 | }, | |
108 | "<IPython.core.display.Javascript at 0x1112b4b50>" |
|
108 | { | |
109 | ] |
|
109 | "cell_type": "markdown", | |
110 | } |
|
110 | "metadata": {}, | |
111 | ], |
|
111 | "source": [ | |
112 | "prompt_number": 7 |
|
112 | "### Image" | |
113 |
|
|
113 | ] | |
114 | { |
|
114 | }, | |
115 | "cell_type": "heading", |
|
115 | { | |
116 | "level": 3, |
|
116 | "cell_type": "code", | |
117 | "metadata": {} |
|
117 | "execution_count": 6, | |
118 | }, |
|
118 | "metadata": { | |
|
119 | "collapsed": false | |||
|
120 | }, | |||
|
121 | "outputs": [ | |||
119 | { |
|
122 | { | |
120 | "cell_type": "code", |
|
123 | "data": { | |
121 | "collapsed": false, |
|
124 | "image/png": [ | |
122 | "input": [ |
|
125 | "iVBORw0KGgoAAAANSUhEUgAAAggAAABDCAYAAAD5/P3lAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n", | |
123 | "from IPython.display import Image\n", |
|
126 | "AAAH3AAAB9wBYvxo6AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURB\n", | |
124 | "Image(\"http://ipython.org/_static/IPy_header.png\")" |
|
127 | "VHic7Z15uBxF1bjfugkJhCWBsCSAJGACNg4QCI3RT1lEAVE+UEBNOmwCDcjHT1wQgU+WD3dFxA1o\n", | |
125 | ], |
|
128 | "CAikAZFFVlnCjizpsCUjHQjBIAkQlpCFJGS79fvjdGf69vTsc2fuza33eeaZmeqq6jM9vZw6dc4p\n", | |
126 | "language": "python", |
|
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 | "metadata": {}, |
|
293 | "metadata": {}, | |
128 | "outputs": [ |
|
294 | "output_type": "execute_result" | |
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 |
|
|||
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 | ] |
|
302 | ], | |
145 | } |
|
303 | "metadata": {}, | |
|
304 | "nbformat": 4, | |||
|
305 | "nbformat_minor": 0 | |||
|
306 | } No newline at end of file |
@@ -1,11 +1,10 b'' | |||||
1 | { |
|
1 | { | |
2 | "cells": [ |
|
2 | "cells": [ | |
3 | { |
|
3 | { | |
4 |
"cell_type": " |
|
4 | "cell_type": "markdown", | |
5 | "level": 1, |
|
|||
6 | "metadata": {}, |
|
5 | "metadata": {}, | |
7 | "source": [ |
|
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": " |
|
18 | "cell_type": "markdown", | |
20 | "level": 2, |
|
|||
21 | "metadata": {}, |
|
19 | "metadata": {}, | |
22 | "source": [ |
|
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": " |
|
44 | "cell_type": "markdown", | |
47 | "level": 2, |
|
|||
48 | "metadata": {}, |
|
45 | "metadata": {}, | |
49 | "source": [ |
|
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": " |
|
111 | "cell_type": "markdown", | |
115 | "level": 3, |
|
|||
116 | "metadata": {}, |
|
112 | "metadata": {}, | |
117 | "source": [ |
|
113 | "source": [ | |
118 | "Image" |
|
114 | "### Image" | |
119 | ] |
|
115 | ] | |
120 | }, |
|
116 | }, | |
121 | { |
|
117 | { |
@@ -28,7 +28,7 b' class TestValidator(TestsBase):' | |||||
28 | self.assertEqual(isvalid(nb), True) |
|
28 | self.assertEqual(isvalid(nb), True) | |
29 |
|
29 | |||
30 | def test_nb4(self): |
|
30 | def test_nb4(self): | |
31 |
"""Test that a v |
|
31 | """Test that a v4 notebook passes validation""" | |
32 | with self.fopen(u'test4.ipynb', u'r') as f: |
|
32 | with self.fopen(u'test4.ipynb', u'r') as f: | |
33 | nb = read(f, u'json') |
|
33 | nb = read(f, u'json') | |
34 | validate(nb) |
|
34 | validate(nb) | |
@@ -37,9 +37,9 b' class TestValidator(TestsBase):' | |||||
37 | def test_invalid(self): |
|
37 | def test_invalid(self): | |
38 | """Test than an invalid notebook does not pass validation""" |
|
38 | """Test than an invalid notebook does not pass validation""" | |
39 | # this notebook has a few different errors: |
|
39 | # this notebook has a few different errors: | |
40 | # - the name is an integer, rather than a string |
|
|||
41 | # - one cell is missing its source |
|
40 | # - one cell is missing its source | |
42 |
# - |
|
41 | # - invalid cell type | |
|
42 | # - invalid output_type | |||
43 | with self.fopen(u'invalid.ipynb', u'r') as f: |
|
43 | with self.fopen(u'invalid.ipynb', u'r') as f: | |
44 | nb = read(f, u'json') |
|
44 | nb = read(f, u'json') | |
45 | with self.assertRaises(ValidationError): |
|
45 | with self.assertRaises(ValidationError): |
@@ -6,7 +6,7 b'' | |||||
6 | from .nbbase import ( |
|
6 | from .nbbase import ( | |
7 | NotebookNode, from_dict, |
|
7 | NotebookNode, from_dict, | |
8 | nbformat, nbformat_minor, nbformat_schema, |
|
8 | nbformat, nbformat_minor, nbformat_schema, | |
9 |
new_code_cell |
|
9 | new_code_cell, new_markdown_cell, new_notebook, | |
10 | new_output, output_from_msg, |
|
10 | new_output, output_from_msg, | |
11 | ) |
|
11 | ) | |
12 |
|
12 |
@@ -4,6 +4,7 b'' | |||||
4 | # Distributed under the terms of the Modified BSD License. |
|
4 | # Distributed under the terms of the Modified BSD License. | |
5 |
|
5 | |||
6 | import json |
|
6 | import json | |
|
7 | import re | |||
7 |
|
8 | |||
8 | from .nbbase import ( |
|
9 | from .nbbase import ( | |
9 | nbformat, nbformat_minor, |
|
10 | nbformat, nbformat_minor, | |
@@ -72,6 +73,7 b' def upgrade(nb, from_version=3, from_minor=0):' | |||||
72 | def upgrade_cell(cell): |
|
73 | def upgrade_cell(cell): | |
73 | """upgrade a cell from v3 to v4 |
|
74 | """upgrade a cell from v3 to v4 | |
74 |
|
75 | |||
|
76 | heading cell -> markdown heading | |||
75 | code cell: |
|
77 | code cell: | |
76 | - remove language metadata |
|
78 | - remove language metadata | |
77 | - cell.input -> cell.source |
|
79 | - cell.input -> cell.source | |
@@ -82,9 +84,16 b' def upgrade_cell(cell):' | |||||
82 | if cell.cell_type == 'code': |
|
84 | if cell.cell_type == 'code': | |
83 | cell.pop('language', '') |
|
85 | cell.pop('language', '') | |
84 | cell.metadata.collapsed = cell.pop('collapsed') |
|
86 | cell.metadata.collapsed = cell.pop('collapsed') | |
85 | cell.source = cell.pop('input') |
|
87 | cell.source = cell.pop('input', '') | |
86 | cell.execution_count = cell.pop('prompt_number', None) |
|
88 | cell.execution_count = cell.pop('prompt_number', None) | |
87 | cell.outputs = upgrade_outputs(cell.outputs) |
|
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 | elif cell.cell_type == 'html': |
|
97 | elif cell.cell_type == 'html': | |
89 | # Technically, this exists. It will never happen in practice. |
|
98 | # Technically, this exists. It will never happen in practice. | |
90 | cell.cell_type = 'markdown' |
|
99 | cell.cell_type = 'markdown' | |
@@ -98,6 +107,8 b' def downgrade_cell(cell):' | |||||
98 | - cell.input <- cell.source |
|
107 | - cell.input <- cell.source | |
99 | - cell.prompt_number <- cell.execution_count |
|
108 | - cell.prompt_number <- cell.execution_count | |
100 | - update outputs |
|
109 | - update outputs | |
|
110 | markdown cell: | |||
|
111 | - single-line heading -> heading cell | |||
101 | """ |
|
112 | """ | |
102 | if cell.cell_type == 'code': |
|
113 | if cell.cell_type == 'code': | |
103 | cell.language = 'python' |
|
114 | cell.language = 'python' | |
@@ -105,6 +116,13 b' def downgrade_cell(cell):' | |||||
105 | cell.prompt_number = cell.pop('execution_count', None) |
|
116 | cell.prompt_number = cell.pop('execution_count', None) | |
106 | cell.collapsed = cell.metadata.pop('collapsed', False) |
|
117 | cell.collapsed = cell.metadata.pop('collapsed', False) | |
107 | cell.outputs = downgrade_outputs(cell.outputs) |
|
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 | return cell |
|
126 | return cell | |
109 |
|
127 | |||
110 | _mime_map = { |
|
128 | _mime_map = { |
@@ -121,16 +121,6 b" def new_markdown_cell(source='', **kwargs):" | |||||
121 | validate(cell, 'markdown_cell') |
|
121 | validate(cell, 'markdown_cell') | |
122 | return cell |
|
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 | def new_raw_cell(source='', **kwargs): |
|
124 | def new_raw_cell(source='', **kwargs): | |
135 | """Create a new raw cell""" |
|
125 | """Create a new raw cell""" | |
136 | cell = NotebookNode(cell_type='raw', source=source) |
|
126 | cell = NotebookNode(cell_type='raw', source=source) |
@@ -59,7 +59,6 b'' | |||||
59 | "oneOf": [ |
|
59 | "oneOf": [ | |
60 | {"$ref": "#/definitions/raw_cell"}, |
|
60 | {"$ref": "#/definitions/raw_cell"}, | |
61 | {"$ref": "#/definitions/markdown_cell"}, |
|
61 | {"$ref": "#/definitions/markdown_cell"}, | |
62 | {"$ref": "#/definitions/heading_cell"}, |
|
|||
63 | {"$ref": "#/definitions/code_cell"} |
|
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 | "code_cell": { |
|
120 | "code_cell": { | |
150 | "description": "Notebook code cell.", |
|
121 | "description": "Notebook code cell.", | |
151 | "type": "object", |
|
122 | "type": "object", |
@@ -44,14 +44,15 b' def rejoin_lines(nb):' | |||||
44 | for cell in nb.cells: |
|
44 | for cell in nb.cells: | |
45 | if 'source' in cell and isinstance(cell.source, list): |
|
45 | if 'source' in cell and isinstance(cell.source, list): | |
46 | cell.source = _join_lines(cell.source) |
|
46 | cell.source = _join_lines(cell.source) | |
47 | if cell.cell_type == 'code': |
|
47 | if cell.get('cell_type', None) == 'code': | |
48 | for output in cell.outputs: |
|
48 | for output in cell.get('outputs', []): | |
49 | if output.output_type in {'execute_result', 'display_data'}: |
|
49 | output_type = output.get('output_type', '') | |
50 | for key, value in output.data.items(): |
|
50 | if output_type in {'execute_result', 'display_data'}: | |
|
51 | for key, value in output.get('data', {}).items(): | |||
51 | if key != 'application/json' and isinstance(value, list): |
|
52 | if key != 'application/json' and isinstance(value, list): | |
52 | output.data[key] = _join_lines(value) |
|
53 | output.data[key] = _join_lines(value) | |
53 |
elif |
|
54 | elif output_type: | |
54 | if isinstance(output.text, list): |
|
55 | if isinstance(output.get('text', ''), list): | |
55 | output.text = _join_lines(output.text) |
|
56 | output.text = _join_lines(output.text) | |
56 | return nb |
|
57 | return nb | |
57 |
|
58 |
@@ -4,7 +4,7 b' import os' | |||||
4 | from base64 import encodestring |
|
4 | from base64 import encodestring | |
5 |
|
5 | |||
6 | from ..nbbase import ( |
|
6 | from ..nbbase import ( | |
7 |
new_code_cell |
|
7 | new_code_cell, new_markdown_cell, new_notebook, | |
8 | new_output, new_raw_cell |
|
8 | new_output, new_raw_cell | |
9 | ) |
|
9 | ) | |
10 |
|
10 | |||
@@ -31,9 +31,8 b' cells.append(new_raw_cell(' | |||||
31 | source='A random array', |
|
31 | source='A random array', | |
32 | )) |
|
32 | )) | |
33 |
|
33 | |||
34 |
cells.append(new_ |
|
34 | cells.append(new_markdown_cell( | |
35 | source=u'My Heading', |
|
35 | source=u'## My Heading', | |
36 | level=2, |
|
|||
37 | )) |
|
36 | )) | |
38 |
|
37 | |||
39 | cells.append(new_code_cell( |
|
38 | cells.append(new_code_cell( |
@@ -1,10 +1,13 b'' | |||||
1 | import copy |
|
1 | import copy | |
2 |
|
2 | |||
|
3 | import nose.tools as nt | |||
|
4 | ||||
3 | from IPython.nbformat.current import validate |
|
5 | from IPython.nbformat.current import validate | |
4 | from .. import convert |
|
6 | from .. import convert | |
5 |
|
7 | |||
6 | from . import nbexamples |
|
8 | from . import nbexamples | |
7 | from IPython.nbformat.v3.tests import nbexamples as v3examples |
|
9 | from IPython.nbformat.v3.tests import nbexamples as v3examples | |
|
10 | from IPython.nbformat import v3, v4 | |||
8 |
|
11 | |||
9 | def test_upgrade_notebook(): |
|
12 | def test_upgrade_notebook(): | |
10 | nb03 = copy.deepcopy(v3examples.nb0) |
|
13 | nb03 = copy.deepcopy(v3examples.nb0) | |
@@ -17,3 +20,48 b' def test_downgrade_notebook():' | |||||
17 | validate(nb04) |
|
20 | validate(nb04) | |
18 | nb03 = convert.downgrade(nb04) |
|
21 | nb03 = convert.downgrade(nb04) | |
19 | validate(nb03) |
|
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 | from IPython.nbformat.validator import isvalid, validate, ValidationError |
|
6 | from IPython.nbformat.validator import isvalid, validate, ValidationError | |
7 | from ..nbbase import ( |
|
7 | from ..nbbase import ( | |
8 | NotebookNode, nbformat, |
|
8 | NotebookNode, nbformat, | |
9 |
new_code_cell |
|
9 | new_code_cell, new_markdown_cell, new_notebook, | |
10 | new_output, new_raw_cell, |
|
10 | new_output, new_raw_cell, | |
11 | ) |
|
11 | ) | |
12 |
|
12 | |||
@@ -34,17 +34,6 b' def test_raw_cell():' | |||||
34 | cell = new_raw_cell('hi') |
|
34 | cell = new_raw_cell('hi') | |
35 | nt.assert_equal(cell.source, u'hi') |
|
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 | def test_empty_code_cell(): |
|
37 | def test_empty_code_cell(): | |
49 | cell = new_code_cell('hi') |
|
38 | cell = new_code_cell('hi') | |
50 | nt.assert_equal(cell.cell_type, 'code') |
|
39 | nt.assert_equal(cell.cell_type, 'code') |
@@ -12,7 +12,7 b' from IPython.nbformat.validator import validate, ValidationError' | |||||
12 | from ..nbjson import reads |
|
12 | from ..nbjson import reads | |
13 | from ..nbbase import ( |
|
13 | from ..nbbase import ( | |
14 | nbformat, |
|
14 | nbformat, | |
15 |
new_code_cell |
|
15 | new_code_cell, new_markdown_cell, new_notebook, | |
16 | new_output, new_raw_cell, |
|
16 | new_output, new_raw_cell, | |
17 | ) |
|
17 | ) | |
18 |
|
18 | |||
@@ -73,31 +73,6 b' def test_invalid_markdown_cell():' | |||||
73 | with nt.assert_raises(ValidationError): |
|
73 | with nt.assert_raises(ValidationError): | |
74 | validate4(cell, 'markdown_cell') |
|
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 | def test_invalid_raw_cell(): |
|
76 | def test_invalid_raw_cell(): | |
102 | cell = new_raw_cell() |
|
77 | cell = new_raw_cell() | |
103 |
|
78 |
@@ -82,24 +82,9 b' as defined in `GitHub-flavored markdown`_, and implemented in marked_.' | |||||
82 | "source" : ["some *markdown*"], |
|
82 | "source" : ["some *markdown*"], | |
83 | } |
|
83 | } | |
84 |
|
84 | |||
|
85 | .. versionchanged:: 4.0 | |||
85 |
|
86 | |||
86 | Heading cells |
|
87 | Heading cells have been removed, in favor of simple headings in markdown. | |
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 | } |
|
|||
103 |
|
88 | |||
104 |
|
89 | |||
105 | Code cells |
|
90 | Code cells |
General Comments 0
You need to be logged in to leave comments.
Login now