##// END OF EJS Templates
Merge pull request #6978 from takluyver/nbconvert-script...
Min RK -
r19053:38e12544 merge
parent child Browse files
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] + '.' + resources['output_extension']
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] + '.' + resources['output_extension']
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(url);
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_py"><a href="#">Python (.py)</a></li>
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 == '.' + exporter.file_extension:
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 + '.' + output_extension
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'``). It may also contain keys
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