From b962ff92ff414b325c1b73f24f2ff3b0ae613dd7 Mon Sep 17 00:00:00 2001 From: pennae Date: Wed, 21 Jun 2023 16:37:40 +0200 Subject: [PATCH] nixos-render-docs: add support for section tocs the nixpkgs manual uses section tocs for eg the nixpkgs library function reference. we will only not emit tocs for subsections at this point, but maybe we should consider doing so in the future. --- .../src/nixos_render_docs/manual.py | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/manual.py b/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/manual.py index 1f0e312c91e1..82e8f3e8a6d7 100644 --- a/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/manual.py +++ b/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/manual.py @@ -235,8 +235,12 @@ class HTMLParameters(NamedTuple): generator: str stylesheets: Sequence[str] scripts: Sequence[str] + # number of levels in the rendered table of contents. tables are prepended to + # the content they apply to (entire document / document chunk / top-level section + # of a chapter), setting a depth of 0 omits the respective table. toc_depth: int chunk_toc_depth: int + section_toc_depth: int class ManualHTMLRenderer(RendererMixin, HTMLRenderer): _base_path: Path @@ -384,7 +388,7 @@ class ManualHTMLRenderer(RendererMixin, HTMLRenderer): return super()._heading_tag(token, tokens, i) def _build_toc(self, tokens: Sequence[Token], i: int) -> str: toc = TocEntry.of(tokens[i]) - if toc.kind == 'section': + if toc.kind == 'section' and self._html_params.section_toc_depth < 1: return "" def walk_and_emit(toc: TocEntry, depth: int) -> list[str]: if depth <= 0: @@ -404,11 +408,20 @@ class ManualHTMLRenderer(RendererMixin, HTMLRenderer): if next_level: result.append(f'
{"".join(next_level)}
') return result - toc_depth = ( - self._html_params.chunk_toc_depth - if toc.starts_new_chunk and toc.kind != 'book' - else self._html_params.toc_depth - ) + # we don't want to generate the "Title of Contents" header for sections, + # docbook doesn't and it's only distracting clutter unless it's the main table. + # we also want to generate tocs only for a top-level section (ie, one that is + # not itself contained in another section) + print_title = toc.kind != 'section' + if toc.kind == 'section': + if toc.parent and toc.parent.kind == 'section': + toc_depth = 0 + else: + toc_depth = self._html_params.section_toc_depth + elif toc.starts_new_chunk and toc.kind != 'book': + toc_depth = self._html_params.chunk_toc_depth + else: + toc_depth = self._html_params.toc_depth if not (items := walk_and_emit(toc, toc_depth)): return "" examples = "" @@ -423,15 +436,15 @@ class ManualHTMLRenderer(RendererMixin, HTMLRenderer): f'
{"".join(examples_entries)}
' '' ) - return ( - f'
' - f'

Table of Contents

' + return "".join([ + f'
', + '

Table of Contents

' if print_title else "", f'
' f' {"".join(items)}' f'
' f'
' f'{examples}' - ) + ]) def _make_hN(self, level: int) -> tuple[str, str]: # for some reason chapters don't increase the hN nesting count in docbook xslts. duplicate @@ -673,6 +686,7 @@ def _build_cli_html(p: argparse.ArgumentParser) -> None: p.add_argument('--script', default=[], action='append') p.add_argument('--toc-depth', default=1, type=int) p.add_argument('--chunk-toc-depth', default=1, type=int) + p.add_argument('--section-toc-depth', default=0, type=int) p.add_argument('infile', type=Path) p.add_argument('outfile', type=Path) @@ -686,7 +700,7 @@ def _run_cli_html(args: argparse.Namespace) -> None: md = HTMLConverter( args.revision, HTMLParameters(args.generator, args.stylesheet, args.script, args.toc_depth, - args.chunk_toc_depth), + args.chunk_toc_depth, args.section_toc_depth), json.load(manpage_urls)) md.convert(args.infile, args.outfile)