docs: Add documentation

This commit is contained in:
Jan Holthuis 2020-02-23 23:51:22 +01:00
parent c5af0add43
commit fcf6342a9a
8 changed files with 582 additions and 0 deletions

13
docs/changelog.rst Normal file
View file

@ -0,0 +1,13 @@
.. _changelog:
=========
Changelog
=========
Version 1.0
===========
Version 1.0.0
-------------
* Initial release

15
docs/conf.py Normal file
View file

@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
"""Sphinx configuration file."""
import time
author = "Jan Holthuis"
project = "sphinx-multiversion"
release = "1.0.0"
version = "1.0"
copyright = '{}, {}'.format(time.strftime('%Y'), author)
html_last_updated_fmt = '%c'
master_doc = 'index'
pygments_style = 'friendly'
templates_path = ['_templates']
extensions = []

108
docs/configuration.rst Normal file
View file

@ -0,0 +1,108 @@
.. _configuration:
=============
Configuration
=============
``sphinx-multiversion`` reads your Sphinx :file:`conf.py` file for configuration.
As usual, you can also override certain options by using ``-D var=value`` on the command line.
This is what the default configuration looks like:
.. code-block:: python
# Whitelist pattern for tags (set to None to ignore all tags)
smv_tag_whitelist = r'^.*$'
# Whitelist pattern for branches (set to None to ignore all branches)
smv_branch_whitelist = r'^.*$'
# Whitelist pattern for remotes (set to None to use local branches only)
smv_remote_whitelist = None
# Pattern for released versions
smv_released_pattern = r'^tags/.*$'
# Format for versioned output directories inside the build directory
smv_outputdir_format = '{ref.name}'
You an override all of these values inside you :file:`conf.py`.
.. note::
You can check which tags/branches are matched by running ``sphinx-multiversion`` with the ``--dump-metadata`` flag.
Tag/Branch/Remote whitelists
============================
Tags, Branches and Remotes are included by `Regular Expressions <python_regex_>`_.
Here are some examples:
.. code-block:: python
smv_tag_whitelist = r'^.*$' # Include all tags
smv_tag_whitelist = r'^v\d+\.\d+$' # Include tags like "v2.1"
smv_branch_whitelist = r'^.*$' # Include all branches
smv_branch_whitelist = r'^(?!master).*$' # Include all branches except "master"
smv_remote_whitelist = None # Only use local branches
smv_remote_whitelist = r'^.*$' # Use branches from all remotes
smv_remote_whitelist = r'^(origin|upstream)$' # Use branches from origin and upstream
.. note::
To list values to match, you can use ``git branch``, ``git tag`` and ``git remote``.
Release Pattern
===============
A Regular Expression is used to determine if a version of the documentation has been released or if it's a development version.
To allow more flexibility, the regex is evaluated over the full refname.
Here are some examples:
.. code-block:: python
smv_released_pattern = r'^tags/.*$' # Tags only
smv_released_pattern = r'^heads/\d+\.\d+$' # Branches like "2.1"
smv_released_pattern = r'^(tags/.*|heads/\d+\.\d+)$' # Branches like "2.1" and all tags
smv_released_pattern = r'^(heads|remotes/[^/]+)/(?!:master).*$' # Everything except master branch
.. note::
To list all refnames , you can use:
.. code-block:: bash
git for-each-ref --format "%(refname)" | sed 's/^refs\///g'
Output Directory Format
=======================
Each version will be built into a seperate subdirectory of the Sphinx output directory.
The ``smv_outputdir_format`` setting determines the directory structure for the subdirectories. It is a new-style Python formatting string with two parameters - ``ref`` and ``config``.
Here are some examples:
.. code-block:: python
smv_outputdir_format = '{ref.name}' # Use the branch/tag name
smv_outputdir_format = '{ref.commit}' # Use the commit hash
smv_outputdir_format = '{ref.commit:.7s}' # Use the commit hash truncated to 7 characters
smv_outputdir_format = '{ref.refname}' # Use the full refname
smv_outputdir_format = '{ref.source}/{ref.name}' # Equivalent to the previous example
smv_outputdir_format = 'versions/{config.release}' # Use "versions" as parent directory and the "release" variable from conf.py
smv_outputdir_format = '{config.version}/{ref.name}' # Use the version from conf.py as parent directory and the branch/tag name as subdirectory
.. seealso::
Have a look at `PyFormat <python_format_>`_ for information how to use new-stye Python formatting.
.. _python_regex: https://docs.python.org/3/howto/regex.html
.. _python_format: https://pyformat.info/

160
docs/context.rst Normal file
View file

