From a65b333c87fa5fdd993cd3f4a66e69da35eab261 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 2 Feb 2021 01:17:56 +0900 Subject: [PATCH] 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. --- CHANGES | 1 + sphinx/ext/todo.py | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 42311e782..ac00be6c8 100644 --- a/CHANGES +++ b/CHANGES @@ -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 diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py index 640c93935..a73dea84d 100644 --- a/sphinx/ext/todo.py +++ b/sphinx/ext/todo.py @@ -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.