Skip to content

Commit 711c4d8

Browse files
ulfalizercarlescufi
authored andcommitted
doc: genrest: Support customizing the description on index pages
Extend the specifications passed to --modules to add the form <title>:<suffix>:<path>:<index description filename> <index description filename> points to a file that contains RST that is inserted at the top of the index page. If no filename is passed, the old default description is used. Also add three flags --top-index-desc, --non-module-index-desc, and --all-index-desc for customizing the text at the top of non-module index pages. This functionality is currently unused in Zephyr, but will probably be used later. It's being added for a downstream project. Signed-off-by: Ulf Magnusson <[email protected]>
1 parent 35eb46c commit 711c4d8

File tree

1 file changed

+127
-43
lines changed

1 file changed

+127
-43
lines changed

doc/scripts/genrest.py

Lines changed: 127 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ def main():
6767
if modules:
6868
write_module_index_pages()
6969
else:
70-
write_sym_index_page(kconf.unique_defined_syms, None, None)
70+
write_index_page(kconf.unique_defined_syms, None, None,
71+
desc_from_file(top_index_desc))
7172

7273
# Write symbol pages
7374
if os.getenv("KCONFIG_TURBO_MODE") == "1":
@@ -89,9 +90,13 @@ def init():
8990
# Title for index of non-module symbols, as passed via
9091
# --non-module-title
9192
#
93+
# top_index_desc/non_module_index_desc/all_index_desc:
94+
# Set to the corresponding command-line arguments (or None if
95+
# missing)
96+
#
9297
# modules:
93-
# A list of (<title>, <suffix>, <path>) tuples. See the --modules
94-
# argument. Empty if --modules wasn't passed.
98+
# A list of (<title>, <suffix>, <path>, <index description>) tuples. See
99+
# the --modules argument. Empty if --modules wasn't passed.
95100
#
96101
# <path> is an absolute pathlib.Path instance, which is handy for robust
97102
# path comparisons.
@@ -102,6 +107,9 @@ def init():
102107
global kconf
103108
global out_dir
104109
global non_module_title
110+
global top_index_desc
111+
global non_module_index_desc
112+
global all_index_desc
105113
global modules
106114
global strip_module_paths
107115

@@ -110,21 +118,31 @@ def init():
110118
kconf = kconfiglib.Kconfig(args.kconfig)
111119
out_dir = args.out_dir
112120
non_module_title = args.non_module_title
121+
top_index_desc = args.top_index_desc
122+
non_module_index_desc = args.non_module_index_desc
123+
all_index_desc = args.all_index_desc
113124
strip_module_paths = args.strip_module_paths
114125

115126
modules = []
116-
for title_suffix_path in args.modules:
117-
if title_suffix_path.count(":") < 2:
127+
for module_spec in args.modules:
128+
if module_spec.count(":") == 2:
129+
title, suffix, path_s = module_spec.split(":")
130+
index_text = DEFAULT_INDEX_DESCRIPTION
131+
elif module_spec.count(":") == 3:
132+
title, suffix, path_s, index_text_fname = module_spec.split(":")
133+
index_text = desc_from_file(index_text_fname)
134+
else:
118135
sys.exit("error: --modules argument '{}' should have the format "
119-
"'<title>:<suffix>:<path>'".format(title_suffix_path))
120-
title, suffix, path_s = title_suffix_path.split(":", 2)
136+
"<title>:<suffix>:<path> or the format "
137+
"<title>:<suffix>:<path>:<index description filename>"
138+
.format(module_spec))
121139

122140
path = pathlib.Path(path_s).resolve()
123141
if not path.exists():
124142
sys.exit("error: path '{}' in --modules argument does not exist"
125143
.format(path))
126144

127-
modules.append((title, suffix, path))
145+
modules.append((title, suffix, path, index_text))
128146

129147

