##// END OF EJS Templates
Heading/plaintext cells now wired up to toolbar UI.
Brian Granger -
Show More
@@ -1,1260 +1,1265 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // Notebook
9 // Notebook
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var utils = IPython.utils;
14 var utils = IPython.utils;
15
15
16 var Notebook = function (selector) {
16 var Notebook = function (selector) {
17 this.read_only = IPython.read_only;
17 this.read_only = IPython.read_only;
18 this.element = $(selector);
18 this.element = $(selector);
19 this.element.scroll();
19 this.element.scroll();
20 this.element.data("notebook", this);
20 this.element.data("notebook", this);
21 this.next_prompt_number = 1;
21 this.next_prompt_number = 1;
22 this.kernel = null;
22 this.kernel = null;
23 this.clipboard = null;
23 this.clipboard = null;
24 this.paste_enabled = false;
24 this.paste_enabled = false;
25 this.dirty = false;
25 this.dirty = false;
26 this.msg_cell_map = {};
26 this.msg_cell_map = {};
27 this.metadata = {};
27 this.metadata = {};
28 this.control_key_active = false;
28 this.control_key_active = false;
29 this.style();
29 this.style();
30 this.create_elements();
30 this.create_elements();
31 this.bind_events();
31 this.bind_events();
32 this.set_tooltipontab(true);
32 this.set_tooltipontab(true);
33 this.set_smartcompleter(true);
33 this.set_smartcompleter(true);
34 this.set_timebeforetooltip(1200);
34 this.set_timebeforetooltip(1200);
35 };
35 };
36
36
37
37
38 Notebook.prototype.style = function () {
38 Notebook.prototype.style = function () {
39 $('div#notebook').addClass('border-box-sizing');
39 $('div#notebook').addClass('border-box-sizing');
40 };
40 };
41
41
42
42
43 Notebook.prototype.create_elements = function () {
43 Notebook.prototype.create_elements = function () {
44 // We add this end_space div to the end of the notebook div to:
44 // We add this end_space div to the end of the notebook div to:
45 // i) provide a margin between the last cell and the end of the notebook
45 // i) provide a margin between the last cell and the end of the notebook
46 // ii) to prevent the div from scrolling up when the last cell is being
46 // ii) to prevent the div from scrolling up when the last cell is being
47 // edited, but is too low on the page, which browsers will do automatically.
47 // edited, but is too low on the page, which browsers will do automatically.
48 var that = this;
48 var that = this;
49 var end_space = $('<div/>').addClass('end_space').height("30%");
49 var end_space = $('<div/>').addClass('end_space').height("30%");
50 end_space.dblclick(function (e) {
50 end_space.dblclick(function (e) {
51 if (that.read_only) return;
51 if (that.read_only) return;
52 var ncells = that.ncells();
52 var ncells = that.ncells();
53 that.insert_cell_below('code',ncells-1);
53 that.insert_cell_below('code',ncells-1);
54 });
54 });
55 this.element.append(end_space);
55 this.element.append(end_space);
56 $('div#notebook').addClass('border-box-sizing');
56 $('div#notebook').addClass('border-box-sizing');
57 };
57 };
58
58
59
59
60 Notebook.prototype.bind_events = function () {
60 Notebook.prototype.bind_events = function () {
61 var that = this;
61 var that = this;
62 $(document).keydown(function (event) {
62 $(document).keydown(function (event) {
63 // console.log(event);
63 // console.log(event);
64 if (that.read_only) return true;
64 if (that.read_only) return true;
65
65
66 // Save (CTRL+S) or (AppleKey+S)
66 // Save (CTRL+S) or (AppleKey+S)
67 //metaKey = applekey on mac
67 //metaKey = applekey on mac
68 if ((event.ctrlKey || event.metaKey) && event.keyCode==83) {
68 if ((event.ctrlKey || event.metaKey) && event.keyCode==83) {
69 IPython.save_widget.save_notebook();
69 IPython.save_widget.save_notebook();
70 event.preventDefault();
70 event.preventDefault();
71 return false;
71 return false;
72 } else if (event.which === 27) {
72 } else if (event.which === 27) {
73 // Intercept escape at highest level to avoid closing
73 // Intercept escape at highest level to avoid closing
74 // websocket connection with firefox
74 // websocket connection with firefox
75 event.preventDefault();
75 event.preventDefault();
76 }
76 }
77 if (event.which === 38 && !event.shiftKey) {
77 if (event.which === 38 && !event.shiftKey) {
78 var cell = that.get_selected_cell();
78 var cell = that.get_selected_cell();
79 if (cell.at_top()) {
79 if (cell.at_top()) {
80 event.preventDefault();
80 event.preventDefault();
81 that.select_prev();
81 that.select_prev();
82 };
82 };
83 } else if (event.which === 40 && !event.shiftKey) {
83 } else if (event.which === 40 && !event.shiftKey) {
84 var cell = that.get_selected_cell();
84 var cell = that.get_selected_cell();
85 if (cell.at_bottom()) {
85 if (cell.at_bottom()) {
86 event.preventDefault();
86 event.preventDefault();
87 that.select_next();
87 that.select_next();
88 };
88 };
89 } else if (event.which === 13 && event.shiftKey) {
89 } else if (event.which === 13 && event.shiftKey) {
90 that.execute_selected_cell();
90 that.execute_selected_cell();
91 return false;
91 return false;
92 } else if (event.which === 13 && event.ctrlKey) {
92 } else if (event.which === 13 && event.ctrlKey) {
93 that.execute_selected_cell({terminal:true});
93 that.execute_selected_cell({terminal:true});
94 return false;
94 return false;
95 } else if (event.which === 77 && event.ctrlKey) {
95 } else if (event.which === 77 && event.ctrlKey) {
96 that.control_key_active = true;
96 that.control_key_active = true;
97 return false;
97 return false;
98 } else if (event.which === 88 && that.control_key_active) {
98 } else if (event.which === 88 && that.control_key_active) {
99 // Cut selected cell = x
99 // Cut selected cell = x
100 that.cut_cell();
100 that.cut_cell();
101 that.control_key_active = false;
101 that.control_key_active = false;
102 return false;
102 return false;
103 } else if (event.which === 67 && that.control_key_active) {
103 } else if (event.which === 67 && that.control_key_active) {
104 // Copy selected cell = c
104 // Copy selected cell = c
105 that.copy_cell();
105 that.copy_cell();
106 that.control_key_active = false;
106 that.control_key_active = false;
107 return false;
107 return false;
108 } else if (event.which === 86 && that.control_key_active) {
108 } else if (event.which === 86 && that.control_key_active) {
109 // Paste selected cell = v
109 // Paste selected cell = v
110 that.paste_cell();
110 that.paste_cell();
111 that.control_key_active = false;
111 that.control_key_active = false;
112 return false;
112 return false;
113 } else if (event.which === 68 && that.control_key_active) {
113 } else if (event.which === 68 && that.control_key_active) {
114 // Delete selected cell = d
114 // Delete selected cell = d
115 that.delete_cell();
115 that.delete_cell();
116 that.control_key_active = false;
116 that.control_key_active = false;
117 return false;
117 return false;
118 } else if (event.which === 65 && that.control_key_active) {
118 } else if (event.which === 65 && that.control_key_active) {
119 // Insert code cell above selected = a
119 // Insert code cell above selected = a
120 that.insert_cell_above('code');
120 that.insert_cell_above('code');
121 that.control_key_active = false;
121 that.control_key_active = false;
122 return false;
122 return false;
123 } else if (event.which === 66 && that.control_key_active) {
123 } else if (event.which === 66 && that.control_key_active) {
124 // Insert code cell below selected = b
124 // Insert code cell below selected = b
125 that.insert_cell_below('code');
125 that.insert_cell_below('code');
126 that.control_key_active = false;
126 that.control_key_active = false;
127 return false;
127 return false;
128 } else if (event.which === 89 && that.control_key_active) {
128 } else if (event.which === 89 && that.control_key_active) {
129 // To code = y
129 // To code = y
130 that.to_code();
130 that.to_code();
131 that.control_key_active = false;
131 that.control_key_active = false;
132 return false;
132 return false;
133 } else if (event.which === 77 && that.control_key_active) {
133 } else if (event.which === 77 && that.control_key_active) {
134 // To markdown = m
134 // To markdown = m
135 that.to_markdown();
135 that.to_markdown();
136 that.control_key_active = false;
136 that.control_key_active = false;
137 return false;
137 return false;
138 } else if (event.which === 84 && that.control_key_active) {
138 } else if (event.which === 84 && that.control_key_active) {
139 // To Plaintext = r
139 // To Plaintext = t
140 that.to_plaintext();
140 that.to_plaintext();
141 that.control_key_active = false;
141 that.control_key_active = false;
142 return false;
142 return false;
143 } else if (event.which === 49 && that.control_key_active) {
143 } else if (event.which === 49 && that.control_key_active) {
144 // To Heading 1 = 1
144 // To Heading 1 = 1
145 that.to_heading(undefined, 1);
145 that.to_heading(undefined, 1);
146 that.control_key_active = false;
146 that.control_key_active = false;
147 return false;
147 return false;
148 } else if (event.which === 50 && that.control_key_active) {
148 } else if (event.which === 50 && that.control_key_active) {
149 // To Heading 2 = 2
149 // To Heading 2 = 2
150 that.to_heading(undefined, 2);
150 that.to_heading(undefined, 2);
151 that.control_key_active = false;
151 that.control_key_active = false;
152 return false;
152 return false;
153 } else if (event.which === 51 && that.control_key_active) {
153 } else if (event.which === 51 && that.control_key_active) {
154 // To Heading 3 = 3
154 // To Heading 3 = 3
155 that.to_heading(undefined, 3);
155 that.to_heading(undefined, 3);
156 that.control_key_active = false;
156 that.control_key_active = false;
157 return false;
157 return false;
158 } else if (event.which === 52 && that.control_key_active) {
158 } else if (event.which === 52 && that.control_key_active) {
159 // To Heading 4 = 4
159 // To Heading 4 = 4
160 that.to_heading(undefined, 4);
160 that.to_heading(undefined, 4);
161 that.control_key_active = false;
161 that.control_key_active = false;
162 return false;
162 return false;
163 } else if (event.which === 53 && that.control_key_active) {
163 } else if (event.which === 53 && that.control_key_active) {
164 // To Heading 5 = 5
164 // To Heading 5 = 5
165 that.to_heading(undefined, 5);
165 that.to_heading(undefined, 5);
166 that.control_key_active = false;
166 that.control_key_active = false;
167 return false;
167 return false;
168 } else if (event.which === 54 && that.control_key_active) {
168 } else if (event.which === 54 && that.control_key_active) {
169 // To Heading 6 = 6
169 // To Heading 6 = 6
170 that.to_heading(undefined, 6);
170 that.to_heading(undefined, 6);
171 that.control_key_active = false;
171 that.control_key_active = false;
172 return false;
172 return false;
173 } else if (event.which === 79 && that.control_key_active) {
173 } else if (event.which === 79 && that.control_key_active) {
174 // Toggle output = o
174 // Toggle output = o
175 that.toggle_output();
175 that.toggle_output();
176 that.control_key_active = false;
176 that.control_key_active = false;
177 return false;
177 return false;
178 } else if (event.which === 83 && that.control_key_active) {
178 } else if (event.which === 83 && that.control_key_active) {
179 // Save notebook = s
179 // Save notebook = s
180 IPython.save_widget.save_notebook();
180 IPython.save_widget.save_notebook();
181 that.control_key_active = false;
181 that.control_key_active = false;
182 return false;
182 return false;
183 } else if (event.which === 74 && that.control_key_active) {
183 } else if (event.which === 74 && that.control_key_active) {
184 // Move cell down = j
184 // Move cell down = j
185 that.move_cell_down();
185 that.move_cell_down();
186 that.control_key_active = false;
186 that.control_key_active = false;
187 return false;
187 return false;
188 } else if (event.which === 75 && that.control_key_active) {
188 } else if (event.which === 75 && that.control_key_active) {
189 // Move cell up = k
189 // Move cell up = k
190 that.move_cell_up();
190 that.move_cell_up();
191 that.control_key_active = false;
191 that.control_key_active = false;
192 return false;
192 return false;
193 } else if (event.which === 80 && that.control_key_active) {
193 } else if (event.which === 80 && that.control_key_active) {
194 // Select previous = p
194 // Select previous = p
195 that.select_prev();
195 that.select_prev();
196 that.control_key_active = false;
196 that.control_key_active = false;
197 return false;
197 return false;
198 } else if (event.which === 78 && that.control_key_active) {
198 } else if (event.which === 78 && that.control_key_active) {
199 // Select next = n
199 // Select next = n
200 that.select_next();
200 that.select_next();
201 that.control_key_active = false;
201 that.control_key_active = false;
202 return false;
202 return false;
203 } else if (event.which === 76 && that.control_key_active) {
203 } else if (event.which === 76 && that.control_key_active) {
204 // Toggle line numbers = l
204 // Toggle line numbers = l
205 that.cell_toggle_line_numbers();
205 that.cell_toggle_line_numbers();
206 that.control_key_active = false;
206 that.control_key_active = false;
207 return false;
207 return false;
208 } else if (event.which === 73 && that.control_key_active) {
208 } else if (event.which === 73 && that.control_key_active) {
209 // Interrupt kernel = i
209 // Interrupt kernel = i
210 IPython.notebook.kernel.interrupt();
210 IPython.notebook.kernel.interrupt();
211 that.control_key_active = false;
211 that.control_key_active = false;
212 return false;
212 return false;
213 } else if (event.which === 190 && that.control_key_active) {
213 } else if (event.which === 190 && that.control_key_active) {
214 // Restart kernel = . # matches qt console
214 // Restart kernel = . # matches qt console
215 IPython.notebook.restart_kernel();
215 IPython.notebook.restart_kernel();
216 that.control_key_active = false;
216 that.control_key_active = false;
217 return false;
217 return false;
218 } else if (event.which === 72 && that.control_key_active) {
218 } else if (event.which === 72 && that.control_key_active) {
219 // Show keyboard shortcuts = h
219 // Show keyboard shortcuts = h
220 IPython.quick_help.show_keyboard_shortcuts();
220 IPython.quick_help.show_keyboard_shortcuts();
221 that.control_key_active = false;
221 that.control_key_active = false;
222 return false;
222 return false;
223 } else if (that.control_key_active) {
223 } else if (that.control_key_active) {
224 that.control_key_active = false;
224 that.control_key_active = false;
225 return true;
225 return true;
226 };
226 };
227 return true;
227 return true;
228 });
228 });
229
229
230 this.element.bind('collapse_pager', function () {
230 this.element.bind('collapse_pager', function () {
231 var app_height = $('div#main_app').height(); // content height
231 var app_height = $('div#main_app').height(); // content height
232 var splitter_height = $('div#pager_splitter').outerHeight(true);
232 var splitter_height = $('div#pager_splitter').outerHeight(true);
233 var new_height = app_height - splitter_height;
233 var new_height = app_height - splitter_height;
234 that.element.animate({height : new_height + 'px'}, 'fast');
234 that.element.animate({height : new_height + 'px'}, 'fast');
235 });
235 });
236
236
237 this.element.bind('expand_pager', function () {
237 this.element.bind('expand_pager', function () {
238 var app_height = $('div#main_app').height(); // content height
238 var app_height = $('div#main_app').height(); // content height
239 var splitter_height = $('div#pager_splitter').outerHeight(true);
239 var splitter_height = $('div#pager_splitter').outerHeight(true);
240 var pager_height = $('div#pager').outerHeight(true);
240 var pager_height = $('div#pager').outerHeight(true);
241 var new_height = app_height - pager_height - splitter_height;
241 var new_height = app_height - pager_height - splitter_height;
242 that.element.animate({height : new_height + 'px'}, 'fast');
242 that.element.animate({height : new_height + 'px'}, 'fast');
243 });
243 });
244
244
245 $(window).bind('beforeunload', function () {
245 $(window).bind('beforeunload', function () {
246 // TODO: Make killing the kernel configurable.
246 // TODO: Make killing the kernel configurable.
247 var kill_kernel = false;
247 var kill_kernel = false;
248 if (kill_kernel) {
248 if (kill_kernel) {
249 that.kernel.kill();
249 that.kernel.kill();
250 }
250 }
251 if (that.dirty && ! that.read_only) {
251 if (that.dirty && ! that.read_only) {
252 return "You have unsaved changes that will be lost if you leave this page.";
252 return "You have unsaved changes that will be lost if you leave this page.";
253 };
253 };
254 // Null is the *only* return value that will make the browser not
254 // Null is the *only* return value that will make the browser not
255 // pop up the "don't leave" dialog.
255 // pop up the "don't leave" dialog.
256 return null;
256 return null;
257 });
257 });
258 };
258 };
259
259
260
260
261 Notebook.prototype.scroll_to_bottom = function () {
261 Notebook.prototype.scroll_to_bottom = function () {
262 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
262 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
263 };
263 };
264
264
265
265
266 Notebook.prototype.scroll_to_top = function () {
266 Notebook.prototype.scroll_to_top = function () {
267 this.element.animate({scrollTop:0}, 0);
267 this.element.animate({scrollTop:0}, 0);
268 };
268 };
269
269
270
270
271 // Cell indexing, retrieval, etc.
271 // Cell indexing, retrieval, etc.
272
272
273 Notebook.prototype.get_cell_elements = function () {
273 Notebook.prototype.get_cell_elements = function () {
274 return this.element.children("div.cell");
274 return this.element.children("div.cell");
275 };
275 };
276
276
277
277
278 Notebook.prototype.get_cell_element = function (index) {
278 Notebook.prototype.get_cell_element = function (index) {
279 var result = null;
279 var result = null;
280 var e = this.get_cell_elements().eq(index);
280 var e = this.get_cell_elements().eq(index);
281 if (e.length !== 0) {
281 if (e.length !== 0) {
282 result = e;
282 result = e;
283 }
283 }
284 return result;
284 return result;
285 };
285 };
286
286
287
287
288 Notebook.prototype.ncells = function (cell) {
288 Notebook.prototype.ncells = function (cell) {
289 return this.get_cell_elements().length;
289 return this.get_cell_elements().length;
290 };
290 };
291
291
292
292
293 // TODO: we are often calling cells as cells()[i], which we should optimize
293 // TODO: we are often calling cells as cells()[i], which we should optimize
294 // to cells(i) or a new method.
294 // to cells(i) or a new method.
295 Notebook.prototype.get_cells = function () {
295 Notebook.prototype.get_cells = function () {
296 return this.get_cell_elements().toArray().map(function (e) {
296 return this.get_cell_elements().toArray().map(function (e) {
297 return $(e).data("cell");
297 return $(e).data("cell");
298 });
298 });
299 };
299 };
300
300
301
301
302 Notebook.prototype.get_cell = function (index) {
302 Notebook.prototype.get_cell = function (index) {
303 var result = null;
303 var result = null;
304 var ce = this.get_cell_element(index);
304 var ce = this.get_cell_element(index);
305 if (ce !== null) {
305 if (ce !== null) {
306 result = ce.data('cell');
306 result = ce.data('cell');
307 }
307 }
308 return result;
308 return result;
309 }
309 }
310
310
311
311
312 Notebook.prototype.get_next_cell = function (cell) {
312 Notebook.prototype.get_next_cell = function (cell) {
313 var result = null;
313 var result = null;
314 var index = this.find_cell_index(cell);
314 var index = this.find_cell_index(cell);
315 if (index !== null && index < this.ncells()) {
315 if (index !== null && index < this.ncells()) {
316 result = this.get_cell(index+1);
316 result = this.get_cell(index+1);
317 }
317 }
318 return result;
318 return result;
319 }
319 }
320
320
321
321
322 Notebook.prototype.get_prev_cell = function (cell) {
322 Notebook.prototype.get_prev_cell = function (cell) {
323 var result = null;
323 var result = null;
324 var index = this.find_cell_index(cell);
324 var index = this.find_cell_index(cell);
325 if (index !== null && index > 1) {
325 if (index !== null && index > 1) {
326 result = this.get_cell(index-1);
326 result = this.get_cell(index-1);
327 }
327 }
328 return result;
328 return result;
329 }
329 }
330
330
331 Notebook.prototype.find_cell_index = function (cell) {
331 Notebook.prototype.find_cell_index = function (cell) {
332 var result = null;
332 var result = null;
333 this.get_cell_elements().filter(function (index) {
333 this.get_cell_elements().filter(function (index) {
334 if ($(this).data("cell") === cell) {
334 if ($(this).data("cell") === cell) {
335 result = index;
335 result = index;
336 };
336 };
337 });
337 });
338 return result;
338 return result;
339 };
339 };
340
340
341
341
342 Notebook.prototype.index_or_selected = function (index) {
342 Notebook.prototype.index_or_selected = function (index) {
343 var i;
343 var i;
344 if (index === undefined || index === null) {
344 if (index === undefined || index === null) {
345 i = this.get_selected_index();
345 i = this.get_selected_index();
346 if (i === null) {
346 if (i === null) {
347 i = 0;
347 i = 0;
348 }
348 }
349 } else {
349 } else {
350 i = index;
350 i = index;
351 }
351 }
352 return i;
352 return i;
353 };
353 };
354
354
355
355
356 Notebook.prototype.get_selected_cell = function () {
356 Notebook.prototype.get_selected_cell = function () {
357 var index = this.get_selected_index();
357 var index = this.get_selected_index();
358 return this.get_cell(index);
358 return this.get_cell(index);
359 };
359 };
360
360
361
361
362 Notebook.prototype.is_valid_cell_index = function (index) {
362 Notebook.prototype.is_valid_cell_index = function (index) {
363 if (index !== null && index >= 0 && index < this.ncells()) {
363 if (index !== null && index >= 0 && index < this.ncells()) {
364 return true;
364 return true;
365 } else {
365 } else {
366 return false;
366 return false;
367 };
367 };
368 }
368 }
369
369
370 Notebook.prototype.get_selected_index = function () {
370 Notebook.prototype.get_selected_index = function () {
371 var result = null;
371 var result = null;
372 this.get_cell_elements().filter(function (index) {
372 this.get_cell_elements().filter(function (index) {
373 if ($(this).data("cell").selected === true) {
373 if ($(this).data("cell").selected === true) {
374 result = index;
374 result = index;
375 };
375 };
376 });
376 });
377 return result;
377 return result;
378 };
378 };
379
379
380
380
381 Notebook.prototype.cell_for_msg = function (msg_id) {
381 Notebook.prototype.cell_for_msg = function (msg_id) {
382 var cell_id = this.msg_cell_map[msg_id];
382 var cell_id = this.msg_cell_map[msg_id];
383 var result = null;
383 var result = null;
384 this.get_cell_elements().filter(function (index) {
384 this.get_cell_elements().filter(function (index) {
385 cell = $(this).data("cell");
385 cell = $(this).data("cell");
386 if (cell.cell_id === cell_id) {
386 if (cell.cell_id === cell_id) {
387 result = cell;
387 result = cell;
388 };
388 };
389 });
389 });
390 return result;
390 return result;
391 };
391 };
392
392
393
393
394 // Cell selection.
394 // Cell selection.
395
395
396 Notebook.prototype.select = function (index) {
396 Notebook.prototype.select = function (index) {
397 if (index !== undefined && index >= 0 && index < this.ncells()) {
397 if (index !== undefined && index >= 0 && index < this.ncells()) {
398 sindex = this.get_selected_index()
398 sindex = this.get_selected_index()
399 if (sindex !== null && index !== sindex) {
399 if (sindex !== null && index !== sindex) {
400 this.get_cell(sindex).unselect();
400 this.get_cell(sindex).unselect();
401 };
401 };
402 var cell = this.get_cell(index)
402 var cell = this.get_cell(index)
403 cell.select();
403 cell.select();
404 IPython.toolbar.set_cell_type(cell.cell_type);
404 if (cell.cell_type === 'heading') {
405 IPython.toolbar.set_cell_type(cell.cell_type+cell.level);
406 } else {
407 IPython.toolbar.set_cell_type(cell.cell_type)
408 }
405 };
409 };
406 return this;
410 return this;
407 };
411 };
408
412
409
413
410 Notebook.prototype.select_next = function () {
414 Notebook.prototype.select_next = function () {
411 var index = this.get_selected_index();
415 var index = this.get_selected_index();
412 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
416 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
413 this.select(index+1);
417 this.select(index+1);
414 };
418 };
415 return this;
419 return this;
416 };
420 };
417
421
418
422
419 Notebook.prototype.select_prev = function () {
423 Notebook.prototype.select_prev = function () {
420 var index = this.get_selected_index();
424 var index = this.get_selected_index();
421 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
425 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
422 this.select(index-1);
426 this.select(index-1);
423 };
427 };
424 return this;
428 return this;
425 };
429 };
426
430
427
431
428 // Cell movement
432 // Cell movement
429
433
430 Notebook.prototype.move_cell_up = function (index) {
434 Notebook.prototype.move_cell_up = function (index) {
431 var i = this.index_or_selected();
435 var i = this.index_or_selected();
432 if (i !== null && i < this.ncells() && i > 0) {
436 if (i !== null && i < this.ncells() && i > 0) {
433 var pivot = this.get_cell_element(i-1);
437 var pivot = this.get_cell_element(i-1);
434 var tomove = this.get_cell_element(i);
438 var tomove = this.get_cell_element(i);
435 if (pivot !== null && tomove !== null) {
439 if (pivot !== null && tomove !== null) {
436 tomove.detach();
440 tomove.detach();
437 pivot.before(tomove);
441 pivot.before(tomove);
438 this.select(i-1);
442 this.select(i-1);
439 };
443 };
440 };
444 };
441 this.dirty = true;
445 this.dirty = true;
442 return this;
446 return this;
443 };
447 };
444
448
445
449
446 Notebook.prototype.move_cell_down = function (index) {
450 Notebook.prototype.move_cell_down = function (index) {
447 var i = this.index_or_selected();
451 var i = this.index_or_selected();
448 if (i !== null && i < (this.ncells()-1) && i >= 0) {
452 if (i !== null && i < (this.ncells()-1) && i >= 0) {
449 var pivot = this.get_cell_element(i+1);
453 var pivot = this.get_cell_element(i+1);
450 var tomove = this.get_cell_element(i);
454 var tomove = this.get_cell_element(i);
451 if (pivot !== null && tomove !== null) {
455 if (pivot !== null && tomove !== null) {
452 tomove.detach();
456 tomove.detach();
453 pivot.after(tomove);
457 pivot.after(tomove);
454 this.select(i+1);
458 this.select(i+1);
455 };
459 };
456 };
460 };
457 this.dirty = true;
461 this.dirty = true;
458 return this;
462 return this;
459 };
463 };
460
464
461
465
462 Notebook.prototype.sort_cells = function () {
466 Notebook.prototype.sort_cells = function () {
463 // This is not working right now. Calling this will actually crash
467 // This is not working right now. Calling this will actually crash
464 // the browser. I think there is an infinite loop in here...
468 // the browser. I think there is an infinite loop in here...
465 var ncells = this.ncells();
469 var ncells = this.ncells();
466 var sindex = this.get_selected_index();
470 var sindex = this.get_selected_index();
467 var swapped;
471 var swapped;
468 do {
472 do {
469 swapped = false;
473 swapped = false;
470 for (var i=1; i<ncells; i++) {
474 for (var i=1; i<ncells; i++) {
471 current = this.get_cell(i);
475 current = this.get_cell(i);
472 previous = this.get_cell(i-1);
476 previous = this.get_cell(i-1);
473 if (previous.input_prompt_number > current.input_prompt_number) {
477 if (previous.input_prompt_number > current.input_prompt_number) {
474 this.move_cell_up(i);
478 this.move_cell_up(i);
475 swapped = true;
479 swapped = true;
476 };
480 };
477 };
481 };
478 } while (swapped);
482 } while (swapped);
479 this.select(sindex);
483 this.select(sindex);
480 return this;
484 return this;
481 };
485 };
482
486
483 // Insertion, deletion.
487 // Insertion, deletion.
484
488
485 Notebook.prototype.delete_cell = function (index) {
489 Notebook.prototype.delete_cell = function (index) {
486 var i = this.index_or_selected(index);
490 var i = this.index_or_selected(index);
487 if (this.is_valid_cell_index(i)) {
491 if (this.is_valid_cell_index(i)) {
488 var ce = this.get_cell_element(i);
492 var ce = this.get_cell_element(i);
489 ce.remove();
493 ce.remove();
490 if (i === (this.ncells())) {
494 if (i === (this.ncells())) {
491 this.select(i-1);
495 this.select(i-1);
492 } else {
496 } else {
493 this.select(i);
497 this.select(i);
494 };
498 };
495 this.dirty = true;
499 this.dirty = true;
496 };
500 };
497 return this;
501 return this;
498 };
502 };
499
503
500
504
501 Notebook.prototype.insert_cell_below = function (type, index) {
505 Notebook.prototype.insert_cell_below = function (type, index) {
502 // type = ('code','html','markdown')
506 // type = ('code','html','markdown')
503 // index = cell index or undefined to insert below selected
507 // index = cell index or undefined to insert below selected
504 index = this.index_or_selected(index);
508 index = this.index_or_selected(index);
505 var cell = null;
509 var cell = null;
506 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
510 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
507 if (type === 'code') {
511 if (type === 'code') {
508 cell = new IPython.CodeCell(this);
512 cell = new IPython.CodeCell(this);
509 cell.set_input_prompt();
513 cell.set_input_prompt();
510 } else if (type === 'markdown') {
514 } else if (type === 'markdown') {
511 cell = new IPython.MarkdownCell(this);
515 cell = new IPython.MarkdownCell(this);
512 } else if (type === 'html') {
516 } else if (type === 'html') {
513 cell = new IPython.HTMLCell(this);
517 cell = new IPython.HTMLCell(this);
514 } else if (type === 'plaintext') {
518 } else if (type === 'plaintext') {
515 cell = new IPython.PlaintextCell(this);
519 cell = new IPython.PlaintextCell(this);
516 } else if (type === 'heading') {
520 } else if (type === 'heading') {
517 cell = new IPython.HeadingCell(this);
521 cell = new IPython.HeadingCell(this);
518 };
522 };
519 if (cell !== null) {
523 if (cell !== null) {
520 if (this.ncells() === 0) {
524 if (this.ncells() === 0) {
521 this.element.find('div.end_space').before(cell.element);
525 this.element.find('div.end_space').before(cell.element);
522 } else if (this.is_valid_cell_index(index)) {
526 } else if (this.is_valid_cell_index(index)) {
523 this.get_cell_element(index).after(cell.element);
527 this.get_cell_element(index).after(cell.element);
524 };
528 };
525 cell.render();
529 cell.render();
526 this.select(this.find_cell_index(cell));
530 this.select(this.find_cell_index(cell));
527 this.dirty = true;
531 this.dirty = true;
528 return cell;
532 return cell;
529 };
533 };
530 };
534 };
531 return cell;
535 return cell;
532 };
536 };
533
537
534
538
535 Notebook.prototype.insert_cell_above = function (type, index) {
539 Notebook.prototype.insert_cell_above = function (type, index) {
536 // type = ('code','html','markdown')
540 // type = ('code','html','markdown')
537 // index = cell index or undefined to insert above selected
541 // index = cell index or undefined to insert above selected
538 index = this.index_or_selected(index);
542 index = this.index_or_selected(index);
539 var cell = null;
543 var cell = null;
540 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
544 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
541 if (type === 'code') {
545 if (type === 'code') {
542 cell = new IPython.CodeCell(this);
546 cell = new IPython.CodeCell(this);
543 cell.set_input_prompt();
547 cell.set_input_prompt();
544 } else if (type === 'markdown') {
548 } else if (type === 'markdown') {
545 cell = new IPython.MarkdownCell(this);
549 cell = new IPython.MarkdownCell(this);
546 } else if (type === 'html') {
550 } else if (type === 'html') {
547 cell = new IPython.HTMLCell(this);
551 cell = new IPython.HTMLCell(this);
548 } else if (type === 'plaintext') {
552 } else if (type === 'plaintext') {
549 cell = new IPython.PlaintextCell(this);
553 cell = new IPython.PlaintextCell(this);
550 } else if (type === 'heading') {
554 } else if (type === 'heading') {
551 cell = new IPython.HeadingCell(this);
555 cell = new IPython.HeadingCell(this);
552 };
556 };
553 if (cell !== null) {
557 if (cell !== null) {
554 if (this.ncells() === 0) {
558 if (this.ncells() === 0) {
555 this.element.find('div.end_space').before(cell.element);
559 this.element.find('div.end_space').before(cell.element);
556 } else if (this.is_valid_cell_index(index)) {
560 } else if (this.is_valid_cell_index(index)) {
557 this.get_cell_element(index).before(cell.element);
561 this.get_cell_element(index).before(cell.element);
558 };
562 };
559 cell.render();
563 cell.render();
560 this.select(this.find_cell_index(cell));
564 this.select(this.find_cell_index(cell));
561 this.dirty = true;
565 this.dirty = true;
562 return cell;
566 return cell;
563 };
567 };
564 };
568 };
565 return cell;
569 return cell;
566 };
570 };
567
571
568
572
569 Notebook.prototype.to_code = function (index) {
573 Notebook.prototype.to_code = function (index) {
570 var i = this.index_or_selected(index);
574 var i = this.index_or_selected(index);
571 if (this.is_valid_cell_index(i)) {
575 if (this.is_valid_cell_index(i)) {
572 var source_element = this.get_cell_element(i);
576 var source_element = this.get_cell_element(i);
573 var source_cell = source_element.data("cell");
577 var source_cell = source_element.data("cell");
574 if (!(source_cell instanceof IPython.CodeCell)) {
578 if (!(source_cell instanceof IPython.CodeCell)) {
575 target_cell = this.insert_cell_below('code',i);
579 target_cell = this.insert_cell_below('code',i);
576 var text = source_cell.get_text();
580 var text = source_cell.get_text();
577 if (text === source_cell.placeholder) {
581 if (text === source_cell.placeholder) {
578 text = '';
582 text = '';
579 }
583 }
580 target_cell.set_text(text);
584 target_cell.set_text(text);
581 source_element.remove();
585 source_element.remove();
582 this.dirty = true;
586 this.dirty = true;
583 };
587 };
584 };
588 };
585 };
589 };
586
590
587
591
588 Notebook.prototype.to_markdown = function (index) {
592 Notebook.prototype.to_markdown = function (index) {
589 var i = this.index_or_selected(index);
593 var i = this.index_or_selected(index);
590 if (this.is_valid_cell_index(i)) {
594 if (this.is_valid_cell_index(i)) {
591 var source_element = this.get_cell_element(i);
595 var source_element = this.get_cell_element(i);
592 var source_cell = source_element.data("cell");
596 var source_cell = source_element.data("cell");
593 if (!(source_cell instanceof IPython.MarkdownCell)) {
597 if (!(source_cell instanceof IPython.MarkdownCell)) {
594 target_cell = this.insert_cell_below('markdown',i);
598 target_cell = this.insert_cell_below('markdown',i);
595 var text = source_cell.get_text();
599 var text = source_cell.get_text();
596 if (text === source_cell.placeholder) {
600 if (text === source_cell.placeholder) {
597 text = '';
601 text = '';
598 };
602 };
599 // The edit must come before the set_text.
603 // The edit must come before the set_text.
600 target_cell.edit();
604 target_cell.edit();
601 target_cell.set_text(text);
605 target_cell.set_text(text);
602 source_element.remove();
606 source_element.remove();
603 this.dirty = true;
607 this.dirty = true;
604 };
608 };
605 };
609 };
606 };
610 };
607
611
608
612
609 Notebook.prototype.to_html = function (index) {
613 Notebook.prototype.to_html = function (index) {
610 var i = this.index_or_selected(index);
614 var i = this.index_or_selected(index);
611 if (this.is_valid_cell_index(i)) {
615 if (this.is_valid_cell_index(i)) {
612 var source_element = this.get_cell_element(i);
616 var source_element = this.get_cell_element(i);
613 var source_cell = source_element.data("cell");
617 var source_cell = source_element.data("cell");
614 var target_cell = null;
618 var target_cell = null;
615 if (!(source_cell instanceof IPython.HTMLCell)) {
619 if (!(source_cell instanceof IPython.HTMLCell)) {
616 target_cell = this.insert_cell_below('html',i);
620 target_cell = this.insert_cell_below('html',i);
617 var text = source_cell.get_text();
621 var text = source_cell.get_text();
618 if (text === source_cell.placeholder) {
622 if (text === source_cell.placeholder) {
619 text = '';
623 text = '';
620 };
624 };
621 // The edit must come before the set_text.
625 // The edit must come before the set_text.
622 target_cell.edit();
626 target_cell.edit();
623 target_cell.set_text(text);
627 target_cell.set_text(text);
624 source_element.remove();
628 source_element.remove();
625 this.dirty = true;
629 this.dirty = true;
626 };
630 };
627 };
631 };
628 };
632 };
629
633
630
634
631 Notebook.prototype.to_plaintext = function (index) {
635 Notebook.prototype.to_plaintext = function (index) {
632 var i = this.index_or_selected(index);
636 var i = this.index_or_selected(index);
633 if (this.is_valid_cell_index(i)) {
637 if (this.is_valid_cell_index(i)) {
634 var source_element = this.get_cell_element(i);
638 var source_element = this.get_cell_element(i);
635 var source_cell = source_element.data("cell");
639 var source_cell = source_element.data("cell");
636 var target_cell = null;
640 var target_cell = null;
637 if (!(source_cell instanceof IPython.PlaintextCell)) {
641 if (!(source_cell instanceof IPython.PlaintextCell)) {
638 target_cell = this.insert_cell_below('plaintext',i);
642 target_cell = this.insert_cell_below('plaintext',i);
639 var text = source_cell.get_text();
643 var text = source_cell.get_text();
640 if (text === source_cell.placeholder) {
644 if (text === source_cell.placeholder) {
641 text = '';
645 text = '';
642 };
646 };
643 // The edit must come before the set_text.
647 // The edit must come before the set_text.
644 target_cell.edit();
648 target_cell.edit();
645 target_cell.set_text(text);
649 target_cell.set_text(text);
646 source_element.remove();
650 source_element.remove();
647 this.dirty = true;
651 this.dirty = true;
648 };
652 };
649 };
653 };
650 };
654 };
651
655
652
656
653 Notebook.prototype.to_heading = function (index, level) {
657 Notebook.prototype.to_heading = function (index, level) {
654 level = level || 1;
658 level = level || 1;
655 var i = this.index_or_selected(index);
659 var i = this.index_or_selected(index);
656 if (this.is_valid_cell_index(i)) {
660 if (this.is_valid_cell_index(i)) {
657 var source_element = this.get_cell_element(i);
661 var source_element = this.get_cell_element(i);
658 var source_cell = source_element.data("cell");
662 var source_cell = source_element.data("cell");
659 var target_cell = null;
663 var target_cell = null;
660 if (source_cell instanceof IPython.HeadingCell) {
664 if (source_cell instanceof IPython.HeadingCell) {
661 source_cell.set_level(level);
665 source_cell.set_level(level);
662 } else {
666 } else {
663 target_cell = this.insert_cell_below('heading',i);
667 target_cell = this.insert_cell_below('heading',i);
664 var text = source_cell.get_text();
668 var text = source_cell.get_text();
665 if (text === source_cell.placeholder) {
669 if (text === source_cell.placeholder) {
666 text = '';
670 text = '';
667 };
671 };
668 // The edit must come before the set_text.
672 // The edit must come before the set_text.
669 target_cell.set_level(level);
673 target_cell.set_level(level);
670 target_cell.edit();
674 target_cell.edit();
671 target_cell.set_text(text);
675 target_cell.set_text(text);
672 source_element.remove();
676 source_element.remove();
673 this.dirty = true;
677 this.dirty = true;
674 };
678 };
679 IPython.toolbar.set_cell_type("heading"+level);
675 };
680 };
676 };
681 };
677
682
678
683
679 // Cut/Copy/Paste
684 // Cut/Copy/Paste
680
685
681 Notebook.prototype.enable_paste = function () {
686 Notebook.prototype.enable_paste = function () {
682 var that = this;
687 var that = this;
683 if (!this.paste_enabled) {
688 if (!this.paste_enabled) {
684 $('#paste_cell').removeClass('ui-state-disabled')
689 $('#paste_cell').removeClass('ui-state-disabled')
685 .on('click', function () {that.paste_cell();});
690 .on('click', function () {that.paste_cell();});
686 $('#paste_cell_above').removeClass('ui-state-disabled')
691 $('#paste_cell_above').removeClass('ui-state-disabled')
687 .on('click', function () {that.paste_cell_above();});
692 .on('click', function () {that.paste_cell_above();});
688 $('#paste_cell_below').removeClass('ui-state-disabled')
693 $('#paste_cell_below').removeClass('ui-state-disabled')
689 .on('click', function () {that.paste_cell_below();});
694 .on('click', function () {that.paste_cell_below();});
690 this.paste_enabled = true;
695 this.paste_enabled = true;
691 };
696 };
692 };
697 };
693
698
694
699
695 Notebook.prototype.disable_paste = function () {
700 Notebook.prototype.disable_paste = function () {
696 if (this.paste_enabled) {
701 if (this.paste_enabled) {
697 $('#paste_cell').addClass('ui-state-disabled').off('click');
702 $('#paste_cell').addClass('ui-state-disabled').off('click');
698 $('#paste_cell_above').addClass('ui-state-disabled').off('click');
703 $('#paste_cell_above').addClass('ui-state-disabled').off('click');
699 $('#paste_cell_below').addClass('ui-state-disabled').off('click');
704 $('#paste_cell_below').addClass('ui-state-disabled').off('click');
700 this.paste_enabled = false;
705 this.paste_enabled = false;
701 };
706 };
702 };
707 };
703
708
704
709
705 Notebook.prototype.cut_cell = function () {
710 Notebook.prototype.cut_cell = function () {
706 this.copy_cell();
711 this.copy_cell();
707 this.delete_cell();
712 this.delete_cell();
708 }
713 }
709
714
710 Notebook.prototype.copy_cell = function () {
715 Notebook.prototype.copy_cell = function () {
711 var cell = this.get_selected_cell();
716 var cell = this.get_selected_cell();
712 this.clipboard = cell.toJSON();
717 this.clipboard = cell.toJSON();
713 this.enable_paste();
718 this.enable_paste();
714 };
719 };
715
720
716
721
717 Notebook.prototype.paste_cell = function () {
722 Notebook.prototype.paste_cell = function () {
718 if (this.clipboard !== null && this.paste_enabled) {
723 if (this.clipboard !== null && this.paste_enabled) {
719 var cell_data = this.clipboard;
724 var cell_data = this.clipboard;
720 var new_cell = this.insert_cell_above(cell_data.cell_type);
725 var new_cell = this.insert_cell_above(cell_data.cell_type);
721 new_cell.fromJSON(cell_data);
726 new_cell.fromJSON(cell_data);
722 old_cell = this.get_next_cell(new_cell);
727 old_cell = this.get_next_cell(new_cell);
723 this.delete_cell(this.find_cell_index(old_cell));
728 this.delete_cell(this.find_cell_index(old_cell));
724 this.select(this.find_cell_index(new_cell));
729 this.select(this.find_cell_index(new_cell));
725 };
730 };
726 };
731 };
727
732
728
733
729 Notebook.prototype.paste_cell_above = function () {
734 Notebook.prototype.paste_cell_above = function () {
730 if (this.clipboard !== null && this.paste_enabled) {
735 if (this.clipboard !== null && this.paste_enabled) {
731 var cell_data = this.clipboard;
736 var cell_data = this.clipboard;
732 var new_cell = this.insert_cell_above(cell_data.cell_type);
737 var new_cell = this.insert_cell_above(cell_data.cell_type);
733 new_cell.fromJSON(cell_data);
738 new_cell.fromJSON(cell_data);
734 };
739 };
735 };
740 };
736
741
737
742
738 Notebook.prototype.paste_cell_below = function () {
743 Notebook.prototype.paste_cell_below = function () {
739 if (this.clipboard !== null && this.paste_enabled) {
744 if (this.clipboard !== null && this.paste_enabled) {
740 var cell_data = this.clipboard;
745 var cell_data = this.clipboard;
741 var new_cell = this.insert_cell_below(cell_data.cell_type);
746 var new_cell = this.insert_cell_below(cell_data.cell_type);
742 new_cell.fromJSON(cell_data);
747 new_cell.fromJSON(cell_data);
743 };
748 };
744 };
749 };
745
750
746
751
747 // Split/merge
752 // Split/merge
748
753
749 Notebook.prototype.split_cell = function () {
754 Notebook.prototype.split_cell = function () {
750 // Todo: implement spliting for other cell types.
755 // Todo: implement spliting for other cell types.
751 var cell = this.get_selected_cell();
756 var cell = this.get_selected_cell();
752 if (cell.is_splittable()) {
757 if (cell.is_splittable()) {
753 texta = cell.get_pre_cursor();
758 texta = cell.get_pre_cursor();
754 textb = cell.get_post_cursor();
759 textb = cell.get_post_cursor();
755 if (cell instanceof IPython.CodeCell) {
760 if (cell instanceof IPython.CodeCell) {
756 cell.set_text(texta);
761 cell.set_text(texta);
757 var new_cell = this.insert_cell_below('code');
762 var new_cell = this.insert_cell_below('code');
758 new_cell.set_text(textb);
763 new_cell.set_text(textb);
759 } else if (cell instanceof IPython.MarkdownCell) {
764 } else if (cell instanceof IPython.MarkdownCell) {
760 cell.set_text(texta);
765 cell.set_text(texta);
761 cell.render();
766 cell.render();
762 var new_cell = this.insert_cell_below('markdown');
767 var new_cell = this.insert_cell_below('markdown');
763 new_cell.edit(); // editor must be visible to call set_text
768 new_cell.edit(); // editor must be visible to call set_text
764 new_cell.set_text(textb);
769 new_cell.set_text(textb);
765 new_cell.render();
770 new_cell.render();
766 } else if (cell instanceof IPython.HTMLCell) {
771 } else if (cell instanceof IPython.HTMLCell) {
767 cell.set_text(texta);
772 cell.set_text(texta);
768 cell.render();
773 cell.render();
769 var new_cell = this.insert_cell_below('html');
774 var new_cell = this.insert_cell_below('html');
770 new_cell.edit(); // editor must be visible to call set_text
775 new_cell.edit(); // editor must be visible to call set_text
771 new_cell.set_text(textb);
776 new_cell.set_text(textb);
772 new_cell.render();
777 new_cell.render();
773 };
778 };
774 };
779 };
775 };
780 };
776
781
777
782
778 Notebook.prototype.merge_cell_above = function () {
783 Notebook.prototype.merge_cell_above = function () {
779 var index = this.get_selected_index();
784 var index = this.get_selected_index();
780 var cell = this.get_cell(index);
785 var cell = this.get_cell(index);
781 if (index > 0) {
786 if (index > 0) {
782 upper_cell = this.get_cell(index-1);
787 upper_cell = this.get_cell(index-1);
783 upper_text = upper_cell.get_text();
788 upper_text = upper_cell.get_text();
784 text = cell.get_text();
789 text = cell.get_text();
785 if (cell instanceof IPython.CodeCell) {
790 if (cell instanceof IPython.CodeCell) {
786 cell.set_text(upper_text+'\n'+text);
791 cell.set_text(upper_text+'\n'+text);
787 } else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
792 } else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
788 cell.edit();
793 cell.edit();
789 cell.set_text(upper_text+'\n'+text);
794 cell.set_text(upper_text+'\n'+text);
790 cell.render();
795 cell.render();
791 };
796 };
792 this.delete_cell(index-1);
797 this.delete_cell(index-1);
793 this.select(this.find_cell_index(cell));
798 this.select(this.find_cell_index(cell));
794 };
799 };
795 };
800 };
796
801
797
802
798 Notebook.prototype.merge_cell_below = function () {
803 Notebook.prototype.merge_cell_below = function () {
799 var index = this.get_selected_index();
804 var index = this.get_selected_index();
800 var cell = this.get_cell(index);
805 var cell = this.get_cell(index);
801 if (index < this.ncells()-1) {
806 if (index < this.ncells()-1) {
802 lower_cell = this.get_cell(index+1);
807 lower_cell = this.get_cell(index+1);
803 lower_text = lower_cell.get_text();
808 lower_text = lower_cell.get_text();
804 text = cell.get_text();
809 text = cell.get_text();
805 if (cell instanceof IPython.CodeCell) {
810 if (cell instanceof IPython.CodeCell) {
806 cell.set_text(text+'\n'+lower_text);
811 cell.set_text(text+'\n'+lower_text);
807 } else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
812 } else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
808 cell.edit();
813 cell.edit();
809 cell.set_text(text+'\n'+lower_text);
814 cell.set_text(text+'\n'+lower_text);
810 cell.render();
815 cell.render();
811 };
816 };
812 this.delete_cell(index+1);
817 this.delete_cell(index+1);
813 this.select(this.find_cell_index(cell));
818 this.select(this.find_cell_index(cell));
814 };
819 };
815 };
820 };
816
821
817
822
818 // Cell collapsing and output clearing
823 // Cell collapsing and output clearing
819
824
820 Notebook.prototype.collapse = function (index) {
825 Notebook.prototype.collapse = function (index) {
821 var i = this.index_or_selected(index);
826 var i = this.index_or_selected(index);
822 this.get_cell(i).collapse();
827 this.get_cell(i).collapse();
823 this.dirty = true;
828 this.dirty = true;
824 };
829 };
825
830
826
831
827 Notebook.prototype.expand = function (index) {
832 Notebook.prototype.expand = function (index) {
828 var i = this.index_or_selected(index);
833 var i = this.index_or_selected(index);
829 this.get_cell(i).expand();
834 this.get_cell(i).expand();
830 this.dirty = true;
835 this.dirty = true;
831 };
836 };
832
837
833
838
834 Notebook.prototype.toggle_output = function (index) {
839 Notebook.prototype.toggle_output = function (index) {
835 var i = this.index_or_selected(index);
840 var i = this.index_or_selected(index);
836 this.get_cell(i).toggle_output();
841 this.get_cell(i).toggle_output();
837 this.dirty = true;
842 this.dirty = true;
838 };
843 };
839
844
840
845
841 Notebook.prototype.set_timebeforetooltip = function (time) {
846 Notebook.prototype.set_timebeforetooltip = function (time) {
842 this.time_before_tooltip = time;
847 this.time_before_tooltip = time;
843 };
848 };
844
849
845
850
846 Notebook.prototype.set_tooltipontab = function (state) {
851 Notebook.prototype.set_tooltipontab = function (state) {
847 this.tooltip_on_tab = state;
852 this.tooltip_on_tab = state;
848 };
853 };
849
854
850
855
851 Notebook.prototype.set_smartcompleter = function (state) {
856 Notebook.prototype.set_smartcompleter = function (state) {
852 this.smart_completer = state;
857 this.smart_completer = state;
853 };
858 };
854
859
855
860
856 Notebook.prototype.clear_all_output = function () {
861 Notebook.prototype.clear_all_output = function () {
857 var ncells = this.ncells();
862 var ncells = this.ncells();
858 var cells = this.get_cells();
863 var cells = this.get_cells();
859 for (var i=0; i<ncells; i++) {
864 for (var i=0; i<ncells; i++) {
860 if (cells[i] instanceof IPython.CodeCell) {
865 if (cells[i] instanceof IPython.CodeCell) {
861 cells[i].clear_output(true,true,true);
866 cells[i].clear_output(true,true,true);
862 }
867 }
863 };
868 };
864 this.dirty = true;
869 this.dirty = true;
865 };
870 };
866
871
867
872
868 // Other cell functions: line numbers, ...
873 // Other cell functions: line numbers, ...
869
874
870 Notebook.prototype.cell_toggle_line_numbers = function() {
875 Notebook.prototype.cell_toggle_line_numbers = function() {
871 this.get_selected_cell().toggle_line_numbers();
876 this.get_selected_cell().toggle_line_numbers();
872 };
877 };
873
878
874 // Kernel related things
879 // Kernel related things
875
880
876 Notebook.prototype.start_kernel = function () {
881 Notebook.prototype.start_kernel = function () {
877 this.kernel = new IPython.Kernel();
882 this.kernel = new IPython.Kernel();
878 var notebook_id = IPython.save_widget.get_notebook_id();
883 var notebook_id = IPython.save_widget.get_notebook_id();
879 this.kernel.start(notebook_id, $.proxy(this.kernel_started, this));
884 this.kernel.start(notebook_id, $.proxy(this.kernel_started, this));
880 };
885 };
881
886
882
887
883 Notebook.prototype.restart_kernel = function () {
888 Notebook.prototype.restart_kernel = function () {
884 var that = this;
889 var that = this;
885 var notebook_id = IPython.save_widget.get_notebook_id();
890 var notebook_id = IPython.save_widget.get_notebook_id();
886
891
887 var dialog = $('<div/>');
892 var dialog = $('<div/>');
888 dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.');
893 dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.');
889 $(document).append(dialog);
894 $(document).append(dialog);
890 dialog.dialog({
895 dialog.dialog({
891 resizable: false,
896 resizable: false,
892 modal: true,
897 modal: true,
893 title: "Restart kernel or continue running?",
898 title: "Restart kernel or continue running?",
894 closeText: '',
899 closeText: '',
895 buttons : {
900 buttons : {
896 "Restart": function () {
901 "Restart": function () {
897 that.kernel.restart($.proxy(that.kernel_started, that));
902 that.kernel.restart($.proxy(that.kernel_started, that));
898 $(this).dialog('close');
903 $(this).dialog('close');
899 },
904 },
900 "Continue running": function () {
905 "Continue running": function () {
901 $(this).dialog('close');
906 $(this).dialog('close');
902 }
907 }
903 }
908 }
904 });
909 });
905 };
910 };
906
911
907
912
908 Notebook.prototype.kernel_started = function () {
913 Notebook.prototype.kernel_started = function () {
909 console.log("Kernel started: ", this.kernel.kernel_id);
914 console.log("Kernel started: ", this.kernel.kernel_id);
910 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
915 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
911 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
916 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
912 };
917 };
913
918
914
919
915 Notebook.prototype.handle_shell_reply = function (e) {
920 Notebook.prototype.handle_shell_reply = function (e) {
916 reply = $.parseJSON(e.data);
921 reply = $.parseJSON(e.data);
917 var header = reply.header;
922 var header = reply.header;
918 var content = reply.content;
923 var content = reply.content;
919 var msg_type = header.msg_type;
924 var msg_type = header.msg_type;
920 // console.log(reply);
925 // console.log(reply);
921 var cell = this.cell_for_msg(reply.parent_header.msg_id);
926 var cell = this.cell_for_msg(reply.parent_header.msg_id);
922 if (msg_type === "execute_reply") {
927 if (msg_type === "execute_reply") {
923 cell.set_input_prompt(content.execution_count);
928 cell.set_input_prompt(content.execution_count);
924 cell.element.removeClass("running");
929 cell.element.removeClass("running");
925 this.dirty = true;
930 this.dirty = true;
926 } else if (msg_type === "complete_reply") {
931 } else if (msg_type === "complete_reply") {
927 cell.finish_completing(content.matched_text, content.matches);
932 cell.finish_completing(content.matched_text, content.matches);
928 } else if (msg_type === "object_info_reply"){
933 } else if (msg_type === "object_info_reply"){
929 //console.log('back from object_info_request : ')
934 //console.log('back from object_info_request : ')
930 rep = reply.content;
935 rep = reply.content;
931 if(rep.found)
936 if(rep.found)
932 {
937 {
933 cell.finish_tooltip(rep);
938 cell.finish_tooltip(rep);
934 }
939 }
935 } else {
940 } else {
936 //console.log("unknown reply:"+msg_type);
941 //console.log("unknown reply:"+msg_type);
937 }
942 }
938 // when having a rely from object_info_reply,
943 // when having a rely from object_info_reply,
939 // no payload so no nned to handle it
944 // no payload so no nned to handle it
940 if(typeof(content.payload)!='undefined') {
945 if(typeof(content.payload)!='undefined') {
941 var payload = content.payload || [];
946 var payload = content.payload || [];
942 this.handle_payload(cell, payload);
947 this.handle_payload(cell, payload);
943 }
948 }
944 };
949 };
945
950
946
951
947 Notebook.prototype.handle_payload = function (cell, payload) {
952 Notebook.prototype.handle_payload = function (cell, payload) {
948 var l = payload.length;
953 var l = payload.length;
949 for (var i=0; i<l; i++) {
954 for (var i=0; i<l; i++) {
950 if (payload[i].source === 'IPython.zmq.page.page') {
955 if (payload[i].source === 'IPython.zmq.page.page') {
951 if (payload[i].text.trim() !== '') {
956 if (payload[i].text.trim() !== '') {
952 IPython.pager.clear();
957 IPython.pager.clear();
953 IPython.pager.expand();
958 IPython.pager.expand();
954 IPython.pager.append_text(payload[i].text);
959 IPython.pager.append_text(payload[i].text);
955 }
960 }
956 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
961 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
957 var index = this.find_cell_index(cell);
962 var index = this.find_cell_index(cell);
958 var new_cell = this.insert_cell_below('code',index);
963 var new_cell = this.insert_cell_below('code',index);
959 new_cell.set_text(payload[i].text);
964 new_cell.set_text(payload[i].text);
960 this.dirty = true;
965 this.dirty = true;
961 }
966 }
962 };
967 };
963 };
968 };
964
969
965
970
966 Notebook.prototype.handle_iopub_reply = function (e) {
971 Notebook.prototype.handle_iopub_reply = function (e) {
967 reply = $.parseJSON(e.data);
972 reply = $.parseJSON(e.data);
968 var content = reply.content;
973 var content = reply.content;
969 // console.log(reply);
974 // console.log(reply);
970 var msg_type = reply.header.msg_type;
975 var msg_type = reply.header.msg_type;
971 var cell = this.cell_for_msg(reply.parent_header.msg_id);
976 var cell = this.cell_for_msg(reply.parent_header.msg_id);
972 if (msg_type !== 'status' && !cell){
977 if (msg_type !== 'status' && !cell){
973 // message not from this notebook, but should be attached to a cell
978 // message not from this notebook, but should be attached to a cell
974 console.log("Received IOPub message not caused by one of my cells");
979 console.log("Received IOPub message not caused by one of my cells");
975 console.log(reply);
980 console.log(reply);
976 return;
981 return;
977 }
982 }
978 var output_types = ['stream','display_data','pyout','pyerr'];
983 var output_types = ['stream','display_data','pyout','pyerr'];
979 if (output_types.indexOf(msg_type) >= 0) {
984 if (output_types.indexOf(msg_type) >= 0) {
980 this.handle_output(cell, msg_type, content);
985 this.handle_output(cell, msg_type, content);
981 } else if (msg_type === 'status') {
986 } else if (msg_type === 'status') {
982 if (content.execution_state === 'busy') {
987 if (content.execution_state === 'busy') {
983 IPython.kernel_status_widget.status_busy();
988 IPython.kernel_status_widget.status_busy();
984 } else if (content.execution_state === 'idle') {
989 } else if (content.execution_state === 'idle') {
985 IPython.kernel_status_widget.status_idle();
990 IPython.kernel_status_widget.status_idle();
986 } else if (content.execution_state === 'dead') {
991 } else if (content.execution_state === 'dead') {
987 this.handle_status_dead();
992 this.handle_status_dead();
988 };
993 };
989 } else if (msg_type === 'clear_output') {
994 } else if (msg_type === 'clear_output') {
990 cell.clear_output(content.stdout, content.stderr, content.other);
995 cell.clear_output(content.stdout, content.stderr, content.other);
991 };
996 };
992 };
997 };
993
998
994
999
995 Notebook.prototype.handle_status_dead = function () {
1000 Notebook.prototype.handle_status_dead = function () {
996 var that = this;
1001 var that = this;
997 this.kernel.stop_channels();
1002 this.kernel.stop_channels();
998 var dialog = $('<div/>');
1003 var dialog = $('<div/>');
999 dialog.html('The kernel has died, would you like to restart it? If you do not restart the kernel, you will be able to save the notebook, but running code will not work until the notebook is reopened.');
1004 dialog.html('The kernel has died, would you like to restart it? If you do not restart the kernel, you will be able to save the notebook, but running code will not work until the notebook is reopened.');
1000 $(document).append(dialog);
1005 $(document).append(dialog);
1001 dialog.dialog({
1006 dialog.dialog({
1002 resizable: false,
1007 resizable: false,
1003 modal: true,
1008 modal: true,
1004 title: "Dead kernel",
1009 title: "Dead kernel",
1005 buttons : {
1010 buttons : {
1006 "Restart": function () {
1011 "Restart": function () {
1007 that.start_kernel();
1012 that.start_kernel();
1008 $(this).dialog('close');
1013 $(this).dialog('close');
1009 },
1014 },
1010 "Continue running": function () {
1015 "Continue running": function () {
1011 $(this).dialog('close');
1016 $(this).dialog('close');
1012 }
1017 }
1013 }
1018 }
1014 });
1019 });
1015 };
1020 };
1016
1021
1017
1022
1018 Notebook.prototype.handle_output = function (cell, msg_type, content) {
1023 Notebook.prototype.handle_output = function (cell, msg_type, content) {
1019 var json = {};
1024 var json = {};
1020 json.output_type = msg_type;
1025 json.output_type = msg_type;
1021 if (msg_type === "stream") {
1026 if (msg_type === "stream") {
1022 json.text = content.data;
1027 json.text = content.data;
1023 json.stream = content.name;
1028 json.stream = content.name;
1024 } else if (msg_type === "display_data") {
1029 } else if (msg_type === "display_data") {
1025 json = this.convert_mime_types(json, content.data);
1030 json = this.convert_mime_types(json, content.data);
1026 } else if (msg_type === "pyout") {
1031 } else if (msg_type === "pyout") {
1027 json.prompt_number = content.execution_count;
1032 json.prompt_number = content.execution_count;
1028 json = this.convert_mime_types(json, content.data);
1033 json = this.convert_mime_types(json, content.data);
1029 } else if (msg_type === "pyerr") {
1034 } else if (msg_type === "pyerr") {
1030 json.ename = content.ename;
1035 json.ename = content.ename;
1031 json.evalue = content.evalue;
1036 json.evalue = content.evalue;
1032 json.traceback = content.traceback;
1037 json.traceback = content.traceback;
1033 };
1038 };
1034 cell.append_output(json);
1039 cell.append_output(json);
1035 this.dirty = true;
1040 this.dirty = true;
1036 };
1041 };
1037
1042
1038
1043
1039 Notebook.prototype.convert_mime_types = function (json, data) {
1044 Notebook.prototype.convert_mime_types = function (json, data) {
1040 if (data['text/plain'] !== undefined) {
1045 if (data['text/plain'] !== undefined) {
1041 json.text = data['text/plain'];
1046 json.text = data['text/plain'];
1042 };
1047 };
1043 if (data['text/html'] !== undefined) {
1048 if (data['text/html'] !== undefined) {
1044 json.html = data['text/html'];
1049 json.html = data['text/html'];
1045 };
1050 };
1046 if (data['image/svg+xml'] !== undefined) {
1051 if (data['image/svg+xml'] !== undefined) {
1047 json.svg = data['image/svg+xml'];
1052 json.svg = data['image/svg+xml'];
1048 };
1053 };
1049 if (data['image/png'] !== undefined) {
1054 if (data['image/png'] !== undefined) {
1050 json.png = data['image/png'];
1055 json.png = data['image/png'];
1051 };
1056 };
1052 if (data['image/jpeg'] !== undefined) {
1057 if (data['image/jpeg'] !== undefined) {
1053 json.jpeg = data['image/jpeg'];
1058 json.jpeg = data['image/jpeg'];
1054 };
1059 };
1055 if (data['text/latex'] !== undefined) {
1060 if (data['text/latex'] !== undefined) {
1056 json.latex = data['text/latex'];
1061 json.latex = data['text/latex'];
1057 };
1062 };
1058 if (data['application/json'] !== undefined) {
1063 if (data['application/json'] !== undefined) {
1059 json.json = data['application/json'];
1064 json.json = data['application/json'];
1060 };
1065 };
1061 if (data['application/javascript'] !== undefined) {
1066 if (data['application/javascript'] !== undefined) {
1062 json.javascript = data['application/javascript'];
1067 json.javascript = data['application/javascript'];
1063 }
1068 }
1064 return json;
1069 return json;
1065 };
1070 };
1066
1071
1067
1072
1068 Notebook.prototype.execute_selected_cell = function (options) {
1073 Notebook.prototype.execute_selected_cell = function (options) {
1069 // add_new: should a new cell be added if we are at the end of the nb
1074 // add_new: should a new cell be added if we are at the end of the nb
1070 // terminal: execute in terminal mode, which stays in the current cell
1075 // terminal: execute in terminal mode, which stays in the current cell
1071 default_options = {terminal: false, add_new: true};
1076 default_options = {terminal: false, add_new: true};
1072 $.extend(default_options, options);
1077 $.extend(default_options, options);
1073 var that = this;
1078 var that = this;
1074 var cell = that.get_selected_cell();
1079 var cell = that.get_selected_cell();
1075 var cell_index = that.find_cell_index(cell);
1080 var cell_index = that.find_cell_index(cell);
1076 if (cell instanceof IPython.CodeCell) {
1081 if (cell instanceof IPython.CodeCell) {
1077 cell.clear_output(true, true, true);
1082 cell.clear_output(true, true, true);
1078 cell.set_input_prompt('*');
1083 cell.set_input_prompt('*');
1079 cell.element.addClass("running");
1084 cell.element.addClass("running");
1080 var code = cell.get_text();
1085 var code = cell.get_text();
1081 var msg_id = that.kernel.execute(cell.get_text());
1086 var msg_id = that.kernel.execute(cell.get_text());
1082 that.msg_cell_map[msg_id] = cell.cell_id;
1087 that.msg_cell_map[msg_id] = cell.cell_id;
1083 } else if (cell instanceof IPython.HTMLCell) {
1088 } else if (cell instanceof IPython.HTMLCell) {
1084 cell.render();
1089 cell.render();
1085 }
1090 }
1086 if (default_options.terminal) {
1091 if (default_options.terminal) {
1087 cell.select_all();
1092 cell.select_all();
1088 } else {
1093 } else {
1089 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
1094 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
1090 that.insert_cell_below('code');
1095 that.insert_cell_below('code');
1091 // If we are adding a new cell at the end, scroll down to show it.
1096 // If we are adding a new cell at the end, scroll down to show it.
1092 that.scroll_to_bottom();
1097 that.scroll_to_bottom();
1093 } else {
1098 } else {
1094 that.select(cell_index+1);
1099 that.select(cell_index+1);
1095 };
1100 };
1096 };
1101 };
1097 this.dirty = true;
1102 this.dirty = true;
1098 };
1103 };
1099
1104
1100
1105
1101 Notebook.prototype.execute_all_cells = function () {
1106 Notebook.prototype.execute_all_cells = function () {
1102 var ncells = this.ncells();
1107 var ncells = this.ncells();
1103 for (var i=0; i<ncells; i++) {
1108 for (var i=0; i<ncells; i++) {
1104 this.select(i);
1109 this.select(i);
1105 this.execute_selected_cell({add_new:false});
1110 this.execute_selected_cell({add_new:false});
1106 };
1111 };
1107 this.scroll_to_bottom();
1112 this.scroll_to_bottom();
1108 };
1113 };
1109
1114
1110
1115
1111 Notebook.prototype.request_tool_tip = function (cell,func) {
1116 Notebook.prototype.request_tool_tip = function (cell,func) {
1112 // Feel free to shorten this logic if you are better
1117 // Feel free to shorten this logic if you are better
1113 // than me in regEx
1118 // than me in regEx
1114 // basicaly you shoul be able to get xxx.xxx.xxx from
1119 // basicaly you shoul be able to get xxx.xxx.xxx from
1115 // something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2,
1120 // something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2,
1116 // remove everything between matchin bracket (need to iterate)
1121 // remove everything between matchin bracket (need to iterate)
1117 matchBracket = /\([^\(\)]+\)/g;
1122 matchBracket = /\([^\(\)]+\)/g;
1118 oldfunc = func;
1123 oldfunc = func;
1119 func = func.replace(matchBracket,"");
1124 func = func.replace(matchBracket,"");
1120 while( oldfunc != func )
1125 while( oldfunc != func )
1121 {
1126 {
1122 oldfunc = func;
1127 oldfunc = func;
1123 func = func.replace(matchBracket,"");
1128 func = func.replace(matchBracket,"");
1124 }
1129 }
1125 // remove everythin after last open bracket
1130 // remove everythin after last open bracket
1126 endBracket = /\([^\(]*$/g;
1131 endBracket = /\([^\(]*$/g;
1127 func = func.replace(endBracket,"");
1132 func = func.replace(endBracket,"");
1128 var re = /[a-zA-Z._]+$/g;
1133 var re = /[a-zA-Z._]+$/g;
1129 var msg_id = this.kernel.object_info_request(re.exec(func));
1134 var msg_id = this.kernel.object_info_request(re.exec(func));
1130 if(typeof(msg_id)!='undefined'){
1135 if(typeof(msg_id)!='undefined'){
1131 this.msg_cell_map[msg_id] = cell.cell_id;
1136 this.msg_cell_map[msg_id] = cell.cell_id;
1132 }
1137 }
1133 };
1138 };
1134
1139
1135 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
1140 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
1136 var msg_id = this.kernel.complete(line, cursor_pos);
1141 var msg_id = this.kernel.complete(line, cursor_pos);
1137 this.msg_cell_map[msg_id] = cell.cell_id;
1142 this.msg_cell_map[msg_id] = cell.cell_id;
1138 };
1143 };
1139
1144
1140 // Persistance and loading
1145 // Persistance and loading
1141
1146
1142
1147
1143 Notebook.prototype.fromJSON = function (data) {
1148 Notebook.prototype.fromJSON = function (data) {
1144 var ncells = this.ncells();
1149 var ncells = this.ncells();
1145 var i;
1150 var i;
1146 for (i=0; i<ncells; i++) {
1151 for (i=0; i<ncells; i++) {
1147 // Always delete cell 0 as they get renumbered as they are deleted.
1152 // Always delete cell 0 as they get renumbered as they are deleted.
1148 this.delete_cell(0);
1153 this.delete_cell(0);
1149 };
1154 };
1150 // Save the metadata
1155 // Save the metadata
1151 this.metadata = data.metadata;
1156 this.metadata = data.metadata;
1152 // Only handle 1 worksheet for now.
1157 // Only handle 1 worksheet for now.
1153 var worksheet = data.worksheets[0];
1158 var worksheet = data.worksheets[0];
1154 if (worksheet !== undefined) {
1159 if (worksheet !== undefined) {
1155 var new_cells = worksheet.cells;
1160 var new_cells = worksheet.cells;
1156 ncells = new_cells.length;
1161 ncells = new_cells.length;
1157 var cell_data = null;
1162 var cell_data = null;
1158 var new_cell = null;
1163 var new_cell = null;
1159 for (i=0; i<ncells; i++) {
1164 for (i=0; i<ncells; i++) {
1160 cell_data = new_cells[i];
1165 cell_data = new_cells[i];
1161 new_cell = this.insert_cell_below(cell_data.cell_type);
1166 new_cell = this.insert_cell_below(cell_data.cell_type);
1162 new_cell.fromJSON(cell_data);
1167 new_cell.fromJSON(cell_data);
1163 };
1168 };
1164 };
1169 };
1165 };
1170 };
1166
1171
1167
1172
1168 Notebook.prototype.toJSON = function () {
1173 Notebook.prototype.toJSON = function () {
1169 var cells = this.get_cells();
1174 var cells = this.get_cells();
1170 var ncells = cells.length;
1175 var ncells = cells.length;
1171 cell_array = new Array(ncells);
1176 cell_array = new Array(ncells);
1172 for (var i=0; i<ncells; i++) {
1177 for (var i=0; i<ncells; i++) {
1173 cell_array[i] = cells[i].toJSON();
1178 cell_array[i] = cells[i].toJSON();
1174 };
1179 };
1175 data = {
1180 data = {
1176 // Only handle 1 worksheet for now.
1181 // Only handle 1 worksheet for now.
1177 worksheets : [{cells:cell_array}],
1182 worksheets : [{cells:cell_array}],
1178 metadata : this.metadata
1183 metadata : this.metadata
1179 };
1184 };
1180 return data;
1185 return data;
1181 };
1186 };
1182
1187
1183 Notebook.prototype.save_notebook = function () {
1188 Notebook.prototype.save_notebook = function () {
1184 var notebook_id = IPython.save_widget.get_notebook_id();
1189 var notebook_id = IPython.save_widget.get_notebook_id();
1185 var nbname = IPython.save_widget.get_notebook_name();
1190 var nbname = IPython.save_widget.get_notebook_name();
1186 // We may want to move the name/id/nbformat logic inside toJSON?
1191 // We may want to move the name/id/nbformat logic inside toJSON?
1187 var data = this.toJSON();
1192 var data = this.toJSON();
1188 data.metadata.name = nbname;
1193 data.metadata.name = nbname;
1189 data.nbformat = 2;
1194 data.nbformat = 2;
1190 // We do the call with settings so we can set cache to false.
1195 // We do the call with settings so we can set cache to false.
1191 var settings = {
1196 var settings = {
1192 processData : false,
1197 processData : false,
1193 cache : false,
1198 cache : false,
1194 type : "PUT",
1199 type : "PUT",
1195 data : JSON.stringify(data),
1200 data : JSON.stringify(data),
1196 headers : {'Content-Type': 'application/json'},
1201 headers : {'Content-Type': 'application/json'},
1197 success : $.proxy(this.notebook_saved,this),
1202 success : $.proxy(this.notebook_saved,this),
1198 error : $.proxy(this.notebook_save_failed,this)
1203 error : $.proxy(this.notebook_save_failed,this)
1199 };
1204 };
1200 IPython.save_widget.status_saving();
1205 IPython.save_widget.status_saving();
1201 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id;
1206 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id;
1202 $.ajax(url, settings);
1207 $.ajax(url, settings);
1203 };
1208 };
1204
1209
1205
1210
1206 Notebook.prototype.notebook_saved = function (data, status, xhr) {
1211 Notebook.prototype.notebook_saved = function (data, status, xhr) {
1207 this.dirty = false;
1212 this.dirty = false;
1208 IPython.save_widget.notebook_saved();
1213 IPython.save_widget.notebook_saved();
1209 IPython.save_widget.status_last_saved();
1214 IPython.save_widget.status_last_saved();
1210 };
1215 };
1211
1216
1212
1217
1213 Notebook.prototype.notebook_save_failed = function (xhr, status, error_msg) {
1218 Notebook.prototype.notebook_save_failed = function (xhr, status, error_msg) {
1214 IPython.save_widget.status_save_failed();
1219 IPython.save_widget.status_save_failed();
1215 };
1220 };
1216
1221
1217
1222
1218 Notebook.prototype.load_notebook = function () {
1223 Notebook.prototype.load_notebook = function () {
1219 var that = this;
1224 var that = this;
1220 var notebook_id = IPython.save_widget.get_notebook_id();
1225 var notebook_id = IPython.save_widget.get_notebook_id();
1221 // We do the call with settings so we can set cache to false.
1226 // We do the call with settings so we can set cache to false.
1222 var settings = {
1227 var settings = {
1223 processData : false,
1228 processData : false,
1224 cache : false,
1229 cache : false,
1225 type : "GET",
1230 type : "GET",
1226 dataType : "json",
1231 dataType : "json",
1227 success : function (data, status, xhr) {
1232 success : function (data, status, xhr) {
1228 that.notebook_loaded(data, status, xhr);
1233 that.notebook_loaded(data, status, xhr);
1229 }
1234 }
1230 };
1235 };
1231 IPython.save_widget.status_loading();
1236 IPython.save_widget.status_loading();
1232 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id;
1237 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id;
1233 $.ajax(url, settings);
1238 $.ajax(url, settings);
1234 };
1239 };
1235
1240
1236
1241
1237 Notebook.prototype.notebook_loaded = function (data, status, xhr) {
1242 Notebook.prototype.notebook_loaded = function (data, status, xhr) {
1238 this.fromJSON(data);
1243 this.fromJSON(data);
1239 if (this.ncells() === 0) {
1244 if (this.ncells() === 0) {
1240 this.insert_cell_below('code');
1245 this.insert_cell_below('code');
1241 };
1246 };
1242 IPython.save_widget.status_last_saved();
1247 IPython.save_widget.status_last_saved();
1243 IPython.save_widget.set_notebook_name(data.metadata.name);
1248 IPython.save_widget.set_notebook_name(data.metadata.name);
1244 this.dirty = false;
1249 this.dirty = false;
1245 if (! this.read_only) {
1250 if (! this.read_only) {
1246 this.start_kernel();
1251 this.start_kernel();
1247 }
1252 }
1248 this.select(0);
1253 this.select(0);
1249 this.scroll_to_top();
1254 this.scroll_to_top();
1250 IPython.save_widget.update_url();
1255 IPython.save_widget.update_url();
1251 IPython.layout_manager.do_resize();
1256 IPython.layout_manager.do_resize();
1252 };
1257 };
1253
1258
1254 IPython.Notebook = Notebook;
1259 IPython.Notebook = Notebook;
1255
1260
1256
1261
1257 return IPython;
1262 return IPython;
1258
1263
1259 }(IPython));
1264 }(IPython));
1260
1265
@@ -1,132 +1,146 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // ToolBar
9 // ToolBar
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var ToolBar = function (selector) {
14 var ToolBar = function (selector) {
15 this.selector = selector;
15 this.selector = selector;
16 if (this.selector !== undefined) {
16 if (this.selector !== undefined) {
17 this.element = $(selector);
17 this.element = $(selector);
18 this.style();
18 this.style();
19 this.bind_events();
19 this.bind_events();
20 }
20 }
21 };
21 };
22
22
23
23
24 ToolBar.prototype.style = function () {
24 ToolBar.prototype.style = function () {
25 this.element.addClass('border-box-sizing');
25 this.element.addClass('border-box-sizing');
26 this.element.find('#cell_type').addClass('ui-widget ui-widget-content');
26 this.element.find('#cell_type').addClass('ui-widget ui-widget-content');
27 this.element.find('#save_b').button({
27 this.element.find('#save_b').button({
28 icons : {primary: 'ui-icon-disk'},
28 icons : {primary: 'ui-icon-disk'},
29 text : false
29 text : false
30 });
30 });
31 this.element.find('#cut_b').button({
31 this.element.find('#cut_b').button({
32 icons: {primary: 'ui-icon-scissors'},
32 icons: {primary: 'ui-icon-scissors'},
33 text : false
33 text : false
34 });
34 });
35 this.element.find('#copy_b').button({
35 this.element.find('#copy_b').button({
36 icons: {primary: 'ui-icon-copy'},
36 icons: {primary: 'ui-icon-copy'},
37 text : false
37 text : false
38 });
38 });
39 this.element.find('#paste_b').button({
39 this.element.find('#paste_b').button({
40 icons: {primary: 'ui-icon-clipboard'},
40 icons: {primary: 'ui-icon-clipboard'},
41 text : false
41 text : false
42 });
42 });
43 this.element.find('#cut_copy_paste').buttonset();
43 this.element.find('#cut_copy_paste').buttonset();
44 this.element.find('#move_up_b').button({
44 this.element.find('#move_up_b').button({
45 icons: {primary: 'ui-icon-arrowthick-1-n'},
45 icons: {primary: 'ui-icon-arrowthick-1-n'},
46 text : false
46 text : false
47 });
47 });
48 this.element.find('#move_down_b').button({
48 this.element.find('#move_down_b').button({
49 icons: {primary: 'ui-icon-arrowthick-1-s'},
49 icons: {primary: 'ui-icon-arrowthick-1-s'},
50 text : false
50 text : false
51 });
51 });
52 this.element.find('#move_up_down').buttonset();
52 this.element.find('#move_up_down').buttonset();
53 this.element.find('#insert_above_b').button({
53 this.element.find('#insert_above_b').button({
54 icons: {primary: 'ui-icon-arrowthickstop-1-n'},
54 icons: {primary: 'ui-icon-arrowthickstop-1-n'},
55 text : false
55 text : false
56 });
56 });
57 this.element.find('#insert_below_b').button({
57 this.element.find('#insert_below_b').button({
58 icons: {primary: 'ui-icon-arrowthickstop-1-s'},
58 icons: {primary: 'ui-icon-arrowthickstop-1-s'},
59 text : false
59 text : false
60 });
60 });
61 this.element.find('#insert_above_below').buttonset();
61 this.element.find('#insert_above_below').buttonset();
62 this.element.find('#run_b').button({
62 this.element.find('#run_b').button({
63 icons: {primary: 'ui-icon-play'},
63 icons: {primary: 'ui-icon-play'},
64 text : false
64 text : false
65 });
65 });
66 this.element.find('#interrupt_b').button({
66 this.element.find('#interrupt_b').button({
67 icons: {primary: 'ui-icon-stop'},
67 icons: {primary: 'ui-icon-stop'},
68 text : false
68 text : false
69 });
69 });
70 this.element.find('#run_int').buttonset();
70 this.element.find('#run_int').buttonset();
71 };
71 };
72
72
73
73
74 ToolBar.prototype.bind_events = function () {
74 ToolBar.prototype.bind_events = function () {
75 this.element.find('#save_b').click(function () {
75 this.element.find('#save_b').click(function () {
76 IPython.save_widget.save_notebook();
76 IPython.save_widget.save_notebook();
77 });
77 });
78 this.element.find('#cut_b').click(function () {
78 this.element.find('#cut_b').click(function () {
79 IPython.notebook.cut_cell();
79 IPython.notebook.cut_cell();
80 });
80 });
81 this.element.find('#copy_b').click(function () {
81 this.element.find('#copy_b').click(function () {
82 IPython.notebook.copy_cell();
82 IPython.notebook.copy_cell();
83 });
83 });
84 this.element.find('#paste_b').click(function () {
84 this.element.find('#paste_b').click(function () {
85 IPython.notebook.paste_cell();
85 IPython.notebook.paste_cell();
86 });
86 });
87 this.element.find('#move_up_b').click(function () {
87 this.element.find('#move_up_b').click(function () {
88 IPython.notebook.move_cell_up();
88 IPython.notebook.move_cell_up();
89 });
89 });
90 this.element.find('#move_down_b').click(function () {
90 this.element.find('#move_down_b').click(function () {
91 IPython.notebook.move_cell_down();
91 IPython.notebook.move_cell_down();
92 });
92 });
93 this.element.find('#insert_above_b').click(function () {
93 this.element.find('#insert_above_b').click(function () {
94 IPython.notebook.insert_cell_above('code');
94 IPython.notebook.insert_cell_above('code');
95 });
95 });
96 this.element.find('#insert_below_b').click(function () {
96 this.element.find('#insert_below_b').click(function () {
97 IPython.notebook.insert_cell_below('code');
97 IPython.notebook.insert_cell_below('code');
98 });
98 });
99 this.element.find('#run_b').click(function () {
99 this.element.find('#run_b').click(function () {
100 IPython.notebook.execute_selected_cell();
100 IPython.notebook.execute_selected_cell();
101 });
101 });
102 this.element.find('#interrupt_b').click(function () {
102 this.element.find('#interrupt_b').click(function () {
103 IPython.notebook.kernel.interrupt();
103 IPython.notebook.kernel.interrupt();
104 });
104 });
105 this.element.find('#cell_type').change(function () {
105 this.element.find('#cell_type').change(function () {
106 var cell_type = $(this).val();
106 var cell_type = $(this).val();
107 if (cell_type === 'code') {
107 if (cell_type === 'code') {
108 IPython.notebook.to_code();
108 IPython.notebook.to_code();
109 } else if (cell_type === 'markdown') {
109 } else if (cell_type === 'markdown') {
110 IPython.notebook.to_markdown();
110 IPython.notebook.to_markdown();
111 } else if (cell_type === 'plaintext') {
112 IPython.notebook.to_plaintext();
113 } else if (cell_type === 'heading1') {
114 IPython.notebook.to_heading(undefined, 1);
115 } else if (cell_type === 'heading2') {
116 IPython.notebook.to_heading(undefined, 2);
117 } else if (cell_type === 'heading3') {
118 IPython.notebook.to_heading(undefined, 3);
119 } else if (cell_type === 'heading4') {
120 IPython.notebook.to_heading(undefined, 4);
121 } else if (cell_type === 'heading5') {
122 IPython.notebook.to_heading(undefined, 5);
123 } else if (cell_type === 'heading6') {
124 IPython.notebook.to_heading(undefined, 6);
111 };
125 };
112 });
126 });
113
127
114 };
128 };
115
129
116
130
117 ToolBar.prototype.set_cell_type = function (cell_type) {
131 ToolBar.prototype.set_cell_type = function (cell_type) {
118 this.element.find('#cell_type').val(cell_type);
132 this.element.find('#cell_type').val(cell_type);
119 };
133 };
120
134
121
135
122 ToolBar.prototype.toggle = function () {
136 ToolBar.prototype.toggle = function () {
123 this.element.toggle();
137 this.element.toggle();
124 IPython.layout_manager.do_resize();
138 IPython.layout_manager.do_resize();
125 };
139 };
126
140
127
141
128 IPython.ToolBar = ToolBar;
142 IPython.ToolBar = ToolBar;
129
143
130 return IPython;
144 return IPython;
131
145
132 }(IPython));
146 }(IPython));
@@ -1,234 +1,241 b''
1 <!DOCTYPE HTML>
1 <!DOCTYPE HTML>
2 <html>
2 <html>
3
3
4 <head>
4 <head>
5 <meta charset="utf-8">
5 <meta charset="utf-8">
6
6
7 <title>IPython Notebook</title>
7 <title>IPython Notebook</title>
8
8
9 {% if mathjax_url %}
9 {% if mathjax_url %}
10 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML" charset="utf-8"></script>
10 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML" charset="utf-8"></script>
11 {% end %}
11 {% end %}
12 <script type="text/javascript">
12 <script type="text/javascript">
13 // MathJax disabled, set as null to distingish from *missing* MathJax,
13 // MathJax disabled, set as null to distingish from *missing* MathJax,
14 // where it will be undefined, and should prompt a dialog later.
14 // where it will be undefined, and should prompt a dialog later.
15 window.mathjax_url = "{{mathjax_url}}";
15 window.mathjax_url = "{{mathjax_url}}";
16 </script>
16 </script>
17
17
18 <link rel="stylesheet" href="{{ static_url("jquery/css/themes/base/jquery-ui.min.css") }}" type="text/css" />
18 <link rel="stylesheet" href="{{ static_url("jquery/css/themes/base/jquery-ui.min.css") }}" type="text/css" />
19 <link rel="stylesheet" href="{{ static_url("codemirror/lib/codemirror.css") }}">
19 <link rel="stylesheet" href="{{ static_url("codemirror/lib/codemirror.css") }}">
20 <link rel="stylesheet" href="{{ static_url("codemirror/theme/ipython.css") }}">
20 <link rel="stylesheet" href="{{ static_url("codemirror/theme/ipython.css") }}">
21
21
22 <link rel="stylesheet" href="{{ static_url("prettify/prettify.css") }}"/>
22 <link rel="stylesheet" href="{{ static_url("prettify/prettify.css") }}"/>
23
23
24 <link rel="stylesheet" href="{{ static_url("css/boilerplate.css") }}" type="text/css" />
24 <link rel="stylesheet" href="{{ static_url("css/boilerplate.css") }}" type="text/css" />
25 <link rel="stylesheet" href="{{ static_url("css/layout.css") }}" type="text/css" />
25 <link rel="stylesheet" href="{{ static_url("css/layout.css") }}" type="text/css" />
26 <link rel="stylesheet" href="{{ static_url("css/base.css") }}" type="text/css" />
26 <link rel="stylesheet" href="{{ static_url("css/base.css") }}" type="text/css" />
27 <link rel="stylesheet" href="{{ static_url("css/notebook.css") }}" type="text/css" />
27 <link rel="stylesheet" href="{{ static_url("css/notebook.css") }}" type="text/css" />
28 <link rel="stylesheet" href="{{ static_url("css/renderedhtml.css") }}" type="text/css" />
28 <link rel="stylesheet" href="{{ static_url("css/renderedhtml.css") }}" type="text/css" />
29
29
30 {% comment In the notebook, the read-only flag is used to determine %}
30 {% comment In the notebook, the read-only flag is used to determine %}
31 {% comment whether to hide the side panels and switch off input %}
31 {% comment whether to hide the side panels and switch off input %}
32 <meta name="read_only" content="{{read_only and not logged_in}}"/>
32 <meta name="read_only" content="{{read_only and not logged_in}}"/>
33
33
34 </head>
34 </head>
35
35
36 <body
36 <body
37 data-project={{project}} data-notebook-id={{notebook_id}}
37 data-project={{project}} data-notebook-id={{notebook_id}}
38 data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
38 data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
39 >
39 >
40
40
41 <div id="header">
41 <div id="header">
42 <span id="ipython_notebook"><h1><a href='..' alt='dashboard'><img src='{{static_url("ipynblogo.png")}}' alt='IPython Notebook'/></a></h1></span>
42 <span id="ipython_notebook"><h1><a href='..' alt='dashboard'><img src='{{static_url("ipynblogo.png")}}' alt='IPython Notebook'/></a></h1></span>
43 <span id="save_widget">
43 <span id="save_widget">
44 <span id="notebook_name"></span>
44 <span id="notebook_name"></span>
45 <span id="save_status"></span>
45 <span id="save_status"></span>
46 </span>
46 </span>
47
47
48 <span id="login_widget">
48 <span id="login_widget">
49 {% comment This is a temporary workaround to hide the logout button %}
49 {% comment This is a temporary workaround to hide the logout button %}
50 {% comment when appropriate until notebook.html is templated %}
50 {% comment when appropriate until notebook.html is templated %}
51 {% if logged_in %}
51 {% if logged_in %}
52 <button id="logout">Logout</button>
52 <button id="logout">Logout</button>
53 {% elif not logged_in and login_available %}
53 {% elif not logged_in and login_available %}
54 <button id="login">Login</button>
54 <button id="login">Login</button>
55 {% end %}
55 {% end %}
56 </span>
56 </span>
57
57
58 <span id="kernel_status">Idle</span>
58 <span id="kernel_status">Idle</span>
59 </div>
59 </div>
60
60
61 <div id="menubar">
61 <div id="menubar">
62 <ul id="menus">
62 <ul id="menus">
63 <li><a href="#">File</a>
63 <li><a href="#">File</a>
64 <ul>
64 <ul>
65 <li id="new_notebook"><a href="#">New</a></li>
65 <li id="new_notebook"><a href="#">New</a></li>
66 <li id="open_notebook"><a href="#">Open...</a></li>
66 <li id="open_notebook"><a href="#">Open...</a></li>
67 <hr/>
67 <hr/>
68 <li id="copy_notebook"><a href="#">Make a Copy...</a></li>
68 <li id="copy_notebook"><a href="#">Make a Copy...</a></li>
69 <li id="rename_notebook"><a href="#">Rename...</a></li>
69 <li id="rename_notebook"><a href="#">Rename...</a></li>
70 <li id="save_notebook"><a href="#">Save</a></li>
70 <li id="save_notebook"><a href="#">Save</a></li>
71 <hr/>
71 <hr/>
72 <li><a href="#">Download as</a>
72 <li><a href="#">Download as</a>
73 <ul>
73 <ul>
74 <li id="download_ipynb"><a href="#">IPython (.ipynb)</a></li>
74 <li id="download_ipynb"><a href="#">IPython (.ipynb)</a></li>
75 <li id="download_py"><a href="#">Python (.py)</a></li>
75 <li id="download_py"><a href="#">Python (.py)</a></li>
76 </ul>
76 </ul>
77 </li>
77 </li>
78 <hr/>
78 <hr/>
79 <li id="print_notebook"><a href="/{{notebook_id}}/print" target="_blank">Print View</a></li>
79 <li id="print_notebook"><a href="/{{notebook_id}}/print" target="_blank">Print View</a></li>
80 </ul>
80 </ul>
81 </li>
81 </li>
82 <li><a href="#">Edit</a>
82 <li><a href="#">Edit</a>
83 <ul>
83 <ul>
84 <li id="cut_cell"><a href="#">Cut Cell</a></li>
84 <li id="cut_cell"><a href="#">Cut Cell</a></li>
85 <li id="copy_cell"><a href="#">Copy Cell</a></li>
85 <li id="copy_cell"><a href="#">Copy Cell</a></li>
86 <li id="paste_cell" class="ui-state-disabled"><a href="#">Paste Cell</a></li>
86 <li id="paste_cell" class="ui-state-disabled"><a href="#">Paste Cell</a></li>
87 <li id="paste_cell_above" class="ui-state-disabled"><a href="#">Paste Cell Above</a></li>
87 <li id="paste_cell_above" class="ui-state-disabled"><a href="#">Paste Cell Above</a></li>
88 <li id="paste_cell_below" class="ui-state-disabled"><a href="#">Paste Cell Below</a></li>
88 <li id="paste_cell_below" class="ui-state-disabled"><a href="#">Paste Cell Below</a></li>
89 <li id="delete_cell"><a href="#">Delete</a></li>
89 <li id="delete_cell"><a href="#">Delete</a></li>
90 <hr/>
90 <hr/>
91 <li id="split_cell"><a href="#">Split Cell</a></li>
91 <li id="split_cell"><a href="#">Split Cell</a></li>
92 <li id="merge_cell_above"><a href="#">Merge Cell Above</a></li>
92 <li id="merge_cell_above"><a href="#">Merge Cell Above</a></li>
93 <li id="merge_cell_below"><a href="#">Merge Cell Below</a></li>
93 <li id="merge_cell_below"><a href="#">Merge Cell Below</a></li>
94 <hr/>
94 <hr/>
95 <li id="move_cell_up"><a href="#">Move Cell Up</a></li>
95 <li id="move_cell_up"><a href="#">Move Cell Up</a></li>
96 <li id="move_cell_down"><a href="#">Move Cell Down</a></li>
96 <li id="move_cell_down"><a href="#">Move Cell Down</a></li>
97 <hr/>
97 <hr/>
98 <li id="select_previous"><a href="#">Select Previous Cell</a></li>
98 <li id="select_previous"><a href="#">Select Previous Cell</a></li>
99 <li id="select_next"><a href="#">Select Next Cell</a></li>
99 <li id="select_next"><a href="#">Select Next Cell</a></li>
100 </ul>
100 </ul>
101 </li>
101 </li>
102 <li><a href="#">View</a>
102 <li><a href="#">View</a>
103 <ul>
103 <ul>
104 <li id="toggle_header"><a href="#">Toggle Header</a></li>
104 <li id="toggle_header"><a href="#">Toggle Header</a></li>
105 <li id="toggle_toolbar"><a href="#">Toggle Toolbar</a></li>
105 <li id="toggle_toolbar"><a href="#">Toggle Toolbar</a></li>
106 </ul>
106 </ul>
107 </li>
107 </li>
108 <li><a href="#">Insert</a>
108 <li><a href="#">Insert</a>
109 <ul>
109 <ul>
110 <li id="insert_cell_above"><a href="#">Insert Cell Above</a></li>
110 <li id="insert_cell_above"><a href="#">Insert Cell Above</a></li>
111 <li id="insert_cell_below"><a href="#">Insert Cell Below</a></li>
111 <li id="insert_cell_below"><a href="#">Insert Cell Below</a></li>
112 </ul>
112 </ul>
113 </li>
113 </li>
114 <li><a href="#">Cell</a>
114 <li><a href="#">Cell</a>
115 <ul>
115 <ul>
116 <li id="run_cell"><a href="#">Run</a></li>
116 <li id="run_cell"><a href="#">Run</a></li>
117 <li id="run_cell_in_place"><a href="#">Run in Place</a></li>
117 <li id="run_cell_in_place"><a href="#">Run in Place</a></li>
118 <li id="run_all_cells"><a href="#">Run All</a></li>
118 <li id="run_all_cells"><a href="#">Run All</a></li>
119 <hr/>
119 <hr/>
120 <li id="to_code"><a href="#">Code</a></li>
120 <li id="to_code"><a href="#">Code</a></li>
121 <li id="to_markdown"><a href="#">Markdown </a></li>
121 <li id="to_markdown"><a href="#">Markdown </a></li>
122 <li id="to_plaintext"><a href="#">Plaintext</a></li>
122 <li id="to_plaintext"><a href="#">Plaintext</a></li>
123 <li id="to_heading1"><a href="#">Heading 1</a></li>
123 <li id="to_heading1"><a href="#">Heading 1</a></li>
124 <li id="to_heading2"><a href="#">Heading 2</a></li>
124 <li id="to_heading2"><a href="#">Heading 2</a></li>
125 <li id="to_heading3"><a href="#">Heading 3</a></li>
125 <li id="to_heading3"><a href="#">Heading 3</a></li>
126 <li id="to_heading4"><a href="#">Heading 4</a></li>
126 <li id="to_heading4"><a href="#">Heading 4</a></li>
127 <li id="to_heading5"><a href="#">Heading 5</a></li>
127 <li id="to_heading5"><a href="#">Heading 5</a></li>
128 <li id="to_heading6"><a href="#">Heading 6</a></li>
128 <li id="to_heading6"><a href="#">Heading 6</a></li>
129 <hr/>
129 <hr/>
130 <li id="toggle_output"><a href="#">Toggle Output</a></li>
130 <li id="toggle_output"><a href="#">Toggle Output</a></li>
131 <li id="clear_all_output"><a href="#">Clear All Output</a></li>
131 <li id="clear_all_output"><a href="#">Clear All Output</a></li>
132 </ul>
132 </ul>
133 </li>
133 </li>
134 <li><a href="#">Kernel</a>
134 <li><a href="#">Kernel</a>
135 <ul>
135 <ul>
136 <li id="int_kernel"><a href="#">Interrupt</a></li>
136 <li id="int_kernel"><a href="#">Interrupt</a></li>
137 <li id="restart_kernel"><a href="#">Restart</a></li>
137 <li id="restart_kernel"><a href="#">Restart</a></li>
138 </ul>
138 </ul>
139 </li>
139 </li>
140 <li><a href="#">Help</a>
140 <li><a href="#">Help</a>
141 <ul>
141 <ul>
142 <li><a href="http://ipython.org/documentation.html" target="_blank">IPython Help</a></li>
142 <li><a href="http://ipython.org/documentation.html" target="_blank">IPython Help</a></li>
143 <li><a href="http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html" target="_blank">Notebook Help</a></li>
143 <li><a href="http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html" target="_blank">Notebook Help</a></li>
144 <li id="keyboard_shortcuts"><a href="#">Keyboard Shortcuts</a></li>
144 <li id="keyboard_shortcuts"><a href="#">Keyboard Shortcuts</a></li>
145 <hr/>
145 <hr/>
146 <li><a href="http://docs.python.org" target="_blank">Python</a></li>
146 <li><a href="http://docs.python.org" target="_blank">Python</a></li>
147 <li><a href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a></li>
147 <li><a href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a></li>
148 <li><a href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a></li>
148 <li><a href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a></li>
149 <li><a href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a></li>
149 <li><a href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a></li>
150 <li><a href="http://matplotlib.sourceforge.net/" target="_blank">Matplotlib</a></li>
150 <li><a href="http://matplotlib.sourceforge.net/" target="_blank">Matplotlib</a></li>
151 </ul>
151 </ul>
152 </li>
152 </li>
153 </ul>
153 </ul>
154
154
155 </div>
155 </div>
156
156
157 <div id="toolbar">
157 <div id="toolbar">
158
158
159 <span>
159 <span>
160 <button id="save_b">Save</button>
160 <button id="save_b">Save</button>
161 </span>
161 </span>
162 <span id="cut_copy_paste">
162 <span id="cut_copy_paste">
163 <button id="cut_b" title="Cut Cell">Cut Cell</button>
163 <button id="cut_b" title="Cut Cell">Cut Cell</button>
164 <button id="copy_b" title="Copy Cell">Copy Cell</button>
164 <button id="copy_b" title="Copy Cell">Copy Cell</button>
165 <button id="paste_b" title="Paste Cell">Paste Cell</button>
165 <button id="paste_b" title="Paste Cell">Paste Cell</button>
166 </span>
166 </span>
167 <span id="move_up_down">
167 <span id="move_up_down">
168 <button id="move_up_b" title="Move Cell Up">Move Cell Up</button>
168 <button id="move_up_b" title="Move Cell Up">Move Cell Up</button>
169 <button id="move_down_b" title="Move Cell Down">Move Down</button>
169 <button id="move_down_b" title="Move Cell Down">Move Down</button>
170 </span>
170 </span>
171 <span id="insert_above_below">
171 <span id="insert_above_below">
172 <button id="insert_above_b" title="Insert Cell Above">Insert Cell Above</button>
172 <button id="insert_above_b" title="Insert Cell Above">Insert Cell Above</button>
173 <button id="insert_below_b" title="Insert Cell Below">Insert Cell Below</button>
173 <button id="insert_below_b" title="Insert Cell Below">Insert Cell Below</button>
174 </span>
174 </span>
175 <span id="run_int">
175 <span id="run_int">
176 <button id="run_b" title="Run Cell">Run Cell</button>
176 <button id="run_b" title="Run Cell">Run Cell</button>
177 <button id="interrupt_b" title="Interrupt">Interrupt</button>
177 <button id="interrupt_b" title="Interrupt">Interrupt</button>
178 </span>
178 </span>
179 <span>
179 <span>
180 <select id="cell_type">
180 <select id="cell_type">
181 <option value="code">Code</option>
181 <option value="code">Code</option>
182 <option value="markdown">Markdown</option>
182 <option value="markdown">Markdown</option>
183 <option value="plaintext">Plaintext</option>
184 <option value="heading1">Heading 1</option>
185 <option value="heading2">Heading 2</option>
186 <option value="heading3">Heading 3</option>
187 <option value="heading4">Heading 4</option>
188 <option value="heading5">Heading 5</option>
189 <option value="heading6">Heading 6</option>
183 </select>
190 </select>
184 </span>
191 </span>
185
192
186 </div>
193 </div>
187
194
188 <div id="main_app">
195 <div id="main_app">
189
196
190 <div id="notebook_panel">
197 <div id="notebook_panel">
191 <div id="notebook"></div>
198 <div id="notebook"></div>
192 <div id="pager_splitter"></div>
199 <div id="pager_splitter"></div>
193 <div id="pager"></div>
200 <div id="pager"></div>
194 </div>
201 </div>
195
202
196 </div>
203 </div>
197
204
198 <script src="{{ static_url("jquery/js/jquery-1.7.1.min.js") }}" type="text/javascript" charset="utf-8"></script>
205 <script src="{{ static_url("jquery/js/jquery-1.7.1.min.js") }}" type="text/javascript" charset="utf-8"></script>
199 <script src="{{ static_url("jquery/js/jquery-ui.min.js") }}" type="text/javascript" charset="utf-8"></script>
206 <script src="{{ static_url("jquery/js/jquery-ui.min.js") }}" type="text/javascript" charset="utf-8"></script>
200
207
201 <script src="{{ static_url("codemirror/lib/codemirror.js") }}" charset="utf-8"></script>
208 <script src="{{ static_url("codemirror/lib/codemirror.js") }}" charset="utf-8"></script>
202 <script src="{{ static_url("codemirror/mode/python/python.js") }}" charset="utf-8"></script>
209 <script src="{{ static_url("codemirror/mode/python/python.js") }}" charset="utf-8"></script>
203 <script src="{{ static_url("codemirror/mode/htmlmixed/htmlmixed.js") }}" charset="utf-8"></script>
210 <script src="{{ static_url("codemirror/mode/htmlmixed/htmlmixed.js") }}" charset="utf-8"></script>
204 <script src="{{ static_url("codemirror/mode/xml/xml.js") }}" charset="utf-8"></script>
211 <script src="{{ static_url("codemirror/mode/xml/xml.js") }}" charset="utf-8"></script>
205 <script src="{{ static_url("codemirror/mode/javascript/javascript.js") }}" charset="utf-8"></script>
212 <script src="{{ static_url("codemirror/mode/javascript/javascript.js") }}" charset="utf-8"></script>
206 <script src="{{ static_url("codemirror/mode/css/css.js") }}" charset="utf-8"></script>
213 <script src="{{ static_url("codemirror/mode/css/css.js") }}" charset="utf-8"></script>
207 <script src="{{ static_url("codemirror/mode/rst/rst.js") }}" charset="utf-8"></script>
214 <script src="{{ static_url("codemirror/mode/rst/rst.js") }}" charset="utf-8"></script>
208 <script src="{{ static_url("codemirror/mode/markdown/markdown.js") }}" charset="utf-8"></script>
215 <script src="{{ static_url("codemirror/mode/markdown/markdown.js") }}" charset="utf-8"></script>
209
216
210 <script src="{{ static_url("pagedown/Markdown.Converter.js") }}" charset="utf-8"></script>
217 <script src="{{ static_url("pagedown/Markdown.Converter.js") }}" charset="utf-8"></script>
211
218
212 <script src="{{ static_url("prettify/prettify.js") }}" charset="utf-8"></script>
219 <script src="{{ static_url("prettify/prettify.js") }}" charset="utf-8"></script>
213 <script src="{{ static_url("dateformat/date.format.js") }}" charset="utf-8"></script>
220 <script src="{{ static_url("dateformat/date.format.js") }}" charset="utf-8"></script>
214
221
215 <script src="{{ static_url("js/namespace.js") }}" type="text/javascript" charset="utf-8"></script>
222 <script src="{{ static_url("js/namespace.js") }}" type="text/javascript" charset="utf-8"></script>
216 <script src="{{ static_url("js/utils.js") }}" type="text/javascript" charset="utf-8"></script>
223 <script src="{{ static_url("js/utils.js") }}" type="text/javascript" charset="utf-8"></script>
217 <script src="{{ static_url("js/cell.js") }}" type="text/javascript" charset="utf-8"></script>
224 <script src="{{ static_url("js/cell.js") }}" type="text/javascript" charset="utf-8"></script>
218 <script src="{{ static_url("js/codecell.js") }}" type="text/javascript" charset="utf-8"></script>
225 <script src="{{ static_url("js/codecell.js") }}" type="text/javascript" charset="utf-8"></script>
219 <script src="{{ static_url("js/textcell.js") }}" type="text/javascript" charset="utf-8"></script>
226 <script src="{{ static_url("js/textcell.js") }}" type="text/javascript" charset="utf-8"></script>
220 <script src="{{ static_url("js/kernel.js") }}" type="text/javascript" charset="utf-8"></script>
227 <script src="{{ static_url("js/kernel.js") }}" type="text/javascript" charset="utf-8"></script>
221 <script src="{{ static_url("js/kernelstatus.js") }}" type="text/javascript" charset="utf-8"></script>
228 <script src="{{ static_url("js/kernelstatus.js") }}" type="text/javascript" charset="utf-8"></script>
222 <script src="{{ static_url("js/layout.js") }}" type="text/javascript" charset="utf-8"></script>
229 <script src="{{ static_url("js/layout.js") }}" type="text/javascript" charset="utf-8"></script>
223 <script src="{{ static_url("js/savewidget.js") }}" type="text/javascript" charset="utf-8"></script>
230 <script src="{{ static_url("js/savewidget.js") }}" type="text/javascript" charset="utf-8"></script>
224 <script src="{{ static_url("js/quickhelp.js") }}" type="text/javascript" charset="utf-8"></script>
231 <script src="{{ static_url("js/quickhelp.js") }}" type="text/javascript" charset="utf-8"></script>
225 <script src="{{ static_url("js/loginwidget.js") }}" type="text/javascript" charset="utf-8"></script>
232 <script src="{{ static_url("js/loginwidget.js") }}" type="text/javascript" charset="utf-8"></script>
226 <script src="{{ static_url("js/pager.js") }}" type="text/javascript" charset="utf-8"></script>
233 <script src="{{ static_url("js/pager.js") }}" type="text/javascript" charset="utf-8"></script>
227 <script src="{{ static_url("js/menubar.js") }}" type="text/javascript" charset="utf-8"></script>
234 <script src="{{ static_url("js/menubar.js") }}" type="text/javascript" charset="utf-8"></script>
228 <script src="{{ static_url("js/toolbar.js") }}" type="text/javascript" charset="utf-8"></script>
235 <script src="{{ static_url("js/toolbar.js") }}" type="text/javascript" charset="utf-8"></script>
229 <script src="{{ static_url("js/notebook.js") }}" type="text/javascript" charset="utf-8"></script>
236 <script src="{{ static_url("js/notebook.js") }}" type="text/javascript" charset="utf-8"></script>
230 <script src="{{ static_url("js/notebookmain.js") }}" type="text/javascript" charset="utf-8"></script>
237 <script src="{{ static_url("js/notebookmain.js") }}" type="text/javascript" charset="utf-8"></script>
231
238
232 </body>
239 </body>
233
240
234 </html>
241 </html>
General Comments 0
You need to be logged in to leave comments. Login now