##// END OF EJS Templates
Merge pull request #1480 from minrk/npmagic...
Merge pull request #1480 from minrk/npmagic Fix %notebook magic, etc. nbformat unicode tests and fixes. * json.writes always gives unicode, so that `current.writes` can be trusted to give the same interface * setup base TestCase for nbformat tests, to consolidate code, and better test both file formats * add tests for reading/writing to files * allow `name` as kwarg to new_notebook to avoid unnecessary breakage of previous API. * remove fallback to xml, which would hide corrupt notebook files behind a nonsensical 'xml unsupported' message. Closes #1545, #1487.

File last commit:

r6084:bd9501bd
r6479:c4cf9403 merge
Show More
notebook.js
1342 lines | 47.1 KiB | application/javascript | JavascriptLexer
Brian E. Granger
More review changes....
r4609 //----------------------------------------------------------------------------
// Copyright (C) 2008-2011 The IPython Development Team
//
// Distributed under the terms of the BSD License. The full license is in
// the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------
Brian Granger
Basic notebook saving and loading....
r4315
Brian Granger
Initial reply handling implemented along with css fixes.
r4299 //============================================================================
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292 // Notebook
//============================================================================
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var IPython = (function (IPython) {
Brian E. Granger
Initial payload handling....
r4356 var utils = IPython.utils;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var Notebook = function (selector) {
MinRK
move read_only flag to page-level...
r5213 this.read_only = IPython.read_only;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 this.element = $(selector);
this.element.scroll();
this.element.data("notebook", this);
this.next_prompt_number = 1;
this.kernel = null;
Brian Granger
Added cell level cut/copy/paste.
r5879 this.clipboard = null;
Brian Granger
Minor, but important fixes to cut/copy/paste....
r5912 this.paste_enabled = false;
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = false;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 this.msg_cell_map = {};
Brian E. Granger
Implemented metadata for notebook format.
r4637 this.metadata = {};
Brian E. Granger
Adding keyboard shortcuts.
r4645 this.control_key_active = false;
Brian Granger
Major refactoring of saving, notification....
r6047 this.notebook_id = null;
this.notebook_name = null;
this.notebook_name_blacklist_re = /[\/\\]/;
Brian Granger
Proper error handling for nbformat versions in client code....
r6061 this.nbformat = 3 // Increment this when changing the nbformat
Brian E. Granger
Refactoring pager into its own class.
r4357 this.style();
Brian E. Granger
Improving the scrolling model.
r4364 this.create_elements();
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 this.bind_events();
Matthias BUSSONNIER
Improve tooltip tringgering,make it configurable...
r5399 this.set_tooltipontab(true);
Matthias BUSSONNIER
smart kwarg completion...
r5401 this.set_smartcompleter(true);
Matthias BUSSONNIER
Make the time before activating a tooltip configurable...
r5400 this.set_timebeforetooltip(1200);
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian E. Granger
Refactoring pager into its own class.
r4357 Notebook.prototype.style = function () {
Brian E. Granger
Left panel is now working.
r4363 $('div#notebook').addClass('border-box-sizing');
Brian E. Granger
Refactoring pager into its own class.
r4357 };
Brian E. Granger
Improving the scrolling model.
r4364 Notebook.prototype.create_elements = function () {
// We add this end_space div to the end of the notebook div to:
// i) provide a margin between the last cell and the end of the notebook
// ii) to prevent the div from scrolling up when the last cell is being
// edited, but is too low on the page, which browsers will do automatically.
Brian E. Granger
Double clicking on the end space will insert a new cell.
r4628 var that = this;
Brian Granger
Refactoring of the notebooks cell management....
r5945 var end_space = $('<div/>').addClass('end_space').height("30%");
Brian E. Granger
Double clicking on the end space will insert a new cell.
r4628 end_space.dblclick(function (e) {
MinRK
add read-only view for notebooks...
r5200 if (that.read_only) return;
Brian E. Granger
Double clicking on the end space will insert a new cell.
r4628 var ncells = that.ncells();
Brian Granger
Refactoring of the notebooks cell management....
r5945 that.insert_cell_below('code',ncells-1);
Brian E. Granger
Double clicking on the end space will insert a new cell.
r4628 });
Brian E. Granger
Don't scroll to bottom when last cell is selected.
r4604 this.element.append(end_space);
Brian E. Granger
Improving the scrolling model.
r4364 $('div#notebook').addClass('border-box-sizing');
};
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 Notebook.prototype.bind_events = function () {
var that = this;
$(document).keydown(function (event) {
Brian E. Granger
Fixing console.log messages related to keyboard shortcuts.
r4647 // console.log(event);
MinRK
don't swallow regular key events in read-only mode
r5546 if (that.read_only) return true;
fawce
added key handler for control-s to notebook, seems to work pretty well
r5990
// Save (CTRL+S) or (AppleKey+S)
//metaKey = applekey on mac
if ((event.ctrlKey || event.metaKey) && event.keyCode==83) {
Brian Granger
Major refactoring of saving, notification....
r6047 that.save_notebook();
fawce
added key handler for control-s to notebook, seems to work pretty well
r5990 event.preventDefault();
fawce
fixed missing return for keybinding
r5991 return false;
fawce
added key handler for control-s to notebook, seems to work pretty well
r5990 } else if (event.which === 27) {
Matthias BUSSONNIER
Intercept <esc> avoid closing websocket on Firefox...
r5389 // Intercept escape at highest level to avoid closing
// websocket connection with firefox
event.preventDefault();
}
Thomas Kluyver
Notebook: don't change cell when selecting code using shift+up/down....
r5418 if (event.which === 38 && !event.shiftKey) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 var cell = that.get_selected_cell();
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 if (cell.at_top()) {
event.preventDefault();
that.select_prev();
};
Thomas Kluyver
Notebook: don't change cell when selecting code using shift+up/down....
r5418 } else if (event.which === 40 && !event.shiftKey) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 var cell = that.get_selected_cell();
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 if (cell.at_bottom()) {
event.preventDefault();
that.select_next();
};
} else if (event.which === 13 && event.shiftKey) {
Brian E. Granger
Fixes to terminal mode execution (ctrl-enter).
r4394 that.execute_selected_cell();
Brian E. Granger
Prevent shift-enter from propagating and performing default.
r4380 return false;
Brian E. Granger
CTRL-ENTER now runs a cell in "terminal mode"...
r4390 } else if (event.which === 13 && event.ctrlKey) {
Brian E. Granger
Fixes to terminal mode execution (ctrl-enter).
r4394 that.execute_selected_cell({terminal:true});
Brian E. Granger
CTRL-ENTER now runs a cell in "terminal mode"...
r4390 return false;
Brian Granger
Fixing #1348 to allow Ctrl-M M to work w/o releasing Ctrl.
r6049 } else if (event.which === 77 && event.ctrlKey && that.control_key_active == false) {
Brian E. Granger
Adding keyboard shortcuts.
r4645 that.control_key_active = true;
return false;
Brian Granger
Adding keyboard sortcuts for cut/copy/paste.
r5880 } else if (event.which === 88 && that.control_key_active) {
// Cut selected cell = x
that.cut_cell();
that.control_key_active = false;
return false;
} else if (event.which === 67 && that.control_key_active) {
// Copy selected cell = c
that.copy_cell();
that.control_key_active = false;
return false;
} else if (event.which === 86 && that.control_key_active) {
// Paste selected cell = v
that.paste_cell();
that.control_key_active = false;
return false;
Brian E. Granger
Adding keyboard shortcuts.
r4645 } else if (event.which === 68 && that.control_key_active) {
// Delete selected cell = d
that.delete_cell();
that.control_key_active = false;
return false;
} else if (event.which === 65 && that.control_key_active) {
Fernando Perez
Fix above/below keybinding mismatch and rename api to use above/below
r4659 // Insert code cell above selected = a
Brian Granger
Refactoring of the notebooks cell management....
r5945 that.insert_cell_above('code');
Brian E. Granger
Adding keyboard shortcuts.
r4645 that.control_key_active = false;
return false;
} else if (event.which === 66 && that.control_key_active) {
Fernando Perez
Fix above/below keybinding mismatch and rename api to use above/below
r4659 // Insert code cell below selected = b
Brian Granger
Refactoring of the notebooks cell management....
r5945 that.insert_cell_below('code');
Brian E. Granger
Adding keyboard shortcuts.
r4645 that.control_key_active = false;
return false;
Brian Granger
Adding keyboard sortcuts for cut/copy/paste.
r5880 } else if (event.which === 89 && that.control_key_active) {
// To code = y
Brian E. Granger
Adding keyboard shortcuts.
r4645 that.to_code();
that.control_key_active = false;
return false;
} else if (event.which === 77 && that.control_key_active) {
// To markdown = m
that.to_markdown();
that.control_key_active = false;
return false;
Brian Granger
Updating JS part of plaintext cell handling.
r6027 } else if (event.which === 84 && that.control_key_active) {
Brian Granger
Heading/plaintext cells now wired up to toolbar UI.
r6028 // To Plaintext = t
Brian Granger
Updating JS part of plaintext cell handling.
r6027 that.to_plaintext();
Brian Granger
A first go at RST cell support in the notebook.
r6017 that.control_key_active = false;
return false;
Brian Granger
Finishing first draft of RST and heading cells.
r6019 } else if (event.which === 49 && that.control_key_active) {
// To Heading 1 = 1
that.to_heading(undefined, 1);
that.control_key_active = false;
return false;
} else if (event.which === 50 && that.control_key_active) {
// To Heading 2 = 2
that.to_heading(undefined, 2);
that.control_key_active = false;
return false;
} else if (event.which === 51 && that.control_key_active) {
// To Heading 3 = 3
that.to_heading(undefined, 3);
that.control_key_active = false;
return false;
} else if (event.which === 52 && that.control_key_active) {
// To Heading 4 = 4
that.to_heading(undefined, 4);
that.control_key_active = false;
return false;
} else if (event.which === 53 && that.control_key_active) {
// To Heading 5 = 5
that.to_heading(undefined, 5);
that.control_key_active = false;
return false;
} else if (event.which === 54 && that.control_key_active) {
// To Heading 6 = 6
that.to_heading(undefined, 6);
that.control_key_active = false;
return false;
Brian Granger
Updating JS part of plaintext cell handling.
r6027 } else if (event.which === 79 && that.control_key_active) {
// Toggle output = o
Brian E. Granger
Adding keyboard shortcuts.
r4645 that.toggle_output();
that.control_key_active = false;
return false;
} else if (event.which === 83 && that.control_key_active) {
// Save notebook = s
Brian Granger
Major refactoring of saving, notification....
r6047 that.save_notebook();
Brian E. Granger
Adding keyboard shortcuts.
r4645 that.control_key_active = false;
return false;
} else if (event.which === 74 && that.control_key_active) {
// Move cell down = j
that.move_cell_down();
that.control_key_active = false;
return false;
} else if (event.which === 75 && that.control_key_active) {
// Move cell up = k
that.move_cell_up();
that.control_key_active = false;
return false;
Brian E. Granger
Changing prev/next keyboard shortcut to use p/n.
r4648 } else if (event.which === 80 && that.control_key_active) {
// Select previous = p
Brian E. Granger
Adding keyboard shortcuts.
r4645 that.select_prev();
that.control_key_active = false;
return false;
Brian E. Granger
Changing prev/next keyboard shortcut to use p/n.
r4648 } else if (event.which === 78 && that.control_key_active) {
// Select next = n
Brian E. Granger
Adding keyboard shortcuts.
r4645 that.select_next();
that.control_key_active = false;
return false;
Fernando Perez
Keep kernel-related bindings together in code.
r5026 } else if (event.which === 76 && that.control_key_active) {
// Toggle line numbers = l
that.cell_toggle_line_numbers();
Brian E. Granger
Adding keyboard shortcut help dialog.
r4646 that.control_key_active = false;
return false;
Fernando Perez
Add C-m-{'i', '.'} as keybindings for kernel interrupt/restart.
r5018 } else if (event.which === 73 && that.control_key_active) {
// Interrupt kernel = i
Brian Granger
Major refactoring of saving, notification....
r6047 that.kernel.interrupt();
Fernando Perez
Add C-m-{'i', '.'} as keybindings for kernel interrupt/restart.
r5018 that.control_key_active = false;
return false;
} else if (event.which === 190 && that.control_key_active) {
// Restart kernel = . # matches qt console
Brian Granger
Major refactoring of saving, notification....
r6047 that.restart_kernel();
Fernando Perez
Add C-m-{'i', '.'} as keybindings for kernel interrupt/restart.
r5018 that.control_key_active = false;
return false;
Brian E. Granger
Adding keyboard shortcut help dialog.
r4646 } else if (event.which === 72 && that.control_key_active) {
// Show keyboard shortcuts = h
Brian Granger
Minor fixes to the menu shortcuts.
r5862 IPython.quick_help.show_keyboard_shortcuts();
Brian E. Granger
Adding keyboard shortcut help dialog.
r4646 that.control_key_active = false;
return false;
Brian E. Granger
Adding keyboard shortcuts.
r4645 } else if (that.control_key_active) {
that.control_key_active = false;
return true;
Brian Granger
Much improved nagivation for the notebook cells....
r4334 };
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 return true;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 });
Brian E. Granger
Pager is working again.
r4361
this.element.bind('collapse_pager', function () {
Brian E. Granger
Implemented basic notebook browser and fixed numerous bugs.
r4488 var app_height = $('div#main_app').height(); // content height
Brian E. Granger
More accuract height calculations for the pager collapse/expand.
r4362 var splitter_height = $('div#pager_splitter').outerHeight(true);
var new_height = app_height - splitter_height;
Brian E. Granger
Pager is working again.
r4361 that.element.animate({height : new_height + 'px'}, 'fast');
});
this.element.bind('expand_pager', function () {
Brian E. Granger
Implemented basic notebook browser and fixed numerous bugs.
r4488 var app_height = $('div#main_app').height(); // content height
Brian E. Granger
More accuract height calculations for the pager collapse/expand.
r4362 var splitter_height = $('div#pager_splitter').outerHeight(true);
Brian E. Granger
Pager is working again.
r4361 var pager_height = $('div#pager').outerHeight(true);
Brian E. Granger
More accuract height calculations for the pager collapse/expand.
r4362 var new_height = app_height - pager_height - splitter_height;
Brian E. Granger
Pager is working again.
r4361 that.element.animate({height : new_height + 'px'}, 'fast');
});
Brian E. Granger
Left panel is now working.
r4363
Brian E. Granger
Disabling auto-save at exit.
r4542 $(window).bind('beforeunload', function () {
Brian Granger
Implemented menu based UI using Wijmo.
r5857 // TODO: Make killing the kernel configurable.
var kill_kernel = false;
Brian E. Granger
Disabling auto-save at exit.
r4542 if (kill_kernel) {
that.kernel.kill();
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 }
MinRK
add read-only view for notebooks...
r5200 if (that.dirty && ! that.read_only) {
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 return "You have unsaved changes that will be lost if you leave this page.";
Brian E. Granger
Disabling auto-save at exit.
r4542 };
Fernando Perez
Fix bug where "don't leave" dialog was appearing when not needed in nb....
r5502 // Null is the *only* return value that will make the browser not
// pop up the "don't leave" dialog.
return null;
Brian E. Granger
Disabling auto-save at exit.
r4542 });
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian E. Granger
Improving the scrolling model.
r4364 Notebook.prototype.scroll_to_bottom = function () {
Brian Granger
Minor fixes to fonts and spacing.
r4366 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
Brian E. Granger
Improving the scrolling model.
r4364 };
Brian E. Granger
Implemented basic notebook browser and fixed numerous bugs.
r4488
Notebook.prototype.scroll_to_top = function () {
this.element.animate({scrollTop:0}, 0);
};
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 // Cell indexing, retrieval, etc.
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.get_cell_elements = function () {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 return this.element.children("div.cell");
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.get_cell_element = function (index) {
var result = null;
var e = this.get_cell_elements().eq(index);
if (e.length !== 0) {
result = e;
}
return result;
};
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 Notebook.prototype.ncells = function (cell) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 return this.get_cell_elements().length;
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 // TODO: we are often calling cells as cells()[i], which we should optimize
// to cells(i) or a new method.
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.get_cells = function () {
return this.get_cell_elements().toArray().map(function (e) {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 return $(e).data("cell");
});
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.get_cell = function (index) {
var result = null;
var ce = this.get_cell_element(index);
if (ce !== null) {
result = ce.data('cell');
}
return result;
}
Notebook.prototype.get_next_cell = function (cell) {
var result = null;
var index = this.find_cell_index(cell);
if (index !== null && index < this.ncells()) {
result = this.get_cell(index+1);
}
return result;
}
Notebook.prototype.get_prev_cell = function (cell) {
var result = null;
var index = this.find_cell_index(cell);
if (index !== null && index > 1) {
result = this.get_cell(index-1);
}
return result;
}
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 Notebook.prototype.find_cell_index = function (cell) {
var result = null;
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.get_cell_elements().filter(function (index) {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 if ($(this).data("cell") === cell) {
result = index;
};
});
return result;
};
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 Notebook.prototype.index_or_selected = function (index) {
Brian Granger
Cell splitting and merging is done!
r5898 var i;
Brian Granger
Refactoring of the notebooks cell management....
r5945 if (index === undefined || index === null) {
i = this.get_selected_index();
Brian Granger
Cell splitting and merging is done!
r5898 if (i === null) {
i = 0;
}
} else {
i = index;
}
return i;
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.get_selected_cell = function () {
var index = this.get_selected_index();
return this.get_cell(index);
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292 };
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.is_valid_cell_index = function (index) {
if (index !== null && index >= 0 && index < this.ncells()) {
return true;
} else {
return false;
Brian Granger
Initial reply handling implemented along with css fixes.
r4299 };
Brian Granger
Refactoring of the notebooks cell management....
r5945 }
Brian Granger
Initial reply handling implemented along with css fixes.
r4299
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.get_selected_index = function () {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var result = null;
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.get_cell_elements().filter(function (index) {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 if ($(this).data("cell").selected === true) {
result = index;
};
});
return result;
};
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 Notebook.prototype.cell_for_msg = function (msg_id) {
var cell_id = this.msg_cell_map[msg_id];
var result = null;
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.get_cell_elements().filter(function (index) {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 cell = $(this).data("cell");
if (cell.cell_id === cell_id) {
result = cell;
};
});
return result;
};
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian Granger
Refactoring of the notebooks cell management....
r5945 // Cell selection.
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.select = function (index) {
if (index !== undefined && index >= 0 && index < this.ncells()) {
sindex = this.get_selected_index()
Brian Granger
Lots of small notebook improvements....
r5946 if (sindex !== null && index !== sindex) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.get_cell(sindex).unselect();
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Brian Granger
Further work on the toolbar UI....
r5994 var cell = this.get_cell(index)
cell.select();
Brian Granger
Heading/plaintext cells now wired up to toolbar UI.
r6028 if (cell.cell_type === 'heading') {
Brian Granger
Major refactoring of saving, notification....
r6047 $([IPython.events]).trigger('selected_cell_type_changed.Notebook',
{'cell_type':cell.cell_type,level:cell.level}
);
Brian Granger
Heading/plaintext cells now wired up to toolbar UI.
r6028 } else {
Brian Granger
Major refactoring of saving, notification....
r6047 $([IPython.events]).trigger('selected_cell_type_changed.Notebook',
{'cell_type':cell.cell_type}
);
};
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292 return this;
};
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.select_next = function () {
var index = this.get_selected_index();
if (index !== null && index >= 0 && (index+1) < this.ncells()) {
this.select(index+1);
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 return this;
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.select_prev = function () {
var index = this.get_selected_index();
if (index !== null && index >= 0 && (index-1) < this.ncells()) {
this.select(index-1);
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 return this;
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian Granger
Refactoring of the notebooks cell management....
r5945 // Cell movement
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 Notebook.prototype.move_cell_up = function (index) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 var i = this.index_or_selected();
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 if (i !== null && i < this.ncells() && i > 0) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 var pivot = this.get_cell_element(i-1);
var tomove = this.get_cell_element(i);
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 if (pivot !== null && tomove !== null) {
tomove.detach();
pivot.before(tomove);
this.select(i-1);
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292 };
};
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = true;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 return this;
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Notebook.prototype.move_cell_down = function (index) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 var i = this.index_or_selected();
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 if (i !== null && i < (this.ncells()-1) && i >= 0) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 var pivot = this.get_cell_element(i+1);
var tomove = this.get_cell_element(i);
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 if (pivot !== null && tomove !== null) {
tomove.detach();
pivot.after(tomove);
this.select(i+1);
};
};
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = true;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 return this;
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Notebook.prototype.sort_cells = function () {
Brian Granger
Refactoring of the notebooks cell management....
r5945 // This is not working right now. Calling this will actually crash
// the browser. I think there is an infinite loop in here...
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var ncells = this.ncells();
Brian Granger
Refactoring of the notebooks cell management....
r5945 var sindex = this.get_selected_index();
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var swapped;
do {
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 swapped = false;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 for (var i=1; i<ncells; i++) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 current = this.get_cell(i);
previous = this.get_cell(i-1);
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 if (previous.input_prompt_number > current.input_prompt_number) {
this.move_cell_up(i);
swapped = true;
};
};
} while (swapped);
this.select(sindex);
return this;
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292 };
Brian Granger
Refactoring of the notebooks cell management....
r5945 // Insertion, deletion.
Brian Granger
Initial draft of HTML5/JS/CSS3 notebook.
r4292
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.delete_cell = function (index) {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var i = this.index_or_selected(index);
Brian Granger
Refactoring of the notebooks cell management....
r5945 if (this.is_valid_cell_index(i)) {
var ce = this.get_cell_element(i);
ce.remove();
if (i === (this.ncells())) {
this.select(i-1);
} else {
this.select(i);
};
this.dirty = true;
};
return this;
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian Granger
Initial reply handling implemented along with css fixes.
r4299
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.insert_cell_below = function (type, index) {
// type = ('code','html','markdown')
// index = cell index or undefined to insert below selected
index = this.index_or_selected(index);
Brian Granger
A first go at RST cell support in the notebook.
r6017 var cell = null;
Brian Granger
Refactoring of the notebooks cell management....
r5945 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
if (type === 'code') {
Brian Granger
A first go at RST cell support in the notebook.
r6017 cell = new IPython.CodeCell(this);
Brian Granger
Refactoring of the notebooks cell management....
r5945 cell.set_input_prompt();
} else if (type === 'markdown') {
Brian Granger
A first go at RST cell support in the notebook.
r6017 cell = new IPython.MarkdownCell(this);
Brian Granger
Refactoring of the notebooks cell management....
r5945 } else if (type === 'html') {
Brian Granger
A first go at RST cell support in the notebook.
r6017 cell = new IPython.HTMLCell(this);
Brian Granger
Updating JS part of plaintext cell handling.
r6027 } else if (type === 'plaintext') {
cell = new IPython.PlaintextCell(this);
Brian Granger
Finishing first draft of RST and heading cells.
r6019 } else if (type === 'heading') {
cell = new IPython.HeadingCell(this);
Brian Granger
Refactoring of the notebooks cell management....
r5945 };
if (cell !== null) {
if (this.ncells() === 0) {
this.element.find('div.end_space').before(cell.element);
} else if (this.is_valid_cell_index(index)) {
this.get_cell_element(index).after(cell.element);
};
Brian Granger
Lots of small notebook improvements....
r5946 cell.render();
this.select(this.find_cell_index(cell));
this.dirty = true;
Brian Granger
Refactoring of the notebooks cell management....
r5945 return cell;
};
};
Brian Granger
A first go at RST cell support in the notebook.
r6017 return cell;
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian E. Granger
Starting work on a Markdown cell.
r4507
Brian Granger
Refactoring of the notebooks cell management....
r5945 Notebook.prototype.insert_cell_above = function (type, index) {
// type = ('code','html','markdown')
// index = cell index or undefined to insert above selected
index = this.index_or_selected(index);
Brian Granger
A first go at RST cell support in the notebook.
r6017 var cell = null;
Brian Granger
Refactoring of the notebooks cell management....
r5945 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
if (type === 'code') {
Brian Granger
A first go at RST cell support in the notebook.
r6017 cell = new IPython.CodeCell(this);
Brian Granger
Refactoring of the notebooks cell management....
r5945 cell.set_input_prompt();
} else if (type === 'markdown') {
Brian Granger
A first go at RST cell support in the notebook.
r6017 cell = new IPython.MarkdownCell(this);
Brian Granger
Refactoring of the notebooks cell management....
r5945 } else if (type === 'html') {
Brian Granger
A first go at RST cell support in the notebook.
r6017 cell = new IPython.HTMLCell(this);
Brian Granger
Updating JS part of plaintext cell handling.
r6027 } else if (type === 'plaintext') {
cell = new IPython.PlaintextCell(this);
Brian Granger
Finishing first draft of RST and heading cells.
r6019 } else if (type === 'heading') {
cell = new IPython.HeadingCell(this);
Brian Granger
Refactoring of the notebooks cell management....
r5945 };
if (cell !== null) {
if (this.ncells() === 0) {
this.element.find('div.end_space').before(cell.element);
} else if (this.is_valid_cell_index(index)) {
this.get_cell_element(index).before(cell.element);
};
Brian Granger
Lots of small notebook improvements....
r5946 cell.render();
this.select(this.find_cell_index(cell));
this.dirty = true;
Brian Granger
Refactoring of the notebooks cell management....
r5945 return cell;
};
};
Brian Granger
A first go at RST cell support in the notebook.
r6017 return cell;
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian E. Granger
Starting work on a Markdown cell.
r4507
Notebook.prototype.to_code = function (index) {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var i = this.index_or_selected(index);
Brian Granger
Refactoring of the notebooks cell management....
r5945 if (this.is_valid_cell_index(i)) {
var source_element = this.get_cell_element(i);
var source_cell = source_element.data("cell");
if (!(source_cell instanceof IPython.CodeCell)) {
target_cell = this.insert_cell_below('code',i);
var text = source_cell.get_text();
if (text === source_cell.placeholder) {
text = '';
}
target_cell.set_text(text);
source_element.remove();
Brian Granger
A first go at RST cell support in the notebook.
r6017 this.dirty = true;
Brian Granger
Refactoring of the notebooks cell management....
r5945 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
};
Brian Granger
Initial reply handling implemented along with css fixes.
r4299
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian Granger
Refactoring of text/markdown/rst/html cells.
r4508 Notebook.prototype.to_markdown = function (index) {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var i = this.index_or_selected(index);
Brian Granger
Refactoring of the notebooks cell management....
r5945 if (this.is_valid_cell_index(i)) {
var source_element = this.get_cell_element(i);
var source_cell = source_element.data("cell");
if (!(source_cell instanceof IPython.MarkdownCell)) {
target_cell = this.insert_cell_below('markdown',i);
var text = source_cell.get_text();
if (text === source_cell.placeholder) {
Brian Granger
Lots of small notebook improvements....
r5946 text = '';
Brian Granger
Refactoring of the notebooks cell management....
r5945 };
Brian Granger
A first go at RST cell support in the notebook.
r6017 // The edit must come before the set_text.
target_cell.edit();
target_cell.set_text(text);
source_element.remove();
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.dirty = true;
Brian Granger
Updating cell logic....
r5944 };
};
Brian E. Granger
Starting work on a Markdown cell.
r4507 };
Notebook.prototype.to_html = function (index) {
var i = this.index_or_selected(index);
Brian Granger
Refactoring of the notebooks cell management....
r5945 if (this.is_valid_cell_index(i)) {
var source_element = this.get_cell_element(i);
var source_cell = source_element.data("cell");
var target_cell = null;
if (!(source_cell instanceof IPython.HTMLCell)) {
target_cell = this.insert_cell_below('html',i);
var text = source_cell.get_text();
if (text === source_cell.placeholder) {
Brian Granger
Lots of small notebook improvements....
r5946 text = '';
Brian Granger
Refactoring of the notebooks cell management....
r5945 };
Brian Granger
A first go at RST cell support in the notebook.
r6017 // The edit must come before the set_text.
target_cell.edit();
target_cell.set_text(text);
source_element.remove();
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.dirty = true;
Brian Granger
Updating cell logic....
r5944 };
};
Brian Granger
Initial reply handling implemented along with css fixes.
r4299 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian Granger
Updating JS part of plaintext cell handling.
r6027 Notebook.prototype.to_plaintext = function (index) {
Brian Granger
A first go at RST cell support in the notebook.
r6017 var i = this.index_or_selected(index);
if (this.is_valid_cell_index(i)) {
var source_element = this.get_cell_element(i);
var source_cell = source_element.data("cell");
var target_cell = null;
Brian Granger
Updating JS part of plaintext cell handling.
r6027 if (!(source_cell instanceof IPython.PlaintextCell)) {
target_cell = this.insert_cell_below('plaintext',i);
Brian Granger
A first go at RST cell support in the notebook.
r6017 var text = source_cell.get_text();
if (text === source_cell.placeholder) {
text = '';
};
// The edit must come before the set_text.
target_cell.edit();
target_cell.set_text(text);
source_element.remove();
this.dirty = true;
};
};
};
Brian Granger
Finishing first draft of RST and heading cells.
r6019
Notebook.prototype.to_heading = function (index, level) {
level = level || 1;
var i = this.index_or_selected(index);
if (this.is_valid_cell_index(i)) {
var source_element = this.get_cell_element(i);
var source_cell = source_element.data("cell");
var target_cell = null;
if (source_cell instanceof IPython.HeadingCell) {
source_cell.set_level(level);
} else {
target_cell = this.insert_cell_below('heading',i);
var text = source_cell.get_text();
if (text === source_cell.placeholder) {
text = '';
};
// The edit must come before the set_text.
target_cell.set_level(level);
target_cell.edit();
target_cell.set_text(text);
source_element.remove();
this.dirty = true;
};
Brian Granger
Major refactoring of saving, notification....
r6047 $([IPython.events]).trigger('selected_cell_type_changed.Notebook',
{'cell_type':'heading',level:level}
);
Brian Granger
Finishing first draft of RST and heading cells.
r6019 };
};
Brian Granger
Refactoring of the notebooks cell management....
r5945 // Cut/Copy/Paste
Brian Granger
Added cell level cut/copy/paste.
r5879
Notebook.prototype.enable_paste = function () {
var that = this;
Brian Granger
Minor, but important fixes to cut/copy/paste....
r5912 if (!this.paste_enabled) {
$('#paste_cell').removeClass('ui-state-disabled')
.on('click', function () {that.paste_cell();});
$('#paste_cell_above').removeClass('ui-state-disabled')
.on('click', function () {that.paste_cell_above();});
$('#paste_cell_below').removeClass('ui-state-disabled')
.on('click', function () {that.paste_cell_below();});
this.paste_enabled = true;
};
Brian Granger
Added cell level cut/copy/paste.
r5879 };
Notebook.prototype.disable_paste = function () {
Brian Granger
Minor, but important fixes to cut/copy/paste....
r5912 if (this.paste_enabled) {
$('#paste_cell').addClass('ui-state-disabled').off('click');
$('#paste_cell_above').addClass('ui-state-disabled').off('click');
$('#paste_cell_below').addClass('ui-state-disabled').off('click');
this.paste_enabled = false;
};
Brian Granger
Added cell level cut/copy/paste.
r5879 };
Notebook.prototype.cut_cell = function () {
this.copy_cell();
this.delete_cell();
}
Notebook.prototype.copy_cell = function () {
Brian Granger
Refactoring of the notebooks cell management....
r5945 var cell = this.get_selected_cell();
Brian Granger
Added cell level cut/copy/paste.
r5879 this.clipboard = cell.toJSON();
this.enable_paste();
};
Notebook.prototype.paste_cell = function () {
Brian Granger
Minor, but important fixes to cut/copy/paste....
r5912 if (this.clipboard !== null && this.paste_enabled) {
Brian Granger
Added cell level cut/copy/paste.
r5879 var cell_data = this.clipboard;
Brian Granger
Refactoring of the notebooks cell management....
r5945 var new_cell = this.insert_cell_above(cell_data.cell_type);
Brian Granger
Updating cell logic....
r5944 new_cell.fromJSON(cell_data);
Brian Granger
Refactoring of the notebooks cell management....
r5945 old_cell = this.get_next_cell(new_cell);
this.delete_cell(this.find_cell_index(old_cell));
this.select(this.find_cell_index(new_cell));
Brian Granger
Added cell level cut/copy/paste.
r5879 };
};
Notebook.prototype.paste_cell_above = function () {
Brian Granger
Minor, but important fixes to cut/copy/paste....
r5912 if (this.clipboard !== null && this.paste_enabled) {
Brian Granger
Added cell level cut/copy/paste.
r5879 var cell_data = this.clipboard;
Brian Granger
Refactoring of the notebooks cell management....
r5945 var new_cell = this.insert_cell_above(cell_data.cell_type);
Brian Granger
Updating cell logic....
r5944 new_cell.fromJSON(cell_data);
Brian Granger
Added cell level cut/copy/paste.
r5879 };
};
Notebook.prototype.paste_cell_below = function () {
Brian Granger
Minor, but important fixes to cut/copy/paste....
r5912 if (this.clipboard !== null && this.paste_enabled) {
Brian Granger
Added cell level cut/copy/paste.
r5879 var cell_data = this.clipboard;
Brian Granger
Refactoring of the notebooks cell management....
r5945 var new_cell = this.insert_cell_below(cell_data.cell_type);
Brian Granger
Updating cell logic....
r5944 new_cell.fromJSON(cell_data);
Brian Granger
Added cell level cut/copy/paste.
r5879 };
};
Brian Granger
Refactoring of the notebooks cell management....
r5945 // Split/merge
Brian Granger
More of the initial split cell capability.
r5897 Notebook.prototype.split_cell = function () {
Brian Granger
Cell splitting and merging is done!
r5898 // Todo: implement spliting for other cell types.
Brian Granger
Refactoring of the notebooks cell management....
r5945 var cell = this.get_selected_cell();
Brian Granger
Lots of small notebook improvements....
r5946 if (cell.is_splittable()) {
texta = cell.get_pre_cursor();
textb = cell.get_post_cursor();
if (cell instanceof IPython.CodeCell) {
cell.set_text(texta);
var new_cell = this.insert_cell_below('code');
new_cell.set_text(textb);
} else if (cell instanceof IPython.MarkdownCell) {
cell.set_text(texta);
cell.render();
var new_cell = this.insert_cell_below('markdown');
new_cell.edit(); // editor must be visible to call set_text
new_cell.set_text(textb);
new_cell.render();
} else if (cell instanceof IPython.HTMLCell) {
cell.set_text(texta);
cell.render();
var new_cell = this.insert_cell_below('html');
new_cell.edit(); // editor must be visible to call set_text
new_cell.set_text(textb);
new_cell.render();
};
Brian Granger
More of the initial split cell capability.
r5897 };
};
Brian Granger
Cell splitting and merging is done!
r5898
Notebook.prototype.merge_cell_above = function () {
Brian Granger
Refactoring of the notebooks cell management....
r5945 var index = this.get_selected_index();
Brian Granger
Lots of small notebook improvements....
r5946 var cell = this.get_cell(index);
Brian Granger
Cell splitting and merging is done!
r5898 if (index > 0) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 upper_cell = this.get_cell(index-1);
Brian Granger
Lots of small notebook improvements....
r5946 upper_text = upper_cell.get_text();
text = cell.get_text();
if (cell instanceof IPython.CodeCell) {
cell.set_text(upper_text+'\n'+text);
} else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
cell.edit();
cell.set_text(upper_text+'\n'+text);
cell.render();
Brian Granger
Cell splitting and merging is done!
r5898 };
Brian Granger
Lots of small notebook improvements....
r5946 this.delete_cell(index-1);
this.select(this.find_cell_index(cell));
Brian Granger
Cell splitting and merging is done!
r5898 };
};
Notebook.prototype.merge_cell_below = function () {
Brian Granger
Refactoring of the notebooks cell management....
r5945 var index = this.get_selected_index();
Brian Granger
Lots of small notebook improvements....
r5946 var cell = this.get_cell(index);
Brian Granger
Cell splitting and merging is done!
r5898 if (index < this.ncells()-1) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 lower_cell = this.get_cell(index+1);
Brian Granger
Lots of small notebook improvements....
r5946 lower_text = lower_cell.get_text();
text = cell.get_text();
if (cell instanceof IPython.CodeCell) {
cell.set_text(text+'\n'+lower_text);
} else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
cell.edit();
cell.set_text(text+'\n'+lower_text);
cell.render();
Brian Granger
Cell splitting and merging is done!
r5898 };
Brian Granger
Lots of small notebook improvements....
r5946 this.delete_cell(index+1);
this.select(this.find_cell_index(cell));
Brian Granger
Cell splitting and merging is done!
r5898 };
};
Brian Granger
Fixing auto-indent issues in CodeMirror config....
r5959
Brian E. Granger
Clear all output is implemented.
r4543 // Cell collapsing and output clearing
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Notebook.prototype.collapse = function (index) {
var i = this.index_or_selected(index);
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.get_cell(i).collapse();
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = true;
Brian Granger
Initial reply handling implemented along with css fixes.
r4299 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 Notebook.prototype.expand = function (index) {
var i = this.index_or_selected(index);
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.get_cell(i).expand();
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = true;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Brian Granger
Basic notebook saving and loading....
r4315
Brian E. Granger
Cell collapse/expand is not called "Toggle".
r4639 Notebook.prototype.toggle_output = function (index) {
var i = this.index_or_selected(index);
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.get_cell(i).toggle_output();
Brian E. Granger
Cell collapse/expand is not called "Toggle".
r4639 this.dirty = true;
};
Matthias BUSSONNIER
Make the time before activating a tooltip configurable...
r5400 Notebook.prototype.set_timebeforetooltip = function (time) {
this.time_before_tooltip = time;
};
Brian Granger
Fixing auto-indent issues in CodeMirror config....
r5959
Matthias BUSSONNIER
Improve tooltip tringgering,make it configurable...
r5399 Notebook.prototype.set_tooltipontab = function (state) {
this.tooltip_on_tab = state;
};
Brian Granger
Fixing auto-indent issues in CodeMirror config....
r5959
Matthias BUSSONNIER
smart kwarg completion...
r5401 Notebook.prototype.set_smartcompleter = function (state) {
this.smart_completer = state;
};
Brian E. Granger
Clear all output is implemented.
r4543
Notebook.prototype.clear_all_output = function () {
var ncells = this.ncells();
Brian Granger
Refactoring of the notebooks cell management....
r5945 var cells = this.get_cells();
Brian E. Granger
Clear all output is implemented.
r4543 for (var i=0; i<ncells; i++) {
if (cells[i] instanceof IPython.CodeCell) {
MinRK
add channel-selection to clear_output...
r5085 cells[i].clear_output(true,true,true);
Brian E. Granger
Clear all output is implemented.
r4543 }
};
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = true;
Brian E. Granger
Clear all output is implemented.
r4543 };
Brian Granger
Fixing auto-indent issues in CodeMirror config....
r5959
Fernando Perez
Refactor line num. toggle into proper function, access via C-m-l....
r5020 // Other cell functions: line numbers, ...
Notebook.prototype.cell_toggle_line_numbers = function() {
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.get_selected_cell().toggle_line_numbers();
Fernando Perez
Refactor line num. toggle into proper function, access via C-m-l....
r5020 };
Brian E. Granger
Clear all output is implemented.
r4543
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 // Kernel related things
Brian Granger
Basic notebook saving and loading....
r4315
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 Notebook.prototype.start_kernel = function () {
this.kernel = new IPython.Kernel();
Brian Granger
Major refactoring of saving, notification....
r6047 this.kernel.start(this.notebook_id, $.proxy(this.kernel_started, this));
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 };
Notebook.prototype.restart_kernel = function () {
Fernando Perez
Clean up accidentally introduced hard tabs in JS code.
r5025 var that = this;
Fernando Perez
Add confirmation dialog to kernel restart action.
r5021 var dialog = $('<div/>');
dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.');
$(document).append(dialog);
dialog.dialog({
resizable: false,
modal: true,
title: "Restart kernel or continue running?",
Brian Granger
Cleaning up menu code....
r5858 closeText: '',
Fernando Perez
Add confirmation dialog to kernel restart action.
r5021 buttons : {
"Restart": function () {
Fernando Perez
Clean up accidentally introduced hard tabs in JS code.
r5025 that.kernel.restart($.proxy(that.kernel_started, that));
Fernando Perez
Add confirmation dialog to kernel restart action.
r5021 $(this).dialog('close');
},
"Continue running": function () {
$(this).dialog('close');
}
}
});
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 };
Notebook.prototype.kernel_started = function () {
console.log("Kernel started: ", this.kernel.kernel_id);
this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
Brian Granger
Basic notebook saving and loading....
r4315 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian E. Granger
Using $.proxy to clean up callbacks.
r4353 Notebook.prototype.handle_shell_reply = function (e) {
reply = $.parseJSON(e.data);
Brian E. Granger
Initial payload handling....
r4356 var header = reply.header;
var content = reply.content;
var msg_type = header.msg_type;
Brian E. Granger
Initial draft of panel section and the cell section working.
r4365 // console.log(reply);
Brian E. Granger
Using $.proxy to clean up callbacks.
r4353 var cell = this.cell_for_msg(reply.parent_header.msg_id);
if (msg_type === "execute_reply") {
Brian E. Granger
Initial payload handling....
r4356 cell.set_input_prompt(content.execution_count);
MinRK
add 'running' class to running code cells...
r5221 cell.element.removeClass("running");
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = true;
Brian Granger
Added complete method of JS kernel object.
r4388 } else if (msg_type === "complete_reply") {
Brian E. Granger
Autocompletion working with CTRL-SPACE.
r4389 cell.finish_completing(content.matched_text, content.matches);
Matthias BUSSONNIER
Add Tootip to notebook....
r5397 } else if (msg_type === "object_info_reply"){
//console.log('back from object_info_request : ')
rep = reply.content;
if(rep.found)
{
Matthias BUSSONNIER
add 'more...' and 'close' button to the pager...
r5404 cell.finish_tooltip(rep);
Matthias BUSSONNIER
Add Tootip to notebook....
r5397 }
} else {
//console.log("unknown reply:"+msg_type);
}
// when having a rely from object_info_reply,
// no payload so no nned to handle it
if(typeof(content.payload)!='undefined') {
var payload = content.payload || [];
this.handle_payload(cell, payload);
}
Brian E. Granger
Using $.proxy to clean up callbacks.
r4353 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian E. Granger
%loadpy works in the notebook and bug with inline plotting fixed.
r4530 Notebook.prototype.handle_payload = function (cell, payload) {
Brian E. Granger
Initial payload handling....
r4356 var l = payload.length;
for (var i=0; i<l; i++) {
Brian E. Granger
%loadpy works in the notebook and bug with inline plotting fixed.
r4530 if (payload[i].source === 'IPython.zmq.page.page') {
Brian E. Granger
Pager is not activated if the pager text is empty....
r4560 if (payload[i].text.trim() !== '') {
IPython.pager.clear();
IPython.pager.expand();
IPython.pager.append_text(payload[i].text);
}
Brian E. Granger
%loadpy works in the notebook and bug with inline plotting fixed.
r4530 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
var index = this.find_cell_index(cell);
Brian Granger
Refactoring of the notebooks cell management....
r5945 var new_cell = this.insert_cell_below('code',index);
Brian Granger
Work on the base Cell API....
r5943 new_cell.set_text(payload[i].text);
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = true;
Brian E. Granger
%loadpy works in the notebook and bug with inline plotting fixed.
r4530 }
Brian E. Granger
Initial payload handling....
r4356 };
};
Brian E. Granger
Refactoring pager into its own class.
r4357
Brian E. Granger
Using $.proxy to clean up callbacks.
r4353 Notebook.prototype.handle_iopub_reply = function (e) {
reply = $.parseJSON(e.data);
var content = reply.content;
// console.log(reply);
var msg_type = reply.header.msg_type;
var cell = this.cell_for_msg(reply.parent_header.msg_id);
MinRK
fix IOPub parent checking in notebook...
r5777 if (msg_type !== 'status' && !cell){
// message not from this notebook, but should be attached to a cell
Brian Granger
Major refactoring of saving, notification....
r6047 // console.log("Received IOPub message not caused by one of my cells");
// console.log(reply);
MinRK
explicitly ignore iopub messages not associated with a cell in the notebook...
r5363 return;
}
Brian E. Granger
Added saving and loading of output of all types.
r4497 var output_types = ['stream','display_data','pyout','pyerr'];
if (output_types.indexOf(msg_type) >= 0) {
this.handle_output(cell, msg_type, content);
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 } else if (msg_type === 'status') {
if (content.execution_state === 'busy') {
Brian Granger
Major refactoring of saving, notification....
r6047 $([IPython.events]).trigger('status_busy.Kernel');
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 } else if (content.execution_state === 'idle') {
Brian Granger
Major refactoring of saving, notification....
r6047 $([IPython.events]).trigger('status_idle.Kernel');
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 } else if (content.execution_state === 'dead') {
this.handle_status_dead();
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Brian Granger
Adding clear_output to kernel and HTML notebook.
r5080 } else if (msg_type === 'clear_output') {
MinRK
add channel-selection to clear_output...
r5085 cell.clear_output(content.stdout, content.stderr, content.other);
Brian Granger
Adding clear_output to kernel and HTML notebook.
r5080 };
Brian E. Granger
Using $.proxy to clean up callbacks.
r4353 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian E. Granger
Using $.proxy to clean up callbacks.
r4353
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 Notebook.prototype.handle_status_dead = function () {
var that = this;
this.kernel.stop_channels();
var dialog = $('<div/>');
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.');
$(document).append(dialog);
dialog.dialog({
resizable: false,
modal: true,
title: "Dead kernel",
buttons : {
Fernando Perez
Change button labels in restart dialog to action words.
r5022 "Restart": function () {
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 that.start_kernel();
$(this).dialog('close');
},
Fernando Perez
Change button labels in restart dialog to action words.
r5022 "Continue running": function () {
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 $(this).dialog('close');
}
}
});
};
Brian E. Granger
Added saving and loading of output of all types.
r4497 Notebook.prototype.handle_output = function (cell, msg_type, content) {
var json = {};
json.output_type = msg_type;
if (msg_type === "stream") {
MinRK
don't preserve fixConsole output in json
r5813 json.text = content.data;
MinRK
support contiguous stream output in notebook...
r4864 json.stream = content.name;
Brian E. Granger
Added saving and loading of output of all types.
r4497 } else if (msg_type === "display_data") {
json = this.convert_mime_types(json, content.data);
} else if (msg_type === "pyout") {
json.prompt_number = content.execution_count;
json = this.convert_mime_types(json, content.data);
} else if (msg_type === "pyerr") {
json.ename = content.ename;
json.evalue = content.evalue;
MinRK
don't preserve fixConsole output in json
r5813 json.traceback = content.traceback;
Brian E. Granger
Added saving and loading of output of all types.
r4497 };
Brian Granger
Javascript output is not run on notebook loading and paste's.
r6084 // append with dynamic=true
cell.append_output(json, true);
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = true;
Brian E. Granger
Added saving and loading of output of all types.
r4497 };
Notebook.prototype.convert_mime_types = function (json, data) {
if (data['text/plain'] !== undefined) {
MinRK
don't preserve fixConsole output in json
r5813 json.text = data['text/plain'];
Brian E. Granger
Added saving and loading of output of all types.
r4497 };
if (data['text/html'] !== undefined) {
json.html = data['text/html'];
};
if (data['image/svg+xml'] !== undefined) {
json.svg = data['image/svg+xml'];
};
if (data['image/png'] !== undefined) {
json.png = data['image/png'];
};
Brian E. Granger
Finishing display system work....
r4528 if (data['image/jpeg'] !== undefined) {
json.jpeg = data['image/jpeg'];
};
Brian E. Granger
Added saving and loading of output of all types.
r4497 if (data['text/latex'] !== undefined) {
json.latex = data['text/latex'];
};
if (data['application/json'] !== undefined) {
json.json = data['application/json'];
};
if (data['application/javascript'] !== undefined) {
json.javascript = data['application/javascript'];
}
return json;
};
Brian Granger
Basic notebook saving and loading....
r4315
Brian E. Granger
Fixes to terminal mode execution (ctrl-enter).
r4394 Notebook.prototype.execute_selected_cell = function (options) {
// add_new: should a new cell be added if we are at the end of the nb
// terminal: execute in terminal mode, which stays in the current cell
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 default_options = {terminal: false, add_new: true};
$.extend(default_options, options);
Brian E. Granger
Fixing execution related things....
r4378 var that = this;
Brian Granger
Refactoring of the notebooks cell management....
r5945 var cell = that.get_selected_cell();
Brian E. Granger
Fixing execution related things....
r4378 var cell_index = that.find_cell_index(cell);
if (cell instanceof IPython.CodeCell) {
MinRK
add channel-selection to clear_output...
r5085 cell.clear_output(true, true, true);
MinRK
set 'In [*]' to indicate pending code cell
r5220 cell.set_input_prompt('*');
MinRK
add 'running' class to running code cells...
r5221 cell.element.addClass("running");
Brian Granger
Work on the base Cell API....
r5943 var code = cell.get_text();
var msg_id = that.kernel.execute(cell.get_text());
Brian E. Granger
Massive work on the notebook document format....
r4484 that.msg_cell_map[msg_id] = cell.cell_id;
Brian E. Granger
New HTMl cell working with CodeMirror editing.
r4499 } else if (cell instanceof IPython.HTMLCell) {
Brian E. Granger
Fixing execution related things....
r4378 cell.render();
}
Brian E. Granger
Fixes to terminal mode execution (ctrl-enter).
r4394 if (default_options.terminal) {
Brian E. Granger
Ctrl-Enter now does not delete input, but selects it.
r4675 cell.select_all();
Brian E. Granger
Fixing execution related things....
r4378 } else {
Brian E. Granger
Fixes to terminal mode execution (ctrl-enter).
r4394 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 that.insert_cell_below('code');
Brian E. Granger
Fixes to terminal mode execution (ctrl-enter).
r4394 // If we are adding a new cell at the end, scroll down to show it.
that.scroll_to_bottom();
} else {
that.select(cell_index+1);
};
Brian E. Granger
Fixing execution related things....
r4378 };
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = true;
Brian E. Granger
Fixing execution related things....
r4378 };
Notebook.prototype.execute_all_cells = function () {
var ncells = this.ncells();
for (var i=0; i<ncells; i++) {
this.select(i);
Matthias BUSSONNIER
execute_get_cell -> execute_cell...
r5967 this.execute_selected_cell({add_new:false});
Brian E. Granger
Fixing execution related things....
r4378 };
this.scroll_to_bottom();
};
Brian E. Granger
Autocompletion working with CTRL-SPACE.
r4389
Matthias BUSSONNIER
Add Tootip to notebook....
r5397 Notebook.prototype.request_tool_tip = function (cell,func) {
Matthias BUSSONNIER
Improve tooltip tringgering,make it configurable...
r5399 // Feel free to shorten this logic if you are better
// than me in regEx
// basicaly you shoul be able to get xxx.xxx.xxx from
// something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2,
// remove everything between matchin bracket (need to iterate)
matchBracket = /\([^\(\)]+\)/g;
oldfunc = func;
func = func.replace(matchBracket,"");
while( oldfunc != func )
{
oldfunc = func;
func = func.replace(matchBracket,"");
}
// remove everythin after last open bracket
endBracket = /\([^\(]*$/g;
func = func.replace(endBracket,"");
Matthias BUSSONNIER
Add Tootip to notebook....
r5397 var re = /[a-zA-Z._]+$/g;
Matthias BUSSONNIER
tooltip on <tab>
r5398 var msg_id = this.kernel.object_info_request(re.exec(func));
Matthias BUSSONNIER
handle null objectname on tooltip
r5409 if(typeof(msg_id)!='undefined'){
this.msg_cell_map[msg_id] = cell.cell_id;
}
Matthias BUSSONNIER
Add Tootip to notebook....
r5397 };
Brian E. Granger
Autocompletion working with CTRL-SPACE.
r4389 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
var msg_id = this.kernel.complete(line, cursor_pos);
this.msg_cell_map[msg_id] = cell.cell_id;
};
Brian Granger
Major refactoring of saving, notification....
r6047
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 // Persistance and loading
Brian Granger
Major refactoring of saving, notification....
r6047 Notebook.prototype.get_notebook_id = function () {
return this.notebook_id;
};
Notebook.prototype.get_notebook_name = function () {
return this.notebook_name;
};
Notebook.prototype.set_notebook_name = function (name) {
this.notebook_name = name;
};
Notebook.prototype.test_notebook_name = function (nbname) {
nbname = nbname || '';
if (this.notebook_name_blacklist_re.test(nbname) == false && nbname.length>0) {
return true;
} else {
return false;
};
};
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Notebook.prototype.fromJSON = function (data) {
var ncells = this.ncells();
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 var i;
for (i=0; i<ncells; i++) {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 // Always delete cell 0 as they get renumbered as they are deleted.
this.delete_cell(0);
};
Brian Granger
Major refactoring of saving, notification....
r6047 // Save the metadata and name.
Brian E. Granger
Implemented metadata for notebook format.
r4637 this.metadata = data.metadata;
Brian Granger
Major refactoring of saving, notification....
r6047 this.notebook_name = data.metadata.name;
Brian E. Granger
Massive work on the notebook document format....
r4484 // Only handle 1 worksheet for now.
var worksheet = data.worksheets[0];
if (worksheet !== undefined) {
var new_cells = worksheet.cells;
ncells = new_cells.length;
var cell_data = null;
Brian E. Granger
Implemented basic notebook browser and fixed numerous bugs.
r4488 var new_cell = null;
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 for (i=0; i<ncells; i++) {
Brian E. Granger
Massive work on the notebook document format....
r4484 cell_data = new_cells[i];
Brian Granger
Refactoring of the notebooks cell management....
r5945 new_cell = this.insert_cell_below(cell_data.cell_type);
new_cell.fromJSON(cell_data);
Brian Granger
Added cell level cut/copy/paste.
r5879 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Brian Granger
Basic notebook saving and loading....
r4315 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Notebook.prototype.toJSON = function () {
Brian Granger
Refactoring of the notebooks cell management....
r5945 var cells = this.get_cells();
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var ncells = cells.length;
cell_array = new Array(ncells);
for (var i=0; i<ncells; i++) {
cell_array[i] = cells[i].toJSON();
};
Brian E. Granger
Massive work on the notebook document format....
r4484 data = {
// Only handle 1 worksheet for now.
Brian E. Granger
Implemented metadata for notebook format.
r4637 worksheets : [{cells:cell_array}],
metadata : this.metadata
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
return data;
Brian E. Granger
Massive work on the notebook document format....
r4484 };
Notebook.prototype.save_notebook = function () {
Brian Granger
Fixing broken notebook saves.
r5958 // We may want to move the name/id/nbformat logic inside toJSON?
var data = this.toJSON();
Brian Granger
Major refactoring of saving, notification....
r6047 data.metadata.name = this.notebook_name;
Brian Granger
Proper error handling for nbformat versions in client code....
r6061 data.nbformat = this.nbformat;
Brian Granger
Fixing broken notebook saves.
r5958 // We do the call with settings so we can set cache to false.
var settings = {
processData : false,
cache : false,
type : "PUT",
data : JSON.stringify(data),
headers : {'Content-Type': 'application/json'},
Brian Granger
Proper error handling for nbformat versions in client code....
r6061 success : $.proxy(this.save_notebook_success,this),
error : $.proxy(this.save_notebook_error,this)
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Brian Granger
Major refactoring of saving, notification....
r6047 $([IPython.events]).trigger('notebook_saving.Notebook');
var url = $('body').data('baseProjectUrl') + 'notebooks/' + this.notebook_id;
Brian Granger
Fixing broken notebook saves.
r5958 $.ajax(url, settings);
Brian Granger
Basic notebook saving and loading....
r4315 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian Granger
Proper error handling for nbformat versions in client code....
r6061 Notebook.prototype.save_notebook_success = function (data, status, xhr) {
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = false;
Brian Granger
Major refactoring of saving, notification....
r6047 $([IPython.events]).trigger('notebook_saved.Notebook');
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian Granger
Proper error handling for nbformat versions in client code....
r6061 Notebook.prototype.save_notebook_error = function (xhr, status, error_msg) {
Brian Granger
Major refactoring of saving, notification....
r6047 $([IPython.events]).trigger('notebook_save_failed.Notebook');
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Felix Werner
Notify the user of errors when saving a notebook.
r5007
Brian Granger
Major refactoring of saving, notification....
r6047 Notebook.prototype.load_notebook = function (notebook_id) {
Brian E. Granger
Implemented basic notebook browser and fixed numerous bugs.
r4488 var that = this;
Brian Granger
Major refactoring of saving, notification....
r6047 this.notebook_id = notebook_id;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 // We do the call with settings so we can set cache to false.
var settings = {
Brian E. Granger
Implemented basic notebook browser and fixed numerous bugs.
r4488 processData : false,
cache : false,
type : "GET",
dataType : "json",
Brian Granger
Proper error handling for nbformat versions in client code....
r6061 success : $.proxy(this.load_notebook_success,this),
error : $.proxy(this.load_notebook_error,this),
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Brian Granger
Major refactoring of saving, notification....
r6047 $([IPython.events]).trigger('notebook_loading.Notebook');
var url = $('body').data('baseProjectUrl') + 'notebooks/' + this.notebook_id;
Brian E. Granger
Updating JS URL scheme to use embedded data....
r5106 $.ajax(url, settings);
Stefan van der Walt
Clean up javascript based on js2-mode feedback.
r5479 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian E. Granger
Massive work on the notebook document format....
r4484
Brian Granger
Major refactoring of saving, notification....
r6047 Notebook.prototype.load_notebook_success = function (data, status, xhr) {
Brian E. Granger
Massive work on the notebook document format....
r4484 this.fromJSON(data);
if (this.ncells() === 0) {
Brian Granger
Refactoring of the notebooks cell management....
r5945 this.insert_cell_below('code');
Brian E. Granger
Massive work on the notebook document format....
r4484 };
Brian E. Granger
Added a notebook dirty flag that is used when exiting page.
r4550 this.dirty = false;
MinRK
move read_only flag to page-level...
r5213 if (! this.read_only) {
MinRK
add read-only view for notebooks...
r5200 this.start_kernel();
}
Brian Granger
Optimizing notebook loading.
r5949 this.select(0);
Brian Granger
Fixing bugs in CodeMirror refreshing.
r5950 this.scroll_to_top();
Brian Granger
Proper error handling for nbformat versions in client code....
r6061 if (data.orig_nbformat !== undefined && data.nbformat !== data.orig_nbformat) {
msg = "This notebook has been converted from an older " +
"notebook format (v"+data.orig_nbformat+") to the current notebook " +
"format (v"+data.nbformat+"). The next time you save this notebook, the " +
"newer notebook format will be used and older verions of IPython " +
"may not be able to read it. To keep the older version, close the " +
"notebook without saving it.";
var dialog = $('<div/>');
dialog.html(msg);
this.element.append(dialog);
dialog.dialog({
resizable: false,
modal: true,
title: "Notebook converted",
closeText: "",
close: function(event, ui) {$(this).dialog('destroy').remove();},
buttons : {
"OK": function () {
$(this).dialog('close');
}
},
width: 400
});
}
Brian Granger
Major refactoring of saving, notification....
r6047 $([IPython.events]).trigger('notebook_loaded.Notebook');
Brian E. Granger
Massive work on the notebook document format....
r4484 };
Brian Granger
Proper error handling for nbformat versions in client code....
r6061
Notebook.prototype.load_notebook_error = function (xhr, textStatus, errorThrow) {
if (xhr.status === 500) {
msg = "An error occurred while loading this notebook. Most likely " +
"this notebook is in a newer format than is supported by this " +
"version of IPython. This version can load notebook formats " +
"v"+this.nbformat+" or earlier.";
var dialog = $('<div/>');
dialog.html(msg);
this.element.append(dialog);
dialog.dialog({
resizable: false,
modal: true,
title: "Error loading notebook",
closeText: "",
close: function(event, ui) {$(this).dialog('destroy').remove();},
buttons : {
"OK": function () {
$(this).dialog('close');
}
},
width: 400
});
}
}
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 IPython.Notebook = Notebook;
Brian E. Granger
Further work updating JS URL scheme to use data-base-project-url.
r5108
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 return IPython;
}(IPython));
Brian Granger
Basic notebook saving and loading....
r4315