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