{ "metadata": { "name": "", "signature": "sha256:cf52e4e5b6babfdd6636814148812f10fcf73b5ade962f69b728c735ac95d33f" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Notebook javascript API" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is a 'pythonic' javascript API in the notebook. From this API you can access code mirror configuration, you can add buttons to the toolbar, enable or disable some code cells,..." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Some examples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "--------------------------------------" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Add line numbers on each cell" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add line number to new cells:\n", "\n", " IPython.Cell.options_default.cm_config.lineNumbers = true;\n", "\n", "or only to new ***code*** cells:\n", "\n", " IPython.CodeCell.options_default.cm_config.lineNumbers = true;" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%javascript\n", "IPython.CodeCell.options_default.cm_config.lineNumbers = false;" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "-----------------------------------------------------------------------------------------------------------------------------" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Modify the cursor blink rate" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cursor blink (extracted from http://pirsquared.org/blog/notebook-blink.html)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%javascript\n", "var rate = 530; // default in codemirror is 530ms\n", "// apply setting to all current CodeMirror instances\n", "IPython.notebook.get_cells().map(\n", " function(c) { return c.code_mirror.options.cursorBlinkRate=rate; }\n", ");\n", "\n", "// make sure new CodeMirror instance also use this setting\n", "CodeMirror.defaults.cursorBlinkRate = rate;" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "--------------------------------------" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Listening the content of cells using a shortcut and the new HTML5 SpeechAPI" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "This functionality has been tested only on modern Chrome versions. I think the latest Firefox nightly build (2014/11/08) allows you to use this API but I didn't find the time to test it on firefox.\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can easily add new shortcuts to include new functionality using the js IPython API. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%javascript\n", "IPython.keyboard_manager.command_shortcuts.add_shortcut(\"Ctrl-Shift-Alt-h\", {\n", " help : 'Talking cells',\n", " help_index : 'zzz',\n", " handler : function() { \n", " var input = IPython.notebook.get_selected_cell().get_text();\n", " var msg = new SpeechSynthesisUtterance();\n", " msg.text = input;\n", " msg.lang = \"es-ES\";\n", " msg.voiceURI = 'native';\n", " msg.volume = 1; // 0 to 1\n", " msg.rate = 0.5; // 0.1 to 10\n", " msg.pitch = 2; //0 to 2\n", " window.speechSynthesis.speak(msg);\n", " return false;\n", " }}\n", ");" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To disable the recently created shortcut:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%javascript\n", "IPython.keyboard_manager.command_shortcuts.remove_shortcut('Ctrl-Shift-Alt-h');" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---------------------------------_" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "A shortcut for simple things" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lets add a shortcut to clear all outputs so we don't have to use the top menus" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%javascript\n", "IPython.keyboard_manager.command_shortcuts.add_shortcut(\"Ctrl-Shift-Alt-h\", {\n", " help : 'Clear all output',\n", " help_index : 'zzz',\n", " handler : function() { \n", " // to clear all the outputs\n", " IPython.notebook.clear_all_output(); \n", " return false;\n", " }}\n", ");" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "%%javascript\n", "IPython.keyboard_manager.command_shortcuts.remove_shortcut('Ctrl-Shift-Alt-h');" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can change the content inside the function with other stuff:\n", "\n", "````javascript\n", "// see http://codemirror.net/mode/ to change the syntax higlighting/codecompletion\n", "IPython.notebook.set_codemirror_mode('ipython');\n", "\n", "// Scroll to top\n", "IPython.notebook.scroll_to_top();\n", " \n", "// Scroll to bottom\n", "IPython.notebook.scroll_to_bottom();\n", " \n", "// To know the number of cells used in the notebook and display it on a pop-up window:\n", "number = IPython.notebook.ncells();\n", "alert(number);\n", " \n", "// Execute all the cells\n", "IPython.notebook.execute_all_cells();\n", "\n", "...\n", "````" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
In the notebook you have two modes: ***edit*** and ***command***. You can add shortcuts when you are in a mode or in the other so if the shortcut is created to work only in a mode while you are in the other mode the shortcut will not work.
" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%javascript\n", "\n", "IPython.keyboard_manager.command_shortcuts.add_shortcut('Ctrl-Alt-c', {\n", " help : 'clear all outputs',\n", " help_index : 'zzz',\n", " handler : function (event) {\n", " IPython.notebook.clear_all_output(); \n", " return false;\n", " }}\n", ");\n", "IPython.keyboard_manager.edit_shortcuts.add_shortcut('Ctrl-Alt-c', {\n", " help : 'clear all outputs',\n", " help_index : 'zzz',\n", " handler : function (event) {\n", " IPython.notebook.clear_all_output(); \n", " return false;\n", " }}\n", ");" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "%%javascript\n", "\n", "IPython.keyboard_manager.command_shortcuts.remove_shortcut('Ctrl-Alt-c');\n", "IPython.keyboard_manager.edit_shortcuts.remove_shortcut('Ctrl-Alt-c');" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "Go deeper with shortcuts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "http://nbviewer.ipython.org/github/ipython/ipython/blob/2.x/examples/Notebook/User%20Interface.ipynb#Keyboard-shortcut-customization" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "------------------------------" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Custom.js and Custom.css" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you want that some of the modifications you made will be available when a notebook is opened you can use the file ***custom.js*** available on each profile. Also, if you want to modify the look you can use the file ***custom.css***\n", "\n", "We can add the ruler option to the ***custom.js*** file of the created *pycones14* profile in previous notebooks." ] }, { "cell_type": "code", "collapsed": false, "input": [ "profile_dir = !ipython locate profile pycones14\n", "profile_dir = profile_dir[0]\n", "profile_dir" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will load the custom.js file of the *pycones14* profile, the loaded code will be saved using `%%writefile` magic and with the updated *custom.js* file we will open a new notebook for that profile to see how the changes are applied." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%load $profile_dir/static/custom/custom.js" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "%%writefile $profile_dir/static/custom/custom.js\n", "// leave at least 2 line with only a star on it below, or doc generation fails\n", "/**\n", " *\n", " *\n", " * Placeholder for custom user javascript\n", " * mainly to be overridden in profile/static/custom/custom.js\n", " * This will always be an empty file in IPython\n", " *\n", " * User could add any javascript in the `profile/static/custom/custom.js` file\n", " * (and should create it if it does not exist).\n", " * It will be executed by the ipython notebook at load time.\n", " *\n", " * Same thing with `profile/static/custom/custom.css` to inject custom css into the notebook.\n", " * \n", " * Classes and functions are available at load time and may be accessed plainly: \n", " * \n", " * IPython.Cell.options_default.cm_config.extraKeys['Home'] = 'goLineLeft';\n", " * IPython.Cell.options_default.cm_config.extraKeys['End'] = 'goLineRight';\n", " * \n", " * Instances are created later however and must be accessed using events:\n", " * \n", " * $([IPython.events]).on(\"app_initialized.NotebookApp\", function () {\n", " * IPython.keyboard_manager....\n", " * });\n", " *\n", " * __Example 1:__\n", " *\n", " * Create a custom button in toolbar that execute `%qtconsole` in kernel\n", " * and hence open a qtconsole attached to the same kernel as the current notebook\n", " *\n", " * IPython.events.on('app_initialized.NotebookApp', function(){\n", " * IPython.toolbar.add_buttons_group([\n", " * {\n", " * 'label' : 'run qtconsole',\n", " * 'icon' : 'icon-terminal', // select your icon from http://fortawesome.github.io/Font-Awesome/icons\n", " * 'callback': function () {\n", " * IPython.notebook.kernel.execute('%qtconsole')\n", " * }\n", " * }\n", " * // add more button here if needed.\n", " * ]);\n", " * });\n", " *\n", " * __Example 2:__\n", " *\n", " * At the completion of the dashboard loading, load an unofficial javascript extension\n", " * that is installed in profile/static/custom/ \n", " *\n", " * IPython.events.on('app_initialized.DashboardApp', function(){\n", " * require(['custom/unofficial_extension.js'])\n", " * });\n", " *\n", " * __Example 3:__\n", " *\n", " * Use `jQuery.getScript(url [, success(script, textStatus, jqXHR)] );`\n", " * to load custom script into the notebook.\n", " *\n", " * // to load the metadata ui extension example.\n", " * $.getScript('/static/notebook/js/celltoolbarpresets/example.js');\n", " * // or\n", " * // to load the metadata ui extension to control slideshow mode / reveal js for nbconvert\n", " * $.getScript('/static/notebook/js/celltoolbarpresets/slideshow.js');\n", " *\n", " *\n", " * @module IPython\n", " * @namespace IPython\n", " * @class customjs\n", " * @static\n", " */\n", "\n", "$([IPython.events]).on(\"app_initialized.NotebookApp\", function () { \n", " \n", " var colors = [[\"Red\", \"PaleVioletRed\"],\n", " [\"Orange\", \"DarkOrange\"], \n", " [\"Green\", \"LightGreen\"], \n", " [\"None\", \"#F7F7F7\"]];\n", " \n", " var cell_flag_init = IPython.CellToolbar.utils.select_ui_generator(\n", " \n", " // List\n", " colors, \n", " // Setter, called when the select state has been changed. \n", " // Sets the color of the cell background\n", " // add the color value in the cell's metadata.\n", " function(cell, value){\n", " if (cell.metadata.bgcolor == undefined){\n", " cell.metadata.bgcolor = {};\n", " }\n", " cell.metadata.bgcolor = value;\n", " var prompt = cell.element.find('div.input_area');\n", " prompt.css(\"background-color\", value);\n", " },\n", " \n", " // Getter, called when the control is rendered. Determines the initial\n", " // state of the checkbox. If the flag doesn't in the metadata, default\n", " // to false.\n", " function(cell){\n", " if (cell.metadata.bgcolor === undefined || cell.metadata.bgcolor == false) {\n", " return \"default\";\n", " } else {\n", " return cell.metadata.bgcolor;\n", " }\n", " },\n", " // Label\n", " \"Choose bg color\"\n", " );\n", "\n", " IPython.CellToolbar.register_callback(\"choose_bg_color\", cell_flag_init);\n", " \n", " // Create and register the toolbar with IPython.\n", " IPython.CellToolbar.register_preset('Choose bg color', [\"choose_bg_color\"]);\n", " console.log(\"Background colors modifications loaded\")\n", " \n", "});\n", "\n", "$([IPython.events]).on('notebook_loaded.Notebook', function(){\n", " \n", " var cells = IPython.notebook.get_cells();\n", " for(var i in cells){\n", " var cell = cells[i];\n", " if (cell.metadata.bgcolor){\n", " var prompt = cell.element.find('div.input_area');\n", " prompt.css(\"background-color\", cell.metadata.bgcolor);\n", " }\n", " }\n", " \n", "});" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "... things happened in the live talk ..." ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "More" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "http://nbviewer.ipython.org/github/ipython/ipython/blob/master/examples/Notebook/JavaScript%20Notebook%20Extensions.ipynb\n", "\n", "https://blog.safaribooksonline.com/2013/12/18/ipython-notebook-plugins/\n", "\n", "http://nbviewer.ipython.org/github/payne92/notebooks/blob/master/00%20Javascript%20In%20Notebooks.ipynb" ] } ], "metadata": {} } ] }