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 * #7118: sphinx-quickstart: questionare got Mojibake if libreadline unavailable
* #8094: texinfo: image files on the different directory with document are not * #8094: texinfo: image files on the different directory with document are not
copied copied
* #8782: todo: Cross references in todolist get broken
* #8720: viewcode: module pages are generated for epub on incremental build * #8720: viewcode: module pages are generated for epub on incremental build
* #8704: viewcode: anchors are generated in incremental build after singlehtml * #8704: viewcode: anchors are generated in incremental build after singlehtml
* #8756: viewcode: highlighted code is generated even if not referenced * #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 from docutils.parsers.rst.directives.admonitions import BaseAdmonition
import sphinx import sphinx
from sphinx import addnodes
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.domains import Domain from sphinx.domains import Domain
@ -153,12 +154,12 @@ class TodoListProcessor:
self.config = app.config self.config = app.config
self.env = app.env self.env = app.env
self.domain = cast(TodoDomain, app.env.get_domain('todo')) self.domain = cast(TodoDomain, app.env.get_domain('todo'))
self.document = new_document('')
self.process(doctree, docname) self.process(doctree, docname)
def process(self, doctree: nodes.document, docname: str) -> None: def process(self, doctree: nodes.document, docname: str) -> None:
todos = sum(self.domain.todos.values(), []) # type: List[todo_node] todos = sum(self.domain.todos.values(), []) # type: List[todo_node]
document = new_document('')
for node in doctree.traverse(todolist): for node in doctree.traverse(todolist):
if not self.config.todo_include_todos: if not self.config.todo_include_todos:
node.parent.remove(node) node.parent.remove(node)
@ -174,12 +175,7 @@ class TodoListProcessor:
new_todo = todo.deepcopy() new_todo = todo.deepcopy()
new_todo['ids'].clear() new_todo['ids'].clear()
# (Recursively) resolve references in the todo content self.resolve_reference(new_todo, docname)
#
# 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)
content.append(new_todo) content.append(new_todo)
todo_ref = self.create_todo_reference(todo, docname) todo_ref = self.create_todo_reference(todo, docname)
@ -215,6 +211,17 @@ class TodoListProcessor:
return para 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: def process_todo_nodes(app: Sphinx, doctree: nodes.document, fromdocname: str) -> None:
"""Replace all todolist nodes with a list of the collected todos. """Replace all todolist nodes with a list of the collected todos.