about summary refs log tree commit diff
path: root/pkgs/tools/nix
diff options
context:
space:
mode:
authorpennae <github@quasiparticle.net>2023-06-21 18:46:02 +0200
committerpennae <github@quasiparticle.net>2023-07-01 20:27:29 +0200
commite5e738b72a879f7c12b314df11f0d1528fc066dc (patch)
tree21be185cad286c91d9a9252f52f5374329f7c15d /pkgs/tools/nix
parent8c2d14a6b850458020fd4ce079a90ee87e64c7a6 (diff)
nixos-render-docs: genericize block numbering
examples and figures behave identically regarding numbering and titling,
they just don't share a common number space. make the numbering/titling
function generic over block types now so figures can just use it.
Diffstat (limited to 'pkgs/tools/nix')
-rw-r--r--pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/manual.py13
-rw-r--r--pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/md.py32
2 files changed, 26 insertions, 19 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 acf562b839e08..cb6b1a0235673 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
@@ -569,23 +569,24 @@ class HTMLConverter(BaseConverter[ManualHTMLRenderer]):
             self._redirection_targets.add(into)
         return tokens
 
-    def _number_examples(self, tokens: Sequence[Token], start: int = 1) -> int:
+    def _number_block(self, block: str, prefix: str, tokens: Sequence[Token], start: int = 1) -> int:
+        title_open, title_close = f'{block}_title_open', f'{block}_title_close'
         for (i, token) in enumerate(tokens):
-            if token.type == "example_title_open":
+            if token.type == title_open:
                 title = tokens[i + 1]
                 assert title.type == 'inline' and title.children
                 # the prefix is split into two tokens because the xref title_html will want
                 # only the first of the two, but both must be rendered into the example itself.
                 title.children = (
                     [
-                        Token('text', '', 0, content=f'Example {start}'),
+                        Token('text', '', 0, content=f'{prefix} {start}'),
                         Token('text', '', 0, content='. ')
                     ] + title.children
                 )
                 start += 1
             elif token.type.startswith('included_') and token.type != 'included_options':
                 for sub, _path in token.meta['included']:
-                    start = self._number_examples(sub, start)
+                    start = self._number_block(block, prefix, sub, start)
         return start
 
     # xref | (id, type, heading inlines, file, starts new file)
@@ -636,7 +637,7 @@ class HTMLConverter(BaseConverter[ManualHTMLRenderer]):
             toc_html = f"{n}. {title_html}"
             title_html = f"Appendix&nbsp;{n}"
         elif typ == 'example':
-            # skip the prepended `Example N. ` from _number_examples
+            # skip the prepended `Example N. ` from numbering
             toc_html, title = self._renderer.renderInline(inlines.children[2:]), title_html
             # xref title wants only the prepended text, sans the trailing colon and space
             title_html = self._renderer.renderInline(inlines.children[0:1])
@@ -651,7 +652,7 @@ class HTMLConverter(BaseConverter[ManualHTMLRenderer]):
         return XrefTarget(id, title_html, toc_html, re.sub('<.*?>', '', title), path, drop_fragment)
 
     def _postprocess(self, infile: Path, outfile: Path, tokens: Sequence[Token]) -> None:
-        self._number_examples(tokens)
+        self._number_block('example', "Example", tokens)
         xref_queue = self._collect_ids(tokens, outfile.name, 'book', True)
 
         failed = False
diff --git a/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/md.py b/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/md.py
index edd4238dd9f06..35a1657ef6bb1 100644
--- a/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/md.py
+++ b/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/md.py
@@ -1,6 +1,6 @@
 from abc import ABC
 from collections.abc import Mapping, MutableMapping, Sequence
-from typing import Any, cast, Generic, get_args, Iterable, Literal, NoReturn, Optional, TypeVar
+from typing import Any, Callable, cast, Generic, get_args, Iterable, Literal, NoReturn, Optional, TypeVar
 
 import dataclasses
 import re
@@ -426,31 +426,37 @@ def _block_attr(md: markdown_it.MarkdownIt) -> None:
 
     md.core.ruler.push("block_attr", block_attr)
 
-def _example_titles(md: markdown_it.MarkdownIt) -> None:
+def _block_titles(block: str) -> Callable[[markdown_it.MarkdownIt], None]:
+    open, close = f'{block}_open', f'{block}_close'
+    title_open, title_close = f'{block}_title_open', f'{block}_title_close'
+
     """
-    find title headings of examples and stick them into meta for renderers, then
-    remove them from the token stream. also checks whether any example contains a
+    find title headings of blocks and stick them into meta for renderers, then
+    remove them from the token stream. also checks whether any block contains a
     non-title heading since those would make toc generation extremely complicated.
     """
-    def example_titles(state: markdown_it.rules_core.StateCore) -> None:
+    def block_titles(state: markdown_it.rules_core.StateCore) -> None:
         in_example = [False]
         for i, token in enumerate(state.tokens):
-            if token.type == 'example_open':
+            if token.type == open:
                 if state.tokens[i + 1].type == 'heading_open':
                     assert state.tokens[i + 3].type == 'heading_close'
-                    state.tokens[i + 1].type = 'example_title_open'
-                    state.tokens[i + 3].type = 'example_title_close'
+                    state.tokens[i + 1].type = title_open
+                    state.tokens[i + 3].type = title_close
                 else:
                     assert token.map
-                    raise RuntimeError(f"found example without title in line {token.map[0] + 1}")
+                    raise RuntimeError(f"found {block} without title in line {token.map[0] + 1}")
                 in_example.append(True)
-            elif token.type == 'example_close':
+            elif token.type == close:
                 in_example.pop()
             elif token.type == 'heading_open' and in_example[-1]:
                 assert token.map
-                raise RuntimeError(f"unexpected non-title heading in example in line {token.map[0] + 1}")
+                raise RuntimeError(f"unexpected non-title heading in {block} in line {token.map[0] + 1}")
+
+    def do_add(md: markdown_it.MarkdownIt) -> None:
+        md.core.ruler.push(f"{block}_titles", block_titles)
 
-    md.core.ruler.push("example_titles", example_titles)
+    return do_add
 
 TR = TypeVar('TR', bound='Renderer')
 
@@ -494,7 +500,7 @@ class Converter(ABC, Generic[TR]):
         self._md.use(_heading_ids)
         self._md.use(_compact_list_attr)
         self._md.use(_block_attr)
-        self._md.use(_example_titles)
+        self._md.use(_block_titles("example"))
         self._md.enable(["smartquotes", "replacements"])
 
     def _parse(self, src: str) -> list[Token]: