Gentoo Archives: gentoo-commits

From: "Michał Górny" <mgorny@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/policy-guide:master commit in: exts/
Date: Tue, 25 Feb 2020 15:16:09
Message-Id: 1582643723.59a72da360e2eff53ef510261c3f6307148b52dc.mgorny@gentoo
1 commit: 59a72da360e2eff53ef510261c3f6307148b52dc
2 Author: Michał Górny <mgorny <AT> gentoo <DOT> org>
3 AuthorDate: Sat Feb 22 17:15:51 2020 +0000
4 Commit: Michał Górny <mgorny <AT> gentoo <DOT> org>
5 CommitDate: Tue Feb 25 15:15:23 2020 +0000
6 URL: https://gitweb.gentoo.org/proj/policy-guide.git/commit/?id=59a72da3
7
8 Generate a Policy Index
9
10 Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>
11
12 exts/policyident.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++---
13 1 file changed, 75 insertions(+), 3 deletions(-)
14
15 diff --git a/exts/policyident.py b/exts/policyident.py
16 index 6093c8c..7ecc9f2 100644
17 --- a/exts/policyident.py
18 +++ b/exts/policyident.py
19 @@ -2,13 +2,44 @@
20 # (c) 2020 Michał Górny
21 # 2-clause BSD license
22
23 +import collections
24 +
25 from docutils import nodes
26
27 +from sphinx.domains import Index
28 from sphinx.util import logging
29
30
31 logger = logging.getLogger(__name__)
32
33 +Policy = collections.namedtuple('Policy', ('id', 'title', 'docname',
34 + 'chapter'))
35 +
36 +
37 +class PolicyIndex(Index):
38 + name = 'policy-index'
39 + localname = 'Policy Index'
40 + shortname = 'Policy Index'
41 +
42 + def generate(self, docnames=None):
43 + env = self.domain.env
44 + if not hasattr(env, 'policy_index'):
45 + env.policy_index = []
46 +
47 + entries = collections.defaultdict(list)
48 + for p in env.policy_index:
49 + if docnames is not None and p.docname not in docnames:
50 + continue
51 + entries[p.chapter].append(('PG' + p.id, # name
52 + 0, # subtype
53 + p.docname, # docname
54 + 'pg' + p.id, # anchor
55 + p.title, # extra
56 + '', # qualifier
57 + '')) # descr
58 +
59 + return ([(k, sorted(v)) for k, v in entries.items()], False)
60 +
61
62 def find_pg_id(section):
63 # first child should be title
64 @@ -17,7 +48,7 @@ def find_pg_id(section):
65 # second child should be field list
66 cl = section.children[1]
67 if not isinstance(cl, nodes.field_list):
68 - return None
69 + return None, title.astext(), None
70
71 for f in cl.traverse(nodes.field):
72 fn = next(iter(f.traverse(nodes.field_name)))
73 @@ -29,20 +60,61 @@ def find_pg_id(section):
74 if fv.astext() != iv:
75 raise RuntimeError('PG value must be 4 digits, zero-padded ({})'
76 .format(iv))
77 - return iv
78 +
79 + el = section
80 + titles = []
81 + while el.parent is not None:
82 + title = el.children[0]
83 + assert isinstance(title, nodes.title)
84 + titles.append(title.astext())
85 + el = el.parent
86 + # combine all section titles up to but excluding
87 + # the chapter title
88 + title = ': '.join(reversed(titles[:-1]))
89 +
90 + return iv, title, titles[-1]
91
92 logger.warning('%s: no PG identifier found', title.astext())
93 + return None, title.astext(), None
94
95
96 def on_doctree_read(app, doctree):
97 + env = app.builder.env
98 + if not hasattr(env, 'policy_index'):
99 + env.policy_index = []
100 +
101 for node in doctree.traverse(nodes.section):
102 - pg_id = find_pg_id(node)
103 + pg_id, title, chapter = find_pg_id(node)
104 if pg_id is not None:
105 node['ids'].insert(0, 'pg' + pg_id)
106 + env.policy_index.append(Policy(pg_id, title, env.docname,
107 + chapter))
108 +
109 +
110 +def on_env_purge_doc(app, env, docname):
111 + if not hasattr(env, 'policy_index'):
112 + return
113 +
114 + env.policy_index = [p for p in env.policy_index
115 + if p.docname != docname]
116 +
117 +
118 +def on_env_merge_info(app, env, docnames, other):
119 + if not hasattr(other, 'policy_index'):
120 + return
121 + if not hasattr(env, 'policy_index'):
122 + env.policy_index = []
123 +
124 + env.policy_index.extend(other.policy_index)
125
126
127 def setup(app):
128 app.connect('doctree-read', on_doctree_read)
129 + app.connect('env-purge-doc', on_env_purge_doc)
130 + app.connect('env-merge-info', on_env_merge_info)
131 + app.add_index_to_domain('std', PolicyIndex)
132 return {
133 'version': '0',
134 + 'parallel_read_safe': True,
135 + 'parallel_write_safe': True,
136 }