chiark / gitweb /
b64ada74e2d1b8fa8b359a85027e7f5cb5a94f27
[elogind.git] / tools / make-man-index.py
1 #!/usr/bin/env python3
2 #  -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
3 # SPDX-License-Identifier: LGPL-2.1+
4 #
5 #  Copyright 2012 Lennart Poettering
6 #  Copyright 2013 Zbigniew Jędrzejewski-Szmek
7
8 import collections
9 import sys
10 import re
11 from xml_helper import xml_parse, xml_print, tree
12
13 MDASH = ' — ' if sys.version_info.major >= 3 else ' -- '
14
15 TEMPLATE = '''\
16 <refentry id="elogind.index" conditional="HAVE_PYTHON">
17
18   <refentryinfo>
19     <title>elogind.index</title>
20     <productname>elogind</productname>
21
22     <authorgroup>
23       <author>
24         <contrib>Developer</contrib>
25         <firstname>Lennart</firstname>
26         <surname>Poettering</surname>
27         <email>lennart@poettering.net</email>
28       </author>
29       <!-- 1 /// Must add elogind authors for the additions and changes -->
30       <author>
31         <contrib>Developer</contrib>
32         <firstname>Sven</firstname>
33         <surname>Eden</surname>
34         <email>sven.eden@gmx.de</email>
35       </author>
36       <!-- // 1 -->
37     </authorgroup>
38   </refentryinfo>
39
40   <refmeta>
41     <refentrytitle>elogind.index</refentrytitle>
42     <manvolnum>7</manvolnum>
43   </refmeta>
44
45   <refnamediv>
46     <refname>elogind.index</refname>
47     <refpurpose>List all manpages from the elogind project</refpurpose>
48   </refnamediv>
49 </refentry>
50 '''
51
52 SUMMARY = '''\
53   <refsect1>
54     <title>See Also</title>
55     <para>
56       <citerefentry><refentrytitle>elogind.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>
57     </para>
58
59     <para id='counts' />
60   </refsect1>
61 '''
62
63 COUNTS = '\
64 This index contains {count} entries, referring to {pages} individual manual pages.'
65
66
67 def check_id(page, t):
68     id = t.getroot().get('id')
69     if not re.search('/' + id + '[.]', page):
70         raise ValueError("id='{}' is not the same as page name '{}'".format(id, page))
71
72 def make_index(pages):
73     index = collections.defaultdict(list)
74     for p in pages:
75         t = xml_parse(p)
76         check_id(p, t)
77         section = t.find('./refmeta/manvolnum').text
78         refname = t.find('./refnamediv/refname').text
79         purpose = ' '.join(t.find('./refnamediv/refpurpose').text.split())
80         for f in t.findall('./refnamediv/refname'):
81             infos = (f.text, section, purpose, refname)
82             index[f.text[0].upper()].append(infos)
83     return index
84
85 def add_letter(template, letter, pages):
86     refsect1 = tree.SubElement(template, 'refsect1')
87     title = tree.SubElement(refsect1, 'title')
88     title.text = letter
89     para = tree.SubElement(refsect1, 'para')
90     for info in sorted(pages, key=lambda info: str.lower(info[0])):
91         refname, section, purpose, realname = info
92
93         b = tree.SubElement(para, 'citerefentry')
94         c = tree.SubElement(b, 'refentrytitle')
95         c.text = refname
96         d = tree.SubElement(b, 'manvolnum')
97         d.text = section
98
99         b.tail = MDASH + purpose # + ' (' + p + ')'
100
101         tree.SubElement(para, 'sbr')
102
103 def add_summary(template, indexpages):
104     count = 0
105     pages = set()
106     for group in indexpages:
107         count += len(group)
108         for info in group:
109             refname, section, purpose, realname = info
110             pages.add((realname, section))
111
112     refsect1 = tree.fromstring(SUMMARY)
113     template.append(refsect1)
114
115     para = template.find(".//para[@id='counts']")
116     para.text = COUNTS.format(count=count, pages=len(pages))
117
118 def make_page(*xml_files):
119     template = tree.fromstring(TEMPLATE)
120     index = make_index(xml_files)
121
122     for letter in sorted(index):
123         add_letter(template, letter, index[letter])
124
125     add_summary(template, index.values())
126
127     return template
128
129 if __name__ == '__main__':
130     with open(sys.argv[1], 'wb') as f:
131         f.write(xml_print(make_page(*sys.argv[2:])))