From 73d0dfa95e908b32e3c222830517e29f4f0df4f7 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Thu, 16 Nov 2023 17:21:00 +0100 Subject: [PATCH] Misc Ascii and browser fixes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This move some of the coloration outside of the templating engine, this should let us add an option to make colors optionals, and should make testing easier, as now we can have expected colorless outputs and test the codebase against it. This also add some fixes to the urwid frontend – which still crashes in a number of places, so I'm wondering if we shoudl rewrite it using textual. One of the other current limitation with urwind is the lack of ability to reflow paragraph is they contain multiple entries. --- papyri/browser.py | 16 +++++++++-- papyri/gen.py | 9 +++--- papyri/render.py | 15 +++++++++- papyri/templates/ascii.tpl.j2 | 54 +++++++++++++++++++++-------------- 4 files changed, 63 insertions(+), 31 deletions(-) diff --git a/papyri/browser.py b/papyri/browser.py index fdafea10..f9c12dc3 100755 --- a/papyri/browser.py +++ b/papyri/browser.py @@ -47,6 +47,9 @@ def __init__(self, attr, text, cb): self.text = text self.cb = cb + def selectable(self): + return True + class TextWithLink(urwid.Text): # _selectable = True @@ -292,7 +295,7 @@ def render_Directive(self, d): c = converter() return ("math", c.convert(cont)) - return ("directive", f"{d.domain}:{d.role}:`{cont}`") + return Text(("directive", f"{d.domain}:{d.role}:`{cont}`")) def render_Example(self, ex): acc = [] @@ -307,7 +310,7 @@ def render_Example(self, ex): def render_Link(self, link): if link.reference.kind == "local": - return ("local", link.value) + return Text(("local", link.value)) return Link("link", link.value, lambda: self.cb(link.reference)) def render_BlockQuote(self, quote): @@ -315,7 +318,7 @@ def render_BlockQuote(self, quote): urwid.Pile([self.render(c) for c in quote.children]), left=4, right=4 ) - def render_Admonition(self, adm): + def render_MAdmonition(self, adm): kind = adm.kind title = (f"{kind} : {adm.title}",) if kind == "versionchanged": @@ -332,6 +335,13 @@ def render_Admonition(self, adm): ), ) + def render_MText(self, text): + return urwid.Text(text.value) + + def render_MParagraph(self, paragraph): + stuff = [self.render(c) for c in paragraph.children] + return urwid.Pile(stuff) + def render_BlockMath(self, math): from flatlatex import converter diff --git a/papyri/gen.py b/papyri/gen.py index bedd29f6..e75634ce 100644 --- a/papyri/gen.py +++ b/papyri/gen.py @@ -33,10 +33,7 @@ import jedi -try: - import tomllib -except ModuleNotFoundError: - import tomli as tomllib +import tomllib import tomli_w from IPython.core.oinspect import find_file from IPython.utils.path import compress_user @@ -1993,7 +1990,9 @@ def collect_api_docs(self, root: str, limit_to: List[str]): "error with %s %s", qa, list(ecollector._errors.keys()) ) else: - self.log.info("only expected error with %s", qa) + self.log.info( + "only expected error with %s, %s", qa, ecollector._errors.keys() + ) continue try: diff --git a/papyri/render.py b/papyri/render.py index e57f6f50..972ea881 100644 --- a/papyri/render.py +++ b/papyri/render.py @@ -68,7 +68,7 @@ def minify(s: str) -> str: def unreachable(*obj): - return str(obj[1]) + return str(obj) assert False, f"Unreachable: {obj=}" @@ -1200,6 +1200,18 @@ def _ascii_env(): env.globals["len"] = len env.globals["unreachable"] = unreachable env.globals["sidebar"] = False + + env.globals["bold"] = lambda x: f"\x1b[1;m{x}\x1b[0;m" + env.globals["underline"] = lambda x: f"\x1b[4;m{x}\x1b[0;m" + env.globals["black"] = lambda x: f"\x1b[30;m{x}\x1b[0;m" + env.globals["red"] = lambda x: f"\x1b[31;m{x}\x1b[0;m" + env.globals["green"] = lambda x: f"\x1b[32;m{x}\x1b[0;m" + env.globals["yellow"] = lambda x: f"\x1b[33;m{x}\x1b[0;m" + env.globals["blue"] = lambda x: f"\x1b[34;m{x}\x1b[0;m" + env.globals["magenta"] = lambda x: f"\x1b[35;m{x}\x1b[0;m" + env.globals["cyan"] = lambda x: f"\x1b[36;m{x}\x1b[0;m" + env.globals["white"] = lambda x: f"\x1b[37;m{x}\x1b[0;m" + try: c = converter() @@ -1245,6 +1257,7 @@ async def ascii_render(name, store=None): key = next(iter(gstore.glob((None, None, "module", name)))) env, template = _ascii_env() + builtins.print(await _ascii_render(key, gstore, env=env, template=template)) diff --git a/papyri/templates/ascii.tpl.j2 b/papyri/templates/ascii.tpl.j2 index 5e5dee8a..0f196ecc 100644 --- a/papyri/templates/ascii.tpl.j2 +++ b/papyri/templates/ascii.tpl.j2 @@ -61,41 +61,53 @@ {% endif %} {% endmacro %} +{% macro render_list(objs) -%} + |{% for item in objs -%} + |{{- render_II(item) -}} + |{% endfor -%} +{%- endmacro %} + {% macro render_II(obj) -%} - |{% if obj.__class__.__name__ == 'Paragraph' %} - | |{{block_paragraph(obj)}} - |{% else %} + |{%- if obj.__class__.__name__ == 'Paragraph' -%} + | |{{- block_paragraph(obj) -}} + |{%- else -%} |{%- set type = obj.__class__.__name__ -%} | |{%- if type in ('Directive', 'Link', 'Math', 'Verbatim') -%} | | |{{unreachable()}} - | |{% elif type == 'MMystDirective' %} + | |{% elif type == 'MMystDirective' -%} | | |{{'\n'}}{{myst_directive(obj)}} - | |{% elif type == 'Verbatim' %} + | |{% elif type == 'Verbatim' -%} | | |{{obj}} - | |{% elif type == 'Paragraph' %} + | |{% elif type == 'Paragraph' -%} | | |{{block_paragraph(obj)}} - | |{% elif type == 'BlockVerbatim' %} + | |{% elif type == 'BlockVerbatim' -%} | | |{{obj.value}} - | |{% elif type == 'DefList' %} + | |{% elif type == 'DefList' -%} | | | {% for item in obj.children %} | | | {{render_II(item.dt)}} | | | {{render_II(item.dd)}} - | | | {%endfor %} + | | | {%endfor %} | |{% elif type == 'DefListItem' %} | | {{-block(obj)-}} | |{% elif type == 'Example' %} | | | |{{block(obj)}} + | |{% elif type == 'MLink' %} + | | |{{render_list(obj.children)}} + | |{% elif type == 'MText' %} + | | |{{obj.value}} + | |{% elif type == 'MParagraph' -%} + | | |{{- render_list(obj.children) -}} | |{% elif type == 'Parameters' %} - | | {% for item in obj.children %} + | | {%- for item in obj.children %} | | {{ render_II(item) }} - | | {% endfor %} + | | {%- endfor %} | |{% elif type == 'Section' %} - | | {% for item in obj %} - | | {{ render_II(item) }} - | | {% endfor %} - | |{% else %} - | | |Some B {{type}} Not implemented yet - | | {#{{unreachable(obj)}}#} + | | {%- for item in obj %} + | | {{- render_II(item) -}} + | | {%- endfor %} + | |{%- else %} + | | |Some B {{type}} Not implemented yet: + | | |{{unreachable(obj)}} | |{%- endif -%} |{%- endif -%} {%- endmacro %} @@ -106,12 +118,12 @@ |{% endif %} |{% for prg in prgs %} | | |{%- for obj in prg.children -%} - | | | {{- render_inner(obj.__class__.__name__, obj) -}} + | | | {{- render_inner(obj.__class__.__name__, obj) -}} | | |{%- endfor -%} |{%- endfor -%} {%- endmacro %} - + {%- macro esc(val, stuff) -%} [{{val}};m{{stuff}} {%- endmacro %} @@ -148,10 +160,8 @@ |{{bold(section)}} | |{% endif %} - |{% if section in ['Summary', 'Extended Summary', 'Notes'] %} - | + |{%- if section in ['Summary', 'Extended Summary', 'Notes'] -%} | |{{render_II(doc.content[section]) | wordwrap}} - | |{% elif section in ['Signature'] %} |{{unreachable()}} |{% elif section in ['Examples'] %}