reStructured Text(Sphinx):文件名中的替换?

时间:2013-12-11 08:21:57

标签: python-sphinx restructuredtext

我想从单个模板创建多个文件,这些文件只有变量名称不同。例如:

(file1.rst):

.. |variable| replace:: 1
.. include template.rst

(template.rst):

Variable |variable|
=====================

Image
-------

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

当然我有一个名为“./images/1-image.png”的图像。替换“|变量|” “1”在标题中运行良好,但不在图像文件名中,在编译时我得到:

WARNING: image file not readable: ./images/|variable|-image.png

如何让reST在变量名中进行替换呢? (如果这改变了什么,我正在使用Sphinx)。

2 个答案:

答案 0 :(得分:9)

这里有两个问题:替换问题和解析顺序问题。

对于第一个问题,替换引用 |variable|不能包含相邻的字符(除了空格或可能_用于超链接),否则它不会被解析为替换引用,所以你需要逃避它:

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

然而,第二个问题即将来临。虽然我不确定细节,但似乎reST无法解析其他指令中的替换。我认为它首先解析image指令,它将它放在文档树中,因此超出了替换机制的范围。同样,我也不认为可以使用替换来插入要解析的内容(例如.. |img1| replace::`.. image:: images/1-image.png`)。这是基于一些测试和我对official documentation的不完全理解的所有推测,所以更有知识的人可以纠正我在这里所说的。

我认为你已经意识到实际的图像替换指令(而不是文本替换),但我认为它不会达到你所瞄准的普遍性(你会这样做)仍然需要一个单独的图像指令作为|变量|),但无论如何它看起来像这样:

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

由于您正在使用Sphinx,您可以尝试创建自己的指令扩展(请参阅this answer获取信息),但它不会解决替换内部标记问题。

答案 1 :(得分:0)

在这种情况下,您必须创建一个自定义指令,因为Sphinx不允许您替换图像路径。您可以按以下方式更改Sphinx Figure指令,并使用它代替image指令。

from typing import Any, Dict, List, Tuple
from 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

if False:
    # For type annotation
    from sphinx.application import Sphinx


class CustomFigure(images.Figure):
    """The figure directive which applies `:name:` option to the figure node
    instead of the image node.
    """

    def run(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()
        if len(result) == 2 or isinstance(result[0], nodes.system_message):
            return result

        assert len(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 node
        if figure_node.line is None and len(figure_node) == 2:
            caption = cast(nodes.caption, figure_node[1])
            figure_node.line = caption.line

        return [figure_node]


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

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

您可以在项目的conf.py中添加此CustomFigure.py指令,并在整个Sphinx项目中使用customfigure指令,而不是Image指令。请参考http://www.sphinx-doc.org/en/master/usage/extensions/index.html向您的Sphinx项目添加自定义指令。