mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-07 06:56:04 +08:00
170 lines
6.2 KiB
Python
170 lines
6.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Author: Óscar Nájera
|
|
# License: 3-clause BSD
|
|
"""
|
|
========================
|
|
Sphinx-Gallery Generator
|
|
========================
|
|
|
|
Attaches Sphinx-Gallery to Sphinx in order to generate the galleries
|
|
when building the documentation.
|
|
"""
|
|
|
|
|
|
from __future__ import division, print_function, absolute_import
|
|
import re
|
|
import os
|
|
from . import glr_path_static
|
|
from .gen_rst import generate_dir_rst
|
|
from .docs_resolv import embed_code_links
|
|
|
|
|
|
def clean_gallery_out(build_dir):
|
|
"""Deletes images under the sphx_glr namespace in the build directory"""
|
|
# Sphinx hack: sphinx copies generated images to the build directory
|
|
# each time the docs are made. If the desired image name already
|
|
# exists, it appends a digit to prevent overwrites. The problem is,
|
|
# the directory is never cleared. This means that each time you build
|
|
# the docs, the number of images in the directory grows.
|
|
#
|
|
# This question has been asked on the sphinx development list, but there
|
|
# was no response: http://osdir.com/ml/sphinx-dev/2011-02/msg00123.html
|
|
#
|
|
# The following is a hack that prevents this behavior by clearing the
|
|
# image build directory from gallery images each time the docs are built.
|
|
# If sphinx changes their layout between versions, this will not
|
|
# work (though it should probably not cause a crash).
|
|
# Tested successfully on Sphinx 1.0.7
|
|
|
|
build_image_dir = os.path.join(build_dir, '_images')
|
|
if os.path.exists(build_image_dir):
|
|
filelist = os.listdir(build_image_dir)
|
|
for filename in filelist:
|
|
if filename.startswith('sphx_glr') and filename.endswith('png'):
|
|
os.remove(os.path.join(build_image_dir, filename))
|
|
|
|
|
|
def generate_gallery_rst(app):
|
|
"""Generate the Main examples gallery reStructuredText
|
|
|
|
Start the sphinx-gallery configuration and recursively scan the examples
|
|
directories in order to populate the examples gallery
|
|
"""
|
|
try:
|
|
plot_gallery = eval(app.builder.config.plot_gallery)
|
|
except TypeError:
|
|
plot_gallery = bool(app.builder.config.plot_gallery)
|
|
|
|
gallery_conf.update(app.config.sphinx_gallery_conf)
|
|
gallery_conf.update(plot_gallery=plot_gallery)
|
|
gallery_conf.update(abort_on_example_error=app.builder.config.abort_on_example_error)
|
|
|
|
# this assures I can call the config in other places
|
|
app.config.sphinx_gallery_conf = gallery_conf
|
|
app.config.html_static_path.append(glr_path_static())
|
|
|
|
clean_gallery_out(app.builder.outdir)
|
|
|
|
examples_dirs = gallery_conf['examples_dirs']
|
|
gallery_dirs = gallery_conf['gallery_dirs']
|
|
|
|
if not isinstance(examples_dirs, list):
|
|
examples_dirs = [examples_dirs]
|
|
if not isinstance(gallery_dirs, list):
|
|
gallery_dirs = [gallery_dirs]
|
|
|
|
# cd to the appropriate directory regardless of sphinx configuration
|
|
working_dir = os.getcwd()
|
|
os.chdir(app.builder.srcdir)
|
|
|
|
mod_examples_dir = os.path.relpath(gallery_conf['mod_example_dir'],
|
|
app.builder.srcdir)
|
|
seen_backrefs = set()
|
|
|
|
computation_times = []
|
|
|
|
for examples_dir, gallery_dir in zip(examples_dirs, gallery_dirs):
|
|
examples_dir = os.path.relpath(examples_dir,
|
|
app.builder.srcdir)
|
|
gallery_dir = os.path.relpath(gallery_dir,
|
|
app.builder.srcdir)
|
|
|
|
for workdir in [examples_dir, gallery_dir, mod_examples_dir]:
|
|
if not os.path.exists(workdir):
|
|
os.makedirs(workdir)
|
|
# we create an index.rst with all examples
|
|
fhindex = open(os.path.join(gallery_dir, 'index.rst'), 'w')
|
|
# Here we don't use an os.walk, but we recurse only twice: flat is
|
|
# better than nested.
|
|
this_fhindex, this_computation_times = \
|
|
generate_dir_rst(examples_dir, gallery_dir, gallery_conf,
|
|
seen_backrefs)
|
|
|
|
computation_times += this_computation_times
|
|
fhindex.write(this_fhindex)
|
|
for directory in sorted(os.listdir(examples_dir)):
|
|
if os.path.isdir(os.path.join(examples_dir, directory)):
|
|
src_dir = os.path.join(examples_dir, directory)
|
|
target_dir = os.path.join(gallery_dir, directory)
|
|
this_fhindex, this_computation_times = \
|
|
generate_dir_rst(src_dir, target_dir, gallery_conf,
|
|
seen_backrefs)
|
|
fhindex.write(this_fhindex)
|
|
computation_times += this_computation_times
|
|
|
|
fhindex.flush()
|
|
# Back to initial directory
|
|
os.chdir(working_dir)
|
|
|
|
print("Computation time summary:")
|
|
for time_elapsed, fname in sorted(computation_times)[::-1]:
|
|
if time_elapsed is not None:
|
|
print("\t- %s : %.2g sec" % (fname, time_elapsed))
|
|
else:
|
|
print("\t- %s : not run" % fname)
|
|
|
|
|
|
def touch_empty_backreferences(app, what, name, obj, options, lines):
|
|
"""Generate empty back-reference example files
|
|
|
|
This avoids inclusion errors/warnings if there are no gallery
|
|
examples for a class / module that is being parsed by autodoc"""
|
|
|
|
examples_path = os.path.join(app.srcdir,
|
|
app.config.sphinx_gallery_conf["mod_example_dir"],
|
|
"%s.examples" % name)
|
|
|
|
if not os.path.exists(examples_path):
|
|
# touch file
|
|
open(examples_path, 'w').close()
|
|
|
|
|
|
gallery_conf = {
|
|
'filename_pattern': re.escape(os.sep) + 'plot',
|
|
'examples_dirs': '../examples',
|
|
'gallery_dirs': 'auto_examples',
|
|
'mod_example_dir': os.path.join('modules', 'generated'),
|
|
'doc_module': (),
|
|
'reference_url': {},
|
|
}
|
|
|
|
|
|
def setup(app):
|
|
"""Setup sphinx-gallery sphinx extension"""
|
|
app.add_config_value('plot_gallery', True, 'html')
|
|
app.add_config_value('abort_on_example_error', False, 'html')
|
|
app.add_config_value('sphinx_gallery_conf', gallery_conf, 'html')
|
|
app.add_stylesheet('gallery.css')
|
|
|
|
if 'sphinx.ext.autodoc' in app._extensions:
|
|
app.connect('autodoc-process-docstring', touch_empty_backreferences)
|
|
|
|
app.connect('builder-inited', generate_gallery_rst)
|
|
|
|
app.connect('build-finished', embed_code_links)
|
|
|
|
|
|
def setup_module():
|
|
# HACK: Stop nosetests running setup() above
|
|
pass
|