pax_global_header00006660000000000000000000000064133055313450014514gustar00rootroot0000000000000052 comment=830a11c6ba5a80a4cbbaff7e2932dd37e81321a5 sphinx-gallery-0.2.0/000077500000000000000000000000001330553134500144615ustar00rootroot00000000000000sphinx-gallery-0.2.0/.gitignore000066400000000000000000000017301330553134500164520ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ lib/ lib64/ parts/ sdist/ var/ *.egg-info/ .installed.cfg *.egg .eggs # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .cache nosetests.xml coverage.xml *.orig # Translations *.mo *.pot # Django stuff: *.log # Sphinx documentation doc/_build/ doc/auto_examples doc/auto_mayavi_examples doc/tutorials/ doc/gen_modules/ # Test builds sphinx_gallery/tests/tinybuild/gen_modules/ sphinx_gallery/tests/tinybuild/auto_examples/ sphinx_gallery/tests/tinybuild/_build/ # PyBuilder target/ # General temporary files to ignore *.swp *.swo # VisualStudioCode .history sphinx-gallery-0.2.0/.travis.yml000066400000000000000000000037021330553134500165740ustar00rootroot00000000000000language: python sudo: false addons: apt: packages: - xvfb # For mayavi headless virtualenv: system_site_packages: true matrix: include: - os: linux env: DISTRIB="ubuntu" PYTHON_VERSION="2.7" addons: apt: packages: - python-numpy - python-matplotlib - python-scipy - python-pip - python-coverage - cython - python-pandas # This environment tests is for mayavi - os: linux env: DISTRIB="conda" PYTHON_VERSION="2.7" INSTALL_MAYAVI="true" # This environment tests the Python 3 versions - os: linux env: DISTRIB="conda" PYTHON_VERSION="3.4" - os: linux env: DISTRIB="conda" PYTHON_VERSION="3.5" - os: linux env: DISTRIB="conda" PYTHON_VERSION="3.6" - os: linux env: DISTRIB="conda" PYTHON_VERSION="2.7" LOCALE=C - os: linux env: DISTRIB="conda" PYTHON_VERSION="3.6" LOCALE=C - os: linux env: DISTRIB="conda" PYTHON_VERSION="2.7" SPHINX_VERSION="dev" if: type = cron - os: linux env: DISTRIB="conda" PYTHON_VERSION="3.6" SPHINX_VERSION="dev" if: type = cron before_install: # Make sure that things work even if the locale is set to C (which # effectively means ASCII). Some of the input rst files have unicode # characters and we need to deal with this gracefully. - | if [[ $LOCALE == C ]]; then export LC_CTYPE=C export LC_ALL=C export LANG=C fi install: - source continuous_integration/travis/install.sh # To test the mayavi environment follow the instructions at # https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-xvfb-to-Run-Tests-That-Require-a-GUI before_script: - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" - sleep 3 # give xvfb some time to start script: - bash continuous_integration/travis/test_script.sh after_success: - pip install codecov - codecov sphinx-gallery-0.2.0/CHANGES.rst000066400000000000000000000341031330553134500162640ustar00rootroot00000000000000Change Log ========== git master ---------- v0.2.0 ------ New features '''''''''''' * Added experimental support to auto-generate Binder links for examples via ``binder`` config. Note that this API may change in the future. `#244 `_ and `#371 `_. * Added ``ignore_pattern`` configurable to allow not adding some python files into the gallery. See `#346 `_ for more details. * Support for custom default thumbnails in 'RGBA' space `#375 `_ * Allow title only -\> use title as first paragraph `#345 `_ Bug Fixes ''''''''' * Fix name string_replace trips on projects with ".py" in path. See `#322 `_ and `#331 `_ for more details. * Fix __future__ imports across cells. See `#308 `_ for more details. * Fix encoding related issues when locale is not UTF-8. See `#311 `_ for more details. * In verbose mode, example output is printed to the console during execution of the example, rather than only at the end. See `#301 `_ for a use case where it matters. * Fix SphinxDocLinkResolver error with sphinx 1.7. See `#352 `_ for more details. * Fix unexpected interaction between ``file_pattern`` and ``expected_failing_examples``. See `#379 `_ and `#335 `_ * FIX: Use unstyled pygments for output `#384 `_ * Fix: Gallery name for paths ending with '/' `#372 `_ * Fix title detection logic. `#356 `_ * FIX: Use ``docutils_namespace`` to avoid warning in sphinx 1.8dev `#387 `_ Incompatible Changes '''''''''''''''''''' * Removed optipng feature that was triggered when the ``SKLEARN_DOC_OPTIPNG`` variable was set. See `#349 `_ for more details. * ``Backreferences_dir`` is now mandatory `#307 `_ Developer changes ''''''''''''''''' * Dropped support for Sphinx <= 1.4. * Add SphinxAppWrapper class in ``test_gen_gallery.py`` `#386 `_ * Notes on how to do a release `#360 `_ * Add codecov support `#328 `_ v0.1.13 ------- New features '''''''''''' * Added ``min_reported_time`` configurable. For examples that run faster than that threshold (in seconds), the execution time is not reported. * Add thumbnail_size option `#283 `_ * Use intersphinx for all function reference resolution `#296 `_ * Sphinx only directive for downloads `#298 `_ * Allow sorting subsection files `#281 `_ * We recommend using a string for ``plot_gallery`` rather than Python booleans, e.g. ``'True'`` instead of ``True``, as it avoids a warning about unicode when controlling this value via the command line switches of ``sphinx-build`` Bug Fixes ''''''''' * Crasher in doc_resolv, in js_index.loads `#287 `_ * Fix gzip/BytesIO error `#293 `_ * Deactivate virtualenv provided by Travis `#294 `_ Developer changes ''''''''''''''''' * Push the docs from Circle CI into github `#268 `_ * Report version to sphinx. `#292 `_ * Minor changes to log format. `#285 `_ and `#291 `_ v0.1.12 ------- New features '''''''''''' * Implement a explicit order sortkey to specify the subsection's order within a gallery. Refer to discussion in `#37 `_, `#233 `_ and `#234 `_ * Cleanup console output during build `#250 `_ * New configuration Test `#225 `_ Bug Fixes ''''''''' * Reset ``sys.argv`` before running each example. See `#252 `_ for more details. * Correctly re-raise errors in doc resolver. See `#264 `_. * Allow and use https links where possible `#258 `_. * Escape tooltips for any HTML special characters. `#249 `_ Documentation ''''''''''''''' * Update link to numpy to point to latest `#271 `_ * Added documentation dependencies. `#267 `_ v0.1.11 ------- Documentation ''''''''''''''' * Frequently Asked Questions added to Documentation. Why `__file__` is not defined? Bug Fixed ''''''''' * Changed attribute name of Sphinx `app` object in `#242 `_ v0.1.10 ------- Bug Fixed ''''''''' * Fix image path handling bug introduced in #218 v0.1.9 ------ Incompatible Changes '''''''''''''''''''' * Sphinx Gallery's example back-references are deactivated by default. Now it is users responsibility to turn them on and set the directory where to store the files. See discussion in `#126 `_ and pull request `#151 `_. Bug Fixed ''''''''' * Fix download zip files path in windows builds. See `#218 `_ * Fix embedded missing link. See `#214 `_ Developer changes ''''''''''''''''' * Move testing to py.test * Include link to github repository in documentation v0.1.8 ------ New features '''''''''''' * Drop styling in codelinks tooltip. Replaced for title attribute which is managed by the browser. * Gallery output is shorter when embedding links * Circle CI testing Bug Fixes ''''''''' * Sphinx-Gallery build even if examples have Syntax errors. See `#177 `_ * Sphinx-Gallery can now build by directly calling sphinx-build from any path, no explicit need to run the Makefile from the sources directory. See `#190 `_ for more details. v0.1.7 ------ Bug Fixes ''''''''' * Released Sphinx 1.5 has new naming convention for auto generated files and breaks Sphinx-Gallery documentation scanner. Fixed in `#178 `_, work for linking to documentation generated with Sphinx<1.5 and for new docs post 1.5 * Code links tooltip are now left aligned with code New features '''''''''''' * Development support of Sphinx-Gallery on Windows `#179 `_ & `#182 `_ v0.1.6 ---------- New features '''''''''''' * Executable script to convert Python scripts into Jupyter Notebooks `#148 `_ Bug Fixes ''''''''' * Sphinx-Gallery now raises an exception if the matplotlib bakend can not be set to ``'agg'``. This can happen for example if matplotlib.pyplot is imported in conf.py. See `#157 `_ for more details. * Fix ``backreferences.identify_names`` when module is used without attribute `#173 `_. Closes `#172 `_ and `#149 `_ * Raise FileNotFoundError when README.txt is not present in the main directory of the examples gallery(`#164 `_). Also include extra empty lines after reading README.txt to obtain the correct rendering of the html file.(`#165 `_) * Ship a License file in PyPI release v0.1.5 ------ New features '''''''''''' * CSS. Now a tooltip is displayed on the source code blocks to make the doc-resolv functionality more discorverable. Function calls in the source code blocks are hyperlinks to their online documentation. * Download buttons have a nicer look across all themes offered by Sphinx Developer changes ''''''''''''''''' * Support on the fly theme change for local builds of the Sphinx-Gallery docs. Passing to the make target the variable `theme` builds the docs with the new theme. All sphinx themes are available plus read the docs online theme under the value `rtd` as shown in this usage example.:: $ make html theme=rtd * Test Sphinx Gallery support on Ubuntu 14 packages, drop Ubuntu 12 support. Drop support for Python 2.6 in the conda environment v0.1.4 ------ New features '''''''''''' * Enhanced CSS for download buttons * Download buttons at the end of the gallery to download all python scripts or Jupyter notebooks together in a zip file. New config variable `download_all_examples` to toggle this effect. Activated by default * Downloadable zip file with all examples as Python scripts and notebooks for each gallery * Improved conversion of rst directives to markdown for the Jupyter notebook text blocks Bug Fixes ''''''''' * When seaborn is imported in a example the plot style preferences are transferred to plots executed afterwards. The CI is set up such that users can follow how to get the compatible versions of mayavi-pandas-seaborn and nomkl in a conda environment to have all the features available. * Fix math conversion from example rst to Jupyter notebook text for inline math and multi-line equations v0.1.3 ------ New features '''''''''''' * Summary of failing examples with traceback at the end of the sphinx build. By default the build exits with a 1 exit code if an example has failed. A list of examples that are expected to fail can be defined in `conf.py` and exit the build with 0 exit code. Alternatively it is possible to exit the build as soon as one example has failed. * Print aggregated and sorted list of computation times of all examples in the console during the build. * For examples that create multiple figures, set the thumbnail image. * The ``plot_gallery`` and ``abort_on_example_error`` options can now be specified in ``sphinx_gallery_conf``. The build option (``-D`` flag passed to ``sphinx-build``) takes precedence over the ``sphinx_gallery_conf`` option. Bug Fixes ''''''''' * Failing examples are retried on every build v0.1.2 ------ Bug Fixes ''''''''' * Examples that use ``if __name__ == '__main__'`` guards are now run * Added vertical space between code output and code source in non notebook examples v0.1.1 ------ Bug Fixes ''''''''' * Restore the html-noplot functionality * Gallery CSS now implicitly enforces thumbnails width v0.1.0 ------ Highlights '''''''''' Example scripts are now available for download as IPython Notebooks `#75 `_ New features '''''''''''' * Configurable filename pattern to select which example scripts are executed while building the Gallery * Examples script update check are now by md5sum check and not date * Broken Examples now display a Broken thumbnail in the gallery view, inside the rendered example traceback is printed. User can also set build process to abort as soon as an example fails. * Sorting examples by script size * Improve examples style v0.0.11 ------- Highlights '''''''''' This release incorporates the Notebook styled examples for the gallery with PR `#36 `_ Incompatible Changes '''''''''''''''''''' Sphinx-Gallery renames its python module name to sphinx\_gallery this follows the discussion raised in `#47 `_ and resolved with `#66 `_ The gallery configuration dictionary also changes its name to ``sphinx_gallery_conf`` From PR `#36 `_ it is decided into a new namespace convention for images, thumbnails and references. See `comment `_ v0.0.10 ------- Highlights '''''''''' This release allows to use the Back references. This features incorporates fine grained examples galleries listing examples using a particular function. `#26 `_ New features '''''''''''' * Shell script to place a local copy of Sphinx-Gallery in your project * Support Mayavi plots in the gallery sphinx-gallery-0.2.0/LICENSE000066400000000000000000000027161330553134500154740ustar00rootroot00000000000000Copyright (c) 2015, Óscar Nájera All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of sphinx-gallery nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sphinx-gallery-0.2.0/MANIFEST.in000066400000000000000000000000441330553134500162150ustar00rootroot00000000000000include CHANGES.rst include LICENSE sphinx-gallery-0.2.0/README.rst000066400000000000000000000161661330553134500161620ustar00rootroot00000000000000=================================== Getting Started with Sphinx-Gallery =================================== .. image:: https://travis-ci.org/sphinx-gallery/sphinx-gallery.svg?branch=master :target: https://travis-ci.org/sphinx-gallery/sphinx-gallery .. image:: https://readthedocs.org/projects/sphinx-gallery/badge/?version=latest :target: https://sphinx-gallery.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status .. image:: https://ci.appveyor.com/api/projects/status/github/sphinx-gallery/sphinx-gallery?branch=master&svg=true :target: https://ci.appveyor.com/project/Titan-C/sphinx-gallery/history A Sphinx extension that builds an HTML version of any Python script and puts it into an examples gallery. It is extracted from the scikit-learn project and aims to be an independent general purpose extension. Who uses Sphinx-Gallery ======================= * `Sphinx-Gallery `_ * `Scikit-learn `_ * `Nilearn `_ * `MNE-python `_ * `PyStruct `_ * `GIMLi `_ * `Nestle `_ * `pyRiemann `_ * `scikit-image `_ * `Astropy `_ * `SunPy `_ * `PySurfer `_ * `Matplotlib `_ `Examples `_ and `Tutorials `__ * `PyTorch tutorials `_ * `Cartopy `_ Getting the package =================== You can do a direct install via pip by using: .. code-block:: bash $ pip install sphinx-gallery Sphinx-Gallery will not manage its dependencies when installing, thus you are required to install them manually. Our minimal dependencies are: * Sphinx * Matplotlib * Pillow Sphinx-Gallery has also support for packages like: * Seaborn * Mayavi Install as developer -------------------- You can get the latest development source from our `Github repository `_. You need ``setuptools`` installed in your system to install Sphinx-Gallery. You will also need to install the dependencies listed above and `pytest` To install everything do: .. code-block:: bash $ git clone https://github.com/sphinx-gallery/sphinx-gallery $ cd sphinx-gallery $ pip install -r requirements.txt $ python setup.py develop In addition, you will need the following dependencies to build the documentation: * Scipy * Seaborn .. _set_up_your_project: Set up your project =================== Let's say your Python project looks like this:: . ├── doc │ ├── conf.py │ ├── index.rst │ └── Makefile ├── py_module │ ├── __init__.py │ └── mod.py └── examples ├── plot_example.py ├── example.py └── README.txt Your Python module is on ``py_module``, examples on how to use it are in ``examples`` and the ``doc`` folder hold the base documentation structure you get from executing ``sphinx-quickstart``. To get Sphinx-Gallery into your project we have to extend the Sphinx ``doc/conf.py`` file with:: extensions = [ ... 'sphinx_gallery.gen_gallery', ] This is to load Sphinx-Gallery as one of your extensions, the ellipsis ``...`` is to represent your other loaded extensions. Now to declare your project structure, we add a configuration dictionary for Sphinx-Gallery. The examples directory ``../examples`` is declared with a relative path from the ``conf.py`` file location:: sphinx_gallery_conf = { # path to your examples scripts 'examples_dirs': '../examples', # path where to save gallery generated examples 'gallery_dirs': 'auto_examples', } The ``gallery_dirs`` is the folder where Sphinx-Gallery will store the converted Python scripts into rst files that Sphinx will process into HTML. The structure of the examples folder ------------------------------------ There are some extra instructions on how to present your examples to Sphinx-Gallery. * A mandatory ``README.txt`` file with rst syntax to introduce your gallery * ``plot_examples.py`` files: Python scripts that have to be executed and output a plot that will be presented in your gallery * ``examples.py`` files: Python scripts that will not be executed but will be presented in the gallery All the Python scripts in the examples folder need to have a docstring. Written in rst syntax as it is used in the generated file for the example gallery. You can have sub-folders in your ``examples`` directory, those will be processed by the gallery extension and presented in the gallery, as long as they also have a ``README.txt`` file. Sub-folders have to respect the same structure examples folder. If these instructions are not clear enough, this package uses itself, to generated its own example gallery. So check the directory structure and the contents of the files. Building the documentation locally ---------------------------------- In your sphinx documentation directory, ``doc`` execute: .. code-block:: bash $ make html This will start the build of your complete documentation including the examples gallery. Once documentation is build, our extension will have generated an ``auto_examples`` directory and populated it with rst files containing the gallery and each example. Sphinx gives this files its regular processing and you can enjoy your generated gallery under the same path. That means you will find the gallery in the path: .. code-block:: bash _build/html/auto_examples/index.html that you can open under your favorite browser. Once a build is completed all your examples outputs are in cache. Thus future rebuilds of your project will not trigger the full execution of all your examples saving your a large amount of time on each iteration. Only examples which have changed (comparison evaluated by md5sum) are built again. Extending your Makefile ----------------------- Once your gallery is working you might need remove completely all generated files by sphinx-gallery to have a clean build, or you might want to build the gallery without running the examples files. For this you need to extend your ``Makefile`` with: .. code-block:: bash clean: rm -rf $(BUILDDIR)/* rm -rf auto_examples/ html-noplot: $(SPHINXBUILD) -D plot_gallery=0 -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." Remember that for ``Makefile`` white space is significant and the indentation are tabs and not spaces sphinx-gallery-0.2.0/appveyor.yml000066400000000000000000000023261330553134500170540ustar00rootroot00000000000000 # CI on Windows via appveyor # This file was based on Olivier Grisel's python-appveyor-demo environment: global: PYTHON: "C:\\conda" MINICONDA_VERSION: "latest" CONDA_DEPENDENCIES: "numpy seaborn matplotlib sphinx pillow pytest pytest-cov" matrix: - PYTHON_VERSION: "2.7" PYTHON_ARCH: "64" - PYTHON_VERSION: "3.5" PYTHON_ARCH: "64" platform: -x64 install: - "git clone git://github.com/astropy/ci-helpers.git" - "powershell ci-helpers/appveyor/install-miniconda.ps1" - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - "activate test" # mayavi only available for Python 2.7 through conda - 'IF "%PYTHON_VERSION%"=="2.7" ( conda install mayavi )' build: false # Not a C# project, build stuff at the test step instead. test_script: - python setup.py develop - pytest sphinx_gallery # Build the docs - cd doc # The Makefile doesn't work directly on Windows PowerShell because of # slashes (but will work e.g. in Msys-git), so for now do these manually # make html-noplot - sphinx-build -D plot_gallery=0 -b html -d _build\doctrees . _build\html # make html - sphinx-build -b html -d _build\doctrees . _build\html artifacts: - path: doc\_build\html sphinx-gallery-0.2.0/bin/000077500000000000000000000000001330553134500152315ustar00rootroot00000000000000sphinx-gallery-0.2.0/bin/copy_sphinxgallery.sh000077500000000000000000000004441330553134500215150ustar00rootroot00000000000000#!/bin/sh # Script to do a local install of sphinx-gallery rm -rf tmp sphinx_gallery easy_install -Zeab tmp sphinx-gallery cp -vru tmp/sphinx-gallery/sphinx_gallery/ . echo "Remember to add sphinx_gallery to your version control" echo "Use in case of git:" echo "$ git add sphinx_gallery" sphinx-gallery-0.2.0/bin/sphx_glr_python_to_jupyter.py000077500000000000000000000007141330553134500233230ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- r""" Sphinx Gallery Notebook converter ================================= Exposes the Sphinx-Gallery Notebook renderer to directly convert Python scripts into Jupyter Notebooks. """ # Author: Óscar Nájera # License: 3-clause BSD from __future__ import division, absolute_import, print_function from sphinx_gallery.notebook import python_to_jupyter_cli if __name__ == '__main__': python_to_jupyter_cli() sphinx-gallery-0.2.0/circle.yml000066400000000000000000000031521330553134500164460ustar00rootroot00000000000000machine: environment: # We need to set this variable to let Anaconda take precedence PATH: "/home/ubuntu/miniconda/envs/circleenv/bin:/home/ubuntu/miniconda/bin:$PATH" dependencies: pre: # Disable pyenv (no cleaner way provided by CircleCI as it prepends pyenv version to PATH) - sudo apt-get update - sudo apt-get --no-install-recommends install -y texlive texlive-latex-extra latexmk - rm -rf ~/.pyenv - rm -rf ~/virtualenvs - wget -q https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O ~/miniconda.sh - chmod +x ~/miniconda.sh - ~/miniconda.sh -b -p /home/ubuntu/miniconda - conda update --yes --quiet conda - conda create -n circleenv --yes pip python=2.7 - sed -i "s/ENABLE_USER_SITE = .*/ENABLE_USER_SITE = False/g" /home/ubuntu/miniconda/envs/circleenv/lib/python2.7/site.py - conda install -n circleenv --yes numpy scipy seaborn mayavi setuptools matplotlib pillow sphinx pytest pytest-cov sphinx_rtd_theme - pip install -r requirements.txt override: - python setup.py develop test: override: - python setup.py build_sphinx - SPHX_GLR_THEME=rtd sphinx-build doc rtd_html - SPHX_GLR_THEME=alabaster sphinx-build doc alabaster_html - sphinx-build sphinx_gallery/tests/tinybuild/ tiny_html - cd sphinx_gallery/tests/tinybuild/ && make latexpdf && cp _build/latex/Python.pdf $CIRCLE_ARTIFACTS general: artifacts: - "doc/_build/html" - "rtd_html" - "alabaster_html" - "tiny_html" - "sphinx_gallery/" deployment: staging: branch: - master commands: - ./docs_deploy.sh rtd_html sphinx-gallery-0.2.0/continuous_integration/000077500000000000000000000000001330553134500212725ustar00rootroot00000000000000sphinx-gallery-0.2.0/continuous_integration/travis/000077500000000000000000000000001330553134500226025ustar00rootroot00000000000000sphinx-gallery-0.2.0/continuous_integration/travis/install.sh000077500000000000000000000032721330553134500246130ustar00rootroot00000000000000#!/bin/bash # This script is meant to be called by the "install" step defined in # .travis.yml. See http://docs.travis-ci.com/ for more details. # The behavior of the script is controlled by environment variabled defined # in the .travis.yml in the top level folder of the project. # # License: 3-clause BSD set -e if [ "$DISTRIB" == "conda" ]; then wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh chmod +x miniconda.sh ./miniconda.sh -b export PATH=$HOME/miniconda3/bin:$PATH conda update --yes conda # force no mkl because mayavi requires old version of numpy # which then crashes with pandas and seaborn conda create --yes -n testenv python=$PYTHON_VERSION pip nomkl numpy\ setuptools matplotlib pillow pytest pytest-cov coverage seaborn source activate testenv if [ "$INSTALL_MAYAVI" == "true" ]; then conda install --yes mayavi fi if [ "$SPHINX_VERSION" != "dev" ]; then conda install "sphinx=${SPHINX_VERSION-*}" --yes else pip install git+https://github.com/sphinx-doc/sphinx.git fi elif [ "$DISTRIB" == "ubuntu" ]; then # Use a separate virtual environment than the one provided by # Travis because it contains numpy and we want to use numpy # from apt-get deactivate virtualenv --system-site-packages testvenv source testvenv/bin/activate pip install -U requests[security] # ensure SSL certificate works pip install "tornado<5" pip install -r requirements.txt pip install seaborn sphinx==1.5.5 pytest "six>=1.10.0" pytest-cov else echo "invalid value for DISTRIB environment variable: $DISTRIB" exit 1 fi python setup.py install sphinx-gallery-0.2.0/continuous_integration/travis/test_script.sh000077500000000000000000000003601330553134500255030ustar00rootroot00000000000000#!/bin/bash # This script is meant to be called by the "script" step defined in # .travis.yml. See http://docs.travis-ci.com/ for more details. # # License: 3-clause BSD set -e pytest sphinx_gallery cd doc make html-noplot make html -j 2 sphinx-gallery-0.2.0/doc/000077500000000000000000000000001330553134500152265ustar00rootroot00000000000000sphinx-gallery-0.2.0/doc/Makefile000066400000000000000000000171001330553134500166650ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext # Theme variable default theme = default help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " can include the sphinx theme to rendered with variable" @echo " theme=[default,rtd,alabaster,sphinxdoc,scrolls,agogo," @echo " traditional,nature,haiku,pyramid,bizstyle]" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: rm -rf $(BUILDDIR)/* rm -rf auto_examples/ rm -rf auto_mayavi_examples/ rm -rf tutorials/ rm -rf gen_modules/ html-noplot: export SPHX_GLR_THEME = $(theme) html-noplot: $(SPHINXBUILD) -D plot_gallery=0 -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." html_abort_on_example_error: export SPHX_GLR_THEME = $(theme) html_abort_on_example_error: $(SPHINXBUILD) -D abort_on_example_error=1 -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." html: export SPHX_GLR_THEME = $(theme) html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Sphinx-Gallery.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Sphinx-Gallery.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/Sphinx-Gallery" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Sphinx-Gallery" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." show: @python -c "import webbrowser; webbrowser.open_new_tab('file://$(PWD)/$(BUILDDIR)/html/index.html')" sphinx-gallery-0.2.0/doc/_static/000077500000000000000000000000001330553134500166545ustar00rootroot00000000000000sphinx-gallery-0.2.0/doc/_static/theme_override.css000066400000000000000000000003761330553134500223750ustar00rootroot00000000000000.wy-nav-top { background-color: #FF8C38 !important; } .wy-side-nav-search { background-color: #FF8C38 !important; } div[class^="highlight"] a { background-color: #E6E6E6; } div[class^="highlight"] a:hover { background-color: #ABECFC; }sphinx-gallery-0.2.0/doc/_templates/000077500000000000000000000000001330553134500173635ustar00rootroot00000000000000sphinx-gallery-0.2.0/doc/_templates/breadcrumbs.html000066400000000000000000000017201330553134500225420ustar00rootroot00000000000000{# Support for Sphinx 1.3+ page_source_suffix, but don't break old builds. #} {% if page_source_suffix %} {% set suffix = page_source_suffix %} {% else %} {% set suffix = source_suffix %} {% endif %}
  • Docs »
  • {% for doc in parents %}
  • {{ doc.title }} »
  • {% endfor %}
  • {{ title }}
  • {% if pagename != "search" %} {% if show_source and source_url_prefix %} View page source {% elif show_source and has_source and sourcename %} View page source {% endif %} {% endif %}

