3
0
Fork 0
forked from mirrors/nixpkgs

nixos-render-docs: use only one container plugin instance

with some fiddling and custom validation logic we can avoid needing
multiple instances of this plugin. originally this wasn't done because
it does need a type stack to emit correct docbook, but since we can
easily do that now we may as well.
This commit is contained in:
pennae 2023-01-25 22:06:36 +01:00
parent 7605068000
commit c2e638391e
2 changed files with 40 additions and 17 deletions

View file

@ -3,6 +3,8 @@ from collections.abc import Mapping, MutableMapping, Sequence
from frozendict import frozendict # type: ignore[attr-defined]
from typing import Any, Callable, Optional
from .types import RenderFn
import markdown_it
from markdown_it.token import Token
from markdown_it.utils import OptionsDict
@ -24,6 +26,9 @@ def md_escape(s: str) -> str:
return s.translate(_md_escape_table)
class Renderer(markdown_it.renderer.RendererProtocol):
_admonitions: dict[str, tuple[RenderFn, RenderFn]]
_admonition_stack: list[str]
def __init__(self, manpage_urls: Mapping[str, str], parser: Optional[markdown_it.MarkdownIt] = None):
self._manpage_urls = manpage_urls
self.rules = {
@ -54,17 +59,28 @@ class Renderer(markdown_it.renderer.RendererProtocol):
'dd_open': self.dd_open,
'dd_close': self.dd_close,
'myst_role': self.myst_role,
"container_{.note}_open": self.note_open,
"container_{.note}_close": self.note_close,
"container_{.caution}_open": self.caution_open,
"container_{.caution}_close": self.caution_close,
"container_{.tip}_open": self.tip_open,
"container_{.tip}_close": self.tip_close,
"container_{.important}_open": self.important_open,
"container_{.important}_close": self.important_close,
"container_{.warning}_open": self.warning_open,
"container_{.warning}_close": self.warning_close,
"container_admonition_open": self.admonition_open,
"container_admonition_close": self.admonition_close,
}
self._admonitions = {
"{.note}": (self.note_open, self.note_close),
"{.caution}": (self.caution_open,self.caution_close),
"{.tip}": (self.tip_open, self.tip_close),
"{.important}": (self.important_open, self.important_close),
"{.warning}": (self.warning_open, self.warning_close),
}
self._admonition_stack = []
def admonition_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
tag = token.info.strip()
self._admonition_stack.append(tag)
return self._admonitions[tag][0](token, tokens, i, options, env)
def admonition_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
return self._admonitions[self._admonition_stack.pop()][1](token, tokens, i, options, env)
def render(self, tokens: Sequence[Token], options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
def do_one(i: int, token: Token) -> str:
@ -212,12 +228,13 @@ class Converter(ABC):
},
renderer_cls=lambda parser: self.__renderer__(self._manpage_urls, parser)
)
# TODO maybe fork the plugin and have only a single rule for all?
self._md.use(container_plugin, name="{.note}")
self._md.use(container_plugin, name="{.caution}")
self._md.use(container_plugin, name="{.tip}")
self._md.use(container_plugin, name="{.important}")
self._md.use(container_plugin, name="{.warning}")
self._md.use(
container_plugin,
name="admonition",
validate=lambda name, *args: (
name.strip() in self._md.renderer._admonitions # type: ignore[attr-defined]
)
)
self._md.use(deflist_plugin)
self._md.use(myst_role_plugin)
self._md.enable(["smartquotes", "replacements"])

View file

@ -1,7 +1,13 @@
from typing import Optional, Tuple, NamedTuple
from collections.abc import Sequence, MutableMapping
from typing import Any, Callable, Optional, Tuple, NamedTuple
from markdown_it.token import Token
from markdown_it.utils import OptionsDict
OptionLoc = str | dict[str, str]
Option = dict[str, str | dict[str, str] | list[OptionLoc]]
RenderedOption = NamedTuple('RenderedOption', [('loc', list[str]),
('lines', list[str])])
RenderFn = Callable[[Token, Sequence[Token], int, OptionsDict, MutableMapping[str, Any]], str]