[IPython-dev] Fix for MathJax installer bug on Windows and more

Stan West stan.west at nrl.navy.mil
Mon Aug 19 17:38:08 EDT 2013


Greetings. While using IPython.external.mathjax to install a downloaded 
ZIP file on Windows, I encountered the exception "zipfile.BadZipfile: 
File is not a zip file". The first of the attached patches resolves that 
by opening the file in binary mode. (I'm submitting patches instead of a 
pull request because I'm not on GitHub yet.)

While I was in the neighborhood, I made some other changes, offered in 
the remainder of the patches. The most significant changes are edits to 
the installation instructions for MathJax and to various strings in the 
mathjax module.

I hope that you find these helpful.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ipython-dev/attachments/20130819/33e34617/attachment.html>
-------------- next part --------------
>From 1dbc75a51d1aba4eb5cefb460e0c8d9ff8b4115c Mon Sep 17 00:00:00 2001
From: Stan West <stan.west at nrl.navy.mil>
Date: Mon, 19 Aug 2013 14:03:56 -0400
Subject: [PATCH] Open MathJax archive in binary mode.

Resolves exception "zipfile.BadZipfile: File is not a zip file" on Windows.
---
 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 2e499fe..0c40113 100644
--- a/IPython/external/mathjax.py
+++ b/IPython/external/mathjax.py
@@ -251,7 +251,7 @@ def main() :
         else :
             extractor = extract_tar
         # do it
-        install_mathjax(file=open(fname, "r"), replace=replace, extractor=extractor, dest=dest )
+        install_mathjax(file=open(fname, "rb"), replace=replace, extractor=extractor, dest=dest )
     else:
         install_mathjax(replace=replace, dest=dest)
 
-- 
1.8.3.msysgit.0

-------------- next part --------------
>From 255b834ef89d9a4125aa45a1cffe6dab48208b59 Mon Sep 17 00:00:00 2001
From: Stan West <stan.west at nrl.navy.mil>
Date: Mon, 19 Aug 2013 14:09:53 -0400
Subject: [PATCH] Close MathJax archive when done installing.

---
 IPython/external/mathjax.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/IPython/external/mathjax.py b/IPython/external/mathjax.py
index 0c40113..40456c9 100644
--- a/IPython/external/mathjax.py
+++ b/IPython/external/mathjax.py
@@ -251,7 +251,9 @@ def main() :
         else :
             extractor = extract_tar
         # do it
-        install_mathjax(file=open(fname, "rb"), replace=replace, extractor=extractor, dest=dest )
+        with open(fname, "rb") as fobj:
+            install_mathjax(file=fobj, replace=replace, extractor=extractor,
+                            dest=dest)
     else:
         install_mathjax(replace=replace, dest=dest)
 
-- 
1.8.3.msysgit.0

-------------- next part --------------
>From 7be03fdc4c62f76d845ba2d22441b2bb5a7e3bc1 Mon Sep 17 00:00:00 2001
From: Stan West <stan.west at nrl.navy.mil>
Date: Mon, 19 Aug 2013 14:22:00 -0400
Subject: [PATCH] Remove superfluous print statement in mathjax.extract_zip.

No longer prints initial extraction directory, consistent with extract_tar.
---
 IPython/external/mathjax.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/IPython/external/mathjax.py b/IPython/external/mathjax.py
index 40456c9..d203ffe 100644
--- a/IPython/external/mathjax.py
+++ b/IPython/external/mathjax.py
@@ -130,7 +130,6 @@ def extract_zip( fd, dest ) :
 
     # it will be mathjax-MathJax-<sha>, rename to just mathjax
     d = os.path.join(parent, topdir)
-    print d
     os.rename(os.path.join(parent, topdir), dest)
 
 ##
-- 
1.8.3.msysgit.0

-------------- next part --------------
>From 12daf6f1ef1bc4498aad0c0620eb488ebdd95619 Mon Sep 17 00:00:00 2001
From: Stan West <stan.west at nrl.navy.mil>
Date: Mon, 19 Aug 2013 14:53:42 -0400
Subject: [PATCH] Suppress undocumented "test" argument from MathJax installer
 help.

---
 IPython/external/mathjax.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/IPython/external/mathjax.py b/IPython/external/mathjax.py
index d203ffe..d24196c 100644
--- a/IPython/external/mathjax.py
+++ b/IPython/external/mathjax.py
@@ -216,7 +216,8 @@ def main() :
     parser.add_argument(
             '-t',
             '--test',
-            action='store_true')
+            action='store_true',
+            help=argparse.SUPPRESS)
     parser.add_argument('tarball',
             help="the local tar/zip-ball containing mathjax",
             nargs='?',
-- 
1.8.3.msysgit.0

-------------- next part --------------
>From 812e27b73e183dac2f49aac1f59c7528d616fe1e Mon Sep 17 00:00:00 2001
From: Stan West <stan.west at nrl.navy.mil>
Date: Mon, 19 Aug 2013 15:12:51 -0400
Subject: [PATCH] Edit strings in MathJax installer.

Edit argument help, print statements, docs, and exceptions.
---
 IPython/external/mathjax.py | 61 ++++++++++++++++++++++-----------------------
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/IPython/external/mathjax.py b/IPython/external/mathjax.py
index d24196c..a976918 100644
--- a/IPython/external/mathjax.py
+++ b/IPython/external/mathjax.py
@@ -1,6 +1,5 @@
 #!/usr/bin/python
-"""Utility function for installing MathJax javascript library into
-the notebook's 'static' directory, for offline use.
+"""Utility for installing the MathJax JavaScript library for offline use.
 
  Authors:
 
@@ -77,7 +76,7 @@ def check_perms(dest, replace=False):
     existing_path = filter(os.path.exists, subpaths)
     last_writable = existing_path[-1]
     if not os.access(last_writable, os.W_OK):
-        raise IOError("Need have write access to %s" % parent)
+        raise IOError('Need to have write access to "%s"' % parent)
     not_existing = [ path for path in subpaths if path not in existing_path]
     # subfolder we will create, will obviously be writable
     # should we still considere checking separately that
@@ -88,12 +87,12 @@ def check_perms(dest, replace=False):
     if os.path.exists(dest):
         if replace:
             if not os.access(dest, os.W_OK):
-                raise IOError("Need have write access to %s" % dest)
-            print "removing previous MathJax install"
+                raise IOError('Need to have write access to "%s"' % dest)
+            print "Removing previous MathJax installation."
             shutil.rmtree(dest)
             return True
         else:
-            print "offline MathJax apparently already installed"
+            print "Offline MathJax is apparently already installed."
             return False
     else :
         return True
@@ -135,28 +134,27 @@ def extract_zip( fd, dest ) :
 ##
 
 def install_mathjax(tag='v2.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 'static' dir in the IPython notebook
-    package, so it will fail if the caller does not have write access
-    to that location.
+    """Install MathJax for offline use, optionally downloading it.
 
+    This will fail if the caller does not have write access to the destination.
     MathJax is a ~15MB download, and ~150MB installed.
 
     Parameters
     ----------
 
-    replace : bool [False]
-        Whether to remove and replace an existing install.
-    dest : str [path to default profile]
-        Where to locally install mathjax
     tag : str ['v2.0']
-        Which tag to download. Default is 'v2.0', the current stable release,
+        Which tag to download.  Default is 'v2.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
+    dest : str [path to default profile]
+        Where to locally install MathJax.
+    replace : bool [False]
+        Whether to remove and replace an existing install.
+    file : file-like object [None]
+        File handle from which to extract MathJax.  If None, MathJax will be
+        downloaded from https://github.com/mathjax/MathJax/tarball/#{tag}.
     extractor : function
-        Method tu use to untar/unzip/... `file`
+        Method to use to untar/unzip/... `file`.  The default handles tar
+        files.
     """
     if not check_perms(dest, replace) :
         return
@@ -164,25 +162,25 @@ def install_mathjax(tag='v2.0', dest=default_dest, replace=False, file=None, ext
     if file is None :
         # download mathjax
         mathjax_url = "https://github.com/mathjax/MathJax/tarball/%s" % tag
-        print "Downloading mathjax source from %s" % mathjax_url
+        print "Downloading MathJax source from %s." % mathjax_url
         response = urllib2.urlopen(mathjax_url)
         file = response.fp
 
-    print "Extracting to %s" % dest
+    print 'Extracting to "%s".' % dest
     extractor( file, dest )
 
 ##
 
 def test_func( remove, dest) :
-    """See if mathjax appears to be installed correctly"""
+    """See if MathJax appears to be installed correctly."""
     status = 0
     if not os.path.isdir( dest ) :
-        print "%s directory not found" % dest
+        print 'Directory "%s" not found.' % dest
         status = 1
     if not os.path.exists( dest + "/MathJax.js" ) :
-        print "MathJax.js not present in %s" % dest
+        print 'MathJax.js not present in "%s".' % dest
         status = 1
-    print "ok"
+    print "OK."
     if remove and os.path.exists(dest):
         shutil.rmtree( dest )
     return status
@@ -195,31 +193,32 @@ def main() :
 
     # What directory is mathjax in?
     parser = argparse.ArgumentParser(
-            description="""Install mathjax from internet or local archive""",
-            )
+            description=('Install MathJax from the Internet or a local '
+                         'archive.'))
 
     parser.add_argument(
             '-i',
             '--install-dir',
             default=default_dest,
-            help='installation directory (by default : %s)' % (default_dest))
+            help='installation directory (default: %s)' % (default_dest))
     parser.add_argument(
             '-d',
             '--dest',
             action='store_true',
-            help='print where is current mathjax would be installed and exit')
+            help='print where MathJax would be installed and exit')
     parser.add_argument(
             '-r',
             '--replace',
             action='store_true',
-            help='Wether to replace current mathjax if already exist')
+            help='replace an existing MathJax in the installation directory')
     parser.add_argument(
             '-t',
             '--test',
             action='store_true',
             help=argparse.SUPPRESS)
     parser.add_argument('tarball',
-            help="the local tar/zip-ball containing mathjax",
+            help=('the local tar/zip-ball containing MathJax; omit to '
+                  'download MathJax'),
             nargs='?',
             metavar='tarball')
 
