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