Created
March 22, 2015 21:55
-
-
Save lisitsyn/a885cd193a4b1b7fae79 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def setup(app): | |
app.add_config_value('todo_include_todos', False, False) | |
app.add_node(todolist) | |
app.add_node(todo, | |
html=(visit_todo_node, depart_todo_node), | |
latex=(visit_todo_node, depart_todo_node), | |
text=(visit_todo_node, depart_todo_node)) | |
app.add_directive('todo', TodoDirective) | |
app.add_directive('todolist', TodolistDirective) | |
app.connect('doctree-resolved', process_todo_nodes) | |
app.connect('env-purge-doc', purge_todos) | |
return {'version': '0.1'} # identifies the version of our extension | |
from docutils import nodes | |
class todo(nodes.Admonition, nodes.Element): | |
pass | |
class todolist(nodes.General, nodes.Element): | |
pass | |
def visit_todo_node(self, node): | |
self.visit_admonition(node) | |
def depart_todo_node(self, node): | |
self.depart_admonition(node) | |
from docutils.parsers.rst import Directive | |
class TodolistDirective(Directive): | |
def run(self): | |
return [todolist('')] | |
from sphinx.util.compat import make_admonition | |
from sphinx.locale import _ | |
class TodoDirective(Directive): | |
# this enables content in the directive | |
has_content = True | |
def run(self): | |
env = self.state.document.settings.env | |
targetid = "todo-%d" % env.new_serialno('todo') | |
targetnode = nodes.target('', '', ids=[targetid]) | |
ad = make_admonition(todo, self.name, [_('Todo')], self.options, | |
self.content, self.lineno, self.content_offset, | |
self.block_text, self.state, self.state_machine) | |
if not hasattr(env, 'todo_all_todos'): | |
env.todo_all_todos = [] | |
env.todo_all_todos.append({ | |
'docname': env.docname, | |
'lineno': self.lineno, | |
'todo': ad[0].deepcopy(), | |
'target': targetnode, | |
}) | |
return [targetnode] + ad | |
def purge_todos(app, env, docname): | |
if not hasattr(env, 'todo_all_todos'): | |
return | |
env.todo_all_todos = [todo for todo in env.todo_all_todos | |
if todo['docname'] != docname] | |
def process_todo_nodes(app, doctree, fromdocname): | |
if not app.config.todo_include_todos: | |
for node in doctree.traverse(todo): | |
node.parent.remove(node) | |
# Replace all todolist nodes with a list of the collected todos. | |
# Augment each todo with a backlink to the original location. | |
env = app.builder.env | |
for node in doctree.traverse(todolist): | |
if not app.config.todo_include_todos: | |
node.replace_self([]) | |
continue | |
content = [] | |
for todo_info in env.todo_all_todos: | |
para = nodes.paragraph() | |
filename = env.doc2path(todo_info['docname'], base=None) | |
description = ( | |
_('(The original entry is located in %s, line %d and can be found ') % | |
(filename, todo_info['lineno'])) | |
para += nodes.Text(description, description) | |
# Create a reference | |
newnode = nodes.reference('', '') | |
innernode = nodes.emphasis(_('here'), _('here')) | |
newnode['refdocname'] = todo_info['docname'] | |
newnode['refuri'] = app.builder.get_relative_uri( | |
fromdocname, todo_info['docname']) | |
newnode['refuri'] += '#' + todo_info['target']['refid'] | |
newnode.append(innernode) | |
para += newnode | |
para += nodes.Text('.)', '.)') | |
# Insert into the todolist | |
content.append(todo_info['todo']) | |
content.append(para) | |
node.replace_self(content) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment