mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
`todo directive now supports :name:` option
This commit is contained in:
1
CHANGES
1
CHANGES
@@ -51,6 +51,7 @@ Features added
|
||||
* Add a helper method ``SphinxDirective.set_source_info()``
|
||||
* #6180: Support ``--keep-going`` with BuildDoc setup command
|
||||
* ``math`` directive now supports ``:class:`` option
|
||||
* todo: ``todo`` directive now supports ``:name:`` option
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
@@ -22,6 +22,7 @@ from sphinx.errors import NoUri
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.nodes import make_refnode
|
||||
from sphinx.util.texescape import tex_escape_map
|
||||
|
||||
if False:
|
||||
@@ -55,6 +56,7 @@ class Todo(BaseAdmonition, SphinxDirective):
|
||||
final_argument_whitespace = False
|
||||
option_spec = {
|
||||
'class': directives.class_option,
|
||||
'name': directives.unchanged,
|
||||
}
|
||||
|
||||
def run(self):
|
||||
@@ -67,13 +69,10 @@ class Todo(BaseAdmonition, SphinxDirective):
|
||||
return [todo]
|
||||
elif isinstance(todo, todo_node):
|
||||
todo.insert(0, nodes.title(text=_('Todo')))
|
||||
self.add_name(todo)
|
||||
self.set_source_info(todo)
|
||||
|
||||
targetid = 'index-%s' % self.env.new_serialno('index')
|
||||
# Stash the target to be retrieved later in latex_visit_todo_node.
|
||||
todo['targetref'] = '%s:%s' % (self.env.docname, targetid)
|
||||
targetnode = nodes.target('', '', ids=[targetid])
|
||||
return [targetnode, todo]
|
||||
self.state.document.note_explicit_target(todo)
|
||||
return [todo]
|
||||
else:
|
||||
raise RuntimeError # never reached here
|
||||
|
||||
@@ -89,20 +88,14 @@ def process_todos(app, doctree):
|
||||
for node in doctree.traverse(todo_node):
|
||||
app.emit('todo-defined', node)
|
||||
|
||||
try:
|
||||
targetnode = node.parent[node.parent.index(node) - 1]
|
||||
if not isinstance(targetnode, nodes.target):
|
||||
raise IndexError
|
||||
except IndexError:
|
||||
targetnode = None
|
||||
newnode = node.deepcopy()
|
||||
del newnode['ids']
|
||||
newnode['ids'] = []
|
||||
env.todo_all_todos.append({ # type: ignore
|
||||
'docname': env.docname,
|
||||
'source': node.source or env.doc2path(env.docname),
|
||||
'lineno': node.line,
|
||||
'todo': newnode,
|
||||
'target': targetnode,
|
||||
'target': node['ids'][0],
|
||||
})
|
||||
|
||||
if env.config.todo_emit_warnings:
|
||||
@@ -167,27 +160,16 @@ def process_todo_nodes(app, doctree, fromdocname):
|
||||
para += nodes.Text(desc1, desc1)
|
||||
|
||||
# Create a reference
|
||||
newnode = nodes.reference('', '', internal=True)
|
||||
innernode = nodes.emphasis(_('original entry'), _('original entry'))
|
||||
try:
|
||||
newnode['refuri'] = app.builder.get_relative_uri(
|
||||
fromdocname, todo_info['docname'])
|
||||
if 'refid' in todo_info['target']:
|
||||
newnode['refuri'] += '#' + todo_info['target']['refid']
|
||||
else:
|
||||
newnode['refuri'] += '#' + todo_info['target']['ids'][0]
|
||||
para += make_refnode(app.builder, fromdocname, todo_info['docname'],
|
||||
todo_info['target'], innernode)
|
||||
except NoUri:
|
||||
# ignore if no URI can be determined, e.g. for LaTeX output
|
||||
pass
|
||||
newnode.append(innernode)
|
||||
para += newnode
|
||||
para += nodes.Text(desc2, desc2)
|
||||
|
||||
todo_entry = todo_info['todo']
|
||||
# Remove targetref from the (copied) node to avoid emitting a
|
||||
# duplicate label of the original entry when we walk this node.
|
||||
if 'targetref' in todo_entry:
|
||||
del todo_entry['targetref']
|
||||
|
||||
# (Recursively) resolve references in the todo content
|
||||
env.resolve_references(todo_entry, todo_info['docname'],
|
||||
@@ -230,12 +212,7 @@ def depart_todo_node(self, node):
|
||||
def latex_visit_todo_node(self, node):
|
||||
# type: (LaTeXTranslator, todo_node) -> None
|
||||
self.body.append('\n\\begin{sphinxadmonition}{note}{')
|
||||
# If this is the original todo node, emit a label that will be referenced by
|
||||
# a hyperref in the todolist.
|
||||
target = node.get('targetref')
|
||||
if target is not None:
|
||||
self.body.append('\\label{%s}' % target)
|
||||
|
||||
self.body.append(self.hypertarget_to(node))
|
||||
title_node = cast(nodes.title, node[0])
|
||||
self.body.append('%s:}' % title_node.astext().translate(tex_escape_map))
|
||||
node.pop(0)
|
||||
|
||||
@@ -107,14 +107,15 @@ def test_todo_valid_link(app, status, warning):
|
||||
# Look for the link to foo. Note that there are two of them because the
|
||||
# source document uses todolist twice. We could equally well look for links
|
||||
# to bar.
|
||||
link = (r'\{\\hyperref\[\\detokenize\{(.*?foo.*?)}]\{\\sphinxcrossref{'
|
||||
link = (r'{\\hyperref\[\\detokenize{(.*?foo.*?)}]{\\sphinxcrossref{'
|
||||
r'\\sphinxstyleemphasis{original entry}}}}')
|
||||
m = re.findall(link, content)
|
||||
assert len(m) == 4
|
||||
target = m[0]
|
||||
|
||||
# Look for the targets of this link.
|
||||
labels = [m for m in re.findall(r'\\label\{([^}]*)}', content) if m == target]
|
||||
labels = re.findall(r'\\label{\\detokenize{([^}]*)}}', content)
|
||||
matched = [l for l in labels if l == target]
|
||||
|
||||
# If everything is correct we should have exactly one target.
|
||||
assert len(labels) == 1
|
||||
assert len(matched) == 1
|
||||
|
||||
Reference in New Issue
Block a user