summaryrefslogtreecommitdiff
path: root/doc/ext/nova_todo.py
blob: eb5335cb2002cd6e8a46c069daab8c635fb95d20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# This is a hack of the builtin todo extension, to make the todo_list
# more user friendly.

import re

from sphinx.ext.todo import depart_todo_node
from sphinx.ext.todo import NoUri
from sphinx.ext.todo import nodes
from sphinx.ext.todo import process_todos
from sphinx.ext.todo import purge_todos
from sphinx.ext.todo import Todo
from sphinx.ext.todo import TodoList
from sphinx.ext.todo import todolist
from sphinx.ext.todo import todo_node
from sphinx.ext.todo import visit_todo_node


def _(s):
    return s


def process_todo_nodes(app, doctree, fromdocname):
    if not app.config['todo_include_todos']:
        for node in doctree.traverse(todo_node):
            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

    if not hasattr(env, 'todo_all_todos'):
        env.todo_all_todos = []

    # remove the item that was added in the constructor, since I'm tired of
    # reading through docutils for the proper way to construct an empty list
    lists = []
    for i in range(5):
        lists.append(nodes.bullet_list("", nodes.Text('', '')))
        lists[i].remove(lists[i][0])
        lists[i]['classes'].append('todo_list')

    for node in doctree.traverse(todolist):
        if not app.config['todo_include_todos']:
            node.replace_self([])
            continue

        for todo_info in env.todo_all_todos:
            para = nodes.paragraph()
            # Create a reference
            newnode = nodes.reference('', '')

            filename = env.doc2path(todo_info['docname'], base=None)
            link = (_('%(filename)s, line %(line_info)d') %
                     {'filename': filename, 'line_info': todo_info['lineno']})

            innernode = nodes.emphasis(link, link)
            newnode['refdocname'] = todo_info['docname']

            try:
                newnode['refuri'] = app.builder.get_relative_uri(
                    fromdocname, todo_info['docname'])
                newnode['refuri'] += '#' + todo_info['target']['refid']
            except NoUri:
                # ignore if no URI can be determined, e.g. for LaTeX output
                pass

            newnode.append(innernode)
            para += newnode
            para['classes'].append('todo_link')

            todo_entry = todo_info['todo']

            env.resolve_references(todo_entry, todo_info['docname'],
                                   app.builder)

            item = nodes.list_item('', para)
            todo_entry[1]['classes'].append('details')

            comment = todo_entry[1]

            m = re.match(r"^P(\d)", comment.astext())
            priority = 5
            if m:
                priority = int(m.group(1))
                if priority < 0:
                    priority = 1
                if priority > 5:
                    priority = 5

            item['classes'].append('todo_p' + str(priority))
            todo_entry['classes'].append('todo_p' + str(priority))

            item.append(comment)

            lists[priority - 1].insert(0, item)

        node.replace_self(lists)


def setup(app):
    app.add_config_value('todo_include_todos', False, False)

    app.add_node(todolist)
    app.add_node(todo_node,
                 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', Todo)
    app.add_directive('todolist', TodoList)
    app.connect('doctree-read', process_todos)
    app.connect('doctree-resolved', process_todo_nodes)
    app.connect('env-purge-doc', purge_todos)