3
0
Fork 0
forked from mirrors/nixpkgs

nixos-render-docs: don't use env for renderer state

since we keep the renderer around for a long time we don't need to stick
renderer state into env, we can use the renderer instance itself instead.
This commit is contained in:
pennae 2023-01-25 20:28:11 +01:00
parent 1016b727a8
commit c63a550e7b
3 changed files with 32 additions and 29 deletions

View file

@ -21,6 +21,8 @@ from .md import md_escape
class Converter:
def __init__(self, manpage_urls: Dict[str, str]):
self._manpage_urls = frozendict(manpage_urls)
self._md = markdown_it.MarkdownIt(
"commonmark",
{
@ -28,7 +30,7 @@ class Converter:
'html': False, # not useful since we target many formats
'typographer': True, # required for smartquotes
},
renderer_cls=DocBookRenderer
renderer_cls=lambda parser: DocBookRenderer(self._manpage_urls, parser)
)
# TODO maybe fork the plugin and have only a single rule for all?
self._md.use(container_plugin, name="{.note}")
@ -38,13 +40,8 @@ class Converter:
self._md.use(myst_role_plugin)
self._md.enable(["smartquotes", "replacements"])
self._manpage_urls = frozendict(manpage_urls)
def render(self, src: str) -> str:
env = {
'manpage_urls': self._manpage_urls
}
return self._md.render(src, env)
return self._md.render(src)
md = Converter(json.load(open(os.getenv('MANPAGE_URLS'))))

View file

@ -1,6 +1,6 @@
from collections.abc import MutableMapping, Sequence
from collections.abc import Mapping, MutableMapping, Sequence
from frozendict import frozendict # type: ignore[attr-defined]
from typing import Any, Optional
from typing import Any, cast, Optional
import markdown_it
from markdown_it.token import Token
@ -22,15 +22,19 @@ _xml_id_translate_table = {
def make_xml_id(s: str) -> str:
return s.translate(_xml_id_translate_table)
class Deflist:
has_dd = False
class DocBookRenderer(Renderer):
__output__ = "docbook"
def render(self, tokens: Sequence[Token], options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
assert '-link-tag-stack' not in env
env['-link-tag-stack'] = []
assert '-deflist-stack' not in env
env['-deflist-stack'] = []
return super().render(tokens, options, env)
_link_tags: list[str]
_deflists: list[Deflist]
def __init__(self, manpage_urls: Mapping[str, str], parser: Optional[markdown_it.MarkdownIt] = None):
super().__init__(manpage_urls, parser)
self._link_tags = []
self._deflists = []
def renderInline(self, tokens: Sequence[Token], options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
# HACK to support docbook links and xrefs. link handling is only necessary because the docbook
@ -72,12 +76,13 @@ class DocBookRenderer(Renderer):
return f"<programlisting>{escape(token.content)}</programlisting>"
def link_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
env['-link-tag-stack'].append(token.tag)
(attr, start) = ('linkend', 1) if token.attrs['href'][0] == '#' else ('xlink:href', 0)
return f"<{token.tag} {attr}={quoteattr(token.attrs['href'][start:])}>"
self._link_tags.append(token.tag)
href = cast(str, token.attrs['href'])
(attr, start) = ('linkend', 1) if href[0] == '#' else ('xlink:href', 0)
return f"<{token.tag} {attr}={quoteattr(href[start:])}>"
def link_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
return f"</{env['-link-tag-stack'].pop()}>"
return f"</{self._link_tags.pop()}>"
def list_item_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
return "<listitem>"
@ -137,24 +142,24 @@ class DocBookRenderer(Renderer):
# we have to reject multiple definitions for the same term for time being.
def dl_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
env['-deflist-stack'].append({})
self._deflists.append(Deflist())
return "<para><variablelist>"
def dl_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
env['-deflist-stack'].pop()
self._deflists.pop()
return "</variablelist></para>"
def dt_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
env['-deflist-stack'][-1]['has-dd'] = False
self._deflists[-1].has_dd = False
return "<varlistentry><term>"
def dt_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
return "</term>"
def dd_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
if env['-deflist-stack'][-1]['has-dd']:
if self._deflists[-1].has_dd:
raise Exception("multiple definitions per term not supported")
env['-deflist-stack'][-1]['has-dd'] = True
self._deflists[-1].has_dd = True
return "<listitem>"
def dd_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
env: MutableMapping[str, Any]) -> str:
@ -178,8 +183,8 @@ class DocBookRenderer(Renderer):
title = f"<refentrytitle>{escape(page)}</refentrytitle>"
vol = f"<manvolnum>{escape(section)}</manvolnum>"
ref = f"<citerefentry>{title}{vol}</citerefentry>"
if man in env['manpage_urls']:
return f"<link xlink:href={quoteattr(env['manpage_urls'][man])}>{ref}</link>"
if man in self._manpage_urls:
return f"<link xlink:href={quoteattr(self._manpage_urls[man])}>{ref}</link>"
else:
return ref
raise NotImplementedError("md node not supported yet", token)

View file

@ -1,4 +1,4 @@
from collections.abc import MutableMapping, Sequence
from collections.abc import Mapping, MutableMapping, Sequence
from typing import Any, Optional
import markdown_it
@ -19,7 +19,8 @@ def md_escape(s: str) -> str:
return s.translate(_md_escape_table)
class Renderer(markdown_it.renderer.RendererProtocol):
def __init__(self, parser: Optional[markdown_it.MarkdownIt] = None):
def __init__(self, manpage_urls: Mapping[str, str], parser: Optional[markdown_it.MarkdownIt] = None):
self._manpage_urls = manpage_urls
self.rules = {
'text': self.text,
'paragraph_open': self.paragraph_open,