-- 
1.8.3.msysgit.0

-------------- next part --------------
>From b760b78e2a13ded8318212d5563dd3775f5da225 Mon Sep 17 00:00:00 2001
From: Stan West <stan.west at nrl.navy.mil>
Date: Mon, 19 Aug 2013 17:17:57 -0400
Subject: [PATCH] Edit installation instructions for MathJax.

Correct the command for finding the desired installation directory. Provide information about system-wide installation, as that information is not in the module.
---
 docs/source/install/install.rst | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/docs/source/install/install.rst b/docs/source/install/install.rst
index a25e305..66403b7 100644
--- a/docs/source/install/install.rst
+++ b/docs/source/install/install.rst
@@ -381,15 +381,17 @@ If you need tighter configuration control, you can download your own copy
 of MathJax from http://www.mathjax.org/download/ - use the MathJax-2.0 link.
 When you have the file stored locally, install it with::
 
-	python -m IPython.external.mathjax /path/to/source/mathjax-MathJax-v2.0-20-g07669ac.zip
+    python -m IPython.external.mathjax /path/to/source/mathjax-MathJax-v2.0-20-g07669ac.zip
 
 For unusual needs, IPython can tell you what directory it wants to find MathJax in::
 
-	python -m IPython.external.mathjax -d /some/other/mathjax
+    python -m IPython.external.mathjax -d
+
+By default, MathJax will be installed in your IPython default profile
+directory, but you can make a system-wide installation by placing the MathJax
+source into the IPython package in :file:`.../IPython/html/static/mathjax`
+(so that, for example, :file:`MathJax.js` lies in that directory).
 
-By default Mathjax will be installed in your ipython profile directory, but you
-can make system wide install, please refer to the documentation and helper function 
-of :mod:`IPython.external.mathjax`
 
 Browser Compatibility
 ---------------------
-- 
1.8.3.msysgit.0



More information about the IPython-dev mailing list