130148
def parse_args():
@@ -146,23 +164,57 @@ def parse_args():
146164
default="Zephyr",
147165
help="""\
148166
The title used for the index page that lists the symbols
149-
that do not appear in any module. Only meaningful in
150-
combination with --module.""")
167+
that do not appear in any module (index-main.rst). Only
168+
meaningful in --modules mode.""")
169+
170+
parser.add_argument(
171+
"--top-index-desc",
172+
metavar="FILE",
173+
help="""\
174+
Path to an RST file with description text for the top-level
175+
index.rst index page. If missing, a generic description will
176+
be used. Used both in --modules and non-modules mode.
177+
178+
See <index description filename> in the --modules
179+
description as well.""")
180+
181+
parser.add_argument(
182+
"--non-module-index-desc",
183+
metavar="FILE",
184+
help="""\
185+
Like --top-index-desc, but for the index page that lists the
186+
non-module symbols in --modules mode (index-main.rst).""")
187+
188+
parser.add_argument(
189+
"--all-index-desc",
190+
metavar="FILE",
191+
help="""\
192+
Like --top-index-desc, but for the index page that lists all
193+
symbols in --modules mode (index-all.rst).""")
151194

152195
parser.add_argument(
153196
"--modules",
154-
metavar="TITLE_SUFFIX_PATH",
197+
metavar="MODULE_SPECIFICATION",
155198
nargs="+",
156199
default=[],
157200
help="""\
158-
Used to split the documentation into several index pages
159-
based on where symbols are defined. Contains a list of
160-
<title>:<suffix>:<path> tuples.
161-
162-
A separate index-<suffix>.rst page is generated for each
163-
tuple, with the title "<title> Configuration Options", a
164-
'configuration_options_<suffix>' RST link target, and links
165-
to all symbols that appear under the tuple's <path>
201+
Used to split the documentation into several index pages,
202+
based on where symbols are defined.
203+
204+
MODULE_SPECIFICATION is either a <title>:<suffix>:<path>
205+
tuple or a
206+
<title>:<suffix>:<path>:<index description filename> tuple.
207+
If the second form is used, <index description filename>
208+
should be the path to an RST file, the contents of which
209+
will appear on the index page that lists the symbols for the
210+
module (under an automatically-inserted Overview heading).
211+
If the first form is used, a generic description will be
212+
used instead.
213+
214+
A separate index-<suffix>.rst index page is generated for
215+
each tuple, with the title "<title> Configuration Options",
216+
a 'configuration_options_<suffix>' RST link target, and
217+
links to all symbols that appear under the tuple's <path>
166218
(possibly more than one level deep). Symbols that do not
167219
appear in any module are added to index-main.rst.
168220
@@ -199,43 +251,45 @@ def parse_args():
199251
def write_module_index_pages():
200252
# Generate all index pages. Passing --modules will generate more than one.
201253

254+
write_toplevel_index()
255+
202256
# Maps each module title to a set of Symbols in the module
203257
module2syms = collections.defaultdict(set)
204258
# Symbols that do not appear in any module
205-
nonmodule_syms = set()
259+
non_module_syms = set()
206260

207261
for sym in kconf.unique_defined_syms:
208262
# Loop over all definition locations
209263
for node in sym.nodes:
210264
mod_title = path2module(node.filename)
211265

212266
if mod_title is None:
213-
nonmodule_syms.add(node.item)
267+
non_module_syms.add(node.item)
214268
else:
215269
module2syms[mod_title].add(node.item)
216270

217-
write_toplevel_index()
218-
219271
# Write the index-main.rst index page, which lists the symbols that aren't
220272
# from a module
221-
write_sym_index_page(nonmodule_syms, non_module_title, "main")
273+
write_index_page(non_module_syms, non_module_title, "main",
274+
desc_from_file(non_module_index_desc))
222275

223276
# Write the index-<suffix>.rst index pages, which list symbols from
224277
# modules. Iterate 'modules' instead of 'module2syms' so that an index page
225278
# gets written even if a module has no symbols, for consistency.
226-
for title, suffix, _ in modules:
227-
write_sym_index_page(module2syms[title], title, suffix)
279+
for title, suffix, _, text in modules:
280+
write_index_page(module2syms[title], title, suffix, text)
228281

229282
# Write the index-all.rst index page, which lists all symbols, including
230283
# both module and non-module symbols
231-
write_sym_index_page(kconf.unique_defined_syms, "All", "all")
284+
write_index_page(kconf.unique_defined_syms, "All", "all",
285+
desc_from_file(all_index_desc))
232286

233287

234288
def write_toplevel_index():
235289
# Used in --modules mode. Writes an index.rst with a TOC tree that links to
236290
# index-main.rst and the index-<suffix>.rst pages.
237291

