Skip to content

Instantly share code, notes, and snippets.

@psychemedia
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save psychemedia/ab7bbc3aa731269bd3b4 to your computer and use it in GitHub Desktop.
Save psychemedia/ab7bbc3aa731269bd3b4 to your computer and use it in GitHub Desktop.
// add button to make codecell activity blue
//based on https://github.com/ipython-contrib/IPython-notebook-extensions/blob/master/usability/read-only.js
"using strict";
var activityCodeCell = (function() {
/**
* Set codecell to activity
*
* @param {Object} cell current notebook cell
* @param {Boolean} val is cell activity
*/
setActivity = function (cell,val) {
if (val == undefined) {
val = false;
}
cell.metadata.activity = val;
var prompt = cell.element.find('div.input_area');
//var output_area = cell.element.find('div.output_subarea');
var cp=cell.element.find('div.input').parent()
if (val == true) {
prompt.css("background-color","#ecf6ff");
cp.css("background-color","#c8ecff");
//output_area.css("background-color","#f5ffff");
} else {
prompt.css("background-color","#f5f5f5");
cp.css("background-color","#ffffff");
//output_area.css("background-color","#ffffff");
}
};
setActivityM = function (cell) {
var prompt = cell.element;
//var cp=cell.element.find('div.input').parent()
if (cell.metadata.activity== undefined) {}
else if (cell.metadata.activity== 'clear') {
prompt.css("background-color","#ffffff");
prompt.find('div.inner_cell').css("background-color","#ffffff")
} else {
if (cell.metadata.activity == 'activityAns') {
prompt.css("background-color","#c8ecff")
prompt.find('div.inner_cell').css("background-color","#ecf6ff")
} else {
prompt.css("background-color","#c8ecff")
prompt.find('div.inner_cell').css("background-color","#c8ecff")
}
}
};
function toggleActivity() {
var cell = IPython.notebook.get_selected_cell();
if ((cell instanceof IPython.CodeCell)) {
if (cell.metadata.activity == undefined){
cell.metadata.activity = {}; }
setActivity(cell,!cell.metadata.activity);
} else if (cell instanceof IPython.MarkdownCell) {
if ((cell.metadata.activity == undefined) || (cell.metadata.activity=='clear'))
cell.metadata.activity = 'activity';
else if (cell.metadata.activity == 'activity' )
cell.metadata.activity = 'activityAns'
else if (cell.metadata.activity == 'activityAns')
cell.metadata.activity='clear'
setActivityM(cell);
}
};
/**
* Register new extraKeys to codemirror for newly created cell
*
* @param {Object} event
* @param {Object} nbcell notebook cell
*/
create_cell = function (event,nbcell,nbindex) {
var cell = nbcell.cell;
};
/**
* Add run control buttons to toolbar and initialize codecells
*
*/
IPython.toolbar.add_buttons_group([
{
id : 'activity_codecell',
label : 'Toggle activity codecell',
icon : 'icon-quote-left',
callback : toggleActivity
}
]);
function oustyle_notebook(){
/* loop through notebook and set read-only cells defined in metadata */
var cells = IPython.notebook.get_cells();
for(var i in cells){
var cell = cells[i];
if ((cell instanceof IPython.CodeCell)) {
if (cell.metadata.activity != undefined) {
setActivity(cell,cell.metadata.activity);
} else { setActivity(cell,false); }
} else if ((cell instanceof IPython.MarkdownCell))
setActivityM(cell)
};
}
$([IPython.events]).on('create.Cell',create_cell);
$([IPython.events]).on('notebook_loaded.Notebook',oustyle_notebook());
})();
//based on https://github.com/ipython/ipython/issues/5591
"using strict";
var answer_button = (function() {
function add_buttons(){
console.log("runit");
$("div").each( function(){
if (this.className === 'answer') {
activityBlock=$(this).parent().parent().parent();
activityBlock.css("background-color","#c8ecff");
var button= '<input type="button" value="Answer" onclick="showHide(' + this.id + ')">';
this.insertAdjacentHTML("beforeBegin",button);
}
if (this.className === 'activity') {
activityBlock=$(this).parent().parent().parent();
activityBlock.css("background-color","#c8ecff");
}
});
};
$([IPython.events]).on('notebook_loaded.Notebook',add_buttons());
IPython.toolbar.add_buttons_group([
{
id : 'add_buttons',
label : 'Add answer buttons',
icon : 'icon-list-alt',
callback : add_buttons
}
]);
})();
function showHide(e) {
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
e.style["background-color"]="#ecf6ff";
}
#Run this in an IPython notebook, then restart the notebook server
#For now, URL_TO: https://gist.github.com/psychemedia/ab7bbc3aa731269bd3b4/raw/
!curl -L URL_TO/answer_button.js > $(ipython locate profile)/static/custom/answer_button.js
!curl -L URL_TO/activityCodeCell.js > $(ipython locate profile)/static/custom/activityCodeCell.js
!curl -L URL_TO/custom.css > $(ipython locate profile)/static/custom/custom.css
#In $(ipython locate profile)/static/custom/custom.js
## $([IPython.events]).on('app_initialized.NotebookApp', function(){ require(['custom/answer_buttons'])});
#!sed -i '$a $([IPython.events]).on("app_initialized.NotebookApp", function(){ require(["custom/answer_button","custom/activityCodeCell"])});' $(ipython locate profile)/static/custom/custom.js
!curl -L URL_TO/custom.js > $(ipython locate profile)/static/custom/custom.js
/*
Placeholder for custom user CSS
mainly to be overridden in profile/static/custom/custom.css
This will always be an empty file in IPython
*/
.activity {
font-size: 20px;
font-style: italic;
}
// leave at least 2 line with only a star on it below, or doc generation fails
/**
*
*
* Placeholder for custom user javascript
* mainly to be overridden in profile/static/custom/custom.js
* This will always be an empty file in IPython
*
* User could add any javascript in the `profile/static/custom/custom.js` file
* (and should create it if it does not exist).
* It will be executed by the ipython notebook at load time.
*
* Same thing with `profile/static/custom/custom.css` to inject custom css into the notebook.
*
* Example :
*
* Create a custom button in toolbar that execute `%qtconsole` in kernel
* and hence open a qtconsole attached to the same kernel as the current notebook
*
* $([IPython.events]).on('app_initialized.NotebookApp', function(){
* IPython.toolbar.add_buttons_group([
* {
* 'label' : 'run qtconsole',
* 'icon' : 'icon-terminal', // select your icon from http://fortawesome.github.io/Font-Awesome/icons
* 'callback': function () {
* IPython.notebook.kernel.execute('%qtconsole')
* }
* }
* // add more button here if needed.
* ]);
* });
*
* Example :
*
* Use `jQuery.getScript(url [, success(script, textStatus, jqXHR)] );`
* to load custom script into the notebook.
*
* // to load the metadata ui extension example.
* $.getScript('/static/notebook/js/celltoolbarpresets/example.js');
* // or
* // to load the metadata ui extension to control slideshow mode / reveal js for nbconvert
* $.getScript('/static/notebook/js/celltoolbarpresets/slideshow.js');
*
*
* @module IPython
* @namespace IPython
* @class customjs
* @static
*/
//$([IPython.events]).on("app_initialized.NotebookApp", function(){ require(["custom/answer_button","custom/activityCodeCell","custom/readonly_extension"])});
$([IPython.events]).on("app_initialized.NotebookApp", function(){ require(["custom/answer_button","custom/activityCodeCell"])});
// add button to make codecell read-only
"use strict";
//FROM https://github.com/ipython-contrib/IPython-notebook-extensions/blob/master/usability/read-only.js
var readonly_extension = (function() {
var readonlyKey = { "Alt-R" : function(){toggleReadOnly();} };
/**
* Concatenate associative array objects
*
* Source: http://stackoverflow.com/questions/2454295/javascript-concatenate-properties-from-multiple-objects-associative-array
*/
function collect() {
var ret = {};
var len = arguments.length;
for (var i=0; i<len; i++) {
for (var p in arguments[i]) {
if (arguments[i].hasOwnProperty(p)) {
ret[p] = arguments[i][p];
}
}
}
return ret;
}
/**
* Set codecell to read-only
*
* @param {Object} cell current notebook cell
* @param {Boolean} val is cell read-only
*/
var setReadOnly = function (cell,val) {
if (val == undefined) {
val = false;
}
if (cell.metadata.run_control == undefined) {
cell.metadata.run_control = {};
}
cell.metadata.run_control.read_only = val;
cell.read_only = val;
var prompt = cell.element.find('div.input_area');
if (val == true) {
prompt.css("background-color","#ffffff");
} else {
prompt.css("background-color","#f5f5f5");
}
cell.code_mirror.setOption('readOnly',val);
};
var setReadOnly_md = function (cell,val) {
if (val == undefined) {
val = false;
}
if (cell.metadata.run_control == undefined) {
cell.metadata.run_control = {};
}
cell.metadata.run_control.read_only = val;
cell.read_only = val;
if (val==true) val='nocursor';
cell.code_mirror.setOption('readOnly',val);
};
function toggleReadOnly() {
var cell = IPython.notebook.get_selected_cell();
if ((cell instanceof IPython.CodeCell)) {
if (cell.metadata.run_control == undefined){
cell.metadata.run_control = {}; }
setReadOnly(cell,!cell.metadata.run_control.read_only);
}
if (!(cell instanceof IPython.CodeCell)) {
if (cell.metadata.read_control == undefined){
cell.metadata.read_control = {}; }
setReadOnly_md(cell,!cell.metadata.run_control.read_only);
}
};
var md_all_toggleState=false;
function toggleReadOnlyAllMD(){
var cells = IPython.notebook.get_cells();
for(var i in cells){
var cell = cells[i];
if (!(cell instanceof IPython.CodeCell)) {
if (cell.metadata.read_control == undefined){
cell.metadata.read_control = {};
}
setReadOnly_md(cell,!md_all_toggleState);
}
}
md_all_toggleState=!md_all_toggleState;
}
function assign_key(cell) {
var keys = cell.code_mirror.getOption('extraKeys');
cell.code_mirror.setOption('extraKeys', collect(keys, readonlyKey ));
}
/**
* Register new extraKeys to codemirror for newly created cell
*
* @param {Object} event
* @param {Object} nbcell notebook cell
*
*/
var create_cell = function (event,nbcell) {
var cell = nbcell.cell;
if ((cell instanceof IPython.CodeCell)) { assign_key(cell); }
};
/**
* Add run control buttons to toolbar and initialize codecells
*
*/
IPython.toolbar.add_buttons_group([
{
id : 'read_only_codecell',
label : 'Toggle read-only cell',
icon : 'icon-lock',
callback : toggleReadOnly
},
{
id : 'read_only_md_cells_all',
label : 'Toggle all md read-only cells',
icon : 'icon-pushpin',
callback : toggleReadOnlyAllMD
}
]);
/* loop through notebook and set read-only cells defined in metadata */
var cells = IPython.notebook.get_cells();
for(var i in cells){
var cell = cells[i];
if ((cell instanceof IPython.CodeCell)) {
assign_key(cell);
if (cell.metadata.run_control != undefined) {
setReadOnly(cell,cell.metadata.run_control.read_only);
} else { setReadOnly(cell,false); }
} else {
if (cell.metadata.run_control != undefined) {
setReadOnly_md(cell,cell.metadata.run_control.read_only);
} else { setReadOnly_md(cell,false); }
}
};
$([IPython.events]).on('create.Cell',create_cell);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment