Skip to content

Commit

Permalink
better Jupyter support
Browse files Browse the repository at this point in the history
  • Loading branch information
willmcgugan committed Apr 2, 2021
1 parent 53698d1 commit ebfab2d
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 23 deletions.
2 changes: 1 addition & 1 deletion rich/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -1681,7 +1681,7 @@ def _check_buffer(self) -> None:
if self.is_jupyter: # pragma: no cover
from .jupyter import display

display(self._buffer)
display(self._buffer, self._render_buffer(self._buffer[:]))
del self._buffer[:]
else:
text = self._render_buffer(self._buffer[:])
Expand Down
37 changes: 20 additions & 17 deletions rich/jupyter.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from typing import Iterable, List, TYPE_CHECKING
from typing import Iterable, List

from . import get_console
from .segment import Segment
from .terminal_theme import DEFAULT_TERMINAL_THEME

if TYPE_CHECKING:
from .console import RenderableType

JUPYTER_HTML_FORMAT = """\
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">{code}</pre>
Expand All @@ -15,28 +13,33 @@
class JupyterRenderable:
"""A shim to write html to Jupyter notebook."""

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

@classmethod
def render(cls, rich_renderable: "RenderableType") -> str:
console = get_console()
segments = console.render(rich_renderable, console.options)
html = _render_segments(segments)
return html

def _repr_html_(self) -> str:
return self.html
def _repr_mimebundle_(self, include, exclude, **kwargs):
data = {"text/plain": self.text, "text/html": self.html}
if include:
data = {k: v for (k, v) in data.items() if k in include}
if exclude:
data = {k: v for (k, v) in data.items() if k not in exclude}
return data


class JupyterMixin:
"""Add to an Rich renderable to make it render in Jupyter notebook."""

def _repr_html_(self) -> str:
def _repr_mimebundle_(self, include, exclude, **kwargs):
console = get_console()
segments = list(console.render(self, console.options)) # type: ignore
html = _render_segments(segments)
return html
text = console._render_buffer(segments)
data = {"text/plain": text, "text/html": html}
if include:
data = {k: v for (k, v) in data.items() if k in include}
if exclude:
data = {k: v for (k, v) in data.items() if k not in exclude}
return data


def _render_segments(segments: Iterable[Segment]) -> str:
Expand Down Expand Up @@ -64,12 +67,12 @@ def escape(text: str) -> str:
return html


def display(segments: Iterable[Segment]) -> None:
def display(segments: Iterable[Segment], text: str) -> None:
"""Render segments to Jupyter."""
from IPython.display import display as ipython_display

html = _render_segments(segments)
jupyter_renderable = JupyterRenderable(html)
jupyter_renderable = JupyterRenderable(html, text)
ipython_display(jupyter_renderable)


Expand Down
2 changes: 0 additions & 2 deletions rich/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
Union,
)

from typing_extensions import Literal

from ._ratio import ratio_resolve
from .align import Align
from .console import Console, ConsoleOptions, RenderableType, RenderResult
Expand Down
8 changes: 5 additions & 3 deletions rich/pretty.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from array import array
from collections import Counter, defaultdict, deque
from dataclasses import dataclass, fields, is_dataclass
import inspect
from itertools import islice
from typing import (
TYPE_CHECKING,
Expand All @@ -27,7 +26,7 @@
from .abc import RichRenderable
from .cells import cell_len
from .highlighter import ReprHighlighter
from .jupyter import JupyterRenderable
from .jupyter import JupyterMixin, JupyterRenderable
from .measure import Measurement
from .text import Text

Expand Down Expand Up @@ -99,6 +98,9 @@ def ipy_display_hook(value: Any) -> None: # pragma: no cover
if console.is_jupyter and any(attr.startswith("_repr_") for attr in dir(value)):
return

if hasattr(value, "_repr_mimebundle_"):
return

# certain renderables should start on a new line
if isinstance(value, ConsoleRenderable):
console.line()
Expand Down Expand Up @@ -130,7 +132,7 @@ def ipy_display_hook(value: Any) -> None: # pragma: no cover
sys.displayhook = display_hook


class Pretty:
class Pretty(JupyterMixin):
"""A rich renderable that pretty prints an object.
Args:
Expand Down

0 comments on commit ebfab2d

Please sign in to comment.