@ -0,0 +1,160 @@
.. _context:
============
HTML Context
============
The following variables and functions are exposed to the `Sphinx HTML builder context <sphinx_context_>`_ in all versions.
``Version`` Objects
===================
All versions will be exposed to the HTML context as ``Version`` objects with the following attributes:
.. attribute:: name
The branch or tag name.
.. attribute:: url
The URL to the current page in this version.
.. attribute:: version
The value of the ``version`` variable in ``conf.py``.
.. attribute:: release
The value of the ``release`` variable in ``conf.py``.
.. attribute:: is_released
``True`` if this version matches the :ref:`configured <configuration>` ``smv_released_pattern`` regular expression, else ``False``.
Versions
========
The most important variable is ``versions``, which can be used to iterate over all found (and whitelisted) versions.
.. attribute:: versions
An iterable that yields all ``Version`` objects.
.. code-block:: jinja
<h3>Versions</h3>
<ul>
{%- for item in versions %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
.. attribute:: versions.branches
You can use the ``branches`` property of the ``versions`` iterable to get the ``Version`` objects for all branches.
.. code-block:: jinja
<h3>Branches</h3>
<ul>
{%- for item in versions.branches %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
.. attribute:: versions.tags
You can use the ``tags`` property of the ``versions`` iterable to get the ``Version`` objects for all tags.
.. code-block:: jinja
<h3>Tags</h3>
<ul>
{%- for item in versions.tags %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
.. attribute:: versions.releases
You can use the ``releases`` property of the ``versions`` iterable to get all ``Version`` objects where the ``ìs_released`` attribute is ``True``.
This is determined by the ``smv_released_pattern`` in the :ref:`Configuration <configuration>`.
.. code-block:: jinja
<h3>Releases</h3>
<ul>
{%- for item in versions.releases %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
.. attribute:: versions.in_development
You can use the ``in_development`` property of the ``versions`` iterable to get all ``Version`` objects where the ``ìs_released`` attribute is ``False``.
This is determined by the ``smv_released_pattern`` in the :ref:`Configuration <configuration>`.
.. code-block:: jinja
<h3>In Development</h3>
<ul>
{%- for item in versions.in_development %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
Functions
=========
Similar to Sphinx's `hasdoc() <sphinx_hasdoc_>`_ function.
.. function:: vhasdoc(other_version)
This function is Similar to Sphinx's `hasdoc() <sphinx_hasdoc_>`_ function.
It takes ``other_version`` as string and returns ``True`` if the current document exists in another version.
.. code-block:: jinja
{% if vhasdoc('master') %}
This page is available in <a href="../master/index.html">master</a>.
{% endif %}
.. function:: vpathto(other_version)
This function is Similar to Sphinx's `pathto() <sphinx_pathto_>`_ function.
It takes ``other_version`` as string and returns the relative URL to the current page in the other version.
If the current page does not exist in that version, the relative URL to its `master_doc <sphinx_master_doc_>`_ is returned instead.
.. code-block:: jinja
{% if vhasdoc('master') %}
This page is also available in <a href="{{ vpathto('master') }}">master</a>.
{% else %}
Go to <a href="{{ vpathto('master') }}">master</a> for the latest docs.
{% endif %}
Other Variables
===============
.. attribute:: current_version
A ``Version`` object for of the current version being built.
.. code-block:: jinja
<h3>Current Version: {{ current_version.name }}</h3>
.. attribute:: latest_version
A ``Version`` object of the latest released version being built.
.. code-block:: jinja
<h3>Latest Version: {{ current_version.name }}</h3>
.. _sphinx_context: http://www.sphinx-doc.org/en/stable/config.html?highlight=context#confval-html_context
.. _sphinx_master_doc: http://www.sphinx-doc.org/en/stable/config.html?highlight=context#confval-master_doc
.. _sphinx_hasdoc: http://www.sphinx-doc.org/en/stable/templating.html#hasdoc
.. _sphinx_pathto: http://www.sphinx-doc.org/en/stable/templating.html#pathto

26
docs/index.rst Normal file
View file

@ -0,0 +1,26 @@
=============================
sphinx-multiversion |version|
=============================
A Sphinx extension for building self-hosted versioned documentation.
Project Links
=============
* Source code: https://github.com/Holzhaus/sphinx-multiversion
.. toctree::
:maxdepth: 3
:caption: General
install
quickstart
configuration
templates
context
.. toctree::
:maxdepth: 1
:caption: Appendix
changelog

35
docs/install.rst Normal file
View file

@ -0,0 +1,35 @@
.. _install:
============
Installation
============
You can install ``sphinx-multiversion`` via `pip <pip_>`_ or directly from :file:`setup.py`.
.. note::
Since ``sphinx-multiversion`` is still under heavy development, it is not available on `PyPI <pypi_>`_ yet.
Install from GitHub
===================
You can install the latest development version using pip to install directly from the GitHub
repository.
.. code-block:: bash
pip install git+https://github.com/Holzhaus/sphinx-multiversion.git
Install via :file:`setup.py`
============================
It's also possible to clone the Git repository and install the extension using its :file:`setup.py`:
.. code-block:: bash
git clone https://github.com/Holzhaus/sphinx-multiversion.git
cd sphinx-multiversion
python setup.py install
.. _pip: https://pip.pypa.io/en/stable/
.. _pypi: https://pypi.org/

80
docs/quickstart.rst Normal file
View file

@ -0,0 +1,80 @@
.. _quickstart:
==========
Quickstart
==========
After :ref:`installation <install>`, using ``sphinx-multiversion`` should be fairly straightforward.
To be able to build multiple versions of Sphinx documentation, ``sphinx-multiversion`` acts as wrapper for ``sphinx-build``.
If you're already using Sphinx documentation for your project, you can now use ``sphinx-multiversion`` to build the HTML documentation.
You can check if it works by running:
.. code-block:: bash
# Without sphinx-multiversion
sphinx-build docs build/html
# With sphinx-multiversion
sphinx-multiversion docs build/html
Don't worry - no version picker will show up in the generated HTML yet.
You need to :ref:`configure <configuration>` the extension first.
.. seealso::
If you're not using Sphinx yet, have a look at the `tutorial <sphinx_tutorial_>`_.
Next, you need to add the extension to the :file:`conf.py` file.
.. code-block:: python
extensions = [
"sphinx_multiversion",
]
To make the different versions show up in the HTML, you also need to add a custom template. For example, you could create a new template named :file:`versioning.html` with the following content:
.. code-block:: html
{% if versions %}
<h3>{{ _('Versions') }}</h3>
<ul>
{%- for item in versions %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
{% endif %}
.. seealso::
You can also list branches, tags, released versions and development branches separately.
See :ref:`Templates <templates>` for details.
Assuming that you're using a theme with sidebar widget support, you just need to make sure that the file is inside the ``templates_path`` and add it to the `html_sidebars <sphinx_html_sidebars_>`_ variable.
.. code-block:: python
templates_path = [
"_templates",
]
html_sidebars = [
"versioning.html",
]
Now rebuild the documentation:
.. code-block:: bash
sphinx-multiversion docs build/html
Done!
.. seealso::
By default, all local branches and tags will be included. If you only want to include certain branches/tags or also include remote branches, see :ref:`Configuration <configuration>`.
.. _sphinx_tutorial: http://www.sphinx-doc.org/en/stable/tutorial.html
.. _sphinx_html_sidebars: https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_sidebars

145
docs/templates.rst Normal file
View file

@ -0,0 +1,145 @@
.. _templates:
=========
Templates
=========
``sphinx-multiversion`` does not change the look of your HTML output by default.
Instead, you can customize the template to cater to your needs.
Version Listings
================
To add version listings to your template, you need to add a custom template to your theme.
You can take one of the snippets below, put it into :file:`_templates/versioning.html` and add it to your theme's sidebar:
.. code-block:: html
templates_path = [
"_templates",
]
html_sidebars = [
"versioning.html",
]
List all branches/tags
----------------------
.. code-block:: html
{% if versions %}
<h3>{{ _('Versions') }}</h3>
<ul>
{%- for item in versions %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
{% endif %}
List branches and tags separately
---------------------------------
.. code-block:: html
{% if versions %}
<h3>{{ _('Branches') }}</h3>
<ul>
{%- for item in versions.branches %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
<h3>{{ _('Tags') }}</h3>
<ul>
{%- for item in versions.tags %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
{% endif %}
List releases and development versions separately
-------------------------------------------------
.. code-block:: html
{% if versions %}
<h3>{{ _('Releases') }}</h3>
<ul>
{%- for item in versions.releases %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
<h3>{{ _('Tags') }}</h3>
<ul>
{%- for item in versions.in_development %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{%- endfor %}
</ul>
{% endif %}
Version Banners
===============
You can also add version banners to your theme, for example:
.. code-block:: html
{% extends "page.html" %}
{% block body %}
{% if current_version and latest_version and current_version != latest_version %}
<p>
<strong>
{% if current_version.is_released %}
You're reading an old version of this documentation.
If you want up-to-date information, please have a look at <a href="{{ vpathto(latest_version.name) }}">{{latest_version.name}}</a>.
{% else %}
You're reading the documentation for a development version.
For the latest released version, please have a look at <a href="{{ vpathto(latest_version.name) }}">{{latest_version.name}}</a>.
{% endif %}
<strong>
</p>
{% endif %}
{{ super() }}
{% endblock %}%
ReadTheDocs Theme
=================
As of version 0.4.3, the `Read the Docs theme <sphinx_rtd_theme_>`_ does not support sidebar widgets.
So instead of adding a custom template to ``html_sidebars``, you need to create a template file named :file:`versions.html` with the following content:
.. code-block:: html
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
<span class="rst-current-version" data-toggle="rst-current-version">
<span class="fa fa-book"> Other Versions</span>
v: {{ current_version.name }}
<span class="fa fa-caret-down"></span>
</span>
<div class="rst-other-versions">
{%- if versions.tags %}
<dl>
<dt>Tags</dt>
{%- for item in versions.tags %}
<dd><a href="{{ item.url }}">{{ item.name }}</a></dd>
{%- endfor %}
</dl>
{%- endif %}
{%- if versions.branches %}
<dl>
<dt>Branches</dt>
{%- for item in versions.branches %}
<dd><a href="{{ item.url }}">{{ item.name }}</a></dd>
{%- endfor %}
</dl>
{%- endif %}
</div>
</div>
.. _sphinx_rtd_theme: https://pypi.org/project/sphinx-rtd-theme/