##// END OF EJS Templates
Merge pull request #4398 from Carreau/no-tooltip-on-tab...
Min RK -
r13484:4134fc9d merge
parent child Browse files
Show More
@@ -0,0 +1,3
1 * In notebook, Showing tooltip on tab has been disables to avoid conflict with
2 completion, Shift-Tab could still be used to invoke tooltip when inside
3 function signature and/or on selection.
@@ -1,466 +1,460
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 * An extendable module that provide base functionnality to create cell for notebook.
12 * An extendable module that provide base functionnality to create cell for notebook.
13 * @module IPython
13 * @module IPython
14 * @namespace IPython
14 * @namespace IPython
15 * @submodule CodeCell
15 * @submodule CodeCell
16 */
16 */
17
17
18
18
19 /* local util for codemirror */
19 /* local util for codemirror */
20 var posEq = function(a, b) {return a.line == b.line && a.ch == b.ch;};
20 var posEq = function(a, b) {return a.line == b.line && a.ch == b.ch;};
21
21
22 /**
22 /**
23 *
23 *
24 * function to delete until previous non blanking space character
24 * function to delete until previous non blanking space character
25 * or first multiple of 4 tabstop.
25 * or first multiple of 4 tabstop.
26 * @private
26 * @private
27 */
27 */
28 CodeMirror.commands.delSpaceToPrevTabStop = function(cm){
28 CodeMirror.commands.delSpaceToPrevTabStop = function(cm){
29 var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
29 var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
30 if (!posEq(from, to)) { cm.replaceRange("", from, to); return; }
30 if (!posEq(from, to)) { cm.replaceRange("", from, to); return; }
31 var cur = cm.getCursor(), line = cm.getLine(cur.line);
31 var cur = cm.getCursor(), line = cm.getLine(cur.line);
32 var tabsize = cm.getOption('tabSize');
32 var tabsize = cm.getOption('tabSize');
33 var chToPrevTabStop = cur.ch-(Math.ceil(cur.ch/tabsize)-1)*tabsize;
33 var chToPrevTabStop = cur.ch-(Math.ceil(cur.ch/tabsize)-1)*tabsize;
34 from = {ch:cur.ch-chToPrevTabStop,line:cur.line};
34 from = {ch:cur.ch-chToPrevTabStop,line:cur.line};
35 var select = cm.getRange(from,cur);
35 var select = cm.getRange(from,cur);
36 if( select.match(/^\ +$/) !== null){
36 if( select.match(/^\ +$/) !== null){
37 cm.replaceRange("",from,cur);
37 cm.replaceRange("",from,cur);
38 } else {
38 } else {
39 cm.deleteH(-1,"char");
39 cm.deleteH(-1,"char");
40 }
40 }
41 };
41 };
42
42
43
43
44 var IPython = (function (IPython) {
44 var IPython = (function (IPython) {
45 "use strict";
45 "use strict";
46
46
47 var utils = IPython.utils;
47 var utils = IPython.utils;
48 var key = IPython.utils.keycodes;
48 var key = IPython.utils.keycodes;
49
49
50 /**
50 /**
51 * A Cell conceived to write code.
51 * A Cell conceived to write code.
52 *
52 *
53 * The kernel doesn't have to be set at creation time, in that case
53 * The kernel doesn't have to be set at creation time, in that case
54 * it will be null and set_kernel has to be called later.
54 * it will be null and set_kernel has to be called later.
55 * @class CodeCell
55 * @class CodeCell
56 * @extends IPython.Cell
56 * @extends IPython.Cell
57 *
57 *
58 * @constructor
58 * @constructor
59 * @param {Object|null} kernel
59 * @param {Object|null} kernel
60 * @param {object|undefined} [options]
60 * @param {object|undefined} [options]
61 * @param [options.cm_config] {object} config to pass to CodeMirror
61 * @param [options.cm_config] {object} config to pass to CodeMirror
62 */
62 */
63 var CodeCell = function (kernel, options) {
63 var CodeCell = function (kernel, options) {
64 this.kernel = kernel || null;
64 this.kernel = kernel || null;
65 this.code_mirror = null;
65 this.code_mirror = null;
66 this.input_prompt_number = null;
66 this.input_prompt_number = null;
67 this.collapsed = false;
67 this.collapsed = false;
68 this.cell_type = "code";
68 this.cell_type = "code";
69
69
70
70
71 var cm_overwrite_options = {
71 var cm_overwrite_options = {
72 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
72 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
73 };
73 };
74
74
75 options = this.mergeopt(CodeCell, options, {cm_config:cm_overwrite_options});
75 options = this.mergeopt(CodeCell, options, {cm_config:cm_overwrite_options});
76
76
77 IPython.Cell.apply(this,[options]);
77 IPython.Cell.apply(this,[options]);
78
78
79 var that = this;
79 var that = this;
80 this.element.focusout(
80 this.element.focusout(
81 function() { that.auto_highlight(); }
81 function() { that.auto_highlight(); }
82 );
82 );
83 };
83 };
84
84
85 CodeCell.options_default = {
85 CodeCell.options_default = {
86 cm_config : {
86 cm_config : {
87 extraKeys: {
87 extraKeys: {
88 "Tab" : "indentMore",
88 "Tab" : "indentMore",
89 "Shift-Tab" : "indentLess",
89 "Shift-Tab" : "indentLess",
90 "Backspace" : "delSpaceToPrevTabStop",
90 "Backspace" : "delSpaceToPrevTabStop",
91 "Cmd-/" : "toggleComment",
91 "Cmd-/" : "toggleComment",
92 "Ctrl-/" : "toggleComment"
92 "Ctrl-/" : "toggleComment"
93 },
93 },
94 mode: 'ipython',
94 mode: 'ipython',
95 theme: 'ipython',
95 theme: 'ipython',
96 matchBrackets: true
96 matchBrackets: true
97 }
97 }
98 };
98 };
99
99
100
100
101 CodeCell.prototype = new IPython.Cell();
101 CodeCell.prototype = new IPython.Cell();
102
102
103 /**
103 /**
104 * @method auto_highlight
104 * @method auto_highlight
105 */
105 */
106 CodeCell.prototype.auto_highlight = function () {
106 CodeCell.prototype.auto_highlight = function () {
107 this._auto_highlight(IPython.config.cell_magic_highlight);
107 this._auto_highlight(IPython.config.cell_magic_highlight);
108 };
108 };
109
109
110 /** @method create_element */
110 /** @method create_element */
111 CodeCell.prototype.create_element = function () {
111 CodeCell.prototype.create_element = function () {
112 IPython.Cell.prototype.create_element.apply(this, arguments);
112 IPython.Cell.prototype.create_element.apply(this, arguments);
113
113
114 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell');
114 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell');
115 cell.attr('tabindex','2');
115 cell.attr('tabindex','2');
116
116
117 this.celltoolbar = new IPython.CellToolbar(this);
117 this.celltoolbar = new IPython.CellToolbar(this);
118
118
119 var input = $('<div></div>').addClass('input');
119 var input = $('<div></div>').addClass('input');
120 var vbox = $('<div/>').addClass('vbox box-flex1');
120 var vbox = $('<div/>').addClass('vbox box-flex1');
121 input.append($('<div/>').addClass('prompt input_prompt'));
121 input.append($('<div/>').addClass('prompt input_prompt'));
122 vbox.append(this.celltoolbar.element);
122 vbox.append(this.celltoolbar.element);
123 var input_area = $('<div/>').addClass('input_area');
123 var input_area = $('<div/>').addClass('input_area');
124 this.code_mirror = CodeMirror(input_area.get(0), this.cm_config);
124 this.code_mirror = CodeMirror(input_area.get(0), this.cm_config);
125 $(this.code_mirror.getInputField()).attr("spellcheck", "false");
125 $(this.code_mirror.getInputField()).attr("spellcheck", "false");
126 vbox.append(input_area);
126 vbox.append(input_area);
127 input.append(vbox);
127 input.append(vbox);
128 var output = $('<div></div>');
128 var output = $('<div></div>');
129 cell.append(input).append(output);
129 cell.append(input).append(output);
130 this.element = cell;
130 this.element = cell;
131 this.output_area = new IPython.OutputArea(output, true);
131 this.output_area = new IPython.OutputArea(output, true);
132
132
133 // construct a completer only if class exist
133 // construct a completer only if class exist
134 // otherwise no print view
134 // otherwise no print view
135 if (IPython.Completer !== undefined)
135 if (IPython.Completer !== undefined)
136 {
136 {
137 this.completer = new IPython.Completer(this);
137 this.completer = new IPython.Completer(this);
138 }
138 }
139 };
139 };
140
140
141 /**
141 /**
142 * This method gets called in CodeMirror's onKeyDown/onKeyPress
142 * This method gets called in CodeMirror's onKeyDown/onKeyPress
143 * handlers and is used to provide custom key handling. Its return
143 * handlers and is used to provide custom key handling. Its return
144 * value is used to determine if CodeMirror should ignore the event:
144 * value is used to determine if CodeMirror should ignore the event:
145 * true = ignore, false = don't ignore.
145 * true = ignore, false = don't ignore.
146 * @method handle_codemirror_keyevent
146 * @method handle_codemirror_keyevent
147 */
147 */
148 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
148 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
149
149
150 var that = this;
150 var that = this;
151 // whatever key is pressed, first, cancel the tooltip request before
151 // whatever key is pressed, first, cancel the tooltip request before
152 // they are sent, and remove tooltip if any, except for tab again
152 // they are sent, and remove tooltip if any, except for tab again
153 if (event.type === 'keydown' && event.which != key.TAB ) {
153 if (event.type === 'keydown' && event.which != key.TAB ) {
154 IPython.tooltip.remove_and_cancel_tooltip();
154 IPython.tooltip.remove_and_cancel_tooltip();
155 }
155 }
156
156
157 var cur = editor.getCursor();
157 var cur = editor.getCursor();
158 if (event.keyCode === key.ENTER){
158 if (event.keyCode === key.ENTER){
159 this.auto_highlight();
159 this.auto_highlight();
160 }
160 }
161
161
162 if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) {
162 if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) {
163 // Always ignore shift-enter in CodeMirror as we handle it.
163 // Always ignore shift-enter in CodeMirror as we handle it.
164 return true;
164 return true;
165 } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
165 } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
166 // triger on keypress (!) otherwise inconsistent event.which depending on plateform
166 // triger on keypress (!) otherwise inconsistent event.which depending on plateform
167 // browser and keyboard layout !
167 // browser and keyboard layout !
168 // Pressing '(' , request tooltip, don't forget to reappend it
168 // Pressing '(' , request tooltip, don't forget to reappend it
169 // The second argument says to hide the tooltip if the docstring
169 // The second argument says to hide the tooltip if the docstring
170 // is actually empty
170 // is actually empty
171 IPython.tooltip.pending(that, true);
171 IPython.tooltip.pending(that, true);
172 } else if (event.which === key.UPARROW && event.type === 'keydown') {
172 } else if (event.which === key.UPARROW && event.type === 'keydown') {
173 // If we are not at the top, let CM handle the up arrow and
173 // If we are not at the top, let CM handle the up arrow and
174 // prevent the global keydown handler from handling it.
174 // prevent the global keydown handler from handling it.
175 if (!that.at_top()) {
175 if (!that.at_top()) {
176 event.stop();
176 event.stop();
177 return false;
177 return false;
178 } else {
178 } else {
179 return true;
179 return true;
180 }
180 }
181 } else if (event.which === key.ESC) {
181 } else if (event.which === key.ESC) {
182 return IPython.tooltip.remove_and_cancel_tooltip(true);
182 return IPython.tooltip.remove_and_cancel_tooltip(true);
183 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
183 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
184 // If we are not at the bottom, let CM handle the down arrow and
184 // If we are not at the bottom, let CM handle the down arrow and
185 // prevent the global keydown handler from handling it.
185 // prevent the global keydown handler from handling it.
186 if (!that.at_bottom()) {
186 if (!that.at_bottom()) {
187 event.stop();
187 event.stop();
188 return false;
188 return false;
189 } else {
189 } else {
190 return true;
190 return true;
191 }
191 }
192 } else if (event.keyCode === key.TAB && event.type == 'keydown' && event.shiftKey) {
192 } else if (event.keyCode === key.TAB && event.type == 'keydown' && event.shiftKey) {
193 if (editor.somethingSelected()){
193 if (editor.somethingSelected()){
194 var anchor = editor.getCursor("anchor");
194 var anchor = editor.getCursor("anchor");
195 var head = editor.getCursor("head");
195 var head = editor.getCursor("head");
196 if( anchor.line != head.line){
196 if( anchor.line != head.line){
197 return false;
197 return false;
198 }
198 }
199 }
199 }
200 IPython.tooltip.request(that);
200 IPython.tooltip.request(that);
201 event.stop();
201 event.stop();
202 return true;
202 return true;
203 } else if (event.keyCode === key.TAB && event.type == 'keydown') {
203 } else if (event.keyCode === key.TAB && event.type == 'keydown') {
204 // Tab completion.
204 // Tab completion.
205 //Do not trim here because of tooltip
205 //Do not trim here because of tooltip
206 if (editor.somethingSelected()) { return false; }
206 if (editor.somethingSelected()) { return false; }
207 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur);
207 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur);
208 if (pre_cursor.trim() === "") {
208 if (pre_cursor.trim() === "") {
209 // Don't autocomplete if the part of the line before the cursor
209 // Don't autocomplete if the part of the line before the cursor
210 // is empty. In this case, let CodeMirror handle indentation.
210 // is empty. In this case, let CodeMirror handle indentation.
211 return false;
211 return false;
212 } else if ((pre_cursor.substr(-1) === "("|| pre_cursor.substr(-1) === " ") && IPython.config.tooltip_on_tab ) {
213 IPython.tooltip.request(that);
214 // Prevent the event from bubbling up.
215 event.stop();
216 // Prevent CodeMirror from handling the tab.
217 return true;
218 } else {
212 } else {
219 event.stop();
213 event.stop();
220 this.completer.startCompletion();
214 this.completer.startCompletion();
221 return true;
215 return true;
222 }
216 }
223 } else {
217 } else {
224 // keypress/keyup also trigger on TAB press, and we don't want to
218 // keypress/keyup also trigger on TAB press, and we don't want to
225 // use those to disable tab completion.
219 // use those to disable tab completion.
226 return false;
220 return false;
227 }
221 }
228 return false;
222 return false;
229 };
223 };
230
224
231
225
232 // Kernel related calls.
226 // Kernel related calls.
233
227
234 CodeCell.prototype.set_kernel = function (kernel) {
228 CodeCell.prototype.set_kernel = function (kernel) {
235 this.kernel = kernel;
229 this.kernel = kernel;
236 };
230 };
237
231
238 /**
232 /**
239 * Execute current code cell to the kernel
233 * Execute current code cell to the kernel
240 * @method execute
234 * @method execute
241 */
235 */
242 CodeCell.prototype.execute = function () {
236 CodeCell.prototype.execute = function () {
243 this.output_area.clear_output();
237 this.output_area.clear_output();
244 this.set_input_prompt('*');
238 this.set_input_prompt('*');
245 this.element.addClass("running");
239 this.element.addClass("running");
246 if (this.last_msg_id) {
240 if (this.last_msg_id) {
247 this.kernel.clear_callbacks_for_msg(this.last_msg_id);
241 this.kernel.clear_callbacks_for_msg(this.last_msg_id);
248 }
242 }
249 var callbacks = this.get_callbacks();
243 var callbacks = this.get_callbacks();
250
244
251 this.last_msg_id = this.kernel.execute(this.get_text(), callbacks, {silent: false, store_history: true});
245 this.last_msg_id = this.kernel.execute(this.get_text(), callbacks, {silent: false, store_history: true});
252 };
246 };
253
247
254 /**
248 /**
255 * Construct the default callbacks for
249 * Construct the default callbacks for
256 * @method get_callbacks
250 * @method get_callbacks
257 */
251 */
258 CodeCell.prototype.get_callbacks = function () {
252 CodeCell.prototype.get_callbacks = function () {
259 return {
253 return {
260 shell : {
254 shell : {
261 reply : $.proxy(this._handle_execute_reply, this),
255 reply : $.proxy(this._handle_execute_reply, this),
262 payload : {
256 payload : {
263 set_next_input : $.proxy(this._handle_set_next_input, this),
257 set_next_input : $.proxy(this._handle_set_next_input, this),
264 page : $.proxy(this._open_with_pager, this)
258 page : $.proxy(this._open_with_pager, this)
265 }
259 }
266 },
260 },
267 iopub : {
261 iopub : {
268 output : $.proxy(this.output_area.handle_output, this.output_area),
262 output : $.proxy(this.output_area.handle_output, this.output_area),
269 clear_output : $.proxy(this.output_area.handle_clear_output, this.output_area),
263 clear_output : $.proxy(this.output_area.handle_clear_output, this.output_area),
270 },
264 },
271 input : $.proxy(this._handle_input_request, this)
265 input : $.proxy(this._handle_input_request, this)
272 };
266 };
273 };
267 };
274
268
275 CodeCell.prototype._open_with_pager = function (payload) {
269 CodeCell.prototype._open_with_pager = function (payload) {
276 $([IPython.events]).trigger('open_with_text.Pager', payload);
270 $([IPython.events]).trigger('open_with_text.Pager', payload);
277 };
271 };
278
272
279 /**
273 /**
280 * @method _handle_execute_reply
274 * @method _handle_execute_reply
281 * @private
275 * @private
282 */
276 */
283 CodeCell.prototype._handle_execute_reply = function (msg) {
277 CodeCell.prototype._handle_execute_reply = function (msg) {
284 this.set_input_prompt(msg.content.execution_count);
278 this.set_input_prompt(msg.content.execution_count);
285 this.element.removeClass("running");
279 this.element.removeClass("running");
286 $([IPython.events]).trigger('set_dirty.Notebook', {value: true});
280 $([IPython.events]).trigger('set_dirty.Notebook', {value: true});
287 };
281 };
288
282
289 /**
283 /**
290 * @method _handle_set_next_input
284 * @method _handle_set_next_input
291 * @private
285 * @private
292 */
286 */
293 CodeCell.prototype._handle_set_next_input = function (payload) {
287 CodeCell.prototype._handle_set_next_input = function (payload) {
294 var data = {'cell': this, 'text': payload.text};
288 var data = {'cell': this, 'text': payload.text};
295 $([IPython.events]).trigger('set_next_input.Notebook', data);
289 $([IPython.events]).trigger('set_next_input.Notebook', data);
296 };
290 };
297
291
298 /**
292 /**
299 * @method _handle_input_request
293 * @method _handle_input_request
300 * @private
294 * @private
301 */
295 */
302 CodeCell.prototype._handle_input_request = function (msg) {
296 CodeCell.prototype._handle_input_request = function (msg) {
303 this.output_area.append_raw_input(msg);
297 this.output_area.append_raw_input(msg);
304 };
298 };
305
299
306
300
307 // Basic cell manipulation.
301 // Basic cell manipulation.
308
302
309 CodeCell.prototype.select = function () {
303 CodeCell.prototype.select = function () {
310 IPython.Cell.prototype.select.apply(this);
304 IPython.Cell.prototype.select.apply(this);
311 this.code_mirror.refresh();
305 this.code_mirror.refresh();
312 this.code_mirror.focus();
306 this.code_mirror.focus();
313 this.auto_highlight();
307 this.auto_highlight();
314 // We used to need an additional refresh() after the focus, but
308 // We used to need an additional refresh() after the focus, but
315 // it appears that this has been fixed in CM. This bug would show
309 // it appears that this has been fixed in CM. This bug would show
316 // up on FF when a newly loaded markdown cell was edited.
310 // up on FF when a newly loaded markdown cell was edited.
317 };
311 };
318
312
319
313
320 CodeCell.prototype.select_all = function () {
314 CodeCell.prototype.select_all = function () {
321 var start = {line: 0, ch: 0};
315 var start = {line: 0, ch: 0};
322 var nlines = this.code_mirror.lineCount();
316 var nlines = this.code_mirror.lineCount();
323 var last_line = this.code_mirror.getLine(nlines-1);
317 var last_line = this.code_mirror.getLine(nlines-1);
324 var end = {line: nlines-1, ch: last_line.length};
318 var end = {line: nlines-1, ch: last_line.length};
325 this.code_mirror.setSelection(start, end);
319 this.code_mirror.setSelection(start, end);
326 };
320 };
327
321
328
322
329 CodeCell.prototype.collapse = function () {
323 CodeCell.prototype.collapse = function () {
330 this.collapsed = true;
324 this.collapsed = true;
331 this.output_area.collapse();
325 this.output_area.collapse();
332 };
326 };
333
327
334
328
335 CodeCell.prototype.expand = function () {
329 CodeCell.prototype.expand = function () {
336 this.collapsed = false;
330 this.collapsed = false;
337 this.output_area.expand();
331 this.output_area.expand();
338 };
332 };
339
333
340
334
341 CodeCell.prototype.toggle_output = function () {
335 CodeCell.prototype.toggle_output = function () {
342 this.collapsed = Boolean(1 - this.collapsed);
336 this.collapsed = Boolean(1 - this.collapsed);
343 this.output_area.toggle_output();
337 this.output_area.toggle_output();
344 };
338 };
345
339
346
340
347 CodeCell.prototype.toggle_output_scroll = function () {
341 CodeCell.prototype.toggle_output_scroll = function () {
348 this.output_area.toggle_scroll();
342 this.output_area.toggle_scroll();
349 };
343 };
350
344
351
345
352 CodeCell.input_prompt_classical = function (prompt_value, lines_number) {
346 CodeCell.input_prompt_classical = function (prompt_value, lines_number) {
353 var ns = prompt_value || "&nbsp;";
347 var ns = prompt_value || "&nbsp;";
354 return 'In&nbsp;[' + ns + ']:';
348 return 'In&nbsp;[' + ns + ']:';
355 };
349 };
356
350
357 CodeCell.input_prompt_continuation = function (prompt_value, lines_number) {
351 CodeCell.input_prompt_continuation = function (prompt_value, lines_number) {
358 var html = [CodeCell.input_prompt_classical(prompt_value, lines_number)];
352 var html = [CodeCell.input_prompt_classical(prompt_value, lines_number)];
359 for(var i=1; i < lines_number; i++) {
353 for(var i=1; i < lines_number; i++) {
360 html.push(['...:']);
354 html.push(['...:']);
361 }
355 }
362 return html.join('<br/>');
356 return html.join('<br/>');
363 };
357 };
364
358
365 CodeCell.input_prompt_function = CodeCell.input_prompt_classical;
359 CodeCell.input_prompt_function = CodeCell.input_prompt_classical;
366
360
367
361
368 CodeCell.prototype.set_input_prompt = function (number) {
362 CodeCell.prototype.set_input_prompt = function (number) {
369 var nline = 1;
363 var nline = 1;
370 if (this.code_mirror !== undefined) {
364 if (this.code_mirror !== undefined) {
371 nline = this.code_mirror.lineCount();
365 nline = this.code_mirror.lineCount();
372 }
366 }
373 this.input_prompt_number = number;
367 this.input_prompt_number = number;
374 var prompt_html = CodeCell.input_prompt_function(this.input_prompt_number, nline);
368 var prompt_html = CodeCell.input_prompt_function(this.input_prompt_number, nline);
375 this.element.find('div.input_prompt').html(prompt_html);
369 this.element.find('div.input_prompt').html(prompt_html);
376 };
370 };
377
371
378
372
379 CodeCell.prototype.clear_input = function () {
373 CodeCell.prototype.clear_input = function () {
380 this.code_mirror.setValue('');
374 this.code_mirror.setValue('');
381 };
375 };
382
376
383
377
384 CodeCell.prototype.get_text = function () {
378 CodeCell.prototype.get_text = function () {
385 return this.code_mirror.getValue();
379 return this.code_mirror.getValue();
386 };
380 };
387
381
388
382
389 CodeCell.prototype.set_text = function (code) {
383 CodeCell.prototype.set_text = function (code) {
390 return this.code_mirror.setValue(code);
384 return this.code_mirror.setValue(code);
391 };
385 };
392
386
393
387
394 CodeCell.prototype.at_top = function () {
388 CodeCell.prototype.at_top = function () {
395 var cursor = this.code_mirror.getCursor();
389 var cursor = this.code_mirror.getCursor();
396 if (cursor.line === 0 && cursor.ch === 0) {
390 if (cursor.line === 0 && cursor.ch === 0) {
397 return true;
391 return true;
398 } else {
392 } else {
399 return false;
393 return false;
400 }
394 }
401 };
395 };
402
396
403
397
404 CodeCell.prototype.at_bottom = function () {
398 CodeCell.prototype.at_bottom = function () {
405 var cursor = this.code_mirror.getCursor();
399 var cursor = this.code_mirror.getCursor();
406 if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
400 if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
407 return true;
401 return true;
408 } else {
402 } else {
409 return false;
403 return false;
410 }
404 }
411 };
405 };
412
406
413
407
414 CodeCell.prototype.clear_output = function (wait) {
408 CodeCell.prototype.clear_output = function (wait) {
415 this.output_area.clear_output(wait);
409 this.output_area.clear_output(wait);
416 };
410 };
417
411
418
412
419 // JSON serialization
413 // JSON serialization
420
414
421 CodeCell.prototype.fromJSON = function (data) {
415 CodeCell.prototype.fromJSON = function (data) {
422 IPython.Cell.prototype.fromJSON.apply(this, arguments);
416 IPython.Cell.prototype.fromJSON.apply(this, arguments);
423 if (data.cell_type === 'code') {
417 if (data.cell_type === 'code') {
424 if (data.input !== undefined) {
418 if (data.input !== undefined) {
425 this.set_text(data.input);
419 this.set_text(data.input);
426 // make this value the starting point, so that we can only undo
420 // make this value the starting point, so that we can only undo
427 // to this state, instead of a blank cell
421 // to this state, instead of a blank cell
428 this.code_mirror.clearHistory();
422 this.code_mirror.clearHistory();
429 this.auto_highlight();
423 this.auto_highlight();
430 }
424 }
431 if (data.prompt_number !== undefined) {
425 if (data.prompt_number !== undefined) {
432 this.set_input_prompt(data.prompt_number);
426 this.set_input_prompt(data.prompt_number);
433 } else {
427 } else {
434 this.set_input_prompt();
428 this.set_input_prompt();
435 }
429 }
436 this.output_area.fromJSON(data.outputs);
430 this.output_area.fromJSON(data.outputs);
437 if (data.collapsed !== undefined) {
431 if (data.collapsed !== undefined) {
438 if (data.collapsed) {
432 if (data.collapsed) {
439 this.collapse();
433 this.collapse();
440 } else {
434 } else {
441 this.expand();
435 this.expand();
442 }
436 }
443 }
437 }
444 }
438 }
445 };
439 };
446
440
447
441
448 CodeCell.prototype.toJSON = function () {
442 CodeCell.prototype.toJSON = function () {
449 var data = IPython.Cell.prototype.toJSON.apply(this);
443 var data = IPython.Cell.prototype.toJSON.apply(this);
450 data.input = this.get_text();
444 data.input = this.get_text();
451 data.cell_type = 'code';
445 data.cell_type = 'code';
452 if (this.input_prompt_number) {
446 if (this.input_prompt_number) {
453 data.prompt_number = this.input_prompt_number;
447 data.prompt_number = this.input_prompt_number;
454 }
448 }
455 var outputs = this.output_area.toJSON();
449 var outputs = this.output_area.toJSON();
456 data.outputs = outputs;
450 data.outputs = outputs;
457 data.language = 'python';
451 data.language = 'python';
458 data.collapsed = this.collapsed;
452 data.collapsed = this.collapsed;
459 return data;
453 return data;
460 };
454 };
461
455
462
456
463 IPython.CodeCell = CodeCell;
457 IPython.CodeCell = CodeCell;
464
458
465 return IPython;
459 return IPython;
466 }(IPython));
460 }(IPython));
@@ -1,80 +1,79
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2012 The IPython Development Team
2 // Copyright (C) 2012 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 /**
12 /**
13 * @module IPython
13 * @module IPython
14 * @namespace IPython
14 * @namespace IPython
15 **/
15 **/
16
16
17 var IPython = (function (IPython) {
17 var IPython = (function (IPython) {
18 "use strict";
18 "use strict";
19 /**
19 /**
20 * A place where some stuff can be confugured.
20 * A place where some stuff can be confugured.
21 *
21 *
22 * @class config
22 * @class config
23 * @static
23 * @static
24 *
24 *
25 **/
25 **/
26 var default_config = {
26 var default_config = {
27 /**
27 /**
28 * Dictionary of object to autodetect highlight mode for code cell.
28 * Dictionary of object to autodetect highlight mode for code cell.
29 * Item of the dictionnary should take the form :
29 * Item of the dictionnary should take the form :
30 *
30 *
31 * key : {'reg':[list_of_regexp]}
31 * key : {'reg':[list_of_regexp]}
32 *
32 *
33 * where `key` will be the code mirror mode name
33 * where `key` will be the code mirror mode name
34 * and `list_of_regexp` should be a list of regext that should match
34 * and `list_of_regexp` should be a list of regext that should match
35 * the first line of the cell to trigger this mode.
35 * the first line of the cell to trigger this mode.
36 *
36 *
37 * if `key` is prefixed by the `magic_` prefix the codemirror `mode`
37 * if `key` is prefixed by the `magic_` prefix the codemirror `mode`
38 * will be applied only at the end of the first line
38 * will be applied only at the end of the first line
39 *
39 *
40 * @attribute cell_magic_highlight
40 * @attribute cell_magic_highlight
41 * @example
41 * @example
42 * This would trigger javascript mode
42 * This would trigger javascript mode
43 * from the second line if first line start with `%%javascript` or `%%jsmagic`
43 * from the second line if first line start with `%%javascript` or `%%jsmagic`
44 *
44 *
45 * cell_magic_highlight['magic_javascript'] = {'reg':[/^%%javascript/,/^%%jsmagic/]}
45 * cell_magic_highlight['magic_javascript'] = {'reg':[/^%%javascript/,/^%%jsmagic/]}
46 * @example
46 * @example
47 * This would trigger javascript mode
47 * This would trigger javascript mode
48 * from the second line if first line start with `var`
48 * from the second line if first line start with `var`
49 *
49 *
50 * cell_magic_highlight['javascript'] = {'reg':[/^var/]}
50 * cell_magic_highlight['javascript'] = {'reg':[/^var/]}
51 */
51 */
52 cell_magic_highlight : {
52 cell_magic_highlight : {
53 'magic_javascript' :{'reg':[/^%%javascript/]}
53 'magic_javascript' :{'reg':[/^%%javascript/]}
54 ,'magic_perl' :{'reg':[/^%%perl/]}
54 ,'magic_perl' :{'reg':[/^%%perl/]}
55 ,'magic_ruby' :{'reg':[/^%%ruby/]}
55 ,'magic_ruby' :{'reg':[/^%%ruby/]}
56 ,'magic_python' :{'reg':[/^%%python3?/]}
56 ,'magic_python' :{'reg':[/^%%python3?/]}
57 ,'magic_shell' :{'reg':[/^%%bash/]}
57 ,'magic_shell' :{'reg':[/^%%bash/]}
58 ,'magic_r' :{'reg':[/^%%R/]}
58 ,'magic_r' :{'reg':[/^%%R/]}
59 ,'magic_text/x-cython' :{'reg':[/^%%cython/]}
59 ,'magic_text/x-cython' :{'reg':[/^%%cython/]}
60 },
60 },
61
61
62 /**
62 /**
63 * same as `cell_magic_highlight` but for raw cells
63 * same as `cell_magic_highlight` but for raw cells
64 * @attribute raw_cell_highlight
64 * @attribute raw_cell_highlight
65 */
65 */
66 raw_cell_highlight : {
66 raw_cell_highlight : {
67 'diff' :{'reg':[/^diff/]}
67 'diff' :{'reg':[/^diff/]}
68 },
68 },
69
69
70 tooltip_on_tab : true,
71 };
70 };
72
71
73 // use the same method to merge user configuration
72 // use the same method to merge user configuration
74 IPython.config = {};
73 IPython.config = {};
75 $.extend(IPython.config, default_config);
74 $.extend(IPython.config, default_config);
76
75
77 return IPython;
76 return IPython;
78
77
79 }(IPython));
78 }(IPython));
80
79
@@ -1,439 +1,439
1 {
1 {
2 "metadata": {
2 "metadata": {
3 "name": ""
3 "name": ""
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "nbformat_minor": 0,
7 "worksheets": [
7 "worksheets": [
8 {
8 {
9 "cells": [
9 "cells": [
10 {
10 {
11 "cell_type": "heading",
11 "cell_type": "heading",
12 "level": 1,
12 "level": 1,
13 "metadata": {},
13 "metadata": {},
14 "source": [
14 "source": [
15 "Running Code in the IPython Notebook"
15 "Running Code in the IPython Notebook"
16 ]
16 ]
17 },
17 },
18 {
18 {
19 "cell_type": "markdown",
19 "cell_type": "markdown",
20 "metadata": {},
20 "metadata": {},
21 "source": [
21 "source": [
22 "First and foremost, the IPython Notebook is an interactive environment for writing and running Python code."
22 "First and foremost, the IPython Notebook is an interactive environment for writing and running Python code."
23 ]
23 ]
24 },
24 },
25 {
25 {
26 "cell_type": "heading",
26 "cell_type": "heading",
27 "level": 2,
27 "level": 2,
28 "metadata": {},
28 "metadata": {},
29 "source": [
29 "source": [
30 "Code cells allow you to enter and run Python code"
30 "Code cells allow you to enter and run Python code"
31 ]
31 ]
32 },
32 },
33 {
33 {
34 "cell_type": "markdown",
34 "cell_type": "markdown",
35 "metadata": {},
35 "metadata": {},
36 "source": [
36 "source": [
37 "Run a code cell using `Shift-Enter` or pressing the \"Play\" button in the toolbar above:"
37 "Run a code cell using `Shift-Enter` or pressing the \"Play\" button in the toolbar above:"
38 ]
38 ]
39 },
39 },
40 {
40 {
41 "cell_type": "code",
41 "cell_type": "code",
42 "collapsed": false,
42 "collapsed": false,
43 "input": [
43 "input": [
44 "a = 10"
44 "a = 10"
45 ],
45 ],
46 "language": "python",
46 "language": "python",
47 "metadata": {},
47 "metadata": {},
48 "outputs": [],
48 "outputs": [],
49 "prompt_number": 10
49 "prompt_number": 10
50 },
50 },
51 {
51 {
52 "cell_type": "code",
52 "cell_type": "code",
53 "collapsed": false,
53 "collapsed": false,
54 "input": [
54 "input": [
55 "print(a)"
55 "print(a)"
56 ],
56 ],
57 "language": "python",
57 "language": "python",
58 "metadata": {},
58 "metadata": {},
59 "outputs": [
59 "outputs": [
60 {
60 {
61 "output_type": "stream",
61 "output_type": "stream",
62 "stream": "stdout",
62 "stream": "stdout",
63 "text": [
63 "text": [
64 "10\n"
64 "10\n"
65 ]
65 ]
66 }
66 }
67 ],
67 ],
68 "prompt_number": 11
68 "prompt_number": 11
69 },
69 },
70 {
70 {
71 "cell_type": "heading",
71 "cell_type": "heading",
72 "level": 2,
72 "level": 2,
73 "metadata": {},
73 "metadata": {},
74 "source": [
74 "source": [
75 "Managing the IPython Kernel"
75 "Managing the IPython Kernel"
76 ]
76 ]
77 },
77 },
78 {
78 {
79 "cell_type": "markdown",
79 "cell_type": "markdown",
80 "metadata": {},
80 "metadata": {},
81 "source": [
81 "source": [
82 "Code is run in a separate process called the IPython Kernel. The Kernel can be interrupted or restarted. Try running the following cell and then hit the \"Stop\" button in the toolbar above."
82 "Code is run in a separate process called the IPython Kernel. The Kernel can be interrupted or restarted. Try running the following cell and then hit the \"Stop\" button in the toolbar above."
83 ]
83 ]
84 },
84 },
85 {
85 {
86 "cell_type": "code",
86 "cell_type": "code",
87 "collapsed": false,
87 "collapsed": false,
88 "input": [
88 "input": [
89 "import time\n",
89 "import time\n",
90 "time.sleep(10)"
90 "time.sleep(10)"
91 ],
91 ],
92 "language": "python",
92 "language": "python",
93 "metadata": {},
93 "metadata": {},
94 "outputs": [
94 "outputs": [
95 {
95 {
96 "ename": "KeyboardInterrupt",
96 "ename": "KeyboardInterrupt",
97 "evalue": "",
97 "evalue": "",
98 "output_type": "pyerr",
98 "output_type": "pyerr",
99 "traceback": [
99 "traceback": [
100 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
100 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
101 "\u001b[0;32m<ipython-input-16-d7b436e260d5>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
101 "\u001b[0;32m<ipython-input-16-d7b436e260d5>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
102 "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
102 "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
103 ]
103 ]
104 }
104 }
105 ],
105 ],
106 "prompt_number": 16
106 "prompt_number": 16
107 },
107 },
108 {
108 {
109 "cell_type": "markdown",
109 "cell_type": "markdown",
110 "metadata": {},
110 "metadata": {},
111 "source": [
111 "source": [
112 "If the Kernel dies you will be prompted to restart it. Here we call the low-level system libc.time routine with the wrong argument via\n",
112 "If the Kernel dies you will be prompted to restart it. Here we call the low-level system libc.time routine with the wrong argument via\n",
113 "ctypes to segfault the Python interpreter:"
113 "ctypes to segfault the Python interpreter:"
114 ]
114 ]
115 },
115 },
116 {
116 {
117 "cell_type": "code",
117 "cell_type": "code",
118 "collapsed": false,
118 "collapsed": false,
119 "input": [
119 "input": [
120 "import sys\n",
120 "import sys\n",
121 "from ctypes import CDLL\n",
121 "from ctypes import CDLL\n",
122 "# This will crash a Linux or Mac system; equivalent calls can be made on Windows\n",
122 "# This will crash a Linux or Mac system; equivalent calls can be made on Windows\n",
123 "dll = 'dylib' if sys.platform == 'darwin' else 'so.6'\n",
123 "dll = 'dylib' if sys.platform == 'darwin' else 'so.6'\n",
124 "libc = CDLL(\"libc.%s\" % dll) \n",
124 "libc = CDLL(\"libc.%s\" % dll) \n",
125 "libc.time(-1) # BOOM!!"
125 "libc.time(-1) # BOOM!!"
126 ],
126 ],
127 "language": "python",
127 "language": "python",
128 "metadata": {},
128 "metadata": {},
129 "outputs": [],
129 "outputs": [],
130 "prompt_number": "*"
130 "prompt_number": "*"
131 },
131 },
132 {
132 {
133 "cell_type": "heading",
133 "cell_type": "heading",
134 "level": 2,
134 "level": 2,
135 "metadata": {},
135 "metadata": {},
136 "source": [
136 "source": [
137 "All of the goodness of IPython works"
137 "All of the goodness of IPython works"
138 ]
138 ]
139 },
139 },
140 {
140 {
141 "cell_type": "markdown",
141 "cell_type": "markdown",
142 "metadata": {},
142 "metadata": {},
143 "source": [
143 "source": [
144 "Here are two system aliases:"
144 "Here are two system aliases:"
145 ]
145 ]
146 },
146 },
147 {
147 {
148 "cell_type": "code",
148 "cell_type": "code",
149 "collapsed": false,
149 "collapsed": false,
150 "input": [
150 "input": [
151 "pwd"
151 "pwd"
152 ],
152 ],
153 "language": "python",
153 "language": "python",
154 "metadata": {},
154 "metadata": {},
155 "outputs": [
155 "outputs": [
156 {
156 {
157 "output_type": "pyout",
157 "output_type": "pyout",
158 "prompt_number": 4,
158 "prompt_number": 4,
159 "text": [
159 "text": [
160 "u'/Users/bgranger/Documents/Computation/IPython/code/ipython/examples/notebooks'"
160 "u'/Users/bgranger/Documents/Computation/IPython/code/ipython/examples/notebooks'"
161 ]
161 ]
162 }
162 }
163 ],
163 ],
164 "prompt_number": 4
164 "prompt_number": 4
165 },
165 },
166 {
166 {
167 "cell_type": "code",
167 "cell_type": "code",
168 "collapsed": false,
168 "collapsed": false,
169 "input": [
169 "input": [
170 "ls"
170 "ls"
171 ],
171 ],
172 "language": "python",
172 "language": "python",
173 "metadata": {},
173 "metadata": {},
174 "outputs": [
174 "outputs": [
175 {
175 {
176 "output_type": "stream",
176 "output_type": "stream",
177 "stream": "stdout",
177 "stream": "stdout",
178 "text": [
178 "text": [
179 "01_notebook_introduction.ipynb Octave Magic.ipynb\r\n",
179 "01_notebook_introduction.ipynb Octave Magic.ipynb\r\n",
180 "Animations Using clear_output.ipynb PyLab and Matplotlib.ipynb\r\n",
180 "Animations Using clear_output.ipynb PyLab and Matplotlib.ipynb\r\n",
181 "Basic Output.ipynb R Magics.ipynb\r\n",
181 "Basic Output.ipynb R Magics.ipynb\r\n",
182 "Custom Display Logic.ipynb Running Code.ipynb\r\n",
182 "Custom Display Logic.ipynb Running Code.ipynb\r\n",
183 "Cython Magics.ipynb Script Magics.ipynb\r\n",
183 "Cython Magics.ipynb Script Magics.ipynb\r\n",
184 "Data Publication API.ipynb SymPy Examples.ipynb\r\n",
184 "Data Publication API.ipynb SymPy Examples.ipynb\r\n",
185 "Display System.ipynb Trapezoid Rule.ipynb\r\n",
185 "Display System.ipynb Trapezoid Rule.ipynb\r\n",
186 "JS Progress Bar.ipynb Typesetting Math Using MathJax.ipynb\r\n",
186 "JS Progress Bar.ipynb Typesetting Math Using MathJax.ipynb\r\n",
187 "Local Files.ipynb animation.m4v\r\n",
187 "Local Files.ipynb animation.m4v\r\n",
188 "Markdown Cells.ipynb python-logo.svg\r\n",
188 "Markdown Cells.ipynb python-logo.svg\r\n",
189 "Notebook Tour.ipynb\r\n"
189 "Notebook Tour.ipynb\r\n"
190 ]
190 ]
191 }
191 }
192 ],
192 ],
193 "prompt_number": 2
193 "prompt_number": 2
194 },
194 },
195 {
195 {
196 "cell_type": "markdown",
196 "cell_type": "markdown",
197 "metadata": {},
197 "metadata": {},
198 "source": [
198 "source": [
199 "Any command line program can be run using `!` with string interpolation from Python variables:"
199 "Any command line program can be run using `!` with string interpolation from Python variables:"
200 ]
200 ]
201 },
201 },
202 {
202 {
203 "cell_type": "code",
203 "cell_type": "code",
204 "collapsed": false,
204 "collapsed": false,
205 "input": [
205 "input": [
206 "message = 'The IPython notebook is great!'\n",
206 "message = 'The IPython notebook is great!'\n",
207 "# note: the echo command does not run on Windows, it's a unix command.\n",
207 "# note: the echo command does not run on Windows, it's a unix command.\n",
208 "!echo $message"
208 "!echo $message"
209 ],
209 ],
210 "language": "python",
210 "language": "python",
211 "metadata": {},
211 "metadata": {},
212 "outputs": []
212 "outputs": []
213 },
213 },
214 {
214 {
215 "cell_type": "markdown",
215 "cell_type": "markdown",
216 "metadata": {},
216 "metadata": {},
217 "source": [
217 "source": [
218 "Tab completion works:"
218 "Tab completion works:"
219 ]
219 ]
220 },
220 },
221 {
221 {
222 "cell_type": "code",
222 "cell_type": "code",
223 "collapsed": false,
223 "collapsed": false,
224 "input": [
224 "input": [
225 "import numpy\n",
225 "import numpy\n",
226 "numpy.random."
226 "numpy.random."
227 ],
227 ],
228 "language": "python",
228 "language": "python",
229 "metadata": {},
229 "metadata": {},
230 "outputs": [],
230 "outputs": [],
231 "prompt_number": 9
231 "prompt_number": 9
232 },
232 },
233 {
233 {
234 "cell_type": "markdown",
234 "cell_type": "markdown",
235 "metadata": {},
235 "metadata": {},
236 "source": [
236 "source": [
237 "Tab completion after `(` brings up a tooltip with the docstring:"
237 "Shift-Tab on selection, or after `(` brings up a tooltip with the docstring:"
238 ]
238 ]
239 },
239 },
240 {
240 {
241 "cell_type": "code",
241 "cell_type": "code",
242 "collapsed": false,
242 "collapsed": false,
243 "input": [
243 "input": [
244 "numpy.random.rand("
244 "numpy.random.rand("
245 ],
245 ],
246 "language": "python",
246 "language": "python",
247 "metadata": {},
247 "metadata": {},
248 "outputs": []
248 "outputs": []
249 },
249 },
250 {
250 {
251 "cell_type": "markdown",
251 "cell_type": "markdown",
252 "metadata": {},
252 "metadata": {},
253 "source": [
253 "source": [
254 "Adding `?` opens the docstring in the pager below:"
254 "Adding `?` opens the docstring in the pager below:"
255 ]
255 ]
256 },
256 },
257 {
257 {
258 "cell_type": "code",
258 "cell_type": "code",
259 "collapsed": false,
259 "collapsed": false,
260 "input": [
260 "input": [
261 "magic?"
261 "magic?"
262 ],
262 ],
263 "language": "python",
263 "language": "python",
264 "metadata": {},
264 "metadata": {},
265 "outputs": [],
265 "outputs": [],
266 "prompt_number": 8
266 "prompt_number": 8
267 },
267 },
268 {
268 {
269 "cell_type": "markdown",
269 "cell_type": "markdown",
270 "metadata": {},
270 "metadata": {},
271 "source": [
271 "source": [
272 "Exceptions are formatted nicely:"
272 "Exceptions are formatted nicely:"
273 ]
273 ]
274 },
274 },
275 {
275 {
276 "cell_type": "code",
276 "cell_type": "code",
277 "collapsed": false,
277 "collapsed": false,
278 "input": [
278 "input": [
279 "x = 1\n",
279 "x = 1\n",
280 "y = 4\n",
280 "y = 4\n",
281 "z = y/(1-x)"
281 "z = y/(1-x)"
282 ],
282 ],
283 "language": "python",
283 "language": "python",
284 "metadata": {},
284 "metadata": {},
285 "outputs": [
285 "outputs": [
286 {
286 {
287 "ename": "ZeroDivisionError",
287 "ename": "ZeroDivisionError",
288 "evalue": "integer division or modulo by zero",
288 "evalue": "integer division or modulo by zero",
289 "output_type": "pyerr",
289 "output_type": "pyerr",
290 "traceback": [
290 "traceback": [
291 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
291 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
292 "\u001b[0;32m<ipython-input-15-dc39888fd1d2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mz\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
292 "\u001b[0;32m<ipython-input-15-dc39888fd1d2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mz\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
293 "\u001b[0;31mZeroDivisionError\u001b[0m: integer division or modulo by zero"
293 "\u001b[0;31mZeroDivisionError\u001b[0m: integer division or modulo by zero"
294 ]
294 ]
295 }
295 }
296 ],
296 ],
297 "prompt_number": 15
297 "prompt_number": 15
298 },
298 },
299 {
299 {
300 "cell_type": "heading",
300 "cell_type": "heading",
301 "level": 2,
301 "level": 2,
302 "metadata": {},
302 "metadata": {},
303 "source": [
303 "source": [
304 "Working with external code"
304 "Working with external code"
305 ]
305 ]
306 },
306 },
307 {
307 {
308 "cell_type": "markdown",
308 "cell_type": "markdown",
309 "metadata": {},
309 "metadata": {},
310 "source": [
310 "source": [
311 "There are a number of ways of getting external code into code cells."
311 "There are a number of ways of getting external code into code cells."
312 ]
312 ]
313 },
313 },
314 {
314 {
315 "cell_type": "markdown",
315 "cell_type": "markdown",
316 "metadata": {},
316 "metadata": {},
317 "source": [
317 "source": [
318 "Pasting code with `>>>` prompts works as expected:"
318 "Pasting code with `>>>` prompts works as expected:"
319 ]
319 ]
320 },
320 },
321 {
321 {
322 "cell_type": "code",
322 "cell_type": "code",
323 "collapsed": false,
323 "collapsed": false,
324 "input": [
324 "input": [
325 ">>> the_world_is_flat = 1\n",
325 ">>> the_world_is_flat = 1\n",
326 ">>> if the_world_is_flat:\n",
326 ">>> if the_world_is_flat:\n",
327 "... print(\"Be careful not to fall off!\")"
327 "... print(\"Be careful not to fall off!\")"
328 ],
328 ],
329 "language": "python",
329 "language": "python",
330 "metadata": {},
330 "metadata": {},
331 "outputs": [
331 "outputs": [
332 {
332 {
333 "output_type": "stream",
333 "output_type": "stream",
334 "stream": "stdout",
334 "stream": "stdout",
335 "text": [
335 "text": [
336 "Be careful not to fall off!\n"
336 "Be careful not to fall off!\n"
337 ]
337 ]
338 }
338 }
339 ],
339 ],
340 "prompt_number": 1
340 "prompt_number": 1
341 },
341 },
342 {
342 {
343 "cell_type": "markdown",
343 "cell_type": "markdown",
344 "metadata": {},
344 "metadata": {},
345 "source": [
345 "source": [
346 "The `%load` magic lets you load code from URLs or local files:"
346 "The `%load` magic lets you load code from URLs or local files:"
347 ]
347 ]
348 },
348 },
349 {
349 {
350 "cell_type": "code",
350 "cell_type": "code",
351 "collapsed": false,
351 "collapsed": false,
352 "input": [
352 "input": [
353 "%load?"
353 "%load?"
354 ],
354 ],
355 "language": "python",
355 "language": "python",
356 "metadata": {},
356 "metadata": {},
357 "outputs": [],
357 "outputs": [],
358 "prompt_number": 14
358 "prompt_number": 14
359 },
359 },
360 {
360 {
361 "cell_type": "code",
361 "cell_type": "code",
362 "collapsed": false,
362 "collapsed": false,
363 "input": [
363 "input": [
364 "%matplotlib inline"
364 "%matplotlib inline"
365 ],
365 ],
366 "language": "python",
366 "language": "python",
367 "metadata": {},
367 "metadata": {},
368 "outputs": [],
368 "outputs": [],
369 "prompt_number": 1
369 "prompt_number": 1
370 },
370 },
371 {
371 {
372 "cell_type": "code",
372 "cell_type": "code",
373 "collapsed": false,
373 "collapsed": false,
374 "input": [
374 "input": [
375 "%load http://matplotlib.sourceforge.net/mpl_examples/pylab_examples/integral_demo.py"
375 "%load http://matplotlib.sourceforge.net/mpl_examples/pylab_examples/integral_demo.py"
376 ],
376 ],
377 "language": "python",
377 "language": "python",
378 "metadata": {},
378 "metadata": {},
379 "outputs": [],
379 "outputs": [],
380 "prompt_number": 2
380 "prompt_number": 2
381 },
381 },
382 {
382 {
383 "cell_type": "code",
383 "cell_type": "code",
384 "collapsed": false,
384 "collapsed": false,
385 "input": [
385 "input": [
386 "#!/usr/bin/env python\n",
386 "#!/usr/bin/env python\n",
387 "\n",
387 "\n",
388 "# implement the example graphs/integral from pyx\n",
388 "# implement the example graphs/integral from pyx\n",
389 "from pylab import *\n",
389 "from pylab import *\n",
390 "from matplotlib.patches import Polygon\n",
390 "from matplotlib.patches import Polygon\n",
391 "\n",
391 "\n",
392 "def func(x):\n",
392 "def func(x):\n",
393 " return (x-3)*(x-5)*(x-7)+85\n",
393 " return (x-3)*(x-5)*(x-7)+85\n",
394 "\n",
394 "\n",
395 "ax = subplot(111)\n",
395 "ax = subplot(111)\n",
396 "\n",
396 "\n",
397 "a, b = 2, 9 # integral area\n",
397 "a, b = 2, 9 # integral area\n",
398 "x = arange(0, 10, 0.01)\n",
398 "x = arange(0, 10, 0.01)\n",
399 "y = func(x)\n",
399 "y = func(x)\n",
400 "plot(x, y, linewidth=1)\n",
400 "plot(x, y, linewidth=1)\n",
401 "\n",
401 "\n",
402 "# make the shaded region\n",
402 "# make the shaded region\n",
403 "ix = arange(a, b, 0.01)\n",
403 "ix = arange(a, b, 0.01)\n",
404 "iy = func(ix)\n",
404 "iy = func(ix)\n",
405 "verts = [(a,0)] + list(zip(ix,iy)) + [(b,0)]\n",
405 "verts = [(a,0)] + list(zip(ix,iy)) + [(b,0)]\n",
406 "poly = Polygon(verts, facecolor='0.8', edgecolor='k')\n",
406 "poly = Polygon(verts, facecolor='0.8', edgecolor='k')\n",
407 "ax.add_patch(poly)\n",
407 "ax.add_patch(poly)\n",
408 "\n",
408 "\n",
409 "text(0.5 * (a + b), 30,\n",
409 "text(0.5 * (a + b), 30,\n",
410 " r\"$\\int_a^b f(x)\\mathrm{d}x$\", horizontalalignment='center',\n",
410 " r\"$\\int_a^b f(x)\\mathrm{d}x$\", horizontalalignment='center',\n",
411 " fontsize=20)\n",
411 " fontsize=20)\n",
412 "\n",
412 "\n",
413 "axis([0,10, 0, 180])\n",
413 "axis([0,10, 0, 180])\n",
414 "figtext(0.9, 0.05, 'x')\n",
414 "figtext(0.9, 0.05, 'x')\n",
415 "figtext(0.1, 0.9, 'y')\n",
415 "figtext(0.1, 0.9, 'y')\n",
416 "ax.set_xticks((a,b))\n",
416 "ax.set_xticks((a,b))\n",
417 "ax.set_xticklabels(('a','b'))\n",
417 "ax.set_xticklabels(('a','b'))\n",
418 "ax.set_yticks([])\n",
418 "ax.set_yticks([])\n",
419 "show()\n"
419 "show()\n"
420 ],
420 ],
421 "language": "python",
421 "language": "python",
422 "metadata": {},
422 "metadata": {},
423 "outputs": [
423 "outputs": [
424 {
424 {
425 "metadata": {},
425 "metadata": {},
426 "output_type": "display_data",
426 "output_type": "display_data",
427 "png": "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\nAAAAQvD/AKh2fy0Nfo/2AAAAAElFTkSuQmCC\n",
427 "png": "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\nAAAAQvD/AKh2fy0Nfo/2AAAAAElFTkSuQmCC\n",
428 "text": [
428 "text": [
429 "<matplotlib.figure.Figure at 0x110035290>"
429 "<matplotlib.figure.Figure at 0x110035290>"
430 ]
430 ]
431 }
431 }
432 ],
432 ],
433 "prompt_number": 3
433 "prompt_number": 3
434 }
434 }
435 ],
435 ],
436 "metadata": {}
436 "metadata": {}
437 }
437 }
438 ]
438 ]
439 } No newline at end of file
439 }
General Comments 0
You need to be logged in to leave comments. Login now