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
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.
+13 -13
View File
@@ -20,19 +20,19 @@ IPython/Jupyter version support
There are different branches of the notebook extensions in this repository.
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
=============
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 json
jupyterdir = jupyter_data_dir()
nbextensions = (get_nbext_dir(), os.path.join(jupyterdir,'nbextensions'))
exclude = [ 'mathjax' ]
class NBExtensionHandler(IPythonHandler):
"""Render the notebook extension configuration interface."""
@web.authenticated
def get(self):
jupyterdir = jupyter_data_dir()
nbextensions = (get_nbext_dir(), os.path.join(jupyterdir,'nbextensions'))
exclude = [ 'mathjax' ]
yaml_list = []
# Traverse through nbextension subdirectories to find all yaml files
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'])
stream.close()
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',
base_url = self.base_url,
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):
webapp = nbapp.web_app
base_url = webapp.settings['base_url']
mdregex = r'([^"\'>]+.md)'
webapp.add_handlers(".*$", [
(ujoin(base_url, r"/rendermd/%s" % mdregex), RenderExtensionHandler),
(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