Reorganize repository

This commit is contained in:
Juergen Hasch
2015-09-01 13:03:39 +02:00
parent e6ec4363a6
commit 64d2e365fc
218 changed files with 404 additions and 345 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
IPython-contrib is licensed under the terms of the Modified BSD License (also IPython-contrib is licensed under the terms of the Modified BSD License (also
known as New or Revised or 3-Clause BSD), as follows: known as New or Revised or 3-Clause BSD), as follows:
- Copyright (c) 2013-2014, IPython-contrib Developers - Copyright (c) 2013-2015, IPython-contrib Developers
All rights reserved. All rights reserved.
+13 -13
View File
@@ -20,19 +20,19 @@ IPython/Jupyter version support
There are different branches of the notebook extensions in this repository. There are different branches of the notebook extensions in this repository.
Please make sure you use the branch corresponding to your IPython/Jupyter version. Please make sure you use the branch corresponding to your IPython/Jupyter version.
Overview
===========================
The repository is organized in different categories:
| Name | Description |
|------------|-------------|
| [usability](https://github.com/ipython-contrib/IPython-notebook-extensions/wiki#usability) | Additional functionality for the notebook |
| [publishing](https://github.com/ipython-contrib/IPython-notebook-extensions/wiki#publishing) | Getting your notebooks out in the wild |
| [styling](https://github.com/ipython-contrib/IPython-notebook-extensions/wiki#styling) | Styling schemes for different looks of the notebook |
| [slidemode](https://github.com/ipython-contrib/IPython-notebook-extensions/wiki#slidemode) | Slideshow creation |
| [testing](https://github.com/ipython-contrib/IPython-notebook-extensions/wiki#testing) | Extensions in a early stage |
Documentation Documentation
============= =============
The extensions are documented in the Wiki. Please take a look [here](https://github.com/ipython-contrib/IPython-notebook-extensions/wiki) Some extensions are not documented. We encourage you to add documentation for them.
All extensions that are maintained and active have a markdown readme file for documentation and a yaml file to
allow them being configured using the 'nbextensions' server extension.
Installation
============
The simple case: You want to install the extensions as local user. Then, simply run `setup.py` or build
a conda package by running `conda build`, and then do a `conda install nbextensions`.
For more complex installation scenarios, please look up the documentation at the Jupyter homepage http://www.jupyter.org
+1
View File
@@ -0,0 +1 @@
ipython install.py
+81
View File
@@ -0,0 +1,81 @@
# Install notebook extensions
from jupyter_core.paths import jupyter_config_dir, jupyter_data_dir, jupyter_runtime_dir
from traitlets.config.loader import Config, JSONFileConfigLoader
import IPython.extensions
import os
import sys
import logging
import json
# http://stackoverflow.com/questions/12683834/how-to-copy-directory-recursively-in-python-and-overwrite-all
def recursive_overwrite(src, dest, ignore=None):
if os.path.isdir(src):
if not os.path.isdir(dest):
os.makedirs(dest)
files = os.listdir(src)
if ignore is not None:
ignored = ignore(src, files)
else:
ignored = set()
for f in files:
if f not in ignored:
recursive_overwrite(os.path.join(src, f),
os.path.join(dest, f),
ignore)
else:
shutil.copyfile(src, dest)
#
# Install files
#
# copy extensions to IPython extensions directory
extensions = os.path.dirname(IPython.extensions.__file__)
src = os.path.join('src','extensions')
print("Install extensions to %s" % extensions)
recursive_overwrite(src, extensions)
# Install templates
templates = os.path.join(jupyter_data_dir(), 'templates')
src = os.path.join('src','templates')
print("Install templates to %s" % templates)
recursive_overwrite(src, templates)
# Install nbextensions
nbextensions = os.path.join(jupyter_data_dir(), 'nbextensions')
src = os.path.join('src','nbextensions')
print("Install notebook extensions to %s" % nbextensions)
recursive_overwrite(src, nbextensions)
#
# Update nbconvert configuration
#
fname = os.path.join(jupyter_config_dir(), 'jupyter_nbconvert_config.json')
cl = JSONFileConfigLoader(fname)
config = cl.load_config()
newconfig=Config()
# Set template path, pre- and postprocessors of notebook extensions
newconfig.Exporter.template_path = [os.path.join(jupyter_data_dir(),'templates') ]
newconfig.Exporter.preprocessors = ["codefolding.CodeFoldingPreprocessor", "pymdpreprocessor.PyMarkdownPreprocessor" ]
newconfig.NbConvertApp.postprocessor_class = 'embed.EmbedPostProcessor'
config.merge(newconfig)
config.version = 1
s=json.dumps(config, indent=2, separators=(',', ': '), sort_keys=True)
with open(fname, 'w') as f:
f.write(s)
#
# Update notebook configuration
#
fname = os.path.join(jupyter_config_dir(), 'jupyter_notebook_config.json')
cl = JSONFileConfigLoader(fname, log=log)
config = cl.load_config()
newconfig=Config()
# Add server extension of /nbextension/ configuration tool
newconfig.NotebookApp.server_extensions = [ "nbextensions" ]
config.merge(newconfig)
config.version = 1
s=json.dumps(config, indent=2, separators=(',', ': '), sort_keys=True)
with open(fname, 'w') as f:
f.write(s)
+36
View File
@@ -0,0 +1,36 @@
package:
name: nbextensions
version: !!str 0.3
source:
path: ./src
build:
script: ipython install.py
requirements:
build:
- python
- jupyter-client
- jupyter-core
- jupyter-notebook
- nbconvert
- nbformat
- traitlets
- ipython >=4
run:
- python
- jupyter-client
- jupyter-core
- jupyter-notebook
- nbconvert
- nbformat
- traitlets
- ipython >=4
about:
home: https://github.com/ipython-contrib/IPython-notebook-extensions/wiki
license: Modified BSD License
summary: 'Notebook extensions for the IPython notebook'
-18
View File
@@ -1,18 +0,0 @@
# Configuration file for ipython-notebook.
from IPython.utils.path import get_ipython_dir
import os
import sys
ipythondir = get_ipython_dir()
extensions = os.path.join(ipythondir,'extensions')
sys.path.append( extensions )
c = get_config()
c.NotebookApp.open_browser = False
#c.IPKernelApp.ip = '127.0.0.1'
#c.FileNotebookManager.notebook_dir = 'i:\\notebook'
c.NotebookApp.server_extensions = [ 'nbextensions' ]
c.NotebookApp.extra_template_paths = [os.path.join(ipythondir,'templates') ]
-6
View File
@@ -1,6 +0,0 @@
.nbextension-row {
border-bottom: 2px solid #888;
padding-left: 20px;
padding-bottom: 20px;
}
-200
View File
@@ -1,200 +0,0 @@
// Copyright (c) IPython-Contrib Team.
// Distributed under the terms of the Modified BSD License.
// Show notebook extension configuration
require([
'base/js/namespace',
'base/js/utils',
'base/js/page',
'base/js/events',
'jquery',
'require',
'contents',
'services/config'
], function(
IPython,
utils,
page,
events,
$, require,
contents,
configmod
){
page = new page.Page();
var base_url = utils.get_body_data('baseUrl');
var extension_list = $('body').data('extension-list');
/* build html body listing all extensions */
var html = "";
for(var i=0; i < extension_list.length; i++) {
var extension = extension_list[i];
var url = base_url + extension['url'];
var icon = url + '/' + extension['Icon'];
var id = extension['Name'].replace(/\s+/g, '');
html += '<div class="row">\n'
+' <div class="row nbextension-row" >\n';
html += ' <div class="col-xs-4 col-sm-6">'
+' <div class="col-sm-9">'
+' <h3>' + extension['Name'] + '</h3></div>';
html += '<div class="col-sm-9">' + extension['Description'] +
' <a href="' + extension['Link'] + '">more...</a></div><br>';
html += '<div class="col-sm-9">'
+'<button type="button" class="btn btn-primary" id="'
+ id + '-on" >Activate</button>'
+'<button type="button" class="btn btn-default" disabled="disabled" id="'
+ id + '-off" >Deactivate</button></div><br>';
if (extension['Parameter'] != undefined) {
/* add an input element to configure extension parameters */
var inputid = 'input_' + extension['Parameter'];
var description = 'Parameter: ' + extension['Parameter'];
console.log(extension.hasOwnProperty('ParameterDescription'))
if (extension.hasOwnProperty('ParameterDescription') === true) description += '<br>'+extension['ParameterDescription'];
html += '<div class="col-xs-12" style="height:10px;"></div><div class="col-sm-9">'
+ description + '<input id="'+inputid+'" type="text" class="form-control searchbar_input">'
+ '</div>';
}
html += '</div>'
+' <div class="col-xs-8 col-sm-6">\n';
html += ' <img src="' + icon + '" height="120px" /></div>'
+'</div></div>'
}
$("#nbextensions-container").html(html);
/**
* Update config in json config file on server to reflect changed activate/deactivate stae
*/
var changeConfig = function(id,state) {
for(var i=0; i < extension_list.length; i++) {
var extension = extension_list[i];
var url = base_url + extension['url'] + '/' + extension['Main'];
url = url.split('.js')[0];
url = url.split('nbextensions/')[1] ;
var extid = extension['Name'].replace(/\s+/g, '');
if (extid === id) {
var ext = {};
if (state === true) {
console.log("Turn extension " + extension['Name'] + ' on');
ext[url] = true;
config.update({"load_extensions": ext })
} else {
console.log("Turn extension " + extension['Name'] + ' off');
ext[url] = null;
config.update({"load_extensions": ext })
}
}
}
};
/**
* Handle button click event to activate/deactivate extension
*/
var clickEvent = function(e) {
var id = this.id.replace(/-on|-off/,'');
var state = this.id.search(/-on/) >= 0;
if (state === true) {
set_buttons(id,false);
changeConfig(id,true)
} else {
set_buttons(id,true);
changeConfig(id,false)
}
};
/**
* install click handler for buttons
*/
for(var i=0; i < extension_list.length; i++) {
var extension = extension_list[i];
var id = extension['Name'].replace(/\s+/g, '');
console.log("Found extension:",id);
$(document.getElementById(id+'-on')).on('click', clickEvent );
$(document.getElementById(id+'-off')).on('click', clickEvent );
}
var set_buttons = function(id, state) {
var on = $(document.getElementById(id+'-on'));
var off = $(document.getElementById(id+'-off'));
if (state === true) {
off = $(document.getElementById(id+'-on'));
on = $(document.getElementById(id+'-off'));
}
on.prop('disabled', true);
on.removeClass('btn-primary');
on.addClass('btn-default');
off.prop('disabled', false);
off.addClass('btn-primary');
off.removeClass('btn-default')
};
/**
* handle input form for extension parameters, update parameter in json config file on server
*/
var handle_input = function(event, configkey)
{
var form = event.target.id;
var input = $(document.getElementById(form));
var c = {};
c[configkey] = input.val();
config.update(c)
};
/**
*
* Get configuration from json config file on server
*/
var config = new configmod.ConfigSection('notebook', {base_url: base_url});
config.load();
/* set activate/deactivate buttons and populate parameter input once config is loaded */
config.loaded.then(function() {
if (config.data.load_extensions) {
var nbextension_paths = Object.getOwnPropertyNames(
config.data.load_extensions);
for(var i=0; i < extension_list.length; i++) {
var extension = extension_list[i];
var parameter = extension['Parameter'];
if ( parameter != undefined) {
if (config.data.hasOwnProperty(parameter)) {
var input = $(document.getElementById('input_'+parameter));
var configkey = parameter;
input.val(config.data[parameter]);
input.on('keyup', function(event) { handle_input(event, configkey);});
}
}
var url = base_url + extension['url'] + '/' + extension['Main'];
url = url.split('.js')[0];
url = url.split('nbextensions/')[1];
if ( config.data.load_extensions[url] === true) {
var id = extension['Name'].replace(/\s+/g, '');
set_buttons(id,false);
}
}
}
});
/**
* Add CSS file
*
* @param name filename
*/
var load_css = function (name) {
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = require.toUrl(name);
document.getElementsByTagName("head")[0].appendChild(link);
};
load_css('/nbextensions/config/main.css');
page.show();
});
-58
View File
@@ -1,58 +0,0 @@
// Example for custom.js
// we want strict javascript that fails on ambiguous syntax
"use strict";
// activate extensions only after Notebook is initialized
require(["base/js/events"], function (events) {
events.on("app_initialized.NotebookApp", function () {
/*
* all exentensions from IPython-notebook-extensions, uncomment to activate
*/
// PUBLISHING
// IPython.load_extensions('publishing/nbviewer_theme/main')
// IPython.load_extensions('publishing/gist_it')
// IPython.load_extensions('publishing/nbconvert_button')
// IPython.load_extensions('publishing/printview/main')
// IPython.load_extensions('publishing/printviewmenu_button')
// SLIDEMODE
// IPython.load_extensions('slidemode/main')
// STYLING
// IPython.load_extensions('styling/css_selector/main')
// TESTING
// IPython.load_extensions('testing/hierarchical_collapse/main')
// USABILITY
// IPython.load_extensions('usability/aspell/ipy-aspell')
// IPython.load_extensions('usability/codefolding/main')
// IPython.load_extensions('usability/dragdrop/drag-and-drop')
// IPython.load_extensions('usability/runtools/main')
// IPython.load_extensions('usability/chrome_clipboard/main')
// IPython.load_extensions('usability/navigation-hotkeys/main')
// IPython.load_extensions('usability/toggle_all_line_number')
// IPython.load_extensions('usability/help_panel/help_panel')
// IPython.load_extensions('usability/hide_input/main')
// IPython.load_extensions('usability/split-combine')
// IPython.load_extensions('usability/read-only')
// IPython.load_extensions('usability/init_cell/main')
// IPython.load_extensions('usability/limit_output/main')
// IPython.load_extensions('usability/autosavetime')
// IPython.load_extensions('usability/autoscroll')
// IPython.load_extensions('usability/breakpoints')
// IPython.load_extensions('usability/clean_start')
// IPython.load_extensions('usability/comment-uncomment')
// IPython.load_extensions('usability/linenumbers')
// IPython.load_extensions('usability/no_exec_dunder')
// IPython.load_extensions('usability/noscroll')
// IPython.load_extensions('usability/hide_io_selected')
// IPython.load_extensions('usability/execute_time/ExecuteTime')
// IPython.load_extensions('usability/python-markdown/main')
});
});
+48
View File
@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
"""PostProcessor for embedding markdown images in HTML files."""
from __future__ import print_function
import os
import re
import base64
import requests
from traitlets import Bool, Unicode, Int
from nbconvert.postprocessors.base import PostProcessorBase
class EmbedPostProcessor(PostProcessorBase):
""" Post processor designed to embed images in markdown cells as base64 encoded blob in HTML file """
def replfunc(self, match):
""" replace source url or file link with base64 encoded blob """
url = match.group(1)
imgformat = url.split('.')[-1]
if url.startswith('http'):
data = request.get(url)
elif url.startswith('data'):
img = '<img src="' + url + '" '+ match.group(2) + ' />'
return img
else:
with open(url, 'rb') as f:
data = f.read()
self.log.info("embedding url: %s, format: %s" % (url, imgformat))
b64_data=base64.b64encode(data).decode("utf-8")
if imgformat == "svg":
img = '<img src="data:image/svg+xml;base64,' + b64_data + '" ' + match.group(2) + '/>'
elif imgformat == "pdf":
img = '<img src="data:application/pdf;base64,' + b64_data + '" ' + match.group(2) + '/>'
else:
img = '<img src="data:image/'+imgformat+';base64,' + b64_data + '" '+ match.group(2) + ' />'
return img
def postprocess(self, input):
regex = re.compile('<img\s+src="(\S+)"\s*(\S*)\s*/>')
ext = input.split('.')[-1]
output=input[0:-(len(ext)+1)] + '-embedded.' + ext
with open(input) as fin, open(output,'w') as fout:
for line in fin:
fout.write(regex.sub(self.replfunc,line))
fin.close()
fout.close()
@@ -12,14 +12,14 @@ import os
import yaml import yaml
import json import json
jupyterdir = jupyter_data_dir()
nbextensions = (get_nbext_dir(), os.path.join(jupyterdir,'nbextensions'))
exclude = [ 'mathjax' ]
class NBExtensionHandler(IPythonHandler): class NBExtensionHandler(IPythonHandler):
"""Render the notebook extension configuration interface.""" """Render the notebook extension configuration interface."""
@web.authenticated @web.authenticated
def get(self): def get(self):
jupyterdir = jupyter_data_dir()
nbextensions = (get_nbext_dir(), os.path.join(jupyterdir,'nbextensions'))
exclude = [ 'mathjax' ]
yaml_list = [] yaml_list = []
# Traverse through nbextension subdirectories to find all yaml files # Traverse through nbextension subdirectories to find all yaml files
for root, dirs, files in chain.from_iterable(os.walk(root) for root in nbextensions): for root, dirs, files in chain.from_iterable(os.walk(root) for root in nbextensions):
@@ -55,16 +55,56 @@ class NBExtensionHandler(IPythonHandler):
self.log.info("Found extension %s" % extension['Name']) self.log.info("Found extension %s" % extension['Name'])
stream.close() stream.close()
json_list = json.dumps(extension_list) json_list = json.dumps(extension_list)
# find where the Javascript code and the readme file are
config_js = None
config_md = None
for root, dirs, files in chain.from_iterable(os.walk(root) for root in nbextensions):
dirs[:] = [d for d in dirs if d not in exclude]
for f in files:
if root.endswith('nbconfig') and f =='main.js':
config_js = os.path.join(root, f)
if root.endswith('nbconfig') and f =='readme.md':
config_md = os.path.join(root, f)
if config_js is None: raise FileNotFoundError('Could not find nbconfig Javascript')
idx_js=config_js.find('nbextensions')
idx_md=config_js.find('nbextensions')
self.write(self.render_template('nbextensions.html', self.write(self.render_template('nbextensions.html',
base_url = self.base_url, base_url = self.base_url,
extension_list = json_list, extension_list = json_list,
page_title="Notebook Extension Configuration" page_title="Notebook Extension Configuration",
config_js = self.base_url + config_js[idx_js::].replace('\\', '/'),
config_md = self.base_url + 'rendermd/' + config_md[idx_md::].replace('\\', '/')
) )
) )
class RenderExtensionHandler(IPythonHandler):
"""Render given markdown file"""
@web.authenticated
def get(self, path):
render_js = None
for root, dirs, files in chain.from_iterable(os.walk(root) for root in nbextensions):
dirs[:] = [d for d in dirs if d not in exclude]
for f in files:
if root.endswith('nbconfig') and f =='render.js':
render_js = os.path.join(root, f)
if render_js is None: raise FileNotFoundError('Could not find nbconfig Javascript')
idx_js=render_js.find('nbextensions')
self.write(self.render_template('rendermd.html',
base_url = self.base_url,
render_url = path,
page_title = path,
render_js = self.base_url + render_js[idx_js::].replace('\\', '/'),
)
)
def load_jupyter_server_extension(nbapp): def load_jupyter_server_extension(nbapp):
webapp = nbapp.web_app webapp = nbapp.web_app
base_url = webapp.settings['base_url'] base_url = webapp.settings['base_url']
mdregex = r'([^"\'>]+.md)'
webapp.add_handlers(".*$", [ webapp.add_handlers(".*$", [
(ujoin(base_url, r"/rendermd/%s" % mdregex), RenderExtensionHandler),
(ujoin(base_url, r"/nbextensions"), NBExtensionHandler),
(ujoin(base_url, r"/nbextensions/"), NBExtensionHandler) (ujoin(base_url, r"/nbextensions/"), NBExtensionHandler)
]) ])

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 291 KiB

After

Width:  |  Height:  |  Size: 291 KiB

Before

Width:  |  Height:  |  Size: 424 KiB

After

Width:  |  Height:  |  Size: 424 KiB

Before

Width:  |  Height:  |  Size: 325 KiB

After

Width:  |  Height:  |  Size: 325 KiB

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 185 KiB

Before

Width:  |  Height:  |  Size: 311 KiB

After

Width:  |  Height:  |  Size: 311 KiB

Before

Width:  |  Height:  |  Size: 252 KiB

After

Width:  |  Height:  |  Size: 252 KiB

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 210 KiB

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Some files were not shown because too many files have changed in this diff Show More