sphinx-ext-substitution


Namesphinx-ext-substitution JSON
Version 0.1.3 PyPI version JSON
download
home_pagehttps://github.com/NordicHPC/sphinx_ext_substitution
SummarySphinx extension for substituting variables
upload_time2023-10-19 22:34:55
maintainer
docs_urlNone
authorRichard Darst
requires_python>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*,
license
keywords sphinx-extension
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Sphinx extension for power substitutions
========================================

`Sphinx <https://www.sphinx-doc.org/>`__ (and `Docutils
<http://docutils.sourceforge.net/>`__) provide a way to template
variables into your documentation, but it can be kind of limited.
This Sphinx extension provides a powerful way to manage a master set
of documentation with local-specific variations.  **Logical
management** is a key design consideration: it's easy to make some
variable substitutions, but harder to keep them up to date when you
make a long-running fork!

Features include:

- Default values can also be included inline and replaced only if a
  replacement value is defined.
- Search paths for variable replacements: hierarchical variable
  substitutions, group and then local customizations supported.
- Multiple compilation mode: original, with substitutions, or both.
  In the "both" mode, both the original and substituted are shown with
  highlighting, so that you can easily compare the current original
  values with your current substitute values.
- Both role (inline) and directive (paragraph level) support.
- Theoretical Markdown support via `myst_parser
  <https://github.com/executablebooks/MyST-Parser>`__.
- Support nested mappings within yaml using `.` to drill into keys.
- Partial key lookup support. You only need to specify some substring
  within the key to get the substitution. If it matches more than one,
  an error will be thrown.


Demo
----

We have this source where we define several substitutions.  Focus on `A2`:

.. figure:: img/demo-source.png

   We see definition of several types of substitutions.  This comes
   from the unit tests.

.. figure:: img/demo-replaced.png

   Here we see the default build, with the replaced value included.
   Any missing replacements keep their default value.

.. figure:: img/demo-original.png

   We might need to be see the original, embedded values.  This is easy.

.. figure:: img/demo-both.png

   Here is the real benefit to sphinx_ext_substitution: compile with
   *both* values included, so that you can quickly scan the text and
   make sure that all substitutions

.. figure:: img/demo-sub-list-directive.png

   Here's a second real benefit: listing of all substitution IDs,
   along with original and replacement values.  This makes it easy to
   see what new substitutions have been added and to keep them in sync.

All of the above not just applies to inline paragraph text (roles),
but to block paragraph-level directives (directives).

Substitutions can be maintained easily within YAML or ``.rst``.



Usage examples
--------------

As a role::

  SSH to :sub:`(hostname) triton.aalto.fi`

We see the ReST role is named ``sub`` (which conflicts with
"subscript", maybe we should change that) and an ID of ``hostname``.
If there is a file called ``hostname.rst`` in the search path or a
file with a ``.yaml`` extension with a ``hostname`` key in the search
path, it will substitute that value into this place.  If this value
doesn't exist, it will use the original (or remove it if the original
is empty).

As a directive::

   .. sub:: ssh_clarification

This directive works analogously to the role, with an ID of
``ssh_clarification``.  There is no default content in this example,
which means that nothing is inserted unless a replacement is defined ,
so in this case when used without content it can be used to add in an
extra content in just some versions.  (There could be default content,
too.)  If the directive had content, then it would work the same as
the first example.

As a reminder, in Docutils/Sphinx, a role is inline text and a
directive is a paragraph-level structure.

There are three run modes, controlled by the ``substitution_mode``
configuration option:

* ``replace``: Use the replacements if defined or else the original,
  with no special markup.  This is the default mode and does what you
  expect for normal use.

* ``both``: Show *both* the ID, original value, and the replacement
  value with distinguishing markup (HTML only).  This can be used to
  compare your local version with the latest upstream. to see what
  needs to be updated - or what substitutions are available and should
  be used.

* ``original``: Show only the original text without any replacements.

Finally, there is a ``sub-list`` directive::

  .. sub-list::

