1 from typing
import TYPE_CHECKING
, Any
, Dict
, Iterable
, List
, Sequence
4 from pip
._vendor
.rich
.console
import ConsoleRenderable
6 from . import get_console
7 from .segment
import Segment
8 from .terminal_theme
import DEFAULT_TERMINAL_THEME
11 from pip
._vendor
.rich
.console
import ConsoleRenderable
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>
18 class JupyterRenderable
:
19 """A shim to write html to Jupyter notebook."""
21 def __init__(self
, html
: str, text
: str) -> None:
25 def _repr_mimebundle_(
26 self
, include
: Sequence
[str], exclude
: Sequence
[str], **kwargs
: Any
28 data
= {"text/plain": self.text, "text/html": self.html}
30 data
= {k: v for (k, v) in data.items() if k in include}
32 data
= {k: v for (k, v) in data.items() if k not in exclude}
37 """Add to an Rich renderable to make it render in Jupyter notebook."""
41 def _repr_mimebundle_(
42 self
: "ConsoleRenderable",
43 include
: Sequence
[str],
44 exclude
: Sequence
[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}
53 data
= {k: v for (k, v) in data.items() if k in include}
55 data
= {k: v for (k, v) in data.items() if k not in exclude}
59 def _render_segments(segments
: Iterable
[Segment
]) -> str:
60 def escape(text
: str) -> str:
62 return text
.replace("&", "&").replace("<", "<").replace(">", ">")
64 fragments
: List
[str] = []
65 append_fragment
= fragments
.append
66 theme
= DEFAULT_TERMINAL_THEME
67 for text
, style
, control
in Segment
.simplify(segments
):
72 rule
= style
.get_html_style(theme
)
73 text
= f
'<span style="{rule}">{text}</span>' if rule
else text
75 text
= f
'<a href="{style.link}" target="_blank">{text}</a>'
78 code
= "".join(fragments
)
79 html
= JUPYTER_HTML_FORMAT
.format(code
=code
)
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
)
89 from IPython
.display
import display
as ipython_display
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.
98 def print(*args
: Any
, **kwargs
: Any
) -> None:
99 """Proxy for Console print."""
100 console
= get_console()
101 return console
.print(*args
, **kwargs
)