##// END OF EJS Templates
Clean up accidentally introduced hard tabs in JS code.
Fernando Perez -
Show More
@@ -1,345 +1,345 b''
1 /**
1 /**
2 * Primary styles
2 * Primary styles
3 *
3 *
4 * Author: IPython Development Team
4 * Author: IPython Development Team
5 */
5 */
6
6
7
7
8 body {
8 body {
9 background-color: white;
9 background-color: white;
10 /* This makes sure that the body covers the entire window and needs to
10 /* This makes sure that the body covers the entire window and needs to
11 be in a different element than the display: box in wrapper below */
11 be in a different element than the display: box in wrapper below */
12 position: absolute;
12 position: absolute;
13 left: 0px;
13 left: 0px;
14 right: 0px;
14 right: 0px;
15 top: 0px;
15 top: 0px;
16 bottom: 0px;
16 bottom: 0px;
17 overflow: hidden;
17 overflow: hidden;
18 }
18 }
19
19
20 span#save_widget {
20 span#save_widget {
21 position: static;
21 position: static;
22 left: 0px;
22 left: 0px;
23 padding: 5px 0px;
23 padding: 5px 0px;
24 margin: 0px 0px 0px 0px;
24 margin: 0px 0px 0px 0px;
25 }
25 }
26
26
27 span#quick_help_area {
27 span#quick_help_area {
28 position: static;
28 position: static;
29 padding: 5px 0px;
29 padding: 5px 0px;
30 margin: 0px 0px 0px 0px;
30 margin: 0px 0px 0px 0px;
31 }
31 }
32
32
33 input#notebook_name {
33 input#notebook_name {
34 height: 1em;
34 height: 1em;
35 line-height: 1em;
35 line-height: 1em;
36 padding: 5px;
36 padding: 5px;
37 }
37 }
38
38
39 span#kernel_status {
39 span#kernel_status {
40 position: absolute;
40 position: absolute;
41 padding: 8px 5px 5px 5px;
41 padding: 8px 5px 5px 5px;
42 right: 10px;
42 right: 10px;
43 font-weight: bold;
43 font-weight: bold;
44 }
44 }
45
45
46
46
47 .status_idle {
47 .status_idle {
48 color: gray;
48 color: gray;
49 }
49 }
50
50
51 .status_busy {
51 .status_busy {
52 color: red;
52 color: red;
53 }
53 }
54
54
55 .status_restarting {
55 .status_restarting {
56 color: black;
56 color: black;
57 }
57 }
58
58
59 div#left_panel {
59 div#left_panel {
60 overflow-y: auto;
60 overflow-y: auto;
61 top: 0px;
61 top: 0px;
62 left: 0px;
62 left: 0px;
63 margin: 0px;
63 margin: 0px;
64 padding: 0px;
64 padding: 0px;
65 position: absolute;
65 position: absolute;
66 }
66 }
67
67
68 h3.section_header {
68 h3.section_header {
69 padding: 5px;
69 padding: 5px;
70 }
70 }
71
71
72 div.section_content {
72 div.section_content {
73 padding: 5px;
73 padding: 5px;
74 }
74 }
75
75
76 span.section_row_buttons button {
76 span.section_row_buttons button {
77 width: 70px;
77 width: 70px;
78 }
78 }
79
79
80 span.section_row_buttons a {
80 span.section_row_buttons a {
81 width: 70px;
81 width: 70px;
82 }
82 }
83
83
84 .section_row {
84 .section_row {
85 margin: 5px 0px;
85 margin: 5px 0px;
86 }
86 }
87
87
88 .section_row_buttons {
88 .section_row_buttons {
89 float: right;
89 float: right;
90 }
90 }
91
91
92 #kernel_persist {
92 #kernel_persist {
93 float: right;
93 float: right;
94 }
94 }
95
95
96 .help_string {
96 .help_string {
97 float: right;
97 float: right;
98 width: 170px;
98 width: 170px;
99 padding: 0px 5px;
99 padding: 0px 5px;
100 text-align: left;
100 text-align: left;
101 font-size: 85%;
101 font-size: 85%;
102 }
102 }
103
103
104 .help_string_label {
104 .help_string_label {
105 float: right;
105 float: right;
106 font-size: 85%;
106 font-size: 85%;
107 }
107 }
108
108
109 #autoindent_span {
109 #autoindent_span {
110 float: right;
110 float: right;
111 }
111 }
112
112
113 .checkbox_label {
113 .checkbox_label {
114 font-size: 85%;
114 font-size: 85%;
115 float: right;
115 float: right;
116 padding: 0.3em;
116 padding: 0.3em;
117 }
117 }
118
118
119 .section_row_header {
119 .section_row_header {
120 float: left;
120 float: left;
121 font-size: 85%;
121 font-size: 85%;
122 padding: 0.4em 0em;
122 padding: 0.4em 0em;
123 font-weight: bold;
123 font-weight: bold;
124 }
124 }
125
125
126 span.button_label {
126 span.button_label {
127 padding: 0.2em 1em;
127 padding: 0.2em 1em;
128 font-size: 77%;
128 font-size: 77%;
129 float: right;
129 float: right;
130 }
130 }
131
131
132 /* This is needed because FF was adding a 2px margin top and bottom. */
132 /* This is needed because FF was adding a 2px margin top and bottom. */
133 .section_row .ui-button {
133 .section_row .ui-button {
134 margin-top: 0px;
134 margin-top: 0px;
135 margin-bottom: 0px;
135 margin-bottom: 0px;
136 }
136 }
137
137
138 #download_format {
138 #download_format {
139 float: right;
139 float: right;
140 font-size: 85%;
140 font-size: 85%;
141 width: 62px;
141 width: 62px;
142 margin: 1px 5px;
142 margin: 1px 5px;
143 }
143 }
144
144
145 div#left_panel_splitter {
145 div#left_panel_splitter {
146 width: 8px;
146 width: 8px;
147 top: 0px;
147 top: 0px;
148 left: 202px;
148 left: 202px;
149 margin: 0px;
149 margin: 0px;
150 padding: 0px;
150 padding: 0px;
151 position: absolute;
151 position: absolute;
152 }
152 }
153
153
154 div#notebook_panel {
154 div#notebook_panel {
155 /* The L margin will be set in the Javascript code*/
155 /* The L margin will be set in the Javascript code*/
156 margin: 0px 0px 0px 0px;
156 margin: 0px 0px 0px 0px;
157 padding: 0px;
157 padding: 0px;
158 }
158 }
159
159
160 div#notebook {
160 div#notebook {
161 overflow-y: scroll;
161 overflow-y: scroll;
162 overflow-x: auto;
162 overflow-x: auto;
163 width: 100%;
163 width: 100%;
164 /* This spaces the cell away from the edge of the notebook area */
164 /* This spaces the cell away from the edge of the notebook area */
165 padding: 5px 5px 15px 5px;
165 padding: 5px 5px 15px 5px;
166 margin: 0px
166 margin: 0px
167 background-color: white;
167 background-color: white;
168 }
168 }
169
169
170 div#pager_splitter {
170 div#pager_splitter {
171 height: 8px;
171 height: 8px;
172 }
172 }
173
173
174 div#pager {
174 div#pager {
175 padding: 15px;
175 padding: 15px;
176 overflow: auto;
176 overflow: auto;
177 }
177 }
178
178
179 div.cell {
179 div.cell {
180 width: 100%;
180 width: 100%;
181 padding: 5px 5px 5px 0px;
181 padding: 5px 5px 5px 0px;
182 /* This acts as a spacer between cells, that is outside the border */
182 /* This acts as a spacer between cells, that is outside the border */
183 margin: 2px 0px 2px 0px;
183 margin: 2px 0px 2px 0px;
184 }
184 }
185
185
186 div.code_cell {
186 div.code_cell {
187 background-color: white;
187 background-color: white;
188 }
188 }
189
189
190 div.prompt {
190 div.prompt {
191 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
191 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
192 width: 11ex;
192 width: 11ex;
193 /* This 0.4em is tuned to match the padding on the CodeMirror editor. */
193 /* This 0.4em is tuned to match the padding on the CodeMirror editor. */
194 padding: 0.4em;
194 padding: 0.4em;
195 margin: 0px;
195 margin: 0px;
196 font-family: monospace;
196 font-family: monospace;
197 text-align:right;
197 text-align:right;
198 }
198 }
199
199
200 div.input {
200 div.input {
201 page-break-inside: avoid;
201 page-break-inside: avoid;
202 }
202 }
203
203
204 /* input_area and input_prompt must match in top border and margin for alignment */
204 /* input_area and input_prompt must match in top border and margin for alignment */
205 div.input_area {
205 div.input_area {
206 color: black;
206 color: black;
207 border: 1px solid #ddd;
207 border: 1px solid #ddd;
208 border-radius: 3px;
208 border-radius: 3px;
209 background: #f4f4f4;
209 background: #f4f4f4;
210 }
210 }
211
211
212 div.input_prompt {
212 div.input_prompt {
213 color: navy;
213 color: navy;
214 border-top: 1px solid transparent;
214 border-top: 1px solid transparent;
215 }
215 }
216
216
217 div.output {
217 div.output {
218 /* This is a spacer between the input and output of each cell */
218 /* This is a spacer between the input and output of each cell */
219 margin-top: 5px;
219 margin-top: 5px;
220 }
220 }
221
221
222 div.output_prompt {
222 div.output_prompt {
223 color: darkred;
223 color: darkred;
224 }
224 }
225
225
226 /* This class is the outer container of all output sections. */
226 /* This class is the outer container of all output sections. */
227 div.output_area {
227 div.output_area {
228 padding: 0px;
228 padding: 0px;
229 page-break-inside: avoid;
229 page-break-inside: avoid;
230 }
230 }
231
231
232 /* This class is for the output subarea inside the output_area and after
232 /* This class is for the output subarea inside the output_area and after
233 the prompt div. */
233 the prompt div. */
234 div.output_subarea {
234 div.output_subarea {
235 padding: 0.4em;
235 padding: 0.4em;
236 }
236 }
237
237
238 /* The rest of the output_* classes are for special styling of the different
238 /* The rest of the output_* classes are for special styling of the different
239 output types */
239 output types */
240
240
241 /* all text output has this class: */
241 /* all text output has this class: */
242 div.output_text {
242 div.output_text {
243 text-align: left;
243 text-align: left;
244 color: black;
244 color: black;
245 font-family: monospace;
245 font-family: monospace;
246 }
246 }
247
247
248 /* stdout/stderr are 'text' as well as 'stream', but pyout/pyerr are *not* streams */
248 /* stdout/stderr are 'text' as well as 'stream', but pyout/pyerr are *not* streams */
249 div.output_stream {
249 div.output_stream {
250 padding-top: 0.0em;
250 padding-top: 0.0em;
251 padding-bottom: 0.0em;
251 padding-bottom: 0.0em;
252 }
252 }
253 div.output_stdout {
253 div.output_stdout {
254 }
254 }
255 div.output_stderr {
255 div.output_stderr {
256 background: #fdd; /* very light red background for stderr */
256 background: #fdd; /* very light red background for stderr */
257 }
257 }
258
258
259 div.output_latex {
259 div.output_latex {
260 text-align: left;
260 text-align: left;
261 color: black;
261 color: black;
262 }
262 }
263
263
264 div.output_html {
264 div.output_html {
265 }
265 }
266
266
267 div.output_png {
267 div.output_png {
268 }
268 }
269
269
270 div.output_jpeg {
270 div.output_jpeg {
271 }
271 }
272
272
273 div.text_cell {
273 div.text_cell {
274 background-color: white;
274 background-color: white;
275 }
275 }
276
276
277 div.text_cell_input {
277 div.text_cell_input {
278 color: black;
278 color: black;
279 }
279 }
280
280
281 div.text_cell_render {
281 div.text_cell_render {
282 font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
282 font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
283 outline: none;
283 outline: none;
284 resize: none;
284 resize: none;
285 width: inherit;
285 width: inherit;
286 border-style: none;
286 border-style: none;
287 padding: 5px;
287 padding: 5px;
288 color: black;
288 color: black;
289 }
289 }
290
290
291 .CodeMirror {
291 .CodeMirror {
292 line-height: 1.231; /* Changed from 1em to our global default */
292 line-height: 1.231; /* Changed from 1em to our global default */
293 }
293 }
294
294
295 .CodeMirror-scroll {
295 .CodeMirror-scroll {
296 height: auto; /* Changed to auto to autogrow */
296 height: auto; /* Changed to auto to autogrow */
297 /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
297 /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
298 /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
298 /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
299 overflow-y: hidden;
299 overflow-y: hidden;
300 overflow-x: auto; /* Changed from auto to remove scrollbar */
300 overflow-x: auto; /* Changed from auto to remove scrollbar */
301 }
301 }
302
302
303 /* CSS font colors for translated ANSI colors. */
303 /* CSS font colors for translated ANSI colors. */
304
304
305
305
306 .ansiblack {color: black;}
306 .ansiblack {color: black;}
307 .ansired {color: darkred;}
307 .ansired {color: darkred;}
308 .ansigreen {color: darkgreen;}
308 .ansigreen {color: darkgreen;}
309 .ansiyellow {color: brown;}
309 .ansiyellow {color: brown;}
310 .ansiblue {color: darkblue;}
310 .ansiblue {color: darkblue;}
311 .ansipurple {color: darkviolet;}
311 .ansipurple {color: darkviolet;}
312 .ansicyan {color: steelblue;}
312 .ansicyan {color: steelblue;}
313 .ansigrey {color: grey;}
313 .ansigrey {color: grey;}
314 .ansibold {font-weight: bold;}
314 .ansibold {font-weight: bold;}
315
315
316 .completions {
316 .completions {
317 position: absolute;
317 position: absolute;
318 z-index: 10;
318 z-index: 10;
319 overflow: auto;
319 overflow: auto;
320 border: 1px solid black;
320 border: 1px solid black;
321 }
321 }
322
322
323 .completions select {
323 .completions select {
324 background: white;
324 background: white;
325 outline: none;
325 outline: none;
326 border: none;
326 border: none;
327 padding: 0px;
327 padding: 0px;
328 margin: 0px;
328 margin: 0px;
329 font-family: monospace;
329 font-family: monospace;
330 }
330 }
331
331
332 @media print {
332 @media print {
333 body { overflow: visible !important; }
333 body { overflow: visible !important; }
334 .ui-widget-content { border: 0px; }
334 .ui-widget-content { border: 0px; }
335 }
335 }
336
336
337 .shortcut_key {
337 .shortcut_key {
338 display: inline-block;
338 display: inline-block;
339 width: 13ex;
339 width: 13ex;
340 text-align: right;
340 text-align: right;
341 font-family: monospace;
341 font-family: monospace;
342 }
342 }
343
343
344 .shortcut_descr {
344 .shortcut_descr {
345 } No newline at end of file
345 }
@@ -1,486 +1,486 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 // CodeCell
9 // CodeCell
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 CodeCell = function (notebook) {
16 var CodeCell = function (notebook) {
17 this.code_mirror = null;
17 this.code_mirror = null;
18 this.input_prompt_number = ' ';
18 this.input_prompt_number = ' ';
19 this.is_completing = false;
19 this.is_completing = false;
20 this.completion_cursor = null;
20 this.completion_cursor = null;
21 this.outputs = [];
21 this.outputs = [];
22 this.collapsed = false;
22 this.collapsed = false;
23 IPython.Cell.apply(this, arguments);
23 IPython.Cell.apply(this, arguments);
24 };
24 };
25
25
26
26
27 CodeCell.prototype = new IPython.Cell();
27 CodeCell.prototype = new IPython.Cell();
28
28
29
29
30 CodeCell.prototype.create_element = function () {
30 CodeCell.prototype.create_element = function () {
31 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell vbox');
31 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell vbox');
32 cell.attr('tabindex','2');
32 cell.attr('tabindex','2');
33 var input = $('<div></div>').addClass('input hbox');
33 var input = $('<div></div>').addClass('input hbox');
34 input.append($('<div/>').addClass('prompt input_prompt'));
34 input.append($('<div/>').addClass('prompt input_prompt'));
35 var input_area = $('<div/>').addClass('input_area box-flex1');
35 var input_area = $('<div/>').addClass('input_area box-flex1');
36 this.code_mirror = CodeMirror(input_area.get(0), {
36 this.code_mirror = CodeMirror(input_area.get(0), {
37 indentUnit : 4,
37 indentUnit : 4,
38 mode: 'python',
38 mode: 'python',
39 theme: 'ipython',
39 theme: 'ipython',
40 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
40 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
41 });
41 });
42 input.append(input_area);
42 input.append(input_area);
43 var output = $('<div></div>').addClass('output vbox');
43 var output = $('<div></div>').addClass('output vbox');
44 cell.append(input).append(output);
44 cell.append(input).append(output);
45 this.element = cell;
45 this.element = cell;
46 this.collapse()
46 this.collapse()
47 };
47 };
48
48
49
49
50 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
50 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
51 // This method gets called in CodeMirror's onKeyDown/onKeyPress
51 // This method gets called in CodeMirror's onKeyDown/onKeyPress
52 // handlers and is used to provide custom key handling. Its return
52 // handlers and is used to provide custom key handling. Its return
53 // value is used to determine if CodeMirror should ignore the event:
53 // value is used to determine if CodeMirror should ignore the event:
54 // true = ignore, false = don't ignore.
54 // true = ignore, false = don't ignore.
55 if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) {
55 if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) {
56 // Always ignore shift-enter in CodeMirror as we handle it.
56 // Always ignore shift-enter in CodeMirror as we handle it.
57 return true;
57 return true;
58 } else if (event.keyCode === 9 && event.type == 'keydown') {
58 } else if (event.keyCode === 9 && event.type == 'keydown') {
59 // Tab completion.
59 // Tab completion.
60 var cur = editor.getCursor();
60 var cur = editor.getCursor();
61 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur).trim();
61 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur).trim();
62 if (pre_cursor === "") {
62 if (pre_cursor === "") {
63 // Don't autocomplete if the part of the line before the cursor
63 // Don't autocomplete if the part of the line before the cursor
64 // is empty. In this case, let CodeMirror handle indentation.
64 // is empty. In this case, let CodeMirror handle indentation.
65 return false;
65 return false;
66 } else {
66 } else {
67 // Autocomplete the current line.
67 // Autocomplete the current line.
68 event.stop();
68 event.stop();
69 var line = editor.getLine(cur.line);
69 var line = editor.getLine(cur.line);
70 this.is_completing = true;
70 this.is_completing = true;
71 this.completion_cursor = cur;
71 this.completion_cursor = cur;
72 IPython.notebook.complete_cell(this, line, cur.ch);
72 IPython.notebook.complete_cell(this, line, cur.ch);
73 return true;
73 return true;
74 }
74 }
75 } else if (event.keyCode === 8 && event.type == 'keydown') {
75 } else if (event.keyCode === 8 && event.type == 'keydown') {
76 // If backspace and the line ends with 4 spaces, remove them.
76 // If backspace and the line ends with 4 spaces, remove them.
77 var cur = editor.getCursor();
77 var cur = editor.getCursor();
78 var line = editor.getLine(cur.line);
78 var line = editor.getLine(cur.line);
79 var ending = line.slice(-4);
79 var ending = line.slice(-4);
80 if (ending === ' ') {
80 if (ending === ' ') {
81 editor.replaceRange('',
81 editor.replaceRange('',
82 {line: cur.line, ch: cur.ch-4},
82 {line: cur.line, ch: cur.ch-4},
83 {line: cur.line, ch: cur.ch}
83 {line: cur.line, ch: cur.ch}
84 );
84 );
85 event.stop();
85 event.stop();
86 return true;
86 return true;
87 } else {
87 } else {
88 return false;
88 return false;
89 };
89 };
90 } else if (event.keyCode === 76 && event.ctrlKey && event.shiftKey
90 } else if (event.keyCode === 76 && event.ctrlKey && event.shiftKey
91 && event.type == 'keydown') {
91 && event.type == 'keydown') {
92 // toggle line numbers with Ctrl-Shift-L
92 // toggle line numbers with Ctrl-Shift-L
93 this.toggle_line_numbers()
93 this.toggle_line_numbers();
94 }
94 }
95 else {
95 else {
96 // keypress/keyup also trigger on TAB press, and we don't want to
96 // keypress/keyup also trigger on TAB press, and we don't want to
97 // use those to disable tab completion.
97 // use those to disable tab completion.
98 if (this.is_completing && event.keyCode !== 9) {
98 if (this.is_completing && event.keyCode !== 9) {
99 var ed_cur = editor.getCursor();
99 var ed_cur = editor.getCursor();
100 var cc_cur = this.completion_cursor;
100 var cc_cur = this.completion_cursor;
101 if (ed_cur.line !== cc_cur.line || ed_cur.ch !== cc_cur.ch) {
101 if (ed_cur.line !== cc_cur.line || ed_cur.ch !== cc_cur.ch) {
102 this.is_completing = false;
102 this.is_completing = false;
103 this.completion_cursor = null;
103 this.completion_cursor = null;
104 };
104 };
105 };
105 };
106 return false;
106 return false;
107 };
107 };
108 };
108 };
109
109
110
110
111 CodeCell.prototype.finish_completing = function (matched_text, matches) {
111 CodeCell.prototype.finish_completing = function (matched_text, matches) {
112 // console.log("Got matches", matched_text, matches);
112 // console.log("Got matches", matched_text, matches);
113 if (!this.is_completing || matches.length === 0) {return;}
113 if (!this.is_completing || matches.length === 0) {return;}
114
114
115 var that = this;
115 var that = this;
116 var cur = this.completion_cursor;
116 var cur = this.completion_cursor;
117
117
118 var insert = function (selected_text) {
118 var insert = function (selected_text) {
119 that.code_mirror.replaceRange(
119 that.code_mirror.replaceRange(
120 selected_text,
120 selected_text,
121 {line: cur.line, ch: (cur.ch-matched_text.length)},
121 {line: cur.line, ch: (cur.ch-matched_text.length)},
122 {line: cur.line, ch: cur.ch}
122 {line: cur.line, ch: cur.ch}
123 );
123 );
124 };
124 };
125
125
126 if (matches.length === 1) {
126 if (matches.length === 1) {
127 insert(matches[0]);
127 insert(matches[0]);
128 setTimeout(function(){that.code_mirror.focus();}, 50);
128 setTimeout(function(){that.code_mirror.focus();}, 50);
129 return;
129 return;
130 };
130 };
131
131
132 var complete = $('<div/>').addClass('completions');
132 var complete = $('<div/>').addClass('completions');
133 var select = $('<select/>').attr('multiple','true');
133 var select = $('<select/>').attr('multiple','true');
134 for (var i=0; i<matches.length; ++i) {
134 for (var i=0; i<matches.length; ++i) {
135 select.append($('<option/>').text(matches[i]));
135 select.append($('<option/>').text(matches[i]));
136 }
136 }
137 select.children().first().attr('selected','true');
137 select.children().first().attr('selected','true');
138 select.attr('size',Math.min(10,matches.length));
138 select.attr('size',Math.min(10,matches.length));
139 var pos = this.code_mirror.cursorCoords();
139 var pos = this.code_mirror.cursorCoords();
140 complete.css('left',pos.x+'px');
140 complete.css('left',pos.x+'px');
141 complete.css('top',pos.yBot+'px');
141 complete.css('top',pos.yBot+'px');
142 complete.append(select);
142 complete.append(select);
143
143
144 $('body').append(complete);
144 $('body').append(complete);
145 var done = false;
145 var done = false;
146
146
147 var close = function () {
147 var close = function () {
148 if (done) return;
148 if (done) return;
149 done = true;
149 done = true;
150 complete.remove();
150 complete.remove();
151 that.is_completing = false;
151 that.is_completing = false;
152 that.completion_cursor = null;
152 that.completion_cursor = null;
153 };
153 };
154
154
155 var pick = function () {
155 var pick = function () {
156 insert(select.val()[0]);
156 insert(select.val()[0]);
157 close();
157 close();
158 setTimeout(function(){that.code_mirror.focus();}, 50);
158 setTimeout(function(){that.code_mirror.focus();}, 50);
159 };
159 };
160
160
161 select.blur(close);
161 select.blur(close);
162 select.keydown(function (event) {
162 select.keydown(function (event) {
163 var code = event.which;
163 var code = event.which;
164 if (code === 13 || code === 32) {
164 if (code === 13 || code === 32) {
165 // Pressing SPACE or ENTER will cause a pick
165 // Pressing SPACE or ENTER will cause a pick
166 event.stopPropagation();
166 event.stopPropagation();
167 event.preventDefault();
167 event.preventDefault();
168 pick();
168 pick();
169 } else if (code === 38 || code === 40) {
169 } else if (code === 38 || code === 40) {
170 // We don't want the document keydown handler to handle UP/DOWN,
170 // We don't want the document keydown handler to handle UP/DOWN,
171 // but we want the default action.
171 // but we want the default action.
172 event.stopPropagation();
172 event.stopPropagation();
173 } else {
173 } else {
174 // All other key presses exit completion.
174 // All other key presses exit completion.
175 event.stopPropagation();
175 event.stopPropagation();
176 event.preventDefault();
176 event.preventDefault();
177 close();
177 close();
178 that.code_mirror.focus();
178 that.code_mirror.focus();
179 }
179 }
180 });
180 });
181 // Double click also causes a pick.
181 // Double click also causes a pick.
182 select.dblclick(pick);
182 select.dblclick(pick);
183 select.focus();
183 select.focus();
184 };
184 };
185
185
186 CodeCell.prototype.toggle_line_numbers = function () {
186 CodeCell.prototype.toggle_line_numbers = function () {
187 if (this.code_mirror.getOption('lineNumbers') == false) {
187 if (this.code_mirror.getOption('lineNumbers') == false) {
188 this.code_mirror.setOption('lineNumbers', true);
188 this.code_mirror.setOption('lineNumbers', true);
189 } else {
189 } else {
190 this.code_mirror.setOption('lineNumbers', false);
190 this.code_mirror.setOption('lineNumbers', false);
191 }
191 }
192 this.code_mirror.refresh()
192 this.code_mirror.refresh()
193 };
193 };
194
194
195 CodeCell.prototype.select = function () {
195 CodeCell.prototype.select = function () {
196 IPython.Cell.prototype.select.apply(this);
196 IPython.Cell.prototype.select.apply(this);
197 // Todo: this dance is needed because as of CodeMirror 2.12, focus is
197 // Todo: this dance is needed because as of CodeMirror 2.12, focus is
198 // not causing the cursor to blink if the editor is empty initially.
198 // not causing the cursor to blink if the editor is empty initially.
199 // While this seems to fix the issue, this should be fixed
199 // While this seems to fix the issue, this should be fixed
200 // in CodeMirror proper.
200 // in CodeMirror proper.
201 var s = this.code_mirror.getValue();
201 var s = this.code_mirror.getValue();
202 this.code_mirror.focus();
202 this.code_mirror.focus();
203 if (s === '') this.code_mirror.setValue('');
203 if (s === '') this.code_mirror.setValue('');
204 };
204 };
205
205
206
206
207 CodeCell.prototype.select_all = function () {
207 CodeCell.prototype.select_all = function () {
208 var start = {line: 0, ch: 0};
208 var start = {line: 0, ch: 0};
209 var nlines = this.code_mirror.lineCount();
209 var nlines = this.code_mirror.lineCount();
210 var last_line = this.code_mirror.getLine(nlines-1);
210 var last_line = this.code_mirror.getLine(nlines-1);
211 var end = {line: nlines-1, ch: last_line.length};
211 var end = {line: nlines-1, ch: last_line.length};
212 this.code_mirror.setSelection(start, end);
212 this.code_mirror.setSelection(start, end);
213 };
213 };
214
214
215
215
216 CodeCell.prototype.append_output = function (json) {
216 CodeCell.prototype.append_output = function (json) {
217 this.expand();
217 this.expand();
218 if (json.output_type === 'pyout') {
218 if (json.output_type === 'pyout') {
219 this.append_pyout(json);
219 this.append_pyout(json);
220 } else if (json.output_type === 'pyerr') {
220 } else if (json.output_type === 'pyerr') {
221 this.append_pyerr(json);
221 this.append_pyerr(json);
222 } else if (json.output_type === 'display_data') {
222 } else if (json.output_type === 'display_data') {
223 this.append_display_data(json);
223 this.append_display_data(json);
224 } else if (json.output_type === 'stream') {
224 } else if (json.output_type === 'stream') {
225 this.append_stream(json);
225 this.append_stream(json);
226 };
226 };
227 this.outputs.push(json);
227 this.outputs.push(json);
228 };
228 };
229
229
230
230
231 CodeCell.prototype.create_output_area = function () {
231 CodeCell.prototype.create_output_area = function () {
232 var oa = $("<div/>").addClass("hbox output_area");
232 var oa = $("<div/>").addClass("hbox output_area");
233 oa.append($('<div/>').addClass('prompt'));
233 oa.append($('<div/>').addClass('prompt'));
234 return oa;
234 return oa;
235 };
235 };
236
236
237
237
238 CodeCell.prototype.append_pyout = function (json) {
238 CodeCell.prototype.append_pyout = function (json) {
239 n = json.prompt_number || ' ';
239 n = json.prompt_number || ' ';
240 var toinsert = this.create_output_area();
240 var toinsert = this.create_output_area();
241 toinsert.find('div.prompt').addClass('output_prompt').html('Out[' + n + ']:');
241 toinsert.find('div.prompt').addClass('output_prompt').html('Out[' + n + ']:');
242 this.append_mime_type(json, toinsert);
242 this.append_mime_type(json, toinsert);
243 this.element.find('div.output').append(toinsert);
243 this.element.find('div.output').append(toinsert);
244 // If we just output latex, typeset it.
244 // If we just output latex, typeset it.
245 if (json.latex !== undefined) {
245 if (json.latex !== undefined) {
246 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
246 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
247 };
247 };
248 };
248 };
249
249
250
250
251 CodeCell.prototype.append_pyerr = function (json) {
251 CodeCell.prototype.append_pyerr = function (json) {
252 var tb = json.traceback;
252 var tb = json.traceback;
253 if (tb !== undefined && tb.length > 0) {
253 if (tb !== undefined && tb.length > 0) {
254 var s = '';
254 var s = '';
255 var len = tb.length;
255 var len = tb.length;
256 for (var i=0; i<len; i++) {
256 for (var i=0; i<len; i++) {
257 s = s + tb[i] + '\n';
257 s = s + tb[i] + '\n';
258 }
258 }
259 s = s + '\n';
259 s = s + '\n';
260 var toinsert = this.create_output_area();
260 var toinsert = this.create_output_area();
261 this.append_text(s, toinsert);
261 this.append_text(s, toinsert);
262 this.element.find('div.output').append(toinsert);
262 this.element.find('div.output').append(toinsert);
263 };
263 };
264 };
264 };
265
265
266
266
267 CodeCell.prototype.append_stream = function (json) {
267 CodeCell.prototype.append_stream = function (json) {
268 // temporary fix: if stream undefined (json file written prior to this patch),
268 // temporary fix: if stream undefined (json file written prior to this patch),
269 // default to most likely stdout:
269 // default to most likely stdout:
270 if (json.stream == undefined){
270 if (json.stream == undefined){
271 json.stream = 'stdout';
271 json.stream = 'stdout';
272 }
272 }
273 var subclass = "output_"+json.stream;
273 var subclass = "output_"+json.stream;
274 if (this.outputs.length > 0){
274 if (this.outputs.length > 0){
275 // have at least one output to consider
275 // have at least one output to consider
276 var last = this.outputs[this.outputs.length-1];
276 var last = this.outputs[this.outputs.length-1];
277 if (last.output_type == 'stream' && json.stream == last.stream){
277 if (last.output_type == 'stream' && json.stream == last.stream){
278 // latest output was in the same stream,
278 // latest output was in the same stream,
279 // so append directly into its pre tag
279 // so append directly into its pre tag
280 this.element.find('div.'+subclass).last().find('pre').append(json.text);
280 this.element.find('div.'+subclass).last().find('pre').append(json.text);
281 return;
281 return;
282 }
282 }
283 }
283 }
284
284
285 // If we got here, attach a new div
285 // If we got here, attach a new div
286 var toinsert = this.create_output_area();
286 var toinsert = this.create_output_area();
287 this.append_text(json.text, toinsert, "output_stream "+subclass);
287 this.append_text(json.text, toinsert, "output_stream "+subclass);
288 this.element.find('div.output').append(toinsert);
288 this.element.find('div.output').append(toinsert);
289 };
289 };
290
290
291
291
292 CodeCell.prototype.append_display_data = function (json) {
292 CodeCell.prototype.append_display_data = function (json) {
293 var toinsert = this.create_output_area();
293 var toinsert = this.create_output_area();
294 this.append_mime_type(json, toinsert)
294 this.append_mime_type(json, toinsert)
295 this.element.find('div.output').append(toinsert);
295 this.element.find('div.output').append(toinsert);
296 // If we just output latex, typeset it.
296 // If we just output latex, typeset it.
297 if (json.latex !== undefined) {
297 if (json.latex !== undefined) {
298 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
298 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
299 };
299 };
300 };
300 };
301
301
302
302
303 CodeCell.prototype.append_mime_type = function (json, element) {
303 CodeCell.prototype.append_mime_type = function (json, element) {
304 if (json.html !== undefined) {
304 if (json.html !== undefined) {
305 this.append_html(json.html, element);
305 this.append_html(json.html, element);
306 } else if (json.latex !== undefined) {
306 } else if (json.latex !== undefined) {
307 this.append_latex(json.latex, element);
307 this.append_latex(json.latex, element);
308 } else if (json.svg !== undefined) {
308 } else if (json.svg !== undefined) {
309 this.append_svg(json.svg, element);
309 this.append_svg(json.svg, element);
310 } else if (json.png !== undefined) {
310 } else if (json.png !== undefined) {
311 this.append_png(json.png, element);
311 this.append_png(json.png, element);
312 } else if (json.jpeg !== undefined) {
312 } else if (json.jpeg !== undefined) {
313 this.append_jpeg(json.jpeg, element);
313 this.append_jpeg(json.jpeg, element);
314 } else if (json.text !== undefined) {
314 } else if (json.text !== undefined) {
315 this.append_text(json.text, element);
315 this.append_text(json.text, element);
316 };
316 };
317 };
317 };
318
318
319
319
320 CodeCell.prototype.append_html = function (html, element) {
320 CodeCell.prototype.append_html = function (html, element) {
321 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_html rendered_html");
321 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_html rendered_html");
322 toinsert.append(html);
322 toinsert.append(html);
323 element.append(toinsert);
323 element.append(toinsert);
324 }
324 }
325
325
326
326
327 CodeCell.prototype.append_text = function (data, element, extra_class) {
327 CodeCell.prototype.append_text = function (data, element, extra_class) {
328 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_text");
328 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_text");
329 if (extra_class){
329 if (extra_class){
330 toinsert.addClass(extra_class);
330 toinsert.addClass(extra_class);
331 }
331 }
332 toinsert.append($("<pre/>").html(data));
332 toinsert.append($("<pre/>").html(data));
333 element.append(toinsert);
333 element.append(toinsert);
334 };
334 };
335
335
336
336
337 CodeCell.prototype.append_svg = function (svg, element) {
337 CodeCell.prototype.append_svg = function (svg, element) {
338 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_svg");
338 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_svg");
339 toinsert.append(svg);
339 toinsert.append(svg);
340 element.append(toinsert);
340 element.append(toinsert);
341 };
341 };
342
342
343
343
344 CodeCell.prototype.append_png = function (png, element) {
344 CodeCell.prototype.append_png = function (png, element) {
345 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_png");
345 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_png");
346 toinsert.append($("<img/>").attr('src','data:image/png;base64,'+png));
346 toinsert.append($("<img/>").attr('src','data:image/png;base64,'+png));
347 element.append(toinsert);
347 element.append(toinsert);
348 };
348 };
349
349
350
350
351 CodeCell.prototype.append_jpeg = function (jpeg, element) {
351 CodeCell.prototype.append_jpeg = function (jpeg, element) {
352 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_jpeg");
352 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_jpeg");
353 toinsert.append($("<img/>").attr('src','data:image/jpeg;base64,'+jpeg));
353 toinsert.append($("<img/>").attr('src','data:image/jpeg;base64,'+jpeg));
354 element.append(toinsert);
354 element.append(toinsert);
355 };
355 };
356
356
357
357
358 CodeCell.prototype.append_latex = function (latex, element) {
358 CodeCell.prototype.append_latex = function (latex, element) {
359 // This method cannot do the typesetting because the latex first has to
359 // This method cannot do the typesetting because the latex first has to
360 // be on the page.
360 // be on the page.
361 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_latex");
361 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_latex");
362 toinsert.append(latex);
362 toinsert.append(latex);
363 element.append(toinsert);
363 element.append(toinsert);
364 }
364 }
365
365
366
366
367 CodeCell.prototype.clear_output = function () {
367 CodeCell.prototype.clear_output = function () {
368 this.element.find("div.output").html("");
368 this.element.find("div.output").html("");
369 this.outputs = [];
369 this.outputs = [];
370 };
370 };
371
371
372
372
373 CodeCell.prototype.clear_input = function () {
373 CodeCell.prototype.clear_input = function () {
374 this.code_mirror.setValue('');
374 this.code_mirror.setValue('');
375 };
375 };
376
376
377
377
378 CodeCell.prototype.collapse = function () {
378 CodeCell.prototype.collapse = function () {
379 if (!this.collapsed) {
379 if (!this.collapsed) {
380 this.element.find('div.output').hide();
380 this.element.find('div.output').hide();
381 this.collapsed = true;
381 this.collapsed = true;
382 };
382 };
383 };
383 };
384
384
385
385
386 CodeCell.prototype.expand = function () {
386 CodeCell.prototype.expand = function () {
387 if (this.collapsed) {
387 if (this.collapsed) {
388 this.element.find('div.output').show();
388 this.element.find('div.output').show();
389 this.collapsed = false;
389 this.collapsed = false;
390 };
390 };
391 };
391 };
392
392
393
393
394 CodeCell.prototype.toggle_output = function () {
394 CodeCell.prototype.toggle_output = function () {
395 if (this.collapsed) {
395 if (this.collapsed) {
396 this.expand();
396 this.expand();
397 } else {
397 } else {
398 this.collapse();
398 this.collapse();
399 };
399 };
400 };
400 };
401
401
402 CodeCell.prototype.set_input_prompt = function (number) {
402 CodeCell.prototype.set_input_prompt = function (number) {
403 var n = number || ' ';
403 var n = number || ' ';
404 this.input_prompt_number = n
404 this.input_prompt_number = n
405 this.element.find('div.input_prompt').html('In&nbsp;[' + n + ']:');
405 this.element.find('div.input_prompt').html('In&nbsp;[' + n + ']:');
406 };
406 };
407
407
408
408
409 CodeCell.prototype.get_code = function () {
409 CodeCell.prototype.get_code = function () {
410 return this.code_mirror.getValue();
410 return this.code_mirror.getValue();
411 };
411 };
412
412
413
413
414 CodeCell.prototype.set_code = function (code) {
414 CodeCell.prototype.set_code = function (code) {
415 return this.code_mirror.setValue(code);
415 return this.code_mirror.setValue(code);
416 };
416 };
417
417
418
418
419 CodeCell.prototype.at_top = function () {
419 CodeCell.prototype.at_top = function () {
420 var cursor = this.code_mirror.getCursor();
420 var cursor = this.code_mirror.getCursor();
421 if (cursor.line === 0) {
421 if (cursor.line === 0) {
422 return true;
422 return true;
423 } else {
423 } else {
424 return false;
424 return false;
425 }
425 }
426 };
426 };
427
427
428
428
429 CodeCell.prototype.at_bottom = function () {
429 CodeCell.prototype.at_bottom = function () {
430 var cursor = this.code_mirror.getCursor();
430 var cursor = this.code_mirror.getCursor();
431 if (cursor.line === (this.code_mirror.lineCount()-1)) {
431 if (cursor.line === (this.code_mirror.lineCount()-1)) {
432 return true;
432 return true;
433 } else {
433 } else {
434 return false;
434 return false;
435 }
435 }
436 };
436 };
437
437
438
438
439 CodeCell.prototype.fromJSON = function (data) {
439 CodeCell.prototype.fromJSON = function (data) {
440 console.log('Import from JSON:', data);
440 console.log('Import from JSON:', data);
441 if (data.cell_type === 'code') {
441 if (data.cell_type === 'code') {
442 if (data.input !== undefined) {
442 if (data.input !== undefined) {
443 this.set_code(data.input);
443 this.set_code(data.input);
444 }
444 }
445 if (data.prompt_number !== undefined) {
445 if (data.prompt_number !== undefined) {
446 this.set_input_prompt(data.prompt_number);
446 this.set_input_prompt(data.prompt_number);
447 } else {
447 } else {
448 this.set_input_prompt();
448 this.set_input_prompt();
449 };
449 };
450 var len = data.outputs.length;
450 var len = data.outputs.length;
451 for (var i=0; i<len; i++) {
451 for (var i=0; i<len; i++) {
452 this.append_output(data.outputs[i]);
452 this.append_output(data.outputs[i]);
453 };
453 };
454 if (data.collapsed !== undefined) {
454 if (data.collapsed !== undefined) {
455 if (data.collapsed) {
455 if (data.collapsed) {
456 this.collapse();
456 this.collapse();
457 };
457 };
458 };
458 };
459 };
459 };
460 };
460 };
461
461
462
462
463 CodeCell.prototype.toJSON = function () {
463 CodeCell.prototype.toJSON = function () {
464 var data = {};
464 var data = {};
465 data.input = this.get_code();
465 data.input = this.get_code();
466 data.cell_type = 'code';
466 data.cell_type = 'code';
467 if (this.input_prompt_number !== ' ') {
467 if (this.input_prompt_number !== ' ') {
468 data.prompt_number = this.input_prompt_number
468 data.prompt_number = this.input_prompt_number
469 };
469 };
470 var outputs = [];
470 var outputs = [];
471 var len = this.outputs.length;
471 var len = this.outputs.length;
472 for (var i=0; i<len; i++) {
472 for (var i=0; i<len; i++) {
473 outputs[i] = this.outputs[i];
473 outputs[i] = this.outputs[i];
474 };
474 };
475 data.outputs = outputs;
475 data.outputs = outputs;
476 data.language = 'python';
476 data.language = 'python';
477 data.collapsed = this.collapsed;
477 data.collapsed = this.collapsed;
478 // console.log('Export to JSON:',data);
478 // console.log('Export to JSON:',data);
479 return data;
479 return data;
480 };
480 };
481
481
482
482
483 IPython.CodeCell = CodeCell;
483 IPython.CodeCell = CodeCell;
484
484
485 return IPython;
485 return IPython;
486 }(IPython));
486 }(IPython));
@@ -1,41 +1,41 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 // HeaderSection
9 // HeaderSection
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var HeaderSection = function (selector) {
14 var HeaderSection = 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.content = this.element.find('div.header');
18 this.content = this.element.find('div.header');
19 this.style();
19 this.style();
20 this.bind_events();
20 this.bind_events();
21 }
21 }
22 };
22 };
23
23
24 HeaderSection.prototype.style = function () {
24 HeaderSection.prototype.style = function () {
25 this.content.addClass('ui-helper-clearfix');
25 this.content.addClass('ui-helper-clearfix');
26 this.content.find('#quick_help').button();
26 this.content.find('#quick_help').button();
27 };
27 };
28
28
29 HeaderSection.prototype.bind_events = function () {
29 HeaderSection.prototype.bind_events = function () {
30 var that = this;
30 var that = this;
31 this.content.find('#quick_help').click(function () {
31 this.content.find('#quick_help').click(function () {
32 IPython.notebook.show_keyboard_shortcuts();
32 IPython.notebook.show_keyboard_shortcuts();
33 });
33 });
34 };
34 };
35
35
36 // Set module variables
36 // Set module variables
37 IPython.HeaderSection = HeaderSection;
37 IPython.HeaderSection = HeaderSection;
38
38
39 return IPython;
39 return IPython;
40
40
41 }(IPython));
41 }(IPython));
@@ -1,972 +1,972 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.element = $(selector);
17 this.element = $(selector);
18 this.element.scroll();
18 this.element.scroll();
19 this.element.data("notebook", this);
19 this.element.data("notebook", this);
20 this.next_prompt_number = 1;
20 this.next_prompt_number = 1;
21 this.kernel = null;
21 this.kernel = null;
22 this.dirty = false;
22 this.dirty = false;
23 this.msg_cell_map = {};
23 this.msg_cell_map = {};
24 this.metadata = {};
24 this.metadata = {};
25 this.control_key_active = false;
25 this.control_key_active = false;
26 this.style();
26 this.style();
27 this.create_elements();
27 this.create_elements();
28 this.bind_events();
28 this.bind_events();
29 };
29 };
30
30
31
31
32 Notebook.prototype.style = function () {
32 Notebook.prototype.style = function () {
33 $('div#notebook').addClass('border-box-sizing');
33 $('div#notebook').addClass('border-box-sizing');
34 };
34 };
35
35
36
36
37 Notebook.prototype.create_elements = function () {
37 Notebook.prototype.create_elements = function () {
38 // We add this end_space div to the end of the notebook div to:
38 // We add this end_space div to the end of the notebook div to:
39 // i) provide a margin between the last cell and the end of the notebook
39 // i) provide a margin between the last cell and the end of the notebook
40 // ii) to prevent the div from scrolling up when the last cell is being
40 // ii) to prevent the div from scrolling up when the last cell is being
41 // edited, but is too low on the page, which browsers will do automatically.
41 // edited, but is too low on the page, which browsers will do automatically.
42 var that = this;
42 var that = this;
43 var end_space = $('<div class="end_space"></div>').height(150);
43 var end_space = $('<div class="end_space"></div>').height(150);
44 end_space.dblclick(function (e) {
44 end_space.dblclick(function (e) {
45 var ncells = that.ncells();
45 var ncells = that.ncells();
46 that.insert_code_cell_below(ncells-1);
46 that.insert_code_cell_below(ncells-1);
47 });
47 });
48 this.element.append(end_space);
48 this.element.append(end_space);
49 $('div#notebook').addClass('border-box-sizing');
49 $('div#notebook').addClass('border-box-sizing');
50 };
50 };
51
51
52
52
53 Notebook.prototype.bind_events = function () {
53 Notebook.prototype.bind_events = function () {
54 var that = this;
54 var that = this;
55 $(document).keydown(function (event) {
55 $(document).keydown(function (event) {
56 // console.log(event);
56 // console.log(event);
57 if (event.which === 38) {
57 if (event.which === 38) {
58 var cell = that.selected_cell();
58 var cell = that.selected_cell();
59 if (cell.at_top()) {
59 if (cell.at_top()) {
60 event.preventDefault();
60 event.preventDefault();
61 that.select_prev();
61 that.select_prev();
62 };
62 };
63 } else if (event.which === 40) {
63 } else if (event.which === 40) {
64 var cell = that.selected_cell();
64 var cell = that.selected_cell();
65 if (cell.at_bottom()) {
65 if (cell.at_bottom()) {
66 event.preventDefault();
66 event.preventDefault();
67 that.select_next();
67 that.select_next();
68 };
68 };
69 } else if (event.which === 13 && event.shiftKey) {
69 } else if (event.which === 13 && event.shiftKey) {
70 that.execute_selected_cell();
70 that.execute_selected_cell();
71 return false;
71 return false;
72 } else if (event.which === 13 && event.ctrlKey) {
72 } else if (event.which === 13 && event.ctrlKey) {
73 that.execute_selected_cell({terminal:true});
73 that.execute_selected_cell({terminal:true});
74 return false;
74 return false;
75 } else if (event.which === 77 && event.ctrlKey) {
75 } else if (event.which === 77 && event.ctrlKey) {
76 that.control_key_active = true;
76 that.control_key_active = true;
77 return false;
77 return false;
78 } else if (event.which === 68 && that.control_key_active) {
78 } else if (event.which === 68 && that.control_key_active) {
79 // Delete selected cell = d
79 // Delete selected cell = d
80 that.delete_cell();
80 that.delete_cell();
81 that.control_key_active = false;
81 that.control_key_active = false;
82 return false;
82 return false;
83 } else if (event.which === 65 && that.control_key_active) {
83 } else if (event.which === 65 && that.control_key_active) {
84 // Insert code cell above selected = a
84 // Insert code cell above selected = a
85 that.insert_code_cell_above();
85 that.insert_code_cell_above();
86 that.control_key_active = false;
86 that.control_key_active = false;
87 return false;
87 return false;
88 } else if (event.which === 66 && that.control_key_active) {
88 } else if (event.which === 66 && that.control_key_active) {
89 // Insert code cell below selected = b
89 // Insert code cell below selected = b
90 that.insert_code_cell_below();
90 that.insert_code_cell_below();
91 that.control_key_active = false;
91 that.control_key_active = false;
92 return false;
92 return false;
93 } else if (event.which === 67 && that.control_key_active) {
93 } else if (event.which === 67 && that.control_key_active) {
94 // To code = c
94 // To code = c
95 that.to_code();
95 that.to_code();
96 that.control_key_active = false;
96 that.control_key_active = false;
97 return false;
97 return false;
98 } else if (event.which === 77 && that.control_key_active) {
98 } else if (event.which === 77 && that.control_key_active) {
99 // To markdown = m
99 // To markdown = m
100 that.to_markdown();
100 that.to_markdown();
101 that.control_key_active = false;
101 that.control_key_active = false;
102 return false;
102 return false;
103 } else if (event.which === 84 && that.control_key_active) {
103 } else if (event.which === 84 && that.control_key_active) {
104 // Toggle output = t
104 // Toggle output = t
105 that.toggle_output();
105 that.toggle_output();
106 that.control_key_active = false;
106 that.control_key_active = false;
107 return false;
107 return false;
108 } else if (event.which === 83 && that.control_key_active) {
108 } else if (event.which === 83 && that.control_key_active) {
109 // Save notebook = s
109 // Save notebook = s
110 IPython.save_widget.save_notebook();
110 IPython.save_widget.save_notebook();
111 that.control_key_active = false;
111 that.control_key_active = false;
112 return false;
112 return false;
113 } else if (event.which === 74 && that.control_key_active) {
113 } else if (event.which === 74 && that.control_key_active) {
114 // Move cell down = j
114 // Move cell down = j
115 that.move_cell_down();
115 that.move_cell_down();
116 that.control_key_active = false;
116 that.control_key_active = false;
117 return false;
117 return false;
118 } else if (event.which === 75 && that.control_key_active) {
118 } else if (event.which === 75 && that.control_key_active) {
119 // Move cell up = k
119 // Move cell up = k
120 that.move_cell_up();
120 that.move_cell_up();
121 that.control_key_active = false;
121 that.control_key_active = false;
122 return false;
122 return false;
123 } else if (event.which === 80 && that.control_key_active) {
123 } else if (event.which === 80 && that.control_key_active) {
124 // Select previous = p
124 // Select previous = p
125 that.select_prev();
125 that.select_prev();
126 that.control_key_active = false;
126 that.control_key_active = false;
127 return false;
127 return false;
128 } else if (event.which === 78 && that.control_key_active) {
128 } else if (event.which === 78 && that.control_key_active) {
129 // Select next = n
129 // Select next = n
130 that.select_next();
130 that.select_next();
131 that.control_key_active = false;
131 that.control_key_active = false;
132 return false;
132 return false;
133 } else if (event.which === 72 && that.control_key_active) {
133 } else if (event.which === 72 && that.control_key_active) {
134 // Show keyboard shortcuts = h
134 // Show keyboard shortcuts = h
135 that.show_keyboard_shortcuts();
135 that.show_keyboard_shortcuts();
136 that.control_key_active = false;
136 that.control_key_active = false;
137 return false;
137 return false;
138 } else if (event.which === 73 && that.control_key_active) {
138 } else if (event.which === 73 && that.control_key_active) {
139 // Interrupt kernel = i
139 // Interrupt kernel = i
140 IPython.notebook.kernel.interrupt();
140 IPython.notebook.kernel.interrupt();
141 that.control_key_active = false;
141 that.control_key_active = false;
142 return false;
142 return false;
143 } else if (event.which === 76 && that.control_key_active) {
143 } else if (event.which === 76 && that.control_key_active) {
144 // Toggle line numbers = l
144 // Toggle line numbers = l
145 that.cell_toggle_line_numbers();
145 that.cell_toggle_line_numbers();
146 that.control_key_active = false;
146 that.control_key_active = false;
147 return false;
147 return false;
148 } else if (event.which === 190 && that.control_key_active) {
148 } else if (event.which === 190 && that.control_key_active) {
149 // Restart kernel = . # matches qt console
149 // Restart kernel = . # matches qt console
150 IPython.notebook.restart_kernel();
150 IPython.notebook.restart_kernel();
151 that.control_key_active = false;
151 that.control_key_active = false;
152 return false;
152 return false;
153 } else if (that.control_key_active) {
153 } else if (that.control_key_active) {
154 that.control_key_active = false;
154 that.control_key_active = false;
155 return true;
155 return true;
156 };
156 };
157 });
157 });
158
158
159 this.element.bind('collapse_pager', function () {
159 this.element.bind('collapse_pager', function () {
160 var app_height = $('div#main_app').height(); // content height
160 var app_height = $('div#main_app').height(); // content height
161 var splitter_height = $('div#pager_splitter').outerHeight(true);
161 var splitter_height = $('div#pager_splitter').outerHeight(true);
162 var new_height = app_height - splitter_height;
162 var new_height = app_height - splitter_height;
163 that.element.animate({height : new_height + 'px'}, 'fast');
163 that.element.animate({height : new_height + 'px'}, 'fast');
164 });
164 });
165
165
166 this.element.bind('expand_pager', function () {
166 this.element.bind('expand_pager', function () {
167 var app_height = $('div#main_app').height(); // content height
167 var app_height = $('div#main_app').height(); // content height
168 var splitter_height = $('div#pager_splitter').outerHeight(true);
168 var splitter_height = $('div#pager_splitter').outerHeight(true);
169 var pager_height = $('div#pager').outerHeight(true);
169 var pager_height = $('div#pager').outerHeight(true);
170 var new_height = app_height - pager_height - splitter_height;
170 var new_height = app_height - pager_height - splitter_height;
171 that.element.animate({height : new_height + 'px'}, 'fast');
171 that.element.animate({height : new_height + 'px'}, 'fast');
172 });
172 });
173
173
174 this.element.bind('collapse_left_panel', function () {
174 this.element.bind('collapse_left_panel', function () {
175 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
175 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
176 var new_margin = splitter_width;
176 var new_margin = splitter_width;
177 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
177 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
178 });
178 });
179
179
180 this.element.bind('expand_left_panel', function () {
180 this.element.bind('expand_left_panel', function () {
181 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
181 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
182 var left_panel_width = IPython.left_panel.width;
182 var left_panel_width = IPython.left_panel.width;
183 var new_margin = splitter_width + left_panel_width;
183 var new_margin = splitter_width + left_panel_width;
184 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
184 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
185 });
185 });
186
186
187 $(window).bind('beforeunload', function () {
187 $(window).bind('beforeunload', function () {
188 var kill_kernel = $('#kill_kernel').prop('checked');
188 var kill_kernel = $('#kill_kernel').prop('checked');
189 if (kill_kernel) {
189 if (kill_kernel) {
190 that.kernel.kill();
190 that.kernel.kill();
191 }
191 }
192 if (that.dirty) {
192 if (that.dirty) {
193 return "You have unsaved changes that will be lost if you leave this page.";
193 return "You have unsaved changes that will be lost if you leave this page.";
194 };
194 };
195 });
195 });
196 };
196 };
197
197
198
198
199 Notebook.prototype.show_keyboard_shortcuts = function () {
199 Notebook.prototype.show_keyboard_shortcuts = function () {
200 var dialog = $('<div/>');
200 var dialog = $('<div/>');
201 var shortcuts = [
201 var shortcuts = [
202 {key: 'Shift-Enter', help: 'run cell'},
202 {key: 'Shift-Enter', help: 'run cell'},
203 {key: 'Ctrl-Enter', help: 'run cell in-place'},
203 {key: 'Ctrl-Enter', help: 'run cell in-place'},
204 {key: 'Ctrl-m d', help: 'delete cell'},
204 {key: 'Ctrl-m d', help: 'delete cell'},
205 {key: 'Ctrl-m a', help: 'insert cell above'},
205 {key: 'Ctrl-m a', help: 'insert cell above'},
206 {key: 'Ctrl-m b', help: 'insert cell below'},
206 {key: 'Ctrl-m b', help: 'insert cell below'},
207 {key: 'Ctrl-m t', help: 'toggle output'},
207 {key: 'Ctrl-m t', help: 'toggle output'},
208 {key: 'Ctrl-m l', help: 'toggle line numbers'},
208 {key: 'Ctrl-m l', help: 'toggle line numbers'},
209 {key: 'Ctrl-m s', help: 'save notebook'},
209 {key: 'Ctrl-m s', help: 'save notebook'},
210 {key: 'Ctrl-m j', help: 'move cell down'},
210 {key: 'Ctrl-m j', help: 'move cell down'},
211 {key: 'Ctrl-m k', help: 'move cell up'},
211 {key: 'Ctrl-m k', help: 'move cell up'},
212 {key: 'Ctrl-m c', help: 'code cell'},
212 {key: 'Ctrl-m c', help: 'code cell'},
213 {key: 'Ctrl-m m', help: 'markdown cell'},
213 {key: 'Ctrl-m m', help: 'markdown cell'},
214 {key: 'Ctrl-m p', help: 'select previous'},
214 {key: 'Ctrl-m p', help: 'select previous'},
215 {key: 'Ctrl-m n', help: 'select next'},
215 {key: 'Ctrl-m n', help: 'select next'},
216 {key: 'Ctrl-m i', help: 'interrupt kernel'},
216 {key: 'Ctrl-m i', help: 'interrupt kernel'},
217 {key: 'Ctrl-m .', help: 'restart kernel'},
217 {key: 'Ctrl-m .', help: 'restart kernel'},
218 {key: 'Ctrl-m h', help: 'show keyboard shortcuts'}
218 {key: 'Ctrl-m h', help: 'show keyboard shortcuts'}
219 ];
219 ];
220 for (var i=0; i<shortcuts.length; i++) {
220 for (var i=0; i<shortcuts.length; i++) {
221 dialog.append($('<div>').
221 dialog.append($('<div>').
222 append($('<span/>').addClass('shortcut_key').html(shortcuts[i].key)).
222 append($('<span/>').addClass('shortcut_key').html(shortcuts[i].key)).
223 append($('<span/>').addClass('shortcut_descr').html(' : ' + shortcuts[i].help))
223 append($('<span/>').addClass('shortcut_descr').html(' : ' + shortcuts[i].help))
224 );
224 );
225 };
225 };
226 dialog.dialog({title: 'Keyboard shortcuts'});
226 dialog.dialog({title: 'Keyboard shortcuts'});
227 };
227 };
228
228
229
229
230 Notebook.prototype.scroll_to_bottom = function () {
230 Notebook.prototype.scroll_to_bottom = function () {
231 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
231 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
232 };
232 };
233
233
234
234
235 Notebook.prototype.scroll_to_top = function () {
235 Notebook.prototype.scroll_to_top = function () {
236 this.element.animate({scrollTop:0}, 0);
236 this.element.animate({scrollTop:0}, 0);
237 };
237 };
238
238
239
239
240 // Cell indexing, retrieval, etc.
240 // Cell indexing, retrieval, etc.
241
241
242
242
243 Notebook.prototype.cell_elements = function () {
243 Notebook.prototype.cell_elements = function () {
244 return this.element.children("div.cell");
244 return this.element.children("div.cell");
245 }
245 }
246
246
247
247
248 Notebook.prototype.ncells = function (cell) {
248 Notebook.prototype.ncells = function (cell) {
249 return this.cell_elements().length;
249 return this.cell_elements().length;
250 }
250 }
251
251
252
252
253 // TODO: we are often calling cells as cells()[i], which we should optimize
253 // TODO: we are often calling cells as cells()[i], which we should optimize
254 // to cells(i) or a new method.
254 // to cells(i) or a new method.
255 Notebook.prototype.cells = function () {
255 Notebook.prototype.cells = function () {
256 return this.cell_elements().toArray().map(function (e) {
256 return this.cell_elements().toArray().map(function (e) {
257 return $(e).data("cell");
257 return $(e).data("cell");
258 });
258 });
259 }
259 }
260
260
261
261
262 Notebook.prototype.find_cell_index = function (cell) {
262 Notebook.prototype.find_cell_index = function (cell) {
263 var result = null;
263 var result = null;
264 this.cell_elements().filter(function (index) {
264 this.cell_elements().filter(function (index) {
265 if ($(this).data("cell") === cell) {
265 if ($(this).data("cell") === cell) {
266 result = index;
266 result = index;
267 };
267 };
268 });
268 });
269 return result;
269 return result;
270 };
270 };
271
271
272
272
273 Notebook.prototype.index_or_selected = function (index) {
273 Notebook.prototype.index_or_selected = function (index) {
274 return index || this.selected_index() || 0;
274 return index || this.selected_index() || 0;
275 }
275 }
276
276
277
277
278 Notebook.prototype.select = function (index) {
278 Notebook.prototype.select = function (index) {
279 if (index !== undefined && index >= 0 && index < this.ncells()) {
279 if (index !== undefined && index >= 0 && index < this.ncells()) {
280 if (this.selected_index() !== null) {
280 if (this.selected_index() !== null) {
281 this.selected_cell().unselect();
281 this.selected_cell().unselect();
282 };
282 };
283 this.cells()[index].select();
283 this.cells()[index].select();
284 };
284 };
285 return this;
285 return this;
286 };
286 };
287
287
288
288
289 Notebook.prototype.select_next = function () {
289 Notebook.prototype.select_next = function () {
290 var index = this.selected_index();
290 var index = this.selected_index();
291 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
291 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
292 this.select(index+1);
292 this.select(index+1);
293 };
293 };
294 return this;
294 return this;
295 };
295 };
296
296
297
297
298 Notebook.prototype.select_prev = function () {
298 Notebook.prototype.select_prev = function () {
299 var index = this.selected_index();
299 var index = this.selected_index();
300 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
300 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
301 this.select(index-1);
301 this.select(index-1);
302 };
302 };
303 return this;
303 return this;
304 };
304 };
305
305
306
306
307 Notebook.prototype.selected_index = function () {
307 Notebook.prototype.selected_index = function () {
308 var result = null;
308 var result = null;
309 this.cell_elements().filter(function (index) {
309 this.cell_elements().filter(function (index) {
310 if ($(this).data("cell").selected === true) {
310 if ($(this).data("cell").selected === true) {
311 result = index;
311 result = index;
312 };
312 };
313 });
313 });
314 return result;
314 return result;
315 };
315 };
316
316
317
317
318 Notebook.prototype.cell_for_msg = function (msg_id) {
318 Notebook.prototype.cell_for_msg = function (msg_id) {
319 var cell_id = this.msg_cell_map[msg_id];
319 var cell_id = this.msg_cell_map[msg_id];
320 var result = null;
320 var result = null;
321 this.cell_elements().filter(function (index) {
321 this.cell_elements().filter(function (index) {
322 cell = $(this).data("cell");
322 cell = $(this).data("cell");
323 if (cell.cell_id === cell_id) {
323 if (cell.cell_id === cell_id) {
324 result = cell;
324 result = cell;
325 };
325 };
326 });
326 });
327 return result;
327 return result;
328 };
328 };
329
329
330
330
331 Notebook.prototype.selected_cell = function () {
331 Notebook.prototype.selected_cell = function () {
332 return this.cell_elements().eq(this.selected_index()).data("cell");
332 return this.cell_elements().eq(this.selected_index()).data("cell");
333 }
333 }
334
334
335
335
336 // Cell insertion, deletion and moving.
336 // Cell insertion, deletion and moving.
337
337
338
338
339 Notebook.prototype.delete_cell = function (index) {
339 Notebook.prototype.delete_cell = function (index) {
340 var i = index || this.selected_index();
340 var i = index || this.selected_index();
341 if (i !== null && i >= 0 && i < this.ncells()) {
341 if (i !== null && i >= 0 && i < this.ncells()) {
342 this.cell_elements().eq(i).remove();
342 this.cell_elements().eq(i).remove();
343 if (i === (this.ncells())) {
343 if (i === (this.ncells())) {
344 this.select(i-1);
344 this.select(i-1);
345 } else {
345 } else {
346 this.select(i);
346 this.select(i);
347 };
347 };
348 };
348 };
349 this.dirty = true;
349 this.dirty = true;
350 return this;
350 return this;
351 };
351 };
352
352
353
353
354 Notebook.prototype.append_cell = function (cell) {
354 Notebook.prototype.append_cell = function (cell) {
355 this.element.find('div.end_space').before(cell.element);
355 this.element.find('div.end_space').before(cell.element);
356 this.dirty = true;
356 this.dirty = true;
357 return this;
357 return this;
358 };
358 };
359
359
360
360
361 Notebook.prototype.insert_cell_below = function (cell, index) {
361 Notebook.prototype.insert_cell_below = function (cell, index) {
362 var ncells = this.ncells();
362 var ncells = this.ncells();
363 if (ncells === 0) {
363 if (ncells === 0) {
364 this.append_cell(cell);
364 this.append_cell(cell);
365 return this;
365 return this;
366 };
366 };
367 if (index >= 0 && index < ncells) {
367 if (index >= 0 && index < ncells) {
368 this.cell_elements().eq(index).after(cell.element);
368 this.cell_elements().eq(index).after(cell.element);
369 };
369 };
370 this.dirty = true;
370 this.dirty = true;
371 return this
371 return this
372 };
372 };
373
373
374
374
375 Notebook.prototype.insert_cell_above = function (cell, index) {
375 Notebook.prototype.insert_cell_above = function (cell, index) {
376 var ncells = this.ncells();
376 var ncells = this.ncells();
377 if (ncells === 0) {
377 if (ncells === 0) {
378 this.append_cell(cell);
378 this.append_cell(cell);
379 return this;
379 return this;
380 };
380 };
381 if (index >= 0 && index < ncells) {
381 if (index >= 0 && index < ncells) {
382 this.cell_elements().eq(index).before(cell.element);
382 this.cell_elements().eq(index).before(cell.element);
383 };
383 };
384 this.dirty = true;
384 this.dirty = true;
385 return this;
385 return this;
386 };
386 };
387
387
388
388
389 Notebook.prototype.move_cell_up = function (index) {
389 Notebook.prototype.move_cell_up = function (index) {
390 var i = index || this.selected_index();
390 var i = index || this.selected_index();
391 if (i !== null && i < this.ncells() && i > 0) {
391 if (i !== null && i < this.ncells() && i > 0) {
392 var pivot = this.cell_elements().eq(i-1);
392 var pivot = this.cell_elements().eq(i-1);
393 var tomove = this.cell_elements().eq(i);
393 var tomove = this.cell_elements().eq(i);
394 if (pivot !== null && tomove !== null) {
394 if (pivot !== null && tomove !== null) {
395 tomove.detach();
395 tomove.detach();
396 pivot.before(tomove);
396 pivot.before(tomove);
397 this.select(i-1);
397 this.select(i-1);
398 };
398 };
399 };
399 };
400 this.dirty = true;
400 this.dirty = true;
401 return this;
401 return this;
402 }
402 }
403
403
404
404
405 Notebook.prototype.move_cell_down = function (index) {
405 Notebook.prototype.move_cell_down = function (index) {
406 var i = index || this.selected_index();
406 var i = index || this.selected_index();
407 if (i !== null && i < (this.ncells()-1) && i >= 0) {
407 if (i !== null && i < (this.ncells()-1) && i >= 0) {
408 var pivot = this.cell_elements().eq(i+1)
408 var pivot = this.cell_elements().eq(i+1)
409 var tomove = this.cell_elements().eq(i)
409 var tomove = this.cell_elements().eq(i)
410 if (pivot !== null && tomove !== null) {
410 if (pivot !== null && tomove !== null) {
411 tomove.detach();
411 tomove.detach();
412 pivot.after(tomove);
412 pivot.after(tomove);
413 this.select(i+1);
413 this.select(i+1);
414 };
414 };
415 };
415 };
416 this.dirty = true;
416 this.dirty = true;
417 return this;
417 return this;
418 }
418 }
419
419
420
420
421 Notebook.prototype.sort_cells = function () {
421 Notebook.prototype.sort_cells = function () {
422 var ncells = this.ncells();
422 var ncells = this.ncells();
423 var sindex = this.selected_index();
423 var sindex = this.selected_index();
424 var swapped;
424 var swapped;
425 do {
425 do {
426 swapped = false
426 swapped = false
427 for (var i=1; i<ncells; i++) {
427 for (var i=1; i<ncells; i++) {
428 current = this.cell_elements().eq(i).data("cell");
428 current = this.cell_elements().eq(i).data("cell");
429 previous = this.cell_elements().eq(i-1).data("cell");
429 previous = this.cell_elements().eq(i-1).data("cell");
430 if (previous.input_prompt_number > current.input_prompt_number) {
430 if (previous.input_prompt_number > current.input_prompt_number) {
431 this.move_cell_up(i);
431 this.move_cell_up(i);
432 swapped = true;
432 swapped = true;
433 };
433 };
434 };
434 };
435 } while (swapped);
435 } while (swapped);
436 this.select(sindex);
436 this.select(sindex);
437 return this;
437 return this;
438 };
438 };
439
439
440
440
441 Notebook.prototype.insert_code_cell_above = function (index) {
441 Notebook.prototype.insert_code_cell_above = function (index) {
442 // TODO: Bounds check for i
442 // TODO: Bounds check for i
443 var i = this.index_or_selected(index);
443 var i = this.index_or_selected(index);
444 var cell = new IPython.CodeCell(this);
444 var cell = new IPython.CodeCell(this);
445 cell.set_input_prompt();
445 cell.set_input_prompt();
446 this.insert_cell_above(cell, i);
446 this.insert_cell_above(cell, i);
447 this.select(this.find_cell_index(cell));
447 this.select(this.find_cell_index(cell));
448 return cell;
448 return cell;
449 }
449 }
450
450
451
451
452 Notebook.prototype.insert_code_cell_below = function (index) {
452 Notebook.prototype.insert_code_cell_below = function (index) {
453 // TODO: Bounds check for i
453 // TODO: Bounds check for i
454 var i = this.index_or_selected(index);
454 var i = this.index_or_selected(index);
455 var cell = new IPython.CodeCell(this);
455 var cell = new IPython.CodeCell(this);
456 cell.set_input_prompt();
456 cell.set_input_prompt();
457 this.insert_cell_below(cell, i);
457 this.insert_cell_below(cell, i);
458 this.select(this.find_cell_index(cell));
458 this.select(this.find_cell_index(cell));
459 return cell;
459 return cell;
460 }
460 }
461
461
462
462
463 Notebook.prototype.insert_html_cell_above = function (index) {
463 Notebook.prototype.insert_html_cell_above = function (index) {
464 // TODO: Bounds check for i
464 // TODO: Bounds check for i
465 var i = this.index_or_selected(index);
465 var i = this.index_or_selected(index);
466 var cell = new IPython.HTMLCell(this);
466 var cell = new IPython.HTMLCell(this);
467 cell.config_mathjax();
467 cell.config_mathjax();
468 this.insert_cell_above(cell, i);
468 this.insert_cell_above(cell, i);
469 this.select(this.find_cell_index(cell));
469 this.select(this.find_cell_index(cell));
470 return cell;
470 return cell;
471 }
471 }
472
472
473
473
474 Notebook.prototype.insert_html_cell_below = function (index) {
474 Notebook.prototype.insert_html_cell_below = function (index) {
475 // TODO: Bounds check for i
475 // TODO: Bounds check for i
476 var i = this.index_or_selected(index);
476 var i = this.index_or_selected(index);
477 var cell = new IPython.HTMLCell(this);
477 var cell = new IPython.HTMLCell(this);
478 cell.config_mathjax();
478 cell.config_mathjax();
479 this.insert_cell_below(cell, i);
479 this.insert_cell_below(cell, i);
480 this.select(this.find_cell_index(cell));
480 this.select(this.find_cell_index(cell));
481 return cell;
481 return cell;
482 }
482 }
483
483
484
484
485 Notebook.prototype.insert_markdown_cell_above = function (index) {
485 Notebook.prototype.insert_markdown_cell_above = function (index) {
486 // TODO: Bounds check for i
486 // TODO: Bounds check for i
487 var i = this.index_or_selected(index);
487 var i = this.index_or_selected(index);
488 var cell = new IPython.MarkdownCell(this);
488 var cell = new IPython.MarkdownCell(this);
489 cell.config_mathjax();
489 cell.config_mathjax();
490 this.insert_cell_above(cell, i);
490 this.insert_cell_above(cell, i);
491 this.select(this.find_cell_index(cell));
491 this.select(this.find_cell_index(cell));
492 return cell;
492 return cell;
493 }
493 }
494
494
495
495
496 Notebook.prototype.insert_markdown_cell_below = function (index) {
496 Notebook.prototype.insert_markdown_cell_below = function (index) {
497 // TODO: Bounds check for i
497 // TODO: Bounds check for i
498 var i = this.index_or_selected(index);
498 var i = this.index_or_selected(index);
499 var cell = new IPython.MarkdownCell(this);
499 var cell = new IPython.MarkdownCell(this);
500 cell.config_mathjax();
500 cell.config_mathjax();
501 this.insert_cell_below(cell, i);
501 this.insert_cell_below(cell, i);
502 this.select(this.find_cell_index(cell));
502 this.select(this.find_cell_index(cell));
503 return cell;
503 return cell;
504 }
504 }
505
505
506
506
507 Notebook.prototype.to_code = function (index) {
507 Notebook.prototype.to_code = function (index) {
508 // TODO: Bounds check for i
508 // TODO: Bounds check for i
509 var i = this.index_or_selected(index);
509 var i = this.index_or_selected(index);
510 var source_element = this.cell_elements().eq(i);
510 var source_element = this.cell_elements().eq(i);
511 var source_cell = source_element.data("cell");
511 var source_cell = source_element.data("cell");
512 if (source_cell instanceof IPython.HTMLCell ||
512 if (source_cell instanceof IPython.HTMLCell ||
513 source_cell instanceof IPython.MarkdownCell) {
513 source_cell instanceof IPython.MarkdownCell) {
514 this.insert_code_cell_below(i);
514 this.insert_code_cell_below(i);
515 var target_cell = this.cells()[i+1];
515 var target_cell = this.cells()[i+1];
516 target_cell.set_code(source_cell.get_source());
516 target_cell.set_code(source_cell.get_source());
517 source_element.remove();
517 source_element.remove();
518 target_cell.select();
518 target_cell.select();
519 };
519 };
520 this.dirty = true;
520 this.dirty = true;
521 };
521 };
522
522
523
523
524 Notebook.prototype.to_markdown = function (index) {
524 Notebook.prototype.to_markdown = function (index) {
525 // TODO: Bounds check for i
525 // TODO: Bounds check for i
526 var i = this.index_or_selected(index);
526 var i = this.index_or_selected(index);
527 var source_element = this.cell_elements().eq(i);
527 var source_element = this.cell_elements().eq(i);
528 var source_cell = source_element.data("cell");
528 var source_cell = source_element.data("cell");
529 var target_cell = null;
529 var target_cell = null;
530 if (source_cell instanceof IPython.CodeCell) {
530 if (source_cell instanceof IPython.CodeCell) {
531 this.insert_markdown_cell_below(i);
531 this.insert_markdown_cell_below(i);
532 var target_cell = this.cells()[i+1];
532 var target_cell = this.cells()[i+1];
533 var text = source_cell.get_code();
533 var text = source_cell.get_code();
534 } else if (source_cell instanceof IPython.HTMLCell) {
534 } else if (source_cell instanceof IPython.HTMLCell) {
535 this.insert_markdown_cell_below(i);
535 this.insert_markdown_cell_below(i);
536 var target_cell = this.cells()[i+1];
536 var target_cell = this.cells()[i+1];
537 var text = source_cell.get_source();
537 var text = source_cell.get_source();
538 if (text === source_cell.placeholder) {
538 if (text === source_cell.placeholder) {
539 text = target_cell.placeholder;
539 text = target_cell.placeholder;
540 }
540 }
541 }
541 }
542 if (target_cell !== null) {
542 if (target_cell !== null) {
543 if (text === "") {text = target_cell.placeholder;};
543 if (text === "") {text = target_cell.placeholder;};
544 target_cell.set_source(text);
544 target_cell.set_source(text);
545 source_element.remove();
545 source_element.remove();
546 target_cell.edit();
546 target_cell.edit();
547 }
547 }
548 this.dirty = true;
548 this.dirty = true;
549 };
549 };
550
550
551
551
552 Notebook.prototype.to_html = function (index) {
552 Notebook.prototype.to_html = function (index) {
553 // TODO: Bounds check for i
553 // TODO: Bounds check for i
554 var i = this.index_or_selected(index);
554 var i = this.index_or_selected(index);
555 var source_element = this.cell_elements().eq(i);
555 var source_element = this.cell_elements().eq(i);
556 var source_cell = source_element.data("cell");
556 var source_cell = source_element.data("cell");
557 var target_cell = null;
557 var target_cell = null;
558 if (source_cell instanceof IPython.CodeCell) {
558 if (source_cell instanceof IPython.CodeCell) {
559 this.insert_html_cell_below(i);
559 this.insert_html_cell_below(i);
560 var target_cell = this.cells()[i+1];
560 var target_cell = this.cells()[i+1];
561 var text = source_cell.get_code();
561 var text = source_cell.get_code();
562 } else if (source_cell instanceof IPython.MarkdownCell) {
562 } else if (source_cell instanceof IPython.MarkdownCell) {
563 this.insert_html_cell_below(i);
563 this.insert_html_cell_below(i);
564 var target_cell = this.cells()[i+1];
564 var target_cell = this.cells()[i+1];
565 var text = source_cell.get_source();
565 var text = source_cell.get_source();
566 if (text === source_cell.placeholder) {
566 if (text === source_cell.placeholder) {
567 text = target_cell.placeholder;
567 text = target_cell.placeholder;
568 }
568 }
569 }
569 }
570 if (target_cell !== null) {
570 if (target_cell !== null) {
571 if (text === "") {text = target_cell.placeholder;};
571 if (text === "") {text = target_cell.placeholder;};
572 target_cell.set_source(text);
572 target_cell.set_source(text);
573 source_element.remove();
573 source_element.remove();
574 target_cell.edit();
574 target_cell.edit();
575 }
575 }
576 this.dirty = true;
576 this.dirty = true;
577 };
577 };
578
578
579
579
580 // Cell collapsing and output clearing
580 // Cell collapsing and output clearing
581
581
582 Notebook.prototype.collapse = function (index) {
582 Notebook.prototype.collapse = function (index) {
583 var i = this.index_or_selected(index);
583 var i = this.index_or_selected(index);
584 this.cells()[i].collapse();
584 this.cells()[i].collapse();
585 this.dirty = true;
585 this.dirty = true;
586 };
586 };
587
587
588
588
589 Notebook.prototype.expand = function (index) {
589 Notebook.prototype.expand = function (index) {
590 var i = this.index_or_selected(index);
590 var i = this.index_or_selected(index);
591 this.cells()[i].expand();
591 this.cells()[i].expand();
592 this.dirty = true;
592 this.dirty = true;
593 };
593 };
594
594
595
595
596 Notebook.prototype.toggle_output = function (index) {
596 Notebook.prototype.toggle_output = function (index) {
597 var i = this.index_or_selected(index);
597 var i = this.index_or_selected(index);
598 this.cells()[i].toggle_output();
598 this.cells()[i].toggle_output();
599 this.dirty = true;
599 this.dirty = true;
600 };
600 };
601
601
602
602
603 Notebook.prototype.set_autoindent = function (state) {
603 Notebook.prototype.set_autoindent = function (state) {
604 var cells = this.cells();
604 var cells = this.cells();
605 len = cells.length;
605 len = cells.length;
606 for (var i=0; i<len; i++) {
606 for (var i=0; i<len; i++) {
607 cells[i].set_autoindent(state)
607 cells[i].set_autoindent(state)
608 };
608 };
609 };
609 };
610
610
611
611
612 Notebook.prototype.clear_all_output = function () {
612 Notebook.prototype.clear_all_output = function () {
613 var ncells = this.ncells();
613 var ncells = this.ncells();
614 var cells = this.cells();
614 var cells = this.cells();
615 for (var i=0; i<ncells; i++) {
615 for (var i=0; i<ncells; i++) {
616 if (cells[i] instanceof IPython.CodeCell) {
616 if (cells[i] instanceof IPython.CodeCell) {
617 cells[i].clear_output();
617 cells[i].clear_output();
618 }
618 }
619 };
619 };
620 this.dirty = true;
620 this.dirty = true;
621 };
621 };
622
622
623 // Other cell functions: line numbers, ...
623 // Other cell functions: line numbers, ...
624
624
625 Notebook.prototype.cell_toggle_line_numbers = function() {
625 Notebook.prototype.cell_toggle_line_numbers = function() {
626 this.selected_cell().toggle_line_numbers()
626 this.selected_cell().toggle_line_numbers()
627 };
627 };
628
628
629 // Kernel related things
629 // Kernel related things
630
630
631 Notebook.prototype.start_kernel = function () {
631 Notebook.prototype.start_kernel = function () {
632 this.kernel = new IPython.Kernel();
632 this.kernel = new IPython.Kernel();
633 var notebook_id = IPython.save_widget.get_notebook_id();
633 var notebook_id = IPython.save_widget.get_notebook_id();
634 this.kernel.start(notebook_id, $.proxy(this.kernel_started, this));
634 this.kernel.start(notebook_id, $.proxy(this.kernel_started, this));
635 };
635 };
636
636
637
637
638 Notebook.prototype.restart_kernel = function () {
638 Notebook.prototype.restart_kernel = function () {
639 var that = this;
639 var that = this;
640 var notebook_id = IPython.save_widget.get_notebook_id();
640 var notebook_id = IPython.save_widget.get_notebook_id();
641
641
642 var dialog = $('<div/>');
642 var dialog = $('<div/>');
643 dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.');
643 dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.');
644 $(document).append(dialog);
644 $(document).append(dialog);
645 dialog.dialog({
645 dialog.dialog({
646 resizable: false,
646 resizable: false,
647 modal: true,
647 modal: true,
648 title: "Restart kernel or continue running?",
648 title: "Restart kernel or continue running?",
649 buttons : {
649 buttons : {
650 "Restart": function () {
650 "Restart": function () {
651 that.kernel.restart($.proxy(that.kernel_started, that));
651 that.kernel.restart($.proxy(that.kernel_started, that));
652 $(this).dialog('close');
652 $(this).dialog('close');
653 },
653 },
654 "Continue running": function () {
654 "Continue running": function () {
655 $(this).dialog('close');
655 $(this).dialog('close');
656 }
656 }
657 }
657 }
658 });
658 });
659 };
659 };
660
660
661
661
662 Notebook.prototype.kernel_started = function () {
662 Notebook.prototype.kernel_started = function () {
663 console.log("Kernel started: ", this.kernel.kernel_id);
663 console.log("Kernel started: ", this.kernel.kernel_id);
664 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
664 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
665 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
665 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
666 };
666 };
667
667
668
668
669 Notebook.prototype.handle_shell_reply = function (e) {
669 Notebook.prototype.handle_shell_reply = function (e) {
670 reply = $.parseJSON(e.data);
670 reply = $.parseJSON(e.data);
671 var header = reply.header;
671 var header = reply.header;
672 var content = reply.content;
672 var content = reply.content;
673 var msg_type = header.msg_type;
673 var msg_type = header.msg_type;
674 // console.log(reply);
674 // console.log(reply);
675 var cell = this.cell_for_msg(reply.parent_header.msg_id);
675 var cell = this.cell_for_msg(reply.parent_header.msg_id);
676 if (msg_type === "execute_reply") {
676 if (msg_type === "execute_reply") {
677 cell.set_input_prompt(content.execution_count);
677 cell.set_input_prompt(content.execution_count);
678 this.dirty = true;
678 this.dirty = true;
679 } else if (msg_type === "complete_reply") {
679 } else if (msg_type === "complete_reply") {
680 cell.finish_completing(content.matched_text, content.matches);
680 cell.finish_completing(content.matched_text, content.matches);
681 };
681 };
682 var payload = content.payload || [];
682 var payload = content.payload || [];
683 this.handle_payload(cell, payload);
683 this.handle_payload(cell, payload);
684 };
684 };
685
685
686
686
687 Notebook.prototype.handle_payload = function (cell, payload) {
687 Notebook.prototype.handle_payload = function (cell, payload) {
688 var l = payload.length;
688 var l = payload.length;
689 for (var i=0; i<l; i++) {
689 for (var i=0; i<l; i++) {
690 if (payload[i].source === 'IPython.zmq.page.page') {
690 if (payload[i].source === 'IPython.zmq.page.page') {
691 if (payload[i].text.trim() !== '') {
691 if (payload[i].text.trim() !== '') {
692 IPython.pager.clear();
692 IPython.pager.clear();
693 IPython.pager.expand();
693 IPython.pager.expand();
694 IPython.pager.append_text(payload[i].text);
694 IPython.pager.append_text(payload[i].text);
695 }
695 }
696 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
696 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
697 var index = this.find_cell_index(cell);
697 var index = this.find_cell_index(cell);
698 var new_cell = this.insert_code_cell_below(index);
698 var new_cell = this.insert_code_cell_below(index);
699 new_cell.set_code(payload[i].text);
699 new_cell.set_code(payload[i].text);
700 this.dirty = true;
700 this.dirty = true;
701 }
701 }
702 };
702 };
703 };
703 };
704
704
705
705
706 Notebook.prototype.handle_iopub_reply = function (e) {
706 Notebook.prototype.handle_iopub_reply = function (e) {
707 reply = $.parseJSON(e.data);
707 reply = $.parseJSON(e.data);
708 var content = reply.content;
708 var content = reply.content;
709 // console.log(reply);
709 // console.log(reply);
710 var msg_type = reply.header.msg_type;
710 var msg_type = reply.header.msg_type;
711 var cell = this.cell_for_msg(reply.parent_header.msg_id);
711 var cell = this.cell_for_msg(reply.parent_header.msg_id);
712 var output_types = ['stream','display_data','pyout','pyerr'];
712 var output_types = ['stream','display_data','pyout','pyerr'];
713 if (output_types.indexOf(msg_type) >= 0) {
713 if (output_types.indexOf(msg_type) >= 0) {
714 this.handle_output(cell, msg_type, content);
714 this.handle_output(cell, msg_type, content);
715 } else if (msg_type === 'status') {
715 } else if (msg_type === 'status') {
716 if (content.execution_state === 'busy') {
716 if (content.execution_state === 'busy') {
717 IPython.kernel_status_widget.status_busy();
717 IPython.kernel_status_widget.status_busy();
718 } else if (content.execution_state === 'idle') {
718 } else if (content.execution_state === 'idle') {
719 IPython.kernel_status_widget.status_idle();
719 IPython.kernel_status_widget.status_idle();
720 } else if (content.execution_state === 'dead') {
720 } else if (content.execution_state === 'dead') {
721 this.handle_status_dead();
721 this.handle_status_dead();
722 };
722 };
723 }
723 }
724 };
724 };
725
725
726
726
727 Notebook.prototype.handle_status_dead = function () {
727 Notebook.prototype.handle_status_dead = function () {
728 var that = this;
728 var that = this;
729 this.kernel.stop_channels();
729 this.kernel.stop_channels();
730 var dialog = $('<div/>');
730 var dialog = $('<div/>');
731 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.');
731 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.');
732 $(document).append(dialog);
732 $(document).append(dialog);
733 dialog.dialog({
733 dialog.dialog({
734 resizable: false,
734 resizable: false,
735 modal: true,
735 modal: true,
736 title: "Dead kernel",
736 title: "Dead kernel",
737 buttons : {
737 buttons : {
738 "Restart": function () {
738 "Restart": function () {
739 that.start_kernel();
739 that.start_kernel();
740 $(this).dialog('close');
740 $(this).dialog('close');
741 },
741 },
742 "Continue running": function () {
742 "Continue running": function () {
743 $(this).dialog('close');
743 $(this).dialog('close');
744 }
744 }
745 }
745 }
746 });
746 });
747 };
747 };
748
748
749
749
750 Notebook.prototype.handle_output = function (cell, msg_type, content) {
750 Notebook.prototype.handle_output = function (cell, msg_type, content) {
751 var json = {};
751 var json = {};
752 json.output_type = msg_type;
752 json.output_type = msg_type;
753 if (msg_type === "stream") {
753 if (msg_type === "stream") {
754 json.text = utils.fixConsole(content.data);
754 json.text = utils.fixConsole(content.data);
755 json.stream = content.name;
755 json.stream = content.name;
756 } else if (msg_type === "display_data") {
756 } else if (msg_type === "display_data") {
757 json = this.convert_mime_types(json, content.data);
757 json = this.convert_mime_types(json, content.data);
758 } else if (msg_type === "pyout") {
758 } else if (msg_type === "pyout") {
759 json.prompt_number = content.execution_count;
759 json.prompt_number = content.execution_count;
760 json = this.convert_mime_types(json, content.data);
760 json = this.convert_mime_types(json, content.data);
761 } else if (msg_type === "pyerr") {
761 } else if (msg_type === "pyerr") {
762 json.ename = content.ename;
762 json.ename = content.ename;
763 json.evalue = content.evalue;
763 json.evalue = content.evalue;
764 var traceback = [];
764 var traceback = [];
765 for (var i=0; i<content.traceback.length; i++) {
765 for (var i=0; i<content.traceback.length; i++) {
766 traceback.push(utils.fixConsole(content.traceback[i]));
766 traceback.push(utils.fixConsole(content.traceback[i]));
767 }
767 }
768 json.traceback = traceback;
768 json.traceback = traceback;
769 };
769 };
770 cell.append_output(json);
770 cell.append_output(json);
771 this.dirty = true;
771 this.dirty = true;
772 };
772 };
773
773
774
774
775 Notebook.prototype.convert_mime_types = function (json, data) {
775 Notebook.prototype.convert_mime_types = function (json, data) {
776 if (data['text/plain'] !== undefined) {
776 if (data['text/plain'] !== undefined) {
777 json.text = utils.fixConsole(data['text/plain']);
777 json.text = utils.fixConsole(data['text/plain']);
778 };
778 };
779 if (data['text/html'] !== undefined) {
779 if (data['text/html'] !== undefined) {
780 json.html = data['text/html'];
780 json.html = data['text/html'];
781 };
781 };
782 if (data['image/svg+xml'] !== undefined) {
782 if (data['image/svg+xml'] !== undefined) {
783 json.svg = data['image/svg+xml'];
783 json.svg = data['image/svg+xml'];
784 };
784 };
785 if (data['image/png'] !== undefined) {
785 if (data['image/png'] !== undefined) {
786 json.png = data['image/png'];
786 json.png = data['image/png'];
787 };
787 };
788 if (data['image/jpeg'] !== undefined) {
788 if (data['image/jpeg'] !== undefined) {
789 json.jpeg = data['image/jpeg'];
789 json.jpeg = data['image/jpeg'];
790 };
790 };
791 if (data['text/latex'] !== undefined) {
791 if (data['text/latex'] !== undefined) {
792 json.latex = data['text/latex'];
792 json.latex = data['text/latex'];
793 };
793 };
794 if (data['application/json'] !== undefined) {
794 if (data['application/json'] !== undefined) {
795 json.json = data['application/json'];
795 json.json = data['application/json'];
796 };
796 };
797 if (data['application/javascript'] !== undefined) {
797 if (data['application/javascript'] !== undefined) {
798 json.javascript = data['application/javascript'];
798 json.javascript = data['application/javascript'];
799 }
799 }
800 return json;
800 return json;
801 };
801 };
802
802
803
803
804 Notebook.prototype.execute_selected_cell = function (options) {
804 Notebook.prototype.execute_selected_cell = function (options) {
805 // add_new: should a new cell be added if we are at the end of the nb
805 // add_new: should a new cell be added if we are at the end of the nb
806 // terminal: execute in terminal mode, which stays in the current cell
806 // terminal: execute in terminal mode, which stays in the current cell
807 default_options = {terminal: false, add_new: true}
807 default_options = {terminal: false, add_new: true}
808 $.extend(default_options, options)
808 $.extend(default_options, options)
809 var that = this;
809 var that = this;
810 var cell = that.selected_cell();
810 var cell = that.selected_cell();
811 var cell_index = that.find_cell_index(cell);
811 var cell_index = that.find_cell_index(cell);
812 if (cell instanceof IPython.CodeCell) {
812 if (cell instanceof IPython.CodeCell) {
813 cell.clear_output();
813 cell.clear_output();
814 var code = cell.get_code();
814 var code = cell.get_code();
815 var msg_id = that.kernel.execute(cell.get_code());
815 var msg_id = that.kernel.execute(cell.get_code());
816 that.msg_cell_map[msg_id] = cell.cell_id;
816 that.msg_cell_map[msg_id] = cell.cell_id;
817 } else if (cell instanceof IPython.HTMLCell) {
817 } else if (cell instanceof IPython.HTMLCell) {
818 cell.render();
818 cell.render();
819 }
819 }
820 if (default_options.terminal) {
820 if (default_options.terminal) {
821 cell.select_all();
821 cell.select_all();
822 } else {
822 } else {
823 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
823 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
824 that.insert_code_cell_below();
824 that.insert_code_cell_below();
825 // If we are adding a new cell at the end, scroll down to show it.
825 // If we are adding a new cell at the end, scroll down to show it.
826 that.scroll_to_bottom();
826 that.scroll_to_bottom();
827 } else {
827 } else {
828 that.select(cell_index+1);
828 that.select(cell_index+1);
829 };
829 };
830 };
830 };
831 this.dirty = true;
831 this.dirty = true;
832 };
832 };
833
833
834
834
835 Notebook.prototype.execute_all_cells = function () {
835 Notebook.prototype.execute_all_cells = function () {
836 var ncells = this.ncells();
836 var ncells = this.ncells();
837 for (var i=0; i<ncells; i++) {
837 for (var i=0; i<ncells; i++) {
838 this.select(i);
838 this.select(i);
839 this.execute_selected_cell({add_new:false});
839 this.execute_selected_cell({add_new:false});
840 };
840 };
841 this.scroll_to_bottom();
841 this.scroll_to_bottom();
842 };
842 };
843
843
844
844
845 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
845 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
846 var msg_id = this.kernel.complete(line, cursor_pos);
846 var msg_id = this.kernel.complete(line, cursor_pos);
847 this.msg_cell_map[msg_id] = cell.cell_id;
847 this.msg_cell_map[msg_id] = cell.cell_id;
848 };
848 };
849
849
850 // Persistance and loading
850 // Persistance and loading
851
851
852
852
853 Notebook.prototype.fromJSON = function (data) {
853 Notebook.prototype.fromJSON = function (data) {
854 var ncells = this.ncells();
854 var ncells = this.ncells();
855 for (var i=0; i<ncells; i++) {
855 for (var i=0; i<ncells; i++) {
856 // Always delete cell 0 as they get renumbered as they are deleted.
856 // Always delete cell 0 as they get renumbered as they are deleted.
857 this.delete_cell(0);
857 this.delete_cell(0);
858 };
858 };
859 // Save the metadata
859 // Save the metadata
860 this.metadata = data.metadata;
860 this.metadata = data.metadata;
861 // Only handle 1 worksheet for now.
861 // Only handle 1 worksheet for now.
862 var worksheet = data.worksheets[0];
862 var worksheet = data.worksheets[0];
863 if (worksheet !== undefined) {
863 if (worksheet !== undefined) {
864 var new_cells = worksheet.cells;
864 var new_cells = worksheet.cells;
865 ncells = new_cells.length;
865 ncells = new_cells.length;
866 var cell_data = null;
866 var cell_data = null;
867 var new_cell = null;
867 var new_cell = null;
868 for (var i=0; i<ncells; i++) {
868 for (var i=0; i<ncells; i++) {
869 cell_data = new_cells[i];
869 cell_data = new_cells[i];
870 if (cell_data.cell_type == 'code') {
870 if (cell_data.cell_type == 'code') {
871 new_cell = this.insert_code_cell_below();
871 new_cell = this.insert_code_cell_below();
872 new_cell.fromJSON(cell_data);
872 new_cell.fromJSON(cell_data);
873 } else if (cell_data.cell_type === 'html') {
873 } else if (cell_data.cell_type === 'html') {
874 new_cell = this.insert_html_cell_below();
874 new_cell = this.insert_html_cell_below();
875 new_cell.fromJSON(cell_data);
875 new_cell.fromJSON(cell_data);
876 } else if (cell_data.cell_type === 'markdown') {
876 } else if (cell_data.cell_type === 'markdown') {
877 new_cell = this.insert_markdown_cell_below();
877 new_cell = this.insert_markdown_cell_below();
878 new_cell.fromJSON(cell_data);
878 new_cell.fromJSON(cell_data);
879 };
879 };
880 };
880 };
881 };
881 };
882 };
882 };
883
883
884
884
885 Notebook.prototype.toJSON = function () {
885 Notebook.prototype.toJSON = function () {
886 var cells = this.cells();
886 var cells = this.cells();
887 var ncells = cells.length;
887 var ncells = cells.length;
888 cell_array = new Array(ncells);
888 cell_array = new Array(ncells);
889 for (var i=0; i<ncells; i++) {
889 for (var i=0; i<ncells; i++) {
890 cell_array[i] = cells[i].toJSON();
890 cell_array[i] = cells[i].toJSON();
891 };
891 };
892 data = {
892 data = {
893 // Only handle 1 worksheet for now.
893 // Only handle 1 worksheet for now.
894 worksheets : [{cells:cell_array}],
894 worksheets : [{cells:cell_array}],
895 metadata : this.metadata
895 metadata : this.metadata
896 }
896 }
897 return data
897 return data
898 };
898 };
899
899
900 Notebook.prototype.save_notebook = function () {
900 Notebook.prototype.save_notebook = function () {
901 if (IPython.save_widget.test_notebook_name()) {
901 if (IPython.save_widget.test_notebook_name()) {
902 var notebook_id = IPython.save_widget.get_notebook_id();
902 var notebook_id = IPython.save_widget.get_notebook_id();
903 var nbname = IPython.save_widget.get_notebook_name();
903 var nbname = IPython.save_widget.get_notebook_name();
904 // We may want to move the name/id/nbformat logic inside toJSON?
904 // We may want to move the name/id/nbformat logic inside toJSON?
905 var data = this.toJSON();
905 var data = this.toJSON();
906 data.metadata.name = nbname;
906 data.metadata.name = nbname;
907 data.nbformat = 2;
907 data.nbformat = 2;
908 // We do the call with settings so we can set cache to false.
908 // We do the call with settings so we can set cache to false.
909 var settings = {
909 var settings = {
910 processData : false,
910 processData : false,
911 cache : false,
911 cache : false,
912 type : "PUT",
912 type : "PUT",
913 data : JSON.stringify(data),
913 data : JSON.stringify(data),
914 headers : {'Content-Type': 'application/json'},
914 headers : {'Content-Type': 'application/json'},
915 success : $.proxy(this.notebook_saved,this)
915 success : $.proxy(this.notebook_saved,this)
916 };
916 };
917 IPython.save_widget.status_saving();
917 IPython.save_widget.status_saving();
918 $.ajax("/notebooks/" + notebook_id, settings);
918 $.ajax("/notebooks/" + notebook_id, settings);
919 };
919 };
920 };
920 };
921
921
922
922
923 Notebook.prototype.notebook_saved = function (data, status, xhr) {
923 Notebook.prototype.notebook_saved = function (data, status, xhr) {
924 this.dirty = false;
924 this.dirty = false;
925 setTimeout($.proxy(IPython.save_widget.status_save,IPython.save_widget),500);
925 setTimeout($.proxy(IPython.save_widget.status_save,IPython.save_widget),500);
926 }
926 }
927
927
928
928
929 Notebook.prototype.load_notebook = function (callback) {
929 Notebook.prototype.load_notebook = function (callback) {
930 var that = this;
930 var that = this;
931 var notebook_id = IPython.save_widget.get_notebook_id();
931 var notebook_id = IPython.save_widget.get_notebook_id();
932 // We do the call with settings so we can set cache to false.
932 // We do the call with settings so we can set cache to false.
933 var settings = {
933 var settings = {
934 processData : false,
934 processData : false,
935 cache : false,
935 cache : false,
936 type : "GET",
936 type : "GET",
937 dataType : "json",
937 dataType : "json",
938 success : function (data, status, xhr) {
938 success : function (data, status, xhr) {
939 that.notebook_loaded(data, status, xhr);
939 that.notebook_loaded(data, status, xhr);
940 if (callback !== undefined) {
940 if (callback !== undefined) {
941 callback();
941 callback();
942 };
942 };
943 }
943 }
944 };
944 };
945 IPython.save_widget.status_loading();
945 IPython.save_widget.status_loading();
946 $.ajax("/notebooks/" + notebook_id, settings);
946 $.ajax("/notebooks/" + notebook_id, settings);
947 }
947 }
948
948
949
949
950 Notebook.prototype.notebook_loaded = function (data, status, xhr) {
950 Notebook.prototype.notebook_loaded = function (data, status, xhr) {
951 this.fromJSON(data);
951 this.fromJSON(data);
952 if (this.ncells() === 0) {
952 if (this.ncells() === 0) {
953 this.insert_code_cell_below();
953 this.insert_code_cell_below();
954 };
954 };
955 IPython.save_widget.status_save();
955 IPython.save_widget.status_save();
956 IPython.save_widget.set_notebook_name(data.metadata.name);
956 IPython.save_widget.set_notebook_name(data.metadata.name);
957 this.start_kernel();
957 this.start_kernel();
958 this.dirty = false;
958 this.dirty = false;
959 // fromJSON always selects the last cell inserted. We need to wait
959 // fromJSON always selects the last cell inserted. We need to wait
960 // until that is done before scrolling to the top.
960 // until that is done before scrolling to the top.
961 setTimeout(function () {
961 setTimeout(function () {
962 IPython.notebook.select(0);
962 IPython.notebook.select(0);
963 IPython.notebook.scroll_to_top();
963 IPython.notebook.scroll_to_top();
964 }, 50);
964 }, 50);
965 };
965 };
966
966
967 IPython.Notebook = Notebook;
967 IPython.Notebook = Notebook;
968
968
969 return IPython;
969 return IPython;
970
970
971 }(IPython));
971 }(IPython));
972
972
@@ -1,282 +1,280 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 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
9 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
10 <!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
10 <!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
12
12
13 <!-- <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script> -->
13 <!-- <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script> -->
14 <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script>
14 <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script>
15 <script type="text/javascript">
15 <script type="text/javascript">
16 function CheckMathJax(){
16 function CheckMathJax(){
17 var div=document.getElementById("MathJaxFetchingWarning")
17 var div=document.getElementById("MathJaxFetchingWarning")
18 if(window.MathJax){
18 if(window.MathJax){
19 document.body.removeChild(div)
19 document.body.removeChild(div)
20 }
20 }
21 else{
21 else{
22 div.style.display = "block";
22 div.style.display = "block";
23 }
23 }
24 }
24 }
25 if (typeof MathJax == 'undefined') {
25 if (typeof MathJax == 'undefined') {
26 console.log("No local MathJax, loading from CDN");
26 console.log("No local MathJax, loading from CDN");
27 document.write(unescape("%3Cscript type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js%3Fconfig=TeX-AMS_HTML' charset='utf-8'%3E%3C/script%3E"));
27 document.write(unescape("%3Cscript type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js%3Fconfig=TeX-AMS_HTML' charset='utf-8'%3E%3C/script%3E"));
28 }else{
28 }else{
29 console.log("Using local MathJax");
29 console.log("Using local MathJax");
30 }
30 }
31 </script>
31 </script>
32
32
33 <link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
33 <link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
34 <link rel="stylesheet" href="static/codemirror/mode/markdown/markdown.css">
34 <link rel="stylesheet" href="static/codemirror/mode/markdown/markdown.css">
35 <link rel="stylesheet" href="static/codemirror/mode/rst/rst.css">
35 <link rel="stylesheet" href="static/codemirror/mode/rst/rst.css">
36 <link rel="stylesheet" href="static/codemirror/theme/ipython.css">
36 <link rel="stylesheet" href="static/codemirror/theme/ipython.css">
37 <link rel="stylesheet" href="static/codemirror/theme/default.css">
37 <link rel="stylesheet" href="static/codemirror/theme/default.css">
38
38
39 <link rel="stylesheet" href="static/prettify/prettify.css"/>
39 <link rel="stylesheet" href="static/prettify/prettify.css"/>
40
40
41 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
41 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
42 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
42 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
43 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
43 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
44 <link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
44 <link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
45 <link rel="stylesheet" href="static/css/renderedhtml.css" type="text/css" />
45 <link rel="stylesheet" href="static/css/renderedhtml.css" type="text/css" />
46
46
47
47
48 </head>
48 </head>
49
49
50 <body onload='CheckMathJax();'>
50 <body onload='CheckMathJax();'>
51
51
52 <div id="header">
52 <div id="header">
53 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
53 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
54 <span id="save_widget">
54 <span id="save_widget">
55 <input type="text" id="notebook_name" size="20"></textarea>
55 <input type="text" id="notebook_name" size="20"></textarea>
56 <span id="notebook_id" style="display:none">{{notebook_id}}</span>
56 <span id="notebook_id" style="display:none">{{notebook_id}}</span>
57 <button id="save_notebook"><u>S</u>ave</button>
57 <button id="save_notebook"><u>S</u>ave</button>
58 </span>
58 </span>
59 <span id="quick_help_area">
59 <span id="quick_help_area">
60 <button id="quick_help">QuickHelp</button>
60 <button id="quick_help">QuickHelp</button>
61 </span>
61 </span>
62 <span id="kernel_status">Idle</span>
62 <span id="kernel_status">Idle</span>
63 </div>
63 </div>
64
64
65 <div id="MathJaxFetchingWarning"
65 <div id="MathJaxFetchingWarning"
66 style="width:80%; margin:auto;padding-top:20%;text-align: justify; display:none">
66 style="width:80%; margin:auto;padding-top:20%;text-align: justify; display:none">
67 <p style="font-size:26px;">There was an issue trying to fetch MathJax.js
67 <p style="font-size:26px;">There was an issue trying to fetch MathJax.js
68 from the internet.</p>
68 from the internet.</p>
69
69
70 <p style="padding:0.2em"> With a working internet connection, you can run
70 <p style="padding:0.2em"> With a working internet connection, you can run
71 the following at a Python or IPython prompt, which will install a local
71 the following at a Python or IPython prompt, which will install a local
72 copy of MathJax:</p>
72 copy of MathJax:</p>
73
73
74 <pre style="background-color:lightblue;border:thin silver solid;padding:0.4em">
74 <pre style="background-color:lightblue;border:thin silver solid;padding:0.4em">
75 from IPython.external import mathjax; mathjax.install_mathjax()
75 from IPython.external import mathjax; mathjax.install_mathjax()
76 </pre>
76 </pre>
77 This will try to install MathJax into the directory where you installed
77 This will try to install MathJax into the directory where you installed
78 IPython. If you installed IPython to a location that requires
78 IPython. If you installed IPython to a location that requires
79 administrative privileges to write, you will need to make this call as
79 administrative privileges to write, you will need to make this call as
80 an administrator. On OSX/Linux/Unix, this can be done at the
80 an administrator. On OSX/Linux/Unix, this can be done at the
81 command-line via:
81 command-line via:
82 <pre style="background-color:lightblue;border:thin silver solid;padding:0.4em">
82 <pre style="background-color:lightblue;border:thin silver solid;padding:0.4em">
83 sudo python -c "from IPython.external import mathjax; mathjax.install_mathjax()"
83 sudo python -c "from IPython.external import mathjax; mathjax.install_mathjax()"
84 </pre>
84 </pre>
85 </p>
85 </p>
86 </div>
86 </div>
87
87
88 <div id="main_app">
88 <div id="main_app">
89
89
90 <div id="left_panel">
90 <div id="left_panel">
91
91
92 <div id="notebook_section">
92 <div id="notebook_section">
93 <h3 class="section_header">Notebook</h3>
93 <h3 class="section_header">Notebook</h3>
94 <div class="section_content">
94 <div class="section_content">
95 <div class="section_row">
95 <div class="section_row">
96 <span id="new_open" class="section_row_buttons">
96 <span id="new_open" class="section_row_buttons">
97 <button id="new_notebook">New</button>
97 <button id="new_notebook">New</button>
98 <button id="open_notebook">Open</button>
98 <button id="open_notebook">Open</button>
99 </span>
99 </span>
100 <span class="section_row_header">Actions</span>
100 <span class="section_row_header">Actions</span>
101 </div>
101 </div>
102 <div class="section_row">
102 <div class="section_row">
103 <span>
103 <span>
104 <select id="download_format">
104 <select id="download_format">
105 <option value="json">ipynb</option>
105 <option value="json">ipynb</option>
106 <option value="py">py</option>
106 <option value="py">py</option>
107 </select>
107 </select>
108 </span>
108 </span>
109 <span class="section_row_buttons">
109 <span class="section_row_buttons">
110 <button id="download_notebook">Download</button>
110 <button id="download_notebook">Download</button>
111 </span>
111 </span>
112 </div>
112 </div>
113 <div class="section_row">
113 <div class="section_row">
114 <span class="section_row_buttons">
114 <span class="section_row_buttons">
115 <span id="print_widget">
115 <span id="print_widget">
116 <button id="print_notebook">Print</button>
116 <button id="print_notebook">Print</button>
117 </span>
117 </span>
118 </span>
118 </span>
119 </div>
119 </div>
120 </div>
120 </div>
121 </div>
121 </div>
122
122
123 <div id="cell_section">
123 <div id="cell_section">
124 <h3 class="section_header">Cell</h3>
124 <h3 class="section_header">Cell</h3>
125 <div class="section_content">
125 <div class="section_content">
126 <div class="section_row">
126 <div class="section_row">
127 <span class="section_row_buttons">
127 <span class="section_row_buttons">
128 <button id="delete_cell"><u>D</u>elete</button>
128 <button id="delete_cell"><u>D</u>elete</button>
129 </span>
129 </span>
130 <span class="section_row_header">Actions</span>
130 <span class="section_row_header">Actions</span>
131 </div>
131 </div>
132 <div class="section_row">
132 <div class="section_row">
133 <span id="cell_type" class="section_row_buttons">
133 <span id="cell_type" class="section_row_buttons">
134 <button id="to_code"><u>C</u>ode</button>
134 <button id="to_code"><u>C</u>ode</button>
135 <!-- <button id="to_html">HTML</button>-->
135 <!-- <button id="to_html">HTML</button>-->
136 <button id="to_markdown"><u>M</u>arkdown</button>
136 <button id="to_markdown"><u>M</u>arkdown</button>
137 </span>
137 </span>
138 <span class="button_label">Format</span>
138 <span class="button_label">Format</span>
139 </div>
139 </div>
140 <div class="section_row">
140 <div class="section_row">
141 <span id="cell_output" class="section_row_buttons">
141 <span id="cell_output" class="section_row_buttons">
142 <button id="toggle_output"><u>T</u>oggle</button>
142 <button id="toggle_output"><u>T</u>oggle</button>
143 <button id="clear_all_output">ClearAll</button>
143 <button id="clear_all_output">ClearAll</button>
144 </span>
144 </span>
145 <span class="button_label">Output</span>
145 <span class="button_label">Output</span>
146 </div>
146 </div>
147 <div class="section_row">
147 <div class="section_row">
148 <span id="insert" class="section_row_buttons">
148 <span id="insert" class="section_row_buttons">
149 <button id="insert_cell_above"><u>A</u>bove</button>
149 <button id="insert_cell_above"><u>A</u>bove</button>
150 <button id="insert_cell_below"><u>B</u>elow</button>
150 <button id="insert_cell_below"><u>B</u>elow</button>
151 </span>
151 </span>
152 <span class="button_label">Insert</span>
152 <span class="button_label">Insert</span>
153 </div>
153 </div>
154 <div class="section_row">
154 <div class="section_row">
155 <span id="move" class="section_row_buttons">
155 <span id="move" class="section_row_buttons">
156 <button id="move_cell_up">Up</button>
156 <button id="move_cell_up">Up</button>
157 <button id="move_cell_down">Down</button>
157 <button id="move_cell_down">Down</button>
158 </span>
158 </span>
159 <span class="button_label">Move</span>
159 <span class="button_label">Move</span>
160 </div>
160 </div>
161 <div class="section_row">
161 <div class="section_row">
162 <span id="run_cells" class="section_row_buttons">
162 <span id="run_cells" class="section_row_buttons">
163 <button id="run_selected_cell">Selected</button>
163 <button id="run_selected_cell">Selected</button>
164 <button id="run_all_cells">All</button>
164 <button id="run_all_cells">All</button>
165 </span>
165 </span>
166 <span class="button_label">Run</span>
166 <span class="button_label">Run</span>
167 </div>
167 </div>
168 <div class="section_row">
168 <div class="section_row">
169 <span id="autoindent_span">
169 <span id="autoindent_span">
170 <input type="checkbox" id="autoindent" checked="true"></input>
170 <input type="checkbox" id="autoindent" checked="true"></input>
171 </span>
171 </span>
172 <span class="checkbox_label">Autoindent:</span>
172 <span class="checkbox_label">Autoindent:</span>
173 </div>
173 </div>
174 </div>
174 </div>
175 </div>
175 </div>
176
176
177 <div id="kernel_section">
177 <div id="kernel_section">
178 <h3 class="section_header">Kernel</h3>
178 <h3 class="section_header">Kernel</h3>
179 <div class="section_content">
179 <div class="section_content">
180 <div class="section_row">
180 <div class="section_row">
181 <span id="int_restart" class="section_row_buttons">
181 <span id="int_restart" class="section_row_buttons">
182 <button id="int_kernel"><u>I</u>nterrupt</button>
182 <button id="int_kernel"><u>I</u>nterrupt</button>
183 <button id="restart_kernel">Restart</button>
183 <button id="restart_kernel">Restart</button>
184 </span>
184 </span>
185 <span class="section_row_header">Actions</span>
185 <span class="section_row_header">Actions</span>
186 </div>
186 </div>
187 <div class="section_row">
187 <div class="section_row">
188 <span id="kernel_persist">
188 <span id="kernel_persist">
189 <input type="checkbox" id="kill_kernel"></input>
189 <input type="checkbox" id="kill_kernel"></input>
190 </span>
190 </span>
191 <span class="checkbox_label">Kill kernel upon exit:</span>
191 <span class="checkbox_label">Kill kernel upon exit:</span>
192 </div>
192 </div>
193 </div>
193 </div>
194 </div>
194 </div>
195
195
196 <div id="help_section">
196 <div id="help_section">
197 <h3 class="section_header">Help</h3>
197 <h3 class="section_header">Help</h3>
198 <div class="section_content">
198 <div class="section_content">
199 <div class="section_row">
199 <div class="section_row">
200 <span id="help_buttons0" class="section_row_buttons">
200 <span id="help_buttons0" class="section_row_buttons">
201 <a id="python_help" href="http://docs.python.org" target="_blank">Python</a>
201 <a id="python_help" href="http://docs.python.org" target="_blank">Python</a>
202 <a id="ipython_help" href="http://ipython.org/documentation.html" target="_blank">IPython</a>
202 <a id="ipython_help" href="http://ipython.org/documentation.html" target="_blank">IPython</a>
203 </span>
203 </span>
204 <span class="section_row_header">Links</span>
204 <span class="section_row_header">Links</span>
205 </div>
205 </div>
206 <div class="section_row">
206 <div class="section_row">
207 <span id="help_buttons1" class="section_row_buttons">
207 <span id="help_buttons1" class="section_row_buttons">
208 <a id="numpy_help" href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a>
208 <a id="numpy_help" href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a>
209 <a id="scipy_help" href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a>
209 <a id="scipy_help" href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a>
210 </span>
210 </span>
211 </div>
211 </div>
212 <div class="section_row">
212 <div class="section_row">
213 <span id="help_buttons2" class="section_row_buttons">
213 <span id="help_buttons2" class="section_row_buttons">
214 <a id="matplotlib_help" href="http://matplotlib.sourceforge.net/" target="_blank">MPL</a>
214 <a id="matplotlib_help" href="http://matplotlib.sourceforge.net/" target="_blank">MPL</a>
215 <a id="sympy_help" href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a>
215 <a id="sympy_help" href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a>
216 </span>
216 </span>
217 </div>
217 </div>
218 <div class="section_row">
218 <div class="section_row">
219 <span class="help_string">run selected cell</span>
219 <span class="help_string">run selected cell</span>
220 <span class="help_string_label">Shift-Enter :</span>
220 <span class="help_string_label">Shift-Enter :</span>
221 </div>
221 </div>
222 <div class="section_row">
222 <div class="section_row">
223 <span class="help_string">run selected cell in-place</span>
223 <span class="help_string">run selected cell in-place</span>
224 <span class="help_string_label">Ctrl-Enter :</span>
224 <span class="help_string_label">Ctrl-Enter :</span>
225 </div>
225 </div>
226 <div class="section_row">
226 <div class="section_row">
227 <span class="help_string">show keyboard shortcuts</span>
227 <span class="help_string">show keyboard shortcuts</span>
228 <span class="help_string_label">Ctrl-m h :</span>
228 <span class="help_string_label">Ctrl-m h :</span>
229 </div>
229 </div>
230 </div>
230 </div>
231 </div>
231 </div>
232
232
233 </div>
233 </div>
234 <div id="left_panel_splitter"></div>
234 <div id="left_panel_splitter"></div>
235 <div id="notebook_panel">
235 <div id="notebook_panel">
236 <div id="notebook"></div>
236 <div id="notebook"></div>
237 <div id="pager_splitter"></div>
237 <div id="pager_splitter"></div>
238 <div id="pager"></div>
238 <div id="pager"></div>
239 </div>
239 </div>
240
240
241 </div>
241 </div>
242
242
243 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
243 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
244 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
244 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
245 <script src="static/jquery/js/jquery.autogrow.js" type="text/javascript" charset="utf-8"></script>
245 <script src="static/jquery/js/jquery.autogrow.js" type="text/javascript" charset="utf-8"></script>
246
246
247 <script src="static/codemirror/lib/codemirror.js" charset="utf-8"></script>
247 <script src="static/codemirror/lib/codemirror.js" charset="utf-8"></script>
248 <script src="static/codemirror/mode/python/python.js" charset="utf-8"></script>
248 <script src="static/codemirror/mode/python/python.js" charset="utf-8"></script>
249 <script src="static/codemirror/mode/htmlmixed/htmlmixed.js" charset="utf-8"></script>
249 <script src="static/codemirror/mode/htmlmixed/htmlmixed.js" charset="utf-8"></script>
250 <script src="static/codemirror/mode/xml/xml.js" charset="utf-8"></script>
250 <script src="static/codemirror/mode/xml/xml.js" charset="utf-8"></script>
251 <script src="static/codemirror/mode/javascript/javascript.js" charset="utf-8"></script>
251 <script src="static/codemirror/mode/javascript/javascript.js" charset="utf-8"></script>
252 <script src="static/codemirror/mode/css/css.js" charset="utf-8"></script>
252 <script src="static/codemirror/mode/css/css.js" charset="utf-8"></script>
253 <script src="static/codemirror/mode/rst/rst.js" charset="utf-8"></script>
253 <script src="static/codemirror/mode/rst/rst.js" charset="utf-8"></script>
254 <script src="static/codemirror/mode/markdown/markdown.js" charset="utf-8"></script>
254 <script src="static/codemirror/mode/markdown/markdown.js" charset="utf-8"></script>
255
255
256 <script src="static/pagedown/Markdown.Converter.js" charset="utf-8"></script>
256 <script src="static/pagedown/Markdown.Converter.js" charset="utf-8"></script>
257
257
258 <script src="static/prettify/prettify.js" charset="utf-8"></script>
258 <script src="static/prettify/prettify.js" charset="utf-8"></script>
259
259
260 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
260 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
261 <script src="static/js/utils.js" type="text/javascript" charset="utf-8"></script>
261 <script src="static/js/utils.js" type="text/javascript" charset="utf-8"></script>
262 <script src="static/js/cell.js" type="text/javascript" charset="utf-8"></script>
262 <script src="static/js/cell.js" type="text/javascript" charset="utf-8"></script>
263 <script src="static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
263 <script src="static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
264 <script src="static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
264 <script src="static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
265 <script src="static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
265 <script src="static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
266 <script src="static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
266 <script src="static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
267 <script src="static/js/layout.js" type="text/javascript" charset="utf-8"></script>
267 <script src="static/js/layout.js" type="text/javascript" charset="utf-8"></script>
268 <script src="static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
268 <script src="static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
269 <script src="static/js/header.js" type="text/javascript" charset="utf-8"></script>
269 <script src="static/js/header.js" type="text/javascript" charset="utf-8"></script>
270 <script src="static/js/pager.js" type="text/javascript" charset="utf-8"></script>
270 <script src="static/js/pager.js" type="text/javascript" charset="utf-8"></script>
271 <script src="static/js/panelsection.js" type="text/javascript" charset="utf-8"></script>
271 <script src="static/js/panelsection.js" type="text/javascript" charset="utf-8"></script>
272 <script src="static/js/printwidget.js" type="text/javascript" charset="utf-8"></script>
272 <script src="static/js/printwidget.js" type="text/javascript" charset="utf-8"></script>
273 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
273 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
274 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
274 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
275 <script src="static/js/notebook_main.js" type="text/javascript" charset="utf-8"></script>
275 <script src="static/js/notebook_main.js" type="text/javascript" charset="utf-8"></script>
276
276
277
277
278 </body>
278 </body>
279
279
280 </html>
280 </html>
281
282
General Comments 0
You need to be logged in to leave comments. Login now