##// END OF EJS Templates
mods to install mathjax from an explicitly downloaded tar or zip file
Mark Sienkiewicz at STScI -
Show More
@@ -1,9 +1,29 b''
1 1 """Utility function for installing MathJax javascript library into
2 2 the notebook's 'static' directory, for offline use.
3 3
4 Authors:
4 To download and install MathJax:
5
6 From Python:
7
8 >>> from IPython.external.mathjax import install_mathjax
9 >>> install_mathjax()
10
11 From the command line:
12
13 $ python -m IPython.external.mathjax
14
15 To install MathJax from a file you have already downloaded:
16
17 $ python -m IPython.external.mathjax mathjax-xxx.tar.gz
18 $ python -m IPython.external.mathjax mathjax-xxx.zip
19
20 It will not install MathJax if it is already there. Use -r to
21 replace the existing copy of MathJax.
22
23 To find the directory where IPython would like MathJax installed:
24
25 $ python -m IPython.external.mathjax -d
5 26
6 * Min RK
7 27 """
8 28
9 29 #-----------------------------------------------------------------------------
@@ -13,81 +33,234 b' Authors:'
13 33 # the file COPYING, distributed as part of this software.
14 34 #-----------------------------------------------------------------------------
15 35
36 # Authors:
37 #
38 # * Min RK
39 # * Mark Sienkiewicz at Space Telescope Science Institute (command line invocation)
40 #
41
16 42 #-----------------------------------------------------------------------------
17 43 # Imports
18 44 #-----------------------------------------------------------------------------
19 45
20 46 import os
21 47 import shutil
22 import urllib2
23 import tempfile
48 import sys
24 49 import tarfile
50 import urllib2
51 import zipfile
25 52
26 from IPython.utils.path import locate_profile
53 from IPython.frontend.html import notebook as nbmod
27 54
28 55 #-----------------------------------------------------------------------------
29 # Imports
56 #
30 57 #-----------------------------------------------------------------------------
31 58
32 def install_mathjax(tag='v2.0', replace=False, dest=None):
33 """Download and install MathJax for offline use.
34
35 You can use this to install mathjax to a location on your static file
36 path. This includes the `static` directory within your IPython profile,
37 which is the default location for this install.
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 ['v2.0']
47 Which tag to download. Default is 'v2.0', the current stable release,
48 but alternatives include 'v1.1' and 'master'.
49 dest : path
50 The path to the directory in which mathjax will be installed.
51 The default is `IPYTHONDIR/profile_default/static`.
52 dest must be on your notebook static_path when you run the notebook server.
53 The default location works for this.
54 """
55
56 mathjax_url = "https://github.com/mathjax/MathJax/tarball/%s" % tag
57
58 if dest is None:
59 dest = os.path.join(locate_profile('default'), 'static')
60
61 if not os.path.exists(dest):
62 os.mkdir(dest)
63
64 static = dest
65 dest = os.path.join(static, 'mathjax')
66
67 # check for existence and permissions
59 # Where mathjax will be installed.
60
61 static = os.path.join(os.path.dirname(os.path.abspath(nbmod.__file__)), 'static')
62 dest = os.path.join(static, 'mathjax')
63
64 ##
65
66 # Test for access to install mathjax.
67
68 def check_perms(replace=False):
68 69 if not os.access(static, os.W_OK):
69 raise IOError("Need have write access to %s" % static)
70 raise IOError("Need have write access to %s"%static)
70 71 if os.path.exists(dest):
71 72 if replace:
72 73 if not os.access(dest, os.W_OK):
73 raise IOError("Need have write access to %s" % dest)
74 raise IOError("Need have write access to %s"%dest)
74 75 print "removing previous MathJax install"
75 76 shutil.rmtree(dest)
77 return True
76 78 else:
77 79 print "offline MathJax apparently already installed"
78 return
79
80 # download mathjax
81 print "Downloading mathjax source from %s ..." % mathjax_url
82 response = urllib2.urlopen(mathjax_url)
83 print "done"
80 return False
81 else :
82 return True
83
84 ##
85
86 def extract_tar( fd, dest ) :
84 87 # use 'r|gz' stream mode, because socket file-like objects can't seek:
85 tar = tarfile.open(fileobj=response.fp, mode='r|gz')
88 tar = tarfile.open(fileobj=fd, mode='r|gz')
89
90 # we just happen to know that the first entry in the mathjax
91 # archive is the directory that the remaining members are in.
86 92 topdir = tar.firstmember.path
87 print "Extracting to %s" % dest
93
94 # extract the archive (contains a single directory) to the static/ directory
88 95 tar.extractall(static)
96
89 97 # it will be mathjax-MathJax-<sha>, rename to just mathjax
90 98 os.rename(os.path.join(static, topdir), dest)
91 99
100 ##
101
102 def extract_zip( fd, dest ) :
103 z = zipfile.ZipFile( fd, 'r' )
104
105 # we just happen to know that the first entry in the mathjax
106 # archive is the directory that the remaining members are in.
107 topdir = z.namelist()[0]
108
109 # extract the archive (contains a single directory) to the static/ directory
110 z.extractall( static )
111
112 # it will be mathjax-MathJax-<sha>, rename to just mathjax
113 d = os.path.join(static, topdir)
114 print d
115 os.rename(os.path.join(static, topdir), dest)
116
117 ##
118
119 def install_mathjax(tag='v1.1', replace=False, fd=None, extractor=extract_tar ):
120 """Download and install MathJax for offline use.
121
122 This will install mathjax to the 'static' dir in the IPython notebook
123 package, so it will fail if the caller does not have write access
124 to that location.
125
126 MathJax is a ~15MB download, and ~150MB installed.
127
128 Parameters
129 ----------
130
131 replace : bool [False]
132 Whether to remove and replace an existing install.
133 tag : str ['v1.1']
134 Which tag to download. Default is 'v1.1', the current stable release,
135 but alternatives include 'v1.1a' and 'master'.
136 """
137
138 if not check_perms(replace) :
139 return
140
141 if fd is None :
142 # download mathjax
143 mathjax_url = "https://github.com/mathjax/MathJax/tarball/%s"%tag
144 print "Downloading mathjax source from %s"%mathjax_url
145 response = urllib2.urlopen(mathjax_url)
146 fd = response.fp
147
148 print "Extracting to %s"%dest
149 extractor( fd, dest )
150
151 ##
152
153 def test_func( remove ) :
154 """See if mathjax appears to be installed correctly"""
155 if not os.path.isdir( dest ) :
156 print "%s directory not found"%dest
157 status=1
158 if not os.path.exists( dest + "/MathJax.js" ) :
159 print "MathJax.js not present in %s"%dest
160 status=1
161 print "ok"
162 if remove :
163 shutil.rmtree( dest )
164 return 0
165
166 ##
167
168 def main( args ) :
169 # This main is just simple enough that it is not worth the
170 # complexity of argparse
171
172 # What directory is mathjax in?
173 if '-d' in args :
174 print dest
175 return
176
177 # help
178 if '-h' in args or '--help' in args :
179 print __doc__
180 return
181
182 # remove/replace existing mathjax?
183 if '-r' in args :
184 replace = True
185 args.remove('-r')
186 else :
187 replace = False
188
189 # undocumented test interface
190 if '-test' in args :
191 return test_func( replace )
192
193 # do it
194 if len(args) == 0 :
195 # This is compatible with the interface documented in ipython 0.13
196 install_mathjax( replace=replace )
197 else :
198 fname = args[0]
199
200 # automatically detect zip/tar - could do something based
201 # on file content, but really not cost-effective here.
202 if fname.endswith('.zip') :
203 extractor = extract_zip
204 else :
205 extractor = extract_tar
206
207 # do it
208 install_mathjax(fd=open(args[0],"r"), replace=replace, extractor=extractor )
209
210 if __name__ == '__main__' :
211 sys.exit(main( sys.argv[1:] ))
92 212
93 __all__ = ['install_mathjax']
213 __all__ = ['install_mathjax','main','dest']
214
215 """
216 Test notes:
217
218 IPython uses IPython.testing.iptest as a custom test controller
219 (though it is based on nose). It might be possible to fit automatic
220 tests of installation into that framework, but it looks awkward to me.
221 So, here is a manual procedure for testing this automatic installer.
222
223 Mark Sienkiewicz, 2012-08-06
224 first 8 letters of my last name @ stsci.edu
225
226 # remove mathjax from the installed ipython instance
227 # IOError ok if mathjax was never installed yet.
228
229 python -m IPython.external.mathjax -test -r
230
231 # download and install mathjax from command line:
232
233 python -m IPython.external.mathjax
234 python -m IPython.external.mathjax -test -r
235
236 # download and install from within python
237
238 python -c "from IPython.external.mathjax import install_mathjax; install_mathjax()"
239 python -m IPython.external.mathjax -test -r
240
241 # view http://www.mathjax.org/download/ in your browser
242 # save-as the link for MathJax-1.1 near the bottom of the page.
243 # The file it offers is mathjax-MathJax-v1.1-0-g5a7e4d7.zip
244
245 python -m IPython.external.mathjax mathjax-MathJax-v1.1-0-g5a7e4d7.zip
246 python -m IPython.external.mathjax -test -r
247
248 # download https://github.com/mathjax/MathJax/tarball/v1.1 in your browser
249 # (this is the url used internally by install_mathjax)
250 # The file it offers is mathjax-MathJax-v1.1-0-g5a7e4d7.tar.gz
251
252 python -m IPython.external.mathjax mathjax-MathJax-v1.1-0-g5a7e4d7.tar.gz
253
254 python -m IPython.external.mathjax -test
255 # note no -r
256
257 # install it again while it is already there
258
259 python -m IPython.external.mathjax mathjax-MathJax-v1.1-0-g5a7e4d7.tar.gz
260 # says "offline MathJax apparently already installed"
261
262 python -m IPython.external.mathjax ~/mathjax-MathJax-v1.1-0-g5a7e4d7.tar.gz
263 python -m IPython.external.mathjax -test
264
265
266 """
@@ -340,15 +340,25 b' The IPython notebook uses the MathJax_ Javascript library for rendering LaTeX'
340 340 in web browsers. Because MathJax is large, we don't include it with
341 341 IPython. Normally IPython will load MathJax from a CDN, but if you have a slow
342 342 network connection, or want to use LaTeX without an internet connection at all,
343 we do include a utility to aid in downloading MathJax and installing it into
344 the proper location::
343 you can install MathJax locally.
344
345 A quick and easy method is to install it from a python session::
345 346
346 347 from IPython.external.mathjax import install_mathjax
347 348 install_mathjax()
348 349
349 This function does require write access to the IPython install directory, so if
350 you have a system-wide Python install, it may need to be done from a ``sudo
351 python`` session.
350 If you need tighter configuration control, you can download your own copy
351 of MathJax from http://www.mathjax.org/download/ - use the MathJax-1.1 link.
352 When you have the file stored locally, install it with::
353
354 python -m IPython.external.mathjax /path/to/source/mathjax-MathJax-v1.1-0-g5a7e4d7.zip
355
356 For unusual needs, IPython can tell you what directory it wants to find MathJax in::
357
358 python -m IPython.external.mathjax -d
359
360 All of these options require write access to the IPython install directory, so if
361 you have a system-wide Python install, it may need to be done with ``sudo``.
352 362
353 363 Browser Compatibility
354 364 ---------------------
General Comments 0
You need to be logged in to leave comments. Login now