ReStructured Text (Sphinx): замена в имени файла?
Я хочу создать несколько файлов из одного шаблона, которые отличаются только именем переменной. Например:
(file1.rst):
.. |variable| replace:: 1
.. include template.rst
(template.rst):
Variable |variable|
=====================
Image
-------
.. image:: ./images/|variable|-image.png
где, конечно, у меня есть изображение под названием "./images/1-image.png". Подстановка "| variable |" по "1" хорошо работает в названии, но не в имени файла изображения, а при компиляции я получаю:
WARNING: image file not readable: ./images/|variable|-image.png
Как я могу получить reST, чтобы сделать замену в имени переменной? (если это что-то меняет, я использую Sphinx).
Ответы
Ответ 1
Здесь есть две проблемы: проблема замещения и проблема с порядком разбора.
Для первой проблемы ссылка на замену |variable|
не может содержать соседние символы (кроме пробелов или, возможно, _ для гиперссылки), иначе она не будет анализироваться как ссылка на замену, поэтому вам нужно ее избежать:
./images/\ |variable|\ -image.png
Тем не менее, вторая проблема ждет за углом. Хотя я не уверен в деталях, кажется, что reST не может разобрать замены внутри других директив. Я думаю, что сначала он анализирует директиву изображения, которая помещает ее в дерево документа и, таким образом, выходит за пределы механизма замены. Точно так же я не думаю, что возможно использовать замену для вставки содержимого, предназначенного для анализа (например, .. |img1| replace::'.. image:: images/1-image.png'
). Это все предположения, основанные на некоторых тестах и моем неполном понимании официальной документации, так что кто-то более знающий может исправить то, что я сказал здесь.
Я думаю, что вы знаете о действительной директиве замены изображения (в отличие от замены текста), но я не думаю, что она достигает общности, к которой вы стремитесь (вам все равно понадобится отдельная директива для изображения, как от | variable |), но в любом случае это выглядит так:
.. |img1| image:: images/1-image.png
Поскольку вы используете Sphinx, вы можете попробовать создать собственное расширение директивы (см. этот ответ для получения информации), но это не решит проблему подстановок внутри разметки.
Ответ 2
В этом случае вы должны создать пользовательскую директиву, так как 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,
}
Вы можете добавить эту директиву CustomFigure.py в conf.py проекта и использовать директиву customfigure в проекте Sphinx вместо директивы Image. Обратитесь http://www.sphinx-doc.org/en/master/usage/extensions/index.html, чтобы добавить пользовательскую директиву в ваш проект Sphinx.