238-
rst = sym_index_header(None, None) + """
292+
rst = index_page_header(None, None, desc_from_file(top_index_desc)) + """
239293
Subsystems
240294
**********
241295
@@ -245,19 +299,19 @@ def write_toplevel_index():
245299
"""
246300

247301
rst += " index-main\n"
248-
for _, suffix, _ in modules:
302+
for _, suffix, _, _ in modules:
249303
rst += " index-{}\n".format(suffix)
250304
rst += " index-all\n"
251305

252306
write_if_updated("index.rst", rst)
253307

254308

255-
def write_sym_index_page(syms, title, suffix):
309+
def write_index_page(syms, title, suffix, text):
256310
# Writes an index page for the Symbols in 'syms' to 'index-<suffix>.rst'
257-
# (or index.rst if 'suffix' is None). 'title' and 'suffix' are also used
258-
# for to generate a page title and link target. See sym_index_header().
311+
# (or index.rst if 'suffix' is None). 'title', 'suffix', and 'text' are
312+
# also used for to generate the index page header. See index_page_header().
259313

260-
rst = sym_index_header(title, suffix)
314+
rst = index_page_header(title, suffix, text)
261315

262316
rst += """
263317
Configuration symbols
@@ -286,11 +340,20 @@ def write_sym_index_page(syms, title, suffix):
286340
write_if_updated(fname, rst)
287341

288342

289-
def sym_index_header(title, link):
290-
# write_sym_index_page() helper. Returns the RST for the beginning of a
291-
# symbol index page, with title '<title> Configuration Options' and a link
292-
# target 'configurations_options_<link>' pointing to the page. 'title'
293-
# and 'link' can be None to skip the prefix/suffix on the title/link.
343+
def index_page_header(title, link, description):
344+
# write_index_page() helper. Returns the RST for the beginning of a symbol
345+
# index page.
346+
#
347+
# title:
348+
# String used for the page title, as '<title> Configuration Options'. If
349+
# None, just 'Configuration Options' is used as the title.
350+
#
351+
# link:
352+
# String used for link target, as 'configuration_options_<link>'. If
353+
# None, the link will be 'configuration_options'.
354+
#
355+
# description:
356+
# RST put into an Overview section at the beginning of the page
294357

295358
if title is None:
296359
title = "Configuration Options"
@@ -312,16 +375,37 @@ def sym_index_header(title, link):
312375
Overview
313376
********
314377
378+
{}
379+
380+
This documentation is generated automatically from the :file:`Kconfig` files by
381+
the :file:`{}` script. Click on symbols for more information.
382+
""".format(link, title, description, os.path.basename(__file__))
383+
384+
385+
DEFAULT_INDEX_DESCRIPTION = """\
315386
:file:`Kconfig` files describe build-time configuration options (called symbols
316387
in Kconfig-speak), how they're grouped into menus and sub-menus, and
317388
dependencies between them that determine what configurations are valid.
318389
319390
:file:`Kconfig` files appear throughout the directory tree. For example,
320391
:file:`subsys/power/Kconfig` defines power-related options.
392+
"""
321393

322-
This documentation is generated automatically from the :file:`Kconfig` files by
323-
the :file:`{}` script. Click on symbols for more information.
324-
""".format(link, title, os.path.basename(__file__))
394+
395+
def desc_from_file(fname):
396+
# Helper for loading files with descriptions for index pages. Returns
397+
# DEFAULT_INDEX_DESCRIPTION if 'fname' is None, and the contents of the
398+
# file otherwise.
399+
400+
if fname is None:
401+
return DEFAULT_INDEX_DESCRIPTION
402+
403+
try:
404+
with open(fname, "r", encoding="utf-8") as f:
405+
return f.read()
406+
except OSError as e:
407+
sys.exit("error: failed to open index description file '{}': {}"
408+
.format(fname, e))
325409

326410

327411
def write_sym_pages():
@@ -661,7 +745,7 @@ def path2module(path):
661745
# part of a module with path foo/bar/. Play it safe with pathlib.
662746

663747
abspath = pathlib.Path(kconf.srctree).joinpath(path).resolve()
664-
for name, _, mod_path in modules:
748+
for name, _, mod_path, _ in modules:
665749
try:
666750
abspath.relative_to(mod_path)
667751
except ValueError:
@@ -680,7 +764,7 @@ def strip_module_path(path):
680764

681765
if strip_module_paths:
682766
abspath = pathlib.Path(kconf.srctree).joinpath(path).resolve()
683-
for title, _, mod_path in modules:
767+
for title, _, mod_path, _ in modules:
684768
try:
685769
relpath = abspath.relative_to(mod_path)
686770
except ValueError:

0 commit comments

Comments
 (0)