Show More
@@ -0,0 +1,14 b'' | |||
|
1 | """Generic script exporter class for any kernel language""" | |
|
2 | ||
|
3 | from .templateexporter import TemplateExporter | |
|
4 | ||
|
5 | class ScriptExporter(TemplateExporter): | |
|
6 | def _template_file_default(self): | |
|
7 | return 'script' | |
|
8 | ||
|
9 | def from_notebook_node(self, nb, resources=None, **kw): | |
|
10 | langinfo = nb.metadata.get('language_info', {}) | |
|
11 | self.file_extension = langinfo.get('file_extension', '.txt') | |
|
12 | self.output_mimetype = langinfo.get('mimetype', 'text/plain') | |
|
13 | ||
|
14 | return super(ScriptExporter, self).from_notebook_node(nb, resources, **kw) |
@@ -0,0 +1,5 b'' | |||
|
1 | {%- extends 'null.tpl' -%} | |
|
2 | ||
|
3 | {% block input %} | |
|
4 | {{ cell.source }} | |
|
5 | {% endblock input %} |
@@ -43,7 +43,7 b' def respond_zip(handler, name, output, resources):' | |||
|
43 | 43 | # Prepare the zip file |
|
44 | 44 | buffer = io.BytesIO() |
|
45 | 45 | zipf = zipfile.ZipFile(buffer, mode='w', compression=zipfile.ZIP_DEFLATED) |
|
46 |
output_filename = os.path.splitext(name)[0] + |
|
|
46 | output_filename = os.path.splitext(name)[0] + resources['output_extension'] | |
|
47 | 47 | zipf.writestr(output_filename, cast_bytes(output, 'utf-8')) |
|
48 | 48 | for filename, data in output_files.items(): |
|
49 | 49 | zipf.writestr(os.path.basename(filename), data) |
@@ -96,7 +96,7 b' class NbconvertFileHandler(IPythonHandler):' | |||
|
96 | 96 | |
|
97 | 97 | # Force download if requested |
|
98 | 98 | if self.get_argument('download', 'false').lower() == 'true': |
|
99 |
filename = os.path.splitext(name)[0] + |
|
|
99 | filename = os.path.splitext(name)[0] + resources['output_extension'] | |
|
100 | 100 | self.set_header('Content-Disposition', |
|
101 | 101 | 'attachment; filename="%s"' % filename) |
|
102 | 102 |
@@ -69,9 +69,6 b' define([' | |||
|
69 | 69 | MenuBar.prototype._nbconvert = function (format, download) { |
|
70 | 70 | download = download || false; |
|
71 | 71 | var notebook_path = this.notebook.notebook_path; |
|
72 | if (this.notebook.dirty) { | |
|
73 | this.notebook.save_notebook({async : false}); | |
|
74 | } | |
|
75 | 72 | var url = utils.url_join_encode( |
|
76 | 73 | this.base_url, |
|
77 | 74 | 'nbconvert', |
@@ -79,7 +76,14 b' define([' | |||
|
79 | 76 | notebook_path |
|
80 | 77 | ) + "?download=" + download.toString(); |
|
81 | 78 | |
|
82 |
window.open( |
|
|
79 | var w = window.open() | |
|
80 | if (this.notebook.dirty) { | |
|
81 | this.notebook.save_notebook().then(function() { | |
|
82 | w.location = url; | |
|
83 | }); | |
|
84 | } else { | |
|
85 | w.location = url; | |
|
86 | } | |
|
83 | 87 | }; |
|
84 | 88 | |
|
85 | 89 | MenuBar.prototype.bind_events = function () { |
@@ -129,10 +133,6 b' define([' | |||
|
129 | 133 | that._nbconvert('html', false); |
|
130 | 134 | }); |
|
131 | 135 | |
|
132 | this.element.find('#download_py').click(function () { | |
|
133 | that._nbconvert('python', true); | |
|
134 | }); | |
|
135 | ||
|
136 | 136 | this.element.find('#download_html').click(function () { |
|
137 | 137 | that._nbconvert('html', true); |
|
138 | 138 | }); |
@@ -308,6 +308,16 b' define([' | |||
|
308 | 308 | this.events.on('checkpoint_created.Notebook', function (event, data) { |
|
309 | 309 | that.update_restore_checkpoint(that.notebook.checkpoints); |
|
310 | 310 | }); |
|
311 | ||
|
312 | this.events.on('notebook_loaded.Notebook', function() { | |
|
313 | var langinfo = that.notebook.metadata.language_info || {}; | |
|
314 | that.update_nbconvert_script(langinfo); | |
|
315 | }); | |
|
316 | ||
|
317 | this.events.on('kernel_ready.Kernel', function(event, data) { | |
|
318 | var langinfo = data.kernel.info_reply.language_info || {}; | |
|
319 | that.update_nbconvert_script(langinfo); | |
|
320 | }); | |
|
311 | 321 | }; |
|
312 | 322 | |
|
313 | 323 | MenuBar.prototype.update_restore_checkpoint = function(checkpoints) { |
@@ -341,6 +351,31 b' define([' | |||
|
341 | 351 | }); |
|
342 | 352 | }; |
|
343 | 353 | |
|
354 | MenuBar.prototype.update_nbconvert_script = function(langinfo) { | |
|
355 | // Set the 'Download as foo' menu option for the relevant language. | |
|
356 | var el = this.element.find('#download_script'); | |
|
357 | var that = this; | |
|
358 | ||
|
359 | // Set menu entry text to e.g. "Python (.py)" | |
|
360 | var langname = (langinfo.name || 'Script') | |
|
361 | langname = langname.charAt(0).toUpperCase()+langname.substr(1) // Capitalise | |
|
362 | el.find('a').text(langname + ' ('+(langinfo.file_extension || 'txt')+')'); | |
|
363 | ||
|
364 | // Unregister any previously registered handlers | |
|
365 | el.off('click'); | |
|
366 | if (langinfo.nbconvert_exporter) { | |
|
367 | // Metadata specifies a specific exporter, e.g. 'python' | |
|
368 | el.click(function() { | |
|
369 | that._nbconvert(langinfo.nbconvert_exporter, true); | |
|
370 | }); | |
|
371 | } else { | |
|
372 | // Use generic 'script' exporter | |
|
373 | el.click(function() { | |
|
374 | that._nbconvert('script', true); | |
|
375 | }); | |
|
376 | } | |
|
377 | }; | |
|
378 | ||
|
344 | 379 | // Backwards compatability. |
|
345 | 380 | IPython.MenuBar = MenuBar; |
|
346 | 381 |
@@ -1944,7 +1944,7 b' define([' | |||
|
1944 | 1944 | var start = new Date().getTime(); |
|
1945 | 1945 | |
|
1946 | 1946 | var that = this; |
|
1947 | this.contents.save(this.notebook_path, model).then( | |
|
1947 | return this.contents.save(this.notebook_path, model).then( | |
|
1948 | 1948 | $.proxy(this.save_notebook_success, this, start), |
|
1949 | 1949 | function (error) { |
|
1950 | 1950 | that.events.trigger('notebook_save_failed.Notebook', error); |
@@ -105,7 +105,7 b' class="notebook_app"' | |||
|
105 | 105 | <li class="dropdown-submenu"><a href="#">Download as</a> |
|
106 | 106 | <ul class="dropdown-menu"> |
|
107 | 107 | <li id="download_ipynb"><a href="#">IPython Notebook (.ipynb)</a></li> |
|
108 |
<li id="download_ |
|
|
108 | <li id="download_script"><a href="#">Script</a></li> | |
|
109 | 109 | <li id="download_html"><a href="#">HTML (.html)</a></li> |
|
110 | 110 | <li id="download_rst"><a href="#">reST (.rst)</a></li> |
|
111 | 111 | <li id="download_pdf"><a href="#">PDF (.pdf)</a></li> |
@@ -75,6 +75,8 b' class IPythonKernel(KernelBase):' | |||
|
75 | 75 | 'codemirror_mode': {'name': 'ipython', |
|
76 | 76 | 'version': sys.version_info[0]}, |
|
77 | 77 | 'pygments_lexer': 'ipython%d' % (3 if PY3 else 2), |
|
78 | 'nbconvert_exporter': 'python', | |
|
79 | 'file_extension': '.py' | |
|
78 | 80 | } |
|
79 | 81 | @property |
|
80 | 82 | def banner(self): |
@@ -19,6 +19,7 b' from .markdown import MarkdownExporter' | |||
|
19 | 19 | from .python import PythonExporter |
|
20 | 20 | from .rst import RSTExporter |
|
21 | 21 | from .notebook import NotebookExporter |
|
22 | from .script import ScriptExporter | |
|
22 | 23 | |
|
23 | 24 | #----------------------------------------------------------------------------- |
|
24 | 25 | # Classes |
@@ -74,6 +75,7 b' __all__ = [' | |||
|
74 | 75 | 'export_pdf', |
|
75 | 76 | 'export_markdown', |
|
76 | 77 | 'export_python', |
|
78 | 'export_script', | |
|
77 | 79 | 'export_rst', |
|
78 | 80 | 'export_by_name', |
|
79 | 81 | 'get_export_names', |
@@ -132,6 +134,7 b' exporter_map = dict(' | |||
|
132 | 134 | python=PythonExporter, |
|
133 | 135 | rst=RSTExporter, |
|
134 | 136 | notebook=NotebookExporter, |
|
137 | script=ScriptExporter, | |
|
135 | 138 | ) |
|
136 | 139 | |
|
137 | 140 | def _make_exporter(name, E): |
@@ -32,7 +32,7 b' class Exporter(LoggingConfigurable):' | |||
|
32 | 32 | """ |
|
33 | 33 | |
|
34 | 34 | file_extension = Unicode( |
|
35 | 'txt', config=True, | |
|
35 | '.txt', config=True, | |
|
36 | 36 | help="Extension of the file that should be written to disk" |
|
37 | 37 | ) |
|
38 | 38 |
@@ -32,7 +32,7 b' class HTMLExporter(TemplateExporter):' | |||
|
32 | 32 | """ |
|
33 | 33 | |
|
34 | 34 | def _file_extension_default(self): |
|
35 | return 'html' | |
|
35 | return '.html' | |
|
36 | 36 | |
|
37 | 37 | def _default_template_path_default(self): |
|
38 | 38 | return os.path.join("..", "templates", "html") |
@@ -37,7 +37,7 b' class LatexExporter(TemplateExporter):' | |||
|
37 | 37 | """ |
|
38 | 38 | |
|
39 | 39 | def _file_extension_default(self): |
|
40 | return 'tex' | |
|
40 | return '.tex' | |
|
41 | 41 | |
|
42 | 42 | def _template_file_default(self): |
|
43 | 43 | return 'article' |
@@ -135,7 +135,7 b' class PDFExporter(LatexExporter):' | |||
|
135 | 135 | |
|
136 | 136 | # convert output extension to pdf |
|
137 | 137 | # the writer above required it to be tex |
|
138 | resources['output_extension'] = 'pdf' | |
|
138 | resources['output_extension'] = '.pdf' | |
|
139 | 139 | |
|
140 | 140 | return pdf_data, resources |
|
141 | 141 |
@@ -23,7 +23,7 b' class PythonExporter(TemplateExporter):' | |||
|
23 | 23 | Exports a Python code file. |
|
24 | 24 | """ |
|
25 | 25 | def _file_extension_default(self): |
|
26 | return 'py' | |
|
26 | return '.py' | |
|
27 | 27 | |
|
28 | 28 | def _template_file_default(self): |
|
29 | 29 | return 'python' |
@@ -26,7 +26,7 b' class RSTExporter(TemplateExporter):' | |||
|
26 | 26 | """ |
|
27 | 27 | |
|
28 | 28 | def _file_extension_default(self): |
|
29 | return 'rst' | |
|
29 | return '.rst' | |
|
30 | 30 | |
|
31 | 31 | def _template_file_default(self): |
|
32 | 32 | return 'rst' |
@@ -25,7 +25,7 b' class SlidesExporter(HTMLExporter):' | |||
|
25 | 25 | """Exports HTML slides with reveal.js""" |
|
26 | 26 | |
|
27 | 27 | def _file_extension_default(self): |
|
28 | return 'slides.html' | |
|
28 | return '.slides.html' | |
|
29 | 29 | |
|
30 | 30 | def _template_file_default(self): |
|
31 | 31 | return 'slides_reveal' |
@@ -286,7 +286,7 b' class NbConvertApp(BaseIPythonApplication):' | |||
|
286 | 286 | # strip duplicate extension from output_base, to avoid Basname.ext.ext |
|
287 | 287 | if getattr(exporter, 'file_extension', False): |
|
288 | 288 | base, ext = os.path.splitext(self.output_base) |
|
289 |
if ext == |
|
|
289 | if ext == exporter.file_extension: | |
|
290 | 290 | self.output_base = base |
|
291 | 291 | notebook_name = self.output_base |
|
292 | 292 | resources = {} |
@@ -93,7 +93,7 b' class FilesWriter(WriterBase):' | |||
|
93 | 93 | |
|
94 | 94 | # Determine where to write conversion results. |
|
95 | 95 | if output_extension is not None: |
|
96 |
dest = notebook_name + |
|
|
96 | dest = notebook_name + output_extension | |
|
97 | 97 | else: |
|
98 | 98 | dest = notebook_name |
|
99 | 99 | if self.build_directory: |
@@ -59,7 +59,7 b' class Testfiles(TestsBase):' | |||
|
59 | 59 | with self.create_temp_cwd(): |
|
60 | 60 | |
|
61 | 61 | # Create the resoruces dictionary |
|
62 | res = {'output_extension': 'txt'} | |
|
62 | res = {'output_extension': '.txt'} | |
|
63 | 63 | |
|
64 | 64 | # Create files writer, test output |
|
65 | 65 | writer = FilesWriter() |
@@ -735,6 +735,9 b' Message type: ``kernel_info_reply``::' | |||
|
735 | 735 | 'language_info': { |
|
736 | 736 | 'mimetype': str, |
|
737 | 737 | |
|
738 | # Extension without the dot, e.g. 'py' | |
|
739 | 'file_extension': str, | |
|
740 | ||
|
738 | 741 | # Pygments lexer, for highlighting |
|
739 | 742 | # Only needed if it differs from the top level 'language' field. |
|
740 | 743 | 'pygments_lexer': str, |
@@ -742,6 +745,11 b' Message type: ``kernel_info_reply``::' | |||
|
742 | 745 | # Codemirror mode, for for highlighting in the notebook. |
|
743 | 746 | # Only needed if it differs from the top level 'language' field. |
|
744 | 747 | 'codemirror_mode': str or dict, |
|
748 | ||
|
749 | # Nbconvert exporter, if notebooks written with this kernel should | |
|
750 | # be exported with something other than the general 'script' | |
|
751 | # exporter. | |
|
752 | 'nbconvert_exporter': str, | |
|
745 | 753 | }, |
|
746 | 754 | |
|
747 | 755 | # A banner of information about the kernel, |
@@ -38,9 +38,10 b' following methods and attributes:' | |||
|
38 | 38 | |
|
39 | 39 | Language information for :ref:`msging_kernel_info` replies, in a dictionary. |
|
40 | 40 | This should contain the key ``mimetype`` with the mimetype of code in the |
|
41 |
target language (e.g. ``'text/x-python'``) |
|
|
42 | ``codemirror_mode`` and ``pygments_lexer`` if they need to differ from | |
|
43 | :attr:`language`. | |
|
41 | target language (e.g. ``'text/x-python'``), and ``file_extension`` (e.g. | |
|
42 | ``'py'``). | |
|
43 | It may also contain keys ``codemirror_mode`` and ``pygments_lexer`` if they | |
|
44 | need to differ from :attr:`language`. | |
|
44 | 45 | |
|
45 | 46 | Other keys may be added to this later. |
|
46 | 47 |
General Comments 0
You need to be logged in to leave comments.
Login now