Skip to content Skip to sidebar Skip to footer

Substitution In A File Name With Restructuredtext (sphinx)?

I want to create several files from a single template, which differ only by a variable name. For example : (file1.rst): .. |variable| replace:: 1 .. include template.rst (template

Solution 1:

There are two problems here: a substitution problem, and a parsing order problem.

For the first problem, the substitution reference|variable| cannot have adjacent characters (besides whitespace or maybe _ for hyperlinking) or else it won't parse as a substitution reference, so you need to escape it:

./images/\ |variable|\ -image.png

However, the second problem is waiting around the corner. While I'm not certain of the details, it seems reST is unable to parse substitutions inside other directives. I think it first parses the image directive, which puts it in the document tree and thus out of reach of the substitution mechanism. Similarly, I don't think it's possible to use a substitution to insert content intended to be parsed (e.g. .. |img1| replace::`.. image:: images/1-image.png`). This is all speculative based on some tests and my incomplete comprehension of the official documentation, so someone more knowledgeable can correct what I've said here.

I think you're aware of the actual image substitution directive (as opposed to text substitution), but I don't think it attains the generality you're aiming for (you'll still need a separate directive for the image as from the |variable|), but in any case it looks like this:

.. |img1| image:: images/1-image.png

Since you're using Sphinx, you can try creating your own directive extension (see this answer for information), but it won't solve the substitutions-inside-markup problem.

Solution 2:

You have to create a custom directive in this case as Sphinx doesn't allow you to substitute image paths. You can change Sphinx figure directive as follows and use it instead of the image directive.

from typing importAny, Dict, List, Tuplefrom typing import cast

from docutils import nodes
from docutils.nodes import Node, make_id, system_message
from docutils.parsers.rst import directives
from docutils.parsers.rst.directives import images, html, tables

from sphinx import addnodes
from sphinx.directives import optional_int
from sphinx.domains.math import MathDomain
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info

ifFalse:
    # For type annotationfrom sphinx.application import Sphinx


classCustomFigure(images.Figure):
    """The figure directive which applies `:name:` option to the figure node
    instead of the image node.
    """defrun(self) -> List[Node]:
        name = self.options.pop('name', None)
        path = self.arguments[0]  #path = ./images/variable-image.png#replace 'variable' from th.e given value 
        self.argument[0] = path.replace("variable", "string substitution")
        result = super().run()
        iflen(result) == 2orisinstance(result[0], nodes.system_message):
            return result

        assertlen(result) == 1
        figure_node = cast(nodes.figure, result[0])
        if name:
            # set ``name`` to figure_node if given
            self.options['name'] = name
            self.add_name(figure_node)

        # copy lineno from image nodeif figure_node.line isNoneandlen(figure_node) == 2:
            caption = cast(nodes.caption, figure_node[1])
            figure_node.line = caption.line

        return [figure_node]


defsetup(app: "Sphinx") -> Dict[str, Any]:
    directives.register_directive('figure', Figure)

    return {
        'version': 'builtin',
        'parallel_read_safe': True,
        'parallel_write_safe': True,
    }

You can add this CustomFigure.py directive in the conf.py of the project and use the customfigure directive across Sphinx project instead of the Image directive. Refer http://www.sphinx-doc.org/en/master/usage/extensions/index.html to add a custom directive to your Sphinx project.

Post a Comment for "Substitution In A File Name With Restructuredtext (sphinx)?"