Fix #8782: todo: Cross references in todolist get broken

On resolving cross reference nodes in todolist, some of them get broken
because todo extension does not rewrite the "refdoc" attribute of them.
This commit is contained in:
Takeshi KOMIYA 2021-02-02 01:17:56 +09:00
parent 2956f19674
commit a65b333c87
2 changed files with 15 additions and 7 deletions

View File

@ -98,6 +98,7 @@ Bugs fixed
* #7118: sphinx-quickstart: questionare got Mojibake if libreadline unavailable
* #8094: texinfo: image files on the different directory with document are not
copied
* #8782: todo: Cross references in todolist get broken
* #8720: viewcode: module pages are generated for epub on incremental build
* #8704: viewcode: anchors are generated in incremental build after singlehtml
* #8756: viewcode: highlighted code is generated even if not referenced

View File

@ -20,6 +20,7 @@ from docutils.parsers.rst import directives
from docutils.parsers.rst.directives.admonitions import BaseAdmonition
import sphinx
from sphinx import addnodes
from sphinx.application import Sphinx
from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.domains import Domain
@ -153,12 +154,12 @@ class TodoListProcessor:
self.config = app.config
self.env = app.env
self.domain = cast(TodoDomain, app.env.get_domain('todo'))
self.document = new_document('')
self.process(doctree, docname)
def process(self, doctree: nodes.document, docname: str) -> None:
todos = sum(self.domain.todos.values(), []) # type: List[todo_node]
document = new_document('')
for node in doctree.traverse(todolist):
if not self.config.todo_include_todos:
node.parent.remove(node)
@ -174,12 +175,7 @@ class TodoListProcessor:
new_todo = todo.deepcopy()
new_todo['ids'].clear()
# (Recursively) resolve references in the todo content
#
# Note: To resolve references, it is needed to wrap it with document node
document += new_todo
self.env.resolve_references(document, todo['docname'], self.builder)
document.remove(new_todo)
self.resolve_reference(new_todo, docname)
content.append(new_todo)
todo_ref = self.create_todo_reference(todo, docname)
@ -215,6 +211,17 @@ class TodoListProcessor:
return para
def resolve_reference(self, todo: todo_node, docname: str) -> None:
"""Resolve references in the todo content."""
for node in todo.traverse(addnodes.pending_xref):
if 'refdoc' in node:
node['refdoc'] = docname
# Note: To resolve references, it is needed to wrap it with document node
self.document += todo
self.env.resolve_references(self.document, docname, self.builder)
self.document.remove(todo)
def process_todo_nodes(app: Sphinx, doctree: nodes.document, fromdocname: str) -> None:
"""Replace all todolist nodes with a list of the collected todos.