diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 0000000..a681190 --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1,13 @@ +.. _changelog: + +========= +Changelog +========= + +Version 1.0 +=========== + +Version 1.0.0 +------------- + +* Initial release diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..067a25e --- /dev/null +++ b/docs/conf.py @@ -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 = [] diff --git a/docs/configuration.rst b/docs/configuration.rst new file mode 100644 index 0000000..120d44d --- /dev/null +++ b/docs/configuration.rst @@ -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 `_. +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 `_ for information how to use new-stye Python formatting. + + +.. _python_regex: https://docs.python.org/3/howto/regex.html +.. _python_format: https://pyformat.info/ diff --git a/docs/context.rst b/docs/context.rst new file mode 100644 index 0000000..e5feb74 --- /dev/null +++ b/docs/context.rst @@ -0,0 +1,160 @@ +.. _context: + +============ +HTML Context +============ + +The following variables and functions are exposed to the `Sphinx HTML builder 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 ` ``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 + +

Versions

+ + +.. attribute:: versions.branches + + You can use the ``branches`` property of the ``versions`` iterable to get the ``Version`` objects for all branches. + + .. code-block:: jinja + +

Branches

+
    + {%- for item in versions.branches %} +
  • {{ item.name }}
  • + {%- endfor %} +
+ +.. attribute:: versions.tags + + You can use the ``tags`` property of the ``versions`` iterable to get the ``Version`` objects for all tags. + + .. code-block:: jinja + +

Tags

+ + +.. 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 `. + + .. code-block:: jinja + +

Releases

+
    + {%- for item in versions.releases %} +
  • {{ item.name }}
  • + {%- endfor %} +
+ +.. 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 `. + + .. code-block:: jinja + +

In Development

+
    + {%- for item in versions.in_development %} +
  • {{ item.name }}
  • + {%- endfor %} +
+ +Functions +========= + +Similar to Sphinx's `hasdoc() `_ function. + +.. function:: vhasdoc(other_version) + + This function is Similar to Sphinx's `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 master. + {% endif %} + +.. function:: vpathto(other_version) + + This function is Similar to Sphinx's `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 `_ is returned instead. + + .. code-block:: jinja + + {% if vhasdoc('master') %} + This page is also available in master. + {% else %} + Go to master for the latest docs. + {% endif %} + +Other Variables +=============== + +.. attribute:: current_version + + A ``Version`` object for of the current version being built. + + .. code-block:: jinja + +

Current Version: {{ current_version.name }}

+ +.. attribute:: latest_version + + A ``Version`` object of the latest released version being built. + + .. code-block:: jinja + +

Latest Version: {{ current_version.name }}

+ + +.. _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 diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..85d5532 --- /dev/null +++ b/docs/index.rst @@ -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 diff --git a/docs/install.rst b/docs/install.rst new file mode 100644 index 0000000..47601c0 --- /dev/null +++ b/docs/install.rst @@ -0,0 +1,35 @@ +.. _install: + +============ +Installation +============ + +You can install ``sphinx-multiversion`` via `pip `_ or directly from :file:`setup.py`. + +.. note:: + Since ``sphinx-multiversion`` is still under heavy development, it is not available on `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/ diff --git a/docs/quickstart.rst b/docs/quickstart.rst new file mode 100644 index 0000000..a5df776 --- /dev/null +++ b/docs/quickstart.rst @@ -0,0 +1,80 @@ +.. _quickstart: + +========== +Quickstart +========== + +After :ref:`installation `, 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 ` the extension first. + +.. seealso:: + + If you're not using Sphinx yet, have a look at the `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 %} +

{{ _('Versions') }}

+ + {% endif %} + +.. seealso:: + + You can also list branches, tags, released versions and development branches separately. + See :ref:`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 `_ 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 `. + + +.. _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 diff --git a/docs/templates.rst b/docs/templates.rst new file mode 100644 index 0000000..424c857 --- /dev/null +++ b/docs/templates.rst @@ -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 %} +

{{ _('Versions') }}

+ + {% endif %} + +List branches and tags separately +--------------------------------- + +.. code-block:: html + + {% if versions %} +

{{ _('Branches') }}

+
    + {%- for item in versions.branches %} +
  • {{ item.name }}
  • + {%- endfor %} +
+

{{ _('Tags') }}

+ + {% endif %} + +List releases and development versions separately +------------------------------------------------- + +.. code-block:: html + + {% if versions %} +

{{ _('Releases') }}

+
    + {%- for item in versions.releases %} +
  • {{ item.name }}
  • + {%- endfor %} +
+

{{ _('Tags') }}

+
    + {%- for item in versions.in_development %} +
  • {{ item.name }}
  • + {%- endfor %} +
+ {% 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 %} +

+ + {% 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 {{latest_version.name}}. + {% else %} + You're reading the documentation for a development version. + For the latest released version, please have a look at {{latest_version.name}}. + {% endif %} + +

+ {% endif %} + {{ super() }} + {% endblock %}% + + +ReadTheDocs Theme +================= + +As of version 0.4.3, the `Read the Docs 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 + +
+ + Other Versions + v: {{ current_version.name }} + + +
+ {%- if versions.tags %} +
+
Tags
+ {%- for item in versions.tags %} +
{{ item.name }}
+ {%- endfor %} +
+ {%- endif %} + {%- if versions.branches %} +
+
Branches
+ {%- for item in versions.branches %} +
{{ item.name }}
+ {%- endfor %} +
+ {%- endif %} +
+
+ + +.. _sphinx_rtd_theme: https://pypi.org/project/sphinx-rtd-theme/