Coverage for /run/media/veganeco/water/status600.com/pypi/reptilian_climates/modules_series_2/ships/fields/gardens_pip/rich/jupyter.py: 25%

1 from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Sequence

2

3 if TYPE_CHECKING:

4 from rich.console import ConsoleRenderable

5

6 from . import get_console

7 from .segment import Segment

8 from .terminal_theme import DEFAULT_TERMINAL_THEME

9

10 if TYPE_CHECKING:

11 from rich.console import ConsoleRenderable

12

13 JUPYTER_HTML_FORMAT = """\

14<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">{code}</pre>

15"""

16

17

18 class JupyterRenderable:

19 """A shim to write html to Jupyter notebook."""

20

21 def __init__(self, html: str, text: str) -> None:

22 self.html = html

23 self.text = text

24

25 def _repr_mimebundle_(

26 self, include: Sequence[str], exclude: Sequence[str], **kwargs: Any

27 ) -> Dict[str, str]:

28 data = {"text/plain": self.text, "text/html": self.html}

29 if include:

30 data = {k: v for (k, v) in data.items() if k in include}

31 if exclude:

32 data = {k: v for (k, v) in data.items() if k not in exclude}

33 return data

34

35

36 class JupyterMixin:

37 """Add to an Rich renderable to make it render in Jupyter notebook."""

38

39 __slots__ = ()

40

41 def _repr_mimebundle_(

42 self: "ConsoleRenderable",

43 include: Sequence[str],

44 exclude: Sequence[str],

45 **kwargs: Any,

46 ) -> Dict[str, str]:

47 console = get_console()

48 segments = list(console.render(self, console.options))

49 html = _render_segments(segments)

50 text = console._render_buffer(segments)

51 data = {"text/plain": text, "text/html": html}

52 if include:

53 data = {k: v for (k, v) in data.items() if k in include}

54 if exclude:

55 data = {k: v for (k, v) in data.items() if k not in exclude}

56 return data

57

58

59 def _render_segments(segments: Iterable[Segment]) -> str:

60 def escape(text: str) -> str:

61 """Escape html."""

62 return text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")

63

64 fragments: List[str] = []

65 append_fragment = fragments.append

66 theme = DEFAULT_TERMINAL_THEME

67 for text, style, control in Segment.simplify(segments):

68 if control:

69 continue

70 text = escape(text)

71 if style:

72 rule = style.get_html_style(theme)

73 text = f'<span style="{rule}">{text}</span>' if rule else text

74 if style.link:

75 text = f'<a href="{style.link}" target="_blank">{text}</a>'

76 append_fragment(text)

77

78 code = "".join(fragments)

79 html = JUPYTER_HTML_FORMAT.format(code=code)

80

81 return html

82

83

84 def display(segments: Iterable[Segment], text: str) -> None:

85 """Render segments to Jupyter."""

86 html = _render_segments(segments)

87 jupyter_renderable = JupyterRenderable(html, text)

88 try:

89 from IPython.display import display as ipython_display

90

91 ipython_display(jupyter_renderable)

92 except ModuleNotFoundError:

93 # Handle the case where the Console has force_jupyter=True,

94 # but IPython is not installed.

95 pass

96

97

98 def print(*args: Any, **kwargs: Any) -> None:

99 """Proxy for Console print."""

100 console = get_console()

101 return console.print(*args, **kwargs)