##// END OF EJS Templates
'Download as' script
Thomas Kluyver -
Show More
@@ -1,348 +1,379 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'jquery',
5 'jquery',
6 'base/js/namespace',
6 'base/js/namespace',
7 'base/js/dialog',
7 'base/js/dialog',
8 'base/js/utils',
8 'base/js/utils',
9 'notebook/js/tour',
9 'notebook/js/tour',
10 'bootstrap',
10 'bootstrap',
11 'moment',
11 'moment',
12 ], function($, IPython, dialog, utils, tour, bootstrap, moment) {
12 ], function($, IPython, dialog, utils, tour, bootstrap, moment) {
13 "use strict";
13 "use strict";
14
14
15 var MenuBar = function (selector, options) {
15 var MenuBar = function (selector, options) {
16 // Constructor
16 // Constructor
17 //
17 //
18 // A MenuBar Class to generate the menubar of IPython notebook
18 // A MenuBar Class to generate the menubar of IPython notebook
19 //
19 //
20 // Parameters:
20 // Parameters:
21 // selector: string
21 // selector: string
22 // options: dictionary
22 // options: dictionary
23 // Dictionary of keyword arguments.
23 // Dictionary of keyword arguments.
24 // notebook: Notebook instance
24 // notebook: Notebook instance
25 // contents: ContentManager instance
25 // contents: ContentManager instance
26 // layout_manager: LayoutManager instance
26 // layout_manager: LayoutManager instance
27 // events: $(Events) instance
27 // events: $(Events) instance
28 // save_widget: SaveWidget instance
28 // save_widget: SaveWidget instance
29 // quick_help: QuickHelp instance
29 // quick_help: QuickHelp instance
30 // base_url : string
30 // base_url : string
31 // notebook_path : string
31 // notebook_path : string
32 // notebook_name : string
32 // notebook_name : string
33 options = options || {};
33 options = options || {};
34 this.base_url = options.base_url || utils.get_body_data("baseUrl");
34 this.base_url = options.base_url || utils.get_body_data("baseUrl");
35 this.selector = selector;
35 this.selector = selector;
36 this.notebook = options.notebook;
36 this.notebook = options.notebook;
37 this.contents = options.contents;
37 this.contents = options.contents;
38 this.layout_manager = options.layout_manager;
38 this.layout_manager = options.layout_manager;
39 this.events = options.events;
39 this.events = options.events;
40 this.save_widget = options.save_widget;
40 this.save_widget = options.save_widget;
41 this.quick_help = options.quick_help;
41 this.quick_help = options.quick_help;
42
42
43 try {
43 try {
44 this.tour = new tour.Tour(this.notebook, this.events);
44 this.tour = new tour.Tour(this.notebook, this.events);
45 } catch (e) {
45 } catch (e) {
46 this.tour = undefined;
46 this.tour = undefined;
47 console.log("Failed to instantiate Notebook Tour", e);
47 console.log("Failed to instantiate Notebook Tour", e);
48 }
48 }
49
49
50 if (this.selector !== undefined) {
50 if (this.selector !== undefined) {
51 this.element = $(selector);
51 this.element = $(selector);
52 this.style();
52 this.style();
53 this.bind_events();
53 this.bind_events();
54 }
54 }
55 };
55 };
56
56
57 // TODO: This has definitively nothing to do with style ...
57 // TODO: This has definitively nothing to do with style ...
58 MenuBar.prototype.style = function () {
58 MenuBar.prototype.style = function () {
59 var that = this;
59 var that = this;
60 this.element.find("li").click(function (event, ui) {
60 this.element.find("li").click(function (event, ui) {
61 // The selected cell loses focus when the menu is entered, so we
61 // The selected cell loses focus when the menu is entered, so we
62 // re-select it upon selection.
62 // re-select it upon selection.
63 var i = that.notebook.get_selected_index();
63 var i = that.notebook.get_selected_index();
64 that.notebook.select(i);
64 that.notebook.select(i);
65 }
65 }
66 );
66 );
67 };
67 };
68
68
69 MenuBar.prototype._nbconvert = function (format, download) {
69 MenuBar.prototype._nbconvert = function (format, download) {
70 download = download || false;
70 download = download || false;
71 var notebook_path = this.notebook.notebook_path;
71 var notebook_path = this.notebook.notebook_path;
72 if (this.notebook.dirty) {
72 if (this.notebook.dirty) {
73 this.notebook.save_notebook({async : false});
73 this.notebook.save_notebook({async : false});
74 }
74 }
75 var url = utils.url_join_encode(
75 var url = utils.url_join_encode(
76 this.base_url,
76 this.base_url,
77 'nbconvert',
77 'nbconvert',
78 format,
78 format,
79 notebook_path
79 notebook_path
80 ) + "?download=" + download.toString();
80 ) + "?download=" + download.toString();
81
81
82 window.open(url);
82 window.open(url);
83 };
83 };
84
84
85 MenuBar.prototype.bind_events = function () {
85 MenuBar.prototype.bind_events = function () {
86 // File
86 // File
87 var that = this;
87 var that = this;
88 this.element.find('#new_notebook').click(function () {
88 this.element.find('#new_notebook').click(function () {
89 var w = window.open();
89 var w = window.open();
90 // Create a new notebook in the same path as the current
90 // Create a new notebook in the same path as the current
91 // notebook's path.
91 // notebook's path.
92 var parent = utils.url_path_split(that.notebook.notebook_path)[0];
92 var parent = utils.url_path_split(that.notebook.notebook_path)[0];
93 that.contents.new_untitled(parent, {type: "notebook"}).then(
93 that.contents.new_untitled(parent, {type: "notebook"}).then(
94 function (data) {
94 function (data) {
95 w.location = utils.url_join_encode(
95 w.location = utils.url_join_encode(
96 that.base_url, 'notebooks', data.path
96 that.base_url, 'notebooks', data.path
97 );
97 );
98 },
98 },
99 function(error) {
99 function(error) {
100 w.close();
100 w.close();
101 dialog.modal({
101 dialog.modal({
102 title : 'Creating Notebook Failed',
102 title : 'Creating Notebook Failed',
103 body : "The error was: " + error.message,
103 body : "The error was: " + error.message,
104 buttons : {'OK' : {'class' : 'btn-primary'}}
104 buttons : {'OK' : {'class' : 'btn-primary'}}
105 });
105 });
106 }
106 }
107 );
107 );
108 });
108 });
109 this.element.find('#open_notebook').click(function () {
109 this.element.find('#open_notebook').click(function () {
110 var parent = utils.url_path_split(that.notebook.notebook_path)[0];
110 var parent = utils.url_path_split(that.notebook.notebook_path)[0];
111 window.open(utils.url_join_encode(that.base_url, 'tree', parent));
111 window.open(utils.url_join_encode(that.base_url, 'tree', parent));
112 });
112 });
113 this.element.find('#copy_notebook').click(function () {
113 this.element.find('#copy_notebook').click(function () {
114 that.notebook.copy_notebook();
114 that.notebook.copy_notebook();
115 return false;
115 return false;
116 });
116 });
117 this.element.find('#download_ipynb').click(function () {
117 this.element.find('#download_ipynb').click(function () {
118 var base_url = that.notebook.base_url;
118 var base_url = that.notebook.base_url;
119 var notebook_path = that.notebook.notebook_path;
119 var notebook_path = that.notebook.notebook_path;
120 if (that.notebook.dirty) {
120 if (that.notebook.dirty) {
121 that.notebook.save_notebook({async : false});
121 that.notebook.save_notebook({async : false});
122 }
122 }
123
123
124 var url = utils.url_join_encode(base_url, 'files', notebook_path);
124 var url = utils.url_join_encode(base_url, 'files', notebook_path);
125 window.open(url + '?download=1');
125 window.open(url + '?download=1');
126 });
126 });
127
127
128 this.element.find('#print_preview').click(function () {
128 this.element.find('#print_preview').click(function () {
129 that._nbconvert('html', false);
129 that._nbconvert('html', false);
130 });
130 });
131
131
132 this.element.find('#download_py').click(function () {
133 that._nbconvert('python', true);
134 });
135
136 this.element.find('#download_html').click(function () {
132 this.element.find('#download_html').click(function () {
137 that._nbconvert('html', true);
133 that._nbconvert('html', true);
138 });
134 });
139
135
140 this.element.find('#download_rst').click(function () {
136 this.element.find('#download_rst').click(function () {
141 that._nbconvert('rst', true);
137 that._nbconvert('rst', true);
142 });
138 });
143
139
144 this.element.find('#download_pdf').click(function () {
140 this.element.find('#download_pdf').click(function () {
145 that._nbconvert('pdf', true);
141 that._nbconvert('pdf', true);
146 });
142 });
147
143
148 this.element.find('#rename_notebook').click(function () {
144 this.element.find('#rename_notebook').click(function () {
149 that.save_widget.rename_notebook({notebook: that.notebook});
145 that.save_widget.rename_notebook({notebook: that.notebook});
150 });
146 });
151 this.element.find('#save_checkpoint').click(function () {
147 this.element.find('#save_checkpoint').click(function () {
152 that.notebook.save_checkpoint();
148 that.notebook.save_checkpoint();
153 });
149 });
154 this.element.find('#restore_checkpoint').click(function () {
150 this.element.find('#restore_checkpoint').click(function () {
155 });
151 });
156 this.element.find('#trust_notebook').click(function () {
152 this.element.find('#trust_notebook').click(function () {
157 that.notebook.trust_notebook();
153 that.notebook.trust_notebook();
158 });
154 });
159 this.events.on('trust_changed.Notebook', function (event, trusted) {
155 this.events.on('trust_changed.Notebook', function (event, trusted) {
160 if (trusted) {
156 if (trusted) {
161 that.element.find('#trust_notebook')
157 that.element.find('#trust_notebook')
162 .addClass("disabled")
158 .addClass("disabled")
163 .find("a").text("Trusted Notebook");
159 .find("a").text("Trusted Notebook");
164 } else {
160 } else {
165 that.element.find('#trust_notebook')
161 that.element.find('#trust_notebook')
166 .removeClass("disabled")
162 .removeClass("disabled")
167 .find("a").text("Trust Notebook");
163 .find("a").text("Trust Notebook");
168 }
164 }
169 });
165 });
170 this.element.find('#kill_and_exit').click(function () {
166 this.element.find('#kill_and_exit').click(function () {
171 var close_window = function () {
167 var close_window = function () {
172 // allow closing of new tabs in Chromium, impossible in FF
168 // allow closing of new tabs in Chromium, impossible in FF
173 window.open('', '_self', '');
169 window.open('', '_self', '');
174 window.close();
170 window.close();
175 };
171 };
176 // finish with close on success or failure
172 // finish with close on success or failure
177 that.notebook.session.delete(close_window, close_window);
173 that.notebook.session.delete(close_window, close_window);
178 });
174 });
179 // Edit
175 // Edit
180 this.element.find('#cut_cell').click(function () {
176 this.element.find('#cut_cell').click(function () {
181 that.notebook.cut_cell();
177 that.notebook.cut_cell();
182 });
178 });
183 this.element.find('#copy_cell').click(function () {
179 this.element.find('#copy_cell').click(function () {
184 that.notebook.copy_cell();
180 that.notebook.copy_cell();
185 });
181 });
186 this.element.find('#delete_cell').click(function () {
182 this.element.find('#delete_cell').click(function () {
187 that.notebook.delete_cell();
183 that.notebook.delete_cell();
188 });
184 });
189 this.element.find('#undelete_cell').click(function () {
185 this.element.find('#undelete_cell').click(function () {
190 that.notebook.undelete_cell();
186 that.notebook.undelete_cell();
191 });
187 });
192 this.element.find('#split_cell').click(function () {
188 this.element.find('#split_cell').click(function () {
193 that.notebook.split_cell();
189 that.notebook.split_cell();
194 });
190 });
195 this.element.find('#merge_cell_above').click(function () {
191 this.element.find('#merge_cell_above').click(function () {
196 that.notebook.merge_cell_above();
192 that.notebook.merge_cell_above();
197 });
193 });
198 this.element.find('#merge_cell_below').click(function () {
194 this.element.find('#merge_cell_below').click(function () {
199 that.notebook.merge_cell_below();
195 that.notebook.merge_cell_below();
200 });
196 });
201 this.element.find('#move_cell_up').click(function () {
197 this.element.find('#move_cell_up').click(function () {
202 that.notebook.move_cell_up();
198 that.notebook.move_cell_up();
203 });
199 });
204 this.element.find('#move_cell_down').click(function () {
200 this.element.find('#move_cell_down').click(function () {
205 that.notebook.move_cell_down();
201 that.notebook.move_cell_down();
206 });
202 });
207 this.element.find('#edit_nb_metadata').click(function () {
203 this.element.find('#edit_nb_metadata').click(function () {
208 that.notebook.edit_metadata({
204 that.notebook.edit_metadata({
209 notebook: that.notebook,
205 notebook: that.notebook,
210 keyboard_manager: that.notebook.keyboard_manager});
206 keyboard_manager: that.notebook.keyboard_manager});
211 });
207 });
212
208
213 // View
209 // View
214 this.element.find('#toggle_header').click(function () {
210 this.element.find('#toggle_header').click(function () {
215 $('div#header').toggle();
211 $('div#header').toggle();
216 that.layout_manager.do_resize();
212 that.layout_manager.do_resize();
217 });
213 });
218 this.element.find('#toggle_toolbar').click(function () {
214 this.element.find('#toggle_toolbar').click(function () {
219 $('div#maintoolbar').toggle();
215 $('div#maintoolbar').toggle();
220 that.layout_manager.do_resize();
216 that.layout_manager.do_resize();
221 });
217 });
222 // Insert
218 // Insert
223 this.element.find('#insert_cell_above').click(function () {
219 this.element.find('#insert_cell_above').click(function () {
224 that.notebook.insert_cell_above('code');
220 that.notebook.insert_cell_above('code');
225 that.notebook.select_prev();
221 that.notebook.select_prev();
226 });
222 });
227 this.element.find('#insert_cell_below').click(function () {
223 this.element.find('#insert_cell_below').click(function () {
228 that.notebook.insert_cell_below('code');
224 that.notebook.insert_cell_below('code');
229 that.notebook.select_next();
225 that.notebook.select_next();
230 });
226 });
231 // Cell
227 // Cell
232 this.element.find('#run_cell').click(function () {
228 this.element.find('#run_cell').click(function () {
233 that.notebook.execute_cell();
229 that.notebook.execute_cell();
234 });
230 });
235 this.element.find('#run_cell_select_below').click(function () {
231 this.element.find('#run_cell_select_below').click(function () {
236 that.notebook.execute_cell_and_select_below();
232 that.notebook.execute_cell_and_select_below();
237 });
233 });
238 this.element.find('#run_cell_insert_below').click(function () {
234 this.element.find('#run_cell_insert_below').click(function () {
239 that.notebook.execute_cell_and_insert_below();
235 that.notebook.execute_cell_and_insert_below();
240 });
236 });
241 this.element.find('#run_all_cells').click(function () {
237 this.element.find('#run_all_cells').click(function () {
242 that.notebook.execute_all_cells();
238 that.notebook.execute_all_cells();
243 });
239 });
244 this.element.find('#run_all_cells_above').click(function () {
240 this.element.find('#run_all_cells_above').click(function () {
245 that.notebook.execute_cells_above();
241 that.notebook.execute_cells_above();
246 });
242 });
247 this.element.find('#run_all_cells_below').click(function () {
243 this.element.find('#run_all_cells_below').click(function () {
248 that.notebook.execute_cells_below();
244 that.notebook.execute_cells_below();
249 });
245 });
250 this.element.find('#to_code').click(function () {
246 this.element.find('#to_code').click(function () {
251 that.notebook.to_code();
247 that.notebook.to_code();
252 });
248 });
253 this.element.find('#to_markdown').click(function () {
249 this.element.find('#to_markdown').click(function () {
254 that.notebook.to_markdown();
250 that.notebook.to_markdown();
255 });
251 });
256 this.element.find('#to_raw').click(function () {
252 this.element.find('#to_raw').click(function () {
257 that.notebook.to_raw();
253 that.notebook.to_raw();
258 });
254 });
259
255
260 this.element.find('#toggle_current_output').click(function () {
256 this.element.find('#toggle_current_output').click(function () {
261 that.notebook.toggle_output();
257 that.notebook.toggle_output();
262 });
258 });
263 this.element.find('#toggle_current_output_scroll').click(function () {
259 this.element.find('#toggle_current_output_scroll').click(function () {
264 that.notebook.toggle_output_scroll();
260 that.notebook.toggle_output_scroll();
265 });
261 });
266 this.element.find('#clear_current_output').click(function () {
262 this.element.find('#clear_current_output').click(function () {
267 that.notebook.clear_output();
263 that.notebook.clear_output();
268 });
264 });
269
265
270 this.element.find('#toggle_all_output').click(function () {
266 this.element.find('#toggle_all_output').click(function () {
271 that.notebook.toggle_all_output();
267 that.notebook.toggle_all_output();
272 });
268 });
273 this.element.find('#toggle_all_output_scroll').click(function () {
269 this.element.find('#toggle_all_output_scroll').click(function () {
274 that.notebook.toggle_all_output_scroll();
270 that.notebook.toggle_all_output_scroll();
275 });
271 });
276 this.element.find('#clear_all_output').click(function () {
272 this.element.find('#clear_all_output').click(function () {
277 that.notebook.clear_all_output();
273 that.notebook.clear_all_output();
278 });
274 });
279
275
280 // Kernel
276 // Kernel
281 this.element.find('#int_kernel').click(function () {
277 this.element.find('#int_kernel').click(function () {
282 that.notebook.kernel.interrupt();
278 that.notebook.kernel.interrupt();
283 });
279 });
284 this.element.find('#restart_kernel').click(function () {
280 this.element.find('#restart_kernel').click(function () {
285 that.notebook.restart_kernel();
281 that.notebook.restart_kernel();
286 });
282 });
287 this.element.find('#reconnect_kernel').click(function () {
283 this.element.find('#reconnect_kernel').click(function () {
288 that.notebook.kernel.reconnect();
284 that.notebook.kernel.reconnect();
289 });
285 });
290 // Help
286 // Help
291 if (this.tour) {
287 if (this.tour) {
292 this.element.find('#notebook_tour').click(function () {
288 this.element.find('#notebook_tour').click(function () {
293 that.tour.start();
289 that.tour.start();
294 });
290 });
295 } else {
291 } else {
296 this.element.find('#notebook_tour').addClass("disabled");
292 this.element.find('#notebook_tour').addClass("disabled");
297 }
293 }
298 this.element.find('#keyboard_shortcuts').click(function () {
294 this.element.find('#keyboard_shortcuts').click(function () {
299 that.quick_help.show_keyboard_shortcuts();
295 that.quick_help.show_keyboard_shortcuts();
300 });
296 });
301
297
302 this.update_restore_checkpoint(null);
298 this.update_restore_checkpoint(null);
303
299
304 this.events.on('checkpoints_listed.Notebook', function (event, data) {
300 this.events.on('checkpoints_listed.Notebook', function (event, data) {
305 that.update_restore_checkpoint(that.notebook.checkpoints);
301 that.update_restore_checkpoint(that.notebook.checkpoints);
306 });
302 });
307
303
308 this.events.on('checkpoint_created.Notebook', function (event, data) {
304 this.events.on('checkpoint_created.Notebook', function (event, data) {
309 that.update_restore_checkpoint(that.notebook.checkpoints);
305 that.update_restore_checkpoint(that.notebook.checkpoints);
310 });
306 });
307
308 this.events.on('notebook_loaded.Notebook', function() {
309 var langinfo = that.notebook.metadata.language_info || {};
310 that.update_nbconvert_script(langinfo);
311 });
312
313 this.events.on('kernel_ready.Kernel', function(event, data) {
314 var langinfo = data.kernel.info_reply.language_info || {};
315 that.update_nbconvert_script(langinfo);
316 });
311 };
317 };
312
318
313 MenuBar.prototype.update_restore_checkpoint = function(checkpoints) {
319 MenuBar.prototype.update_restore_checkpoint = function(checkpoints) {
314 var ul = this.element.find("#restore_checkpoint").find("ul");
320 var ul = this.element.find("#restore_checkpoint").find("ul");
315 ul.empty();
321 ul.empty();
316 if (!checkpoints || checkpoints.length === 0) {
322 if (!checkpoints || checkpoints.length === 0) {
317 ul.append(
323 ul.append(
318 $("<li/>")
324 $("<li/>")
319 .addClass("disabled")
325 .addClass("disabled")
320 .append(
326 .append(
321 $("<a/>")
327 $("<a/>")
322 .text("No checkpoints")
328 .text("No checkpoints")
323 )
329 )
324 );
330 );
325 return;
331 return;
326 }
332 }
327
333
328 var that = this;
334 var that = this;
329 checkpoints.map(function (checkpoint) {
335 checkpoints.map(function (checkpoint) {
330 var d = new Date(checkpoint.last_modified);
336 var d = new Date(checkpoint.last_modified);
331 ul.append(
337 ul.append(
332 $("<li/>").append(
338 $("<li/>").append(
333 $("<a/>")
339 $("<a/>")
334 .attr("href", "#")
340 .attr("href", "#")
335 .text(moment(d).format("LLLL"))
341 .text(moment(d).format("LLLL"))
336 .click(function () {
342 .click(function () {
337 that.notebook.restore_checkpoint_dialog(checkpoint);
343 that.notebook.restore_checkpoint_dialog(checkpoint);
338 })
344 })
339 )
345 )
340 );
346 );
341 });
347 });
342 };
348 };
349
350 MenuBar.prototype.update_nbconvert_script = function(langinfo) {
351 // Set the 'Download as foo' menu option for the relevant language.
352 var el = this.element.find('#download_script');
353 var that = this;
354
355 // Set menu entry text to e.g. "Python (.py)"
356 var langname = (langinfo.name || 'Script')
357 langname = langname.charAt(0).toUpperCase()+langname.substr(1) // Capitalise
358 el.find('a').text(langname + ' (.'+(langinfo.file_extension || 'txt')+')');
359
360 // Unregister any previously registered handlers
361 el.off('click');
362 if (langinfo.nbconvert_exporter) {
363 // Metadata specifies a specific exporter, e.g. 'python'
364 el.click(function() {
365 that._nbconvert(langinfo.nbconvert_exporter, true);
366 });
367 } else {
368 // Use generic 'script' exporter
369 el.click(function() {
370 that._nbconvert('script', true);
371 });
372 }
373 };
343
374
344 // Backwards compatability.
375 // Backwards compatability.
345 IPython.MenuBar = MenuBar;
376 IPython.MenuBar = MenuBar;
346
377
347 return {'MenuBar': MenuBar};
378 return {'MenuBar': MenuBar};
348 });
379 });
@@ -1,328 +1,328 b''
1 {% extends "page.html" %}
1 {% extends "page.html" %}
2
2
3 {% block stylesheet %}
3 {% block stylesheet %}
4
4
5 {% if mathjax_url %}
5 {% if mathjax_url %}
6 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML-full&delayStartupUntil=configured" charset="utf-8"></script>
6 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML-full&delayStartupUntil=configured" charset="utf-8"></script>
7 {% endif %}
7 {% endif %}
8 <script type="text/javascript">
8 <script type="text/javascript">
9 // MathJax disabled, set as null to distingish from *missing* MathJax,
9 // MathJax disabled, set as null to distingish from *missing* MathJax,
10 // where it will be undefined, and should prompt a dialog later.
10 // where it will be undefined, and should prompt a dialog later.
11 window.mathjax_url = "{{mathjax_url}}";
11 window.mathjax_url = "{{mathjax_url}}";
12 </script>
12 </script>
13
13
14 <link rel="stylesheet" href="{{ static_url("components/bootstrap-tour/build/css/bootstrap-tour.min.css") }}" type="text/css" />
14 <link rel="stylesheet" href="{{ static_url("components/bootstrap-tour/build/css/bootstrap-tour.min.css") }}" type="text/css" />
15 <link rel="stylesheet" href="{{ static_url("components/codemirror/lib/codemirror.css") }}">
15 <link rel="stylesheet" href="{{ static_url("components/codemirror/lib/codemirror.css") }}">
16
16
17 {{super()}}
17 {{super()}}
18
18
19 <link rel="stylesheet" href="{{ static_url("notebook/css/override.css") }}" type="text/css" />
19 <link rel="stylesheet" href="{{ static_url("notebook/css/override.css") }}" type="text/css" />
20
20
21 {% endblock %}
21 {% endblock %}
22
22
23 {% block params %}
23 {% block params %}
24
24
25 data-project="{{project}}"
25 data-project="{{project}}"
26 data-base-url="{{base_url}}"
26 data-base-url="{{base_url}}"
27 data-ws-url="{{ws_url}}"
27 data-ws-url="{{ws_url}}"
28 data-notebook-name="{{notebook_name}}"
28 data-notebook-name="{{notebook_name}}"
29 data-notebook-path="{{notebook_path}}"
29 data-notebook-path="{{notebook_path}}"
30 class="notebook_app"
30 class="notebook_app"
31
31
32 {% endblock %}
32 {% endblock %}
33
33
34
34
35 {% block header %}
35 {% block header %}
36
36
37
37
38 <span id="save_widget" class="nav pull-left">
38 <span id="save_widget" class="nav pull-left">
39 <span id="notebook_name"></span>
39 <span id="notebook_name"></span>
40 <span id="checkpoint_status"></span>
40 <span id="checkpoint_status"></span>
41 <span id="autosave_status"></span>
41 <span id="autosave_status"></span>
42 </span>
42 </span>
43
43
44 <span id="kernel_selector_widget" class="pull-right dropdown">
44 <span id="kernel_selector_widget" class="pull-right dropdown">
45 <button class="dropdown-toggle" data-toggle="dropdown" type='button' id="current_kernel_spec">
45 <button class="dropdown-toggle" data-toggle="dropdown" type='button' id="current_kernel_spec">
46 <span class='kernel_name'>Python</span>
46 <span class='kernel_name'>Python</span>
47 <span class="caret"></span>
47 <span class="caret"></span>
48 </button>
48 </button>
49 <ul id="kernel_selector" class="dropdown-menu">
49 <ul id="kernel_selector" class="dropdown-menu">
50 </ul>
50 </ul>
51 </span>
51 </span>
52
52
53 {% endblock %}
53 {% endblock %}
54
54
55
55
56 {% block site %}
56 {% block site %}
57
57
58 <div id="menubar-container" class="container">
58 <div id="menubar-container" class="container">
59 <div id="menubar">
59 <div id="menubar">
60 <div id="menus" class="navbar navbar-default" role="navigation">
60 <div id="menus" class="navbar navbar-default" role="navigation">
61 <div class="container-fluid">
61 <div class="container-fluid">
62 <button type="button" class="btn btn-default navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
62 <button type="button" class="btn btn-default navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
63 <i class="fa fa-bars"></i>
63 <i class="fa fa-bars"></i>
64 <span class="navbar-text">Menu</span>
64 <span class="navbar-text">Menu</span>
65 </button>
65 </button>
66 <ul class="nav navbar-nav navbar-right">
66 <ul class="nav navbar-nav navbar-right">
67 <li id="kernel_indicator">
67 <li id="kernel_indicator">
68 <i id="kernel_indicator_icon"></i>
68 <i id="kernel_indicator_icon"></i>
69 </li>
69 </li>
70 <li id="modal_indicator">
70 <li id="modal_indicator">
71 <i id="modal_indicator_icon"></i>
71 <i id="modal_indicator_icon"></i>
72 </li>
72 </li>
73 <li id="notification_area"></li>
73 <li id="notification_area"></li>
74 </ul>
74 </ul>
75 <div class="navbar-collapse collapse">
75 <div class="navbar-collapse collapse">
76 <ul class="nav navbar-nav">
76 <ul class="nav navbar-nav">
77 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">File</a>
77 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">File</a>
78 <ul id="file_menu" class="dropdown-menu">
78 <ul id="file_menu" class="dropdown-menu">
79 <li id="new_notebook"
79 <li id="new_notebook"
80 title="Make a new notebook (Opens a new window)">
80 title="Make a new notebook (Opens a new window)">
81 <a href="#">New</a></li>
81 <a href="#">New</a></li>
82 <li id="open_notebook"
82 <li id="open_notebook"
83 title="Opens a new window with the Dashboard view">
83 title="Opens a new window with the Dashboard view">
84 <a href="#">Open...</a></li>
84 <a href="#">Open...</a></li>
85 <!-- <hr/> -->
85 <!-- <hr/> -->
86 <li class="divider"></li>
86 <li class="divider"></li>
87 <li id="copy_notebook"
87 <li id="copy_notebook"
88 title="Open a copy of this notebook's contents and start a new kernel">
88 title="Open a copy of this notebook's contents and start a new kernel">
89 <a href="#">Make a Copy...</a></li>
89 <a href="#">Make a Copy...</a></li>
90 <li id="rename_notebook"><a href="#">Rename...</a></li>
90 <li id="rename_notebook"><a href="#">Rename...</a></li>
91 <li id="save_checkpoint"><a href="#">Save and Checkpoint</a></li>
91 <li id="save_checkpoint"><a href="#">Save and Checkpoint</a></li>
92 <!-- <hr/> -->
92 <!-- <hr/> -->
93 <li class="divider"></li>
93 <li class="divider"></li>
94 <li id="restore_checkpoint" class="dropdown-submenu"><a href="#">Revert to Checkpoint</a>
94 <li id="restore_checkpoint" class="dropdown-submenu"><a href="#">Revert to Checkpoint</a>
95 <ul class="dropdown-menu">
95 <ul class="dropdown-menu">
96 <li><a href="#"></a></li>
96 <li><a href="#"></a></li>
97 <li><a href="#"></a></li>
97 <li><a href="#"></a></li>
98 <li><a href="#"></a></li>
98 <li><a href="#"></a></li>
99 <li><a href="#"></a></li>
99 <li><a href="#"></a></li>
100 <li><a href="#"></a></li>
100 <li><a href="#"></a></li>
101 </ul>
101 </ul>
102 </li>
102 </li>
103 <li class="divider"></li>
103 <li class="divider"></li>
104 <li id="print_preview"><a href="#">Print Preview</a></li>
104 <li id="print_preview"><a href="#">Print Preview</a></li>
105 <li class="dropdown-submenu"><a href="#">Download as</a>
105 <li class="dropdown-submenu"><a href="#">Download as</a>
106 <ul class="dropdown-menu">
106 <ul class="dropdown-menu">
107 <li id="download_ipynb"><a href="#">IPython Notebook (.ipynb)</a></li>
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 <li id="download_html"><a href="#">HTML (.html)</a></li>
109 <li id="download_html"><a href="#">HTML (.html)</a></li>
110 <li id="download_rst"><a href="#">reST (.rst)</a></li>
110 <li id="download_rst"><a href="#">reST (.rst)</a></li>
111 <li id="download_pdf"><a href="#">PDF (.pdf)</a></li>
111 <li id="download_pdf"><a href="#">PDF (.pdf)</a></li>
112 </ul>
112 </ul>
113 </li>
113 </li>
114 <li class="divider"></li>
114 <li class="divider"></li>
115 <li id="trust_notebook"
115 <li id="trust_notebook"
116 title="Trust the output of this notebook">
116 title="Trust the output of this notebook">
117 <a href="#" >Trust Notebook</a></li>
117 <a href="#" >Trust Notebook</a></li>
118 <li class="divider"></li>
118 <li class="divider"></li>
119 <li id="kill_and_exit"
119 <li id="kill_and_exit"
120 title="Shutdown this notebook's kernel, and close this window">
120 title="Shutdown this notebook's kernel, and close this window">
121 <a href="#" >Close and halt</a></li>
121 <a href="#" >Close and halt</a></li>
122 </ul>
122 </ul>
123 </li>
123 </li>
124 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Edit</a>
124 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Edit</a>
125 <ul id="edit_menu" class="dropdown-menu">
125 <ul id="edit_menu" class="dropdown-menu">
126 <li id="cut_cell"><a href="#">Cut Cell</a></li>
126 <li id="cut_cell"><a href="#">Cut Cell</a></li>
127 <li id="copy_cell"><a href="#">Copy Cell</a></li>
127 <li id="copy_cell"><a href="#">Copy Cell</a></li>
128 <li id="paste_cell_above" class="disabled"><a href="#">Paste Cell Above</a></li>
128 <li id="paste_cell_above" class="disabled"><a href="#">Paste Cell Above</a></li>
129 <li id="paste_cell_below" class="disabled"><a href="#">Paste Cell Below</a></li>
129 <li id="paste_cell_below" class="disabled"><a href="#">Paste Cell Below</a></li>
130 <li id="paste_cell_replace" class="disabled"><a href="#">Paste Cell &amp; Replace</a></li>
130 <li id="paste_cell_replace" class="disabled"><a href="#">Paste Cell &amp; Replace</a></li>
131 <li id="delete_cell"><a href="#">Delete Cell</a></li>
131 <li id="delete_cell"><a href="#">Delete Cell</a></li>
132 <li id="undelete_cell" class="disabled"><a href="#">Undo Delete Cell</a></li>
132 <li id="undelete_cell" class="disabled"><a href="#">Undo Delete Cell</a></li>
133 <li class="divider"></li>
133 <li class="divider"></li>
134 <li id="split_cell"><a href="#">Split Cell</a></li>
134 <li id="split_cell"><a href="#">Split Cell</a></li>
135 <li id="merge_cell_above"><a href="#">Merge Cell Above</a></li>
135 <li id="merge_cell_above"><a href="#">Merge Cell Above</a></li>
136 <li id="merge_cell_below"><a href="#">Merge Cell Below</a></li>
136 <li id="merge_cell_below"><a href="#">Merge Cell Below</a></li>
137 <li class="divider"></li>
137 <li class="divider"></li>
138 <li id="move_cell_up"><a href="#">Move Cell Up</a></li>
138 <li id="move_cell_up"><a href="#">Move Cell Up</a></li>
139 <li id="move_cell_down"><a href="#">Move Cell Down</a></li>
139 <li id="move_cell_down"><a href="#">Move Cell Down</a></li>
140 <li class="divider"></li>
140 <li class="divider"></li>
141 <li id="edit_nb_metadata"><a href="#">Edit Notebook Metadata</a></li>
141 <li id="edit_nb_metadata"><a href="#">Edit Notebook Metadata</a></li>
142 </ul>
142 </ul>
143 </li>
143 </li>
144 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">View</a>
144 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">View</a>
145 <ul id="view_menu" class="dropdown-menu">
145 <ul id="view_menu" class="dropdown-menu">
146 <li id="toggle_header"
146 <li id="toggle_header"
147 title="Show/Hide the IPython Notebook logo and notebook title (above menu bar)">
147 title="Show/Hide the IPython Notebook logo and notebook title (above menu bar)">
148 <a href="#">Toggle Header</a></li>
148 <a href="#">Toggle Header</a></li>
149 <li id="toggle_toolbar"
149 <li id="toggle_toolbar"
150 title="Show/Hide the action icons (below menu bar)">
150 title="Show/Hide the action icons (below menu bar)">
151 <a href="#">Toggle Toolbar</a></li>
151 <a href="#">Toggle Toolbar</a></li>
152 </ul>
152 </ul>
153 </li>
153 </li>
154 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Insert</a>
154 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Insert</a>
155 <ul id="insert_menu" class="dropdown-menu">
155 <ul id="insert_menu" class="dropdown-menu">
156 <li id="insert_cell_above"
156 <li id="insert_cell_above"
157 title="Insert an empty Code cell above the currently active cell">
157 title="Insert an empty Code cell above the currently active cell">
158 <a href="#">Insert Cell Above</a></li>
158 <a href="#">Insert Cell Above</a></li>
159 <li id="insert_cell_below"
159 <li id="insert_cell_below"
160 title="Insert an empty Code cell below the currently active cell">
160 title="Insert an empty Code cell below the currently active cell">
161 <a href="#">Insert Cell Below</a></li>
161 <a href="#">Insert Cell Below</a></li>
162 </ul>
162 </ul>
163 </li>
163 </li>
164 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Cell</a>
164 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Cell</a>
165 <ul id="cell_menu" class="dropdown-menu">
165 <ul id="cell_menu" class="dropdown-menu">
166 <li id="run_cell" title="Run this cell, and move cursor to the next one">
166 <li id="run_cell" title="Run this cell, and move cursor to the next one">
167 <a href="#">Run</a></li>
167 <a href="#">Run</a></li>
168 <li id="run_cell_select_below" title="Run this cell, select below">
168 <li id="run_cell_select_below" title="Run this cell, select below">
169 <a href="#">Run and Select Below</a></li>
169 <a href="#">Run and Select Below</a></li>
170 <li id="run_cell_insert_below" title="Run this cell, insert below">
170 <li id="run_cell_insert_below" title="Run this cell, insert below">
171 <a href="#">Run and Insert Below</a></li>
171 <a href="#">Run and Insert Below</a></li>
172 <li id="run_all_cells" title="Run all cells in the notebook">
172 <li id="run_all_cells" title="Run all cells in the notebook">
173 <a href="#">Run All</a></li>
173 <a href="#">Run All</a></li>
174 <li id="run_all_cells_above" title="Run all cells above (but not including) this cell">
174 <li id="run_all_cells_above" title="Run all cells above (but not including) this cell">
175 <a href="#">Run All Above</a></li>
175 <a href="#">Run All Above</a></li>
176 <li id="run_all_cells_below" title="Run this cell and all cells below it">
176 <li id="run_all_cells_below" title="Run this cell and all cells below it">
177 <a href="#">Run All Below</a></li>
177 <a href="#">Run All Below</a></li>
178 <li class="divider"></li>
178 <li class="divider"></li>
179 <li id="change_cell_type" class="dropdown-submenu"
179 <li id="change_cell_type" class="dropdown-submenu"
180 title="All cells in the notebook have a cell type. By default, new cells are created as 'Code' cells">
180 title="All cells in the notebook have a cell type. By default, new cells are created as 'Code' cells">
181 <a href="#">Cell Type</a>
181 <a href="#">Cell Type</a>
182 <ul class="dropdown-menu">
182 <ul class="dropdown-menu">
183 <li id="to_code"
183 <li id="to_code"
184 title="Contents will be sent to the kernel for execution, and output will display in the footer of cell">
184 title="Contents will be sent to the kernel for execution, and output will display in the footer of cell">
185 <a href="#">Code</a></li>
185 <a href="#">Code</a></li>
186 <li id="to_markdown"
186 <li id="to_markdown"
187 title="Contents will be rendered as HTML and serve as explanatory text">
187 title="Contents will be rendered as HTML and serve as explanatory text">
188 <a href="#">Markdown</a></li>
188 <a href="#">Markdown</a></li>
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 </ul>
192 </ul>
193 </li>
193 </li>
194 <li class="divider"></li>
194 <li class="divider"></li>
195 <li id="current_outputs" class="dropdown-submenu"><a href="#">Current Output</a>
195 <li id="current_outputs" class="dropdown-submenu"><a href="#">Current Output</a>
196 <ul class="dropdown-menu">
196 <ul class="dropdown-menu">
197 <li id="toggle_current_output"
197 <li id="toggle_current_output"
198 title="Hide/Show the output of the current cell">
198 title="Hide/Show the output of the current cell">
199 <a href="#">Toggle</a>
199 <a href="#">Toggle</a>
200 </li>
200 </li>
201 <li id="toggle_current_output_scroll"
201 <li id="toggle_current_output_scroll"
202 title="Scroll the output of the current cell">
202 title="Scroll the output of the current cell">
203 <a href="#">Toggle Scrolling</a>
203 <a href="#">Toggle Scrolling</a>
204 </li>
204 </li>
205 <li id="clear_current_output"
205 <li id="clear_current_output"
206 title="Clear the output of the current cell">
206 title="Clear the output of the current cell">
207 <a href="#">Clear</a>
207 <a href="#">Clear</a>
208 </li>
208 </li>
209 </ul>
209 </ul>
210 </li>
210 </li>
211 <li id="all_outputs" class="dropdown-submenu"><a href="#">All Output</a>
211 <li id="all_outputs" class="dropdown-submenu"><a href="#">All Output</a>
212 <ul class="dropdown-menu">
212 <ul class="dropdown-menu">
213 <li id="toggle_all_output"
213 <li id="toggle_all_output"
214 title="Hide/Show the output of all cells">
214 title="Hide/Show the output of all cells">
215 <a href="#">Toggle</a>
215 <a href="#">Toggle</a>
216 </li>
216 </li>
217 <li id="toggle_all_output_scroll"
217 <li id="toggle_all_output_scroll"
218 title="Scroll the output of all cells">
218 title="Scroll the output of all cells">
219 <a href="#">Toggle Scrolling</a>
219 <a href="#">Toggle Scrolling</a>
220 </li>
220 </li>
221 <li id="clear_all_output"
221 <li id="clear_all_output"
222 title="Clear the output of all cells">
222 title="Clear the output of all cells">
223 <a href="#">Clear</a>
223 <a href="#">Clear</a>
224 </li>
224 </li>
225 </ul>
225 </ul>
226 </li>
226 </li>
227 </ul>
227 </ul>
228 </li>
228 </li>
229 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Kernel</a>
229 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Kernel</a>
230 <ul id="kernel_menu" class="dropdown-menu">
230 <ul id="kernel_menu" class="dropdown-menu">
231 <li id="int_kernel"
231 <li id="int_kernel"
232 title="Send KeyboardInterrupt (CTRL-C) to the Kernel">
232 title="Send KeyboardInterrupt (CTRL-C) to the Kernel">
233 <a href="#">Interrupt</a>
233 <a href="#">Interrupt</a>
234 </li>
234 </li>
235 <li id="restart_kernel"
235 <li id="restart_kernel"
236 title="Restart the Kernel">
236 title="Restart the Kernel">
237 <a href="#">Restart</a>
237 <a href="#">Restart</a>
238 </li>
238 </li>
239 <li id="reconnect_kernel"
239 <li id="reconnect_kernel"
240 title="Reconnect to the Kernel">
240 title="Reconnect to the Kernel">
241 <a href="#">Reconnect</a>
241 <a href="#">Reconnect</a>
242 </li>
242 </li>
243 <li class="divider"></li>
243 <li class="divider"></li>
244 <li id="menu-change-kernel" class="dropdown-submenu">
244 <li id="menu-change-kernel" class="dropdown-submenu">
245 <a href="#">Change kernel</a>
245 <a href="#">Change kernel</a>
246 <ul class="dropdown-menu" id="menu-change-kernel-submenu"></ul>
246 <ul class="dropdown-menu" id="menu-change-kernel-submenu"></ul>
247 </li>
247 </li>
248 </ul>
248 </ul>
249 </li>
249 </li>
250 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Help</a>
250 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Help</a>
251 <ul id="help_menu" class="dropdown-menu">
251 <ul id="help_menu" class="dropdown-menu">
252 <li id="notebook_tour" title="A quick tour of the notebook user interface"><a href="#">User Interface Tour</a></li>
252 <li id="notebook_tour" title="A quick tour of the notebook user interface"><a href="#">User Interface Tour</a></li>
253 <li id="keyboard_shortcuts" title="Opens a tooltip with all keyboard shortcuts"><a href="#">Keyboard Shortcuts</a></li>
253 <li id="keyboard_shortcuts" title="Opens a tooltip with all keyboard shortcuts"><a href="#">Keyboard Shortcuts</a></li>
254 <li class="divider"></li>
254 <li class="divider"></li>
255 {% set
255 {% set
256 sections = (
256 sections = (
257 (
257 (
258 ("http://ipython.org/documentation.html","IPython Help",True),
258 ("http://ipython.org/documentation.html","IPython Help",True),
259 ("http://nbviewer.ipython.org/github/ipython/ipython/tree/2.x/examples/Index.ipynb", "Notebook Help", True),
259 ("http://nbviewer.ipython.org/github/ipython/ipython/tree/2.x/examples/Index.ipynb", "Notebook Help", True),
260 ),(
260 ),(
261 ("http://docs.python.org","Python",True),
261 ("http://docs.python.org","Python",True),
262 ("http://help.github.com/articles/github-flavored-markdown","Markdown",True),
262 ("http://help.github.com/articles/github-flavored-markdown","Markdown",True),
263 ("http://docs.scipy.org/doc/numpy/reference/","NumPy",True),
263 ("http://docs.scipy.org/doc/numpy/reference/","NumPy",True),
264 ("http://docs.scipy.org/doc/scipy/reference/","SciPy",True),
264 ("http://docs.scipy.org/doc/scipy/reference/","SciPy",True),
265 ("http://matplotlib.org/contents.html","Matplotlib",True),
265 ("http://matplotlib.org/contents.html","Matplotlib",True),
266 ("http://docs.sympy.org/latest/index.html","SymPy",True),
266 ("http://docs.sympy.org/latest/index.html","SymPy",True),
267 ("http://pandas.pydata.org/pandas-docs/stable/","pandas", True)
267 ("http://pandas.pydata.org/pandas-docs/stable/","pandas", True)
268 )
268 )
269 )
269 )
270 %}
270 %}
271
271
272 {% for helplinks in sections %}
272 {% for helplinks in sections %}
273 {% for link in helplinks %}
273 {% for link in helplinks %}
274 <li><a href="{{link[0]}}" {{'target="_blank" title="Opens in a new window"' if link[2]}}>
274 <li><a href="{{link[0]}}" {{'target="_blank" title="Opens in a new window"' if link[2]}}>
275 {{'<i class="fa fa-external-link menu-icon pull-right"></i>' if link[2]}}
275 {{'<i class="fa fa-external-link menu-icon pull-right"></i>' if link[2]}}
276 {{link[1]}}
276 {{link[1]}}
277 </a></li>
277 </a></li>
278 {% endfor %}
278 {% endfor %}
279 {% if not loop.last %}
279 {% if not loop.last %}
280 <li class="divider"></li>
280 <li class="divider"></li>
281 {% endif %}
281 {% endif %}
282 {% endfor %}
282 {% endfor %}
283 <li class="divider"></li>
283 <li class="divider"></li>
284 <li title="About IPython Notebook"><a id="notebook_about" href="#">About</a></li>
284 <li title="About IPython Notebook"><a id="notebook_about" href="#">About</a></li>
285 </ul>
285 </ul>
286 </li>
286 </li>
287 </ul>
287 </ul>
288 </div>
288 </div>
289 </div>
289 </div>
290 </div>
290 </div>
291 </div>
291 </div>
292 <div id="maintoolbar" class="navbar">
292 <div id="maintoolbar" class="navbar">
293 <div class="toolbar-inner navbar-inner navbar-nobg">
293 <div class="toolbar-inner navbar-inner navbar-nobg">
294 <div id="maintoolbar-container" class="container"></div>
294 <div id="maintoolbar-container" class="container"></div>
295 </div>
295 </div>
296 </div>
296 </div>
297 </div>
297 </div>
298
298
299 <div id="ipython-main-app">
299 <div id="ipython-main-app">
300
300
301 <div id="notebook_panel">
301 <div id="notebook_panel">
302 <div id="notebook"></div>
302 <div id="notebook"></div>
303 <div id="pager_splitter"></div>
303 <div id="pager_splitter"></div>
304 <div id="pager">
304 <div id="pager">
305 <div id='pager_button_area'>
305 <div id='pager_button_area'>
306 </div>
306 </div>
307 <div id="pager-container" class="container"></div>
307 <div id="pager-container" class="container"></div>
308 </div>
308 </div>
309 </div>
309 </div>
310
310
311 </div>
311 </div>
312 <div id='tooltip' class='ipython_tooltip' style='display:none'></div>
312 <div id='tooltip' class='ipython_tooltip' style='display:none'></div>
313
313
314
314
315 {% endblock %}
315 {% endblock %}
316
316
317
317
318 {% block script %}
318 {% block script %}
319 {{super()}}
319 {{super()}}
320 <script type="text/javascript">
320 <script type="text/javascript">
321 sys_info = {{sys_info}};
321 sys_info = {{sys_info}};
322 </script>
322 </script>
323
323
324 <script src="{{ static_url("components/text-encoding/lib/encoding.js") }}" charset="utf-8"></script>
324 <script src="{{ static_url("components/text-encoding/lib/encoding.js") }}" charset="utf-8"></script>
325
325
326 <script src="{{ static_url("notebook/js/main.js") }}" charset="utf-8"></script>
326 <script src="{{ static_url("notebook/js/main.js") }}" charset="utf-8"></script>
327
327
328 {% endblock %}
328 {% endblock %}
@@ -1,328 +1,330 b''
1 """The IPython kernel implementation"""
1 """The IPython kernel implementation"""
2
2
3 import getpass
3 import getpass
4 import sys
4 import sys
5 import traceback
5 import traceback
6
6
7 from IPython.core import release
7 from IPython.core import release
8 from IPython.html.widgets import Widget
8 from IPython.html.widgets import Widget
9 from IPython.utils.py3compat import builtin_mod, PY3
9 from IPython.utils.py3compat import builtin_mod, PY3
10 from IPython.utils.tokenutil import token_at_cursor, line_at_cursor
10 from IPython.utils.tokenutil import token_at_cursor, line_at_cursor
11 from IPython.utils.traitlets import Instance, Type, Any
11 from IPython.utils.traitlets import Instance, Type, Any
12 from IPython.utils.decorators import undoc
12 from IPython.utils.decorators import undoc
13
13
14 from ..comm import CommManager
14 from ..comm import CommManager
15 from .kernelbase import Kernel as KernelBase
15 from .kernelbase import Kernel as KernelBase
16 from .serialize import serialize_object, unpack_apply_message
16 from .serialize import serialize_object, unpack_apply_message
17 from .zmqshell import ZMQInteractiveShell
17 from .zmqshell import ZMQInteractiveShell
18
18
19 class IPythonKernel(KernelBase):
19 class IPythonKernel(KernelBase):
20 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
20 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
21 shell_class = Type(ZMQInteractiveShell)
21 shell_class = Type(ZMQInteractiveShell)
22
22
23 user_module = Any()
23 user_module = Any()
24 def _user_module_changed(self, name, old, new):
24 def _user_module_changed(self, name, old, new):
25 if self.shell is not None:
25 if self.shell is not None:
26 self.shell.user_module = new
26 self.shell.user_module = new
27
27
28 user_ns = Instance(dict, args=None, allow_none=True)
28 user_ns = Instance(dict, args=None, allow_none=True)
29 def _user_ns_changed(self, name, old, new):
29 def _user_ns_changed(self, name, old, new):
30 if self.shell is not None:
30 if self.shell is not None:
31 self.shell.user_ns = new
31 self.shell.user_ns = new
32 self.shell.init_user_ns()
32 self.shell.init_user_ns()
33
33
34 # A reference to the Python builtin 'raw_input' function.
34 # A reference to the Python builtin 'raw_input' function.
35 # (i.e., __builtin__.raw_input for Python 2.7, builtins.input for Python 3)
35 # (i.e., __builtin__.raw_input for Python 2.7, builtins.input for Python 3)
36 _sys_raw_input = Any()
36 _sys_raw_input = Any()
37 _sys_eval_input = Any()
37 _sys_eval_input = Any()
38
38
39 def __init__(self, **kwargs):
39 def __init__(self, **kwargs):
40 super(IPythonKernel, self).__init__(**kwargs)
40 super(IPythonKernel, self).__init__(**kwargs)
41
41
42 # Initialize the InteractiveShell subclass
42 # Initialize the InteractiveShell subclass
43 self.shell = self.shell_class.instance(parent=self,
43 self.shell = self.shell_class.instance(parent=self,
44 profile_dir = self.profile_dir,
44 profile_dir = self.profile_dir,
45 user_module = self.user_module,
45 user_module = self.user_module,
46 user_ns = self.user_ns,
46 user_ns = self.user_ns,
47 kernel = self,
47 kernel = self,
48 )
48 )
49 self.shell.displayhook.session = self.session
49 self.shell.displayhook.session = self.session
50 self.shell.displayhook.pub_socket = self.iopub_socket
50 self.shell.displayhook.pub_socket = self.iopub_socket
51 self.shell.displayhook.topic = self._topic('execute_result')
51 self.shell.displayhook.topic = self._topic('execute_result')
52 self.shell.display_pub.session = self.session
52 self.shell.display_pub.session = self.session
53 self.shell.display_pub.pub_socket = self.iopub_socket
53 self.shell.display_pub.pub_socket = self.iopub_socket
54 self.shell.data_pub.session = self.session
54 self.shell.data_pub.session = self.session
55 self.shell.data_pub.pub_socket = self.iopub_socket
55 self.shell.data_pub.pub_socket = self.iopub_socket
56
56
57 # TMP - hack while developing
57 # TMP - hack while developing
58 self.shell._reply_content = None
58 self.shell._reply_content = None
59
59
60 self.comm_manager = CommManager(shell=self.shell, parent=self,
60 self.comm_manager = CommManager(shell=self.shell, parent=self,
61 kernel=self)
61 kernel=self)
62 self.comm_manager.register_target('ipython.widget', Widget.handle_comm_opened)
62 self.comm_manager.register_target('ipython.widget', Widget.handle_comm_opened)
63
63
64 self.shell.configurables.append(self.comm_manager)
64 self.shell.configurables.append(self.comm_manager)
65 comm_msg_types = [ 'comm_open', 'comm_msg', 'comm_close' ]
65 comm_msg_types = [ 'comm_open', 'comm_msg', 'comm_close' ]
66 for msg_type in comm_msg_types:
66 for msg_type in comm_msg_types:
67 self.shell_handlers[msg_type] = getattr(self.comm_manager, msg_type)
67 self.shell_handlers[msg_type] = getattr(self.comm_manager, msg_type)
68
68
69 # Kernel info fields
69 # Kernel info fields
70 implementation = 'ipython'
70 implementation = 'ipython'
71 implementation_version = release.version
71 implementation_version = release.version
72 language = 'python'
72 language = 'python'
73 language_version = sys.version.split()[0]
73 language_version = sys.version.split()[0]
74 language_info = {'mimetype': 'text/x-python',
74 language_info = {'mimetype': 'text/x-python',
75 'codemirror_mode': {'name': 'ipython',
75 'codemirror_mode': {'name': 'ipython',
76 'version': sys.version_info[0]},
76 'version': sys.version_info[0]},
77 'pygments_lexer': 'ipython%d' % (3 if PY3 else 2),
77 'pygments_lexer': 'ipython%d' % (3 if PY3 else 2),
78 'nbconvert_exporter': 'python',
79 'file_extension': 'py'
78 }
80 }
79 @property
81 @property
80 def banner(self):
82 def banner(self):
81 return self.shell.banner
83 return self.shell.banner
82
84
83 def start(self):
85 def start(self):
84 self.shell.exit_now = False
86 self.shell.exit_now = False
85 super(IPythonKernel, self).start()
87 super(IPythonKernel, self).start()
86
88
87 def set_parent(self, ident, parent):
89 def set_parent(self, ident, parent):
88 """Overridden from parent to tell the display hook and output streams
90 """Overridden from parent to tell the display hook and output streams
89 about the parent message.
91 about the parent message.
90 """
92 """
91 super(IPythonKernel, self).set_parent(ident, parent)
93 super(IPythonKernel, self).set_parent(ident, parent)
92 self.shell.set_parent(parent)
94 self.shell.set_parent(parent)
93
95
94 def _forward_input(self, allow_stdin=False):
96 def _forward_input(self, allow_stdin=False):
95 """Forward raw_input and getpass to the current frontend.
97 """Forward raw_input and getpass to the current frontend.
96
98
97 via input_request
99 via input_request
98 """
100 """
99 self._allow_stdin = allow_stdin
101 self._allow_stdin = allow_stdin
100
102
101 if PY3:
103 if PY3:
102 self._sys_raw_input = builtin_mod.input
104 self._sys_raw_input = builtin_mod.input
103 builtin_mod.input = self.raw_input
105 builtin_mod.input = self.raw_input
104 else:
106 else:
105 self._sys_raw_input = builtin_mod.raw_input
107 self._sys_raw_input = builtin_mod.raw_input
106 self._sys_eval_input = builtin_mod.input
108 self._sys_eval_input = builtin_mod.input
107 builtin_mod.raw_input = self.raw_input
109 builtin_mod.raw_input = self.raw_input
108 builtin_mod.input = lambda prompt='': eval(self.raw_input(prompt))
110 builtin_mod.input = lambda prompt='': eval(self.raw_input(prompt))
109 self._save_getpass = getpass.getpass
111 self._save_getpass = getpass.getpass
110 getpass.getpass = self.getpass
112 getpass.getpass = self.getpass
111
113
112 def _restore_input(self):
114 def _restore_input(self):
113 """Restore raw_input, getpass"""
115 """Restore raw_input, getpass"""
114 if PY3:
116 if PY3:
115 builtin_mod.input = self._sys_raw_input
117 builtin_mod.input = self._sys_raw_input
116 else:
118 else:
117 builtin_mod.raw_input = self._sys_raw_input
119 builtin_mod.raw_input = self._sys_raw_input
118 builtin_mod.input = self._sys_eval_input
120 builtin_mod.input = self._sys_eval_input
119
121
120 getpass.getpass = self._save_getpass
122 getpass.getpass = self._save_getpass
121
123
122 @property
124 @property
123 def execution_count(self):
125 def execution_count(self):
124 return self.shell.execution_count
126 return self.shell.execution_count
125
127
126 @execution_count.setter
128 @execution_count.setter
127 def execution_count(self, value):
129 def execution_count(self, value):
128 # Ignore the incrememnting done by KernelBase, in favour of our shell's
130 # Ignore the incrememnting done by KernelBase, in favour of our shell's
129 # execution counter.
131 # execution counter.
130 pass
132 pass
131
133
132 def do_execute(self, code, silent, store_history=True,
134 def do_execute(self, code, silent, store_history=True,
133 user_expressions=None, allow_stdin=False):
135 user_expressions=None, allow_stdin=False):
134 shell = self.shell # we'll need this a lot here
136 shell = self.shell # we'll need this a lot here
135
137
136 self._forward_input(allow_stdin)
138 self._forward_input(allow_stdin)
137
139
138 reply_content = {}
140 reply_content = {}
139 # FIXME: the shell calls the exception handler itself.
141 # FIXME: the shell calls the exception handler itself.
140 shell._reply_content = None
142 shell._reply_content = None
141 try:
143 try:
142 shell.run_cell(code, store_history=store_history, silent=silent)
144 shell.run_cell(code, store_history=store_history, silent=silent)
143 except:
145 except:
144 status = u'error'
146 status = u'error'
145 # FIXME: this code right now isn't being used yet by default,
147 # FIXME: this code right now isn't being used yet by default,
146 # because the run_cell() call above directly fires off exception
148 # because the run_cell() call above directly fires off exception
147 # reporting. This code, therefore, is only active in the scenario
149 # reporting. This code, therefore, is only active in the scenario
148 # where runlines itself has an unhandled exception. We need to
150 # where runlines itself has an unhandled exception. We need to
149 # uniformize this, for all exception construction to come from a
151 # uniformize this, for all exception construction to come from a
150 # single location in the codbase.
152 # single location in the codbase.
151 etype, evalue, tb = sys.exc_info()
153 etype, evalue, tb = sys.exc_info()
152 tb_list = traceback.format_exception(etype, evalue, tb)
154 tb_list = traceback.format_exception(etype, evalue, tb)
153 reply_content.update(shell._showtraceback(etype, evalue, tb_list))
155 reply_content.update(shell._showtraceback(etype, evalue, tb_list))
154 else:
156 else:
155 status = u'ok'
157 status = u'ok'
156 finally:
158 finally:
157 self._restore_input()
159 self._restore_input()
158
160
159 reply_content[u'status'] = status
161 reply_content[u'status'] = status
160
162
161 # Return the execution counter so clients can display prompts
163 # Return the execution counter so clients can display prompts
162 reply_content['execution_count'] = shell.execution_count - 1
164 reply_content['execution_count'] = shell.execution_count - 1
163
165
164 # FIXME - fish exception info out of shell, possibly left there by
166 # FIXME - fish exception info out of shell, possibly left there by
165 # runlines. We'll need to clean up this logic later.
167 # runlines. We'll need to clean up this logic later.
166 if shell._reply_content is not None:
168 if shell._reply_content is not None:
167 reply_content.update(shell._reply_content)
169 reply_content.update(shell._reply_content)
168 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='execute')
170 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='execute')
169 reply_content['engine_info'] = e_info
171 reply_content['engine_info'] = e_info
170 # reset after use
172 # reset after use
171 shell._reply_content = None
173 shell._reply_content = None
172
174
173 if 'traceback' in reply_content:
175 if 'traceback' in reply_content:
174 self.log.info("Exception in execute request:\n%s", '\n'.join(reply_content['traceback']))
176 self.log.info("Exception in execute request:\n%s", '\n'.join(reply_content['traceback']))
175
177
176
178
177 # At this point, we can tell whether the main code execution succeeded
179 # At this point, we can tell whether the main code execution succeeded
178 # or not. If it did, we proceed to evaluate user_expressions
180 # or not. If it did, we proceed to evaluate user_expressions
179 if reply_content['status'] == 'ok':
181 if reply_content['status'] == 'ok':
180 reply_content[u'user_expressions'] = \
182 reply_content[u'user_expressions'] = \
181 shell.user_expressions(user_expressions or {})
183 shell.user_expressions(user_expressions or {})
182 else:
184 else:
183 # If there was an error, don't even try to compute expressions
185 # If there was an error, don't even try to compute expressions
184 reply_content[u'user_expressions'] = {}
186 reply_content[u'user_expressions'] = {}
185
187
186 # Payloads should be retrieved regardless of outcome, so we can both
188 # Payloads should be retrieved regardless of outcome, so we can both
187 # recover partial output (that could have been generated early in a
189 # recover partial output (that could have been generated early in a
188 # block, before an error) and clear the payload system always.
190 # block, before an error) and clear the payload system always.
189 reply_content[u'payload'] = shell.payload_manager.read_payload()
191 reply_content[u'payload'] = shell.payload_manager.read_payload()
190 # Be agressive about clearing the payload because we don't want
192 # Be agressive about clearing the payload because we don't want
191 # it to sit in memory until the next execute_request comes in.
193 # it to sit in memory until the next execute_request comes in.
192 shell.payload_manager.clear_payload()
194 shell.payload_manager.clear_payload()
193
195
194 return reply_content
196 return reply_content
195
197
196 def do_complete(self, code, cursor_pos):
198 def do_complete(self, code, cursor_pos):
197 # FIXME: IPython completers currently assume single line,
199 # FIXME: IPython completers currently assume single line,
198 # but completion messages give multi-line context
200 # but completion messages give multi-line context
199 # For now, extract line from cell, based on cursor_pos:
201 # For now, extract line from cell, based on cursor_pos:
200 if cursor_pos is None:
202 if cursor_pos is None:
201 cursor_pos = len(code)
203 cursor_pos = len(code)
202 line, offset = line_at_cursor(code, cursor_pos)
204 line, offset = line_at_cursor(code, cursor_pos)
203 line_cursor = cursor_pos - offset
205 line_cursor = cursor_pos - offset
204
206
205 txt, matches = self.shell.complete('', line, line_cursor)
207 txt, matches = self.shell.complete('', line, line_cursor)
206 return {'matches' : matches,
208 return {'matches' : matches,
207 'cursor_end' : cursor_pos,
209 'cursor_end' : cursor_pos,
208 'cursor_start' : cursor_pos - len(txt),
210 'cursor_start' : cursor_pos - len(txt),
209 'metadata' : {},
211 'metadata' : {},
210 'status' : 'ok'}
212 'status' : 'ok'}
211
213
212 def do_inspect(self, code, cursor_pos, detail_level=0):
214 def do_inspect(self, code, cursor_pos, detail_level=0):
213 name = token_at_cursor(code, cursor_pos)
215 name = token_at_cursor(code, cursor_pos)
214 info = self.shell.object_inspect(name)
216 info = self.shell.object_inspect(name)
215
217
216 reply_content = {'status' : 'ok'}
218 reply_content = {'status' : 'ok'}
217 reply_content['data'] = data = {}
219 reply_content['data'] = data = {}
218 reply_content['metadata'] = {}
220 reply_content['metadata'] = {}
219 reply_content['found'] = info['found']
221 reply_content['found'] = info['found']
220 if info['found']:
222 if info['found']:
221 info_text = self.shell.object_inspect_text(
223 info_text = self.shell.object_inspect_text(
222 name,
224 name,
223 detail_level=detail_level,
225 detail_level=detail_level,
224 )
226 )
225 data['text/plain'] = info_text
227 data['text/plain'] = info_text
226
228
227 return reply_content
229 return reply_content
228
230
229 def do_history(self, hist_access_type, output, raw, session=None, start=None,
231 def do_history(self, hist_access_type, output, raw, session=None, start=None,
230 stop=None, n=None, pattern=None, unique=False):
232 stop=None, n=None, pattern=None, unique=False):
231 if hist_access_type == 'tail':
233 if hist_access_type == 'tail':
232 hist = self.shell.history_manager.get_tail(n, raw=raw, output=output,
234 hist = self.shell.history_manager.get_tail(n, raw=raw, output=output,
233 include_latest=True)
235 include_latest=True)
234
236
235 elif hist_access_type == 'range':
237 elif hist_access_type == 'range':
236 hist = self.shell.history_manager.get_range(session, start, stop,
238 hist = self.shell.history_manager.get_range(session, start, stop,
237 raw=raw, output=output)
239 raw=raw, output=output)
238
240
239 elif hist_access_type == 'search':
241 elif hist_access_type == 'search':
240 hist = self.shell.history_manager.search(
242 hist = self.shell.history_manager.search(
241 pattern, raw=raw, output=output, n=n, unique=unique)
243 pattern, raw=raw, output=output, n=n, unique=unique)
242 else:
244 else:
243 hist = []
245 hist = []
244
246
245 return {'history' : list(hist)}
247 return {'history' : list(hist)}
246
248
247 def do_shutdown(self, restart):
249 def do_shutdown(self, restart):
248 self.shell.exit_now = True
250 self.shell.exit_now = True
249 return dict(status='ok', restart=restart)
251 return dict(status='ok', restart=restart)
250
252
251 def do_is_complete(self, code):
253 def do_is_complete(self, code):
252 status, indent_spaces = self.shell.input_transformer_manager.check_complete(code)
254 status, indent_spaces = self.shell.input_transformer_manager.check_complete(code)
253 r = {'status': status}
255 r = {'status': status}
254 if status == 'incomplete':
256 if status == 'incomplete':
255 r['indent'] = ' ' * indent_spaces
257 r['indent'] = ' ' * indent_spaces
256 return r
258 return r
257
259
258 def do_apply(self, content, bufs, msg_id, reply_metadata):
260 def do_apply(self, content, bufs, msg_id, reply_metadata):
259 shell = self.shell
261 shell = self.shell
260 try:
262 try:
261 working = shell.user_ns
263 working = shell.user_ns
262
264
263 prefix = "_"+str(msg_id).replace("-","")+"_"
265 prefix = "_"+str(msg_id).replace("-","")+"_"
264
266
265 f,args,kwargs = unpack_apply_message(bufs, working, copy=False)
267 f,args,kwargs = unpack_apply_message(bufs, working, copy=False)
266
268
267 fname = getattr(f, '__name__', 'f')
269 fname = getattr(f, '__name__', 'f')
268
270
269 fname = prefix+"f"
271 fname = prefix+"f"
270 argname = prefix+"args"
272 argname = prefix+"args"
271 kwargname = prefix+"kwargs"
273 kwargname = prefix+"kwargs"
272 resultname = prefix+"result"
274 resultname = prefix+"result"
273
275
274 ns = { fname : f, argname : args, kwargname : kwargs , resultname : None }
276 ns = { fname : f, argname : args, kwargname : kwargs , resultname : None }
275 # print ns
277 # print ns
276 working.update(ns)
278 working.update(ns)
277 code = "%s = %s(*%s,**%s)" % (resultname, fname, argname, kwargname)
279 code = "%s = %s(*%s,**%s)" % (resultname, fname, argname, kwargname)
278 try:
280 try:
279 exec(code, shell.user_global_ns, shell.user_ns)
281 exec(code, shell.user_global_ns, shell.user_ns)
280 result = working.get(resultname)
282 result = working.get(resultname)
281 finally:
283 finally:
282 for key in ns:
284 for key in ns:
283 working.pop(key)
285 working.pop(key)
284
286
285 result_buf = serialize_object(result,
287 result_buf = serialize_object(result,
286 buffer_threshold=self.session.buffer_threshold,
288 buffer_threshold=self.session.buffer_threshold,
287 item_threshold=self.session.item_threshold,
289 item_threshold=self.session.item_threshold,
288 )
290 )
289
291
290 except:
292 except:
291 # invoke IPython traceback formatting
293 # invoke IPython traceback formatting
292 shell.showtraceback()
294 shell.showtraceback()
293 # FIXME - fish exception info out of shell, possibly left there by
295 # FIXME - fish exception info out of shell, possibly left there by
294 # run_code. We'll need to clean up this logic later.
296 # run_code. We'll need to clean up this logic later.
295 reply_content = {}
297 reply_content = {}
296 if shell._reply_content is not None:
298 if shell._reply_content is not None:
297 reply_content.update(shell._reply_content)
299 reply_content.update(shell._reply_content)
298 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='apply')
300 e_info = dict(engine_uuid=self.ident, engine_id=self.int_id, method='apply')
299 reply_content['engine_info'] = e_info
301 reply_content['engine_info'] = e_info
300 # reset after use
302 # reset after use
301 shell._reply_content = None
303 shell._reply_content = None
302
304
303 self.send_response(self.iopub_socket, u'error', reply_content,
305 self.send_response(self.iopub_socket, u'error', reply_content,
304 ident=self._topic('error'))
306 ident=self._topic('error'))
305 self.log.info("Exception in apply request:\n%s", '\n'.join(reply_content['traceback']))
307 self.log.info("Exception in apply request:\n%s", '\n'.join(reply_content['traceback']))
306 result_buf = []
308 result_buf = []
307
309
308 if reply_content['ename'] == 'UnmetDependency':
310 if reply_content['ename'] == 'UnmetDependency':
309 reply_metadata['dependencies_met'] = False
311 reply_metadata['dependencies_met'] = False
310 else:
312 else:
311 reply_content = {'status' : 'ok'}
313 reply_content = {'status' : 'ok'}
312
314
313 return reply_content, result_buf
315 return reply_content, result_buf
314
316
315 def do_clear(self):
317 def do_clear(self):
316 self.shell.reset(False)
318 self.shell.reset(False)
317 return dict(status='ok')
319 return dict(status='ok')
318
320
319
321
320 # This exists only for backwards compatibility - use IPythonKernel instead
322 # This exists only for backwards compatibility - use IPythonKernel instead
321
323
322 @undoc
324 @undoc
323 class Kernel(IPythonKernel):
325 class Kernel(IPythonKernel):
324 def __init__(self, *args, **kwargs):
326 def __init__(self, *args, **kwargs):
325 import warnings
327 import warnings
326 warnings.warn('Kernel is a deprecated alias of IPython.kernel.zmq.ipkernel.IPythonKernel',
328 warnings.warn('Kernel is a deprecated alias of IPython.kernel.zmq.ipkernel.IPythonKernel',
327 DeprecationWarning)
329 DeprecationWarning)
328 super(Kernel, self).__init__(*args, **kwargs) No newline at end of file
330 super(Kernel, self).__init__(*args, **kwargs)
General Comments 0
You need to be logged in to leave comments. Login now