【问题标题】:Substitution in a file name with reStructuredText (Sphinx)?用reStructuredText(Sphinx)替换文件名?
【发布时间】:2013-12-29 02:54:25
【问题描述】:

我想从一个模板创建多个文件,它们的区别仅在于变量名。例如:

(file1.rst):

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

(模板.rst):

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

Image
-------

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

我当然有一个名为“./images/1-image.png”的图像。 “|变量|”的替换by "1" 在标题中效果很好,但在图像文件名中效果不佳,并且在编译时我得到:

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

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

【问题讨论】:

    标签: python-sphinx substitution restructuredtext


    【解决方案1】:

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

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

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

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

    我认为您知道实际的图像替换指令(与文本替换相反),但我认为它没有达到您的目标通用性(您仍然需要一个单独的图像指令从|变量|),但无论如何它看起来像这样:

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

    由于您使用的是 Sphinx,您可以尝试创建自己的指令扩展(有关信息,请参阅 this answer),但它不能解决替代标记问题。

    【讨论】:

    • 所以,简而言之,您告诉我没有简单的方法可以做到这一点......我真的不知道如何绕过这个解析顺序问题。这太糟糕了,因为它限制了 reST 的模板可能性。我最终决定使用复制 reST 代码的 Python 脚本进行替换。它很难看,但效果很好。无论如何,谢谢!
    【解决方案2】:

    在这种情况下,您必须创建自定义指令,因为 Sphinx 不允许您替换图像路径。您可以如下更改 Sphinx 图形指令并使用它来代替图像指令。

    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 项目添加自定义指令。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-03
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      • 2014-06-11
      相关资源
      最近更新 更多