mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-17 23:19:25 +03:00
nixos-render-docs: drop options, env parameters
these weren't used for anything. options never was (and does not contain any information for the renderer that we *want* to honor), and env is not used because typed renderer state is much more useful for all our cases.
This commit is contained in:
parent
0236dcb59f
commit
6f253fc70b
8 changed files with 288 additions and 538 deletions
|
@ -1,9 +1,8 @@
|
|||
from collections.abc import Mapping, MutableMapping, Sequence
|
||||
from collections.abc import Mapping, Sequence
|
||||
from typing import Any, cast, Optional, NamedTuple
|
||||
|
||||
import markdown_it
|
||||
from markdown_it.token import Token
|
||||
from markdown_it.utils import OptionsDict
|
||||
from xml.sax.saxutils import escape, quoteattr
|
||||
|
||||
from .md import Renderer
|
||||
|
@ -44,13 +43,11 @@ class DocBookRenderer(Renderer):
|
|||
self._headings = []
|
||||
self._attrspans = []
|
||||
|
||||
def render(self, tokens: Sequence[Token], options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
result = super().render(tokens, options, env)
|
||||
result += self._close_headings(None, env)
|
||||
def render(self, tokens: Sequence[Token]) -> str:
|
||||
result = super().render(tokens)
|
||||
result += self._close_headings(None)
|
||||
return result
|
||||
def renderInline(self, tokens: Sequence[Token], options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def renderInline(self, tokens: Sequence[Token]) -> str:
|
||||
# HACK to support docbook links and xrefs. link handling is only necessary because the docbook
|
||||
# manpage stylesheet converts - in urls to a mathematical minus, which may be somewhat incorrect.
|
||||
for i, token in enumerate(tokens):
|
||||
|
@ -64,135 +61,98 @@ class DocBookRenderer(Renderer):
|
|||
if tokens[i + 1].type == 'text' and tokens[i + 1].content == token.attrs['href']:
|
||||
tokens[i + 1].content = ''
|
||||
|
||||
return super().renderInline(tokens, options, env)
|
||||
return super().renderInline(tokens)
|
||||
|
||||
def text(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def text(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return escape(token.content)
|
||||
def paragraph_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def paragraph_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<para>"
|
||||
def paragraph_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def paragraph_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</para>"
|
||||
def hardbreak(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def hardbreak(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<literallayout>\n</literallayout>"
|
||||
def softbreak(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def softbreak(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
# should check options.breaks() and emit hard break if so
|
||||
return "\n"
|
||||
def code_inline(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def code_inline(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return f"<literal>{escape(token.content)}</literal>"
|
||||
def code_block(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def code_block(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
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:
|
||||
def link_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
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:
|
||||
def link_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
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:
|
||||
def list_item_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<listitem>"
|
||||
def list_item_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def list_item_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</listitem>\n"
|
||||
# HACK open and close para for docbook change size. remove soon.
|
||||
def bullet_list_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def bullet_list_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
spacing = ' spacing="compact"' if token.meta.get('compact', False) else ''
|
||||
return f"<para><itemizedlist{spacing}>\n"
|
||||
def bullet_list_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def bullet_list_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "\n</itemizedlist></para>"
|
||||
def em_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def em_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<emphasis>"
|
||||
def em_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def em_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</emphasis>"
|
||||
def strong_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def strong_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<emphasis role=\"strong\">"
|
||||
def strong_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def strong_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</emphasis>"
|
||||
def fence(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def fence(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
info = f" language={quoteattr(token.info)}" if token.info != "" else ""
|
||||
return f"<programlisting{info}>{escape(token.content)}</programlisting>"
|
||||
def blockquote_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def blockquote_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<para><blockquote>"
|
||||
def blockquote_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def blockquote_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</blockquote></para>"
|
||||
def note_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def note_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<para><note>"
|
||||
def note_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def note_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</note></para>"
|
||||
def caution_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def caution_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<para><caution>"
|
||||
def caution_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def caution_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</caution></para>"
|
||||
def important_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def important_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<para><important>"
|
||||
def important_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def important_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</important></para>"
|
||||
def tip_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def tip_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<para><tip>"
|
||||
def tip_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def tip_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</tip></para>"
|
||||
def warning_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def warning_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "<para><warning>"
|
||||
def warning_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def warning_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</warning></para>"
|
||||
# markdown-it emits tokens based on the html syntax tree, but docbook is
|
||||
# slightly different. html has <dl>{<dt/>{<dd/>}}</dl>,
|
||||
# docbook has <variablelist>{<varlistentry><term/><listitem/></varlistentry>}<variablelist>
|
||||
# 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:
|
||||
def dl_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
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:
|
||||
def dl_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
self._deflists.pop()
|
||||
return "</variablelist></para>"
|
||||
def dt_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def dt_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
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:
|
||||
def dt_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</term>"
|
||||
def dd_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def dd_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
if self._deflists[-1].has_dd:
|
||||
raise Exception("multiple definitions per term not supported")
|
||||
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:
|
||||
def dd_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return "</listitem></varlistentry>"
|
||||
def myst_role(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def myst_role(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
if token.meta['name'] == 'command':
|
||||
return f"<command>{escape(token.content)}</command>"
|
||||
if token.meta['name'] == 'file':
|
||||
|
@ -215,8 +175,7 @@ class DocBookRenderer(Renderer):
|
|||
else:
|
||||
return ref
|
||||
raise NotImplementedError("md node not supported yet", token)
|
||||
def attr_span_begin(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def attr_span_begin(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
# we currently support *only* inline anchors and the special .keycap class to produce
|
||||
# <keycap> docbook elements.
|
||||
(id_part, class_part) = ("", "")
|
||||
|
@ -227,31 +186,26 @@ class DocBookRenderer(Renderer):
|
|||
class_part = "<keycap>"
|
||||
self._attrspans.append("</keycap>")
|
||||
else:
|
||||
return super().attr_span_begin(token, tokens, i, options, env)
|
||||
return super().attr_span_begin(token, tokens, i)
|
||||
else:
|
||||
self._attrspans.append("")
|
||||
return id_part + class_part
|
||||
def attr_span_end(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def attr_span_end(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return self._attrspans.pop()
|
||||
def ordered_list_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def ordered_list_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
start = f' startingnumber="{token.attrs["start"]}"' if 'start' in token.attrs else ""
|
||||
spacing = ' spacing="compact"' if token.meta.get('compact', False) else ''
|
||||
return f"<orderedlist{start}{spacing}>"
|
||||
def ordered_list_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def ordered_list_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return f"</orderedlist>"
|
||||
def heading_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def heading_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
hlevel = int(token.tag[1:])
|
||||
result = self._close_headings(hlevel, env)
|
||||
(tag, attrs) = self._heading_tag(token, tokens, i, options, env)
|
||||
result = self._close_headings(hlevel)
|
||||
(tag, attrs) = self._heading_tag(token, tokens, i)
|
||||
self._headings.append(Heading(tag, hlevel))
|
||||
attrs_str = "".join([ f" {k}={quoteattr(v)}" for k, v in attrs.items() ])
|
||||
return result + f'<{tag}{attrs_str}>\n<title>'
|
||||
def heading_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def heading_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
heading = self._headings[-1]
|
||||
result = '</title>'
|
||||
if heading.container_tag == 'part':
|
||||
|
@ -263,16 +217,14 @@ class DocBookRenderer(Renderer):
|
|||
maybe_id = " xml:id=" + quoteattr(id + "-intro")
|
||||
result += f"<partintro{maybe_id}>"
|
||||
return result
|
||||
def example_open(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def example_open(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
if id := token.attrs.get('id'):
|
||||
return f"<anchor xml:id={quoteattr(cast(str, id))} />"
|
||||
return ""
|
||||
def example_close(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> str:
|
||||
def example_close(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||
return ""
|
||||
|
||||
def _close_headings(self, level: Optional[int], env: MutableMapping[str, Any]) -> str:
|
||||
def _close_headings(self, level: Optional[int]) -> str:
|
||||
# we rely on markdown-it producing h{1..6} tags in token.tag for this to work
|
||||
result = []
|
||||
while len(self._headings):
|
||||
|
@ -285,8 +237,7 @@ class DocBookRenderer(Renderer):
|
|||
break
|
||||
return "\n".join(result)
|
||||
|
||||
def _heading_tag(self, token: Token, tokens: Sequence[Token], i: int, options: OptionsDict,
|
||||
env: MutableMapping[str, Any]) -> tuple[str, dict[str, str]]:
|
||||
def _heading_tag(self, token: Token, tokens: Sequence[Token], i: int) -> tuple[str, dict[str, str]]:
|
||||
attrs = {}
|
||||
if id := token.attrs.get('id'):
|
||||
attrs['xml:id'] = cast(str, id)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue