]>
git.ipfire.org Git - thirdparty/systemd.git/blob - tools/make-directive-index.py
2 # SPDX-License-Identifier: LGPL-2.1-or-later
7 from copy
import deepcopy
9 from xml_helper
import tree
, xml_parse
, xml_print
12 This index contains {count} entries in {sections} sections,
13 referring to {pages} individual manual pages.
16 def _extract_directives(directive_groups
, formatting
, page
):
18 section
= t
.find('./refmeta/manvolnum').text
19 pagename
= t
.find('./refmeta/refentrytitle').text
21 storopt
= directive_groups
['options']
22 for variablelist
in t
.iterfind('.//variablelist'):
23 klass
= variablelist
.attrib
.get('class')
24 searchpath
= variablelist
.attrib
.get('xpath','./varlistentry/term/varname')
25 storvar
= directive_groups
[klass
or 'miscellaneous']
26 # <option>s go in OPTIONS, unless class is specified
27 for xpath
, stor
in ((searchpath
, storvar
),
28 ('./varlistentry/term/option',
29 storvar
if klass
else storopt
)):
30 for name
in variablelist
.iterfind(xpath
):
31 text
= re
.sub(r
'([= ]).*', r
'\1', name
.text
).rstrip()
32 if text
.startswith('-'):
33 # for options, merge options with and without mandatory arg
34 text
= text
.partition('=')[0]
35 stor
[text
].append((pagename
, section
))
36 if text
not in formatting
:
37 # use element as formatted display
38 if name
.text
[-1] in "= '":
43 formatting
[text
] = name
44 extra
= variablelist
.attrib
.get('extra-ref')
46 stor
[extra
].append((pagename
, section
))
47 if extra
not in formatting
:
48 elt
= tree
.Element("varname")
50 formatting
[extra
] = elt
52 storfile
= directive_groups
['filenames']
53 for xpath
, absolute_only
in (('.//refsynopsisdiv//filename', False),
54 ('.//refsynopsisdiv//command', False),
55 ('.//filename', True)):
56 for name
in t
.iterfind(xpath
):
57 if absolute_only
and not (name
.text
and name
.text
.startswith('/')):
59 if name
.attrib
.get('index') == 'false':
63 if name
.text
.endswith('*'):
64 name
.text
= name
.text
[:-1]
65 if not name
.text
.startswith('.'):
66 text
= name
.text
.partition(' ')[0]
70 if text
.endswith('/'):
72 storfile
[text
].append((pagename
, section
))
73 if text
not in formatting
:
74 # use element as formatted display
75 formatting
[text
] = name
77 text
= ' '.join(name
.itertext())
78 storfile
[text
].append((pagename
, section
))
79 formatting
[text
] = name
81 for name
in t
.iterfind('.//constant'):
82 if name
.attrib
.get('index') == 'false':
85 if name
.text
.startswith('('): # a cast, strip it
86 name
.text
= name
.text
.partition(' ')[2]
87 klass
= name
.attrib
.get('class') or 'constants'
88 storfile
= directive_groups
[klass
]
89 storfile
[name
.text
].append((pagename
, section
))
90 formatting
[name
.text
] = name
92 storfile
= directive_groups
['specifiers']
93 for name
in t
.iterfind(".//table[@class='specifiers']//entry/literal"):
94 if name
.text
[0] != '%' or name
.getparent().text
is not None:
96 if name
.attrib
.get('index') == 'false':
98 storfile
[name
.text
].append((pagename
, section
))
99 formatting
[name
.text
] = name
100 for name
in t
.iterfind(".//literal[@class='specifiers']"):
101 storfile
[name
.text
].append((pagename
, section
))
102 formatting
[name
.text
] = name
104 def _make_section(template
, name
, directives
, formatting
):
105 varlist
= template
.find(f
".//*[@id='{name}']")
106 for varname
, manpages
in sorted(directives
.items()):
107 entry
= tree
.SubElement(varlist
, 'varlistentry')
108 term
= tree
.SubElement(entry
, 'term')
109 display
= deepcopy(formatting
[varname
])
112 para
= tree
.SubElement(tree
.SubElement(entry
, 'listitem'), 'para')
115 for manpage
, manvolume
in sorted(set(manpages
)):
118 b
= tree
.SubElement(para
, 'citerefentry')
119 c
= tree
.SubElement(b
, 'refentrytitle')
121 c
.attrib
['target'] = varname
122 d
= tree
.SubElement(b
, 'manvolnum')
126 def _make_colophon(template
, groups
):
131 for pagelist
in group
.values():
132 pages |
= set(pagelist
)
134 para
= template
.find(".//para[@id='colophon']")
135 para
.text
= COLOPHON
.format(count
=count
,
136 sections
=len(groups
),
139 def _make_page(template
, directive_groups
, formatting
):
140 """Create an XML tree from directive_groups.
143 'class': {'variable': [('manpage', 'manvolume'), ...],
148 for name
, directives
in directive_groups
.items():
149 _make_section(template
, name
, directives
, formatting
)
151 _make_colophon(template
, directive_groups
.values())
155 def make_page(template_path
, xml_files
):
156 "Extract directives from xml_files and return XML index tree."
157 template
= xml_parse(template_path
)
158 names
= [vl
.get('id') for vl
in template
.iterfind('.//variablelist')]
159 directive_groups
= {name
:collections
.defaultdict(list)
162 for page
in xml_files
:
164 _extract_directives(directive_groups
, formatting
, page
)
165 except Exception as e
:
166 raise ValueError("failed to process " + page
) from e
168 return _make_page(template
, directive_groups
, formatting
)
170 if __name__
== '__main__':
171 with
open(sys
.argv
[1], 'wb') as f
:
172 _template_path
= sys
.argv
[2]
173 _xml_files
= sys
.argv
[3:]
174 _xml
= make_page(_template_path
, _xml_files
)
175 f
.write(xml_print(_xml
))