diff --git a/.gitignore b/.gitignore
index 1611f4e..276a34c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,16 @@
-custom.js
-custom.css
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.cache
+nosetests.xml
+coverage.xml
+
+# Sphinx documentation
+docs/_build/
+
+.idea
diff --git a/bld.bat b/bld.bat
new file mode 100644
index 0000000..c40a9bb
--- /dev/null
+++ b/bld.bat
@@ -0,0 +1,2 @@
+"%PYTHON%" setup.py install
+if errorlevel 1 exit 1
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..434a40f
--- /dev/null
+++ b/build.sh
@@ -0,0 +1 @@
+python install.py
\ No newline at end of file
diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh
deleted file mode 100755
index 8a1fa0c..0000000
--- a/conda-recipe/build.sh
+++ /dev/null
@@ -1 +0,0 @@
-ipython install.py
\ No newline at end of file
diff --git a/conda-recipe/install.py b/conda-recipe/install.py
deleted file mode 100755
index d26fe53..0000000
--- a/conda-recipe/install.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# 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)
diff --git a/extensions/nbextensions.py b/extensions/nbextensions.py
index 6573edf..a8176d9 100644
--- a/extensions/nbextensions.py
+++ b/extensions/nbextensions.py
@@ -8,93 +8,95 @@ from notebook.base.handlers import IPythonHandler, json_errors
from notebook.nbextensions import _get_nbext_dir as get_nbext_dir
from tornado import web
from itertools import chain
-import os
+import os.path
import yaml
+from yaml.scanner import ScannerError
import json
jupyterdir = jupyter_data_dir()
-nbextensions = (get_nbext_dir(), os.path.join(jupyterdir,'nbextensions'))
+nbextension_dirs = (get_nbext_dir(), os.path.join(jupyterdir, 'nbextensions'))
exclude = [ 'mathjax' ]
+
class NBExtensionHandler(IPythonHandler):
"""Render the notebook extension configuration interface."""
+
@web.authenticated
def get(self):
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):
+ for root, dirs, files in chain.from_iterable(
+ os.walk(nb_ext_dir) for nb_ext_dir in nbextension_dirs):
+ # filter to exclude directories
dirs[:] = [d for d in dirs if d not in exclude]
- for f in files:
- if f.endswith('.yaml'):
- yaml_list.append([ root, f] )
+
+ for filename in files:
+ if filename.endswith('.yaml'):
+ yaml_list.append((root, filename))
+
# Build a list of extensions from YAML file description
# containing at least the following entries:
- # Type - identifier
- # Name - unique name of the extension
- # Description - short explanation of the extension
- # Main - main file that is loaded, typically 'main.js'
+ # Type - identifier
+ # Compatibility - compatible notebook version, e.g. '4.x'
+ # Name - unique name of the extension
+ # Description - short explanation of the extension
+ # Main - main file that is loaded, typically 'main.js'
#
extension_list = []
- for y in yaml_list:
- stream = open(os.path.join(y[0],y[1]), 'r')
- extension = yaml.load(stream)
- if all (k in extension for k in ('Type', 'Compatibility', 'Name', 'Main', 'Description')):
- if not extension['Type'].strip().startswith('IPython Notebook Extension'):
+ required_keys = (
+ 'Type', 'Compatibility', 'Name', 'Main', 'Description')
+
+ for ext_dir, yaml_filename in sorted(yaml_list):
+ with open(os.path.join(ext_dir, yaml_filename), 'r') as stream:
+ try:
+ extension = yaml.load(stream)
+ except ScannerError:
+ self.log.warning(
+ 'failed to load yaml file %r', yaml_filename)
continue
- if not extension['Compatibility'].strip().startswith(notebook.__version__[0:2]):
- continue
- # generate URL to extension
- idx=y[0].find('nbextensions')
- url = y[0][idx::].replace('\\', '/')
- extension['url'] = url
- # replace single quote with HTML representation
- for key in extension:
- if isinstance(extension[key], str):
- extension[key] = extension[key].replace("'","'")
- extension_list.append(extension)
- 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',
+
+ if any(key not in extension for key in required_keys):
+ continue
+ if not extension['Type'].strip().startswith(
+ 'IPython Notebook Extension'):
+ continue
+ compat = extension['Compatibility'].strip()
+ if not compat.startswith(
+ notebook.__version__[:2]):
+ pass
+ # continue
+
+ # generate URL to extension's main js file
+ idx = ext_dir.find('nbextensions')
+ url = ext_dir[idx::].replace('\\', '/')
+ extension['url'] = url
+
+ # replace single quote with HTML representation
+ for key in extension:
+ if isinstance(extension[key], str):
+ extension[key] = extension[key].replace("'","'")
+
+ extension_list.append(extension)
+ self.log.info(
+ "Found {} extension {}".format(compat, extension['Name']))
+
+ extension_list_json = json.dumps(extension_list)
+ self.write(self.render_template(
+ 'nbextensions.html',
base_url = self.base_url,
- extension_list = json_list,
- 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('\\', '/')
- )
- )
+ extension_list = extension_list_json,
+ page_title="Notebook Extension Configuration"
+ ))
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('\\', '/'),
)
)
diff --git a/extensions/embed.py b/extensions/post_htmlembed.py
old mode 100755
new mode 100644
similarity index 75%
rename from extensions/embed.py
rename to extensions/post_htmlembed.py
index ac16f17..3bc8246
--- a/extensions/embed.py
+++ b/extensions/post_htmlembed.py
@@ -1,48 +1,51 @@
-# -*- 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 = ''
- 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 = '
'
- elif imgformat == "pdf":
- img = '
'
- else:
- img = '
'
- return img
-
- def postprocess(self, input):
- regex = re.compile('
')
- 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()
+# -*- 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 = '
'
+ 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 = '
'
+ elif imgformat == "pdf":
+ img = '
'
+ else:
+ img = '
'
+ return img
+
+ def postprocess(self, input):
+ #print(self.__dir__())
+ print(self.config)
+ if self.config.export_format == "html":
+ regex = re.compile('
')
+ 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()
diff --git a/extensions/codefolding.py b/extensions/pre_codefolding.py
similarity index 100%
rename from extensions/codefolding.py
rename to extensions/pre_codefolding.py
diff --git a/extensions/pymdpreprocessor.py b/extensions/pre_pymarkdown.py
similarity index 100%
rename from extensions/pymdpreprocessor.py
rename to extensions/pre_pymarkdown.py
diff --git a/conda-recipe/meta.yaml b/meta.yaml
old mode 100755
new mode 100644
similarity index 78%
rename from conda-recipe/meta.yaml
rename to meta.yaml
index fb80415..5b54fb5
--- a/conda-recipe/meta.yaml
+++ b/meta.yaml
@@ -1,36 +1,37 @@
package:
name: nbextensions
- version: !!str 0.3
+ version: "4.0"
source:
- path: ./src
+ git_url: https://github.com/ipython-contrib/IPython-notebook-extensions
+ git_tag: "4.0"
build:
- script: ipython install.py
+ script: python install.py
requirements:
build:
- - python
+ - ipython >=4
- jupyter-client
- jupyter-core
- jupyter-notebook
- nbconvert
- nbformat
+ - python
- traitlets
- - ipython >=4
run:
- - python
+ - ipython >=4
- jupyter-client
- jupyter-core
- jupyter-notebook
- nbconvert
- nbformat
+ - python
- traitlets
- - ipython >=4
about:
- home: https://github.com/ipython-contrib/IPython-notebook-extensions/wiki
+ home: https://github.com/ipython-contrib/IPython-notebook-extensions
license: Modified BSD License
summary: 'Notebook extensions for the IPython notebook'
diff --git a/nbextensions/config/config_menu/config_menu.yaml b/nbextensions/config/config_menu/config_menu.yaml
new file mode 100644
index 0000000..573abf6
--- /dev/null
+++ b/nbextensions/config/config_menu/config_menu.yaml
@@ -0,0 +1,6 @@
+Type: IPython Notebook Extension
+Name: NbExtensions menu item
+Description: Add an edit-menu item to open the NbExtensions config page
+Main: main.js
+Compatibility: 4.x
+Icon: icon.png
diff --git a/nbextensions/config/config_menu/icon.png b/nbextensions/config/config_menu/icon.png
new file mode 100644
index 0000000..5b4a3f8
Binary files /dev/null and b/nbextensions/config/config_menu/icon.png differ
diff --git a/nbextensions/config/config_menu/main.js b/nbextensions/config/config_menu/main.js
new file mode 100644
index 0000000..d2d6b06
--- /dev/null
+++ b/nbextensions/config/config_menu/main.js
@@ -0,0 +1,29 @@
+// extension by jcb91
+// Tiny extension to add an edit-menu item to open the NbExtensions config page
+
+define(["jquery"], function ($) {
+ "use strict";
+
+ var load_ipython_extension = function () {
+ var menu_item = $('
`
+
+If you run `nbconvert` to generate a HTML file, this image will remain outside of the html file. You can embedd all images by calling `nbconvert` with the option `--post=embed.EmbedPostProcessor`. The file `embed.py`, located in the same directory of this extension needs to be in `PYTHONPATH` to be found.
\ No newline at end of file
diff --git a/nbextensions/usability/execute_time/ExecuteTime.js b/nbextensions/usability/execute_time/ExecuteTime.js
index 82fd407..20485a0 100755
--- a/nbextensions/usability/execute_time/ExecuteTime.js
+++ b/nbextensions/usability/execute_time/ExecuteTime.js
@@ -18,7 +18,7 @@ define(["require", "jquery", "base/js/namespace", "base/js/events"], function (r
var patchCodecellExecute = function() {
console.log('patching codecell to trigger ExecuteCell.ExecuteTime');
- IPython.CodeCell.prototype.old_execute = IPython.CodeCell.prototype.execute
+ IPython.CodeCell.prototype.old_execute = IPython.CodeCell.prototype.execute;
IPython.CodeCell.prototype.execute = function () {
this.old_execute(arguments);
@@ -165,14 +165,18 @@ define(["require", "jquery", "base/js/namespace", "base/js/events"], function (r
}
};
+ var load_ipython_extension = function() {
+ patchCodecellExecute();
- patchCodecellExecute();
+ events.on('ExecuteCell.ExecuteTime', executionStartTime);
+ events.on('kernel_idle.Kernel', executionEndTime);
- events.on('ExecuteCell.ExecuteTime',executionStartTime);
- events.on('kernel_idle.Kernel', executionEndTime);
+ $("head").append($(""));
+ create_menu();
+ };
- $("head").append($(""));
- create_menu();
-
- console.log('Execute Timings loaded');
+ var extension = {
+ load_ipython_extension : load_ipython_extension
+ };
+ return extension;
});
diff --git a/nbextensions/usability/execute_time/ExecuteTime.yaml b/nbextensions/usability/execute_time/ExecuteTime.yaml
index 36baf93..6df3cda 100644
--- a/nbextensions/usability/execute_time/ExecuteTime.yaml
+++ b/nbextensions/usability/execute_time/ExecuteTime.yaml
@@ -1,7 +1,7 @@
# IPython Notebook Extension Description
Name: ExecuteTime
Description: Display when each cell has been executed and how long it took
-Link: https://github.com/ipython-contrib/IPython-notebook-extensions/wiki/execute_timings
+Link: readme.md
Icon: icon.png
Main: main.js
-Compatibility: 3.x
+Compatibility: 4.x
diff --git a/nbextensions/usability/execute_time/execution-timings-box.png b/nbextensions/usability/execute_time/execution-timings-box.png
deleted file mode 100644
index 401edc0..0000000
Binary files a/nbextensions/usability/execute_time/execution-timings-box.png and /dev/null differ
diff --git a/nbextensions/usability/execute_time/execution-timings-menu.png b/nbextensions/usability/execute_time/execution-timings-menu.png
deleted file mode 100644
index fa129d3..0000000
Binary files a/nbextensions/usability/execute_time/execution-timings-menu.png and /dev/null differ
diff --git a/nbextensions/usability/execute_time/readme.md b/nbextensions/usability/execute_time/readme.md
new file mode 100644
index 0000000..7611119
--- /dev/null
+++ b/nbextensions/usability/execute_time/readme.md
@@ -0,0 +1,28 @@
+This extension displays when the last execution of a cell occurred and how long it took.
+
+## Display
+
+Every executed cell is extended with a new area, attached at the bottom of the input area, that displays when the user started the last execution of this cell. When the kernel finishes to execute a cell, this area is update with the duration.
+
+
+
+## Toggling
+
+The timings area can be hide by double clicking on it or using the option in the cell menu. The menu toggle timings->All hides (resp. shows) all the possible timings area if the first cell is displayed (resp. hidden).
+
+
+
+## Internals
+To be sure that the kernel is run intentionally by executing a codecell, codecell.prototype.execute() is overloaded and a new event 'ExecuteCell.ExecuteTime' is fired, that this extension catches to display the start time. We use the event 'status_idle.Kernel' to know when the kernel finished the execution of the cell.
+
+## Installation
+Copy `ExecuteTime.{js,css}`, and add `require(['/static/custom/ExecuteTime.js'])` to `custom.js` in your profile's `/static/custom` directory, so it looks like this:
+```javascript
+$([IPython.events]).on('app_initialized.NotebookApp', function(){
+ //...
+ require(['/static/custom/ExecuteTime.js'])
+});
+```
+
+## TODO
+The timings information could be stored into the notebook and displayed when it is loaded. Where these information should be stored is still to be decided (maybe in the metadata).
diff --git a/nbextensions/usability/exercise/exercise.yaml b/nbextensions/usability/exercise/exercise.yaml
new file mode 100644
index 0000000..e62ead7
--- /dev/null
+++ b/nbextensions/usability/exercise/exercise.yaml
@@ -0,0 +1,7 @@
+Type: IPython Notebook Extension
+Name: Exercise
+Description: Exercise TEST
+Link: https://github.com/ipython-contrib/IPython-notebook-extensions/wiki/
+Icon: icon.png
+Main: main.js
+Compatibility: 3.x
diff --git a/nbextensions/usability/exercise/icon.png b/nbextensions/usability/exercise/icon.png
new file mode 100644
index 0000000..4acc18f
Binary files /dev/null and b/nbextensions/usability/exercise/icon.png differ
diff --git a/nbextensions/usability/exercise/main.js b/nbextensions/usability/exercise/main.js
index cf387d9..9862eab 100644
--- a/nbextensions/usability/exercise/main.js
+++ b/nbextensions/usability/exercise/main.js
@@ -1,14 +1,15 @@
-// Hide or diplay solutions in a notebook
+// Copyright (c) IPython-Contrib Team.
+// Distributed under the terms of the Modified BSD License.
-// To define a solution, select all cells of a solution using shift button and mouse
-// All cells will be hidden, except the first one
-// A hide/unhide symbol will be displayed. Click on it and the solution will be displayed/hidden
+// Hide or diplay solutions in a notebook
define([
'base/js/namespace',
'jquery',
- "base/js/events",
-], function(IPython, $, events) {
+ 'require',
+ 'base/js/events',
+ 'nbextensions/usability/rubberband/main'
+], function(IPython, $, require, events, rubberband) {
"use strict";
/**
@@ -18,21 +19,21 @@ define([
* @param ev {Event} jquery event
*/
function click_solution_lock(ev) {
- var cell=IPython.notebook.get_selected_cell()
- var is_locked = cell.element.find('#lock').hasClass('fa-plus-square-o')
+ var cell=IPython.notebook.get_selected_cell();
+ var is_locked = cell.element.find('#lock').hasClass('fa-plus-square-o');
if (is_locked == true) {
- cell.element.find('#lock').removeClass('fa-plus-square-o')
- cell.element.find('#lock').addClass('fa-minus-square-o')
+ cell.element.find('#lock').removeClass('fa-plus-square-o');
+ cell.element.find('#lock').addClass('fa-minus-square-o');
while (cell.metadata.solution == true) {
IPython.notebook.select_next();
cell.element.show();
cell = IPython.notebook.get_selected_cell()
}
} else {
- cell.element.find('#lock').removeClass('fa-minus-square-o')
- cell.element.find('#lock').addClass('fa-plus-square-o')
+ cell.element.find('#lock').removeClass('fa-minus-square-o');
+ cell.element.find('#lock').addClass('fa-plus-square-o');
IPython.notebook.select_next();
- cell = IPython.notebook.get_selected_cell()
+ cell = IPython.notebook.get_selected_cell();
while (cell.metadata.solution == true) {
cell.element.hide();
IPython.notebook.select_next();
@@ -49,48 +50,48 @@ define([
*/
function hide_solutions() {
// first check if lock symbol is already present in selected cell, if yes, remove it
- var cell=IPython.notebook.get_selected_cell()
- var has_lock = cell.element.find('#lock').is('div')
+ var cell=IPython.notebook.get_selected_cell();
+ var has_lock = cell.element.find('#lock').is('div');
if (has_lock === true) {
- cell.element.find('#lock').remove()
+ cell.element.find('#lock').remove();
while (cell.metadata.solution == true) {
- delete cell.metadata.solution
- cell.element.show()
- IPython.notebook.select_next()
+ delete cell.metadata.solution;
+ cell.element.show();
+ IPython.notebook.select_next();
cell = IPython.notebook.get_selected_cell()
}
} else {
// find first cell with solution
- var start_cell_i // = undefined
- var cells = IPython.notebook.get_cells()
+ var start_cell_i; // = undefined
+ var cells = IPython.notebook.get_cells();
for(var i in cells){
- var cell = cells[i]
+ var cell = cells[i];
if (typeof cell.metadata.selected != undefined && cell.metadata.selected === true) {
- start_cell_i = i
- console.log("selected start cell:",i)
+ start_cell_i = i;
+ console.log("selected start cell:", i);
break
}
}
- IPython.notebook.select(start_cell_i)
+ IPython.notebook.select(start_cell_i);
if (cell.metadata.selected == true) {
- var el = $('