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