chiark / gitweb /
Fix service file to match installed elogind binary location
[elogind.git] / tools / make-man-index.py
1 #!/usr/bin/env python3
2 #  -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
3 #
4 #  This file is part of systemd.
5 #
6 #  Copyright 2012 Lennart Poettering
7 #  Copyright 2013 Zbigniew Jędrzejewski-Szmek
8 #
9 #  systemd is free software; you can redistribute it and/or modify it
10 #  under the terms of the GNU Lesser General Public License as published by
11 #  the Free Software Foundation; either version 2.1 of the License, or
12 #  (at your option) any later version.
13 #
14 #  systemd is distributed in the hope that it will be useful, but
15 #  WITHOUT ANY WARRANTY; without even the implied warranty of
16 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 #  Lesser General Public License for more details.
18 #
19 #  You should have received a copy of the GNU Lesser General Public License
20 #  along with systemd; If not, see <http://www.gnu.org/licenses/>.
21
22 import collections
23 import sys
24 import re
25 from xml_helper import *
26
27 MDASH = ' — ' if sys.version_info.major >= 3 else ' -- '
28
29 TEMPLATE = '''\
30 <refentry id="elogind.index" conditional="HAVE_PYTHON">
31
32   <refentryinfo>
33     <title>elogind.index</title>
34     <productname>elogind</productname>
35
36     <authorgroup>
37       <author>
38         <contrib>Developer</contrib>
39         <firstname>Lennart</firstname>
40         <surname>Poettering</surname>
41         <email>lennart@poettering.net</email>
42       </author>
43     </authorgroup>
44   </refentryinfo>
45
46   <refmeta>
47     <refentrytitle>elogind.index</refentrytitle>
48     <manvolnum>7</manvolnum>
49   </refmeta>
50
51   <refnamediv>
52     <refname>elogind.index</refname>
53     <refpurpose>List all manpages from the elogind project</refpurpose>
54   </refnamediv>
55 </refentry>
56 '''
57
58 SUMMARY = '''\
59   <refsect1>
60     <title>See Also</title>
61     <para>
62       <citerefentry><refentrytitle>elogind.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>
63     </para>
64
65     <para id='counts' />
66   </refsect1>
67 '''
68
69 COUNTS = '\
70 This index contains {count} entries, referring to {pages} individual manual pages.'
71
72
73 def check_id(page, t):
74     id = t.getroot().get('id')
75     if not re.search('/' + id + '[.]', page):
76         raise ValueError("id='{}' is not the same as page name '{}'".format(id, page))
77
78 def make_index(pages):
79     index = collections.defaultdict(list)
80     for p in pages:
81         t = xml_parse(p)
82         check_id(p, t)
83         section = t.find('./refmeta/manvolnum').text
84         refname = t.find('./refnamediv/refname').text
85         purpose = ' '.join(t.find('./refnamediv/refpurpose').text.split())
86         for f in t.findall('./refnamediv/refname'):
87             infos = (f.text, section, purpose, refname)
88             index[f.text[0].upper()].append(infos)
89     return index
90
91 def add_letter(template, letter, pages):
92     refsect1 = tree.SubElement(template, 'refsect1')
93     title = tree.SubElement(refsect1, 'title')
94     title.text = letter
95     para = tree.SubElement(refsect1, 'para')
96     for info in sorted(pages, key=lambda info: str.lower(info[0])):
97         refname, section, purpose, realname = info
98
99         b = tree.SubElement(para, 'citerefentry')
100         c = tree.SubElement(b, 'refentrytitle')
101         c.text = refname
102         d = tree.SubElement(b, 'manvolnum')
103         d.text = section
104
105         b.tail = MDASH + purpose # + ' (' + p + ')'
106
107         tree.SubElement(para, 'sbr')
108
109 def add_summary(template, indexpages):
110     count = 0
111     pages = set()
112     for group in indexpages:
113         count += len(group)
114         for info in group:
115             refname, section, purpose, realname = info
116             pages.add((realname, section))
117
118     refsect1 = tree.fromstring(SUMMARY)
119     template.append(refsect1)
120
121     para = template.find(".//para[@id='counts']")
122     para.text = COUNTS.format(count=count, pages=len(pages))
123
124 def make_page(*xml_files):
125     template = tree.fromstring(TEMPLATE)
126     index = make_index(xml_files)
127
128     for letter in sorted(index):
129         add_letter(template, letter, index[letter])
130
131     add_summary(template, index.values())
132
133     return template
134
135 if __name__ == '__main__':
136     with open(sys.argv[1], 'wb') as f:
137         f.write(xml_print(make_page(*sys.argv[2:])))