sphinx-gallery-0.2.0/doc/_templates/module.rst000066400000000000000000000016021330553134500214010ustar00rootroot00000000000000.. Please when editing this file make sure to keep it matching the docs in ../advanced_configuration.rst:reference_to_examples {{ fullname }} {{ underline }} .. automodule:: {{ fullname }} {% block functions %} {% if functions %} Functions --------- {% for item in functions %} .. autofunction:: {{ item }} .. include:: backreferences/{{fullname}}.{{item}}.examples .. raw:: html
{%- endfor %} {% endif %} {% endblock %} {% block classes %} {% if classes %} Classes ------- {% for item in classes %} .. autoclass:: {{ item }} :members: {%- endfor %} {% endif %} {% endblock %} {% block exceptions %} {% if exceptions %} Exceptions ---------- .. autosummary:: {% for item in exceptions %} {{ item }} {%- endfor %} {% endif %} {% endblock %} sphinx-gallery-0.2.0/doc/advanced_configuration.rst000066400000000000000000000577401330553134500224710ustar00rootroot00000000000000============= Configuration ============= Configuration and customization of sphinx-gallery is done primarily with a dictionary specified in your ``conf.py`` file. A list of the possible keys are listed :ref:`below ` and explained in greater detail in subsequent sections. .. _list_of_options: List of config options ====================== Most sphinx-gallery configuration options are set in the Sphinx ``conf.py`` file: - ``examples_dirs`` and ``gallery_dirs`` (:ref:`multiple_galleries_config`) - ``filename_pattern`` and ``ignore_pattern`` (:ref:`build_pattern`) - ``subsection_order`` (:ref:`sub_gallery_order`) - ``within_subsection_order`` (:ref:`within_gallery_order`) - ``reference_url`` (:ref:`link_to_documentation`) - ``backreferences_dir`` and ``doc_module`` (:ref:`references_to_examples`) - ``default_thumb_file`` (:ref:`custom_default_thumb`) - ``thumbnail_size`` (:ref:`setting_thumbnail_size`) - ``line_numbers`` (:ref:`adding_line_numbers`) - ``download_all_examples`` (:ref:`disable_all_scripts_download`) - ``plot_gallery`` (:ref:`without_execution`) - ``find_mayavi_figures`` (:ref:`find_mayavi`) - ``abort_on_example_error`` (:ref:`abort_on_first`) - ``expected_failing_examples`` (:ref:`dont_fail_exit`) - ``min_reported_time`` (:ref:`min_reported_time`) - ``binder`` (:ref:`binder_links`) Some options can also be set or overridden on a file-by-file basis: - ``# sphinx_gallery_line_numbers`` (:ref:`adding_line_numbers`) - ``# sphinx_gallery_thumbnail_number`` (:ref:`choosing_thumbnail`) Some options can be set during the build execution step, e.g. using a Makefile: - ``make html-noplot`` (:ref:`without_execution`) - ``make html_abort_on_example_error`` (:ref:`abort_on_first`) And some things can be tweaked directly in CSS: - ``.sphx-glr-thumbcontainer`` (:ref:`setting_thumbnail_size`) .. _multiple_galleries_config: Managing multiple galleries =========================== Sphinx-Gallery only supports up to sub-folder level in its gallery directories. This might be a limitation for you. Or you might want to have separate galleries for different purposes, an examples gallery and a tutorials gallery. For this you use in your Sphinx ``conf.py`` file a list of directories in the sphinx configuration dictionary:: sphinx_gallery_conf = { ... 'examples_dirs': ['../examples', '../tutorials'], 'gallery_dirs': ['auto_examples', 'tutorials'], } Keep in mind that both lists have to be of the same length. .. _build_pattern: Parsing and executing examples based on matching patterns ========================================================= By default, Sphinx-Gallery will **parse and add** all files with a ``.py`` extension to the gallery. To ignore some files and omit them from the gallery entirely, you can use a regular expression (the default is shown here):: sphinx_gallery_conf = { ... 'ignore_pattern': '__init__\.py', } Of the files that get **parsed and added** to the gallery, by default Sphinx-Gallery only **executes** files whose name begins with ``plot``. However, if this naming convention does not suit your project, you can modify the pattern of filenames to build in your Sphinx ``conf.py``. For example:: sphinx_gallery_conf = { ... 'filename_pattern': '/plot_compute_', } will build all examples starting with ``plot_compute_``. The key ``filename_pattern`` accepts `regular expressions`_ which will be matched with the full path of the example. This is the reason the leading ``'/'`` is required. Users are advised to use ``os.sep`` instead of ``'/'`` if they want to be agnostic to the operating system. This option is also useful if you want to build only a subset of the examples. For example, you may want to build only one example so that you can link it in the documentation. In that case, you would do:: sphinx_gallery_conf = { ... 'filename_pattern': 'plot_awesome_example\.py', } Here, one should escape the dot ``'\.'`` as otherwise python `regular expressions`_ matches any character. Nevertheless, as one is targeting a specific file, it would match the dot in the filename even without this escape character. Similarly, to build only examples in a specific directory, you can do:: sphinx_gallery_conf = { ... 'filename_pattern': '/directory/plot_', } Alternatively, you can skip executing some examples. For example, to skip building examples starting with ``plot_long_examples_``, you would do:: sphinx_gallery_conf = { ... 'filename_pattern': '/plot_(?!long_examples)', } As the patterns are parsed as `regular expressions`_, users are advised to consult the `regular expressions`_ module for more details. .. note:: Remember that Sphinx allows overriding ``conf.py`` values from the command line, so you can for example build a single example directly via something like: .. code-block:: console $ sphinx-build -D sphinx_gallery_conf.filename_pattern=plot_specific_example\.py ... .. _sub_gallery_order: Sorting gallery subsections =========================== Gallery subsections are sorted by default alphabetically by their folder name, and as such you can always organize them by changing your folder names. An alternative option is to use a sortkey to organize those subsections. We provide an explicit order sortkey where you have to define the order of all subfolders in your galleries:: from sphinx_gallery.sorting import ExplicitOrder sphinx_gallery_conf = { ... 'examples_dirs': ['../examples','../tutorials'], 'subsection_order': ExplicitOrder(['../examples/sin_func', '../examples/no_output', '../tutorials/seaborn']), } Here we build 2 main galleries `examples` and `tutorials`, each of them with subsections. To specify their order explicitly in the gallery we import :class:`sphinx_gallery.sorting.ExplicitOrder` and initialize it with the list of all subfolders with their paths relative to `conf.py` in the order you prefer them to appear. Keep in mind that we use a single sort key for all the galleries that are built, thus we include the prefix of each gallery in the corresponding subsection folders. One does not define a sortkey per gallery. You can use Linux paths, and if your documentation is built in a Windows system, paths will be transformed to work accordingly, the converse does not hold. If you so desire you can implement your own sorting key. It will be provided the relative paths to `conf.py` of each sub gallery folder. .. _within_gallery_order: Sorting gallery examples ======================== Within a given gallery (sub)section, the example files are ordered by using the standard :func:`sorted` function with the ``key`` argument by default set to :class:`NumberOfCodeLinesSortKey(src_dir) `, which sorts the files based on the number of code lines:: from sphinx_gallery.sorting import NumberOfCodeLinesSortKey sphinx_gallery_conf = { ... 'within_subsection_order': NumberOfCodeLinesSortKey, } In addition, multiple convenience classes are provided for use with ``within_subsection_order``: - :class:`sphinx_gallery.sorting.NumberOfCodeLinesSortKey` (default) to sort by the number of code lines. - :class:`sphinx_gallery.sorting.FileSizeSortKey` to sort by file size. - :class:`sphinx_gallery.sorting.FileNameSortKey` to sort by file name. - :class:`sphinx_gallery.sorting.ExampleTitleSortKey` to sort by example title. .. _link_to_documentation: Linking to documentation ======================== Sphinx-Gallery enables you to add hyperlinks in your example scripts so that you can link the used functions to their matching online documentation. As such code snippets within the gallery appear like this .. raw:: html
    y = np.sin(x)
    
