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