98 lines
2.8 KiB
Python
98 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Iterable
|
|
|
|
import rich.repr
|
|
from rich.console import Console, ConsoleOptions, RenderResult
|
|
from rich.highlighter import ReprHighlighter
|
|
from rich.markup import render
|
|
from rich.text import Text
|
|
|
|
_highlighter = ReprHighlighter()
|
|
|
|
|
|
def _markup_and_highlight(text: str) -> Text:
|
|
"""Highlight and render markup in a string of text, returning
|
|
a styled Text object.
|
|
|
|
Args:
|
|
text: The text to highlight and markup.
|
|
|
|
Returns:
|
|
The Text, with highlighting and markup applied.
|
|
"""
|
|
return _highlighter(render(text))
|
|
|
|
|
|
class Example:
|
|
"""Renderable for an example, which can appear below bullet points in
|
|
the help text.
|
|
|
|
Attributes:
|
|
markup: The markup to display for this example
|
|
"""
|
|
|
|
def __init__(self, markup: str) -> None:
|
|
self.markup: str = markup
|
|
|
|
def __rich_console__(
|
|
self, console: Console, options: ConsoleOptions
|
|
) -> RenderResult:
|
|
yield _markup_and_highlight(f" [dim]e.g. [/][i]{self.markup}[/]")
|
|
|
|
|
|
@rich.repr.auto
|
|
class Bullet:
|
|
"""Renderable for a single 'bullet point' containing information and optionally some examples
|
|
pertaining to that information.
|
|
|
|
Attributes:
|
|
markup: The markup to display
|
|
examples: An optional list of examples
|
|
to display below this bullet.
|
|
"""
|
|
|
|
def __init__(self, markup: str, examples: Iterable[Example] | None = None) -> None:
|
|
self.markup: str = markup
|
|
self.examples: Iterable[Example] | None = [] if examples is None else examples
|
|
|
|
def __rich_console__(
|
|
self, console: Console, options: ConsoleOptions
|
|
) -> RenderResult:
|
|
yield _markup_and_highlight(self.markup)
|
|
if self.examples is not None:
|
|
yield from self.examples
|
|
|
|
|
|
@rich.repr.auto
|
|
class HelpText:
|
|
"""Renderable for help text - the user is shown this when they
|
|
encounter a style-related error (e.g. setting a style property to an invalid
|
|
value).
|
|
|
|
Attributes:
|
|
summary: A succinct summary of the issue.
|
|
bullets: Bullet points which provide additional
|
|
context around the issue. These are rendered below the summary.
|
|
"""
|
|
|
|
def __init__(
|
|
self, summary: str, *, bullets: Iterable[Bullet] | None = None
|
|
) -> None:
|
|
self.summary: str = summary
|
|
self.bullets: Iterable[Bullet] | None = bullets or []
|
|
|
|
def __str__(self) -> str:
|
|
return self.summary
|
|
|
|
def __rich_console__(
|
|
self, console: Console, options: ConsoleOptions
|
|
) -> RenderResult:
|
|
from rich.tree import Tree
|
|
|
|
tree = Tree(_markup_and_highlight(f"[b blue]{self.summary}"), guide_style="dim")
|
|
if self.bullets is not None:
|
|
for bullet in self.bullets:
|
|
tree.add(bullet)
|
|
yield tree
|