Skip to content
This repository

Install mathjax for offline use #714

Merged
merged 2 commits into from over 2 years ago

3 participants

Min RK Fernando Perez Brian E. Granger
Min RK
Owner

Add simple function to IPython.external for installing mathjax to the static dir for offline use. It checks for permission, existence, etc. and allows for installing from different tags, e.g. if you want to use stable (v1.1) or master.

All you need to do to get offline mathjax is:

from IPython.external.mathjax import install_mathjax
install_mathjax()

This could be located somewhere else, or also called from a magic, but external seemed the most logical place, since it is for bundling an external library.

I also reversed the priority of offline/cdn mathjax, so offline mathjax is preferred, since it is presumably less expensive to load. Of course, this is only true in the local network case, and a notebook server that's run from a real server would probably prefer to use the cdn. This is in a separate commit, so it's easy to rollback if we want to keep the CDN priority.

added some commits August 20, 2011
Min RK Add utility function for installing mathjax for offline use
from IPython.external.mathjax import install_mathjax

install_mathjax()

* add mathjax destination to gitignore
ff2b547
Min RK update notebook template to prefer offline mathjax 89aca0b
Fernando Perez
Owner

I actually was asking @ellisonbg about the same of switching priorities. On Friday for some odd reason the mathjax CDN was timing out on my firefox session (it seems to be some dd interaction with firebug, couldn't quite figure it out) and I had to do this switch locally just so I could keep working. But I'd like Brian to give us his take on it.

In terms of the other code, a couple of comments.

  • Let's keep IPython.external to be for the actual external library hosting, so that we know that IPython.external in principle can be empty if all dependencies are provided, for example, by a linux distro.

  • would it be possible/sensible to offer the option to do a user-level install (like the --local option)? So that people could install it without sudo access?

I'm not sure how much the latter is really needed, since you tend to only not have sudo on servers, which by definition need good net connectivity. This is mostly needed for laptops likely to be offline. I just want to float the thought before we finalize it and merge.

Min RK
Owner
  • Let's keep IPython.external to be for the actual external library hosting, so that we know that IPython.external in principle can be empty if all dependencies are provided, for example, by a linux distro.

I think this makes perfect sense...but then where should we move the Qt import code to, since it doesn't qualify? And where should the mathjax install go? IPython.utils? IPython.frontend.html.notebook.util?

The ssh code was also put into external, with the argument that it is really a standalone tool, that could be brought into another package (specifically pyzmq). It can be moved to IPython.utils as well

  • would it be possible/sensible to offer the option to do a user-level install (like the --local option)? So that people could install it without sudo access?

It would be possible, as I think was discussed on IRC or Skype, to add some location in IPYTHON_DIR, but it would mean adding three-level logic for loading MathJax: 1. user-installed, 2. IPython-lib installed, 3. CDN.

Fernando Perez
Owner

It seems to me that IPython.utils is fine... I didn't realize that we had let other things slip into external. We should probably clean that up later on, though by now we'll have to be more careful and put in deprecation warnings, as someone is likely to have started using those locations.

As for the local install, we can leave that for a future pass, if you prefer. I don't have strong feelings about it.

Brian E. Granger
Owner

I think external is a much better place than this. MathJax is a an external dependency that we would ship if it were not smaller. If we don't do external, then I think it should be in IPython.frontend.html.notebook.

Min RK
Owner

IPython.frontend.html.notebook.util is where I put it the first time, but I moved it to external, based on the idea that no users should ever actually import a 5-level-down module.

If we want IPython.external to be something that distributors can easily ship without, then we should change all our conditional external imports, such that the try/except is in the actual import, rather then relying on IPython.external to do the logic:

try:
    import package
except ImportError:
    from IPython.external import package

We frequently do just the external import, and let the IPython.external package perform the try/exceptfor whether to use the bundled version or not.

Brian E. Granger ellisonbg merged commit 89aca0b into from August 22, 2011
Brian E. Granger ellisonbg closed this August 22, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 2 unique commits by 1 author.

Aug 20, 2011
Min RK Add utility function for installing mathjax for offline use
from IPython.external.mathjax import install_mathjax

install_mathjax()

* add mathjax destination to gitignore
ff2b547
Min RK update notebook template to prefer offline mathjax 89aca0b
This page is out of date. Refresh to see the latest.
1  .gitignore
@@ -4,6 +4,7 @@ _build
4 4
 docs/man/*.gz
5 5
 docs/source/api/generated
6 6
 docs/gh-pages
  7
+IPython/frontend/html/notebook/static/mathjax
7 8
 *.py[co]
8 9
 build
9 10
 *.egg-info
82  IPython/external/mathjax.py
... ...
@@ -0,0 +1,82 @@
  1
+"""Utility function for installing MathJax javascript library into
  2
+the notebook's 'static' directory, for offline use.
  3
+
  4
+Authors:
  5
+
  6
+* Min RK
  7
+"""
  8
+
  9
+#-----------------------------------------------------------------------------
  10
+#  Copyright (C) 2008-2011  The IPython Development Team
  11
+#
  12
+#  Distributed under the terms of the BSD License.  The full license is in
  13
+#  the file COPYING, distributed as part of this software.
  14
+#-----------------------------------------------------------------------------
  15
+
  16
+#-----------------------------------------------------------------------------
  17
+# Imports
  18
+#-----------------------------------------------------------------------------
  19
+
  20
+import os
  21
+import shutil
  22
+import urllib2
  23
+import tempfile
  24
+import tarfile
  25
+
  26
+from IPython.frontend.html import notebook as nbmod
  27
+
  28
+#-----------------------------------------------------------------------------
  29
+# Imports
  30
+#-----------------------------------------------------------------------------
  31
+
  32
+def install_mathjax(tag='v1.1', replace=False):
  33
+    """Download and install MathJax for offline use.
  34
+    
  35
+    This will install mathjax to the 'static' dir in the IPython notebook
  36
+    package, so it will fail if the caller does not have write access
  37
+    to that location.
  38
+    
  39
+    MathJax is a ~15MB download, and ~150MB installed.
  40
+    
  41
+    Parameters
  42
+    ----------
  43
+    
  44
+    replace : bool [False]
  45
+        Whether to remove and replace an existing install.
  46
+    tag : str ['v1.1']
  47
+        Which tag to download. Default is 'v1.1', the current stable release,
  48
+        but alternatives include 'v1.1a' and 'master'.
  49
+    """
  50
+    mathjax_url = "https://github.com/mathjax/MathJax/tarball/%s"%tag
  51
+    
  52
+    nbdir = os.path.dirname(os.path.abspath(nbmod.__file__))
  53
+    static = os.path.join(nbdir, 'static')
  54
+    dest = os.path.join(static, 'mathjax')
  55
+    
  56
+    # check for existence and permissions
  57
+    if not os.access(static, os.W_OK):
  58
+        raise IOError("Need have write access to %s"%static)
  59
+    if os.path.exists(dest):
  60
+        if replace:
  61
+            if not os.access(dest, os.W_OK):
  62
+                raise IOError("Need have write access to %s"%dest)
  63
+            print "removing previous MathJax install"
  64
+            shutil.rmtree(dest)
  65
+        else:
  66
+            print "offline MathJax apparently already installed"
  67
+            return
  68
+    
  69
+    # download mathjax
  70
+    print "Downloading mathjax source..."
  71
+    response = urllib2.urlopen(mathjax_url)
  72
+    print "done"
  73
+    # use 'r|gz' stream mode, because socket file-like objects can't seek:
  74
+    tar = tarfile.open(fileobj=response.fp, mode='r|gz')
  75
+    topdir = tar.firstmember.path
  76
+    print "Extracting to %s"%dest
  77
+    tar.extractall(static)
  78
+    # it will be mathjax-MathJax-<sha>, rename to just mathjax
  79
+    os.rename(os.path.join(static, topdir), dest)
  80
+
  81
+
  82
+__all__ = ['install_mathjax']
10  IPython/frontend/html/notebook/templates/notebook.html
@@ -10,12 +10,14 @@
10 10
 <!--     <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
11 11
 <!--    <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
12 12
 
13  
-    <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script>
14  
-    <!-- <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script> -->
  13
+    <!-- <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script> -->
  14
+    <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script>
15 15
     <script type="text/javascript">
16 16
     if (typeof MathJax == 'undefined') {
17  
-        console.log("Trying to load local copy of MathJax");
18  
-        document.write(unescape("%3Cscript type='text/javascript' src='static/mathjax/MathJax.js%3Fconfig=TeX-AMS_HTML' charset='utf-8'%3E%3C/script%3E"));
  17
+        console.log("No local MathJax, loading from CDN");
  18
+        document.write(unescape("%3Cscript type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js%3Fconfig=TeX-AMS_HTML' charset='utf-8'%3E%3C/script%3E"));
  19
+    }else{
  20
+        console.log("Using local MathJax");
19 21
     }
20 22
     </script>
21 23
 
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.