|
|
|
@@ -17,6 +17,8 @@ from StringIO import StringIO
|
|
|
|
|
import cPickle
|
|
|
|
|
import re
|
|
|
|
|
import urllib2
|
|
|
|
|
import gzip
|
|
|
|
|
import posixpath
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
from PIL import Image
|
|
|
|
@@ -53,46 +55,240 @@ class Tee(object):
|
|
|
|
|
# Documentation link resolver objects
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DocLinkResolver(object):
|
|
|
|
|
""" Resolver for packages that document each object/function on an
|
|
|
|
|
individual page """
|
|
|
|
|
def __init__(self, doc_base_url, relative=False):
|
|
|
|
|
if relative and doc_base_url.startswith('http'):
|
|
|
|
|
raise ValueError('relative and http url not supported')
|
|
|
|
|
self.doc_base_url = doc_base_url
|
|
|
|
|
def get_data(url):
|
|
|
|
|
"""Helper function to get data over http or from a local file"""
|
|
|
|
|
if url.startswith('http://'):
|
|
|
|
|
resp = urllib2.urlopen(url)
|
|
|
|
|
encoding = resp.headers.dict.get('content-encoding', 'plain')
|
|
|
|
|
data = resp.read()
|
|
|
|
|
if encoding == 'plain':
|
|
|
|
|
pass
|
|
|
|
|
elif encoding == 'gzip':
|
|
|
|
|
data = StringIO(data)
|
|
|
|
|
data = gzip.GzipFile(fileobj=data).read()
|
|
|
|
|
else:
|
|
|
|
|
raise RuntimeError('unknown encoding')
|
|
|
|
|
else:
|
|
|
|
|
with open(url, 'r') as fid:
|
|
|
|
|
data = fid.read()
|
|
|
|
|
fid.close()
|
|
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_sphinx_searchindex(searchindex):
|
|
|
|
|
"""Parse a Sphinx search index
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
|
|
|
|
searchindex : str
|
|
|
|
|
The Sphinx search index (contents of searchindex.js)
|
|
|
|
|
|
|
|
|
|
Returns
|
|
|
|
|
-------
|
|
|
|
|
filenames : list of str
|
|
|
|
|
The file names parsed from the search index.
|
|
|
|
|
objects : dict
|
|
|
|
|
The objects parsed from the search index.
|
|
|
|
|
"""
|
|
|
|
|
def _select_block(str_in, start_tag, end_tag):
|
|
|
|
|
"""Select first block delimited by start_tag and end_tag"""
|
|
|
|
|
start_pos = str_in.find(start_tag)
|
|
|
|
|
if start_pos < 0:
|
|
|
|
|
raise ValueError('start_tag not found')
|
|
|
|
|
depth = 0
|
|
|
|
|
for pos in range(start_pos, len(str_in)):
|
|
|
|
|
if str_in[pos] == start_tag:
|
|
|
|
|
depth += 1
|
|
|
|
|
elif str_in[pos] == end_tag:
|
|
|
|
|
depth -= 1
|
|
|
|
|
|
|
|
|
|
if depth == 0:
|
|
|
|
|
break
|
|
|
|
|
sel = str_in[start_pos + 1:pos]
|
|
|
|
|
return sel
|
|
|
|
|
|
|
|
|
|
def _parse_dict_recursive(dict_str):
|
|
|
|
|
"""Parse a dictionary from the search index"""
|
|
|
|
|
dict_out = dict()
|
|
|
|
|
pos_last = 0
|
|
|
|
|
pos = dict_str.find(':')
|
|
|
|
|
while pos >= 0:
|
|
|
|
|
key = dict_str[pos_last:pos]
|
|
|
|
|
if dict_str[pos + 1] == '[':
|
|
|
|
|
# value is a list
|
|
|
|
|
pos_tmp = dict_str.find(']', pos + 1)
|
|
|
|
|
if pos_tmp < 0:
|
|
|
|
|
raise RuntimeError('error when parsing dict')
|
|
|
|
|
value = dict_str[pos + 2: pos_tmp].split(',')
|
|
|
|
|
# try to convert elements to int
|
|
|
|
|
for i in range(len(value)):
|
|
|
|
|
try:
|
|
|
|
|
value[i] = int(value[i])
|
|
|
|
|
except ValueError:
|
|
|
|
|
pass
|
|
|
|
|
elif dict_str[pos + 1] == '{':
|
|
|
|
|
# value is another dictionary
|
|
|
|
|
subdict_str = _select_block(dict_str[pos:], '{', '}')
|
|
|
|
|
value = _parse_dict_recursive(subdict_str)
|
|
|
|
|
pos_tmp = pos + len(subdict_str)
|
|
|
|
|
else:
|
|
|
|
|
raise ValueError('error when parsing dict: unknown elem')
|
|
|
|
|
|
|
|
|
|
key = key.strip('"')
|
|
|
|
|
if len(key) > 0:
|
|
|
|
|
dict_out[key] = value
|
|
|
|
|
|
|
|
|
|
pos_last = dict_str.find(',', pos_tmp)
|
|
|
|
|
if pos_last < 0:
|
|
|
|
|
break
|
|
|
|
|
pos_last += 1
|
|
|
|
|
pos = dict_str.find(':', pos_last)
|
|
|
|
|
|
|
|
|
|
return dict_out
|
|
|
|
|
|
|
|
|
|
# parse objects
|
|
|
|
|
query = 'objects:'
|
|
|
|
|
pos = searchindex.find(query)
|
|
|
|
|
if pos < 0:
|
|
|
|
|
raise ValueError('"objects:" not found in search index')
|
|
|
|
|
|
|
|
|
|
sel = _select_block(searchindex[pos:], '{', '}')
|
|
|
|
|
objects = _parse_dict_recursive(sel)
|
|
|
|
|
|
|
|
|
|
# parse filenames
|
|
|
|
|
query = 'filenames:'
|
|
|
|
|
pos = searchindex.find(query)
|
|
|
|
|
if pos < 0:
|
|
|
|
|
raise ValueError('"filenames:" not found in search index')
|
|
|
|
|
filenames = searchindex[pos + len(query) + 1:]
|
|
|
|
|
filenames = filenames[:filenames.find(']')]
|
|
|
|
|
filenames = [f.strip('"') for f in filenames.split(',')]
|
|
|
|
|
|
|
|
|
|
return filenames, objects
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SphinxDocLinkResolver(object):
|
|
|
|
|
""" Resolve documentation links using searchindex.js generated by Sphinx
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
|
|
|
|
doc_url : str
|
|
|
|
|
The base URL of the project website.
|
|
|
|
|
searchindex : str
|
|
|
|
|
Filename of searchindex, relative to doc_url.
|
|
|
|
|
extra_modules_test : list of str
|
|
|
|
|
List of extra module names to test.
|
|
|
|
|
relative : bool
|
|
|
|
|
Return relative links (only useful for links to documentation of this
|
|
|
|
|
package).
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def __init__(self, doc_url, searchindex='searchindex.js',
|
|
|
|
|
extra_modules_test=[], relative=False):
|
|
|
|
|
self.doc_url = doc_url
|
|
|
|
|
self.relative = relative
|
|
|
|
|
self._link_cache = {}
|
|
|
|
|
|
|
|
|
|
def get_link(self, cobj):
|
|
|
|
|
"""Get a valid link, False if not found"""
|
|
|
|
|
link = (self.doc_base_url + '/' + cobj['module_short'] + '.'
|
|
|
|
|
+ cobj['name'] + '.html')
|
|
|
|
|
if link.startswith('http://'):
|
|
|
|
|
try:
|
|
|
|
|
resp = urllib2.urlopen(link)
|
|
|
|
|
if resp.code != 200:
|
|
|
|
|
link = False
|
|
|
|
|
except urllib2.HTTPError:
|
|
|
|
|
link = False
|
|
|
|
|
self.extra_modules_test = extra_modules_test
|
|
|
|
|
self._page_cache = {}
|
|
|
|
|
if doc_url.startswith('http://'):
|
|
|
|
|
if relative:
|
|
|
|
|
raise ValueError('Relative links are only supported for local '
|
|
|
|
|
'URLs (doc_url cannot start with "http://)"')
|
|
|
|
|
searchindex_url = doc_url + '/' + searchindex
|
|
|
|
|
else:
|
|
|
|
|
# assume it is a local file
|
|
|
|
|
if not os.path.exists(link):
|
|
|
|
|
link = False
|
|
|
|
|
searchindex_url = os.path.join(doc_url, searchindex)
|
|
|
|
|
|
|
|
|
|
if link is not False:
|
|
|
|
|
# make a link that highlights the occurence
|
|
|
|
|
link = link + '#' + cobj['module_short'] + '.' + cobj['name']
|
|
|
|
|
# detect if we are using relative links on a Windows system
|
|
|
|
|
if os.name.lower() == 'nt' and not doc_url.startswith('http://'):
|
|
|
|
|
if not relative:
|
|
|
|
|
raise ValueError('You have to use relative=True for the local'
|
|
|
|
|
'package on a Windows system.')
|
|
|
|
|
self._is_windows = True
|
|
|
|
|
else:
|
|
|
|
|
self._is_windows = False
|
|
|
|
|
|
|
|
|
|
# download and initialize the search index
|
|
|
|
|
sindex = get_data(searchindex_url)
|
|
|
|
|
filenames, objects = parse_sphinx_searchindex(sindex)
|
|
|
|
|
|
|
|
|
|
self._searchindex = dict(filenames=filenames, objects=objects)
|
|
|
|
|
|
|
|
|
|
def _get_link(self, cobj):
|
|
|
|
|
"""Get a valid link, False if not found"""
|
|
|
|
|
|
|
|
|
|
fname_idx = None
|
|
|
|
|
modules_test = [cobj['module_short']] + self.extra_modules_test
|
|
|
|
|
|
|
|
|
|
for module in modules_test:
|
|
|
|
|
full_name = module + '.' + cobj['name']
|
|
|
|
|
if full_name in self._searchindex['objects']:
|
|
|
|
|
value = self._searchindex['objects'][full_name]
|
|
|
|
|
if isinstance(value, dict):
|
|
|
|
|
value = value[value.keys()[0]]
|
|
|
|
|
fname_idx = value[0]
|
|
|
|
|
elif module in self._searchindex['objects']:
|
|
|
|
|
value = self._searchindex['objects'][module]
|
|
|
|
|
if cobj['name'] in value.keys():
|
|
|
|
|
fname_idx = value[cobj['name']][0]
|
|
|
|
|
if fname_idx is not None:
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
if fname_idx is not None:
|
|
|
|
|
fname = self._searchindex['filenames'][fname_idx] + '.html'
|
|
|
|
|
|
|
|
|
|
if self._is_windows:
|
|
|
|
|
fname = fname.replace('/', '\\')
|
|
|
|
|
link = os.path.join(self.doc_url, fname)
|
|
|
|
|
else:
|
|
|
|
|
link = posixpath.join(self.doc_url, fname)
|
|
|
|
|
|
|
|
|
|
if link in self._page_cache:
|
|
|
|
|
html = self._page_cache[link]
|
|
|
|
|
else:
|
|
|
|
|
html = get_data(link)
|
|
|
|
|
self._page_cache[link] = html
|
|
|
|
|
|
|
|
|
|
# test if cobj appears in page
|
|
|
|
|
url = False
|
|
|
|
|
for comb_name in ['%s.%s' % (module, cobj['name']) for module
|
|
|
|
|
in modules_test]:
|
|
|
|
|
if html.find(comb_name) >= 0:
|
|
|
|
|
url = link + '#' + comb_name
|
|
|
|
|
link = url
|
|
|
|
|
else:
|
|
|
|
|
link = False
|
|
|
|
|
|
|
|
|
|
return link
|
|
|
|
|
|
|
|
|
|
def resolve(self, cobj, this_url):
|
|
|
|
|
"""Resolve the link to the documentation, returns None if not found"""
|
|
|
|
|
link = self._link_cache.get(cobj['name'], None)
|
|
|
|
|
"""Resolve the link to the documentation, returns None if not found
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
|
|
|
|
cobj : dict
|
|
|
|
|
Dict with information about the "code object" for which we are
|
|
|
|
|
resolving a link.
|
|
|
|
|
cobi['name'] : function or class name (str)
|
|
|
|
|
cobj['module_short'] : shortened module name (str)
|
|
|
|
|
cobj['module'] : module name (str)
|
|
|
|
|
this_url: str
|
|
|
|
|
URL of the current page. Needed to construct relative URLs
|
|
|
|
|
(only used if relative=True in constructor).
|
|
|
|
|
|
|
|
|
|
Returns
|
|
|
|
|
-------
|
|
|
|
|
link : str | None
|
|
|
|
|
The link (URL) to the documentation.
|
|
|
|
|
"""
|
|
|
|
|
full_name = cobj['module_short'] + '.' + cobj['name']
|
|
|
|
|
link = self._link_cache.get(full_name, None)
|
|
|
|
|
if link is None:
|
|
|
|
|
# we don't have it cached
|
|
|
|
|
link = self.get_link(cobj)
|
|
|
|
|
link = self._get_link(cobj)
|
|
|
|
|
# cache it for the future
|
|
|
|
|
self._link_cache[cobj['name']] = link
|
|
|
|
|
self._link_cache[full_name] = link
|
|
|
|
|
|
|
|
|
|
if link is False or link is None:
|
|
|
|
|
# failed to resolve
|
|
|
|
@@ -100,43 +296,16 @@ class DocLinkResolver(object):
|
|
|
|
|
|
|
|
|
|
if self.relative:
|
|
|
|
|
link = os.path.relpath(link, start=this_url)
|
|
|
|
|
if self._is_windows:
|
|
|
|
|
# replace '\' with '/' so it on the web
|
|
|
|
|
link = link.replace('\\', '/')
|
|
|
|
|
|
|
|
|
|
# for some reason, the relative link goes one directory too high up
|
|
|
|
|
link = link[3:]
|
|
|
|
|
|
|
|
|
|
return link
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SinglePageDocLinkResolver(DocLinkResolver):
|
|
|
|
|
""" Resolver for packages that use pages that document several items """
|
|
|
|
|
|
|
|
|
|
def __init__(self, doc_pages_url, extra_modules_test=None):
|
|
|
|
|
super(SinglePageDocLinkResolver, self).__init__(self, None)
|
|
|
|
|
# get all the pages
|
|
|
|
|
doc_pages_html = []
|
|
|
|
|
for url in doc_pages_url:
|
|
|
|
|
try:
|
|
|
|
|
resp = urllib2.urlopen(url)
|
|
|
|
|
html = resp.read()
|
|
|
|
|
doc_pages_html.append(html)
|
|
|
|
|
except urllib2.HTTPError:
|
|
|
|
|
print 'error when retrieving %s' % url
|
|
|
|
|
doc_pages_html.append('')
|
|
|
|
|
self.doc_pages_html = doc_pages_html
|
|
|
|
|
self.doc_pages_url = doc_pages_url
|
|
|
|
|
self.extra_modules_test = extra_modules_test
|
|
|
|
|
|
|
|
|
|
def get_link(self, cobj):
|
|
|
|
|
comb_names = [cobj['module_short'] + '.' + cobj['name']]
|
|
|
|
|
if self.extra_modules_test is not None:
|
|
|
|
|
for mod in self.extra_modules_test:
|
|
|
|
|
comb_names.append(mod + '.' + cobj['name'])
|
|
|
|
|
for comb_name in comb_names:
|
|
|
|
|
# find if the item we search for appears in any of the pages
|
|
|
|
|
for html, url in zip(self.doc_pages_html, self.doc_pages_url):
|
|
|
|
|
if html.find(comb_name) >= 0:
|
|
|
|
|
return url + '#' + comb_name
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
|
rst_template = """
|
|
|
|
|
|
|
|
|
@@ -166,6 +335,29 @@ plot_rst_template = """
|
|
|
|
|
:lines: %(end_row)s-
|
|
|
|
|
|
|
|
|
|
**Total running time of the example:** %(time_elapsed) 4i seconds
|
|
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
|
|
<div class="social-button-container">
|
|
|
|
|
<div class="social-button">
|
|
|
|
|
<a href="https://twitter.com/share" class="twitter-share-button">Tweet</a>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="social-button">
|
|
|
|
|
<g:plusone annotation="inline" width="120" size="medium"></g:plusone>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="social-button">
|
|
|
|
|
<div id="fb-root"></div>
|
|
|
|
|
<script>(function(d, s, id) {
|
|
|
|
|
var js, fjs = d.getElementsByTagName(s)[0];
|
|
|
|
|
if (d.getElementById(id)) return;
|
|
|
|
|
js = d.createElement(s); js.id = id;
|
|
|
|
|
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
|
|
|
|
|
fjs.parentNode.insertBefore(js, fjs);
|
|
|
|
|
}(document, 'script', 'facebook-jssdk'));
|
|
|
|
|
</script>
|
|
|
|
|
<div class="fb-like" data-send="false" data-width="450" data-show-faces="false"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# The following strings are used when we have several pictures: we use
|
|
|
|
@@ -209,8 +401,8 @@ def extract_docstring(filename):
|
|
|
|
|
docstring = eval(tok_content)
|
|
|
|
|
# If the docstring is formatted with several paragraphs, extract
|
|
|
|
|
# the first one:
|
|
|
|
|
paragraphs = '\n'.join(line.rstrip()
|
|
|
|
|
for line in docstring.split('\n')).split('\n\n')
|
|
|
|
|
paragraphs = '\n'.join(line.rstrip() for line in
|
|
|
|
|
docstring.split('\n')).split('\n\n')
|
|
|
|
|
if len(paragraphs) > 0:
|
|
|
|
|
first_par = paragraphs[0]
|
|
|
|
|
break
|
|
|
|
@@ -291,7 +483,7 @@ def generate_dir_rst(dir, fhindex, example_dir, root_dir, plot_gallery):
|
|
|
|
|
if not os.path.exists(os.path.join(src_dir, 'README.txt')):
|
|
|
|
|
print 80 * '_'
|
|
|
|
|
print ('Example directory %s does not have a README.txt file'
|
|
|
|
|
% src_dir)
|
|
|
|
|
% src_dir)
|
|
|
|
|
print 'Skipping this directory'
|
|
|
|
|
print 80 * '_'
|
|
|
|
|
return
|
|
|
|
@@ -320,7 +512,7 @@ def generate_dir_rst(dir, fhindex, example_dir, root_dir, plot_gallery):
|
|
|
|
|
link_name = link_name[2:]
|
|
|
|
|
if dir != '.':
|
|
|
|
|
fhindex.write(' :target: ./%s/%s.html\n\n' % (dir,
|
|
|
|
|
fname[:-3]))
|
|
|
|
|
fname[:-3]))
|
|
|
|
|
else:
|
|
|
|
|
fhindex.write(' :target: ./%s.html\n\n' % link_name[:-3])
|
|
|
|
|
fhindex.write(""" :ref:`example_%s`
|
|
|
|
@@ -338,7 +530,7 @@ def generate_dir_rst(dir, fhindex, example_dir, root_dir, plot_gallery):
|
|
|
|
|
""") # clear at the end of the section
|
|
|
|
|
|
|
|
|
|
# modules for which we embed links into example code
|
|
|
|
|
DOCMODULES = ['mne', 'matplotlib', 'numpy', 'mayavi']
|
|
|
|
|
DOCMODULES = ['mne', 'matplotlib', 'numpy', 'scipy', 'mayavi']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def make_thumbnail(in_fname, out_fname, width, height):
|
|
|
|
@@ -415,7 +607,7 @@ def generate_file_rst(fname, target_dir, src_dir, plot_gallery):
|
|
|
|
|
stdout_path = os.path.join(image_dir,
|
|
|
|
|
'stdout_%s.txt' % base_image_name)
|
|
|
|
|
time_path = os.path.join(image_dir,
|
|
|
|
|
'time_%s.txt' % base_image_name)
|
|
|
|
|
'time_%s.txt' % base_image_name)
|
|
|
|
|
thumb_file = os.path.join(thumb_dir, fname[:-3] + '.png')
|
|
|
|
|
time_elapsed = 0
|
|
|
|
|
if plot_gallery:
|
|
|
|
@@ -431,8 +623,8 @@ def generate_file_rst(fname, target_dir, src_dir, plot_gallery):
|
|
|
|
|
time_elapsed = float(open(time_path).read())
|
|
|
|
|
|
|
|
|
|
if (not os.path.exists(first_image_file) or
|
|
|
|
|
os.stat(first_image_file).st_mtime <=
|
|
|
|
|
os.stat(src_file).st_mtime):
|
|
|
|
|
os.stat(first_image_file).st_mtime
|
|
|
|
|
<= os.stat(src_file).st_mtime):
|
|
|
|
|
# We need to execute the code
|
|
|
|
|
print 'plotting %s' % fname
|
|
|
|
|
t0 = time()
|
|
|
|
@@ -484,60 +676,60 @@ def generate_file_rst(fname, target_dir, src_dir, plot_gallery):
|
|
|
|
|
|
|
|
|
|
# find functions so we can later add links to the documentation
|
|
|
|
|
funregex = re.compile('[\w.]+\(')
|
|
|
|
|
fid = open(src_file, 'rt')
|
|
|
|
|
for line in fid.readlines():
|
|
|
|
|
if line.startswith('#'):
|
|
|
|
|
continue
|
|
|
|
|
for match in funregex.findall(line):
|
|
|
|
|
fun_name = match[:-1]
|
|
|
|
|
try:
|
|
|
|
|
exec('this_fun = %s' % fun_name, my_globals)
|
|
|
|
|
except Exception as err:
|
|
|
|
|
print 'extracting function failed'
|
|
|
|
|
print err
|
|
|
|
|
continue
|
|
|
|
|
this_fun = my_globals['this_fun']
|
|
|
|
|
if not callable(this_fun):
|
|
|
|
|
continue
|
|
|
|
|
if not hasattr(this_fun, '__module__'):
|
|
|
|
|
continue
|
|
|
|
|
if not isinstance(this_fun.__module__, basestring):
|
|
|
|
|
continue
|
|
|
|
|
if this_fun.__module__.split('.')[0] not in DOCMODULES:
|
|
|
|
|
with open(src_file, 'rt') as fid:
|
|
|
|
|
for line in fid.readlines():
|
|
|
|
|
if line.startswith('#'):
|
|
|
|
|
continue
|
|
|
|
|
for match in funregex.findall(line):
|
|
|
|
|
fun_name = match[:-1]
|
|
|
|
|
try:
|
|
|
|
|
exec('this_fun = %s' % fun_name, my_globals)
|
|
|
|
|
except Exception as err:
|
|
|
|
|
print 'extracting function failed'
|
|
|
|
|
print err
|
|
|
|
|
continue
|
|
|
|
|
this_fun = my_globals['this_fun']
|
|
|
|
|
if not callable(this_fun):
|
|
|
|
|
continue
|
|
|
|
|
if not hasattr(this_fun, '__module__'):
|
|
|
|
|
continue
|
|
|
|
|
if not isinstance(this_fun.__module__, basestring):
|
|
|
|
|
continue
|
|
|
|
|
if (this_fun.__module__.split('.')[0]
|
|
|
|
|
not in DOCMODULES):
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# get shortened module name
|
|
|
|
|
fun_name_short = fun_name.split('.')[-1]
|
|
|
|
|
module_short = get_short_module_name(
|
|
|
|
|
this_fun.__module__, fun_name_short)
|
|
|
|
|
cobj = {'name': fun_name_short,
|
|
|
|
|
'module': this_fun.__module__,
|
|
|
|
|
'module_short': module_short,
|
|
|
|
|
'obj_type': 'function'}
|
|
|
|
|
example_code_obj[fun_name] = cobj
|
|
|
|
|
# get shortened module name
|
|
|
|
|
fun_name_short = fun_name.split('.')[-1]
|
|
|
|
|
module_short = get_short_module_name(
|
|
|
|
|
this_fun.__module__, fun_name_short)
|
|
|
|
|
cobj = {'name': fun_name_short,
|
|
|
|
|
'module': this_fun.__module__,
|
|
|
|
|
'module_short': module_short,
|
|
|
|
|
'obj_type': 'function'}
|
|
|
|
|
example_code_obj[fun_name] = cobj
|
|
|
|
|
|
|
|
|
|
fid.close()
|
|
|
|
|
if len(example_code_obj) > 0:
|
|
|
|
|
# save the dictionary, so we can later add hyperlinks
|
|
|
|
|
codeobj_fname = example_file[:-3] + '_codeobj.pickle'
|
|
|
|
|
fid = open(codeobj_fname, 'wb')
|
|
|
|
|
cPickle.dump(example_code_obj, fid,
|
|
|
|
|
cPickle.HIGHEST_PROTOCOL)
|
|
|
|
|
with open(codeobj_fname, 'wb') as fid:
|
|
|
|
|
cPickle.dump(example_code_obj, fid,
|
|
|
|
|
cPickle.HIGHEST_PROTOCOL)
|
|
|
|
|
fid.close()
|
|
|
|
|
if '__doc__' in my_globals:
|
|
|
|
|
# The __doc__ is often printed in the example, we
|
|
|
|
|
# don't with to echo it
|
|
|
|
|
my_stdout = my_stdout.replace(
|
|
|
|
|
my_globals['__doc__'],
|
|
|
|
|
'')
|
|
|
|
|
my_stdout = my_stdout.replace(my_globals['__doc__'],
|
|
|
|
|
'')
|
|
|
|
|
my_stdout = my_stdout.strip()
|
|
|
|
|
if my_stdout:
|
|
|
|
|
output_lines = my_stdout.split('\n')
|
|
|
|
|
if len(output_lines) > MAX_NB_LINES_STDOUT:
|
|
|
|
|
output_lines = output_lines[:MAX_NB_LINES_STDOUT]
|
|
|
|
|
output_lines.append('...')
|
|
|
|
|
stdout = '**Script output**::\n\n %s\n\n' % (
|
|
|
|
|
'\n '.join(output_lines))
|
|
|
|
|
stdout = ('**Script output**::\n\n %s\n\n'
|
|
|
|
|
% ('\n '.join(output_lines)))
|
|
|
|
|
open(stdout_path, 'w').write(stdout)
|
|
|
|
|
open(time_path, 'w').write('%f' % time_elapsed)
|
|
|
|
|
os.chdir(cwd)
|
|
|
|
@@ -582,8 +774,7 @@ def generate_file_rst(fname, target_dir, src_dir, plot_gallery):
|
|
|
|
|
print " - time elapsed : %.2g sec" % time_elapsed
|
|
|
|
|
else:
|
|
|
|
|
figure_list = [f[len(image_dir):]
|
|
|
|
|
for f in glob.glob(image_path % '[1-9]')]
|
|
|
|
|
#for f in glob.glob(image_path % '*')]
|
|
|
|
|
for f in glob.glob(image_path % '[1-9]')]
|
|
|
|
|
|
|
|
|
|
# generate thumb file
|
|
|
|
|
this_template = plot_rst_template
|
|
|
|
@@ -619,29 +810,25 @@ def embed_code_links(app, exception):
|
|
|
|
|
|
|
|
|
|
# Add resolvers for the packages for which we want to show links
|
|
|
|
|
doc_resolvers = {}
|
|
|
|
|
doc_resolvers['mne'] = DocLinkResolver(
|
|
|
|
|
os.path.abspath(os.path.join(app.builder.outdir, 'generated')),
|
|
|
|
|
relative=True)
|
|
|
|
|
doc_resolvers['mne'] = SphinxDocLinkResolver(app.builder.outdir,
|
|
|
|
|
relative=True)
|
|
|
|
|
|
|
|
|
|
doc_resolvers['numpy'] = DocLinkResolver(
|
|
|
|
|
'http://docs.scipy.org/doc/numpy-1.6.0/reference/generated')
|
|
|
|
|
doc_resolvers['matplotlib'] = SphinxDocLinkResolver(
|
|
|
|
|
'http://matplotlib.org')
|
|
|
|
|
|
|
|
|
|
# matplotlib and mayavi document several items on the same page
|
|
|
|
|
doc_resolvers['matplotlib'] = SinglePageDocLinkResolver(
|
|
|
|
|
['http://matplotlib.org/api/pyplot_api.html'])
|
|
|
|
|
doc_resolvers['numpy'] = SphinxDocLinkResolver(
|
|
|
|
|
'http://docs.scipy.org/doc/numpy-1.6.0')
|
|
|
|
|
|
|
|
|
|
mayavi_base = 'http://docs.enthought.com/mayavi/mayavi/auto/'
|
|
|
|
|
doc_resolvers['mayavi'] = SinglePageDocLinkResolver(
|
|
|
|
|
[mayavi_base + 'mlab_helper_functions.html',
|
|
|
|
|
mayavi_base + 'mlab_figure.html',
|
|
|
|
|
mayavi_base + 'mlab_decorations.html',
|
|
|
|
|
mayavi_base + 'mlab_camera.html',
|
|
|
|
|
mayavi_base + 'mlab_other_functions.html'],
|
|
|
|
|
doc_resolvers['scipy'] = SphinxDocLinkResolver(
|
|
|
|
|
'http://docs.scipy.org/doc/scipy-0.11.0/reference')
|
|
|
|
|
|
|
|
|
|
doc_resolvers['mayavi'] = SphinxDocLinkResolver(
|
|
|
|
|
'http://docs.enthought.com/mayavi/mayavi',
|
|
|
|
|
extra_modules_test=['mayavi.mlab'])
|
|
|
|
|
|
|
|
|
|
example_dir = os.path.join(app.builder.srcdir, 'auto_examples')
|
|
|
|
|
html_example_dir = os.path.abspath(app.builder.outdir + '/auto_examples')
|
|
|
|
|
|
|
|
|
|
html_example_dir = os.path.abspath(os.path.join(app.builder.outdir,
|
|
|
|
|
'auto_examples'))
|
|
|
|
|
# patterns for replacement
|
|
|
|
|
link_pattern = '<a href="%s">%s</a>'
|
|
|
|
|
orig_pattern = '<span class="n">%s</span>'
|
|
|
|
@@ -651,20 +838,23 @@ def embed_code_links(app, exception):
|
|
|
|
|
for fname in filenames:
|
|
|
|
|
print '\tprocessing: %s' % fname
|
|
|
|
|
full_fname = os.path.join(html_example_dir, dirpath, fname)
|
|
|
|
|
subpath = dirpath[len(html_example_dir):]
|
|
|
|
|
pickle_fname = (example_dir + '/' + subpath + '/' + fname[:-5]
|
|
|
|
|
+ '_codeobj.pickle')
|
|
|
|
|
subpath = dirpath[len(html_example_dir) + 1:]
|
|
|
|
|
pickle_fname = os.path.join(example_dir, subpath,
|
|
|
|
|
fname[:-5] + '_codeobj.pickle')
|
|
|
|
|
|
|
|
|
|
if os.path.exists(pickle_fname):
|
|
|
|
|
# we have a pickle file with the objects to embed links for
|
|
|
|
|
fid = open(pickle_fname, 'rb')
|
|
|
|
|
example_code_obj = cPickle.load(fid)
|
|
|
|
|
with open(pickle_fname, 'rb') as fid:
|
|
|
|
|
example_code_obj = cPickle.load(fid)
|
|
|
|
|
fid.close()
|
|
|
|
|
str_repl = {}
|
|
|
|
|
# generate replacement strings with the links
|
|
|
|
|
for name, cobj in example_code_obj.iteritems():
|
|
|
|
|
this_module = cobj['module'].split('.')[0]
|
|
|
|
|
|
|
|
|
|
if this_module not in doc_resolvers:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
link = doc_resolvers[this_module].resolve(cobj,
|
|
|
|
|
full_fname)
|
|
|
|
|
if link is not None:
|
|
|
|
@@ -675,15 +865,16 @@ def embed_code_links(app, exception):
|
|
|
|
|
str_repl[name_html] = link_pattern % (link, name_html)
|
|
|
|
|
# do the replacement in the html file
|
|
|
|
|
if len(str_repl) > 0:
|
|
|
|
|
fid = open(full_fname, 'rt')
|
|
|
|
|
lines_in = fid.readlines()
|
|
|
|
|
with open(full_fname, 'rt') as fid:
|
|
|
|
|
lines_in = fid.readlines()
|
|
|
|
|
fid.close()
|
|
|
|
|
fid = open(full_fname, 'wt')
|
|
|
|
|
for line in lines_in:
|
|
|
|
|
for name, link in str_repl.iteritems():
|
|
|
|
|
line = line.replace(name, link)
|
|
|
|
|
fid.write(line)
|
|
|
|
|
with open(full_fname, 'wt') as fid:
|
|
|
|
|
for line in lines_in:
|
|
|
|
|
for name, link in str_repl.iteritems():
|
|
|
|
|
line = line.replace(name, link)
|
|
|
|
|
fid.write(line)
|
|
|
|
|
fid.close()
|
|
|
|
|
|
|
|
|
|
print '[done]'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|