├── .gitignore ├── LICENSE ├── README.md ├── bower.json ├── demo.gif ├── main.js ├── scratchpad.css └── scratchpad.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | #Jupyter Notebook 62 | *~ 63 | .ipynb_checkpoints 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Min RK 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of nbextension-scratchpad nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scratchpad notebook extension 2 | 3 | Adds a scratchpad cell to Jupyter notebook. 4 | This is a cell in which you can execute code against the current kernel without modifying the notebook document. 5 | 6 | The scratchpad can be toggled by clicking the icon in the bottom-right, 7 | or via the keyboard shortcut `Ctrl-B`. 8 | 9 | ![demo](demo.gif) 10 | 11 | 12 | ## Install 13 | 14 | You can install with bower: 15 | 16 | ```bash 17 | bower install --config.directory="$(jupyter --data-dir)/nbextensions" nbextension-scratchpad 18 | ``` 19 | 20 | Or clone the repo manually: 21 | 22 | ```bash 23 | git clone git://github.com/minrk/nbextension-scratchpad 24 | jupyter nbextension install nbextension-scratchpad 25 | ``` 26 | 27 | And enable the extension: 28 | 29 | ```bash 30 | jupyter nbextension enable nbextension-scratchpad/main 31 | ``` 32 | 33 | You can disable the extension again: 34 | 35 | ```bash 36 | jupyter nbextension disable nbextension-scratchpad/main 37 | ``` 38 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nbextension-scratchpad", 3 | "authors": [ 4 | "Min RK " 5 | ], 6 | "description": "scratchpad extension for jupyter notebook", 7 | "main": "main.js", 8 | "moduleType": [ 9 | "amd" 10 | ], 11 | "keywords": [ 12 | "jupyter", 13 | "nbextension" 14 | ], 15 | "license": "BSD", 16 | "homepage": "https://github.com/minrk/nbextension-scratchpad", 17 | "ignore": [ 18 | "**/.*", 19 | "node_modules", 20 | "bower_components", 21 | "test", 22 | "tests" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minrk/nbextension-scratchpad/e92fa23c6c4222247722f97d0ee34013f80faa0f/demo.gif -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'require', 3 | 'jquery', 4 | 'base/js/namespace', 5 | 'base/js/events', 6 | 'base/js/utils', 7 | 'notebook/js/codecell', 8 | ], function ( 9 | requirejs, 10 | $, 11 | Jupyter, 12 | events, 13 | utils, 14 | codecell 15 | ) { 16 | "use strict"; 17 | var CodeCell = codecell.CodeCell; 18 | 19 | var Scratchpad = function (nb) { 20 | var scratchpad = this; 21 | this.notebook = nb; 22 | this.kernel = nb.kernel; 23 | this.km = nb.keyboard_manager; 24 | this.collapsed = true; 25 | 26 | // create elements 27 | this.element = $("
"); 28 | this.close_button = $("").addClass("fa fa-caret-square-o-down scratchpad-btn scratchpad-close"); 29 | this.open_button = $("").addClass("fa fa-caret-square-o-up scratchpad-btn scratchpad-open"); 30 | this.element.append(this.close_button); 31 | this.element.append(this.open_button); 32 | this.open_button.click(function () { 33 | scratchpad.expand(); 34 | }); 35 | this.close_button.click(function () { 36 | scratchpad.collapse(); 37 | }); 38 | 39 | // create my cell 40 | var cell = this.cell = new CodeCell(nb.kernel, { 41 | events: nb.events, 42 | config: nb.config, 43 | keyboard_manager: nb.keyboard_manager, 44 | notebook: nb, 45 | tooltip: nb.tooltip, 46 | }); 47 | cell.set_input_prompt(); 48 | this.element.append($("
").addClass('cell-wrapper').append(this.cell.element)); 49 | cell.render(); 50 | cell.refresh(); 51 | this.collapse(); 52 | 53 | // override ctrl/shift-enter to execute me if I'm focused instead of the notebook's cell 54 | var execute_and_select_action = this.km.actions.register({ 55 | handler: $.proxy(this.execute_and_select_event, this), 56 | }, 'scratchpad-execute-and-select'); 57 | var execute_action = this.km.actions.register({ 58 | handler: $.proxy(this.execute_event, this), 59 | }, 'scratchpad-execute'); 60 | var toggle_action = this.km.actions.register({ 61 | handler: $.proxy(this.toggle, this), 62 | }, 'scratchpad-toggle'); 63 | 64 | var shortcuts = { 65 | 'shift-enter': execute_and_select_action, 66 | 'ctrl-enter': execute_action, 67 | 'ctrl-b': toggle_action, 68 | } 69 | this.km.edit_shortcuts.add_shortcuts(shortcuts); 70 | this.km.command_shortcuts.add_shortcuts(shortcuts); 71 | 72 | // finally, add me to the page 73 | $("body").append(this.element); 74 | }; 75 | 76 | Scratchpad.prototype.toggle = function () { 77 | if (this.collapsed) { 78 | this.expand(); 79 | } else { 80 | this.collapse(); 81 | } 82 | return false; 83 | }; 84 | 85 | Scratchpad.prototype.expand = function () { 86 | this.collapsed = false; 87 | var site_height = $("#site").height(); 88 | this.element.animate({ 89 | height: site_height, 90 | }, 200); 91 | this.open_button.hide(); 92 | this.close_button.show(); 93 | this.cell.element.show(); 94 | this.cell.focus_editor(); 95 | $("#notebook-container").css('margin-left', 0); 96 | }; 97 | 98 | Scratchpad.prototype.collapse = function () { 99 | this.collapsed = true; 100 | $("#notebook-container").css('margin-left', 'auto'); 101 | this.element.animate({ 102 | height: 0, 103 | }, 100); 104 | this.close_button.hide(); 105 | this.open_button.show(); 106 | this.cell.element.hide(); 107 | }; 108 | 109 | Scratchpad.prototype.execute_and_select_event = function (evt) { 110 | if (utils.is_focused(this.element)) { 111 | this.cell.execute(); 112 | } else { 113 | this.notebook.execute_cell_and_select_below(); 114 | } 115 | }; 116 | 117 | Scratchpad.prototype.execute_event = function (evt) { 118 | if (utils.is_focused(this.element)) { 119 | this.cell.execute(); 120 | } else { 121 | this.notebook.execute_selected_cells(); 122 | } 123 | }; 124 | 125 | function setup_scratchpad () { 126 | // lazy, hook it up to Jupyter.notebook as the handle on all the singletons 127 | console.log("Setting up scratchpad"); 128 | return new Scratchpad(Jupyter.notebook); 129 | } 130 | 131 | function load_extension () { 132 | // add css 133 | var link = document.createElement("link"); 134 | link.type = "text/css"; 135 | link.rel = "stylesheet"; 136 | link.href = requirejs.toUrl("./scratchpad.css"); 137 | document.getElementsByTagName("head")[0].appendChild(link); 138 | // load when the kernel's ready 139 | if (Jupyter.notebook.kernel) { 140 | setup_scratchpad(); 141 | } else { 142 | events.on('kernel_ready.Kernel', setup_scratchpad); 143 | } 144 | } 145 | 146 | return { 147 | load_ipython_extension: load_extension, 148 | }; 149 | }); -------------------------------------------------------------------------------- /scratchpad.css: -------------------------------------------------------------------------------- 1 | #nbextension-scratchpad { 2 | position: absolute; 3 | right: 0; 4 | bottom: 0; 5 | width: 50%; 6 | background-color: #F8F5E1; 7 | border-left: 1px solid #aaa; 8 | border-top: 1px solid #aaa; 9 | z-index: 105; 10 | } 11 | 12 | #nbextension-scratchpad .cell-wrapper { 13 | height: 100%; 14 | overflow: auto; 15 | } 16 | 17 | .scratchpad-btn { 18 | float: right; 19 | margin-right: 24px; 20 | opacity: 0.2; 21 | font-size: 24px; 22 | z-index: 106; 23 | } 24 | 25 | .scratchpad-btn:hover { 26 | opacity: 1; 27 | } 28 | 29 | .scratchpad-close { 30 | display: none; 31 | position: absolute; 32 | float: right; 33 | bottom: 8px; 34 | right: 0; 35 | } 36 | 37 | .scratchpad-open { 38 | margin-top: -32px; 39 | } 40 | -------------------------------------------------------------------------------- /scratchpad.yaml: -------------------------------------------------------------------------------- 1 | Type: Jupyter Notebook Extension 2 | Name: Scratchpad 3 | Description: Adds a scratchpad cell to Jupyter notebook. 4 | Link: README.md 5 | Main: main.js 6 | Compatibility: 4.x, 5.x 7 | --------------------------------------------------------------------------------