Объявить дополнительную зависимость от sphinx-build в расширении

TL,DR: Из расширения Sphinx, как я могу указать sphinx-build рассматривать дополнительный файл как зависимость? В моем непосредственном случае использования это исходный код расширения, но вопрос в равной степени может относиться к некоторому вспомогательному файлу, используемому расширением.

Я создаю документацию с помощью Sphinx, используя собственное расширение. Я использую sphinx-build для создания документации. Например, я использую эту команду для создания HTML (это команда в make-файле, сгенерированном sphinx-quickstart):

sphinx-build -b html -d _build/doctrees   . _build/html

Поскольку мое пользовательское расширение поддерживается вместе с источником документации, я хочу, чтобы sphinx-build рассматривал его как зависимость сгенерированного HTML (и LaTeX и т. д.). Поэтому всякий раз, когда я изменяю исходный код своего расширения, я хочу, чтобы sphinx-build регенерировал вывод.

Как указать sphinx-build рассматривать дополнительный файл как зависимость? Это не упоминается в toctree, поскольку не является частью исходного кода. По логике, это должно быть чем-то, что я делаю из функции setup моего расширения.


Пример расширения (my_extension.py):

from docutils import nodes
from docutils.parsers.rst import Directive

class Foo(Directive):
    def run(self):
        node = nodes.paragraph(text='Hello world\n')
        return [node]

def setup(app):
    app.add_directive('foo', Foo)

Источник образца (index.rst):

.. toctree::
   :maxdepth: 2

.. foo::

Пример conf.py (в основном вывод sphinx-quickstart плюс мое расширение):

import sys
import os
sys.path.insert(0, os.path.abspath('.'))
extensions = ['my_extension']
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
project = 'Hello directive'
copyright = '2019, Gilles'
author = 'Gilles'
version = '1'
release = '1'
language = None
exclude_patterns = ['_build']
pygments_style = 'sphinx'
todo_include_todos = False
html_theme = 'alabaster'
html_static_path = ['_static']
htmlhelp_basename = 'Hellodirectivedoc'
latex_elements = {
}
latex_documents = [
    (master_doc, 'Hellodirective.tex', 'Hello directive Documentation',
     'Gilles', 'manual'),
]
man_pages = [
    (master_doc, 'hellodirective', 'Hello directive Documentation',
     [author], 1)
]
texinfo_documents = [
    (master_doc, 'Hellodirective', 'Hello directive Documentation',
     author, 'Hellodirective', 'One line description of project.',
     'Miscellaneous'),
]

Проверка решения:

  1. Запустите make html (или sphinx-build, как указано выше).
  2. Измените my_extension.py, заменив Hello world на Hello again.
  3. Запустите make html еще раз.
  4. Сгенерированный HTML (_build/html/index.html) теперь должен содержать Hello again вместо Hello world.

person Gilles 'SO- stop being evil'    schedule 04.02.2019    source источник


Ответы (1)


Это похоже на метод note_dependency в API среды сборки должен делать то, что я хочу. Но когда я должен позвонить? Я перепробовал различные события, но ни одно из них не помогло объект среды в правильном состоянии. Что действительно сработало, так это вызвать его из директивы.

import os
from docutils import nodes
from docutils.parsers.rst import Directive
import sphinx.application

class Foo(Directive):
    def run(self):
        self.state.document.settings.env.note_dependency(__file__)
        node = nodes.paragraph(text='Hello done\n')
        return [node]

def setup(app):
    app.add_directive('foo', Foo)

Если документ содержит хотя бы одну директиву foo, он будет помечен как устаревший при изменении расширения, вводящего эту директиву. Это имеет смысл, хотя может стать утомительным, если расширение добавляет много директив или вносит разные изменения. Я не знаю, есть ли лучший способ.

Вдохновленный autodoc-C Люка Ван Остенрика.

person Gilles 'SO- stop being evil'    schedule 06.02.2019