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