ansi and tests

This commit is contained in:
Will McGugan 2020-11-05 18:41:49 +00:00
parent d88a08eaf6
commit 8294fee361
7 changed files with 65 additions and 13 deletions

View file

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added tracebacks_show_locals parameter to RichHandler
- Applied dim=True to indent guide styles
- Added max_string to Pretty
- Added rich.ansi.AnsiDecoder
## [9.1.0] - 2020-10-23

View file

@ -18,6 +18,7 @@ Reference
reference/measure.rst
reference/padding.rst
reference/panel.rst
reference/pretty.rst
reference/progress.rst
reference/progress_bar.rst
reference/prompt.rst

View file

@ -0,0 +1,6 @@
rich.pretty
===========
.. automodule:: rich.pretty
:members:

View file

@ -146,12 +146,13 @@ class AnsiDecoder:
if osc.startswith("8;"):
_params, semicolon, link = osc[2:].partition(";")
if semicolon:
self.style = self.style.update_link(link)
self.style = self.style.update_link(link or None)
elif sgr:
# Translate in to semi-colon separated codes
# Ignore invalid codes, because we want to be lenient
codes = [int(_code) for _code in sgr.split(";") if _code.isdigit()]
codes = [code for code in codes if code <= 255]
codes = [
min(255, int(_code)) for _code in sgr.split(";") if _code.isdigit()
]
iter_codes = iter(codes)
for code in iter_codes:
if code == 0:
@ -163,15 +164,21 @@ class AnsiDecoder:
color_type = next(iter_codes)
if color_type == 5:
color = from_ansi(next(iter_codes))
self.style += (
_Style(color=color)
if code == 38
else _Style(bgcolor=color)
)
elif color_type == 2:
color = from_rgb(
next(iter_codes), next(iter_codes), next(iter_codes)
)
else:
continue
self.style += (
_Style(color=color) if code == 38 else _Style(bgcolor=color)
)
self.style += (
_Style(color=color)
if code == 38
else _Style(bgcolor=color)
)
return text

View file

@ -27,7 +27,7 @@ from typing import (
)
from . import filesize, get_console
from .progress_bar import ProgressBar
from .ansi import AnsiDecoder
from .console import (
Console,
ConsoleRenderable,
@ -40,6 +40,7 @@ from .control import Control
from .highlighter import Highlighter
from .jupyter import JupyterMixin
from .live_render import LiveRender
from .progress_bar import ProgressBar
from .style import StyleType
from .table import Table
from .text import Text
@ -480,6 +481,7 @@ class _FileProxy(io.TextIOBase):
self.__console = console
self.__file = file
self.__buffer: List[str] = []
self.__ansi_decoder = AnsiDecoder()
def __getattr__(self, name: str) -> Any:
return getattr(self.__file, name)
@ -498,7 +500,9 @@ class _FileProxy(io.TextIOBase):
if lines:
console = self.__console
with console:
output = "\n".join(lines)
output = Text("\n").join(
self.__ansi_decoder.decode_line(line) for line in lines
)
console.print(output, markup=False, emoji=False, highlight=False)
return len(text)
@ -846,8 +850,8 @@ class Progress(JupyterMixin, RenderHook):
"""Refresh (render) the progress information."""
if self.console.is_jupyter: # pragma: no cover
try:
from ipywidgets import Output
from IPython.display import display
from ipywidgets import Output
except ImportError:
import warnings
@ -974,13 +978,13 @@ class Progress(JupyterMixin, RenderHook):
if __name__ == "__main__": # pragma: no coverage
import time
import random
import time
from .panel import Panel
from .rule import Rule
from .syntax import Syntax
from .table import Table
from .rule import Rule
syntax = Syntax(
'''def loop_last(values: Iterable[T]) -> Iterable[Tuple[bool, T]]:

29
tests/test_ansi.py Normal file
View file

@ -0,0 +1,29 @@
import io
from rich.ansi import AnsiDecoder
from rich.console import Console
from rich.style import Style
from rich.text import Span, Text
def test_decode():
console = Console(force_terminal=True, color_system="truecolor")
console.begin_capture()
console.print("Hello")
console.print("[b]foo[/b]")
console.print("[link http://example.org]bar")
console.print("[#ff0000 on color(200)]red")
terminal_codes = console.end_capture()
decoder = AnsiDecoder()
lines = list(decoder.decode(terminal_codes))
parse = Style.parse
expected = [
Text("Hello"),
Text("foo", spans=[Span(0, 3, parse("bold"))]),
Text("bar", spans=[Span(0, 3, parse("link http://example.org"))]),
Text("red", spans=[Span(0, 3, parse("#ff0000 on color(200)"))]),
]
assert lines == expected

View file

@ -73,6 +73,10 @@ def test_from_rgb() -> None:
)
def test_from_ansi() -> None:
assert Color.from_ansi(1) == Color("color(1)", ColorType.STANDARD, 1)
def test_default() -> None:
assert Color.default() == Color("default", ColorType.DEFAULT, None, None)