Have a look at this in full action in our example :ref:`sphx_glr_auto_examples_plot_gallery_version.py`. To make this work in your documentation you need to include to the configuration dictionary within your Sphinx ``conf.py`` file:: sphinx_gallery_conf = { ... 'reference_url': { # The module you locally document uses None 'sphinx_gallery': None, } } To link to external modules, if you use the Sphinx extension :mod:`sphinx.ext.intersphinx`, no additional changes are necessary, as the ``intersphinx`` inventory will automatically be used. If you do not use ``intersphinx``, then you should add entries that point to the directory containing ``searchindex.js``, such as ``'matplotlib': 'https://matplotlib.org'``. .. _references_to_examples: Adding references to examples ============================= Sphinx-Gallery enables you, when documenting your modules, to reference to the examples that use a particular function. For example if we are documenting the :func:`numpy.exp` function its possible to embed a small gallery of examples that is specific to this function and looks like this: .. include:: gen_modules/backreferences/numpy.exp.examples .. raw:: html
For such behavior to be available, you have to activate it in your Sphinx-Gallery configuration ``conf.py`` file with:: sphinx_gallery_conf = { ... # directory where function granular galleries are stored 'backreferences_dir' : 'gen_modules/backreferences', # Modules for which function level galleries are created. In # this case sphinx_gallery and numpy in a tuple of strings. 'doc_module' : ('sphinx_gallery', 'numpy')} The path you specify in ``backreferences_dir``, here we choose ``gen_modules/backreferences`` will get populated with ReStructuredText files, each of which contains a reduced version of the gallery specific to every function used across all the examples galleries and belonging to the modules listed in ``doc_module``. Keep in mind that the path set in ``backreferences_dir`` is **relative** to the ``conf.py`` file. Then within your sphinx documentation ``.rst`` files you write these lines to include this reduced version of the Gallery, which has examples in use of a specific function, in this case ``numpy.exp``:: .. include:: gen_modules/backreferences/numpy.exp.examples .. raw:: html
The ``include`` directive takes a path **relative** to the ``rst`` file it is called from. In the case of this documentation file (which is in the same directory as ``conf.py``) we directly use the path declared in ``backreferences_dir`` followed by the function whose examples we want to show and the file has the ``.examples`` extension. Auto-documenting your API with links to examples ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The previous feature can be automated for all your modules combining it with the standard sphinx extensions `autodoc `_ and `autosummary `_. First enable them in your ``conf.py`` extensions list:: import sphinx_gallery extensions = [ ... 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'sphinx_gallery.gen_gallery', ] # generate autosummary even if no references autosummary_generate = True `autodoc `_ and `autosummary `_ are very powerful extensions please read about them. In this example we'll explain how the :ref:`sphx_glr_api_reference` is automatically generated. The documentation is done at the module level. We first start with the ``reference.rst`` file .. literalinclude:: reference.rst :language: rst The important directives are ``currentmodule`` where we specify which module we are documenting, for our purpose is ``sphinx_gallery``. The ``autosummary`` directive is responsible for generating the ``rst`` files documenting each module. ``autosummary`` takes the option *toctree* which is where the ``rst`` files are saved and *template* which is the file that describes how the module ``rst`` documentation file is to be constructed, finally we write the modules we wish to document, in this case all modules of Sphinx-Gallery. The template file ``module.rst`` for the ``autosummary`` directive has to be saved in the path ``_templates/module.rst``. We present our configuration in the following block. The most relevant part is the loop defined between lines **12-22** that parses all the functions of the module. There we have included the snippet introduced in the previous section. Keep in mind that the include directive is **relative** to the file location, and module documentation files are saved in the directory we specified in the *toctree* option of the ``autosummary`` directive used before in the ``reference.rst`` file. The files we are including are from the ``backreferences_dir`` configuration option setup for Sphinx-Gallery. .. literalinclude:: _templates/module.rst :language: rst :lines: 3- :emphasize-lines: 12-22 :linenos: .. _custom_default_thumb: Using a custom default thumbnail ================================ In case you want to use your own image for the thumbnail of examples that do not generate any plot, you can specify it by editing your Sphinx ``conf.py`` file. You need to add to the configuration dictionary a key called `default_thumb_file`. For example:: sphinx_gallery_conf = { ... 'default_thumb_file': 'path/to/thumb/file.png', } .. _adding_line_numbers: Adding line numbers to examples =============================== Line numbers can be displayed in listings by adding the global ``line_numbers`` setting:: sphinx_gallery_conf = { ... 'line_numbers': True, } or by adding a comment to the example script, which overrides any global setting:: # sphinx_gallery_line_numbers = True Note that for Sphinx < 1.3, the line numbers will not be consistent with the original file. .. _disable_all_scripts_download: Disabling download button of all scripts ======================================== By default Sphinx-Gallery collects all python scripts and all Jupyter notebooks from each gallery into zip files which are made available for download at the bottom of each gallery. To disable this behavior add to the configuration dictionary in your ``conf.py`` file:: sphinx_gallery_conf = { ... 'download_all_examples': False, } .. _choosing_thumbnail: Choosing the thumbnail image ============================ For examples that generate multiple figures, the default behavior will use the first figure created in each as the thumbnail image displayed in the gallery. To change the thumbnail image to a figure generated later in an example script, add a comment to the example script to specify the number of the figure you would like to use as the thumbnail. For example, to use the 2nd figure created as the thumbnail:: # sphinx_gallery_thumbnail_number = 2 The default behavior is ``sphinx_gallery_thumbnail_number = 1``. See :ref:`sphx_glr_auto_examples_plot_choose_thumbnail.py` for an example of this functionality. .. _binder_links: Generate Binder links for gallery notebooks (experimental) ========================================================== Sphinx-Gallery automatically generates Jupyter notebooks for any examples built with the gallery. `Binder `_ makes it possible to create interactive GitHub repositories that connect to cloud resources. If you host your documentation on a GitHub repository, it is possible to auto-generate a Binder link for each notebook. Clicking this link will take users to a live version of the Jupyter notebook where they may run the code interactively. For more information see the `Binder documentation `_. .. warning:: Binder is still beta technology, so there may be instability in the experience of users who click Binder links. In order to enable Binder links with Sphinx-Gallery, you must specify a few pieces of information in ``conf.py``. These are given as a nested dictionary following the pattern below:: sphinx_gallery_conf = { ... 'binder': { # Required keys 'org': '', 'repo': '', 'url': '', # Any URL of a binder server. Must be full URL (e.g. https://mybinder.org). 'branch': '', # Can be any branch, tag, or commit hash. Use a branch that hosts your docs. 'dependencies': '', # Optional keys 'filepath_prefix': '' # A prefix to append to any filepaths in Binder links. 'notebooks_dir': '' # Jupyter notebooks for Binder will be copied to this directory (relative to site root). 'use_jupyter_lab': # Whether Binder links should start Jupyter Lab instead of the Jupyter Notebook interface. } } Note that ``branch:`` should be the branch on which your documentation is hosted. If you host your documentation on GitHub, this is usually ``gh-pages`` or ``master``. Each generated Jupyter Notebook will be copied to the folder specified in ``notebooks_dir``. This will be a subfolder of the sphinx output directory and included with your site build. Binder links will point to these notebooks. .. important:: ``dependencies`` should be a list of paths to Binder configuration files that define the environment needed to run the examples. For example, a ``requirements.txt`` file. These will be copied to the documentation branch specified in ``branch:``. When a user clicks your Binder link, these files will be used to create the environment. For more information on what files you can use, see `preparing your repository `_ in the `Binder documentation `_ for more information on what build files are supported. See the Sphinx-Gallery `Sphinx configuration file `_ for an example that uses the `public Binder server `_. .. _without_execution: Building without executing examples =================================== Sphinx-Gallery can parse all your examples and build the gallery without executing any of the scripts. This is just for speed visualization processes of the gallery and the size it takes your website to display, or any use you can imagine for it. To achieve this you need to pass the no plot option in the build process by modifying your ``Makefile`` with:: html-noplot: $(SPHINXBUILD) -D plot_gallery=0 -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." Remember that for ``Makefile`` white space is significant and the indentation are tabs and not spaces. Alternatively, you can add the ``plot_gallery`` option to the ``sphinx_gallery_conf`` dictionary inside your ``conf.py`` to have it as a default:: sphinx_gallery_conf = { ... 'plot_gallery': 'False', } The highest precedence is always given to the `-D` flag of the ``sphinx-build`` command. .. _find_mayavi: Finding Mayavi figures ====================== By default, Sphinx-gallery will only look for :mod:`matplotlib.pyplot` figures when building. However, extracting figures generated by :mod:`mayavi.mlab` is also supported. To enable this feature, you can do:: sphinx_gallery_conf = { ... 'find_mayavi_figures': True, } Dealing with failing Gallery example scripts ============================================ As your project evolves some of your example scripts might stop executing properly. Sphinx-Gallery assist you in the discovery process of those bugged examples. The default behavior is to replace the thumbnail of those examples in the gallery with the broken thumbnail. That allows you to find with a quick glance of the gallery which examples failed. Broken examples remain accessible in the html view of the gallery and the traceback message is written for the failing code block. Refer to example :ref:`sphx_glr_auto_examples_no_output_plot_raise.py` to view the default behavior. The build is also failed exiting with code 1 and giving you a summary of the failed examples with their respective traceback. This way you are aware of failing examples right after the build and can find them easily. There are some additional options at your hand to deal with broken examples. .. _abort_on_first: Abort build on first fail ^^^^^^^^^^^^^^^^^^^^^^^^^ Sphinx-Gallery provides the early fail option. In this mode the gallery build process breaks as soon as an exception occurs in the execution of the examples scripts. To activate this behavior you need to pass a flag at the build process. It can be done by including in your ``Makefile``:: html_abort_on_example_error: $(SPHINXBUILD) -D abort_on_example_error=1 -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." Remember that for ``Makefile`` white space is significant and the indentation are tabs and not spaces. Alternatively, you can add the ``abort_on_example_error`` option to the ``sphinx_gallery_conf`` dictionary inside your ``conf.py`` configuration file to have it as a default:: sphinx_gallery_conf = { ... 'abort_on_example_error': True, } The highest precedence is always given to the `-D` flag of the ``sphinx-build`` command. .. _dont_fail_exit: Don't fail the build on exit ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ It might be the case that you want to keep the gallery even with failed examples. Thus you can configure Sphinx-Gallery to allow certain examples to fail and still exit with a 0 exit code. For this you need to list all the examples you want to allow to fail during build. Change your `conf.py` accordingly:: sphinx_gallery_conf = { ... 'expected_failing_examples': ['../examples/plot_raise.py'] } Here you list the examples you allow to fail during the build process, keep in mind to specify the full relative path from your `conf.py` to the example script. .. _setting_thumbnail_size: Setting gallery thumbnail size ============================== By default Sphinx-gallery will generate thumbnails at size ``(400, 280)``, and add pillarboxes or letterboxes as necessary to scale the image while maintaining the original aspect ratio. This size can be controlled with the ``thumbnail_size`` entry as, e.g.:: sphinx_gallery_conf = { ... 'thumbnail_size': (250, 250), } The gallery uses various CSS classes to display these thumbnails, which default to maximum 160x160px. To change this, e.g. to display the images at 250x250px, you can modify the default CSS with something like the following in your own site's CSS file: .. code-block:: css .sphx-glr-thumbcontainer { min-height: 320px !important; margin: 20px !important; } .sphx-glr-thumbcontainer .figure { width: 250px !important; } .sphx-glr-thumbcontainer img { max-height: 250px !important; width: 250px !important; } .sphx-glr-thumbcontainer a.internal { padding: 270px 10px 0 !important; } .. _min_reported_time: Minimal reported time ===================== By default, Sphinx-gallery logs and embeds in the html output the time it took to run each script. If the majority of your examples runs quickly, you may not need this information. The ``min_reported_time`` configuration can be set to a number of seconds. The duration of scripts that ran faster than that amount will not be logged nor embedded in the html output. .. _regular expressions: https://docs.python.org/2/library/re.html sphinx-gallery-0.2.0/doc/binder/000077500000000000000000000000001330553134500164715ustar00rootroot00000000000000sphinx-gallery-0.2.0/doc/binder/requirements.txt000066400000000000000000000002401330553134500217510ustar00rootroot00000000000000# Requirements for the documentation. # These are extra dependencies that aren't required to use sphinx-gallery. matplotlib pillow seaborn scipy sphinx-gallery sphinx-gallery-0.2.0/doc/changes.rst000066400000000000000000000000351330553134500173660ustar00rootroot00000000000000 .. include:: ../CHANGES.rst sphinx-gallery-0.2.0/doc/conf.py000066400000000000000000000266631330553134500165420ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Sphinx-Gallery documentation build configuration file, created by # sphinx-quickstart on Mon Nov 17 16:01:26 2014. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys import os from datetime import date import sphinx_gallery # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.autosummary', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.mathjax', 'sphinx_gallery.gen_gallery', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # generate autosummary even if no references autosummary_generate = True # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Sphinx-Gallery' copyright = u'2014-%s, Óscar Nájera' % date.today().year # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = sphinx_gallery.__version__ # The full version, including alpha/beta/rc tags. release = sphinx_gallery.__version__ + '-git' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # See warnings about bad links nitpicky = True # we intentionally link outside images suppress_warnings = ['image.nonlocal_uri'] # The reST default role (used for this markup: `text`) to use for all # documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # The theme is set by the make target html_theme = os.environ.get('SPHX_GLR_THEME', 'default') # on_rtd is whether we are on readthedocs.org, this line of code grabbed # from docs.readthedocs.org on_rtd = os.environ.get('READTHEDOCS', None) == 'True' # only import rtd theme and set it if want to build docs locally if not on_rtd and html_theme == 'rtd': import sphinx_rtd_theme html_theme = 'sphinx_rtd_theme' html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # otherwise, readthedocs.org uses their theme by default, so no need to # specify it def setup(app): app.add_stylesheet('theme_override.css') # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. #html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'Sphinx-Gallerydoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'Sphinx-Gallery.tex', u'Sphinx-Gallery Documentation', u'Óscar Nájera', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'sphinx-gallery', u'Sphinx-Gallery Documentation', [u'Óscar Nájera'], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'Sphinx-Gallery', u'Sphinx-Gallery Documentation', u'Óscar Nájera', 'Sphinx-Gallery', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { 'python': ('https://docs.python.org/{.major}'.format(sys.version_info), None), 'numpy': ('https://docs.scipy.org/doc/numpy/', None), 'scipy': ('https://docs.scipy.org/doc/scipy/reference', None), 'matplotlib': ('https://matplotlib.org/', None), 'mayavi': ('http://docs.enthought.com/mayavi/mayavi', None), 'sklearn': ('http://scikit-learn.org/stable', None), 'sphinx': ('http://www.sphinx-doc.org/en/stable', None), } from sphinx_gallery.sorting import ExplicitOrder, NumberOfCodeLinesSortKey examples_dirs = ['../examples', '../tutorials'] gallery_dirs = ['auto_examples', 'tutorials'] try: # Run the mayavi examples and find the mayavi figures if mayavi is # installed from mayavi import mlab find_mayavi_figures = True examples_dirs.append('../mayavi_examples') gallery_dirs.append('auto_mayavi_examples') # Do not pop up any mayavi windows while running the # examples. These are very annoying since they steal the focus. mlab.options.offscreen = True except Exception: # can raise all sorts of errors find_mayavi_figures = False sphinx_gallery_conf = { 'backreferences_dir': 'gen_modules/backreferences', 'doc_module': ('sphinx_gallery', 'numpy'), 'reference_url': { 'sphinx_gallery': None, }, 'examples_dirs': examples_dirs, 'gallery_dirs': gallery_dirs, 'subsection_order': ExplicitOrder(['../examples/sin_func', '../examples/no_output', '../tutorials/seaborn']), 'within_subsection_order': NumberOfCodeLinesSortKey, 'find_mayavi_figures': find_mayavi_figures, 'expected_failing_examples': ['../examples/no_output/plot_raise.py', '../examples/no_output/plot_syntaxerror.py'], 'binder': {'org': 'sphinx-gallery', 'repo': 'sphinx-gallery.github.io', 'url': 'https://mybinder.org', 'branch': 'master', 'dependencies': './binder/requirements.txt', 'notebooks_dir': 'notebooks', 'use_jupyter_lab': True, } } sphinx-gallery-0.2.0/doc/faq.rst000066400000000000000000000015011330553134500165240ustar00rootroot00000000000000Frequently Asked Questions ========================== .. contents:: **Contents** :local: :depth: 1 Why is `__file__` not defined? What can I use? ---------------------------------------------- The global `__file__` variable defined by Python when running scripts is not defined on Jupyter notebooks. Since Sphinx-Gallery supports notebook styled examples and also exports to Jupyter notebooks we agreed on keeping this variable out of scope when executing the example scripts. Instead of `__file__` use :func:`os.getcwd` to get the directory where the file is located. Sphinx-Gallery executes the examples scripts in their source directory. .. seealso:: `Github PR #166 `_ `Github PR #212 `_ sphinx-gallery-0.2.0/doc/getting_started.rst000066400000000000000000000017221330553134500211510ustar00rootroot00000000000000.. include:: ../README.rst Know your Gallery files ======================= The Gallery has been built, now you and all of your project's users can already start enjoying it. All the temporary files needed to generate the gallery(rst files, images, chache objects, etc) are stored where you configured in ``gallery_dirs``. The final files that go into the HTML version of your documentation have a particular namespace, to avoid colisions with your own files and images. Our namespace convention is to prefix everything with ``sphx_glr`` and change path separators with underscores. This is valid for cross-references labels, and images. So for example if we want to reference the example :ref:`sphx_glr_auto_examples_plot_gallery_version.py`, we just call its reference ``:ref:`sphx_glr_auto_examples_plot_gallery_version.py```. The image it generated has the name ``sphx_glr_plot_gallery_version_thumb.png`` and its thumbnail is ``sphx_glr_plot_gallery_version_thumb.png`` sphinx-gallery-0.2.0/doc/index.rst000066400000000000000000000047371330553134500171020ustar00rootroot00000000000000.. Sphinx-Gallery documentation master file, created by sphinx-quickstart on Mon Nov 17 16:01:26 2014. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to Sphinx-Gallery's documentation! ========================================== A `Sphinx `_ extension that builds an HTML gallery of examples from any set of Python scripts. It is extracted from the scikit-learn project and aims to be an independent general purpose extension. The code of the project is on Github: `Sphinx-Gallery `_ Why Sphinx-Gallery? ------------------- * Simple examples that run out of the box are the best way to learn a library * Pleasing, organized, visual layouts * Links, searching, backlinks throughout examples and documentation What does it look like? ----------------------- Here is an example gallery generated from a few Python scripts. .. include:: gen_modules/backreferences/numpy.sin.examples .. raw:: html
Here we put only the examples of our gallery that use a specific function. This display granularity ready to use within your documentation, not just the gigantic galleries with all the examples together. Go ahead, click on those thumbnails to go to the examples. Beautifully rendered HTML versions of the original python scripts with, narrating prose from the doctrings and inline comments and plots generated by the scripts. Features -------- * Runs Python files and captures outputs + figures. Learn how to :ref:`set_up_your_project` * :ref:`multiple_galleries_config` no number limit. * Automatically hyperlink the code in the gallery to the corresponding function documentation. :ref:`link_to_documentation` * Automatically links from documented functions to examples using the function. :ref:`references_to_examples` * :ref:`notebook_examples`: turn your scripts into a full narrative with the :ref:`notebook_examples_syntax` Sphinx-Gallery Show: :ref:`examples-index` ------------------------------------------ Contents: ========= .. toctree:: :maxdepth: 2 getting_started advanced_configuration faq syntax utils reference auto_examples/index tutorials/index auto_mayavi_examples/index changes Fork sphinx-gallery on Github Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` sphinx-gallery-0.2.0/doc/maintainers.rst000066400000000000000000000022251330553134500202730ustar00rootroot00000000000000How to make a release ===================== * Update the change log Use `github_changelog_generator `_ to gather all merged pull requests and closed issues during the development cycle. We do this because our failing discipline of writing in the CHANGES.rst all relevant changes, this helps our memory. .. code-block:: bash github_changelog_generator sphinx-gallery/sphinx-gallery Read the changes in the generated CHANGELOG.md and propagate the relevant to CHANGES.rst * Update version Update the version in ``sphinx_gallery/__init__.py``. * Build the docs cleanly Make sure to clean all and have a clean build. Double-check visually that everything looks right. * Push to your own master branch and check CI is happy * Draft release copy and edit to github markdown all changes from CHANGELOG.md. * Build a source distribution .. code-block:: bash python setup.py sdist * Test upload to PyPI .. code-block:: bash twine upload --repository test dist/sphinx-gallery-.tar.gz * Upload to PyPI .. code-block:: bash twine upload dist/sphinx-gallery-.tar.gz sphinx-gallery-0.2.0/doc/make.bat000066400000000000000000000150751330553134500166430ustar00rootroot00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Sphinx-Gallery.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Sphinx-Gallery.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %BUILDDIR%/.. echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %BUILDDIR%/.. echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) :end sphinx-gallery-0.2.0/doc/reference.rst000066400000000000000000000010051330553134500177120ustar00rootroot00000000000000 .. _sphx_glr_api_reference: Sphinx-Gallery API Reference ============================ The complete Sphinx-Gallery project is automatically documented for every module. .. currentmodule:: sphinx_gallery .. automodule:: sphinx_gallery :no-members: :no-inherited-members: :py:mod:`sphinx_gallery`: .. autosummary:: :toctree: gen_modules/ :template: module.rst gen_gallery backreferences gen_rst py_source_parser docs_resolv notebook downloads docs_resolv sorting binder sphinx-gallery-0.2.0/doc/syntax.rst000066400000000000000000000026421330553134500173120ustar00rootroot00000000000000===================== Sphinx-Gallery Syntax ===================== For your examples to work you have to make them valid python code. Simple examples =============== This is the base of a python script of module. The structure follows a leading docstring that must follow reStructuredText syntax and a header. Then the executable code of your script. For a quick reference have a look at the example :ref:`sphx_glr_auto_examples_plot_gallery_version.py` In this 2 block structure, the website is rendered ordered with the docstring, then output images and output code. Finally the generating code script. .. _notebook_examples_syntax: Notebook Styled examples syntax =============================== It is also possible to have more complicated examples, for which you want to embed more documenting strings within your code and separating it by blocks. This is also possible, you follow standard python coding syntax but new documenting strings that will be rendered as reStructuredText have to be leaded by a line of hashes. For a clear example refer to the rendered example :ref:`sphx_glr_tutorials_plot_notebook.py` and compare it to the generating :download:`original python script ` In this multiblock structure, the website is rendered ordered by the leading docstring. Then executable python code is presented and after its output in images and test, following the intuitive notebook structure. sphinx-gallery-0.2.0/doc/utils.rst000066400000000000000000000017241330553134500171240ustar00rootroot00000000000000======================== Sphinx-Gallery Utilities ======================== Convert Python scripts into Jupyter Notebooks ============================================= Sphinx Gallery exposes its python source to Jupyter notebook converter as a executable script too. To use this utility just call the script and give the Python source file as argument:: $ sphx_glr_python_to_jupyter.py python_script.py Embedding Sphinx-Gallery inside your documentation script extensions ==================================================================== If you want to embed Sphinx-Gallery in your project instead of putting it as a dependency you can call our embedding script inside your Sphinx extensions folder:: $ copy_sphinxgallery.sh This will download directly from PyPI our latest released code and save it to the current folder. This is a stripped version of the Sphinx-Gallery module to incorporate in your project. You should also add it to your version control system. sphinx-gallery-0.2.0/docs_deploy.sh000077500000000000000000000017341330553134500173310ustar00rootroot00000000000000#!/bin/sh # ideas used from https://gist.github.com/motemen/8595451 # abort the script if there is a non-zero error set -e # show where we are on the machine pwd siteSource="$1" if [ ! -d "$siteSource" ] then echo "Usage: $0 " exit 1 fi # now lets setup the docs repo so we can update them with the current build git config --global user.email "Circle CI" > /dev/null 2>&1 git config --global user.name "bot@try.out" > /dev/null 2>&1 git clone git@github.com:sphinx-gallery/sphinx-gallery.github.io.git cd sphinx-gallery.github.io/ # copy over or recompile the new site git rm -rf . cp -a "../${siteSource}/." . # github nojekyll touch .nojekyll # stage any changes and new files git add -A # now commit git commit --allow-empty -m "Update the docs from master" # and push, but send any output to /dev/null to hide anything sensitive git push --force --quiet origin master > /dev/null 2>&1 # go back to where we started cd .. echo "Finished Deployment!" sphinx-gallery-0.2.0/examples/000077500000000000000000000000001330553134500162775ustar00rootroot00000000000000sphinx-gallery-0.2.0/examples/README.txt000066400000000000000000000002731330553134500177770ustar00rootroot00000000000000.. _examples-index: Gallery of Examples =================== .. _general_examples: General examples ---------------- General-purpose and introductory examples from the sphinx-gallery sphinx-gallery-0.2.0/examples/no_output/000077500000000000000000000000001330553134500203335ustar00rootroot00000000000000sphinx-gallery-0.2.0/examples/no_output/README.txt000066400000000000000000000005441330553134500220340ustar00rootroot00000000000000.. _no_out_examples: Examples which don't produce image output ----------------------------------------- This section gathers examples which by design don't follow the pattern of the gallery of producing figure. Some examples only output to stdout, other are there to demonstrate how Sphinx-Gallery handles examples with error that hinder building them. sphinx-gallery-0.2.0/examples/no_output/just_code.py000066400000000000000000000004731330553134500226700ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ A short Python script ===================== A script that is not executed when gallery is generated but nevertheless gets included as an example. Doing a list """ # Code source: Óscar Nájera # License: BSD 3 clause from __future__ import print_function print([i for i in range(10)]) sphinx-gallery-0.2.0/examples/no_output/plot_raise.py000066400000000000000000000021671330553134500230540ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Example that fails to execute ============================= When scripts fail their gallery thumbnail is replaced with the broken image stamp. Thus allowing easy identification in the gallery display. You also get the python traceback of the failed code block """ # Code source: Óscar Nájera # License: BSD 3 clause # sphinx_gallery_line_numbers = True import numpy as np import matplotlib.pyplot as plt plt.pcolormesh(np.random.randn(100, 100)) ############################################################################### # This next block will raise a NameError iae ############################################################################### # Sphinx gallery will stop executing the remaining code blocks after # the exception has occurred in the example script. Nevertheless the # html will still render all the example annotated text and # code blocks, but no output will be shown. ############################################################################### # Here is another error raising block but will not be executed plt.plot('Strings are not a valid argument for the plot function') sphinx-gallery-0.2.0/examples/no_output/plot_strings.py000066400000000000000000000006261330553134500234400ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Constrained Text output frame ============================= This example captures the stdout and includes it in the example. If output is too long it becomes automatically framed into a text area. """ # Code source: Óscar Nájera # License: BSD 3 clause print('This is a long test Output\n' * 50) #################################### # One line out print('one line out') sphinx-gallery-0.2.0/examples/no_output/plot_syntaxerror.py000066400000000000000000000005621330553134500243460ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Example with SyntaxError ======================== Sphinx-Gallery uses Python's AST parser, thus you need to have written valid python code for Sphinx-Gallery to parse it. If your script has a SyntaxError you'll be presented the traceback and the original code. """ # Code source: Óscar Nájera # License: BSD 3 clause Invalid Python code sphinx-gallery-0.2.0/examples/plot_choose_thumbnail.py000066400000000000000000000017341330553134500232370ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Choosing the thumbnail figure ============================= An example to demonstrate how to choose which figure is displayed as the thumbnail if the example generates more than one figure. This is done by specifying the keyword-value pair ``sphinx_gallery_thumbnail_number = 2`` as a comment somewhere below the docstring in the example file. """ # Code source: Óscar Nájera # License: BSD 3 clause import numpy as np import matplotlib.pyplot as plt def main(): x = np.linspace(-1, 2, 100) y = np.exp(x) plt.figure() plt.plot(x, y) plt.xlabel('$x$') plt.ylabel('$\exp(x)$') # The next line sets the thumbnail for the second figure in the gallery # (plot with negative exponential in orange) # sphinx_gallery_thumbnail_number = 2 plt.figure() plt.plot(x, -np.exp(-x), color='orange', linewidth=4) plt.xlabel('$x$') plt.ylabel('$-\exp(-x)$') plt.show() if __name__ == '__main__': main() sphinx-gallery-0.2.0/examples/plot_colors.py000066400000000000000000000014241330553134500212110ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" Colormaps alter your perception =============================== Here I plot the function .. math:: f(x, y) = \sin(x) + \cos(y) with different colormaps. """ import numpy as np import matplotlib.pyplot as plt x = np.linspace(-np.pi, np.pi, 300) xx, yy = np.meshgrid(x, x) z = np.cos(xx) + np.cos(yy) plt.figure() plt.imshow(z) plt.figure() plt.imshow(z, cmap=plt.cm.get_cmap('hot')) plt.figure() plt.imshow(z, cmap=plt.cm.get_cmap('Spectral'), interpolation='none') # Not needed for the Gallery. # Only for direct execution plt.show() ################################################ # You can define blocks in your source code # with interleaving prose. # print("This writes to stdout and will be", " displayed in the HTML file") sphinx-gallery-0.2.0/examples/plot_exp.py000066400000000000000000000012131330553134500205000ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Plotting the exponential function ================================= A simple example for ploting two figures of a exponential function in order to test the autonomy of the gallery stacking multiple images. """ # Code source: Óscar Nájera # License: BSD 3 clause import numpy as np import matplotlib.pyplot as plt def main(): x = np.linspace(-1, 2, 100) y = np.exp(x) plt.figure() plt.plot(x, y) plt.xlabel('$x$') plt.ylabel('$\exp(x)$') plt.figure() plt.plot(x, -np.exp(-x)) plt.xlabel('$x$') plt.ylabel('$-\exp(-x)$') plt.show() if __name__ == '__main__': main() sphinx-gallery-0.2.0/examples/plot_function_identifier.py000066400000000000000000000020721330553134500237370ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Identifying function names in a script ====================================== Calls Sphinx-Gallery identify names function to figure out which functions are called in the script and to which module do they belong. """ # Code source: Óscar Nájera # License: BSD 3 clause import matplotlib.pyplot as plt import sphinx_gallery.backreferences as spback filename = spback.__file__.replace('.pyc', '.py') names = spback.identify_names(filename) figheight = len(names) + .5 fontsize = 22 fig = plt.figure() for i, (name, obj) in enumerate(names.items()): fig.text(0.3, (float(len(names)) - 0.5 - i) / figheight, name, ha="right", size=fontsize, transform=fig.transFigure, bbox=dict(boxstyle='square', fc="w", ec="k")) fig.text(0.35, (float(len(names)) - 0.5 - i) / figheight, obj["module"], ha="left", size=fontsize, transform=fig.transFigure, bbox=dict(boxstyle='larrow', fc="w", ec="k")) # plt.draw() plt.show() sphinx-gallery-0.2.0/examples/plot_gallery_version.py000066400000000000000000000021171330553134500231140ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Sphinx-Gallery introduction =========================== Plot to present Sphinx-Gallery using itself to display its version. """ # Code source: Óscar Nájera # License: BSD 3 clause import numpy as np import matplotlib.pyplot as plt import sphinx_gallery np.random.seed(32) def layers(n, m): """ Return *n* random Gaussian mixtures, each of length *m*. """ def bump(a): x = 1 / (.1 + np.random.random()) y = 2 * np.random.random() - .3 z = 13 / (.1 + np.random.random()) for i in range(m): w = (i / float(m) - y) * z a[i] += x * np.exp(-w * w) a = np.zeros((m, n)) for i in range(n): for j in range(12): bump(a[:, i]) return np.abs(a) fig = plt.figure() d = layers(3, 100) x = range(100) for mixture in d.T: mixture[[0, -1]] = 0. plt.fill(x, mixture, alpha=0.9) plt.annotate('Introducing Sphinx-Gallery ' + sphinx_gallery.__version__, xy=(12, 4), arrowprops=dict(arrowstyle='->'), xytext=(22, 6)) plt.xticks([]) plt.yticks([]) plt.show() sphinx-gallery-0.2.0/examples/plot_quantum.py000066400000000000000000000054141330553134500214050ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" Some Quantum Mechanics, filling an atomic orbital ================================================= Considering an atomic single orbital and how to fill it by use of the chemical potential. This system has a four element basis, :math:`B = \{ \lvert \emptyset \rangle, \lvert \uparrow \rangle, \lvert \downarrow \rangle, \lvert \uparrow\downarrow \rangle \}`, that is the empty orbital, one spin up electron, one spin down electron and the filled orbital. The environment of the orbital is set up by an energy cost for occupying the orbital, that is :math:`\epsilon` and when both electrons meet a contact interaction corresponding to the Coulomb repulsion :math:`U`. Finally the chemical potential :math:`\mu` is what allows in the Grand canonical picture, to fill up our atomic orbital from a reservoir of electrons. The the simple Hamiltonian to model this system is given by: .. math:: \mathcal{H} = \sum_{\sigma=\uparrow,\downarrow} \epsilon c^\dagger_\sigma c_\sigma + Un_\uparrow n_\downarrow - \mu \hat{N} Here :math:`c^\dagger,c` creation and annihilation operators, :math:`n=c^\dagger c`, and :math:`\hat{N}=n_\uparrow+n_\downarrow`. This Hamiltonian is diagonal in the basis of particle number we have chosen earlier, as the basis elements are also eigenvectors. .. math:: \mathcal{H} \lvert \emptyset \rangle &= 0 \\ \mathcal{H} \lvert \uparrow \rangle &= (\epsilon - \mu) | \uparrow \rangle \\ \mathcal{H} \lvert \downarrow \rangle &= (\epsilon - \mu) | \downarrow \rangle \\ \mathcal{H} \lvert \uparrow\downarrow \rangle &= (2\epsilon - 2\mu +U) \lvert \uparrow\downarrow \rangle It is easy to see, that the system will prefer to be empty if :math:`\mu \in [0,\epsilon)`, be single occupied if :math:`\mu \in (\epsilon, \epsilon +U)` and doubly occupied if :math:`\mu > \epsilon +U`. For a more rigorous treatment, the partition function has to be calculated and then the expected particle number can be found. Introducing a new variable :math:`\xi = \epsilon - \mu`, and :math:`\beta` corresponding to the inverse temperature of the system. .. math:: \mathcal{Z} &= Tr(e^{-\beta \mathcal{H}}) = 1 + 2e^{-\beta\xi} + e^{-\beta(2\xi + U)} \\ \langle \hat{N} \rangle &= \frac{1}{\beta} \frac{\partial}{\partial \mu} \ln \mathcal{Z} """ # Code source: Óscar Nájera # License: BSD 3 clause import matplotlib.pyplot as plt import numpy as np mu = np.linspace(0, 3, 800) for b in [10, 20, 30]: n = 2 * (np.exp(b * (mu - 1)) + np.exp(b * (2 * mu - 3))) / \ (1 + np.exp(b * (mu - 1)) * (2 + np.exp(b * (mu - 2)))) plt.plot(mu, n, label=r"$\beta={0}$".format(b)) plt.xlabel(r'$\mu$ ($\epsilon=1$, $U=1$)') plt.ylabel(r'$\langle N \rangle=\langle n_\uparrow \rangle+\langle n_\downarrow\rangle$') plt.legend(loc=0) plt.show() sphinx-gallery-0.2.0/examples/plot_seaborn.py000066400000000000000000000012521330553134500213400ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" Seaborn example =============== Preview the capture of seaborn styles in plots """ # Author: Michael Waskom # License: BSD 3 clause from __future__ import division, absolute_import, print_function import numpy as np import seaborn as sns # Enforce the use of default set style #sns.set(style="darkgrid", palette="Set2") # Create a noisy periodic dataset sines = [] rs = np.random.RandomState(8) for _ in range(15): x = np.linspace(0, 30 / 2, 30) y = np.sin(x) + rs.normal(0, 1.5) + rs.normal(0, .3, 30) sines.append(y) # Plot the average over replicates with bootstrap resamples sns.tsplot(sines, err_style="boot_traces", n_boot=500) sphinx-gallery-0.2.0/examples/plot_sys_argv.py000066400000000000000000000006301330553134500215430ustar00rootroot00000000000000""" Using ``sys.argv`` in examples ============================== Note that your example will be run by sphinx-gallery without arguments. """ import argparse import sys parser = argparse.ArgumentParser(description='Toy parser') parser.add_argument('--option', default='default', help='a dummy optional argument') print('sys.argv:', sys.argv) print('parsed args:', parser.parse_args()) sphinx-gallery-0.2.0/examples/plot_unicode_everywhere.py000066400000000000000000000017651330553134500236130ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Using Unicode everywhere 🤗 =========================== This examples includes unicode characters, mostly emoji 🎉 to stress test the build and test environments that parse the example files. """ from __future__ import unicode_literals # 🎉 👍 # Code source: Óscar Nájera # License: BSD 3 clause import numpy as np import matplotlib.pyplot as plt plt.rcParams['font.size'] = 20 plt.rcParams["font.monospace"] = ["DejaVu Sans Mono"] plt.rcParams["font.family"] = "monospace" plt.figure() x = np.random.randn(100) * 2 + 1 y = np.random.randn(100) * 6 + 3 s = np.random.rand(*x.shape) * 800 + 500 plt.scatter(x, y, s, marker=r'$\oint$') x = np.random.randn(60) * 7 - 4 y = np.random.randn(60) * 3 - 2 plt.scatter(x, y, s, alpha=0.5, c='g', marker=r'$\clubsuit$') plt.xlabel('⇒') plt.ylabel('⇒') plt.title('♲' * 10) print('Std out capture 😎') plt.show() ########################################################################### # Debug fonts print(plt.rcParams) sphinx-gallery-0.2.0/examples/sin_func/000077500000000000000000000000001330553134500201035ustar00rootroot00000000000000sphinx-gallery-0.2.0/examples/sin_func/README.txt000066400000000000000000000002161330553134500216000ustar00rootroot00000000000000.. _sin_examples: The sin function ---------------- Specific examples for the sin function. Saved in the examples directory in a subfolder. sphinx-gallery-0.2.0/examples/sin_func/plot_sin.py000066400000000000000000000016741330553134500223140ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Plotting simple sin function ============================ A simple example of the plot of a sin function in order to test the autonomy of the gallery. To illustrate how to insert maths in example descriptions, it corresponds mathematically to the function: .. math:: x \\rightarrow \\sin(x) Here the function :math:`\\sin` is evaluated at each point the variable :math:`x` is defined. Note that ``sphinx-gallery`` automatically creates labels for each example from its filename. You can thus refer to it from any part of the documentation, including from other examples, as here .. seealso:: :ref:`sphx_glr_auto_examples_sin_func_plot_sin_black_background.py` for a fancier plot """ # Code source: Óscar Nájera # License: BSD 3 clause import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 2 * np.pi, 100) y = np.sin(x) plt.plot(x, y) plt.xlabel('$x$') plt.ylabel('$\sin(x)$') plt.show() sphinx-gallery-0.2.0/examples/sin_func/plot_sin_black_background.py000066400000000000000000000015021330553134500256350ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Plotting simple sin function on a black background ================================================== A simple example of the plot of a sin function on a black background """ # Code source: Loïc Estève # License: BSD 3 clause import numpy as np import matplotlib.pyplot as plt bg_color = 'black' fg_color = 'white' fig = plt.figure(facecolor=bg_color, edgecolor=fg_color) axes = fig.add_subplot(111) axes.patch.set_facecolor(bg_color) axes.xaxis.set_tick_params(color=fg_color, labelcolor=fg_color) axes.yaxis.set_tick_params(color=fg_color, labelcolor=fg_color) for spine in axes.spines.values(): spine.set_color(fg_color) x = np.linspace(0, 2 * np.pi, 100) y = np.sin(x) plt.plot(x, y, 'cyan', axes=axes) plt.xlabel('$x$', color=fg_color) plt.ylabel('$\sin(x)$', color=fg_color) plt.show() sphinx-gallery-0.2.0/mayavi_examples/000077500000000000000000000000001330553134500176455ustar00rootroot00000000000000sphinx-gallery-0.2.0/mayavi_examples/README.txt000066400000000000000000000003451330553134500213450ustar00rootroot00000000000000.. _mayavi-examples-index: Gallery of Examples using Mayavi ================================ .. _general_mayavi_examples: Mayavi examples --------------- Examples from the sphinx-gallery using Mayavi for embedding 3d plots. sphinx-gallery-0.2.0/mayavi_examples/plot_3d.py000066400000000000000000000015141330553134500215640ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Plotting simple 3D graph with Mayavi ==================================== A simple example of the plot of a 3D graph with Mayavi in order to test the autonomy of the gallery. """ # Code source: Alex Gramfort # License: BSD 3 clause # This will show the mlab.test_mesh figure in the gallery # sphinx_gallery_thumbnail_number = 4 from mayavi import mlab mlab.test_plot3d() mlab.figure() mlab.test_contour3d() ##################################################################### # Note: this shows that inside a cell matplotlib figures are always # put before mayavi in the example HTML. In other words, the order of # plotting is not respected between matplotlib and mayavi figures mlab.figure() mlab.test_mesh() mlab.figure() mlab.test_flow() import matplotlib.pyplot as plt plt.plot([1, 2, 3], [1, 2, 3]) sphinx-gallery-0.2.0/requirements.txt000066400000000000000000000000531330553134500177430ustar00rootroot00000000000000setuptools matplotlib pillow sphinx pytest sphinx-gallery-0.2.0/setup.cfg000066400000000000000000000004421330553134500163020ustar00rootroot00000000000000[tool:pytest] addopts = --cov-report term-missing --cov=sphinx_gallery --durations=5 -rs python_files = tests/*.py norecursedirs = build _build auto_examples gen_modules sphinx_gallery/tests/tinybuild [build_sphinx] source-dir = doc/ build-dir = doc/_build all_files = 1 sphinx-gallery-0.2.0/setup.py000066400000000000000000000026661330553134500162050ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Óscar Nájera # License: 3-clause BSD """ Installer Sphinx extension for gallery generator """ import codecs import os from setuptools import setup, find_packages import sphinx_gallery with codecs.open('README.rst', mode='r', encoding='utf-8') as f: long_description = f.read() # XXX : don't force requirements in setup.py as it tends to break # people's setups install_requires = [] if os.environ.get('READTHEDOCS', None) == 'True': # So that we can build documentation using seaborn install_requires = ['seaborn'] setup( name="sphinx-gallery", description="Sphinx extension to automatically generate an examples gallery", long_description=long_description, version=sphinx_gallery.__version__, packages=find_packages(), package_data={'sphinx_gallery': ['_static/gallery.css', '_static/no_image.png', '_static/broken_example.png']}, scripts=['bin/copy_sphinxgallery.sh', 'bin/sphx_glr_python_to_jupyter.py'], url="https://github.com/sphinx-gallery/sphinx-gallery", author="Óscar Nájera", author_email='najera.oscar@gmail.com', install_requires=install_requires, license='3-clause BSD', classifiers=['Intended Audience :: Developers', 'Development Status :: 3 - Alpha', 'Framework :: Sphinx :: Extension', 'Programming Language :: Python', ], ) sphinx-gallery-0.2.0/sphinx_gallery/000077500000000000000000000000001330553134500175115ustar00rootroot00000000000000sphinx-gallery-0.2.0/sphinx_gallery/__init__.py000066400000000000000000000003371330553134500216250ustar00rootroot00000000000000""" Sphinx Gallery ============== """ import os __version__ = '0.2.0' def glr_path_static(): """Returns path to packaged static files""" return os.path.abspath(os.path.join(os.path.dirname(__file__), '_static')) sphinx-gallery-0.2.0/sphinx_gallery/_static/000077500000000000000000000000001330553134500211375ustar00rootroot00000000000000sphinx-gallery-0.2.0/sphinx_gallery/_static/broken_example.png000066400000000000000000000516341330553134500246510ustar00rootroot00000000000000PNG  IHDR@rsBIT|d pHYs  tEXtSoftwarewww.inkscape.org< IDATxweoz $z ޤ DĆEE`r "":!BK-ϚٳO99{>|>sΞ=yfgk tmuB{/ ""}`!0 Xv^RDDDD}a` m2k :lopAܾ""""G m\WDDDD`AWOtt0[rkX` S[L*sHk %җ,)sHk 66\=y"`#q[x#b }{!dٽL@=gEiwz& ^z W/X9f8v߶{QpMB^@DDD`LqȒ֠' DcY["=VwA.JsXj?gw50XX [q2<LCe|-Pq߶36y# GD40 2x$b?#koBK~DA$?Ki`DDo{/%/@V:4 {w2֞Q-I5r{|wP.^Xs<ƾ~wPLpCLDD42z(q`H2%<^i Lf0=cM|C#  ,(_Jv#2|Beopj$<(F `DD;Iew`l?8UsћZhͺG;3Az~Y0D6*Hޒ!5T;S&èqFPeLk7b 0"dU@zI^F`x8 kX րH#"J`A׼lHЀWrW[}z(B-f`GF#" Src_m,pw7G1CQmh)% Х|Yۢq[~fz `DDiAHԭ$I7EKGMer[ɍֈ.pDD$U cNޅo'T x̸O5DM9&{\'XD蓃֛ZTFG$6)y pc8_Os|͐yDX{| ?yFV]$yvR6"bGAoS'~~|E~"YChC^cwm;kFFDLC0_y2WdH$k)j>î 6<)8`iA# #"ZϚ  cvL4X2{'EI܁s &n(u9jİ B\>O~ϣJ(oX6oű5N"FfӰL64-lbi ?tk"-gw.[o;zRt:,pD*`9rWP ܋H7x;5 kw;;G@֧R3'AС:"Lxt'}s8SQ/Д^7ܱ's7f#" "3зJ.zZx'Q*v;g&T $cۮ~Y dKaN\̶n#uP]M!e(I2ȈVó{ LiAHSf揭: r26Zs>/e$=YuDh3 `Re1z1o$ XkI? kkck"?#2Yh= ,tk,9w YjD]f-ivnJA$x.uAVdV2 "2:CIOBɗhlf@u6%]J3D0]+2%莪N5݂vyl诓XɺȻ{oEfl-O kZJG# ,ϣ,O,|$X`SoDY lrFYndrٛ'pr,uҝX =<)`ڂekgDB̺]'S|{@ڄ`rJX^c:י|(S s^o4Ci]!` >|P{e'_E2!WvǑ16U[߭NPy(3{3ɜ8%,yNXCFiɡ`? 6iKYMmj!(7zJw"u2\dߖ)5$^W :h4ǎGD'=?Ze"`=U \]G[; ˫0j$ GW$р;JZj̮mHf,f9?̺-  >oz2|-.PNbjݑ*7}ra; ;{&_`ijw)g`H1f0䦿g@&ܘ\wD$ 7x/?bbhˀ'`DžbpX&Y$cF_\>EA℻Z5y H .VI@n1:'b1F#kcDPIGYBb 7a|[T~)h9ExN"з"Y"FtllE5 b_F?sݪY`|Yk. 5HQ&kp.Hd- 7pJB죉罆HXQbː&*uǠU`}KEIhhi -oŹT ]2Nn. 1'Q)9g$^@9s0 `k%I^D18|sjhrzb2r{s=`Kn7D 0!HQ.y֠O[~^A#J)%`g(du181_Yk,4#_Pb}lgq1?k"MƁ⦫`~Pr>J1Zsrĺa9< ;C dּ5>m{r'՞.X$cvڈQ6UѐIPwfP7y}=xr=e9Jl LjtmtΜ+NE' Rg&>vXdY^Ҋó3ӇUxYVɾ}1'Xvow*%7o,ys 0*KnMK cI[.y[;>bph "3n D\nqr[YJn<׆T5͐,qOzYx!DlGV"qy%jk҂57Ye6O%f ?D̥-M3  L2XsXHk1j*uZ-xhXrT;&qtn{-5EYaw6W'O %/*j  vKDFj%ߖ !#wLNU{(Lы&y)~ԈOG+ =Qfzt Zk ܂8Y$:$8 ]DߗeGkz$+p6F4q^MfyAYO UD5D3Prrȟ? Cr"U*%7ۙ\̺ Y~ΐ"'% QYBDm;+!S@wQӂRTQ Dwo$vRb?j4e񿇩YD]l3x H| pBXT\+X}_ Ӆ݃Ԓpz K4Oԩ2iж.bLy?cIq(Jn1~h} Ѝ;V_JJ#InXv-8G᥄TZH&ہ!'5]@ۣp|gK /aj'tA?E9%A?4cdjD-GeHXODl"DNFoN&αR?#\wyGR&]؝'**˗uEkd/ Y"v0|P& WtǞ;R!҆#Ÿ§ ~{]} g2n$)wdYDZ`^oh.CQe&Lem )i'{ %7*kmH/A(Et<ܐ_7-7"$f\ ڸ?/=H'ݖ&p? 3ȺGP>v8d"liCI#i+xbf,"ُ=ݧA IDATJ:`߳f!`Ãg!OfDP*45KgI;!9VMFUҟz hwg흎yH8$>f PD>uV6r݅s,|CШRH t~ݍ \?Ҁymӑ#p+頡?WCuAj7ۊ+ 7_ ]@[Y[u^|@>\_GkލDl@w] yiA.{25L.VR"WVy/Q?#s!efMM+ OYux)J#!`w9[rC}A,("&-0j[K5{oGC֎JxʥJfe?>N=Y74Y>OS\4@*j;:"6L#PܾuїZ5LĸW E1ι I<i& P;{x'ֳM`n ;IEz"IoxS׵(|<텈ۭ)؎p ]+#iDD~ whuXɐ'IA*xD3.yUWSmB:Zf5Y~ LBxD kIaf32Е= `L|P ,|)?AesIp6-$['D '$+J;~1L8YGEbfǣpA,4%.GYzB?C"|!տZc{"`;e!An@:D.{BI \e Q-{ҮumJ><ZX[ܮǨll vG1AT^#t3dB2"Gr|"װ1ՑwB2Ea_Zn BDIr?T[5KAL6!Wev@Ĥ(&8`'d[yijG./*K+u"7)B~Y9yqtJҬ jW{%aP|೹SE'*(jYE?Ȫ3$.׼!B'̚~ 'fF.18Z?!oJ nj_N5F|8%ݣP[*Hj,ӤXDҖ!5N"rۗ#W1[Ȫ+!OI<\Y퇬,yz ŧ]o6"dHґyL3}6ۡʸi%05o뱼J&fMW?,'$:",m>(۟<>.֗q7k>E:Ob)>bS[m%7?`T/UbACr_rkpWo""סyyLA|bA;%tFCZ9Ã:.?2 )z"ro 4z p5aoFZQi}!Wl^uAq}="n+DRI0ڏ[ oIAS9sN1~oF%yr[\A p1J\H";r(j[zlolɈAYXpFH{)b0ǹ(@qtuv(%6?@N2tZO7%@@STw;:ge1,8}Qp3\SO#Vb|7 _ǽNs$6I(E~ "IC T:]PA;R)c{`?!H5>Pch0 Ie㿐zxf[@x[fL55cǵ@+"QwE.x͊}Ư >q3xA5tWu'-!2oD:&ҤZ\x n.}Ոw2ɲ 0 YDUQӇ^kfM""_&l%e#XN0Y]g# DTRIT wNtN3>A/(v2\r{!?'X?a%@'Vkb}w&</kk "6&|TP!g_++FTK*~!!c۞]@VPHHq]ʖDB_쨟5# tg S8H$Kz Kːڡ5 "6ģ? [qr]KɤN8%F#78Q:;d{e_'*wIV3a3bCtۧLպ'{JB&k`tU2hb$Ttv2>?4Kw2mEұB0bԾheg*gdB'n 7zDfCczеAN8 h">"`VCnbeU7Dw1^.S {H1 G:uFa\s)*m[rקya⯡%c< a`Y)c}:t zmH zz8X-40MZёhdṂmm_댠KЍTYiuF^g [ezɱn x,ڂH? d_OQAk5l!vA @R)?LIp 7߸ }Z;uZvAS|ҪG$0eE&&A]A.@Ț:5Y2nH"LJх7eY^0^X‚ln67 0TbZ(SG ua !_D+suB;XQgh}g->߿ Hru'TG D#5?Ro$mp8q$Dx$~ rŖblι^1 IVC6I(;SuxUķf>irA:TD˹F rl.5eϩ\AP Qrs_%Ig"[pXڜs%L%vG"k{ {Cu 8Fb @S7dv74\ґ? ͏Q5&y2IM бڭ U-6.8^EP-8j]-GSv~ri;w0k DVD|<%אΣ\؀5kFd{(Q"XDPOh&uC&;;Lj?*4@79!WP򱠱5=20iAߕ@{|k@YQ7dI'.FݟC^n똓H 7c=Hƫν҉q9 !L`˾ň-Qm4QZGc#@KkN#m]<[(Q9$o3BTWX;# f zT# $8ŧ'\<ߋZC/J.ȭ.p$iOv}PBj9"RGC^u:R~HΓ|Nf ZI;2 `Ӓj:1HBʆ/>f0LzeU 0T=xLFE7WzQ: !vwȍt{uYӑRwBJԞyEQCGP?+Zn}}M5Sx,3 n$<{C| YDkLth4”8 8#H?uw{;AOk &k}>!i$* X7y_2qv˸+H:.g}c++0M녒fPCЦh.r,_k`tH4Xԇ. mzHfq 7%]tn{ AYʣssc/4@<! Lb<]s۟mmt53] ɣ*@.zIR8W}c!Yak]v+I ȇ H; rXc3QLhsH[qj} [3,7%Eg&CYFTZk/u ~m*|ʹ zNài碐H*uYgT۲vD;!*A"Ys]Ԯ#s27l׹.}7M"%, o;$k]Dl7]}n?7QBd)31ISvFdkG$id;W@BȂJ ui0&y;n@]|49/ %nj(J/:Y]ds8Yw#%5 0RWq ,A!6}g7 `AK{ .THn*nm@6 I~G' 9"Ga"3R9)ҶMz*bB@Hvlş,`ut!2 ;I MzU]2, ڹ2O@ zH[kGɜ|N"Il8`*KBV{i]P/C:uQ9ϯe 5ok0JM.׏Đnʶ(n5"2>wcFD"Nb QC[3@%yɡbۛ <ϐGAV ruFvGBXQACBCPZ )=ۡ"X*5Ze}@I/5W.23E>D=Pl Y;8j{ɎVܭU Eq d-;ʓHwئ"  +ti"in]o2|= .7|Z+;"/ n)˘80<q49Y[]2P Yn.:LSH.G@,6A7Qf A.nN"[.\\k?Qf-+Q}2ʈNpM5v" N(['nAVJ1T̥ۜCi8f]}8?#SS| "_*Y QT&%kPV鞅 R?۩)"+L|K%;6ט.c̢-iD(ؗ݊tZѹFI-tA 磲=Cq?->e#"6vVoS 6g!2*E H2Y~d)%,W 74{:Ynx =.Glz<`'Y18*-džgnwGVܟQ,O~ۢQO,eAĚz/n4pH0 % F1-wP,܌$)("RSr[ tF`$*"M1vXnp'S~&fW|jHH+BC킒Dnvhkڜ]vjzoN`אY'T^8cn#H1 ߨSqET3q+JP,xz[-"LHsOMYcr˞k  . Mck1э' \ HzH#>ԫP6.x"Ms4]˵s&mor#}cBJxP ϟ6daϭg\se(.ϙU0Tq]†#mA (h@ԅ»(x&~\b-؛ ?IDAT3ۺz1wX$5 &4n$oۚ `A>,C^@bWP㑵SJ~/G-ܗq@^ "|2j/ j$x۳̱:Ơ }fD*QZGh7wk qv\'b_B-m?57`Oǝ7 V-oK^8T-N cn-w$`{*+j|1ED0ߔ N8$sCn f p>lr[,7?#Inq!27 00mݍXېL1N8N ϛ!U'Z'| z#LL40[ZtB[W5e)Pp>IUKc<_2FD4J x<ϔX՟Igo{ʔҔy۔gO6x?\g0$xnqcMRm,$3=U$%0U\4 $ǹŸ2_K dfg}w7MM=^w\>Vo'w272sk< ~S廝߷U "wyS4R3iL~^K>R/&׽#LFaA72+;v{NwG?eg7Ǥ+h2Ϧ0o[:3dߟH_vs+j*MSƘZ0 X`G:^w99 9/L6M[4o0.6) ~'}LC))|wJ_0(O3UҵS-8.2عuMB>]`u$6 SdSw n)CSގN~YAyZʳ9 S;MdqgL܎3ǔ/SÁynndݽg ?El5P1iƪU2 CNDDD[m%1-Sa wrw'Oipn5ʈ-m9fMM/gM"͛vJ:3I9_*+!=le64JGZa Lqn zeﻵIC8ed3IrFǟd}4tRq}|1=MU+W[nZ^DDD?gn04gJΚZڑS%ʓV0:ӓ5Ǚ$00@"ԥI`mɇfh-v6I|bm""""`cZ.v믟NU#'~$޸ܕFDDtx~6l+Mu_M""""Zw{0ZReawSYg-bv7""bajmIX\%1i`V<8iziZODDZ|͓ >UnnФk 6o9%6GVbI6|MMnяPp\Suǁm5ajs2wmtZ)zVP ?򵈈FbS湿74d&]yHzDDDtA_Tp»(#""߾w?ni 49jjzX۾V*_seM 7MTiR"`/[Lk]#""" /2mg&;4p-DDDDn˷fV3'3]Ϸe3l_p6`2KDDDDapef|Z/2S'8 jA/'xKSE mXA@a1ZB""""V+g SMkv+EDDDtXip*վe+"""Y}kۻ=QWlb$7니h5] LG.po.*""" q/YlSѡ+>7IENDB`sphinx-gallery-0.2.0/sphinx_gallery/_static/broken_stamp.svg000066400000000000000000001500241330553134500243460ustar00rootroot00000000000000 image/svg+xml sphinx-gallery-0.2.0/sphinx_gallery/_static/gallery.css000066400000000000000000000073431330553134500233170ustar00rootroot00000000000000/* Sphinx-Gallery has compatible CSS to fix default sphinx themes Tested for Sphinx 1.3.1 for all themes: default, alabaster, sphinxdoc, scrolls, agogo, traditional, nature, haiku, pyramid Tested for Read the Docs theme 0.1.7 */ .sphx-glr-thumbcontainer { background: #fff; border: solid #fff 1px; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; box-shadow: none; float: left; margin: 5px; min-height: 230px; padding-top: 5px; position: relative; } .sphx-glr-thumbcontainer:hover { border: solid #b4ddfc 1px; box-shadow: 0 0 15px rgba(142, 176, 202, 0.5); } .sphx-glr-thumbcontainer a.internal { bottom: 0; display: block; left: 0; padding: 150px 10px 0; position: absolute; right: 0; top: 0; } /* Next one is to avoid Sphinx traditional theme to cover all the thumbnail with its default link Background color */ .sphx-glr-thumbcontainer a.internal:hover { background-color: transparent; } .sphx-glr-thumbcontainer p { margin: 0 0 .1em 0; } .sphx-glr-thumbcontainer .figure { margin: 10px; width: 160px; } .sphx-glr-thumbcontainer img { display: inline; max-height: 160px; width: 160px; } .sphx-glr-thumbcontainer[tooltip]:hover:after { background: rgba(0, 0, 0, 0.8); -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; color: #fff; content: attr(tooltip); left: 95%; padding: 5px 15px; position: absolute; z-index: 98; width: 220px; bottom: 52%; } .sphx-glr-thumbcontainer[tooltip]:hover:before { border: solid; border-color: #333 transparent; border-width: 18px 0 0 20px; bottom: 58%; content: ''; left: 85%; position: absolute; z-index: 99; } .highlight-pytb pre { background-color: #ffe4e4; border: 1px solid #f66; margin-top: 10px; padding: 7px; } .sphx-glr-script-out { color: #888; margin: 0; } .sphx-glr-script-out .highlight { background-color: transparent; margin-left: 2.5em; margin-top: -1.4em; } .sphx-glr-script-out .highlight pre { background-color: #fafae2; border: 0; max-height: 30em; overflow: auto; padding-left: 1ex; margin: 0px; word-break: break-word; } .sphx-glr-script-out + p { margin-top: 1.8em; } blockquote.sphx-glr-script-out { margin-left: 0pt; } div.sphx-glr-footer { text-align: center; } div.binder-badge { margin: 1em auto; vertical-align: middle; } div.sphx-glr-download { margin: 1em auto; vertical-align: middle; } div.sphx-glr-download a { background-color: #ffc; background-image: linear-gradient(to bottom, #FFC, #d5d57e); border-radius: 4px; border: 1px solid #c2c22d; color: #000; display: inline-block; font-weight: bold; padding: 1ex; text-align: center; } div.sphx-glr-download code.download { display: inline-block; white-space: normal; word-break: normal; overflow-wrap: break-word; /* border and background are given by the enclosing 'a' */ border: none; background: none; } div.sphx-glr-download a:hover { box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 5px rgba(0,0,0,.25); text-decoration: none; background-image: none; background-color: #d5d57e; } .sphx-glr-example-title > :target::before { display: block; content: ""; margin-top: -50px; height: 50px; visibility: hidden; } ul.sphx-glr-horizontal { list-style: none; padding: 0; } ul.sphx-glr-horizontal li { display: inline; } ul.sphx-glr-horizontal img { height: auto !important; } .sphx-glr-single-img { margin: auto; display: block; max-width: 100%; } .sphx-glr-multi-img { max-width: 42%; height: auto; } p.sphx-glr-signature a.reference.external { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; padding: 3px; font-size: 75%; text-align: right; margin-left: auto; display: table; } sphinx-gallery-0.2.0/sphinx_gallery/_static/no_image.png000066400000000000000000000103331330553134500234230ustar00rootroot00000000000000PNG  IHDRy XsRGB pHYs B(xtIME+'gbKGDC[IDATx흋o (Wܨ$#hP@p H>Í#VEPEbRvgZh;3{gwnodP3g<"o@Z )h)R$R$RHH@K""E-E]0kH$>6bS#^0{   2{nbXU!fjrƻN0ukUL2m>.-x\DT`uC$yafa vA-YCvh+ t7_6 GrMn{[Nug=x|zcs% 7B n@w@ܗq ^;A'aFd t\hۥZCݠ ڣ%(?`;$KවVs/(=ki]S[7H t1m#"  U",Pa6Շ|:rGz_y'>z%jM(P'|Y~@M:E]@ 1k|1ac2*>Gj8^]H `3X륞5fi)`f9RkE *<F1ay'0@.FE * t>F|¬~>9 IATZ{@}"@PyRYU:4gܬu n!wyO4e)iݠlܣI77A}8Q@ & `|Sf0FABa:^a kz7< = @> Zc;>T܀] =GDm:V@5¬z9 sV.@mA>}6{fP{pBoKh.ߑBSs4ބb t@ ֭- t0lmƆq ځ5[%%l `">G"F8qD4S@k t@ipf:kJw7*h=h@ f(h讅:3Sp l3d3+mOJY; h>+=¡*lѧ $QYvt>]YhC[@/р`輄G-ʐTYy!q9hl4I0;"5?娛'RɨoJD4] r<>R]@0Set8jQ/qt$.\).Kւ}*lCO$ש>+)"Bbŏ;oBF< `/Ѝh{z89}_oE$6xr=ZxMz.s=q;OjtRөY{ٮbs? NL t鳣6.Cv0+Ц]h;GIKOW~[WKr}}fఽwXVmUzrϴT88܌f Y(ś ) OvpPte^KoD砬V#woJэ!ӾuMT7xcOĚIȈ_sKPk"΅NG2L{\ rݗ% +I۪Y?e+ T@`+WT_(r+܋v-r5ЙfmZs݈AuWL{^M^^Gyvf޹d10}x;m8xp-f&:=<ߤIoO_SDl~車i-QU2TТBi# z̯9 [ڜwuΗytOM[jUw{.;1*#Qklxm*EznsTpXZ] Nu׎ODю Oy-E-EZ t}U)RyL(a; iJǑOJ>?MDcf|pͱEuo%e.Y:9yL{e8\m~w:kCۓ(r ФIsC`c2-aX4/ODqj  tP׋{2uSw78$('h:pN +u$=D/qqR/@)5[.C|׬GJfj@z *Xz_ 3>;VP"P?.8<4+Wfڰ&vf},1֔ ЃGDL@Wtpy_0WID__\w- ]{ qTT/<>DߥQXn͡$}0&0FiLo7}IENDB`sphinx-gallery-0.2.0/sphinx_gallery/backreferences.py000066400000000000000000000151771330553134500230400ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Óscar Nájera # License: 3-clause BSD """ Backreferences Generator ======================== Parses example file code in order to keep track of used functions """ from __future__ import print_function, unicode_literals import codecs import ast import os # Try Python 2 first, otherwise load from Python 3 try: import cPickle as pickle except ImportError: import pickle # Try Python 3 first, otherwise load from Python 2 try: from html import escape except ImportError: from functools import partial from xml.sax.saxutils import escape escape = partial(escape, entities={'"': '"'}) from .py_source_parser import parse_source_file class NameFinder(ast.NodeVisitor): """Finds the longest form of variable names and their imports in code Only retains names from imported modules. """ def __init__(self): super(NameFinder, self).__init__() self.imported_names = {} self.accessed_names = set() def visit_Import(self, node, prefix=''): for alias in node.names: local_name = alias.asname or alias.name self.imported_names[local_name] = prefix + alias.name def visit_ImportFrom(self, node): self.visit_Import(node, node.module + '.') def visit_Name(self, node): self.accessed_names.add(node.id) def visit_Attribute(self, node): attrs = [] while isinstance(node, ast.Attribute): attrs.append(node.attr) node = node.value if isinstance(node, ast.Name): # This is a.b, not e.g. a().b attrs.append(node.id) self.accessed_names.add('.'.join(reversed(attrs))) else: # need to get a in a().b self.visit(node) def get_mapping(self): for name in self.accessed_names: local_name = name.split('.', 1)[0] remainder = name[len(local_name):] if local_name in self.imported_names: # Join import path to relative path full_name = self.imported_names[local_name] + remainder yield name, full_name def get_short_module_name(module_name, obj_name): """ Get the shortest possible module name """ scope = {} try: # Find out what the real object is supposed to be. exec('from %s import %s' % (module_name, obj_name), scope, scope) real_obj = scope[obj_name] except Exception: return module_name parts = module_name.split('.') short_name = module_name for i in range(len(parts) - 1, 0, -1): short_name = '.'.join(parts[:i]) scope = {} try: exec('from %s import %s' % (short_name, obj_name), scope, scope) # Ensure shortened object is the same as what we expect. assert real_obj is scope[obj_name] except Exception: # libraries can throw all sorts of exceptions... # get the last working module name short_name = '.'.join(parts[:(i + 1)]) break return short_name def identify_names(filename): """Builds a codeobj summary by identifying and resolving used names""" node, _ = parse_source_file(filename) if node is None: return {} finder = NameFinder() finder.visit(node) example_code_obj = {} for name, full_name in finder.get_mapping(): # name is as written in file (e.g. np.asarray) # full_name includes resolved import path (e.g. numpy.asarray) splitted = full_name.rsplit('.', 1) if len(splitted) == 1: # module without attribute. This is not useful for # backreferences continue module, attribute = splitted # get shortened module name module_short = get_short_module_name(module, attribute) cobj = {'name': attribute, 'module': module, 'module_short': module_short} example_code_obj[name] = cobj return example_code_obj def scan_used_functions(example_file, gallery_conf): """save variables so we can later add links to the documentation""" example_code_obj = identify_names(example_file) if example_code_obj: codeobj_fname = example_file[:-3] + '_codeobj.pickle' with open(codeobj_fname, 'wb') as fid: pickle.dump(example_code_obj, fid, pickle.HIGHEST_PROTOCOL) backrefs = set('{module_short}.{name}'.format(**entry) for entry in example_code_obj.values() if entry['module'].startswith(gallery_conf['doc_module'])) return backrefs THUMBNAIL_TEMPLATE = """ .. raw:: html
.. only:: html .. figure:: /{thumbnail} :ref:`sphx_glr_{ref_name}` .. raw:: html
""" BACKREF_THUMBNAIL_TEMPLATE = THUMBNAIL_TEMPLATE + """ .. only:: not html * :ref:`sphx_glr_{ref_name}` """ def _thumbnail_div(full_dir, fname, snippet, is_backref=False): """Generates RST to place a thumbnail in a gallery""" thumb = os.path.join(full_dir, 'images', 'thumb', 'sphx_glr_%s_thumb.png' % fname[:-3]) # Inside rst files forward slash defines paths thumb = thumb.replace(os.sep, "/") ref_name = os.path.join(full_dir, fname).replace(os.path.sep, '_') template = BACKREF_THUMBNAIL_TEMPLATE if is_backref else THUMBNAIL_TEMPLATE return template.format(snippet=escape(snippet), thumbnail=thumb, ref_name=ref_name) def write_backreferences(seen_backrefs, gallery_conf, target_dir, fname, snippet): """Writes down back reference files, which include a thumbnail list of examples using a certain module""" if gallery_conf['backreferences_dir'] is None: return example_file = os.path.join(target_dir, fname) build_target_dir = os.path.relpath(target_dir, gallery_conf['src_dir']) backrefs = scan_used_functions(example_file, gallery_conf) for backref in backrefs: include_path = os.path.join(gallery_conf['src_dir'], gallery_conf['backreferences_dir'], '%s.examples' % backref) seen = backref in seen_backrefs with codecs.open(include_path, 'a' if seen else 'w', encoding='utf-8') as ex_file: if not seen: heading = '\n\nExamples using ``%s``' % backref ex_file.write(heading + '\n') ex_file.write('^' * len(heading) + '\n') ex_file.write(_thumbnail_div(build_target_dir, fname, snippet, is_backref=True)) seen_backrefs.add(backref) sphinx-gallery-0.2.0/sphinx_gallery/binder.py000066400000000000000000000201731330553134500213310ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Chris Holdgraf # License: 3-clause BSD """ Binder utility functions ======================== Integration with Binder is on an experimental stage. Note that this API may change in the future. .. warning:: Binder is still beta technology, so there may be instability in the experience of users who click Binder links. """ import shutil import os try: basestring except NameError: basestring = str unicode = str from .utils import replace_py_ipynb from . import sphinx_compatibility logger = sphinx_compatibility.getLogger('sphinx-gallery') def gen_binder_url(fname, binder_conf, gallery_conf): """Generate a Binder URL according to the configuration in conf.py. Parameters ---------- fname: str The path to the `.py` file for which a Binder badge will be generated. binder_conf: dict | None The Binder configuration dictionary. See `gen_binder_rst` for details. Returns ------- binder_url : str A URL that can be used to direct the user to the live Binder environment. """ # Build the URL fpath_prefix = binder_conf.get('filepath_prefix') link_base = binder_conf.get('notebooks_dir') # We want to keep the relative path to sub-folders relative_link = os.path.relpath(fname, gallery_conf['src_dir']) path_link = os.path.join( link_base, replace_py_ipynb(relative_link)) # In case our website is hosted in a sub-folder if fpath_prefix is not None: path_link = '/'.join([fpath_prefix.strip('/'), path_link]) # Make sure we have the right slashes (in case we're on Windows) path_link = path_link.replace(os.path.sep, '/') # Create the URL binder_url = binder_conf['url'] binder_url = '/'.join([binder_conf['url'], 'v2', 'gh', binder_conf['org'], binder_conf['repo'], binder_conf['branch']]) if binder_conf.get('use_jupyter_lab', False) is True: binder_url += '?urlpath=lab/tree/{}'.format(path_link) else: binder_url += '?filepath={}'.format(path_link) return binder_url def gen_binder_rst(fname, binder_conf, gallery_conf): """Generate the RST + link for the Binder badge. Parameters ---------- fname: str The path to the `.py` file for which a Binder badge will be generated. binder_conf: dict | None If a dictionary it must have the following keys: 'url': The URL of the BinderHub instance that's running a Binder service. 'org': The GitHub organization to which the documentation will be pushed. 'repo': The GitHub repository to which the documentation will be pushed. 'branch': The Git branch on which the documentation exists (e.g., gh-pages). 'dependencies': A list of paths to dependency files that match the Binderspec. Returns ------- rst : str The reStructuredText for the Binder badge that links to this file. """ binder_conf = check_binder_conf(binder_conf) binder_url = gen_binder_url(fname, binder_conf, gallery_conf) rst = ( "\n" " .. container:: binder-badge\n\n" " .. image:: https://static.mybinder.org/badge.svg\n" " :target: {}\n" " :width: 150 px\n").format(binder_url) return rst def copy_binder_files(app, exception): """Copy all Binder requirements and notebooks files.""" if exception is not None: return if app.builder.name not in ['html', 'readthedocs']: return gallery_conf = app.config.sphinx_gallery_conf binder_conf = check_binder_conf(gallery_conf.get('binder')) if not len(binder_conf) > 0: return logger.info('copying binder requirements...', color='white') _copy_binder_reqs(app, binder_conf) _copy_binder_notebooks(app) def _copy_binder_reqs(app, binder_conf): """Copy Binder requirements files to a "binder" folder in the docs.""" path_reqs = binder_conf.get('dependencies') binder_folder = os.path.join(app.outdir, 'binder') if not os.path.isdir(binder_folder): os.makedirs(binder_folder) for path in path_reqs: shutil.copy(os.path.join(app.srcdir, path), binder_folder) def _remove_ipynb_files(path, contents): """Given a list of files in `contents`, remove all files named `ipynb` or directories named `images` and return the result. Used with the `shutil` "ignore" keyword to filter out non-ipynb files.""" contents_return = [] for entry in contents: if entry.endswith('.ipynb'): # Don't include ipynb files pass elif (entry != "images") and os.path.isdir(os.path.join(path, entry)): # Don't include folders not called "images" pass else: # Keep everything else contents_return.append(entry) return contents_return def _copy_binder_notebooks(app): """Copy Jupyter notebooks to the binder notebooks directory. Copy each output gallery directory structure but only including the Jupyter notebook files.""" gallery_conf = app.config.sphinx_gallery_conf gallery_dirs = gallery_conf.get('gallery_dirs') binder_conf = gallery_conf.get('binder') notebooks_dir = os.path.join(app.outdir, binder_conf.get('notebooks_dir')) shutil.rmtree(notebooks_dir, ignore_errors=True) os.makedirs(notebooks_dir) iterator = sphinx_compatibility.status_iterator( gallery_dirs, 'copying binder notebooks...', length=len(gallery_dirs)) for i_folder in iterator: shutil.copytree(os.path.join(app.srcdir, i_folder), os.path.join(notebooks_dir, i_folder), ignore=_remove_ipynb_files) def check_binder_conf(binder_conf): """Check to make sure that the Binder configuration is correct.""" # Grab the configuration and return None if it's not configured binder_conf = {} if binder_conf is None else binder_conf if not isinstance(binder_conf, dict): raise ValueError('`binder_conf` must be a dictionary or None.') if len(binder_conf) == 0: return binder_conf # Ensure all fields are populated req_values = ['url', 'org', 'repo', 'branch', 'dependencies'] optional_values = ['filepath_prefix', 'notebooks_dir', 'use_jupyter_lab'] missing_values = [] for val in req_values: if binder_conf.get(val) is None: missing_values.append(val) if len(missing_values) > 0: raise ValueError('binder_conf is missing values for: {}'.format( missing_values)) for key in binder_conf.keys(): if key not in (req_values + optional_values): raise ValueError("Unknown Binder config key: {}".format(key)) # Ensure we have http in the URL if not any(binder_conf['url'].startswith(ii) for ii in ['http://', 'https://']): raise ValueError('did not supply a valid url, ' 'gave url: {}'.format(binder_conf['url'])) # Ensure we have at least one dependency file # Need at least one of these two files required_reqs_files = ['requirements.txt', 'environment.yml'] path_reqs = binder_conf['dependencies'] if isinstance(path_reqs, basestring): path_reqs = [path_reqs] binder_conf['dependencies'] = path_reqs elif not isinstance(path_reqs, (list, tuple)): raise ValueError("`dependencies` value should be a list of strings. " "Got type {}.".format(type(path_reqs))) binder_conf['notebooks_dir'] = binder_conf.get('notebooks_dir', 'notebooks') path_reqs_filenames = [os.path.basename(ii) for ii in path_reqs] if not any(ii in path_reqs_filenames for ii in required_reqs_files): raise ValueError( 'Did not find one of `requirements.txt` or `environment.yml` ' 'in the "dependencies" section of the binder configuration ' 'for sphinx-gallery. A path to at least one of these files ' 'must exist in your Binder dependencies.') return binder_conf sphinx-gallery-0.2.0/sphinx_gallery/docs_resolv.py000066400000000000000000000351041330553134500224100ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Óscar Nájera # License: 3-clause BSD """ Link resolver objects ===================== """ from __future__ import print_function import codecs import gzip import os import posixpath import re import shelve import sys # Try Python 2 first, otherwise load from Python 3 try: import cPickle as pickle except ImportError: import pickle try: import urllib2 as urllib_request from urllib2 import HTTPError, URLError import urlparse as urllib_parse except ImportError: import urllib.request as urllib_request import urllib.parse as urllib_parse from urllib.error import HTTPError, URLError from io import BytesIO from sphinx.search import js_index from . import sphinx_compatibility logger = sphinx_compatibility.getLogger('sphinx-gallery') def _get_data(url): """Helper function to get data over http(s) or from a local file""" if urllib_parse.urlparse(url).scheme in ('http', 'https'): resp = urllib_request.urlopen(url) encoding = resp.headers.get('content-encoding', 'plain') data = resp.read() if encoding == 'plain': data = data.decode('utf-8') elif encoding == 'gzip': data = BytesIO(data) data = gzip.GzipFile(fileobj=data).read().decode('utf-8') else: raise RuntimeError('unknown encoding') else: with codecs.open(url, mode='r', encoding='utf-8') as fid: data = fid.read() return data def get_data(url, gallery_dir): """Persistent dictionary usage to retrieve the search indexes""" # shelve keys need to be str in python 2 if sys.version_info[0] == 2 and isinstance(url, unicode): url = url.encode('utf-8') cached_file = os.path.join(gallery_dir, 'searchindex') search_index = shelve.open(cached_file) if url in search_index: data = search_index[url] else: data = _get_data(url) search_index[url] = data search_index.close() return data def parse_sphinx_docopts(index): """ Parse the Sphinx index for documentation options. Parameters ---------- index : str The Sphinx index page Returns ------- docopts : dict The documentation options from the page. """ pos = index.find('var DOCUMENTATION_OPTIONS') if pos < 0: raise ValueError('Documentation options could not be found in index.') pos = index.find('{', pos) if pos < 0: raise ValueError('Documentation options could not be found in index.') endpos = index.find('};', pos) if endpos < 0: raise ValueError('Documentation options could not be found in index.') block = index[pos + 1:endpos].strip() docopts = {} for line in block.splitlines(): key, value = line.split(':', 1) key = key.strip().strip('"') value = value.strip() if value[-1] == ',': value = value[:-1].rstrip() if value[0] in '"\'': value = value[1:-1] elif value == 'false': value = False elif value == 'true': value = True else: try: value = int(value) except ValueError: # In Sphinx 1.7.5, URL_ROOT is a JavaScript fragment. # Ignoring this entry since URL_ROOT is not used # elsewhere. # https://github.com/sphinx-gallery/sphinx-gallery/issues/382 continue docopts[key] = value return docopts class SphinxDocLinkResolver(object): """ Resolve documentation links using searchindex.js generated by Sphinx Parameters ---------- doc_url : str The base URL of the project website. relative : bool Return relative links (only useful for links to documentation of this package). """ def __init__(self, doc_url, gallery_dir, relative=False): self.doc_url = doc_url self.gallery_dir = gallery_dir self.relative = relative self._link_cache = {} if doc_url.startswith(('http://', 'https://')): if relative: raise ValueError('Relative links are only supported for local ' 'URLs (doc_url cannot be absolute)') index_url = doc_url + '/' searchindex_url = doc_url + '/searchindex.js' docopts_url = doc_url + '_static/documentation_options.js' else: index_url = os.path.join(doc_url, 'index.html') searchindex_url = os.path.join(doc_url, 'searchindex.js') docopts_url = os.path.join(doc_url, '_static', 'documentation_options.js') # detect if we are using relative links on a Windows system if (os.name.lower() == 'nt' and not doc_url.startswith(('http://', 'https://'))): 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 find documentation options. As of Sphinx 1.7, these # options are now kept in a standalone file called # 'documentation_options.js'. Since SphinxDocLinkResolver can be called # not only for the documentation which is being built but also ones that # are being referenced, we need to try and get the index page first and # if that doesn't work, check for the documentation_options.js file. index = get_data(index_url, gallery_dir) if 'var DOCUMENTATION_OPTIONS' in index: self._docopts = parse_sphinx_docopts(index) else: docopts = get_data(docopts_url, gallery_dir) self._docopts = parse_sphinx_docopts(docopts) # download and initialize the search index sindex = get_data(searchindex_url, gallery_dir) self._searchindex = js_index.loads(sindex) def _get_link(self, cobj): """Get a valid link, False if not found""" fullname = cobj['module_short'] + '.' + cobj['name'] try: value = self._searchindex['objects'][cobj['module_short']] match = value[cobj['name']] except KeyError: link = False else: fname_idx = match[0] objname_idx = str(match[1]) anchor = match[3] fname = self._searchindex['filenames'][fname_idx] # In 1.5+ Sphinx seems to have changed from .rst.html to only # .html extension in converted files. Find this from the options. ext = self._docopts.get('FILE_SUFFIX', '.rst.html') fname = os.path.splitext(fname)[0] + ext if self._is_windows: fname = fname.replace('/', '\\') link = os.path.join(self.doc_url, fname) else: link = posixpath.join(self.doc_url, fname) if anchor == '': anchor = fullname elif anchor == '-': anchor = (self._searchindex['objnames'][objname_idx][1] + '-' + fullname) link = link + '#' + anchor return link def resolve(self, cobj, this_url): """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. cobj['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) # cache it for the future self._link_cache[full_name] = link if link is False or link is None: # failed to resolve return None 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 def _embed_code_links(app, gallery_conf, gallery_dir): # Add resolvers for the packages for which we want to show links doc_resolvers = {} src_gallery_dir = os.path.join(app.builder.srcdir, gallery_dir) for this_module, url in gallery_conf['reference_url'].items(): try: if url is None: doc_resolvers[this_module] = SphinxDocLinkResolver( app.builder.outdir, src_gallery_dir, relative=True) else: doc_resolvers[this_module] = SphinxDocLinkResolver( url, src_gallery_dir) except HTTPError as e: logger.warning( 'The following HTTP Error has occurred fetching %s: %d %s', e.url, e.code, e.msg) except URLError as e: logger.warning( "Embedding the documentation hyperlinks requires Internet " "access.\nPlease check your network connection.\nUnable to " "continue embedding `%s` links due to a URL Error:\n%s", this_module, str(e.args)) html_gallery_dir = os.path.abspath(os.path.join(app.builder.outdir, gallery_dir)) # patterns for replacement link_pattern = ('%s') orig_pattern = '%s' period = '.' # This could be turned into a generator if necessary, but should be okay flat = [[dirpath, filename] for dirpath, _, filenames in os.walk(html_gallery_dir) for filename in filenames] iterator = sphinx_compatibility.status_iterator( flat, 'embedding documentation hyperlinks for %s... ' % gallery_dir, color='fuchsia', length=len(flat), stringify_func=lambda x: os.path.basename(x[1])) intersphinx_inv = getattr(app.env, 'intersphinx_named_inventory', dict()) for dirpath, fname in iterator: full_fname = os.path.join(html_gallery_dir, dirpath, fname) subpath = dirpath[len(html_gallery_dir) + 1:] pickle_fname = os.path.join(src_gallery_dir, subpath, fname[:-5] + '_codeobj.pickle') if os.path.exists(pickle_fname): # we have a pickle file with the objects to embed links for with open(pickle_fname, 'rb') as fid: example_code_obj = pickle.load(fid) fid.close() str_repl = {} # generate replacement strings with the links for name, cobj in example_code_obj.items(): this_module = cobj['module'].split('.')[0] # Try doc resolvers first link = None if this_module in doc_resolvers: try: link = doc_resolvers[this_module].resolve(cobj, full_fname) except (HTTPError, URLError) as e: if isinstance(e, HTTPError): extra = e.code else: extra = e.reason logger.warning("Error resolving %s.%s: %r (%s)", cobj['module'], cobj['name'], e, extra) link = None # next try intersphinx if link is None and this_module in intersphinx_inv: inv = app.env.intersphinx_named_inventory[this_module] want = '%s.%s' % (cobj['module'], cobj['name']) for value in inv.values(): if want in value: link = value[want][2] break if link is not None: parts = name.split('.') name_html = period.join(orig_pattern % part for part in parts) full_function_name = '%s.%s' % ( cobj['module'], cobj['name']) str_repl[name_html] = link_pattern % ( link, full_function_name, name_html) # do the replacement in the html file # ensure greediness names = sorted(str_repl, key=len, reverse=True) regex_str = '|'.join(re.escape(name) for name in names) regex = re.compile(regex_str) def substitute_link(match): return str_repl[match.group()] if len(str_repl) > 0: with open(full_fname, 'rb') as fid: lines_in = fid.readlines() with open(full_fname, 'wb') as fid: for line in lines_in: line = line.decode('utf-8') line = regex.sub(substitute_link, line) fid.write(line.encode('utf-8')) def embed_code_links(app, exception): """Embed hyperlinks to documentation into example code""" if exception is not None: return # No need to waste time embedding hyperlinks when not running the examples # XXX: also at the time of writing this fixes make html-noplot # for some reason I don't fully understand if not app.builder.config.plot_gallery: return # XXX: Whitelist of builders for which it makes sense to embed # hyperlinks inside the example html. Note that the link embedding # require searchindex.js to exist for the links to the local doc # and there does not seem to be a good way of knowing which # builders creates a searchindex.js. if app.builder.name not in ['html', 'readthedocs']: return logger.info('embedding documentation hyperlinks...', color='white') gallery_conf = app.config.sphinx_gallery_conf gallery_dirs = gallery_conf['gallery_dirs'] if not isinstance(gallery_dirs, list): gallery_dirs = [gallery_dirs] for gallery_dir in gallery_dirs: _embed_code_links(app, gallery_conf, gallery_dir) sphinx-gallery-0.2.0/sphinx_gallery/downloads.py000066400000000000000000000071351330553134500220630ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" Utilities for downloadable items ================================ """ # Author: Óscar Nájera # License: 3-clause BSD from __future__ import absolute_import, division, print_function import os import zipfile CODE_DOWNLOAD = """ .. _sphx_glr_download_{3}: \n.. only :: html .. container:: sphx-glr-footer :class: sphx-glr-footer-example {2} \n .. container:: sphx-glr-download :download:`Download Python source code: {0} <{0}>`\n \n .. container:: sphx-glr-download :download:`Download Jupyter notebook: {1} <{1}>`\n""" CODE_ZIP_DOWNLOAD = """ \n.. only :: html .. container:: sphx-glr-footer :class: sphx-glr-footer-gallery \n .. container:: sphx-glr-download :download:`Download all examples in Python source code: {0} `\n \n .. container:: sphx-glr-download :download:`Download all examples in Jupyter notebooks: {2} `\n""" def python_zip(file_list, gallery_path, extension='.py'): """Stores all files in file_list into an zip file Parameters ---------- file_list : list of strings Holds all the file names to be included in zip file gallery_path : str path to where the zipfile is stored extension : str '.py' or '.ipynb' In order to deal with downloads of python sources and jupyter notebooks the file extension from files in file_list will be removed and replace with the value of this variable while generating the zip file Returns ------- zipname : str zip file name, written as `target_dir_{python,jupyter}.zip` depending on the extension """ zipname = os.path.basename(os.path.normpath(gallery_path)) zipname += '_python' if extension == '.py' else '_jupyter' zipname = os.path.join(gallery_path, zipname + '.zip') zipf = zipfile.ZipFile(zipname, mode='w') for fname in file_list: file_src = os.path.splitext(fname)[0] + extension zipf.write(file_src, os.path.relpath(file_src, gallery_path)) zipf.close() return zipname def list_downloadable_sources(target_dir): """Returns a list of python source files is target_dir Parameters ---------- target_dir : str path to the directory where python source file are Returns ------- list list of paths to all Python source files in `target_dir` """ return [os.path.join(target_dir, fname) for fname in os.listdir(target_dir) if fname.endswith('.py')] def generate_zipfiles(gallery_dir): """ Collects all Python source files and Jupyter notebooks in gallery_dir and makes zipfiles of them Parameters ---------- gallery_dir : str path of the gallery to collect downloadable sources Return ------ download_rst: str RestructuredText to include download buttons to the generated files """ listdir = list_downloadable_sources(gallery_dir) for directory in sorted(os.listdir(gallery_dir)): if os.path.isdir(os.path.join(gallery_dir, directory)): target_dir = os.path.join(gallery_dir, directory) listdir.extend(list_downloadable_sources(target_dir)) py_zipfile = python_zip(listdir, gallery_dir) jy_zipfile = python_zip(listdir, gallery_dir, ".ipynb") def rst_path(filepath): return filepath.replace(os.sep, '/') dw_rst = CODE_ZIP_DOWNLOAD.format(os.path.basename(py_zipfile), rst_path(py_zipfile), os.path.basename(jy_zipfile), rst_path(jy_zipfile)) return dw_rst sphinx-gallery-0.2.0/sphinx_gallery/gen_gallery.py000066400000000000000000000346541330553134500223670ustar00rootroot00000000000000# -*- 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 codecs import copy import re import os from sphinx.util.console import red from . import sphinx_compatibility, glr_path_static, __version__ as _sg_version from .gen_rst import generate_dir_rst, SPHX_GLR_SIG from .docs_resolv import embed_code_links from .downloads import generate_zipfiles from .sorting import NumberOfCodeLinesSortKey from .binder import copy_binder_files, check_binder_conf try: FileNotFoundError except NameError: # Python2 FileNotFoundError = IOError DEFAULT_GALLERY_CONF = { 'filename_pattern': re.escape(os.sep) + 'plot', 'ignore_pattern': '__init__\.py', 'examples_dirs': os.path.join('..', 'examples'), 'subsection_order': None, 'within_subsection_order': NumberOfCodeLinesSortKey, 'gallery_dirs': 'auto_examples', 'backreferences_dir': None, 'doc_module': (), 'reference_url': {}, # Build options # ------------- # We use a string for 'plot_gallery' rather than simply the Python boolean # `True` as it avoids a warning about unicode when controlling this value # via the command line switches of sphinx-build 'plot_gallery': 'True', 'download_all_examples': True, 'abort_on_example_error': False, 'failing_examples': {}, 'expected_failing_examples': set(), 'thumbnail_size': (400, 280), # Default CSS does 0.4 scaling (160, 112) 'min_reported_time': 0, 'binder': {}, } logger = sphinx_compatibility.getLogger('sphinx-gallery') 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: https://git.net/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 parse_config(app): """Process the Sphinx Gallery configuration""" try: plot_gallery = eval(app.builder.config.plot_gallery) except TypeError: plot_gallery = bool(app.builder.config.plot_gallery) gallery_conf = copy.deepcopy(DEFAULT_GALLERY_CONF) 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) gallery_conf['src_dir'] = app.builder.srcdir if gallery_conf.get("mod_example_dir", False): backreferences_warning = """\n======== Sphinx-Gallery found the configuration key 'mod_example_dir'. This is deprecated, and you should now use the key 'backreferences_dir' instead. Support for 'mod_example_dir' will be removed in a subsequent version of Sphinx-Gallery. For more details, see the backreferences documentation: https://sphinx-gallery.readthedocs.io/en/latest/advanced_configuration.html#references-to-examples""" gallery_conf['backreferences_dir'] = gallery_conf['mod_example_dir'] logger.warning( backreferences_warning, type=DeprecationWarning) # 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()) return gallery_conf def get_subsections(srcdir, examples_dir, sortkey): """Returns the list of subsections of a gallery Parameters ---------- srcdir : str absolute path to directory containing conf.py examples_dir : str path to the examples directory relative to conf.py sortkey : callable The sort key to use. Returns ------- out : list sorted list of gallery subsection folder names """ subfolders = [subfolder for subfolder in os.listdir(examples_dir) if os.path.exists(os.path.join(examples_dir, subfolder, 'README.txt'))] base_examples_dir_path = os.path.relpath(examples_dir, srcdir) subfolders_with_path = [os.path.join(base_examples_dir_path, item) for item in subfolders] sorted_subfolders = sorted(subfolders_with_path, key=sortkey) return [subfolders[i] for i in [subfolders_with_path.index(item) for item in sorted_subfolders]] def _prepare_sphx_glr_dirs(gallery_conf, srcdir): """Creates necessary folders for sphinx_gallery files """ 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] if bool(gallery_conf['backreferences_dir']): backreferences_dir = os.path.join( srcdir, gallery_conf['backreferences_dir']) if not os.path.exists(backreferences_dir): os.makedirs(backreferences_dir) return list(zip(examples_dirs, gallery_dirs)) 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 """ logger.info('generating gallery...', color='white') gallery_conf = parse_config(app) clean_gallery_out(app.builder.outdir) seen_backrefs = set() computation_times = [] workdirs = _prepare_sphx_glr_dirs(gallery_conf, app.builder.srcdir) # Check for duplicate filenames to make sure linking works as expected examples_dirs = [ex_dir for ex_dir, _ in workdirs] files = collect_gallery_files(examples_dirs) check_duplicate_filenames(files) for examples_dir, gallery_dir in workdirs: examples_dir = os.path.join(app.builder.srcdir, examples_dir) gallery_dir = os.path.join(app.builder.srcdir, gallery_dir) if not os.path.exists(os.path.join(examples_dir, 'README.txt')): raise FileNotFoundError("Main example directory {0} does not " "have a README.txt file. Please write " "one to introduce your gallery." .format(examples_dir)) # 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 # we create an index.rst with all examples with codecs.open(os.path.join(gallery_dir, 'index.rst'), 'w', encoding='utf-8') as fhindex: # :orphan: to suppress "not included in TOCTREE" sphinx warnings fhindex.write(":orphan:\n\n" + this_fhindex) for subsection in get_subsections(app.builder.srcdir, examples_dir, gallery_conf['subsection_order']): src_dir = os.path.join(examples_dir, subsection) target_dir = os.path.join(gallery_dir, subsection) 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 if gallery_conf['download_all_examples']: download_fhindex = generate_zipfiles(gallery_dir) fhindex.write(download_fhindex) fhindex.write(SPHX_GLR_SIG) if gallery_conf['plot_gallery']: logger.info("computation time summary:", color='white') for time_elapsed, fname in sorted(computation_times, reverse=True): if time_elapsed is not None: if time_elapsed >= gallery_conf['min_reported_time']: logger.info("\t- %s: %.2g sec", fname, time_elapsed) else: logger.info("\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""" if not bool(app.config.sphinx_gallery_conf['backreferences_dir']): return examples_path = os.path.join(app.srcdir, app.config.sphinx_gallery_conf[ "backreferences_dir"], "%s.examples" % name) if not os.path.exists(examples_path): # touch file open(examples_path, 'w').close() def sumarize_failing_examples(app, exception): """Collects the list of falling examples during build and prints them with the traceback Raises ValueError if there where failing examples """ if exception is not None: return # Under no-plot Examples are not run so nothing to summarize if not app.config.sphinx_gallery_conf['plot_gallery']: return gallery_conf = app.config.sphinx_gallery_conf failing_examples = set(gallery_conf['failing_examples'].keys()) expected_failing_examples = set([os.path.normpath(os.path.join(app.srcdir, path)) for path in gallery_conf['expected_failing_examples']]) examples_expected_to_fail = failing_examples.intersection( expected_failing_examples) if examples_expected_to_fail: logger.info("Examples failing as expected:", color='brown') for fail_example in examples_expected_to_fail: logger.info('%s failed leaving traceback:', fail_example) logger.info(gallery_conf['failing_examples'][fail_example]) examples_not_expected_to_fail = failing_examples.difference( expected_failing_examples) fail_msgs = [] if examples_not_expected_to_fail: fail_msgs.append(red("Unexpected failing examples:")) for fail_example in examples_not_expected_to_fail: fail_msgs.append(fail_example + ' failed leaving traceback:\n' + gallery_conf['failing_examples'][fail_example] + '\n') examples_not_expected_to_pass = expected_failing_examples.difference( failing_examples) # filter from examples actually run filename_pattern = gallery_conf.get('filename_pattern') examples_not_expected_to_pass = [src_file for src_file in examples_not_expected_to_pass if re.search(filename_pattern, src_file)] if examples_not_expected_to_pass: fail_msgs.append(red("Examples expected to fail, but not failing:\n") + "Please remove these examples from\n" + "sphinx_gallery_conf['expected_failing_examples']\n" + "in your conf.py file" "\n".join(examples_not_expected_to_pass)) if fail_msgs: raise ValueError("Here is a summary of the problems encountered when " "running the examples\n\n" + "\n".join(fail_msgs) + "\n" + "-" * 79) def collect_gallery_files(examples_dirs): """Collect python files from the gallery example directories.""" files = [] for example_dir in examples_dirs: for root, dirnames, filenames in os.walk(example_dir): for filename in filenames: if filename.endswith('.py'): files.append(os.path.join(root, filename)) return files def check_duplicate_filenames(files): """Check for duplicate filenames across gallery directories.""" # Check whether we'll have duplicates used_names = set() dup_names = list() for this_file in files: this_fname = os.path.basename(this_file) if this_fname in used_names: dup_names.append(this_file) else: used_names.add(this_fname) if len(dup_names) > 0: logger.warning( 'Duplicate file name(s) found. Having duplicate file names will ' 'break some links. List of files: {}'.format(sorted(dup_names),)) def get_default_config_value(key): def default_getter(conf): return conf['sphinx_gallery_conf'].get(key, DEFAULT_GALLERY_CONF[key]) return default_getter def setup(app): """Setup sphinx-gallery sphinx extension""" sphinx_compatibility._app = app app.add_config_value('sphinx_gallery_conf', DEFAULT_GALLERY_CONF, 'html') for key in ['plot_gallery', 'abort_on_example_error']: app.add_config_value(key, get_default_config_value(key), 'html') app.add_stylesheet('gallery.css') # Sphinx < 1.6 calls it `_extensions`, >= 1.6 is `extensions`. extensions_attr = '_extensions' if hasattr( app, '_extensions') else 'extensions' if 'sphinx.ext.autodoc' in getattr(app, extensions_attr): app.connect('autodoc-process-docstring', touch_empty_backreferences) app.connect('builder-inited', generate_gallery_rst) app.connect('build-finished', copy_binder_files) app.connect('build-finished', sumarize_failing_examples) app.connect('build-finished', embed_code_links) metadata = {'parallel_read_safe': True, 'version': _sg_version} return metadata def setup_module(): # HACK: Stop nosetests running setup() above pass sphinx-gallery-0.2.0/sphinx_gallery/gen_rst.py000066400000000000000000000622431330553134500215330ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Óscar Nájera # License: 3-clause BSD """ RST file generator ================== Generate the rst files for the examples by iterating over the python example files. Files that generate images should start with 'plot' """ # Don't use unicode_literals here (be explicit with u"..." instead) otherwise # tricky errors come up with exec(code_blocks, ...) calls from __future__ import division, print_function, absolute_import from time import time import ast import codecs import hashlib import os import re import shutil import subprocess import sys import traceback import codeop from distutils.version import LooseVersion from .utils import replace_py_ipynb # Try Python 2 first, otherwise load from Python 3 try: # textwrap indent only exists in python 3 from textwrap import indent except ImportError: def indent(text, prefix, predicate=None): """Adds 'prefix' to the beginning of selected lines in 'text'. If 'predicate' is provided, 'prefix' will only be added to the lines where 'predicate(line)' is True. If 'predicate' is not provided, it will default to adding 'prefix' to all non-empty lines that do not consist solely of whitespace characters. """ if predicate is None: def predicate(line): return line.strip() def prefixed_lines(): for line in text.splitlines(True): yield (prefix + line if predicate(line) else line) return ''.join(prefixed_lines()) from io import StringIO # make sure that the Agg backend is set before importing any # matplotlib import matplotlib matplotlib.use('agg') matplotlib_backend = matplotlib.get_backend() if matplotlib_backend != 'agg': mpl_backend_msg = ( "Sphinx-Gallery relies on the matplotlib 'agg' backend to " "render figures and write them to files. You are " "currently using the {} backend. Sphinx-Gallery will " "terminate the build now, because changing backends is " "not well supported by matplotlib. We advise you to move " "sphinx_gallery imports before any matplotlib-dependent " "import. Moving sphinx_gallery imports at the top of " "your conf.py file should fix this issue") raise ValueError(mpl_backend_msg.format(matplotlib_backend)) import matplotlib.pyplot as plt import sphinx from . import glr_path_static from . import sphinx_compatibility from .backreferences import write_backreferences, _thumbnail_div from .downloads import CODE_DOWNLOAD from .py_source_parser import split_code_and_text_blocks from .notebook import jupyter_notebook, save_notebook from .binder import check_binder_conf, gen_binder_rst try: basestring except NameError: basestring = str unicode = str logger = sphinx_compatibility.getLogger('sphinx-gallery') ############################################################################### class LoggingTee(object): """A tee object to redirect streams to the logger""" def __init__(self, output_file, logger, src_filename): self.output_file = output_file self.logger = logger self.src_filename = src_filename self.first_write = True self.logger_buffer = '' def write(self, data): self.output_file.write(data) if self.first_write: self.logger.verbose('Output from %s', self.src_filename, color='brown') self.first_write = False data = self.logger_buffer + data lines = data.splitlines() if data and data[-1] not in '\r\n': # Wait to write last line if it's incomplete. It will write next # time or when the LoggingTee is flushed. self.logger_buffer = lines[-1] lines = lines[:-1] else: self.logger_buffer = '' for line in lines: self.logger.verbose('%s', line) def flush(self): self.output_file.flush() if self.logger_buffer: self.logger.verbose('%s', self.logger_buffer) self.logger_buffer = '' # When called from a local terminal seaborn needs it in Python3 def isatty(self): return self.output_file.isatty() class MixedEncodingStringIO(StringIO): """Helper when both ASCII and unicode strings will be written""" def write(self, data): if not isinstance(data, unicode): data = data.decode('utf-8') StringIO.write(self, data) ############################################################################### # The following strings are used when we have several pictures: we use # an html div tag that our CSS uses to turn the lists into horizontal # lists. HLIST_HEADER = """ .. rst-class:: sphx-glr-horizontal """ HLIST_IMAGE_TEMPLATE = """ * .. image:: /%s :class: sphx-glr-multi-img """ SINGLE_IMAGE = """ .. image:: /%s :class: sphx-glr-single-img """ # This one could contain unicode CODE_OUTPUT = u""".. rst-class:: sphx-glr-script-out Out: .. code-block:: none {0}\n""" SPHX_GLR_SIG = """\n .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_\n""" def codestr2rst(codestr, lang='python', lineno=None): """Return reStructuredText code block from code string""" if lineno is not None: if LooseVersion(sphinx.__version__) >= '1.3': # Sphinx only starts numbering from the first non-empty line. blank_lines = codestr.count('\n', 0, -len(codestr.lstrip())) lineno = ' :lineno-start: {0}\n'.format(lineno + blank_lines) else: lineno = ' :linenos:\n' else: lineno = '' code_directive = "\n.. code-block:: {0}\n{1}\n".format(lang, lineno) indented_block = indent(codestr, ' ' * 4) return code_directive + indented_block def extract_intro_and_title(filename, docstring): """ Extract the first paragraph of module-level docstring. max:95 char""" # lstrip is just in case docstring has a '\n\n' at the beginning paragraphs = docstring.lstrip().split('\n\n') # remove comments and other syntax like `.. _link:` paragraphs = [p for p in paragraphs if not p.startswith('.. ') and len(p) > 0] if len(paragraphs) == 0: raise ValueError( "Example docstring should have a header for the example title. " "Please check the example file:\n {}\n".format(filename)) # Title is the first paragraph with any ReSTructuredText title chars # removed, i.e. lines that consist of (all the same) 7-bit non-ASCII chars. # This conditional is not perfect but should hopefully be good enough. title_paragraph = paragraphs[0] match = re.search(r'([\w ]+)', title_paragraph) if match is None: raise ValueError( 'Could not find a title in first paragraph:\n{}'.format( title_paragraph)) title = match.group(1).strip() # Use the title if no other paragraphs are provided intro_paragraph = title if len(paragraphs) < 2 else paragraphs[1] # Concatenate all lines of the first paragraph and truncate at 95 chars intro = re.sub('\n', ' ', intro_paragraph) if len(intro) > 95: intro = intro[:95] + '...' return intro, title def get_md5sum(src_file): """Returns md5sum of file""" with open(src_file, 'rb') as src_data: src_content = src_data.read() src_md5 = hashlib.md5(src_content).hexdigest() return src_md5 def md5sum_is_current(src_file): """Checks whether src_file has the same md5 hash as the one on disk""" src_md5 = get_md5sum(src_file) src_md5_file = src_file + '.md5' if os.path.exists(src_md5_file): with open(src_md5_file, 'r') as file_checksum: ref_md5 = file_checksum.read() return src_md5 == ref_md5 return False def save_figures(image_path, fig_count, gallery_conf): """Save all open matplotlib figures of the example code-block Parameters ---------- image_path : str Path where plots are saved (format string which accepts figure number) fig_count : int Previous figure number count. Figure number add from this number gallery_conf : dict Contains the configuration of Sphinx-Gallery Returns ------- images_rst : str rst code to embed the images in the document fig_num : int number of figures saved """ figure_list = [] for fig_num in plt.get_fignums(): # Set the fig_num figure as the current figure as we can't # save a figure that's not the current figure. fig = plt.figure(fig_num) kwargs = {} to_rgba = matplotlib.colors.colorConverter.to_rgba for attr in ['facecolor', 'edgecolor']: fig_attr = getattr(fig, 'get_' + attr)() default_attr = matplotlib.rcParams['figure.' + attr] if to_rgba(fig_attr) != to_rgba(default_attr): kwargs[attr] = fig_attr current_fig = image_path.format(fig_count + fig_num) fig.savefig(current_fig, **kwargs) figure_list.append(current_fig) if gallery_conf.get('find_mayavi_figures', False): from mayavi import mlab e = mlab.get_engine() last_matplotlib_fig_num = fig_count + len(figure_list) total_fig_num = last_matplotlib_fig_num + len(e.scenes) mayavi_fig_nums = range(last_matplotlib_fig_num + 1, total_fig_num + 1) for scene, mayavi_fig_num in zip(e.scenes, mayavi_fig_nums): current_fig = image_path.format(mayavi_fig_num) mlab.savefig(current_fig, figure=scene) # make sure the image is not too large scale_image(current_fig, current_fig, 850, 999) figure_list.append(current_fig) mlab.close(all=True) return figure_rst(figure_list, gallery_conf['src_dir']) def figure_rst(figure_list, sources_dir): """Given a list of paths to figures generate the corresponding rst Depending on whether we have one or more figures, we use a single rst call to 'image' or a horizontal list. Parameters ---------- figure_list : list of str Strings are the figures' absolute paths sources_dir : str absolute path of Sphinx documentation sources Returns ------- images_rst : str rst code to embed the images in the document fig_num : int number of figures saved """ figure_paths = [os.path.relpath(figure_path, sources_dir) .replace(os.sep, '/').lstrip('/') for figure_path in figure_list] images_rst = "" if len(figure_paths) == 1: figure_name = figure_paths[0] images_rst = SINGLE_IMAGE % figure_name elif len(figure_paths) > 1: images_rst = HLIST_HEADER for figure_name in figure_paths: images_rst += HLIST_IMAGE_TEMPLATE % figure_name return images_rst, len(figure_list) def scale_image(in_fname, out_fname, max_width, max_height): """Scales an image with the same aspect ratio centered in an image with a given max_width and max_height if in_fname == out_fname the image can only be scaled down """ # local import to avoid testing dependency on PIL: try: from PIL import Image except ImportError: import Image img = Image.open(in_fname) width_in, height_in = img.size scale_w = max_width / float(width_in) scale_h = max_height / float(height_in) if height_in * scale_w <= max_height: scale = scale_w else: scale = scale_h if scale >= 1.0 and in_fname == out_fname: return width_sc = int(round(scale * width_in)) height_sc = int(round(scale * height_in)) # resize the image using resize; if using .thumbnail and the image is # already smaller than max_width, max_height, then this won't scale up # at all (maybe could be an option someday...) img = img.resize((width_sc, height_sc), Image.BICUBIC) # img.thumbnail((width_sc, height_sc), Image.BICUBIC) # width_sc, height_sc = img.size # necessary if using thumbnail # insert centered thumb = Image.new('RGBA', (max_width, max_height), (255, 255, 255, 255)) pos_insert = ((max_width - width_sc) // 2, (max_height - height_sc) // 2) thumb.paste(img, pos_insert) thumb.save(out_fname) def save_thumbnail(image_path_template, src_file, file_conf, gallery_conf): """Save the thumbnail image""" # read specification of the figure to display as thumbnail from main text thumbnail_number = file_conf.get('thumbnail_number', 1) if not isinstance(thumbnail_number, int): raise TypeError( 'sphinx_gallery_thumbnail_number setting is not a number.') thumbnail_image_path = image_path_template.format(thumbnail_number) thumb_dir = os.path.join(os.path.dirname(thumbnail_image_path), 'thumb') if not os.path.exists(thumb_dir): os.makedirs(thumb_dir) base_image_name = os.path.splitext(os.path.basename(src_file))[0] thumb_file = os.path.join(thumb_dir, 'sphx_glr_%s_thumb.png' % base_image_name) if src_file in gallery_conf['failing_examples']: img = os.path.join(glr_path_static(), 'broken_example.png') elif os.path.exists(thumbnail_image_path): img = thumbnail_image_path elif not os.path.exists(thumb_file): # create something to replace the thumbnail img = os.path.join(glr_path_static(), 'no_image.png') img = gallery_conf.get("default_thumb_file", img) else: return scale_image(img, thumb_file, *gallery_conf["thumbnail_size"]) def generate_dir_rst(src_dir, target_dir, gallery_conf, seen_backrefs): """Generate the gallery reStructuredText for an example directory""" with codecs.open(os.path.join(src_dir, 'README.txt'), 'r', encoding='utf-8') as fid: fhindex = fid.read() # Add empty lines to avoid bug in issue #165 fhindex += "\n\n" if not os.path.exists(target_dir): os.makedirs(target_dir) # get filenames listdir = [fname for fname in os.listdir(src_dir) if fname.endswith('.py')] # limit which to look at based on regex (similar to filename_pattern) listdir = [fname for fname in listdir if re.search(gallery_conf['ignore_pattern'], os.path.normpath(os.path.join(src_dir, fname))) is None] # sort them sorted_listdir = sorted( listdir, key=gallery_conf['within_subsection_order'](src_dir)) entries_text = [] computation_times = [] build_target_dir = os.path.relpath(target_dir, gallery_conf['src_dir']) iterator = sphinx_compatibility.status_iterator( sorted_listdir, 'generating gallery for %s... ' % build_target_dir, length=len(sorted_listdir)) for fname in iterator: intro, time_elapsed = generate_file_rst( fname, target_dir, src_dir, gallery_conf) computation_times.append((time_elapsed, fname)) this_entry = _thumbnail_div(build_target_dir, fname, intro) + """ .. toctree:: :hidden: /%s\n""" % os.path.join(build_target_dir, fname[:-3]).replace(os.sep, '/') entries_text.append(this_entry) if gallery_conf['backreferences_dir']: write_backreferences(seen_backrefs, gallery_conf, target_dir, fname, intro) for entry_text in entries_text: fhindex += entry_text # clear at the end of the section fhindex += """.. raw:: html\n
\n\n""" return fhindex, computation_times def handle_exception(exc_info, src_file, block_vars, gallery_conf): etype, exc, tb = exc_info stack = traceback.extract_tb(tb) # Remove our code from traceback: if isinstance(exc, SyntaxError): # Remove one extra level through ast.parse. stack = stack[2:] else: stack = stack[1:] formatted_exception = 'Traceback (most recent call last):\n' + ''.join( traceback.format_list(stack) + traceback.format_exception_only(etype, exc)) logger.warning('%s failed to execute correctly: %s', src_file, formatted_exception) except_rst = codestr2rst(formatted_exception, lang='pytb') # Breaks build on first example error if gallery_conf['abort_on_example_error']: raise # Stores failing file gallery_conf['failing_examples'][src_file] = formatted_exception block_vars['execute_script'] = False return except_rst def execute_code_block(compiler, src_file, code_block, lineno, example_globals, block_vars, gallery_conf): """Executes the code block of the example file""" time_elapsed = 0 # If example is not suitable to run, skip executing its blocks if not block_vars['execute_script']: return '', time_elapsed plt.close('all') cwd = os.getcwd() # Redirect output to stdout and orig_stdout = sys.stdout src_file = block_vars['src_file'] # First cd in the original example dir, so that any file # created by the example get created in this directory my_stdout = MixedEncodingStringIO() os.chdir(os.path.dirname(src_file)) sys.stdout = LoggingTee(my_stdout, logger, src_file) try: dont_inherit = 1 code_ast = compile(code_block, src_file, 'exec', ast.PyCF_ONLY_AST | compiler.flags, dont_inherit) ast.increment_lineno(code_ast, lineno - 1) t_start = time() # don't use unicode_literals at the top of this file or you get # nasty errors here on Py2.7 exec(compiler(code_ast, src_file, 'exec'), example_globals) time_elapsed = time() - t_start except Exception: sys.stdout.flush() sys.stdout = orig_stdout except_rst = handle_exception(sys.exc_info(), src_file, block_vars, gallery_conf) # python2.7: Code was read in bytes needs decoding to utf-8 # unless future unicode_literals is imported in source which # make ast output unicode strings if hasattr(except_rst, 'decode') and not isinstance(except_rst, unicode): except_rst = except_rst.decode('utf-8') code_output = u"\n{0}\n\n\n\n".format(except_rst) else: sys.stdout.flush() sys.stdout = orig_stdout os.chdir(cwd) my_stdout = my_stdout.getvalue().strip().expandtabs() if my_stdout: stdout = CODE_OUTPUT.format(indent(my_stdout, u' ' * 4)) else: stdout = '' images_rst, fig_num = save_figures(block_vars['image_path'], block_vars['fig_count'], gallery_conf) block_vars['fig_count'] += fig_num code_output = u"\n{0}\n\n{1}\n\n".format(images_rst, stdout) finally: os.chdir(cwd) sys.stdout = orig_stdout return code_output, time_elapsed def clean_modules(): """Remove "unload" seaborn from the name space After a script is executed it can load a variety of setting that one does not want to influence in other examples in the gallery.""" # Horrible code to 'unload' seaborn, so that it resets # its default when is load # Python does not support unloading of modules # https://bugs.python.org/issue9072 for module in list(sys.modules.keys()): if 'seaborn' in module: del sys.modules[module] # Reset Matplotlib to default plt.rcdefaults() def generate_file_rst(fname, target_dir, src_dir, gallery_conf): """Generate the rst file for a given example. Returns ------- intro: str The introduction of the example time_elapsed : float seconds required to run the script """ binder_conf = check_binder_conf(gallery_conf.get('binder')) src_file = os.path.normpath(os.path.join(src_dir, fname)) example_file = os.path.join(target_dir, fname) shutil.copyfile(src_file, example_file) file_conf, script_blocks = split_code_and_text_blocks(src_file) intro, title = extract_intro_and_title(fname, script_blocks[0][1]) if md5sum_is_current(example_file): return intro, 0 image_dir = os.path.join(target_dir, 'images') if not os.path.exists(image_dir): os.makedirs(image_dir) base_image_name = os.path.splitext(fname)[0] image_fname = 'sphx_glr_' + base_image_name + '_{0:03}.png' image_path_template = os.path.join(image_dir, image_fname) ref_fname = os.path.relpath(example_file, gallery_conf['src_dir']) ref_fname = ref_fname.replace(os.path.sep, '_') binder_text = (" or run this example in your browser via Binder" if len(binder_conf) else "") example_rst = (".. note::\n" " :class: sphx-glr-download-link-note\n\n" " Click :ref:`here ` " "to download the full example code{1}\n" ".. rst-class:: sphx-glr-example-title\n\n" ".. _sphx_glr_{0}:\n\n" ).format( ref_fname, binder_text) filename_pattern = gallery_conf.get('filename_pattern') execute_script = re.search(filename_pattern, src_file) and gallery_conf[ 'plot_gallery'] example_globals = { # A lot of examples contains 'print(__doc__)' for example in # scikit-learn so that running the example prints some useful # information. Because the docstring has been separated from # the code blocks in sphinx-gallery, __doc__ is actually # __builtin__.__doc__ in the execution context and we do not # want to print it '__doc__': '', # Examples may contain if __name__ == '__main__' guards # for in example scikit-learn if the example uses multiprocessing '__name__': '__main__', # Don't ever support __file__: Issues #166 #212 } compiler = codeop.Compile() # A simple example has two blocks: one for the # example introduction/explanation and one for the code is_example_notebook_like = len(script_blocks) > 2 time_elapsed = 0 block_vars = {'execute_script': execute_script, 'fig_count': 0, 'image_path': image_path_template, 'src_file': src_file} argv_orig = sys.argv[:] if block_vars['execute_script']: # We want to run the example without arguments. See # https://github.com/sphinx-gallery/sphinx-gallery/pull/252 # for more details. sys.argv[0] = src_file sys.argv[1:] = [] for blabel, bcontent, lineno in script_blocks: if blabel == 'code': code_output, rtime = execute_code_block(compiler, src_file, bcontent, lineno, example_globals, block_vars, gallery_conf) time_elapsed += rtime if not file_conf.get('line_numbers', gallery_conf.get('line_numbers', False)): lineno = None if is_example_notebook_like: example_rst += codestr2rst(bcontent, lineno=lineno) + '\n' example_rst += code_output else: example_rst += code_output if 'sphx-glr-script-out' in code_output: # Add some vertical space after output example_rst += "\n\n|\n\n" example_rst += codestr2rst(bcontent, lineno=lineno) + '\n' else: example_rst += bcontent + '\n\n' sys.argv = argv_orig clean_modules() # Writes md5 checksum if example has build correctly # not failed and was initially meant to run(no-plot shall not cache md5sum) if block_vars['execute_script']: with open(example_file + '.md5', 'w') as file_checksum: file_checksum.write(get_md5sum(example_file)) save_thumbnail(image_path_template, src_file, file_conf, gallery_conf) time_m, time_s = divmod(time_elapsed, 60) example_nb = jupyter_notebook(script_blocks) save_notebook(example_nb, replace_py_ipynb(example_file)) with codecs.open(os.path.join(target_dir, base_image_name + '.rst'), mode='w', encoding='utf-8') as f: if time_elapsed >= gallery_conf["min_reported_time"]: example_rst += ("**Total running time of the script:**" " ({0: .0f} minutes {1: .3f} seconds)\n\n".format( time_m, time_s)) # Generate a binder URL if specified binder_badge_rst = '' if len(binder_conf) > 0: binder_badge_rst += gen_binder_rst(example_file, binder_conf, gallery_conf) example_rst += CODE_DOWNLOAD.format(fname, replace_py_ipynb(fname), binder_badge_rst, ref_fname) example_rst += SPHX_GLR_SIG f.write(example_rst) if block_vars['execute_script']: logger.debug("%s ran in : %.2g seconds", src_file, time_elapsed) return intro, time_elapsed sphinx-gallery-0.2.0/sphinx_gallery/notebook.py000066400000000000000000000133321330553134500217050ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" Parser for Jupyter notebooks ============================ Class that holds the Jupyter notebook information """ # Author: Óscar Nájera # License: 3-clause BSD from __future__ import division, absolute_import, print_function from functools import partial import argparse import json import re import sys from .py_source_parser import split_code_and_text_blocks from .utils import replace_py_ipynb def jupyter_notebook_skeleton(): """Returns a dictionary with the elements of a Jupyter notebook""" py_version = sys.version_info notebook_skeleton = { "cells": [], "metadata": { "kernelspec": { "display_name": "Python " + str(py_version[0]), "language": "python", "name": "python" + str(py_version[0]) }, "language_info": { "codemirror_mode": { "name": "ipython", "version": py_version[0] }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython" + str(py_version[0]), "version": '{0}.{1}.{2}'.format(*sys.version_info[:3]) } }, "nbformat": 4, "nbformat_minor": 0 } return notebook_skeleton def directive_fun(match, directive): """Helper to fill in directives""" directive_to_alert = dict(note="info", warning="danger") return ('

{1}

{2}

' .format(directive_to_alert[directive], directive.capitalize(), match.group(1).strip())) def rst2md(text): """Converts the RST text from the examples docstrigs and comments into markdown text for the Jupyter notebooks""" top_heading = re.compile(r'^=+$\s^([\w\s-]+)^=+$', flags=re.M) text = re.sub(top_heading, r'# \1', text) math_eq = re.compile(r'^\.\. math::((?:.+)?(?:\n+^ .+)*)', flags=re.M) text = re.sub(math_eq, lambda match: r'\begin{{align}}{0}\end{{align}}'.format( match.group(1).strip()), text) inline_math = re.compile(r':math:`(.+?)`', re.DOTALL) text = re.sub(inline_math, r'$\1$', text) directives = ('warning', 'note') for directive in directives: directive_re = re.compile(r'^\.\. %s::((?:.+)?(?:\n+^ .+)*)' % directive, flags=re.M) text = re.sub(directive_re, partial(directive_fun, directive=directive), text) links = re.compile(r'^ *\.\. _.*:.*$\n', flags=re.M) text = re.sub(links, '', text) refs = re.compile(r':ref:`') text = re.sub(refs, '`', text) contents = re.compile(r'^\s*\.\. contents::.*$(\n +:\S+: *$)*\n', flags=re.M) text = re.sub(contents, '', text) images = re.compile( r'^\.\. image::(.*$)(?:\n *:alt:(.*$)\n)?(?: +:\S+:.*$\n)*', flags=re.M) text = re.sub( images, lambda match: '![{1}]({0})\n'.format( match.group(1).strip(), (match.group(2) or '').strip()), text) return text def jupyter_notebook(script_blocks): """Generate a Jupyter notebook file cell-by-cell Parameters ---------- script_blocks: list script execution cells """ work_notebook = jupyter_notebook_skeleton() add_code_cell(work_notebook, "%matplotlib inline") fill_notebook(work_notebook, script_blocks) return work_notebook def add_code_cell(work_notebook, code): """Add a code cell to the notebook Parameters ---------- code : str Cell content """ code_cell = { "cell_type": "code", "execution_count": None, "metadata": {"collapsed": False}, "outputs": [], "source": [code.strip()] } work_notebook["cells"].append(code_cell) def add_markdown_cell(work_notebook, text): """Add a markdown cell to the notebook Parameters ---------- code : str Cell content """ markdown_cell = { "cell_type": "markdown", "metadata": {}, "source": [rst2md(text)] } work_notebook["cells"].append(markdown_cell) def fill_notebook(work_notebook, script_blocks): """Writes the Jupyter notebook cells Parameters ---------- script_blocks : list of tuples """ for blabel, bcontent, lineno in script_blocks: if blabel == 'code': add_code_cell(work_notebook, bcontent) else: add_markdown_cell(work_notebook, bcontent + '\n') def save_notebook(work_notebook, write_file): """Saves the Jupyter work_notebook to write_file""" with open(write_file, 'w') as out_nb: json.dump(work_notebook, out_nb, indent=2) ############################################################################### # Notebook shell utility def python_to_jupyter_cli(args=None, namespace=None): """Exposes the jupyter notebook renderer to the command line Takes the same arguments as ArgumentParser.parse_args """ parser = argparse.ArgumentParser( description='Sphinx-Gallery Notebook converter') parser.add_argument('python_src_file', nargs='+', help='Input Python file script to convert. ' 'Supports multiple files and shell wildcards' ' (e.g. *.py)') args = parser.parse_args(args, namespace) for src_file in args.python_src_file: file_conf, blocks = split_code_and_text_blocks(src_file) print('Converting {0}'.format(src_file)) example_nb = jupyter_notebook(blocks) save_notebook(example_nb, replace_py_ipynb(src_file)) sphinx-gallery-0.2.0/sphinx_gallery/py_source_parser.py000066400000000000000000000140471330553134500234550ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" Parser for python source files ============================== """ # Created Sun Nov 27 14:03:07 2016 # Author: Óscar Nájera from __future__ import division, absolute_import, print_function import ast import re from textwrap import dedent SYNTAX_ERROR_DOCSTRING = """ SyntaxError =========== Example script with invalid Python syntax """ def parse_source_file(filename): """Parse source file into AST node Parameters ---------- filename : str File path Returns ------- node : AST node content : utf-8 encoded string """ # can't use codecs.open(filename, 'r', 'utf-8') here b/c ast doesn't # work with unicode strings in Python2.7 "SyntaxError: encoding # declaration in Unicode string" In python 2.7 the string can't be # encoded and have information about its encoding. That is particularly # problematic since source files include in their header information # about the file encoding. # Minimal example to fail: ast.parse(u'# -*- coding: utf-8 -*-') with open(filename, 'rb') as fid: content = fid.read() # change from Windows format to UNIX for uniformity content = content.replace(b'\r\n', b'\n') try: node = ast.parse(content) return node, content.decode('utf-8') except SyntaxError: return None, content.decode('utf-8') def get_docstring_and_rest(filename): """Separate ``filename`` content between docstring and the rest Strongly inspired from ast.get_docstring. Returns ------- docstring: str docstring of ``filename`` rest: str ``filename`` content without the docstring """ node, content = parse_source_file(filename) if node is None: return SYNTAX_ERROR_DOCSTRING, content, 1 if not isinstance(node, ast.Module): raise TypeError("This function only supports modules. " "You provided {0}".format(node.__class__.__name__)) try: # in python 3.7 module knows it's docstring # everything else will raise an attribute error docstring = node.docstring import tokenize from io import BytesIO ts = tokenize.tokenize(BytesIO(content).readline) ds_lines = 0 # find the first string according to the tokenizer and get # it's end row for tk in ts: if tk.exact_type == 3: ds_lines, _ = tk.end break # grab the rest of the file rest = '\n'.join(content.split('\n')[ds_lines:]) lineno = ds_lines + 1 except AttributeError: # this block can be removed when python 3.6 support is dropped if node.body and isinstance(node.body[0], ast.Expr) and \ isinstance(node.body[0].value, ast.Str): docstring_node = node.body[0] docstring = docstring_node.value.s # python2.7: Code was read in bytes needs decoding to utf-8 # unless future unicode_literals is imported in source which # make ast output unicode strings if hasattr(docstring, 'decode') and not isinstance(docstring, unicode): docstring = docstring.decode('utf-8') lineno = docstring_node.lineno # The last line of the string. # This get the content of the file after the docstring last line # Note: 'maxsplit' argument is not a keyword argument in python2 rest = content.split('\n', lineno)[-1] lineno += 1 else: docstring, rest = '', '' if not docstring: raise ValueError(('Could not find docstring in file "{0}". ' 'A docstring is required by sphinx-gallery ' 'unless the file is ignored by "ignore_pattern"') .format(filename)) return docstring, rest, lineno def extract_file_config(content): """ Pull out the file-specific config specified in the docstring. """ prop_pat = re.compile( r"^\s*#\s*sphinx_gallery_([A-Za-z0-9_]+)\s*=\s*(.+)\s*$", re.MULTILINE) file_conf = {} for match in re.finditer(prop_pat, content): name = match.group(1) value = match.group(2) try: value = ast.literal_eval(value) except (SyntaxError, ValueError): logger.warning( 'Sphinx-gallery option %s was passed invalid value %s', name, value) else: file_conf[name] = value return file_conf def split_code_and_text_blocks(source_file): """Return list with source file separated into code and text blocks. Returns ------- file_conf : dict File-specific settings given in comments as: ``# sphinx_gallery_ = `` blocks : list of (label, content) List where each element is a tuple with the label ('text' or 'code'), and content string of block. """ docstring, rest_of_content, lineno = get_docstring_and_rest(source_file) blocks = [('text', docstring, 1)] file_conf = extract_file_config(rest_of_content) pattern = re.compile( r'(?P^#{20,}.*)\s(?P(?:^#.*\s)*)', flags=re.M) sub_pat = re.compile('^#', flags=re.M) pos_so_far = 0 for match in re.finditer(pattern, rest_of_content): code_block_content = rest_of_content[pos_so_far:match.start()] if code_block_content.strip(): blocks.append(('code', code_block_content, lineno)) lineno += code_block_content.count('\n') lineno += 1 # Ignored header line of hashes. text_content = match.group('text_content') text_block_content = dedent(re.sub(sub_pat, '', text_content)).lstrip() if text_block_content.strip(): blocks.append(('text', text_block_content, lineno)) lineno += text_content.count('\n') pos_so_far = match.end() remaining_content = rest_of_content[pos_so_far:] if remaining_content.strip(): blocks.append(('code', remaining_content, lineno)) return file_conf, blocks sphinx-gallery-0.2.0/sphinx_gallery/sorting.py000066400000000000000000000064171330553134500215600ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" Sorters for Sphinx-Gallery (sub)sections ======================================== Sorting key functions for gallery subsection folders and section files. """ # Created: Sun May 21 20:38:59 2017 # Author: Óscar Nájera # License: 3-clause BSD from __future__ import division, absolute_import, print_function import os import types from .gen_rst import extract_intro_and_title from .py_source_parser import split_code_and_text_blocks class ExplicitOrder(object): """Sorting key for all gallery subsections. This requires all folders to be listed otherwise an exception is raised. Parameters ---------- ordered_list : list, tuple, types.GeneratorType Hold the paths of each galleries' subsections. Raises ------ ValueError Wrong input type or Subgallery path missing. """ def __init__(self, ordered_list): if not isinstance(ordered_list, (list, tuple, types.GeneratorType)): raise ValueError("ExplicitOrder sorting key takes a list, " "tuple or Generator, which hold" "the paths of each gallery subfolder") self.ordered_list = list(os.path.normpath(path) for path in ordered_list) def __call__(self, item): if item in self.ordered_list: return self.ordered_list.index(item) else: raise ValueError('If you use an explicit folder ordering, you ' 'must specify all folders. Explicit order not ' 'found for {}'.format(item)) class _SortKey(object): """Base class for section order key classes.""" def __init__(self, src_dir): self.src_dir = src_dir class NumberOfCodeLinesSortKey(_SortKey): """Sort examples in src_dir by the number of code lines. Parameters ---------- src_dir : str The source directory. """ def __call__(self, filename): src_file = os.path.normpath(os.path.join(self.src_dir, filename)) file_conf, script_blocks = split_code_and_text_blocks(src_file) amount_of_code = sum([len(bcontent) for blabel, bcontent, lineno in script_blocks if blabel == 'code']) return amount_of_code class FileSizeSortKey(_SortKey): """Sort examples in src_dir by file size. Parameters ---------- src_dir : str The source directory. """ def __call__(self, filename): src_file = os.path.normpath(os.path.join(self.src_dir, filename)) return os.stat(src_file).st_size class FileNameSortKey(_SortKey): """Sort examples in src_dir by file size. Parameters ---------- src_dir : str The source directory. """ def __call__(self, filename): return filename class ExampleTitleSortKey(_SortKey): """Sort examples in src_dir by example title. Parameters ---------- src_dir : str The source directory. """ def __call__(self, filename): src_file = os.path.normpath(os.path.join(self.src_dir, filename)) _, script_blocks = split_code_and_text_blocks(src_file) _, title = extract_intro_and_title(src_file, script_blocks[0][1]) return title sphinx-gallery-0.2.0/sphinx_gallery/sphinx_compatibility.py000066400000000000000000000044171330553134500243330ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Backwards-compatility shims for Sphinx ====================================== """ from __future__ import division, absolute_import, print_function from distutils.version import LooseVersion import sphinx import sphinx.util # This gets set when the extension is initialized. _app = None def _app_get_logger(name): class SphinxLoggerAdapter: def _color_to_func(self, kwargs, default=''): return getattr(sphinx.util.console, kwargs.pop('color', default), None) def error(self, msg, *args, **kwargs): msg = msg % args colorfunc = self._color_to_func(kwargs, default='red') return _app.warn(colorfunc(msg), **kwargs) def critical(self, msg, *args, **kwargs): msg = msg % args colorfunc = self._color_to_func(kwargs, default='red') return _app.warn(colorfunc(msg), **kwargs) def warning(self, msg, *args, **kwargs): msg = msg % args colorfunc = self._color_to_func(kwargs) if colorfunc: # colorfunc is a valid kwarg in 1.5, but not older, so we just # apply it ourselves. msg = colorfunc(msg) return _app.warn(msg, **kwargs) def info(self, msg='', *args, **kwargs): msg = msg % args colorfunc = self._color_to_func(kwargs) if colorfunc: msg = colorfunc(msg) return _app.info(msg, **kwargs) def verbose(self, msg, *args, **kwargs): return _app.verbose(msg, *args, **kwargs) def debug(self, msg, *args, **kwargs): return _app.debug(msg, *args, **kwargs) return SphinxLoggerAdapter() def _app_status_iterator(iterable, summary, **kwargs): global _app color = kwargs.pop('color', None) if color is not None: kwargs['colorfunc'] = getattr(sphinx.util.console, color) for item in _app.status_iterator(iterable, summary, **kwargs): yield item if LooseVersion(sphinx.__version__) >= '1.6': getLogger = sphinx.util.logging.getLogger status_iterator = sphinx.util.status_iterator else: getLogger = _app_get_logger status_iterator = _app_status_iterator sphinx-gallery-0.2.0/sphinx_gallery/tests/000077500000000000000000000000001330553134500206535ustar00rootroot00000000000000sphinx-gallery-0.2.0/sphinx_gallery/tests/__init__.py000066400000000000000000000000001330553134500227520ustar00rootroot00000000000000sphinx-gallery-0.2.0/sphinx_gallery/tests/conftest.py000066400000000000000000000050271330553134500230560ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Pytest fixtures """ from __future__ import division, absolute_import, print_function import collections import logging import pytest import sphinx_gallery.docs_resolv import sphinx_gallery.gen_gallery import sphinx_gallery.gen_rst from sphinx_gallery import sphinx_compatibility Params = collections.namedtuple('Params', 'args kwargs') class FakeSphinxApp: def __init__(self): self.calls = collections.defaultdict(list) def status_iterator(self, *args, **kwargs): self.calls['status_iterator'].append(Params(args, kwargs)) for it in args[0]: yield it def warning(self, *args, **kwargs): self.calls['warning'].append(Params(args, kwargs)) def warn(self, *args, **kwargs): self.calls['warn'].append(Params(args, kwargs)) def info(self, *args, **kwargs): self.calls['info'].append(Params(args, kwargs)) def verbose(self, *args, **kwargs): self.calls['verbose'].append(Params(args, kwargs)) def debug(self, *args, **kwargs): self.calls['debug'].append(Params(args, kwargs)) @pytest.fixture def fakesphinxapp(): orig_app = sphinx_gallery.sphinx_compatibility._app sphinx_gallery.sphinx_compatibility._app = app = FakeSphinxApp() try: yield app finally: sphinx_gallery.sphinx_compatibility._app = orig_app @pytest.fixture def log_collector(): orig_dr_logger = sphinx_gallery.docs_resolv.logger orig_gg_logger = sphinx_gallery.gen_gallery.logger orig_gr_logger = sphinx_gallery.gen_rst.logger app = FakeSphinxApp() sphinx_gallery.docs_resolv.logger = app sphinx_gallery.gen_gallery.logger = app sphinx_gallery.gen_rst.logger = app try: yield app finally: sphinx_gallery.docs_resolv.logger = orig_dr_logger sphinx_gallery.gen_gallery.logger = orig_gg_logger sphinx_gallery.gen_rst.logger = orig_gr_logger @pytest.fixture def unicode_sample(tmpdir): """Return temporary python source file with Unicode in various places""" code_str = b"""# -*- coding: utf-8 -*- ''' \xc3\x9anicode in header ================= U\xc3\xb1icode in description ''' # Code source: \xc3\x93scar N\xc3\xa1jera # License: BSD 3 clause import os path = os.path.join('a','b') a = 'hei\xc3\x9f' # Unicode string import sphinx_gallery.back_references as br br.identify_names from sphinx_gallery.back_references import identify_names identify_names """ fname = tmpdir.join("unicode_sample.py") fname.write(code_str, 'wb') return fname.strpath sphinx-gallery-0.2.0/sphinx_gallery/tests/reference_parse.txt000066400000000000000000000045001330553134500245430ustar00rootroot00000000000000[('text', '\nThe Header Docstring\n====================\n\nWhen writting latex in a Python string keep in mind to escape the backslashes\nor use a raw docstring\n\n.. math:: \\sin (x)\n\nClosing this string quotes on same line', 1), ('text', 'Direct first comment\nwith second line\n', 15), ('code', '\nimport numpy as np\n\n', 17), ('code', 'A = 1\n\nimport matplotlib.pyplot as plt\n\n', 21), ('text', 'There is no need to always alternate between code and comment blocks\nNow there is free repetition of both\n', 26), ('text', 'And a single line of hashes can split your blocks\n', 30), ('text', 'Latex in the comments does not need to be escaped\n\n.. math::\n \\sin\n', 34), ('code', '\ndef dummy():\n """This should not be part of a \'text\' block\'"""\n\n ######################################\n # Comment inside code to remain here\n pass\n\n# this should not be part of a \'text\' block\n\n', 38), ('text', '####################################################################\n\nMaking a line cut in sphinx\n', 49), ('text', '.. warning::\n The next kind of comments are not supported and become to hard to escape\n so just don\'t code like this.\n\n.. code-block:: python\n\n def dummy2():\n """Function docstring"""\n ####################################\n # This comment inside python indentation\n # breaks the block structure and is not\n # supported\n dummy2\n\n', 55), ('code', '\n"""Free strings are not supported they remain part of the code"""\n\n', 69), ('text', 'New lines can be included in you block comments and the parser\nis capable of retaining this significant whitespace to work with sphinx\n\nSo the reStructuredText headers survive\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', 73), ('code', "\n\nprint('one')\n\n", 78), ('text', 'Code block separators\n##############################################################################\n Surrounding a comment line with lines of # like a block spliter also\n works and creates a new header for that comment block\n too. Nevertheless to get rich text formatting we advise to use\n RestructuredText syntax in the comment blocks.\n', 83), ('code', "\nprint('two')\n", 89), ('code', 'B = 1\n\n', 93), ('text', "End comments\n\nThat's all folks !\n\n.. literalinclude:: plot_parse.py\n\n\n", 96)] sphinx-gallery-0.2.0/sphinx_gallery/tests/test_backreferences.py000066400000000000000000000045211330553134500252300ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Óscar Nájera # License: 3-clause BSD """ Testing the rst files generator """ from __future__ import division, absolute_import, print_function import sphinx_gallery.backreferences as sg def test_thumbnail_div(): """Test if the thumbnail div generates the correct string""" html_div = sg._thumbnail_div('fake_dir', 'test_file.py', '<"test">') reference = r""" .. raw:: html
.. only:: html .. figure:: /fake_dir/images/thumb/sphx_glr_test_file_thumb.png :ref:`sphx_glr_fake_dir_test_file.py` .. raw:: html
""" assert html_div == reference def test_backref_thumbnail_div(): """Test if the thumbnail div generates the correct string""" html_div = sg._thumbnail_div('fake_dir', 'test_file.py', 'test formating', is_backref=True) reference = """ .. raw:: html
.. only:: html .. figure:: /fake_dir/images/thumb/sphx_glr_test_file_thumb.png :ref:`sphx_glr_fake_dir_test_file.py` .. raw:: html
.. only:: not html * :ref:`sphx_glr_fake_dir_test_file.py` """ assert html_div == reference def test_identify_names(unicode_sample): expected = { 'os.path.join': {'name': 'join', 'module': 'os.path', 'module_short': 'os.path'}, 'br.identify_names': {'name': 'identify_names', 'module': 'sphinx_gallery.back_references', 'module_short': 'sphinx_gallery.back_references'}, 'identify_names': {'name': 'identify_names', 'module': 'sphinx_gallery.back_references', 'module_short': 'sphinx_gallery.back_references'} } res = sg.identify_names(unicode_sample) assert expected == res def test_identify_names2(tmpdir): code_str = b""" # -*- coding: utf-8 -*- # \xc3\x9f from a.b import c import d as e print(c) e.HelloWorld().f.g """ expected = {'c': {'name': 'c', 'module': 'a.b', 'module_short': 'a.b'}, 'e.HelloWorld': {'name': 'HelloWorld', 'module': 'd', 'module_short': 'd'}} fname = tmpdir.join("indentify_names.py") fname.write(code_str, 'wb') res = sg.identify_names(fname.strpath) assert expected == res sphinx-gallery-0.2.0/sphinx_gallery/tests/test_binder.py000066400000000000000000000072151330553134500235340ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Chris Holdgraf # License: 3-clause BSD """ Testing the binder badge functionality """ from __future__ import division, absolute_import, print_function import os import tempfile import sys from copy import deepcopy import pytest from sphinx_gallery.binder import gen_binder_url, check_binder_conf def test_binder(): """Testing binder URL generation and checks.""" file_path = 'blahblah/mydir/myfile.py' conf_base = {'url': 'http://test1.com', 'org': 'org', 'repo': 'repo', 'branch': 'branch', 'dependencies': '../requirements.txt'} conf_base = check_binder_conf(conf_base) gallery_conf_base = {'gallery_dirs': ['mydir'], 'src_dir': 'blahblah'} url = gen_binder_url(file_path, conf_base, gallery_conf_base) expected = ('http://test1.com/v2/gh/org/repo/' 'branch?filepath=notebooks/mydir/myfile.ipynb') assert url == expected # Assert filepath prefix is added prefix = 'my_prefix/foo' conf1 = deepcopy(conf_base) conf1['filepath_prefix'] = prefix url = gen_binder_url(file_path, conf1, gallery_conf_base) expected = ('http://test1.com/v2/gh/org/repo/' 'branch?filepath={}/notebooks/' 'mydir/myfile.ipynb').format(prefix) assert url == expected conf1.pop('filepath_prefix') # URL must have http with pytest.raises(ValueError) as excinfo: conf2 = deepcopy(conf1) conf2['url'] = 'test1.com' url = check_binder_conf(conf2) excinfo.match(r'did not supply a valid url') # Assert missing params for key in conf1.keys(): if key == 'notebooks_dir': continue conf3 = deepcopy(conf1) conf3.pop(key) with pytest.raises(ValueError) as excinfo: url = check_binder_conf(conf3) excinfo.match(r"binder_conf is missing values for") # Dependencies file dependency_file_tests = ['requirements_not.txt', 'doc-requirements.txt'] for ifile in dependency_file_tests: with pytest.raises(ValueError) as excinfo: conf3 = deepcopy(conf1) conf3['dependencies'] = ifile url = check_binder_conf(conf3) excinfo.match(r"Did not find one of `requirements.txt` " "or `environment.yml`") with pytest.raises(ValueError) as excinfo: conf6 = deepcopy(conf1) conf6['dependencies'] = {'test': 'test'} url = check_binder_conf(conf6) excinfo.match(r"`dependencies` value should be a list of strings") # Check returns the correct object conf4 = check_binder_conf({}) conf5 = check_binder_conf(None) for iconf in [conf4, conf5]: assert iconf == {} # Assert extra unkonwn params with pytest.raises(ValueError) as excinfo: conf7 = deepcopy(conf1) conf7['foo'] = 'blah' url = check_binder_conf(conf7) excinfo.match(r"Unknown Binder config key") # Assert using lab correctly changes URL conf_lab = deepcopy(conf_base) conf_lab['use_jupyter_lab'] = True url = gen_binder_url(file_path, conf_lab, gallery_conf_base) expected = ('http://test1.com/v2/gh/org/repo/' 'branch?urlpath=lab/tree/notebooks/mydir/myfile.ipynb') assert url == expected # Assert using static folder correctly changes URL conf_static = deepcopy(conf_base) file_path = 'blahblah/mydir/myfolder/myfile.py' conf_static['notebooks_dir'] = 'ntbk_folder' url = gen_binder_url(file_path, conf_static, gallery_conf_base) expected = ('http://test1.com/v2/gh/org/repo/' 'branch?filepath=ntbk_folder/mydir/myfolder/myfile.ipynb') assert url == expected sphinx-gallery-0.2.0/sphinx_gallery/tests/test_docs_resolv.py000066400000000000000000000054271330553134500246160ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Óscar Nájera # License: 3-clause BSD """ Testing the rst files generator """ from __future__ import division, absolute_import, print_function import os import tempfile import sys import pytest import sphinx_gallery.docs_resolv as sg from sphinx_gallery.utils import _TempDir def test_embed_code_links_get_data(): """Test that we can get data for code links.""" sg._get_data('http://docs.scipy.org/doc/scipy/reference') sg._get_data('http://scikit-learn.org/stable/') # GZip def test_shelve(): """Test if shelve can be caches information retrieved after file is deleted""" test_string = 'test information' tmp_cache = _TempDir() with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write(test_string) try: # recovers data from temporary file and caches it in the shelve file_data = sg.get_data(f.name, tmp_cache) finally: os.remove(f.name) # tests recovered data matches assert file_data == test_string # test if cached data is available after temporary file has vanished assert sg.get_data(f.name, tmp_cache) == test_string # shelve keys need to be str in python 2, deal with unicode input if sys.version_info[0] == 2: unicode_name = unicode(f.name) assert sg.get_data(unicode_name, tmp_cache) == test_string def test_parse_sphinx_docopts(): data = ''' ''' assert sg.parse_sphinx_docopts(data) == { 'URL_ROOT': './', 'VERSION': '2.0.2', 'COLLAPSE_INDEX': False, 'FILE_SUFFIX': '.html', 'HAS_SOURCE': True, 'SOURCELINK_SUFFIX': '.txt' } data_sphinx_175 = ''' ''' assert sg.parse_sphinx_docopts(data_sphinx_175) == { 'VERSION': '2.0.2', 'COLLAPSE_INDEX': False, 'FILE_SUFFIX': '.html', 'HAS_SOURCE': True, 'SOURCELINK_SUFFIX': '.txt' } with pytest.raises(ValueError): sg.parse_sphinx_docopts('empty input') with pytest.raises(ValueError): sg.parse_sphinx_docopts('DOCUMENTATION_OPTIONS = ') with pytest.raises(ValueError): sg.parse_sphinx_docopts('DOCUMENTATION_OPTIONS = {') sphinx-gallery-0.2.0/sphinx_gallery/tests/test_full.py000066400000000000000000000037761330553134500232430ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Óscar Nájera # License: 3-clause BSD """ Test the SG pipeline used with Sphinx """ from __future__ import division, absolute_import, print_function import codecs import os import os.path as op import shutil from sphinx.application import Sphinx import pytest @pytest.fixture(scope='module') def sphinx_app(tmpdir_factory): temp_dir = (tmpdir_factory.getbasetemp() / 'root').strpath src_dir = op.join(op.dirname(__file__), 'tinybuild') def ignore(src, names): return ('_build', 'gen_modules', 'auto_examples') shutil.copytree(src_dir, temp_dir, ignore=ignore) # For testing iteration, you can get similar behavior just doing `make` # inside the tinybuild directory src_dir = temp_dir conf_dir = temp_dir out_dir = op.join(temp_dir, '_build', 'html') toctrees_dir = op.join(temp_dir, '_build', 'toctrees') app = Sphinx(src_dir, conf_dir, out_dir, toctrees_dir, buildername='html') app.build(False, []) return app def test_run_sphinx(sphinx_app): out_dir = sphinx_app.outdir out_files = os.listdir(out_dir) assert 'index.html' in out_files assert 'auto_examples' in out_files generated_examples_dir = op.join(out_dir, 'auto_examples') assert op.isdir(generated_examples_dir) def test_embed_links(sphinx_app): """Test that links are embedded properly in doc.""" out_dir = sphinx_app.outdir examples_dir = op.join(out_dir, 'auto_examples') assert op.isdir(examples_dir) example_files = os.listdir(examples_dir) assert 'plot_numpy_scipy.html' in example_files example_file = op.join(examples_dir, 'plot_numpy_scipy.html') with codecs.open(example_file, 'r', 'utf-8') as fid: lines = fid.read() # ensure we've linked properly assert '#module-scipy.signal' in lines assert 'scipy.signal.firwin.html' in lines assert '#module-numpy' in lines assert 'numpy.arange.html' in lines # assert '#module-matplotlib.pyplot' in lines # assert 'pyplot.html' in lines sphinx-gallery-0.2.0/sphinx_gallery/tests/test_gen_gallery.py000066400000000000000000000300011330553134500245460ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Óscar Nájera # License: 3-clause BSD r""" Test Sphinx-Gallery """ from __future__ import (division, absolute_import, print_function, unicode_literals) import codecs import os import sys import re import shutil import pytest from sphinx.application import Sphinx from sphinx.errors import ExtensionError from sphinx.util.docutils import docutils_namespace from sphinx_gallery.gen_rst import MixedEncodingStringIO from sphinx_gallery import sphinx_compatibility from sphinx_gallery.gen_gallery import (check_duplicate_filenames, collect_gallery_files) from sphinx_gallery.utils import _TempDir @pytest.fixture def conf_file(request): env = request.node.get_marker('conf_file') kwargs = env.kwargs if env else {} result = { 'content': "", } result.update(kwargs) return result @pytest.fixture def tempdir(): """ temporary directory that wrapped with `path` class. this fixture is for compat with old test implementation. """ return _TempDir() class SphinxAppWrapper(object): """Wrapper for sphinx.application.Application. This allows to control when the sphinx application is initialized, since part of the sphinx-gallery build is done in sphinx.application.Application.__init__ and the remainder is done in sphinx.application.Application.build. """ def __init__(self, srcdir, confdir, outdir, doctreedir, buildername, **kwargs): self.srcdir = srcdir self.confdir = confdir self.outdir = outdir self.doctreedir = doctreedir self.buildername = buildername self.kwargs = kwargs def create_sphinx_app(self): # Avoid warnings about re-registration, see: # https://github.com/sphinx-doc/sphinx/issues/5038 with docutils_namespace(): app = Sphinx(self.srcdir, self.confdir, self.outdir, self.doctreedir, self.buildername, **self.kwargs) sphinx_compatibility._app = app return app def build_sphinx_app(self, *args, **kwargs): app = self.create_sphinx_app() app.build(*args, **kwargs) return app @pytest.fixture def sphinx_app_wrapper(tempdir, conf_file): _fixturedir = os.path.join(os.path.dirname(__file__), 'testconfs') srcdir = os.path.join(tempdir, "config_test") shutil.copytree(_fixturedir, srcdir) shutil.copytree(os.path.join(_fixturedir, "src"), os.path.join(tempdir, "examples")) base_config = """ import os import sphinx_gallery extensions = ['sphinx_gallery.gen_gallery'] exclude_patterns = ['_build'] source_suffix = '.rst' master_doc = 'index' # General information about the project. project = u'Sphinx-Gallery '\n\n """ with open(os.path.join(srcdir, "conf.py"), "w") as conffile: conffile.write(base_config + conf_file['content']) return SphinxAppWrapper( srcdir, srcdir, os.path.join(srcdir, "_build"), os.path.join(srcdir, "_build", "toctree"), "html", warning=MixedEncodingStringIO()) def test_default_config(sphinx_app_wrapper): """Test the default Sphinx-Gallery configuration is loaded if only the extension is added to Sphinx""" sphinx_app = sphinx_app_wrapper.create_sphinx_app() cfg = sphinx_app.config assert cfg.project == "Sphinx-Gallery " # no duplicate values allowed The config is present already with pytest.raises(ExtensionError) as excinfo: sphinx_app.add_config_value('sphinx_gallery_conf', 'x', True) assert 'already present' in str(excinfo.value) @pytest.mark.conf_file(content=""" sphinx_gallery_conf = { 'examples_dirs': 'src', 'gallery_dirs': 'ex', }""") def test_no_warning_simple_config(sphinx_app_wrapper): """Testing that no warning is issued with a simple config. The simple config only specifies input (examples_dirs) and output (gallery_dirs) directories. """ sphinx_app = sphinx_app_wrapper.create_sphinx_app() cfg = sphinx_app.config assert cfg.project == "Sphinx-Gallery " build_warn = sphinx_app._warning.getvalue() assert build_warn == '' @pytest.mark.conf_file(content=""" sphinx_gallery_conf = { 'mod_example_dir' : os.path.join('modules', 'gen'), 'examples_dirs': 'src', 'gallery_dirs': 'ex', }""") def test_config_old_backreferences_conf(sphinx_app_wrapper): """Testing Deprecation warning message against old backreference config In this case the user is required to update the mod_example_dir config variable Sphinx-Gallery should notify the user and also silently update the old config to the new one. """ sphinx_app = sphinx_app_wrapper.create_sphinx_app() cfg = sphinx_app.config assert cfg.project == "Sphinx-Gallery " assert cfg.sphinx_gallery_conf['backreferences_dir'] == os.path.join( 'modules', 'gen') build_warn = sphinx_app._warning.getvalue() assert "WARNING:" in build_warn assert "deprecated" in build_warn assert "Support for 'mod_example_dir' will be removed" in build_warn @pytest.mark.conf_file(content=""" sphinx_gallery_conf = { 'backreferences_dir': os.path.join('gen_modules', 'backreferences'), 'examples_dirs': 'src', 'gallery_dirs': 'ex', }""") def test_config_backreferences(sphinx_app_wrapper): """Test no warning is issued under the new configuration""" sphinx_app = sphinx_app_wrapper.create_sphinx_app() cfg = sphinx_app.config assert cfg.project == "Sphinx-Gallery " assert cfg.sphinx_gallery_conf['backreferences_dir'] == os.path.join( 'gen_modules', 'backreferences') build_warn = sphinx_app._warning.getvalue() assert build_warn == '' def test_duplicate_files_warn(sphinx_app_wrapper): """Test for a warning when two files with the same filename exist.""" sphinx_app = sphinx_app_wrapper.create_sphinx_app() files = ['./a/file1.py', './a/file2.py', 'a/file3.py', './b/file1.py'] msg = ("Duplicate file name(s) found. Having duplicate file names " "will break some links. List of files: {}") m = "['./b/file1.py']" if sys.version_info[0] >= 3 else "[u'./b/file1.py']" # No warning because no overlapping names check_duplicate_filenames(files[:-1]) build_warn = sphinx_app._warning.getvalue() assert build_warn == '' # Warning because last file is named the same check_duplicate_filenames(files) build_warn = sphinx_app._warning.getvalue() assert msg.format(m) in build_warn def _check_order(sphinx_app, key): index_fname = os.path.join(sphinx_app.outdir, '..', 'ex', 'index.rst') order = list() regex = '.*:%s=(.):.*' % key with codecs.open(index_fname, 'r', 'utf-8') as fid: for line in fid: if 'sphx-glr-thumbcontainer' in line: order.append(int(re.match(regex, line).group(1))) assert len(order) == 3 assert order == [1, 2, 3] @pytest.mark.conf_file(content=""" sphinx_gallery_conf = { 'examples_dirs': 'src', 'gallery_dirs': 'ex', }""") def test_example_sorting_default(sphinx_app_wrapper): """Test sorting of examples by default key (number of code lines).""" sphinx_app = sphinx_app_wrapper.create_sphinx_app() _check_order(sphinx_app, 'lines') @pytest.mark.conf_file(content=""" from sphinx_gallery.sorting import FileSizeSortKey sphinx_gallery_conf = { 'examples_dirs': 'src', 'gallery_dirs': 'ex', 'within_subsection_order': FileSizeSortKey, }""") def test_example_sorting_filesize(sphinx_app_wrapper): """Test sorting of examples by filesize.""" sphinx_app = sphinx_app_wrapper.create_sphinx_app() _check_order(sphinx_app, 'filesize') @pytest.mark.conf_file(content=""" from sphinx_gallery.sorting import FileNameSortKey sphinx_gallery_conf = { 'examples_dirs': 'src', 'gallery_dirs': 'ex', 'within_subsection_order': FileNameSortKey, }""") def test_example_sorting_filename(sphinx_app_wrapper): """Test sorting of examples by filename.""" sphinx_app = sphinx_app_wrapper.create_sphinx_app() _check_order(sphinx_app, 'filename') @pytest.mark.conf_file(content=""" from sphinx_gallery.sorting import ExampleTitleSortKey sphinx_gallery_conf = { 'examples_dirs': 'src', 'gallery_dirs': 'ex', 'within_subsection_order': ExampleTitleSortKey, }""") def test_example_sorting_title(sphinx_app_wrapper): """Test sorting of examples by title.""" sphinx_app = sphinx_app_wrapper.create_sphinx_app() _check_order(sphinx_app, 'title') def test_collect_gallery_files(sphinx_app_wrapper, tmpdir): """Test that example files are collected properly.""" rel_filepaths = ['examples/file1.py', 'examples/test.rst', 'examples/README.txt', 'examples/folder1/file1.py', 'examples/folder1/file2.py', 'examples/folder2/file1.py', 'tutorials/folder1/subfolder/file1.py', 'tutorials/folder2/subfolder/subsubfolder/file1.py'] abs_paths = [tmpdir.join(rp) for rp in rel_filepaths] for ap in abs_paths: ap.ensure() examples_path = tmpdir.join('examples') dirs = [examples_path.strpath] collected_files = set(collect_gallery_files(dirs)) expected_files = set( [ap.strpath for ap in abs_paths if re.search(r'examples.*\.py$', ap.strpath)]) assert collected_files == expected_files tutorials_path = tmpdir.join('tutorials') dirs = [examples_path.strpath, tutorials_path.strpath] collected_files = set(collect_gallery_files(dirs)) expected_files = set( [ap.strpath for ap in abs_paths if re.search(r'.*\.py$', ap.strpath)]) assert collected_files == expected_files @pytest.mark.conf_file(content=""" sphinx_gallery_conf = { 'backreferences_dir' : os.path.join('modules', 'gen'), 'examples_dirs': 'src', 'gallery_dirs': ['ex'], 'binder': {'url': 'http://test1.com', 'org': 'org', 'repo': 'repo', 'branch': 'branch', 'notebooks_dir': 'ntbk_folder', 'dependencies': 'requirements.txt'} }""") def test_binder_copy_files(sphinx_app_wrapper, tmpdir): """Test that notebooks are copied properly.""" from sphinx_gallery.binder import copy_binder_files sphinx_app = sphinx_app_wrapper.create_sphinx_app() gallery_conf = sphinx_app.config.sphinx_gallery_conf # Create requirements file with open(os.path.join(sphinx_app.srcdir, 'requirements.txt'), 'w'): pass copy_binder_files(sphinx_app, None) for i_file in ['plot_1', 'plot_2', 'plot_3']: assert os.path.exists(os.path.join( sphinx_app.outdir, 'ntbk_folder', gallery_conf['gallery_dirs'][0], i_file+'.ipynb')) @pytest.mark.conf_file(content=""" sphinx_gallery_conf = { 'examples_dirs': 'src', 'gallery_dirs': 'ex', }""") def test_failing_examples_raise_exception(sphinx_app_wrapper): example_dir = os.path.join(sphinx_app_wrapper.srcdir, 'src') with codecs.open(os.path.join(example_dir, 'plot_3.py'), 'a', encoding='utf-8') as fid: fid.write('raise SyntaxError') with pytest.raises(ValueError) as excinfo: sphinx_app_wrapper.build_sphinx_app() assert "Unexpected failing examples" in str(excinfo.value) @pytest.mark.conf_file(content=""" sphinx_gallery_conf = { 'examples_dirs': 'src', 'gallery_dirs': 'ex', 'filename_pattern': 'plot_1.py', }""") def test_expected_failing_examples_were_executed(sphinx_app_wrapper): """Testing that no exception is issued when broken example is not built See #335 for more details. """ sphinx_app_wrapper.build_sphinx_app() @pytest.mark.conf_file(content=""" sphinx_gallery_conf = { 'examples_dirs': 'src', 'gallery_dirs': 'ex', 'expected_failing_examples' :['src/plot_2.py'], }""") def test_examples_not_expected_to_pass(sphinx_app_wrapper): with pytest.raises(ValueError) as excinfo: sphinx_app_wrapper.build_sphinx_app() assert "expected to fail, but not failing" in str(excinfo.value) sphinx-gallery-0.2.0/sphinx_gallery/tests/test_gen_rst.py000066400000000000000000000351271330553134500237350ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Óscar Nájera # License: 3-clause BSD """ Testing the rst files generator """ from __future__ import (division, absolute_import, print_function, unicode_literals) import ast import codecs import copy import io import tempfile import re import os import shutil import zipfile import pytest import sphinx_gallery.gen_rst as sg from sphinx_gallery import gen_gallery, downloads from sphinx_gallery.gen_gallery import generate_dir_rst from sphinx_gallery.utils import _TempDir # Need to import gen_rst before matplotlib.pyplot to set backend to 'Agg' import matplotlib.pyplot as plt CONTENT = [ '"""', '================', 'Docstring header', '================', '', 'This is the description of the example', 'which goes on and on, Óscar', '', '', 'And this is a second paragraph', '"""', '', '# and now comes the module code', 'import logging', 'import sys', 'x, y = 1, 2', 'print(u"Óscar output") # need some code output', 'logger = logging.getLogger()', 'logger.setLevel(logging.INFO)', 'lh = logging.StreamHandler(sys.stdout)', 'lh.setFormatter(logging.Formatter("log:%(message)s"))', 'logger.addHandler(lh)', 'logger.info(u"Óscar")', 'print(r"$\\langle n_\\uparrow n_\\downarrow \\rangle$")', ] def test_split_code_and_text_blocks(): """Test if a known example file gets properly split""" file_conf, blocks = sg.split_code_and_text_blocks( 'examples/no_output/just_code.py') assert file_conf == {} assert blocks[0][0] == 'text' assert blocks[1][0] == 'code' def test_bug_cases_of_notebook_syntax(): """Test over the known requirements of supported syntax in the notebook styled comments""" with open('sphinx_gallery/tests/reference_parse.txt') as reference: ref_blocks = ast.literal_eval(reference.read()) file_conf, blocks = sg.split_code_and_text_blocks( 'tutorials/plot_parse.py') assert file_conf == {} assert blocks == ref_blocks def test_direct_comment_after_docstring(): # For more details see # https://github.com/sphinx-gallery/sphinx-gallery/pull/49 with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write('\n'.join(['"Docstring"', '# and now comes the module code', '# with a second line of comment', 'x, y = 1, 2', ''])) try: file_conf, result = sg.split_code_and_text_blocks(f.name) finally: os.remove(f.name) assert file_conf == {} expected_result = [ ('text', 'Docstring', 1), ('code', '\n'.join(['# and now comes the module code', '# with a second line of comment', 'x, y = 1, 2', '']), 2)] assert result == expected_result def test_codestr2rst(): """Test the correct translation of a code block into rst""" output = sg.codestr2rst('print("hello world")') reference = """ .. code-block:: python print("hello world")""" assert reference == output def test_extract_intro_and_title(): intro, title = sg.extract_intro_and_title('', '\n'.join(CONTENT[1:10])) assert title == 'Docstring header' assert 'Docstring' not in intro assert intro == 'This is the description of the example which goes on and on, Óscar' # noqa assert 'second paragraph' not in intro # SG incorrectly grabbing description when a label is defined (gh-232) intro_label, title_label = sg.extract_intro_and_title( '', '\n'.join(['.. my_label', ''] + CONTENT[1:10])) assert intro_label == intro assert title_label == title intro_whitespace, title_whitespace = sg.extract_intro_and_title( '', '\n'.join(CONTENT[1:4] + [''] + CONTENT[5:10])) assert intro_whitespace == intro assert title_whitespace == title # Make example title optional (gh-222) intro, title = sg.extract_intro_and_title('', 'Title\n-----') assert intro == title == 'Title' # Title beginning with a space (gh-356) intro, title = sg.extract_intro_and_title('filename', '^^^^^\n Title two \n^^^^^') assert intro == title == 'Title two' # Long intro paragraph gets shortened intro_paragraph = '\n'.join(['this is one line' for _ in range(10)]) intro, _ = sg.extract_intro_and_title( 'filename', 'Title\n-----\n\n' + intro_paragraph) assert len(intro_paragraph) > 100 assert len(intro) < 100 assert intro.endswith('...') assert intro_paragraph.replace('\n', ' ')[:95] == intro[:95] # Errors with pytest.raises(ValueError, match='should have a header'): sg.extract_intro_and_title('', '') # no title with pytest.raises(ValueError, match='Could not find a title'): sg.extract_intro_and_title('', '-') # no real title def test_md5sums(): """Test md5sum check functions work on know file content""" with tempfile.NamedTemporaryFile('wb', delete=False) as f: f.write(b'Local test\n') try: file_md5 = sg.get_md5sum(f.name) # verify correct md5sum assert 'ea8a570e9f3afc0a7c3f2a17a48b8047' == file_md5 # False because is a new file assert not sg.md5sum_is_current(f.name) # Write md5sum to file to check is current with open(f.name + '.md5', 'w') as file_checksum: file_checksum.write(file_md5) try: assert sg.md5sum_is_current(f.name) finally: os.remove(f.name + '.md5') finally: os.remove(f.name) @pytest.fixture def gallery_conf(): """Sets up a test sphinx-gallery configuration""" gallery_conf = copy.deepcopy(gen_gallery.DEFAULT_GALLERY_CONF) gallery_conf.update(examples_dir=_TempDir(), gallery_dir=_TempDir()) gallery_conf['src_dir'] = gallery_conf['gallery_dir'] return gallery_conf def test_fail_example(gallery_conf, log_collector): """Test that failing examples are only executed until failing block""" gallery_conf.update(filename_pattern='raise.py') failing_code = CONTENT + ['#' * 79, 'First_test_fail', '#' * 79, 'second_fail'] with codecs.open(os.path.join(gallery_conf['examples_dir'], 'raise.py'), mode='w', encoding='utf-8') as f: f.write('\n'.join(failing_code)) sg.generate_file_rst('raise.py', gallery_conf['gallery_dir'], gallery_conf['examples_dir'], gallery_conf) assert len(log_collector.calls['warning']) == 1 assert 'not defined' in log_collector.calls['warning'][0].args[2] # read rst file and check if it contains traceback output with codecs.open(os.path.join(gallery_conf['gallery_dir'], 'raise.rst'), mode='r', encoding='utf-8') as f: ex_failing_blocks = f.read().count('pytb') if ex_failing_blocks == 0: raise ValueError('Did not run into errors in bad code') elif ex_failing_blocks > 1: raise ValueError('Did not stop executing script after error') def test_gen_dir_rst(gallery_conf, fakesphinxapp): """Test gen_dir_rst.""" print(os.listdir(gallery_conf['examples_dir'])) fname_readme = os.path.join(gallery_conf['src_dir'], 'README.txt') with open(fname_readme, 'wb') as fid: fid.write(u"Testing\n=======\n\nÓscar here.".encode('utf-8')) args = (gallery_conf['src_dir'], gallery_conf['gallery_dir'], gallery_conf, []) out = generate_dir_rst(*args) assert u"Óscar here" in out[0] def test_pattern_matching(gallery_conf, log_collector): """Test if only examples matching pattern are executed""" gallery_conf.update(filename_pattern=re.escape(os.sep) + 'plot_0') code_output = ('\n Out:\n\n .. code-block:: none\n' '\n' ' Óscar output\n' ' log:Óscar\n' ' $\\langle n_\\uparrow n_\\downarrow \\rangle$\n\n' ) # create three files in tempdir (only one matches the pattern) fnames = ['plot_0.py', 'plot_1.py', 'plot_2.py'] for fname in fnames: with codecs.open(os.path.join(gallery_conf['examples_dir'], fname), mode='w', encoding='utf-8') as f: f.write('\n'.join(CONTENT)) # generate rst file sg.generate_file_rst(fname, gallery_conf['gallery_dir'], gallery_conf['examples_dir'], gallery_conf) # read rst file and check if it contains code output rst_fname = os.path.splitext(fname)[0] + '.rst' with codecs.open(os.path.join(gallery_conf['gallery_dir'], rst_fname), mode='r', encoding='utf-8') as f: rst = f.read() if re.search(gallery_conf['filename_pattern'], os.path.join(gallery_conf['gallery_dir'], rst_fname)): assert code_output in rst else: assert code_output not in rst @pytest.mark.parametrize('test_str', [ '# sphinx_gallery_thumbnail_number= 2', '# sphinx_gallery_thumbnail_number=2', '#sphinx_gallery_thumbnail_number = 2', ' # sphinx_gallery_thumbnail_number=2']) def test_thumbnail_number(test_str): # which plot to show as the thumbnail image with tempfile.NamedTemporaryFile('w', delete=False) as f: f.write('\n'.join(['"Docstring"', test_str])) try: file_conf, blocks = sg.split_code_and_text_blocks(f.name) finally: os.remove(f.name) assert file_conf == {'thumbnail_number': 2} def test_save_figures(gallery_conf): """Test file naming when saving figures. Requires mayavi.""" try: from mayavi import mlab except ImportError: raise pytest.skip('Mayavi not installed') mlab.options.offscreen = True gallery_conf.update(find_mayavi_figures=True) mlab.test_plot3d() plt.plot(1, 1) fname_template = os.path.join(gallery_conf['gallery_dir'], 'image{0}.png') image_rst, fig_num = sg.save_figures(fname_template, 0, gallery_conf) assert fig_num == 2 assert '/image1.png' in image_rst assert '/image2.png' in image_rst mlab.test_plot3d() plt.plot(1, 1) image_rst, fig_num = sg.save_figures(fname_template, 2, gallery_conf) assert fig_num == 2 assert '/image2.png' not in image_rst assert '/image3.png' in image_rst assert '/image4.png' in image_rst shutil.rmtree(gallery_conf['gallery_dir']) def test_zip_notebooks(gallery_conf): """Test generated zipfiles are not corrupt""" gallery_conf.update(examples_dir='examples') examples = downloads.list_downloadable_sources( gallery_conf['examples_dir']) zipfilepath = downloads.python_zip(examples, gallery_conf['gallery_dir']) zipf = zipfile.ZipFile(zipfilepath) check = zipf.testzip() if check: raise OSError("Bad file in zipfile: {0}".format(check)) def test_figure_rst(): """Testing rst of images""" figure_list = ['sphx_glr_plot_1.png'] image_rst, fig_num = sg.figure_rst(figure_list, '.') single_image = """ .. image:: /sphx_glr_plot_1.png :class: sphx-glr-single-img """ assert image_rst == single_image assert fig_num == 1 image_rst, fig_num = sg.figure_rst(figure_list + ['second.png'], '.') image_list_rst = """ .. rst-class:: sphx-glr-horizontal * .. image:: /sphx_glr_plot_1.png :class: sphx-glr-multi-img * .. image:: /second.png :class: sphx-glr-multi-img """ assert image_rst == image_list_rst assert fig_num == 2 # test issue #229 local_img = [os.path.join(os.getcwd(), 'third.png')] image_rst, fig_num = sg.figure_rst(local_img, '.') single_image = sg.SINGLE_IMAGE % "third.png" assert image_rst == single_image assert fig_num == 1 class TestLoggingTee: def setup(self): self.output_file = io.StringIO() self.src_filename = 'source file name' self.tee = sg.LoggingTee(self.output_file, sg.logger, self.src_filename) def test_full_line(self, log_collector): # A full line is output immediately. self.tee.write('Output\n') self.tee.flush() assert self.output_file.getvalue() == 'Output\n' assert len(log_collector.calls['verbose']) == 2 assert self.src_filename in log_collector.calls['verbose'][0].args assert 'Output' in log_collector.calls['verbose'][1].args def test_incomplete_line_with_flush(self, log_collector): # An incomplete line ... self.tee.write('Output') assert self.output_file.getvalue() == 'Output' assert len(log_collector.calls['verbose']) == 1 assert self.src_filename in log_collector.calls['verbose'][0].args # ... should appear when flushed. self.tee.flush() assert len(log_collector.calls['verbose']) == 2 assert 'Output' in log_collector.calls['verbose'][1].args def test_incomplete_line_with_more_output(self, log_collector): # An incomplete line ... self.tee.write('Output') assert self.output_file.getvalue() == 'Output' assert len(log_collector.calls['verbose']) == 1 assert self.src_filename in log_collector.calls['verbose'][0].args # ... should appear when more data is written. self.tee.write('\nMore output\n') assert self.output_file.getvalue() == 'Output\nMore output\n' assert len(log_collector.calls['verbose']) == 3 assert 'Output' in log_collector.calls['verbose'][1].args assert 'More output' in log_collector.calls['verbose'][2].args def test_multi_line(self, log_collector): self.tee.write('first line\rsecond line\nthird line') assert (self.output_file.getvalue() == 'first line\rsecond line\nthird line') verbose_calls = log_collector.calls['verbose'] assert len(verbose_calls) == 3 assert self.src_filename in verbose_calls[0].args assert 'first line' in verbose_calls[1].args assert 'second line' in verbose_calls[2].args assert self.tee.logger_buffer == 'third line' def test_isatty(self, monkeypatch): assert not self.tee.isatty() monkeypatch.setattr(self.tee.output_file, 'isatty', lambda: True) assert self.tee.isatty() # TODO: test that broken thumbnail does appear when needed # TODO: test that examples are not executed twice # TODO: test that examples are executed after a no-plot and produce # the correct image in the thumbnail sphinx-gallery-0.2.0/sphinx_gallery/tests/test_notebook.py000066400000000000000000000057601330553134500241140ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Author: Óscar Nájera # License: 3-clause BSD r""" Testing the Jupyter notebook parser """ from __future__ import division, absolute_import, print_function import json import tempfile import os import pytest import sphinx_gallery.gen_rst as sg from sphinx_gallery.notebook import (rst2md, jupyter_notebook, save_notebook, python_to_jupyter_cli) try: FileNotFoundError except NameError: # Python2 FileNotFoundError = IOError def test_latex_conversion(): """Latex parsing from rst into Jupyter Markdown""" double_inline_rst = r":math:`T<0` and :math:`U>0`" double_inline_jmd = r"$T<0$ and $U>0$" assert double_inline_jmd == rst2md(double_inline_rst) align_eq = r""" .. math:: \mathcal{H} &= 0 \\ \mathcal{G} &= D""" align_eq_jmd = r""" \begin{align}\mathcal{H} &= 0 \\ \mathcal{G} &= D\end{align}""" assert align_eq_jmd == rst2md(align_eq) def test_convert(): """Test ReST conversion""" rst = """hello .. contents:: :local: This is :math:`some` math :math:`stuff`. .. note:: Interpolation is a linear operation that can be performed also on Raw and Epochs objects. .. warning:: Go away For more details on interpolation see the page :ref:`channel_interpolation`. .. _foo: bar .. image:: foobar :alt: me :whatever: you """ markdown = """hello This is $some$ math $stuff$.

Note

Interpolation is a linear operation that can be performed also on Raw and Epochs objects.

Warning

Go away

For more details on interpolation see the page `channel_interpolation`. ![me](foobar) """ # noqa assert rst2md(rst) == markdown def test_jupyter_notebook(): """Test that written ipython notebook file corresponds to python object""" file_conf, blocks = sg.split_code_and_text_blocks('tutorials/plot_parse.py') example_nb = jupyter_notebook(blocks) with tempfile.NamedTemporaryFile('w', delete=False) as f: save_notebook(example_nb, f.name) try: with open(f.name, "r") as fname: assert json.load(fname) == example_nb finally: os.remove(f.name) ############################################################################### # Notebook shell utility def test_with_empty_args(): """ User passes no args, should fail with SystemExit """ with pytest.raises(SystemExit): python_to_jupyter_cli([]) def test_missing_file(): """ User passes non existing file, should fail with FileNotFoundError """ with pytest.raises(FileNotFoundError) as excinfo: python_to_jupyter_cli(['nofile.py']) excinfo.match(r'No such file or directory.+nofile\.py') def test_file_is_generated(): """User passes good python file. Check notebook file is created""" python_to_jupyter_cli(['examples/plot_quantum.py']) assert os.path.isfile('examples/plot_quantum.ipynb') os.remove('examples/plot_quantum.ipynb') sphinx-gallery-0.2.0/sphinx_gallery/tests/test_py_source_parser.py000066400000000000000000000006451330553134500256550ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" Test source parser ================== """ # Author: Óscar Nájera # License: 3-clause BSD from __future__ import division, absolute_import, print_function import sphinx_gallery.py_source_parser as sg def test_get_docstring_and_rest(unicode_sample): docstring, rest, lineno = sg.get_docstring_and_rest(unicode_sample) assert u'Únicode' in docstring assert u'heiß' in rest sphinx-gallery-0.2.0/sphinx_gallery/tests/test_sorting.py000066400000000000000000000017021330553134500237510ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" Tests for sorting keys on gallery (sub)sections =============================================== """ # Author: Óscar Nájera # License: 3-clause BSD from __future__ import division, absolute_import, print_function import pytest def test_ExplicitOrder_sorting_key(): """Test ExplicitOrder""" from sphinx_gallery.sorting import ExplicitOrder all_folders = ['e', 'f', 'd', 'c', '01b', 'a'] explicit_folders = ['f', 'd'] key = ExplicitOrder(explicit_folders) sorted_folders = sorted(["d", "f"], key=key) assert sorted_folders == explicit_folders # Test fails on wrong input with pytest.raises(ValueError) as excinfo: ExplicitOrder('nope') excinfo.match("ExplicitOrder sorting key takes a list") # Test missing folder with pytest.raises(ValueError) as excinfo: sorted_folders = sorted(all_folders, key=key) excinfo.match('If you use an explicit folder ordering') sphinx-gallery-0.2.0/sphinx_gallery/tests/test_sphinx_compatibility.py000066400000000000000000000055241330553134500265340ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Testing the Sphinx compatibility shims """ from __future__ import division, absolute_import, print_function import sphinx.util.console from sphinx_gallery import sphinx_compatibility def test_status_iterator(fakesphinxapp): for _ in sphinx_compatibility._app_status_iterator([1, 2, 3], 'summary', length=3): pass assert len(fakesphinxapp.calls['status_iterator']) == 1 call = fakesphinxapp.calls['status_iterator'][0] assert call.args == ([1, 2, 3], 'summary') assert 'color' not in call.kwargs assert 'colorfunc' not in call.kwargs assert call.kwargs['length'] == 3 def test_status_iterator_color(fakesphinxapp): for _ in sphinx_compatibility._app_status_iterator([1, 2, 3], 'summary', color='green', length=3): pass assert len(fakesphinxapp.calls['status_iterator']) == 1 call = fakesphinxapp.calls['status_iterator'][0] assert call.args == ([1, 2, 3], 'summary') assert 'color' not in call.kwargs assert call.kwargs['colorfunc'] == sphinx.util.console.green assert call.kwargs['length'] == 3 def test_get_logger(fakesphinxapp): logger = sphinx_compatibility._app_get_logger('sphinx-gallery-tests') logger.error('error') logger.critical('critical') logger.warning('warning 1') logger.warning('warning 2', color='green') logger.info('info 1') logger.info('info 2', color='green') logger.verbose('verbose') logger.debug('debug') # Error + critical both go through warning: assert len(fakesphinxapp.calls['warn']) == 4 error, critical, warning1, warning2 = fakesphinxapp.calls['warn'] assert error.args == (sphinx.util.console.red('error'), ) assert error.kwargs == {} assert critical.args == (sphinx.util.console.red('critical'), ) assert critical.kwargs == {} assert warning1.args == ('warning 1', ) assert warning1.kwargs == {} assert warning2.args == (sphinx.util.console.green('warning 2'), ) assert warning2.kwargs == {} assert len(fakesphinxapp.calls['info']) == 2 info1, info2 = fakesphinxapp.calls['info'] assert info1.args == ('info 1', ) assert info1.kwargs == {} assert info2.args == (sphinx.util.console.green('info 2'), ) assert info2.kwargs == {} assert len(fakesphinxapp.calls['verbose']) == 1 assert fakesphinxapp.calls['verbose'][0].args == ('verbose', ) assert fakesphinxapp.calls['verbose'][0].kwargs == {} assert len(fakesphinxapp.calls['debug']) == 1 assert fakesphinxapp.calls['debug'][0].args == ('debug', ) assert fakesphinxapp.calls['debug'][0].kwargs == {} sphinx-gallery-0.2.0/sphinx_gallery/tests/test_utils.py000066400000000000000000000013011330553134500234170ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" Test utility functions ================== """ # Author: Nicholas Cain # License: 3-clause BSD from __future__ import division, absolute_import, print_function import sphinx_gallery.utils as utils import pytest def test_replace_py_ipynb(): # Test behavior of function with expected input: for file_name in ['some/file/name', '/corner.pycase']: assert utils.replace_py_ipynb(file_name+'.py') == file_name+'.ipynb' # Test behavior of function with unexpected input: with pytest.raises(ValueError) as expected_exception: utils.replace_py_ipynb(file_name+'.txt') assert 'Unrecognized file extension' in str(expected_exception.value) sphinx-gallery-0.2.0/sphinx_gallery/tests/testconfs/000077500000000000000000000000001330553134500226635ustar00rootroot00000000000000sphinx-gallery-0.2.0/sphinx_gallery/tests/testconfs/index.rst000066400000000000000000000000711330553134500245220ustar00rootroot00000000000000Tiny test build =============== Minimal testing example sphinx-gallery-0.2.0/sphinx_gallery/tests/testconfs/src/000077500000000000000000000000001330553134500234525ustar00rootroot00000000000000sphinx-gallery-0.2.0/sphinx_gallery/tests/testconfs/src/README.txt000066400000000000000000000000421330553134500251440ustar00rootroot00000000000000The Test Gallery ================ sphinx-gallery-0.2.0/sphinx_gallery/tests/testconfs/src/plot_1.py000066400000000000000000000001601330553134500252170ustar00rootroot00000000000000""" ====== B test ====== :filename=1:title=2:lines=3:filesize=2: """ print('foo') print('bar') print('again') sphinx-gallery-0.2.0/sphinx_gallery/tests/testconfs/src/plot_2.py000066400000000000000000000001241330553134500252200ustar00rootroot00000000000000""" ====== C test ====== :filename=2:title=3:lines=1:filesize=1: """ print('foo') sphinx-gallery-0.2.0/sphinx_gallery/tests/testconfs/src/plot_3.py000066400000000000000000000004771330553134500252340ustar00rootroot00000000000000#!/usr/bin/env python2 # -*- coding: utf-8 -*- """ .. _extra_ref: =========================================================== A test with a really long title to make the filesize larger =========================================================== :filename=3:title=1:lines=2:filesize=3: """ print('foo') print('bar') sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/000077500000000000000000000000001330553134500226565ustar00rootroot00000000000000sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/Makefile000066400000000000000000000007321330553134500243200ustar00rootroot00000000000000all: clean html show clean: rm -rf _build/* rm -rf auto_examples/ rm -rf gen_modules/ html: sphinx-build -b html -d _build/doctrees . _build/html latexpdf: sphinx-build -b latex -d _build/doctrees . _build/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C _build/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." show: @python -c "import webbrowser; webbrowser.open_new_tab('file://$(PWD)/_build/html/index.html')" sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/_templates/000077500000000000000000000000001330553134500250135ustar00rootroot00000000000000sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/_templates/module.rst000066400000000000000000000016021330553134500270310ustar00rootroot00000000000000.. Please when editing this file make sure to keep it matching the docs in ../advanced_configuration.rst:reference_to_examples {{ fullname }} {{ underline }} .. automodule:: {{ fullname }} {% block functions %} {% if functions %} Functions --------- {% for item in functions %} .. autofunction:: {{ item }} .. include:: backreferences/{{fullname}}.{{item}}.examples .. raw:: html
{%- endfor %} {% endif %} {% endblock %} {% block classes %} {% if classes %} Classes ------- {% for item in classes %} .. autoclass:: {{ item }} :members: {%- endfor %} {% endif %} {% endblock %} {% block exceptions %} {% if exceptions %} Exceptions ---------- .. autosummary:: {% for item in exceptions %} {{ item }} {%- endfor %} {% endif %} {% endblock %} sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/conf.py000066400000000000000000000020071330553134500241540ustar00rootroot00000000000000import sphinx_gallery # noqa from sphinx_gallery.sorting import FileNameSortKey extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.autosummary', 'sphinx.ext.intersphinx', 'sphinx_gallery.gen_gallery', ] templates_path = ['_templates'] autosummary_generate = True source_suffix = '.rst' master_doc = 'index' exclude_patterns = ['_build'] intersphinx_mapping = { 'python': ('https://docs.python.org/3', None), 'numpy': ('https://docs.scipy.org/doc/numpy/', None), 'scipy': ('https://docs.scipy.org/doc/scipy/reference', None), 'matplotlib': ('https://matplotlib.org/', None), } sphinx_gallery_conf = { 'doc_module': ('sphinx_gallery',), 'reference_url': { 'sphinx_gallery': None, }, 'examples_dirs': ['examples/'], 'gallery_dirs': ['auto_examples'], 'backreferences_dir': 'gen_modules/backreferences', 'within_section_order': FileNameSortKey, 'expected_failing_examples': ['examples/plot_future_imports_broken.py'], } nitpicky = True sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/examples/000077500000000000000000000000001330553134500244745ustar00rootroot00000000000000sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/examples/README.txt000066400000000000000000000000701330553134500261670ustar00rootroot00000000000000Gallery of Examples =================== Test examples. sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/examples/__init__.py000066400000000000000000000002331330553134500266030ustar00rootroot00000000000000# This file is ignored through ignore_pattern so it does not need to have a # docstring following the sphinx-gallery convention (i.e. title + description) sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/examples/plot_future_imports.py000066400000000000000000000004441330553134500311750ustar00rootroot00000000000000""" Test __future__ imports across cells ------------------------------------ This example tests that __future__ imports works across cells. """ from __future__ import division from __future__ import print_function #################### # Dummy section assert 3/2 == 1.5 print(3/2, end='') sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/examples/plot_future_imports_broken.py000066400000000000000000000007551330553134500325420ustar00rootroot00000000000000""" Test without __future__ imports ------------------------------- Test that __future__ imports inside sphinx_gallery modules does not affect the parsing of this script. """ import sys PY3_OR_LATER = sys.version_info[0] >= 3 # SyntaxError on Python 2 print(3/2, end='') # Need to make this example fail on Python 3 as well (currently no way to say # that an example is expected to fail only on Python 2) if PY3_OR_LATER: raise RuntimeError('Forcing this example to fail on Python 3') sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/examples/plot_numpy_scipy.py000066400000000000000000000005441330553134500304660ustar00rootroot00000000000000""" ====================== Link to other packages ====================== Use :mod:`sphinx_gallery` to link to other packages, like :mod:`numpy`, :mod:`scipy.signal`, and :mod:`matplotlib.pyplot`. """ import numpy as np from scipy.signal import firwin import matplotlib.pyplot as plt t = np.arange(1001) / 1000. win = firwin(1001, 0.05) plt.plot(t, win) sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/examples/plot_second_future_imports.py000066400000000000000000000010101330553134500325160ustar00rootroot00000000000000""" Testing future statements across examples ----------------------------------------- This example runs after plot_future_statements.py (alphabetical ordering within subsection) and should be unaffected by the __future__ import in plot_future_statements.py. """ import sys PY2 = sys.version_info[0] == 2 expected = 1 if PY2 else 1.5 assert 3/2 == expected # Make sure print is a keyword not a function. Note: need to use exec because # otherwise you get a SyntaxError on Python 3 if PY2: exec('print "test"') sphinx-gallery-0.2.0/sphinx_gallery/tests/tinybuild/index.rst000066400000000000000000000010751330553134500245220ustar00rootroot00000000000000Tiny test build =============== The complete Sphinx-Gallery project is automatically documented for every module. Examples `here `_. .. currentmodule:: sphinx_gallery .. automodule:: sphinx_gallery :no-members: :no-inherited-members: :py:mod:`sphinx_gallery`: .. autosummary:: :toctree: gen_modules/ :template: module.rst gen_gallery backreferences gen_rst py_source_parser docs_resolv notebook downloads docs_resolv sorting Examples -------- .. toctree:: :maxdepth: 2 auto_examples/index.rst sphinx-gallery-0.2.0/sphinx_gallery/utils.py000066400000000000000000000027221330553134500212260ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Utilities ========= Miscellaneous utilities. """ # Author: Eric Larson # License: 3-clause BSD from __future__ import division, absolute_import, print_function import tempfile from shutil import rmtree import os class _TempDir(str): """Create and auto-destroy temp dir. This is designed to be used with testing modules. Instances should be defined inside test functions. Instances defined at module level can not guarantee proper destruction of the temporary directory. When used at module level, the current use of the __del__() method for cleanup can fail because the rmtree function may be cleaned up before this object (an alternative could be using the atexit module instead). """ # adapted from MNE-Python def __new__(self): # noqa: D105 new = str.__new__(self, tempfile.mkdtemp(prefix='tmp_sg_tempdir_')) return new def __init__(self): # noqa: D102 self._path = self.__str__() def __del__(self): # noqa: D105 rmtree(self._path, ignore_errors=True) def replace_py_ipynb(fname): """Replace .py extension in filename by .ipynb""" fname_prefix, extension = os.path.splitext(fname) allowed_extension='.py' if extension != allowed_extension: raise ValueError( "Unrecognized file extension, expected %s, got %s" % (allowed_extension, extension)) new_extension = '.ipynb' return '{}{}'.format(fname_prefix, new_extension) sphinx-gallery-0.2.0/tutorials/000077500000000000000000000000001330553134500165075ustar00rootroot00000000000000sphinx-gallery-0.2.0/tutorials/README.txt000066400000000000000000000004271330553134500202100ustar00rootroot00000000000000.. _tutorials-index: Secondary gallery ================= .. _notebook_examples: Notebook styled examples ------------------------ You can have multiple galleries each one for different uses. Serving the purpose of having just examples and a different section for tutorials. sphinx-gallery-0.2.0/tutorials/plot_notebook.py000066400000000000000000000100421330553134500217340ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Notebook styled examples ======================== The gallery is capable of transforming Python files into reStructuredText files with a notebook structure. For this to be used you need to respect some syntax rules. It makes a lot of sense to contrast this output rst file with the :download:`original Python script ` to get better feeling of the necessary file structure. Anything before the Python script docstring is ignored by sphinx-gallery and will not appear in the rst file, nor will it be executed. This Python docstring requires an reStructuredText title to name the file and correctly build the reference links. Once you close the docstring you would be writing Python code. This code gets executed by sphinx gallery shows the plots and attaches the generating code. Nevertheless you can break your code into blocks and give the rendered file a notebook style. In this case you have to include a code comment breaker a line of at least 20 hashes and then every comment start with the a new hash. As in this example we start by first writing this module style docstring, then for the first code block we write the example file author and script license continued by the import modules instructions. """ # Code source: Óscar Nájera # License: BSD 3 clause import numpy as np import matplotlib.pyplot as plt ############################################################################## # This code block is executed, although it produces no output. Lines starting # with a simple hash are code comment and get treated as part of the code # block. To include this new comment string we started the new block with a # long line of hashes. # # The sphinx-gallery parser will assume everything after this splitter and that # continues to start with a **comment hash and space** (respecting code style) # is text that has to be rendered in # html format. Keep in mind to always keep your comments always together by # comment hashes. That means to break a paragraph you still need to commend # that line break. # # In this example the next block of code produces some plotable data. Code is # executed, figure is saved and then code is presented next, followed by the # inlined figure. x = np.linspace(-np.pi, np.pi, 300) xx, yy = np.meshgrid(x, x) z = np.cos(xx) + np.cos(yy) plt.figure() plt.imshow(z) plt.colorbar() plt.xlabel('$x$') plt.ylabel('$y$') ########################################################################### # Again it is possble to continue the discussion with a new Python string. This # time to introduce the next code block generates 2 separate figures. plt.figure() plt.imshow(z, cmap=plt.cm.get_cmap('hot')) plt.figure() plt.imshow(z, cmap=plt.cm.get_cmap('Spectral'), interpolation='none') ########################################################################## # There's some subtle differences between rendered html rendered comment # strings and code comment strings which I'll demonstrate below. (Some of this # only makes sense if you look at the # :download:`raw Python script `) # # Comments in comment blocks remain nested in the text. def dummy(): """Dummy function to make sure docstrings don't get rendered as text""" pass # Code comments not preceded by the hash splitter are left in code blocks. string = """ Triple-quoted string which tries to break parser but doesn't. """ ############################################################################ # Output of the script is captured: print('Some output from Python') ############################################################################ # Finally, I'll call ``show`` at the end just so someone running the Python # code directly will see the plots; this is not necessary for creating the docs plt.show() ############################################################################ # You can also include :math:`math` inline, or as separate equations: # # .. math:: # # \exp(j\pi) = -1 # # You can also insert images: # # .. image:: http://www.sphinx-doc.org/en/stable/_static/sphinxheader.png # :alt: Sphinx header # sphinx-gallery-0.2.0/tutorials/plot_parse.py000066400000000000000000000053261330553134500212370ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ The Header Docstring ==================== When writting latex in a Python string keep in mind to escape the backslashes or use a raw docstring .. math:: \\sin (x) Closing this string quotes on same line""" ############################################################################## # Direct first comment # with second line import numpy as np ################################################## A = 1 import matplotlib.pyplot as plt ##################################### # There is no need to always alternate between code and comment blocks # Now there is free repetition of both ############################################# # And a single line of hashes can split your blocks ############################################################################### # Latex in the comments does not need to be escaped # # .. math:: # \sin def dummy(): """This should not be part of a 'text' block'""" ###################################### # Comment inside code to remain here pass # this should not be part of a 'text' block ###################################################################### # # #################################################################### # # Making a line cut in sphinx ############################################################################### # .. warning:: # The next kind of comments are not supported and become to hard to escape # so just don't code like this. # # .. code-block:: python # # def dummy2(): # """Function docstring""" # #################################### # # This comment inside python indentation # # breaks the block structure and is not # # supported # dummy2 # """Free strings are not supported they remain part of the code""" ############################################################################## # New lines can be included in you block comments and the parser # is capable of retaining this significant whitespace to work with sphinx # # So the reStructuredText headers survive # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ print('one') ############################################################################### # Code block separators ############################################################################### # Surrounding a comment line with lines of # like a block spliter also # works and creates a new header for that comment block # too. Nevertheless to get rich text formatting we advise to use # RestructuredText syntax in the comment blocks. print('two') ################################################## # B = 1 ############################################################################## # End comments # # That's all folks ! # # .. literalinclude:: plot_parse.py # # sphinx-gallery-0.2.0/tutorials/seaborn/000077500000000000000000000000001330553134500201405ustar00rootroot00000000000000sphinx-gallery-0.2.0/tutorials/seaborn/README.txt000066400000000000000000000000741330553134500216370ustar00rootroot00000000000000.. _seaborn_tutorials: Seaborn notebooks ----------------- sphinx-gallery-0.2.0/tutorials/seaborn/plot_seaborn_notebook.py000066400000000000000000000020301330553134500250740ustar00rootroot00000000000000# -*- coding: utf-8 -*- r""" A notebook seaborn test ======================= Just to have examples in the gallery of notebooks """ # Author: Michael Waskom # License: BSD 3 clause from __future__ import division, absolute_import, print_function import numpy as np from scipy.stats import kendalltau import seaborn as sns import matplotlib.pyplot as plt sns.set(style="ticks") rs = np.random.RandomState(11) x = rs.gamma(2, size=1000) y = -.5 * x + rs.normal(size=1000) sns.jointplot(x, y, kind="hex", stat_func=kendalltau, color="#4CB391") ############################################################################### # A new block in the notebook to have different styles # sns.set(style="whitegrid", palette="pastel", color_codes=True) # Load the example tips dataset tips = sns.load_dataset("tips") # Draw a nested violinplot and split the violins for easier comparison sns.violinplot(x="day", y="total_bill", hue="sex", data=tips, split=True, inner="quart", palette={"Male": "b", "Female": "y"}) sns.despine(left=True)