From b072562a471675a614af02a986cc882827ce9076 Mon Sep 17 00:00:00 2001 From: sukisuki Date: Mon, 13 Apr 2015 12:10:22 -0400 Subject: [PATCH 0001/5101] fixed base64 embedding for video on python3 python 2 compatible --- IPython/core/display.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/IPython/core/display.py b/IPython/core/display.py index e353af215e3..d66bc866ef0 100644 --- a/IPython/core/display.py +++ b/IPython/core/display.py @@ -6,6 +6,7 @@ from __future__ import print_function +import base64 import json import mimetypes import os @@ -869,14 +870,14 @@ def _repr_html_(self): mimetype, encoding = mimetypes.guess_type(self.filename) video = open(self.filename, 'rb').read() - video_encoded = video.encode('base64') + video_encoded = base64.b64encode(video) else: video_encoded = self.data mimetype = self.mimetype output = """""".format(mimetype, video_encoded) + """.format(mimetype, video_encoded.decode('utf-8')) return output def reload(self): From 752eb4326a22565b36a36200981d90d738f0d599 Mon Sep 17 00:00:00 2001 From: sukisuki Date: Mon, 13 Apr 2015 12:43:02 -0400 Subject: [PATCH 0002/5101] Changed decode line: base64 can only produce ASCII characters --- IPython/core/display.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IPython/core/display.py b/IPython/core/display.py index d66bc866ef0..d69819f3eb6 100644 --- a/IPython/core/display.py +++ b/IPython/core/display.py @@ -877,7 +877,7 @@ def _repr_html_(self): output = """""".format(mimetype, video_encoded.decode('utf-8')) + """.format(mimetype, video_encoded.decode('ASCII')) return output def reload(self): From 0ca23b4f7d1943fa63e4bf2096307735afefc854 Mon Sep 17 00:00:00 2001 From: sukisuki Date: Wed, 15 Apr 2015 06:56:13 -0400 Subject: [PATCH 0003/5101] added basic test - ensure video embedding doesn't outright fail - check that the generated url is correct --- IPython/core/tests/test_display.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/IPython/core/tests/test_display.py b/IPython/core/tests/test_display.py index fca6963f5d1..5d827e32829 100644 --- a/IPython/core/tests/test_display.py +++ b/IPython/core/tests/test_display.py @@ -2,6 +2,7 @@ # Distributed under the terms of the Modified BSD License. import json +import tempfile import os import warnings @@ -149,4 +150,12 @@ def test_json(): nt.assert_equal(len(w), 1) nt.assert_equal(j._repr_json_(), lis) - +def test_video_embedding(): + """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash""" + with tempfile.NamedTemporaryFile(suffix='.mp4') as f: + with open(f.name,'wb') as f: + f.write(b'abc') + + v = display.Video(f.name, embed=True) + html = v._repr_html_() + nt.assert_in('src="data:video/mp4;base64,YWJj"',html) From e97b7e68a3bb2f4871ff75b63bb9ef3923907173 Mon Sep 17 00:00:00 2001 From: jc Date: Wed, 24 Jun 2015 11:44:25 +0300 Subject: [PATCH 0004/5101] fix to autoreload for cases when module has no __name__ attribute --- IPython/extensions/autoreload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IPython/extensions/autoreload.py b/IPython/extensions/autoreload.py index 8459dc71f08..60d95725791 100644 --- a/IPython/extensions/autoreload.py +++ b/IPython/extensions/autoreload.py @@ -186,7 +186,7 @@ def filename_and_mtime(self, module): if not hasattr(module, '__file__') or module.__file__ is None: return None, None - if module.__name__ == '__main__': + if getattr(module, '__name__', None) == '__main__': # we cannot reload(__main__) return None, None From 9e57dd2967fc8e91eddfac6333e37be6fb9d22c5 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sat, 15 Aug 2015 18:15:19 -0700 Subject: [PATCH 0005/5101] remove mathjax utils Mathjax is now part of notebook. closes #8735 --- IPython/external/mathjax.py | 234 +----------------------------------- 1 file changed, 5 insertions(+), 229 deletions(-) diff --git a/IPython/external/mathjax.py b/IPython/external/mathjax.py index 4b95befdb78..dea19cd8aa3 100644 --- a/IPython/external/mathjax.py +++ b/IPython/external/mathjax.py @@ -1,237 +1,13 @@ #!/usr/bin/python -"""Utility function for installing MathJax javascript library into -your IPython nbextensions directory, for offline use. - - Authors: - - * Min RK - * Mark Sienkiewicz - * Matthias Bussonnier - -To download and install MathJax: - -From Python: - - >>> from IPython.external.mathjax import install_mathjax - >>> install_mathjax() - -From the command line: - - $ python -m IPython.external.mathjax - -To a specific location: - - $ python -m IPython.external.mathjax -i /usr/share/ - -will install mathjax to /usr/share/mathjax - -To install MathJax from a file you have already downloaded: - - $ python -m IPython.external.mathjax mathjax-xxx.tar.gz - $ python -m IPython.external.mathjax mathjax-xxx.zip - -It will not install MathJax if it is already there. Use -r to -replace the existing copy of MathJax. - -To find the directory where IPython would like MathJax installed: - - $ python -m IPython.external.mathjax -d - """ -from __future__ import print_function - - -#----------------------------------------------------------------------------- -# Copyright (C) 2011 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- - - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -import argparse -import os -import shutil -import sys -import tarfile -import zipfile - -from IPython.paths import get_ipython_dir - -try: - from urllib.request import urlopen # Py 3 -except ImportError: - from urllib2 import urlopen - -#----------------------------------------------------------------------------- -# -#----------------------------------------------------------------------------- - -# Where mathjax will be installed - -nbextensions = os.path.join(get_ipython_dir(), 'nbextensions') -default_dest = os.path.join(nbextensions, 'mathjax') - -# Test for access to install mathjax - -def prepare_dest(dest, replace=False): - """prepare the destination folder for mathjax install - - Returns False if mathjax appears to already be installed and there is nothing to do, - True otherwise. - """ - - parent = os.path.abspath(os.path.join(dest, os.path.pardir)) - if not os.path.exists(parent): - os.makedirs(parent) - - if os.path.exists(dest): - if replace: - print("removing existing MathJax at %s" % dest) - shutil.rmtree(dest) - return True - else: - mathjax_js = os.path.join(dest, 'MathJax.js') - if not os.path.exists(mathjax_js): - raise IOError("%s exists, but does not contain MathJax.js" % dest) - print("%s already exists" % mathjax_js) - return False - else: - return True +`IPython.external.mathjax` is deprecated with IPython 4.0+ +mathjax is now install by default with the notebook package -def extract_tar(fd, dest): - """extract a tarball from filelike `fd` to destination `dest`""" - # use 'r|gz' stream mode, because socket file-like objects can't seek: - tar = tarfile.open(fileobj=fd, mode='r|gz') - - # The first entry in the archive is the top-level dir - topdir = tar.firstmember.path - - # extract the archive (contains a single directory) to the destination directory - parent = os.path.abspath(os.path.join(dest, os.path.pardir)) - tar.extractall(parent) - - # it will be mathjax-MathJax-, rename to just mathjax - os.rename(os.path.join(parent, topdir), dest) - - -def extract_zip(fd, dest): - """extract a zip file from filelike `fd` to destination `dest`""" - z = zipfile.ZipFile(fd, 'r') - - # The first entry in the archive is the top-level dir - topdir = z.namelist()[0] - - # extract the archive (contains a single directory) to the static/ directory - parent = os.path.abspath(os.path.join(dest, os.path.pardir)) - z.extractall(parent) - - # it will be mathjax-MathJax-, rename to just mathjax - os.rename(os.path.join(parent, topdir), dest) - - -def install_mathjax(tag='2.4.0', dest=default_dest, replace=False, file=None, extractor=extract_tar): - """Download and/or install MathJax for offline use. - - This will install mathjax to the nbextensions dir in your IPYTHONDIR. - - MathJax is a ~15MB download, and ~150MB installed. - - Parameters - ---------- - - replace : bool [False] - Whether to remove and replace an existing install. - dest : str [IPYTHONDIR/nbextensions/mathjax] - Where to install mathjax - tag : str ['2.4.0'] - Which tag to download. Default is '2.4.0', the current stable release, - but alternatives include 'v1.1a' and 'master'. - file : file like object [ defualt to content of https://github.com/mathjax/MathJax/tarball/#{tag}] - File handle from which to untar/unzip/... mathjax - extractor : function - Method to use to untar/unzip/... `file` - """ - try: - anything_to_do = prepare_dest(dest, replace) - except OSError as e: - print("ERROR %s, require write access to %s" % (e, dest)) - return 1 - else: - if not anything_to_do: - return 0 - - if file is None: - # download mathjax - mathjax_url = "https://github.com/mathjax/MathJax/archive/%s.tar.gz" %tag - print("Downloading mathjax source from %s" % mathjax_url) - response = urlopen(mathjax_url) - file = response.fp - - print("Extracting to %s" % dest) - extractor(file, dest) - return 0 - - -def main(): - parser = argparse.ArgumentParser( - description="""Install mathjax from internet or local archive""", - ) - - parser.add_argument( - '-i', - '--install-dir', - default=nbextensions, - help='custom installation directory. Mathjax will be installed in here/mathjax') - - parser.add_argument( - '-d', - '--print-dest', - action='store_true', - help='print where mathjax would be installed and exit') - parser.add_argument( - '-r', - '--replace', - action='store_true', - help='Whether to replace current mathjax if it already exists') - parser.add_argument('filename', - help="the local tar/zip-ball filename containing mathjax", - nargs='?', - metavar='filename') - - pargs = parser.parse_args() - - dest = os.path.join(pargs.install_dir, 'mathjax') - - if pargs.print_dest: - print(dest) - return - - # remove/replace existing mathjax? - replace = pargs.replace - - # do it - if pargs.filename: - fname = pargs.filename - - # automatically detect zip/tar - could do something based - # on file content, but really not cost-effective here. - if fname.endswith('.zip'): - extractor = extract_zip - else : - extractor = extract_tar - # do it - return install_mathjax(file=open(fname, "rb"), replace=replace, extractor=extractor, dest=dest) - else: - return install_mathjax(replace=replace, dest=dest) +""" +import sys if __name__ == '__main__' : - sys.exit(main()) + sys.exit("IPython.external.mathjax is deprecated") -__all__ = ['install_mathjax', 'main', 'default_dest'] From 8e996f80a452a7e5b1dfd85187dec8f5e7451aeb Mon Sep 17 00:00:00 2001 From: Aaron Meurer Date: Sun, 16 Aug 2015 11:35:31 -0600 Subject: [PATCH 0006/5101] Be a little smarter about invisible characters in terminal prompts This is a partial fix to #8724. Previously, only known color codes were considered to be invisible. Now, it looks for any kind of invisible sequence as defined by the \001 \002 delimiters (which is what readline uses). The situation could still be improved, as it still assumes that the number of invisible characters is constant for a given template. Making this work correctly with the existing API is awkward, so I didn't attempt it, especially since the readline frontend may be removed at some point in the near future. --- IPython/core/prompts.py | 11 +++++++++-- IPython/core/tests/test_prompts.py | 24 ++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/IPython/core/prompts.py b/IPython/core/prompts.py index 3dd9d8c0fa9..837afc6b6bb 100644 --- a/IPython/core/prompts.py +++ b/IPython/core/prompts.py @@ -257,6 +257,14 @@ def _lenlastline(s): return len(s.splitlines()[-1]) +invisible_chars_re = re.compile('\001[^\001\002]*\002') +def _invisible_characters(s): + """ + Get the number of invisible ANSI characters in s. Invisible characters + must be delimited by \001 and \002. + """ + return _lenlastline(s) - _lenlastline(invisible_chars_re.sub('', s)) + class UserNSFormatter(Formatter): """A Formatter that falls back on a shell's user_ns and __builtins__ for name resolution""" def __init__(self, shell): @@ -350,8 +358,7 @@ def update_prompt(self, name, new_template=None): self.templates[name] = multiple_replace(prompt_abbreviations, new_template) # We count invisible characters (colour escapes) on the last line of the # prompt, to calculate the width for lining up subsequent prompts. - invis_chars = _lenlastline(self._render(name, color=True)) - \ - _lenlastline(self._render(name, color=False)) + invis_chars = _invisible_characters(self._render(name, color=True)) self.invisible_chars[name] = invis_chars def _update_prompt_trait(self, traitname, new_template): diff --git a/IPython/core/tests/test_prompts.py b/IPython/core/tests/test_prompts.py index 7f128045b79..e1bcae69550 100644 --- a/IPython/core/tests/test_prompts.py +++ b/IPython/core/tests/test_prompts.py @@ -6,7 +6,7 @@ import os from IPython.testing import tools as tt, decorators as dec -from IPython.core.prompts import PromptManager, LazyEvaluate +from IPython.core.prompts import PromptManager, LazyEvaluate, _invisible_characters from IPython.testing.globalipapp import get_ipython from IPython.utils.tempdir import TemporaryWorkingDirectory from IPython.utils import py3compat @@ -106,4 +106,24 @@ def test_cwd_x(self): self.assertEqual(p, '~') finally: os.chdir(save) - + + def test_invisible_chars(self): + self.assertEqual(_invisible_characters('abc'), 0) + self.assertEqual(_invisible_characters('\001\033[1;37m\002'), 9) + # Sequences must be between \001 and \002 to be counted + self.assertEqual(_invisible_characters('\033[1;37m'), 0) + # Test custom escape sequences + self.assertEqual(_invisible_characters('\001\033]133;A\a\002'), 10) + + def test_width(self): + default_in = '\x01\x1b]133;A\x07\x02In [\\#]: \x01\x1b]133;B\x07\x02' + self.pm.in_template = default_in + self.pm.render('in') + self.assertEqual(self.pm.width, 8) + self.assertEqual(self.pm.txtwidth, 8) + + # Test custom escape sequences + self.pm.in_template = '\001\033]133;A\a\002' + default_in + '\001\033]133;B\a\002' + self.pm.render('in') + self.assertEqual(self.pm.width, 8) + self.assertEqual(self.pm.txtwidth, 8) From 1da5de91e359b46ee0db3e5672720b7cb291c546 Mon Sep 17 00:00:00 2001 From: Aaron Meurer Date: Sun, 16 Aug 2015 14:07:16 -0600 Subject: [PATCH 0007/5101] Remove dependence on execution_count in test_width --- IPython/core/tests/test_prompts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IPython/core/tests/test_prompts.py b/IPython/core/tests/test_prompts.py index e1bcae69550..024ebaa104b 100644 --- a/IPython/core/tests/test_prompts.py +++ b/IPython/core/tests/test_prompts.py @@ -116,7 +116,7 @@ def test_invisible_chars(self): self.assertEqual(_invisible_characters('\001\033]133;A\a\002'), 10) def test_width(self): - default_in = '\x01\x1b]133;A\x07\x02In [\\#]: \x01\x1b]133;B\x07\x02' + default_in = '\x01\x1b]133;A\x07\x02In [1]: \x01\x1b]133;B\x07\x02' self.pm.in_template = default_in self.pm.render('in') self.assertEqual(self.pm.width, 8) From fa0c8cb13f7013186348b022893c28c1907cf2fa Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Tue, 18 Aug 2015 10:22:27 +0200 Subject: [PATCH 0008/5101] Be more descriptive in error message. --- IPython/external/mathjax.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IPython/external/mathjax.py b/IPython/external/mathjax.py index dea19cd8aa3..1b9b80905ba 100644 --- a/IPython/external/mathjax.py +++ b/IPython/external/mathjax.py @@ -9,5 +9,5 @@ import sys if __name__ == '__main__' : - sys.exit("IPython.external.mathjax is deprecated") + sys.exit("IPython.external.mathjax is deprecated, Mathjax is now installed by default with the notebook package") From 1a273e45ce7f77678699f66775c2696695ba6da0 Mon Sep 17 00:00:00 2001 From: Alexandre Avanian Date: Wed, 19 Aug 2015 23:54:10 +0900 Subject: [PATCH 0009/5101] Fixes #8743 (warning string) Corrects "IPython_nbconvert" to "nbconvert" --- IPython/nbconvert.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IPython/nbconvert.py b/IPython/nbconvert.py index 3ae73e88dcb..5e353249513 100644 --- a/IPython/nbconvert.py +++ b/IPython/nbconvert.py @@ -10,7 +10,7 @@ from IPython.utils.shimmodule import ShimModule, ShimWarning warn("The `IPython.nbconvert` package has been deprecated. " - "You should import from ipython_nbconvert instead.", ShimWarning) + "You should import from nbconvert instead.", ShimWarning) # Unconditionally insert the shim into sys.modules so that further import calls # trigger the custom attribute access above From 7ab783188852174dacd8d28115752ab6a6c79099 Mon Sep 17 00:00:00 2001 From: naught101 Date: Thu, 20 Aug 2015 09:59:31 +1000 Subject: [PATCH 0010/5101] Row-first option for columnize --- IPython/utils/text.py | 77 ++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/IPython/utils/text.py b/IPython/utils/text.py index 5935aacaea0..9b780d29a40 100644 --- a/IPython/utils/text.py +++ b/IPython/utils/text.py @@ -618,25 +618,30 @@ def parse(self, fmt_string): # Utils to columnize a list of string #----------------------------------------------------------------------------- -def _chunks(l, n): - """Yield successive n-sized chunks from l.""" - for i in py3compat.xrange(0, len(l), n): - yield l[i:i+n] +def _col_chunks(l, nrows, row_first=False): + """Yield successive nrows-sized column chunks from l.""" + if row_first: + ncols = (len(l) // nrows) + (len(l) % nrows > 0) + for i in py3compat.xrange(ncols): + yield [l[j] for j in py3compat.xrange(i, len(l), nrows)] + else: + for i in py3compat.xrange(0, len(l), nrows): + yield l[i:(i + nrows)] -def _find_optimal(rlist , separator_size=2 , displaywidth=80): +def _find_optimal(rlist, row_first=False, separator_size=2, displaywidth=80): """Calculate optimal info to columnize a list of string""" - for nrow in range(1, len(rlist)+1) : - chk = list(map(max,_chunks(rlist, nrow))) - sumlength = sum(chk) - ncols = len(chk) - if sumlength+separator_size*(ncols-1) <= displaywidth : - break; - return {'columns_numbers' : ncols, - 'optimal_separator_width':(displaywidth - sumlength)/(ncols-1) if (ncols -1) else 0, - 'rows_numbers' : nrow, - 'columns_width' : chk - } + for nrow in range(1, len(rlist) + 1): + col_widths = list(map(max, _col_chunks(rlist, nrow, row_first))) + sumlength = sum(col_widths) + ncols = len(col_widths) + if sumlength + separator_size * (ncols - 1) <= displaywidth: + break + return {'num_columns': ncols, + 'optimal_separator_width': (displaywidth - sumlength) / (ncols - 1) if (ncols - 1) else 0, + 'num_rows': nrow, + 'column_widths': col_widths + } def _get_or_default(mylist, i, default=None): @@ -647,7 +652,7 @@ def _get_or_default(mylist, i, default=None): return mylist[i] -def compute_item_matrix(items, empty=None, *args, **kwargs) : +def compute_item_matrix(items, row_first=False, empty=None, *args, **kwargs) : """Returns a nested list, and info to columnize items Parameters @@ -655,6 +660,9 @@ def compute_item_matrix(items, empty=None, *args, **kwargs) : items list of strings to columize + row_first : (default False) + Whether to to compute columns for a row-first matrix instead ofr + column-first (default). empty : (default None) default value to fill list if needed separator_size : int (default=2) @@ -675,11 +683,11 @@ def compute_item_matrix(items, empty=None, *args, **kwargs) : dict_info some info to make columnize easier: - columns_numbers + num_columns number of columns - rows_numbers + num_rows number of rows - columns_width + column_widths list of with of each columns optimal_separator_width best separator width between columns @@ -689,24 +697,27 @@ def compute_item_matrix(items, empty=None, *args, **kwargs) : :: In [1]: l = ['aaa','b','cc','d','eeeee','f','g','h','i','j','k','l'] - ...: compute_item_matrix(l,displaywidth=12) + ...: compute_item_matrix(l, displaywidth=12) Out[1]: ([['aaa', 'f', 'k'], ['b', 'g', 'l'], ['cc', 'h', None], ['d', 'i', None], ['eeeee', 'j', None]], - {'columns_numbers': 3, - 'columns_width': [5, 1, 1], + {'num_columns': 3, + 'column_widths': [5, 1, 1], 'optimal_separator_width': 2, - 'rows_numbers': 5}) + 'num_rows': 5}) """ - info = _find_optimal(list(map(len, items)), *args, **kwargs) - nrow, ncol = info['rows_numbers'], info['columns_numbers'] - return ([[ _get_or_default(items, c*nrow+i, default=empty) for c in range(ncol) ] for i in range(nrow) ], info) + info = _find_optimal(list(map(len, items)), row_first, *args, **kwargs) + nrow, ncol = info['num_rows'], info['num_columns'] + if row_first: + return ([[_get_or_default(items, c * nrow + r, default=empty) for r in range(nrow)] for c in range(ncol)], info) + else: + return ([[_get_or_default(items, c * nrow + r, default=empty) for c in range(ncol)] for r in range(nrow)], info) -def columnize(items, separator=' ', displaywidth=80): +def columnize(items, row_first=False, separator=' ', displaywidth=80): """ Transform a list of strings into a single string with columns. Parameters @@ -714,6 +725,10 @@ def columnize(items, separator=' ', displaywidth=80): items : sequence of strings The strings to process. + row_first : (default False) + Whether to to compute columns for a row-first matrix instead ofr + column-first (default). + separator : str, optional [default is two spaces] The string that separates columns. @@ -724,11 +739,11 @@ def columnize(items, separator=' ', displaywidth=80): ------- The formatted string. """ - if not items : + if not items: return '\n' - matrix, info = compute_item_matrix(items, separator_size=len(separator), displaywidth=displaywidth) + matrix, info = compute_item_matrix(items, row_first=row_first, separator_size=len(separator), displaywidth=displaywidth) fmatrix = [filter(None, x) for x in matrix] - sjoin = lambda x : separator.join([ y.ljust(w, ' ') for y, w in zip(x, info['columns_width'])]) + sjoin = lambda x : separator.join([ y.ljust(w, ' ') for y, w in zip(x, info['column_widths'])]) return '\n'.join(map(sjoin, fmatrix))+'\n' From d0670917f0ddafee583e1b31d009c7eee6f5512f Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Thu, 20 Aug 2015 09:12:55 +0200 Subject: [PATCH 0011/5101] fix doc on extension loading --- docs/source/config/extensions/index.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/source/config/extensions/index.rst b/docs/source/config/extensions/index.rst index 5c6714648b0..fa56815e39b 100644 --- a/docs/source/config/extensions/index.rst +++ b/docs/source/config/extensions/index.rst @@ -56,9 +56,11 @@ imported, and the currently active :class:`~IPython.core.interactiveshell.Intera instance is passed as the only argument. You can do anything you want with IPython at that point. -:func:`load_ipython_extension` will be called again if you load or reload -the extension again. It is up to the extension author to add code to manage -that. +:func:`load_ipython_extension` will not be called again if the user use +`%load_extension`. The user have to explicitly ask the extension to be +reloaded (with `%reload_extension`). In case where the use ask the extension to +be reloaded, , the extension will be unloaded (with +`unload_ipython_extension`), and loaded again. Useful :class:`InteractiveShell` methods include :meth:`~IPython.core.interactiveshell.InteractiveShell.register_magic_function`, :meth:`~IPython.core.interactiveshell.InteractiveShell.push` (to add variables to the user namespace) and From 6b3ae1b146bc0e83dcfea62bd74b0c6797b41ac9 Mon Sep 17 00:00:00 2001 From: naught101 Date: Thu, 20 Aug 2015 17:59:55 +1000 Subject: [PATCH 0012/5101] fix help text --- IPython/utils/text.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IPython/utils/text.py b/IPython/utils/text.py index 9b780d29a40..9e6d50b08b9 100644 --- a/IPython/utils/text.py +++ b/IPython/utils/text.py @@ -661,7 +661,7 @@ def compute_item_matrix(items, row_first=False, empty=None, *args, **kwargs) : items list of strings to columize row_first : (default False) - Whether to to compute columns for a row-first matrix instead ofr + Whether to compute columns for a row-first matrix instead of column-first (default). empty : (default None) default value to fill list if needed @@ -726,7 +726,7 @@ def columnize(items, row_first=False, separator=' ', displaywidth=80): The strings to process. row_first : (default False) - Whether to to compute columns for a row-first matrix instead ofr + Whether to compute columns for a row-first matrix instead of column-first (default). separator : str, optional [default is two spaces] From 19e214e7706628fa4c38b4b9adf7aa55e8254712 Mon Sep 17 00:00:00 2001 From: naught101 Date: Thu, 20 Aug 2015 18:42:36 +1000 Subject: [PATCH 0013/5101] add some extra tests for row-first columnize --- IPython/utils/tests/test_text.py | 62 ++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/IPython/utils/tests/test_text.py b/IPython/utils/tests/test_text.py index a528e461bf3..303e23abff7 100644 --- a/IPython/utils/tests/test_text.py +++ b/IPython/utils/tests/test_text.py @@ -30,44 +30,60 @@ def test_columnize(): """Basic columnize tests.""" size = 5 - items = [l*size for l in 'abc'] + items = [l*size for l in 'abcd'] + out = text.columnize(items, displaywidth=80) - nt.assert_equal(out, 'aaaaa bbbbb ccccc\n') + nt.assert_equal(out, 'aaaaa bbbbb ccccc ddddd\n') + out = text.columnize(items, displaywidth=25) + nt.assert_equal(out, 'aaaaa ccccc\nbbbbb ddddd\n') out = text.columnize(items, displaywidth=12) - nt.assert_equal(out, 'aaaaa ccccc\nbbbbb\n') + nt.assert_equal(out, 'aaaaa ccccc\nbbbbb ddddd\n') out = text.columnize(items, displaywidth=10) - nt.assert_equal(out, 'aaaaa\nbbbbb\nccccc\n') + nt.assert_equal(out, 'aaaaa\nbbbbb\nccccc\nddddd\n') + + out = text.columnize(items, row_first=True, displaywidth=80) + nt.assert_equal(out, 'aaaaa bbbbb ccccc ddddd\n') + out = text.columnize(items, row_first=True, displaywidth=25) + nt.assert_equal(out, 'aaaaa bbbbb\nccccc ddddd\n') + out = text.columnize(items, row_first=True, displaywidth=12) + nt.assert_equal(out, 'aaaaa bbbbb\nccccc ddddd\n') + out = text.columnize(items, row_first=True, displaywidth=10) + nt.assert_equal(out, 'aaaaa\nbbbbb\nccccc\nddddd\n') + def test_columnize_random(): """Test with random input to hopfully catch edge case """ - for nitems in [random.randint(2,70) for i in range(2,20)]: - displaywidth = random.randint(20,200) - rand_len = [random.randint(2,displaywidth) for i in range(nitems)] - items = ['x'*l for l in rand_len] - out = text.columnize(items, displaywidth=displaywidth) - longer_line = max([len(x) for x in out.split('\n')]) - longer_element = max(rand_len) - if longer_line > displaywidth: - print("Columnize displayed something lager than displaywidth : %s " % longer_line) - print("longer element : %s " % longer_element) - print("displaywidth : %s " % displaywidth) - print("number of element : %s " % nitems) - print("size of each element :\n %s" % rand_len) - assert False + for row_first in [True, False]: + for nitems in [random.randint(2,70) for i in range(2,20)]: + displaywidth = random.randint(20,200) + rand_len = [random.randint(2,displaywidth) for i in range(nitems)] + items = ['x'*l for l in rand_len] + out = text.columnize(items, row_first=row_first, displaywidth=displaywidth) + longer_line = max([len(x) for x in out.split('\n')]) + longer_element = max(rand_len) + if longer_line > displaywidth: + print("Columnize displayed something lager than displaywidth : %s " % longer_line) + print("longer element : %s " % longer_element) + print("displaywidth : %s " % displaywidth) + print("number of element : %s " % nitems) + print("size of each element :\n %s" % rand_len) + assert False, "row_first={0}".format(row_first) def test_columnize_medium(): - """Test with inputs than shouldn't be wider tahn 80 """ + """Test with inputs than shouldn't be wider than 80""" size = 40 items = [l*size for l in 'abc'] - out = text.columnize(items, displaywidth=80) - nt.assert_equal(out, '\n'.join(items+[''])) + for row_first in [True, False]: + out = text.columnize(items, row_first=row_first, displaywidth=80) + nt.assert_equal(out, '\n'.join(items+['']), "row_first={0}".format(row_first)) def test_columnize_long(): """Test columnize with inputs longer than the display window""" size = 11 items = [l*size for l in 'abc'] - out = text.columnize(items, displaywidth=size-1) - nt.assert_equal(out, '\n'.join(items+[''])) + for row_first in [True, False]: + out = text.columnize(items, row_first=row_first, displaywidth=size-1) + nt.assert_equal(out, '\n'.join(items+['']), "row_first={0}".format(row_first)) def eval_formatter_check(f): ns = dict(n=12, pi=math.pi, stuff='hello there', os=os, u=u"café", b="café") From cafd7d46f9f85e85c4843d68ec88ab075edfb008 Mon Sep 17 00:00:00 2001 From: naught101 Date: Thu, 20 Aug 2015 19:33:30 +1000 Subject: [PATCH 0014/5101] Fix loop logic --- IPython/utils/text.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IPython/utils/text.py b/IPython/utils/text.py index 9e6d50b08b9..33c1e42032d 100644 --- a/IPython/utils/text.py +++ b/IPython/utils/text.py @@ -623,7 +623,7 @@ def _col_chunks(l, nrows, row_first=False): if row_first: ncols = (len(l) // nrows) + (len(l) % nrows > 0) for i in py3compat.xrange(ncols): - yield [l[j] for j in py3compat.xrange(i, len(l), nrows)] + yield [l[j] for j in py3compat.xrange(i, len(l), ncols)] else: for i in py3compat.xrange(0, len(l), nrows): yield l[i:(i + nrows)] @@ -712,7 +712,7 @@ def compute_item_matrix(items, row_first=False, empty=None, *args, **kwargs) : info = _find_optimal(list(map(len, items)), row_first, *args, **kwargs) nrow, ncol = info['num_rows'], info['num_columns'] if row_first: - return ([[_get_or_default(items, c * nrow + r, default=empty) for r in range(nrow)] for c in range(ncol)], info) + return ([[_get_or_default(items, r * ncol + c, default=empty) for c in range(ncol)] for r in range(nrow)], info) else: return ([[_get_or_default(items, c * nrow + r, default=empty) for c in range(ncol)] for r in range(nrow)], info) From 89f92058b5da3c5a1dac89ec7c784b7ad43148cd Mon Sep 17 00:00:00 2001 From: naught101 Date: Thu, 20 Aug 2015 19:39:40 +1000 Subject: [PATCH 0015/5101] rename num_rows etc to max_rows for clarity It can be the case when calculating row-first that the number of columns ends up allowing all cells to be accomodated in fewer rows. For example, if you have 6 items, and set nrows=4, then ncols=2, but 6 items can be accomodated in 3 rows. --- IPython/utils/text.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/IPython/utils/text.py b/IPython/utils/text.py index 33c1e42032d..2cbaa203305 100644 --- a/IPython/utils/text.py +++ b/IPython/utils/text.py @@ -618,28 +618,28 @@ def parse(self, fmt_string): # Utils to columnize a list of string #----------------------------------------------------------------------------- -def _col_chunks(l, nrows, row_first=False): - """Yield successive nrows-sized column chunks from l.""" +def _col_chunks(l, max_rows, row_first=False): + """Yield successive max_rows-sized column chunks from l.""" if row_first: - ncols = (len(l) // nrows) + (len(l) % nrows > 0) + ncols = (len(l) // max_rows) + (len(l) % max_rows > 0) for i in py3compat.xrange(ncols): yield [l[j] for j in py3compat.xrange(i, len(l), ncols)] else: - for i in py3compat.xrange(0, len(l), nrows): - yield l[i:(i + nrows)] + for i in py3compat.xrange(0, len(l), max_rows): + yield l[i:(i + max_rows)] def _find_optimal(rlist, row_first=False, separator_size=2, displaywidth=80): """Calculate optimal info to columnize a list of string""" - for nrow in range(1, len(rlist) + 1): - col_widths = list(map(max, _col_chunks(rlist, nrow, row_first))) + for max_rows in range(1, len(rlist) + 1): + col_widths = list(map(max, _col_chunks(rlist, max_rows, row_first))) sumlength = sum(col_widths) ncols = len(col_widths) if sumlength + separator_size * (ncols - 1) <= displaywidth: break return {'num_columns': ncols, 'optimal_separator_width': (displaywidth - sumlength) / (ncols - 1) if (ncols - 1) else 0, - 'num_rows': nrow, + 'max_rows': max_rows, 'column_widths': col_widths } @@ -685,8 +685,8 @@ def compute_item_matrix(items, row_first=False, empty=None, *args, **kwargs) : num_columns number of columns - num_rows - number of rows + max_rows + maximum number of rows (final number may be less) column_widths list of with of each columns optimal_separator_width @@ -707,10 +707,10 @@ def compute_item_matrix(items, row_first=False, empty=None, *args, **kwargs) : {'num_columns': 3, 'column_widths': [5, 1, 1], 'optimal_separator_width': 2, - 'num_rows': 5}) + 'max_rows': 5}) """ info = _find_optimal(list(map(len, items)), row_first, *args, **kwargs) - nrow, ncol = info['num_rows'], info['num_columns'] + nrow, ncol = info['max_rows'], info['num_columns'] if row_first: return ([[_get_or_default(items, r * ncol + c, default=empty) for c in range(ncol)] for r in range(nrow)], info) else: From 804d6ec37e0ef21ff494f3376206d58099de9628 Mon Sep 17 00:00:00 2001 From: naught101 Date: Sat, 22 Aug 2015 09:53:18 +1000 Subject: [PATCH 0016/5101] Add spread option, to allow columns to fill space. --- IPython/utils/tests/test_text.py | 9 +++++++++ IPython/utils/text.py | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/IPython/utils/tests/test_text.py b/IPython/utils/tests/test_text.py index 303e23abff7..fd2c64f6e21 100644 --- a/IPython/utils/tests/test_text.py +++ b/IPython/utils/tests/test_text.py @@ -50,6 +50,15 @@ def test_columnize(): out = text.columnize(items, row_first=True, displaywidth=10) nt.assert_equal(out, 'aaaaa\nbbbbb\nccccc\nddddd\n') + out = text.columnize(items, displaywidth=40, spread=True) + nt.assert_equal(out, 'aaaaa bbbbb ccccc ddddd\n') + out = text.columnize(items, displaywidth=20, spread=True) + nt.assert_equal(out, 'aaaaa ccccc\nbbbbb ddddd\n') + out = text.columnize(items, displaywidth=12, spread=True) + nt.assert_equal(out, 'aaaaa ccccc\nbbbbb ddddd\n') + out = text.columnize(items, displaywidth=10, spread=True) + nt.assert_equal(out, 'aaaaa\nbbbbb\nccccc\nddddd\n') + def test_columnize_random(): """Test with random input to hopfully catch edge case """ diff --git a/IPython/utils/text.py b/IPython/utils/text.py index 2cbaa203305..724fe915813 100644 --- a/IPython/utils/text.py +++ b/IPython/utils/text.py @@ -717,7 +717,7 @@ def compute_item_matrix(items, row_first=False, empty=None, *args, **kwargs) : return ([[_get_or_default(items, c * nrow + r, default=empty) for c in range(ncol)] for r in range(nrow)], info) -def columnize(items, row_first=False, separator=' ', displaywidth=80): +def columnize(items, row_first=False, separator=' ', displaywidth=80, spread=False): """ Transform a list of strings into a single string with columns. Parameters @@ -742,6 +742,8 @@ def columnize(items, row_first=False, separator=' ', displaywidth=80): if not items: return '\n' matrix, info = compute_item_matrix(items, row_first=row_first, separator_size=len(separator), displaywidth=displaywidth) + if spread: + separator = separator.ljust(int(info['optimal_separator_width'])) fmatrix = [filter(None, x) for x in matrix] sjoin = lambda x : separator.join([ y.ljust(w, ' ') for y, w in zip(x, info['column_widths'])]) return '\n'.join(map(sjoin, fmatrix))+'\n' From a1286777c99ef52ed28ff1866addb0d86b4f2d70 Mon Sep 17 00:00:00 2001 From: Yuri Numerov Date: Sat, 22 Aug 2015 03:20:41 +0200 Subject: [PATCH 0017/5101] fixed exit confirmation glitch --- IPython/core/interactiveshell.py | 4 ++-- IPython/terminal/interactiveshell.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 61079ac2a0f..3dbb7ad1e8f 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -3252,10 +3252,10 @@ def write_err(self,data): """Write a string to the default error output""" io.stderr.write(data) - def ask_yes_no(self, prompt, default=None): + def ask_yes_no(self, prompt, default=None, interrupt=None): if self.quiet: return True - return ask_yes_no(prompt,default) + return ask_yes_no(prompt,default,interrupt) def show_usage(self): """Show a usage message""" diff --git a/IPython/terminal/interactiveshell.py b/IPython/terminal/interactiveshell.py index 1a66d2e8a79..326bc864253 100644 --- a/IPython/terminal/interactiveshell.py +++ b/IPython/terminal/interactiveshell.py @@ -617,7 +617,7 @@ def exit(self): This method calls the ask_exit callback.""" if self.confirm_exit: - if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'): + if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'): self.ask_exit() else: self.ask_exit() From 1ab497b7af49feaace10a442e4e91293f3bfcd82 Mon Sep 17 00:00:00 2001 From: Yuri Numerov Date: Sat, 22 Aug 2015 03:21:23 +0200 Subject: [PATCH 0018/5101] added .swp files to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f16c98128b3..c10cded6d18 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ __pycache__ \#*# .#* .coverage +*.swp From 473a40e4480ef31122ca9594d9fd3c8303347eda Mon Sep 17 00:00:00 2001 From: Ben Rousch Date: Fri, 28 Aug 2015 16:24:57 -0400 Subject: [PATCH 0019/5101] Grammar and spelling improvements --- .../JavaScript Notebook Extensions.ipynb | 89 ++++++++++--------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/examples/Notebook/JavaScript Notebook Extensions.ipynb b/examples/Notebook/JavaScript Notebook Extensions.ipynb index db001a9f78a..70daddbaed3 100644 --- a/examples/Notebook/JavaScript Notebook Extensions.ipynb +++ b/examples/Notebook/JavaScript Notebook Extensions.ipynb @@ -11,14 +11,15 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "One of the main reason that allowed us to developp the current notebook web application \n", - "was to embrase the web technology. \n", + "One of the main reasons we developed the current notebook as a web application \n", + "is to embrace the available-everywhere web technology. \n", "\n", - "By beeing a pure web application using HTML, Javascript and CSS, the Notebook can get \n", - "all the web technology improvement for free. Thus, as browsers support for different \n", - "media extend, The notebook web app should be able to be compatible without modification. \n", + "Being a pure web application using only HTML, Javascript and CSS, the Notebook can access \n", + "all of the web technology improvements for free. Thus, as browsers support for different \n", + "media extend, the notebook web app should be compatible without modification. \n", "\n", - "This is also true with performance of the User Interface as the speed of javascript VM increase. " + "This is also true with performance of the User Interface as the speed of the Javascript \n", + "VM increases. " ] }, { @@ -27,27 +28,27 @@ "source": [ "The other advantage of using only web technology is that the code of the interface is fully accessible to the end user, and modifiable live.\n", "Even if this task is not always easy, we strive to keep our code as accessible and reusable as possible.\n", - "This should allow with minimum effort to develop small extensions that customize the behavior of the web interface. " + "This should allow - with minimum effort - development of small extensions that customize the behavior of the web interface. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Tempering with Notebook app" + "## Tampering with the Notebook app" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The first tool that is availlable to you and that you shoudl be aware of are browser \"developpers tool\". The exact naming can change across browser, and might require the installation of extensions. But basically they can allow you to inspect/modify the DOM, and interact with the javascript code that run the frontend.\n", + "The first tool that is available to you and that you should be aware of are browser \"developer tools\". The exact name of these tools is different in each browser, and might require the installation of extensions. But basically they can allow you to inspect/modify the DOM, and interact with the Javascript code that runs the frontend.\n", "\n", - " - In Chrome and safari Developper tools are in the menu [Put mmenu name in english here] \n", - " - In firefox you might need to install [Firebug](http://getfirebug.com/)\n", + " - In Chrome and Safari, Developer tools are in the menu [Menu -> More tools -> Developer Tools] \n", + " - In Firefox you might need to install [Firebug](http://getfirebug.com/)\n", " - others ?\n", " \n", - "Those will be your best friends to debug and try different approach for your extensions." + "Those will be your best friends to debug and try different approaches for your extensions." ] }, { @@ -68,12 +69,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Above tools can be tedious to edit long javascipt files. Hopefully we provide the `%%javascript` magic. This allows you to quickly inject javascript into the notebook. Still the javascript injected this way will not survive reloading. Hence it is a good tool for testing an refinig a script.\n", + "The above tools can be tedious for editing long Javascipt files. Helpfully, we provide the `%%javascript` magic. This allows you to quickly inject Javascript into the notebook. Still, the Javascript injected this way will not survive reloading. Hence, it is a good tool for testing and refining a script.\n", "\n", - "You might see here and there people modifying css and injecting js into notebook by reading file and publishing them into the notebook.\n", - "Not only this often break the flow of the notebook and make the re-execution of the notebook broken, but it also mean that you need to execute those cells on all the notebook every time you need to update the code.\n", + "You might see here and there people modifying CSS and injecting Javascript into notebook by reading files and publishing them into the notebook.\n", + "Not only does this often break the flow of the notebook and break the re-execution of the notebook, but it also means that you need to execute those cells every time you need to update the code.\n", "\n", - "This can still be usefull in some cases, like the `%autosave` magic that allows to control the time between each save. But this can be replaced by a Javascript dropdown menu to select save interval." + "This can still be useful in some cases, like the `%autosave` magic that allows you to control the time between each save. But this can be replaced by a Javascript dropdown menu to select a save interval." ] }, { @@ -84,7 +85,7 @@ }, "outputs": [], "source": [ - "## you can inspect the autosave code to see what it does.\n", + "## You can inspect the autosave code to see what it does.\n", "%autosave??" ] }, @@ -99,10 +100,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "To inject Javascript we provide an entry point: `custom.js` that allow teh user to execute and load other resources into the notebook.\n", - "Javascript code in `custom.js` will be executed when the notebook app start and can then be used to customise almost anything in the UI and in the behavior of the notebook.\n", + "To inject Javascript we provide an entry point: `custom.js` that allows the user to execute and load other resources into the notebook.\n", + "Javascript code in `custom.js` will be executed when the notebook app starts and can then be used to customize almost anything in the UI and in the behavior of the notebook.\n", "\n", - "`custom.js` can be found in IPython profile dir, and so you can have different UI modification on a per profile basis, as well as share your modfication with others." + "`custom.js` can be found in the IPython profile dir, and so you can have different UI modifications on a per-profile basis, as well as share your modfications with others." ] }, { @@ -116,8 +117,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "You have been provided with an already existing profile folder with this tutorial...\n", - "start the notebook from the root of the tutorial directory with :\n", + "You have been provided with an pre-existing profile folder with this tutorial...\n", + "Start the notebook from the root of the tutorial directory with :\n", "\n", "```bash\n", "$ ipython notebook --ProfileDir.location=./profile_euroscipy\n", @@ -181,14 +182,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Note that `custom.js` is ment to be modified by user, when writing a script, you can define it in a separate file and add a line of configuration into `custom.js` that will fetch and execute the file." + "Note that `custom.js` is meant to be modified by the user. When writing a script, you can define it in a separate file and add a line of configuration into `custom.js` that will fetch and execute the file." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Warning** : even if modification of `custom.js` take effect immediately after browser refresh (except if browser cache is aggressive), *creating* a file in `static/` directory need a **server restart**." + "**Warning** : even if modification of `custom.js` takes effect immediately after a browser refresh (except if browser cache is aggressive), *creating* a file in `static/` directory needs a **server restart**." ] }, { @@ -215,7 +216,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Have a look at [default custom.js](https://github.com/ipython/ipython/blob/1.x/IPython/html/static/custom/custom.js), to see it's content and some more explanation." + "Have a look at [default custom.js](https://github.com/ipython/ipython/blob/1.x/IPython/html/static/custom/custom.js), to see it's contents and for more explanation." ] }, { @@ -229,7 +230,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We've seen above that you can change the autosave rate by using a magic. This is typically something I don't want to type everytime, and that I don't like to embed into my workwlow and documents. (reader don't care what my autosave time is), let's build an extension that allow to do it. " + "We've seen above that you can change the autosave rate by using a magic. This is typically something I don't want to type everytime, and that I don't like to embed into my workflow and documents. (The reader doesn't care what my autosave time is), so let's build an extension that allow to do it. " ] }, { @@ -238,10 +239,10 @@ "foo": true }, "source": [ - "Create a dropdow elemement in the toolbar (DOM `IPython.toolbar.element`), you will need \n", + "Create a dropdown elemement in the toolbar (DOM `IPython.toolbar.element`). You will need \n", "\n", "- `IPython.notebook.set_autosave_interval(miliseconds)`\n", - "- know that 1min = 60 sec, and 1 sec = 1000 ms" + "- know that 1 min = 60 sec, and 1 sec = 1000 ms" ] }, { @@ -287,7 +288,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### A non interactive example first" + "#### A non-interactive example first" ] }, { @@ -301,7 +302,7 @@ "traitlets.config.cell_magic_highlight['magic_text/x-cython'].reg = [/^%%cython/]\n", "```\n", "\n", - "`text/x-cython` is the name of CodeMirror mode name, `magic_` prefix will just patch the mode so that the first line that contains a magic does not screw up the highlighting. `reg`is a list or regular expression that will trigger the change of mode." + "`text/x-cython` is the name of a CodeMirror mode name, the `magic_` prefix will just patch the mode so that the first line that contains a magic does not screw up the highlighting. `reg`is a list or regular expression that will trigger the change of mode." ] }, { @@ -315,7 +316,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Sadly you will have to read the js source file (but there are lots of comments) an/or build the javascript documentation using yuidoc.\n", + "Sadly, you will have to read the Javascript source file (but there are lots of comments) and/or build the Javascript documentation using YUIDoc.\n", "If you have `node` and `yui-doc` installed:" ] }, @@ -340,7 +341,7 @@ "info: (server): Starting server: http://127.0.0.1:3000\n", "```\n", "\n", - "and browse http://127.0.0.1:3000 to get docs" + "and browse to http://127.0.0.1:3000 to get the docs" ] }, { @@ -356,7 +357,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "By browsing the doc you will see that we have soem convenience methods that avoid to re-invent the UI everytime :\n", + "By browsing the docs you will see that we have some convenience methods that avoid re-inventing the UI everytime :\n", "```javascript\n", "IPython.toolbar.add_buttons_group([\n", " {\n", @@ -388,8 +389,8 @@ "foo": true }, "source": [ - "The most requested feature is generaly to be able to distinguish individual cell in th enotebook, or run specific action with them.\n", - "To do so, you can either use `IPython.notebook.get_selected_cell()`, or rely on `CellToolbar`. This allow you to register aset of action and graphical element that will be attached on individual cells." + "The most requested feature is generally to be able to distinguish individual cells in the notebook, or run specific actions with them.\n", + "To do so, you can either use `IPython.notebook.get_selected_cell()`, or rely on `CellToolbar`. This allows you to register a set of actions and graphical elements that will be attached to individual cells." ] }, { @@ -403,14 +404,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "You can see some example of what can be done by toggling the `Cell Toolbar` selector in the toolbar on top of the notebook. It provide two default `presets` that are `Default` and `slideshow`. Default allow edit the metadata attached to each cell manually." + "You can see some examples of what can be done by toggling the `Cell Toolbar` selector in the toolbar on top of the notebook. It provides two default `presets` that are `Default` and `slideshow`. Defaults allow editing the metadata attached to each cell manually." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "First we define a function that takes at first parameter an element on the DOM in which to inject UI element. Second element will be the cell this element will be registerd with. Then we will need to register that function ad give it a name.\n" + "First we define a function that takes as the first parameter an element on the DOM into which to inject UI element. The second element will be the cell with which this element will be registerd. Then we will need to register that function and give it a name.\n" ] }, { @@ -433,7 +434,7 @@ "var toggle = function(div, cell) {\n", " var button_container = $(div)\n", "\n", - " // let's create a button that show the current value of the metadata\n", + " // Let's create a button that shows the current value of the metadata\n", " var button = $('