This directive is replaced with a table that contains all substitution
IDs, original values, and replacements that have been used in the
document.


When searching for replacement values:

1. First, each item in the search path (configuration option
   ``substitute_path``) is searched.

   a. If it's a file, load it as YAML (see below)

   b. If it's a directory, go to step 2.

2. List the directory and search for files to load.

   a. First, load all ``*.rst`` files.  The ``*`` value is used as the
      replacement ID.

   b. Second, search for all ``*.yaml`` files.  Load them as YAML
      data, which should be a mapping from keys to values.

   c. All values are ``.strip()``\ ped.

3. Use the first-detected value for each ID.  Thus, earlier items in
   the search path take precedence over later ones.


YAML reminder::

  ID1: this is the text for replacement id = ID1
  ID2: |
      This is a block text that preserves newlines.

      The "|" character is what indicates that newlines should be
      preserved.
  ID3: >
      Using the ">" character removes all newlines and runs the block
      text together.


Installation
------------
Install the extension.  Currently not in any package managers, so::

    pip install

Add the extension to your Sphinx ``conf.py`` file::

    extensions = [
        'sphinx_ext_substitution'
    ]

There are no non-trivial dependencies besides PyYAML (which is listed
as a dependency, but if you don't use the YAML feature it isn't
needed).  Sphinx and Docutils are obviously required - our goal is to
support any reasonable version.



Configuration
-------------

Currently there are two Sphinx variables defined:

* ``substitute_mode``: One of ``replace`` (the default), ``original``,
  or ``both``.  See above for the meaning of these values.

* ``substitute_path`` is a path to search for replacement variables,
  keyed by ID.  In Sphinx, this is a list of paths, but if given on
  command with ``-D substitute_path=dir1:dir2``, you can
  colon-separate paths as well.  Each file on this path that ends in
  ``.rst`` or ``.yaml`` is searched for variables.  The default is
  ``.``.

* The environment variable ``SPHINX_EXT_SUBSTITUTION_PATH`` is used
  *before* the ``substitute_path`` configuration option.  Both are
  used if both are given (the env var takes precedence).  There is no
  need for both, but it provides more flexible configuration for
  integration to your build system.

..
  * If ``partial_match_substitution`` set to true, then only a partial
    string match to the key will result in a substitution.


Development and maintenance
---------------------------

Most functonality exists and this is now usable, but not extensively
used yet.  Please send any changes or requests to us.  This was
developed as a first non-trivial Sphinx extension, so any refactorings
to make things better are welcome.

