sphinx-doc / sphinx

The Sphinx documentation generator
https://www.sphinx-doc.org/
Other
6.46k stars 2.1k forks source link

Mark documents as always outdated && Rebuild documents with todolist iff todo item was added/deleted #9706

Open latosha-maltba opened 3 years ago

latosha-maltba commented 3 years ago

Is your feature request related to a problem? Please describe.

I use the sphinx.ext.todo extension and have the .. todolist:: in its own file. The problem is that file is not updated when a .. todo:: item is added in another file.

MWE:

index.rst

.. toctree::

   todolist

.. todo:: Do this first

todolist.rst

Heading, so we don't get a warning
==================================

.. todolist::
sphinx-build -b html . build
sphinx-build -b html . build

The second sphinx-build does nothing, as no changes where made. Add another todo item in index.rst, e.g.

.. toctree::

   todolist

.. todo:: Do this first
.. todo:: Do this second
sphinx-build -b html . build

This build only updates the document index but not the document todolist, thus the todolist is outdated and incompelet showing only one todo item, where there should be shown two.

Describe the solution you'd like

Ideally, the todo extension would remember which documents have a .. todolist:: directive and rebuild those documents once the set of todo items changes.

Describe alternatives you've considered

As a workaround for this it would be nice to have a possibility to mark a document as always outdated. So it gets rebuild every time. This is not so efficitient for the todo list (which might have not changed) but at least its not outdated anymore. Furthermore, other scenarios might profit from that which are not todo related.

Sphinx does not provide the possibility to mark a document as always outdated. However, the following custom directive helps but might have other gotchas:

conf.py

from sphinx.util.docutils import SphinxDirective

class AlwaysOutdated(SphinxDirective):
    def run(self):
        self.env.note_reread()
        return []

def setup(app):
   app.add_directive('always-outdated', AlwaysOutdated)

Use .. always-outdated: in a document to mark it as always outdated. (Not tested how this behaves if documents are included in other documents in various ways.)

todolist.rst

Heading, so we don't get a warning
==================================

.. always-outdated::
.. todolist::

Remark: There are field-lists [1] which provide the a way to mark documents, e.g. :orphan:. Instead of a directive marking them with these kind of metadata would fit well into the current scheme.

Summary

Two things take from the above:

[1] https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html

tk0miya commented 2 years ago

Thank you for reporting. Indeed, it's not undesirable behavior. But it's difficult to rebuild documents only if todo items changed. IMO, a workaround is to rebuild the document having todolist directive always.