Primary maintainer: Richard Darst, Aalto University.



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/NordicHPC/sphinx_ext_substitution",
    "name": "sphinx-ext-substitution",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*,",
    "maintainer_email": "",
    "keywords": "sphinx-extension",
    "author": "Richard Darst",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/0f/93/74a6557b40efb35eb1952600533c930e85e8214848541bb99395d6d1e447/sphinx_ext_substitution-0.1.3.tar.gz",
    "platform": null,
    "description": "Sphinx extension for power substitutions\n========================================\n\n`Sphinx <https://www.sphinx-doc.org/>`__ (and `Docutils\n<http://docutils.sourceforge.net/>`__) provide a way to template\nvariables into your documentation, but it can be kind of limited.\nThis Sphinx extension provides a powerful way to manage a master set\nof documentation with local-specific variations.  **Logical\nmanagement** is a key design consideration: it's easy to make some\nvariable substitutions, but harder to keep them up to date when you\nmake a long-running fork!\n\nFeatures include:\n\n- Default values can also be included inline and replaced only if a\n  replacement value is defined.\n- Search paths for variable replacements: hierarchical variable\n  substitutions, group and then local customizations supported.\n- Multiple compilation mode: original, with substitutions, or both.\n  In the \"both\" mode, both the original and substituted are shown with\n  highlighting, so that you can easily compare the current original\n  values with your current substitute values.\n- Both role (inline) and directive (paragraph level) support.\n- Theoretical Markdown support via `myst_parser\n  <https://github.com/executablebooks/MyST-Parser>`__.\n- Support nested mappings within yaml using `.` to drill into keys.\n- Partial key lookup support. You only need to specify some substring\n  within the key to get the substitution. If it matches more than one,\n  an error will be thrown.\n\n\nDemo\n----\n\nWe have this source where we define several substitutions.  Focus on `A2`:\n\n.. figure:: img/demo-source.png\n\n   We see definition of several types of substitutions.  This comes\n   from the unit tests.\n\n.. figure:: img/demo-replaced.png\n\n   Here we see the default build, with the replaced value included.\n   Any missing replacements keep their default value.\n\n.. figure:: img/demo-original.png\n\n   We might need to be see the original, embedded values.  This is easy.\n\n.. figure:: img/demo-both.png\n\n   Here is the real benefit to sphinx_ext_substitution: compile with\n   *both* values included, so that you can quickly scan the text and\n   make sure that all substitutions\n\n.. figure:: img/demo-sub-list-directive.png\n\n   Here's a second real benefit: listing of all substitution IDs,\n   along with original and replacement values.  This makes it easy to\n   see what new substitutions have been added and to keep them in sync.\n\nAll of the above not just applies to inline paragraph text (roles),\nbut to block paragraph-level directives (directives).\n\nSubstitutions can be maintained easily within YAML or ``.rst``.\n\n\n\nUsage examples\n--------------\n\nAs a role::\n\n  SSH to :sub:`(hostname) triton.aalto.fi`\n\nWe see the ReST role is named ``sub`` (which conflicts with\n\"subscript\", maybe we should change that) and an ID of ``hostname``.\nIf there is a file called ``hostname.rst`` in the search path or a\nfile with a ``.yaml`` extension with a ``hostname`` key in the search\npath, it will substitute that value into this place.  If this value\ndoesn't exist, it will use the original (or remove it if the original\nis empty).\n\nAs a directive::\n\n   .. sub:: ssh_clarification\n\nThis directive works analogously to the role, with an ID of\n``ssh_clarification``.  There is no default content in this example,\nwhich means that nothing is inserted unless a replacement is defined ,\nso in this case when used without content it can be used to add in an\nextra content in just some versions.  (There could be default content,\ntoo.)  If the directive had content, then it would work the same as\nthe first example.\n\nAs a reminder, in Docutils/Sphinx, a role is inline text and a\ndirective is a paragraph-level structure.\n\nThere are three run modes, controlled by the ``substitution_mode``\nconfiguration option:\n\n* ``replace``: Use the replacements if defined or else the original,\n  with no special markup.  This is the default mode and does what you\n  expect for normal use.\n\n* ``both``: Show *both* the ID, original value, and the replacement\n  value with distinguishing markup (HTML only).  This can be used to\n  compare your local version with the latest upstream. to see what\n  needs to be updated - or what substitutions are available and should\n  be used.\n\n* ``original``: Show only the original text without any replacements.\n\nFinally, there is a ``sub-list`` directive::\n\n  .. sub-list::\n\nThis directive is replaced with a table that contains all substitution\nIDs, original values, and replacements that have been used in the\ndocument.\n\n\nWhen searching for replacement values:\n\n1. First, each item in the search path (configuration option\n   ``substitute_path``) is searched.\n\n   a. If it's a file, load it as YAML (see below)\n\n   b. If it's a directory, go to step 2.\n\n2. List the directory and search for files to load.\n\n   a. First, load all ``*.rst`` files.  The ``*`` value is used as the\n      replacement ID.\n\n   b. Second, search for all ``*.yaml`` files.  Load them as YAML\n      data, which should be a mapping from keys to values.\n\n   c. All values are ``.strip()``\\ ped.\n\n3. Use the first-detected value for each ID.  Thus, earlier items in\n   the search path take precedence over later ones.\n\n\nYAML reminder::\n\n  ID1: this is the text for replacement id = ID1\n  ID2: |\n      This is a block text that preserves newlines.\n\n      The \"|\" character is what indicates that newlines should be\n      preserved.\n  ID3: >\n      Using the \">\" character removes all newlines and runs the block\n      text together.\n\n\nInstallation\n------------\nInstall the extension.  Currently not in any package managers, so::\n\n    pip install\n\nAdd the extension to your Sphinx ``conf.py`` file::\n\n    extensions = [\n        'sphinx_ext_substitution'\n    ]\n\nThere are no non-trivial dependencies besides PyYAML (which is listed\nas a dependency, but if you don't use the YAML feature it isn't\nneeded).  Sphinx and Docutils are obviously required - our goal is to\nsupport any reasonable version.\n\n\n\nConfiguration\n-------------\n\nCurrently there are two Sphinx variables defined:\n\n* ``substitute_mode``: One of ``replace`` (the default), ``original``,\n  or ``both``.  See above for the meaning of these values.\n\n* ``substitute_path`` is a path to search for replacement variables,\n  keyed by ID.  In Sphinx, this is a list of paths, but if given on\n  command with ``-D substitute_path=dir1:dir2``, you can\n  colon-separate paths as well.  Each file on this path that ends in\n  ``.rst`` or ``.yaml`` is searched for variables.  The default is\n  ``.``.\n\n* The environment variable ``SPHINX_EXT_SUBSTITUTION_PATH`` is used\n  *before* the ``substitute_path`` configuration option.  Both are\n  used if both are given (the env var takes precedence).  There is no\n  need for both, but it provides more flexible configuration for\n  integration to your build system.\n\n..\n  * If ``partial_match_substitution`` set to true, then only a partial\n    string match to the key will result in a substitution.\n\n\nDevelopment and maintenance\n---------------------------\n\nMost functonality exists and this is now usable, but not extensively\nused yet.  Please send any changes or requests to us.  This was\ndeveloped as a first non-trivial Sphinx extension, so any refactorings\nto make things better are welcome.\n\nPrimary maintainer: Richard Darst, Aalto University.\n\n\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Sphinx extension for substituting variables",
    "version": "0.1.3",
    "project_urls": {
        "Homepage": "https://github.com/NordicHPC/sphinx_ext_substitution"
    },
    "split_keywords": [
        "sphinx-extension"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6ce87e2d958c825d0636d1ca6e1f366fad083af7a07c8c58182c6611981e9471",
                "md5": "172c64352be6c8f48e1a462e68f7c222",
                "sha256": "8aeb49edab48a142793f6a582e6a76ad4f75fd365afc5b2f445204a0ae36c2d7"
            },
            "downloads": -1,
            "filename": "sphinx_ext_substitution-0.1.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "172c64352be6c8f48e1a462e68f7c222",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*,",
            "size": 13292,
            "upload_time": "2023-10-19T22:34:54",
            "upload_time_iso_8601": "2023-10-19T22:34:54.010700Z",
            "url": "https://files.pythonhosted.org/packages/6c/e8/7e2d958c825d0636d1ca6e1f366fad083af7a07c8c58182c6611981e9471/sphinx_ext_substitution-0.1.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0f9374a6557b40efb35eb1952600533c930e85e8214848541bb99395d6d1e447",
                "md5": "c3b411151e9ec364c518d3db275347ca",
                "sha256": "aaa99ae8af0c81d9a986b171071d69b2bed198548c0257ee834ecfd22590c657"
            },
            "downloads": -1,
            "filename": "sphinx_ext_substitution-0.1.3.tar.gz",
            "has_sig": false,
            "md5_digest": "c3b411151e9ec364c518d3db275347ca",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*,",
            "size": 14736,
            "upload_time": "2023-10-19T22:34:55",
            "upload_time_iso_8601": "2023-10-19T22:34:55.028542Z",
            "url": "https://files.pythonhosted.org/packages/0f/93/74a6557b40efb35eb1952600533c930e85e8214848541bb99395d6d1e447/sphinx_ext_substitution-0.1.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-19 22:34:55",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "NordicHPC",
    "github_project": "sphinx_ext_substitution",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "sphinx-ext-substitution"
}
        
Elapsed time: 2.70102s