mirror of https://github.com/Textualize/rich.git
fixes
This commit is contained in:
parent
d359770970
commit
a49e595996
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [9.11.1] - Unreleased
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed table with expand=False not expanding when justify="center"
|
||||
- Fixed single renderable in Layout not respecting height
|
||||
- Fixed COLUMNS and LINES env var https://github.com/willmcgugan/rich/issues/1019
|
||||
- Layout now respects minimum_size when fixes sizes are greater than available space
|
||||
- HTML export now changes link underline score to match terminal https://github.com/willmcgugan/rich/issues/1009
|
||||
|
||||
### Changed
|
||||
|
||||
- python -m rich.markdown and rich.syntax show usage with no file
|
||||
|
||||
### Added
|
||||
|
||||
- Added height parameter to Layout
|
||||
|
||||
## [9.11.0] - 2021-02-15
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -4,18 +4,13 @@ Demonstration of Console.screen()
|
|||
|
||||
from time import sleep
|
||||
|
||||
from rich.console import Console
|
||||
from rich.align import Align
|
||||
from rich.text import Text
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
|
||||
console = Console()
|
||||
|
||||
with console.screen(style="bold white on red") as screen:
|
||||
for count in range(5, 0, -1):
|
||||
text = Align.center(
|
||||
Text.from_markup(f"[blink]Don't Panic![/blink]\n{count}", justify="center"),
|
||||
vertical="middle",
|
||||
)
|
||||
screen.update(Panel(text))
|
||||
sleep(1)
|
||||
text = Align.center("[blink]Don't Panic![/blink]", vertical="middle")
|
||||
screen.update(Panel(text))
|
||||
sleep(5)
|
||||
|
|
|
@ -42,7 +42,10 @@ def ratio_resolve(total: int, edges: Sequence[Edge]) -> List[int]:
|
|||
remaining = total - sum(size or 0 for size in sizes)
|
||||
if remaining <= 0:
|
||||
# No room for flexible edges
|
||||
return [(size or 1) for size in sizes]
|
||||
return [
|
||||
((edge.minimum_size or 1) if size is None else size)
|
||||
for size, edge in zip(sizes, edges)
|
||||
]
|
||||
# Calculate number of characters in a ratio portion
|
||||
portion = remaining / sum((edge.ratio or 1) for _, edge in flexible_edges)
|
||||
|
||||
|
|
|
@ -299,9 +299,7 @@ class ScreenContext:
|
|||
self.screen = Screen(style=style)
|
||||
self._changed = False
|
||||
|
||||
def update(
|
||||
self, renderable: RenderableType = None, style: StyleType = None
|
||||
) -> None:
|
||||
def update(self, *renderables: RenderableType, style: StyleType = None) -> None:
|
||||
"""Update the screen.
|
||||
|
||||
Args:
|
||||
|
@ -309,8 +307,10 @@ class ScreenContext:
|
|||
or None for no change. Defaults to None.
|
||||
style: (Style, optional): Replacement style, or None for no change. Defaults to None.
|
||||
"""
|
||||
if renderable is not None:
|
||||
self.screen.renderable = renderable
|
||||
if renderables:
|
||||
self.screen.renderable = (
|
||||
RenderGroup(*renderables) if len(renderables) > 1 else renderables[0]
|
||||
)
|
||||
if style is not None:
|
||||
self.screen.style = style
|
||||
self.console.print(self.screen, end="")
|
||||
|
@ -532,6 +532,16 @@ class Console:
|
|||
if self.is_jupyter:
|
||||
width = width or 93
|
||||
height = height or 100
|
||||
|
||||
if width is None:
|
||||
columns = self._environ.get("COLUMNS")
|
||||
if columns is not None and columns.isdigit():
|
||||
width = int(columns)
|
||||
if height is None:
|
||||
lines = self._environ.get("LINES")
|
||||
if lines is not None and lines.isdigit():
|
||||
height = int(lines)
|
||||
|
||||
self.soft_wrap = soft_wrap
|
||||
self._width = width
|
||||
self._height = height
|
||||
|
@ -1050,6 +1060,7 @@ class Console:
|
|||
*,
|
||||
style: Optional[Style] = None,
|
||||
pad: bool = True,
|
||||
new_lines: bool = False,
|
||||
) -> List[List[Segment]]:
|
||||
"""Render objects in to a list of lines.
|
||||
|
||||
|
@ -1061,7 +1072,7 @@ class Console:
|
|||
options (Optional[ConsoleOptions], optional): Console options, or None to use self.options. Default to ``None``.
|
||||
style (Style, optional): Optional style to apply to renderables. Defaults to ``None``.
|
||||
pad (bool, optional): Pad lines shorter than render width. Defaults to ``True``.
|
||||
range (Optional[Tuple[int, int]], optional): Range of lines to render, or ``None`` for all line. Defaults to ``None``
|
||||
new_lines (bool, optional): Include "\n" characters at end of line.
|
||||
|
||||
Returns:
|
||||
List[List[Segment]]: A list of lines, where a line is a list of Segment objects.
|
||||
|
@ -1072,7 +1083,10 @@ class Console:
|
|||
_rendered = Segment.apply_style(_rendered, style)
|
||||
lines = list(
|
||||
Segment.split_and_crop_lines(
|
||||
_rendered, render_options.max_width, include_new_lines=False, pad=pad
|
||||
_rendered,
|
||||
render_options.max_width,
|
||||
include_new_lines=new_lines,
|
||||
pad=pad,
|
||||
)
|
||||
)
|
||||
if render_options.height is not None:
|
||||
|
@ -1368,7 +1382,7 @@ class Console:
|
|||
for hook in self._render_hooks:
|
||||
renderables = hook.process_renderables(renderables)
|
||||
render_options = self.options.update(
|
||||
justify="default",
|
||||
justify=justify,
|
||||
overflow=overflow,
|
||||
width=min(width, self.width) if width else NO_CHANGE,
|
||||
height=height,
|
||||
|
@ -1697,9 +1711,9 @@ class Console:
|
|||
text = escape(text)
|
||||
if style:
|
||||
rule = style.get_html_style(_theme)
|
||||
text = f'<span style="{rule}">{text}</span>' if rule else text
|
||||
if style.link:
|
||||
text = f'<a href="{style.link}">{text}</a>'
|
||||
text = f'<span style="{rule}">{text}</span>' if rule else text
|
||||
append(text)
|
||||
else:
|
||||
styles: Dict[str, int] = {}
|
||||
|
@ -1709,11 +1723,11 @@ class Console:
|
|||
text = escape(text)
|
||||
if style:
|
||||
rule = style.get_html_style(_theme)
|
||||
if rule:
|
||||
style_number = styles.setdefault(rule, len(styles) + 1)
|
||||
text = f'<span class="r{style_number}">{text}</span>'
|
||||
style_number = styles.setdefault(rule, len(styles) + 1)
|
||||
if style.link:
|
||||
text = f'<a href="{style.link}">{text}</a>'
|
||||
text = f'<a class="r{style_number}" href="{style.link}">{text}</a>'
|
||||
else:
|
||||
text = f'<span class="r{style_number}">{text}</span>'
|
||||
append(text)
|
||||
stylesheet_rules: List[str] = []
|
||||
stylesheet_append = stylesheet_rules.append
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from .align import Align
|
||||
from .console import Console, ConsoleOptions, RenderResult, RenderableType
|
||||
from .highlighter import ReprHighlighter
|
||||
from ._loop import loop_last
|
||||
from .panel import Panel
|
||||
from .pretty import Pretty
|
||||
from ._ratio import ratio_resolve
|
||||
|
@ -77,6 +78,7 @@ class Layout:
|
|||
ratio: int = 1,
|
||||
name: str = None,
|
||||
visible: bool = True,
|
||||
height: int = None,
|
||||
) -> None:
|
||||
self._renderable = renderable or _Placeholder(self)
|
||||
self.direction = direction
|
||||
|
@ -85,6 +87,7 @@ class Layout:
|
|||
self.ratio = ratio
|
||||
self.name = name
|
||||
self.visible = visible
|
||||
self.height = height
|
||||
self._children: List[Layout] = []
|
||||
|
||||
def __repr__(self) -> str:
|
||||
|
@ -179,13 +182,19 @@ class Layout:
|
|||
def __rich_console__(
|
||||
self, console: Console, options: ConsoleOptions
|
||||
) -> RenderResult:
|
||||
options = options.update(height=options.height or options.size.height)
|
||||
render_options = options.update(
|
||||
height=options.height or self.height or options.size.height
|
||||
)
|
||||
if not self.children:
|
||||
yield from console.render(self._renderable or "", options)
|
||||
for line in console.render_lines(
|
||||
self._renderable or "", render_options, new_lines=True
|
||||
):
|
||||
yield from line
|
||||
|
||||
elif self.direction == "vertical":
|
||||
yield from self._render_vertical(console, options)
|
||||
yield from self._render_vertical(console, render_options)
|
||||
elif self.direction == "horizontal":
|
||||
yield from self._render_horizontal(console, options)
|
||||
yield from self._render_horizontal(console, render_options)
|
||||
|
||||
def _render_horizontal(
|
||||
self, console: Console, options: ConsoleOptions
|
||||
|
@ -206,14 +215,14 @@ class Layout:
|
|||
) -> RenderResult:
|
||||
render_heights = ratio_resolve(options.height or console.height, self.children)
|
||||
renders = [
|
||||
console.render_lines(child.renderable, options.update(height=render_height))
|
||||
console.render_lines(
|
||||
child.renderable, options.update(height=render_height), new_lines=True
|
||||
)
|
||||
for child, render_height in zip(self.children, render_heights)
|
||||
]
|
||||
new_line = Segment.line()
|
||||
for render in renders:
|
||||
for line in render:
|
||||
yield from line
|
||||
yield new_line
|
||||
|
||||
|
||||
if __name__ == "__main__": # type: ignore
|
||||
|
|
|
@ -40,7 +40,7 @@ class Live(JupyterMixin, RenderHook):
|
|||
screen (bool, optional): Enable alternate screen mode. Defaults to False.
|
||||
auto_refresh (bool, optional): Enable auto refresh. If disabled, you will need to call `refresh()` or `update()` with refresh flag. Defaults to True
|
||||
refresh_per_second (float, optional): Number of times per second to refresh the live display. Defaults to 1.
|
||||
transient (bool, optional): Clear the renderable on exit. Defaults to False.
|
||||
transient (bool, optional): Clear the renderable on exit (has no effect when screen=True). Defaults to False.
|
||||
redirect_stdout (bool, optional): Enable redirection of stdout, so ``print`` may be used. Defaults to True.
|
||||
redirect_stderr (bool, optional): Enable redirection of stderr. Defaults to True.
|
||||
vertical_overflow (VerticalOverflowMethod, optional): How to handle renderable when it is too tall for the console. Defaults to "ellipsis".
|
||||
|
@ -76,7 +76,7 @@ class Live(JupyterMixin, RenderHook):
|
|||
self.ipy_widget: Optional[Any] = None
|
||||
self.auto_refresh = auto_refresh
|
||||
self._started: bool = False
|
||||
self.transient = transient
|
||||
self.transient = True if screen else transient
|
||||
|
||||
self._refresh_thread: Optional[_RefreshThread] = None
|
||||
self.refresh_per_second = refresh_per_second
|
||||
|
@ -145,7 +145,7 @@ class Live(JupyterMixin, RenderHook):
|
|||
if self._refresh_thread is not None:
|
||||
self._refresh_thread.join()
|
||||
self._refresh_thread = None
|
||||
if self.transient and not self._screen:
|
||||
if self.transient and not self._alt_screen:
|
||||
self.console.control(self._live_render.restore_cursor())
|
||||
if self.ipy_widget is not None: # pragma: no cover
|
||||
if self.transient:
|
||||
|
|
|
@ -535,8 +535,7 @@ if __name__ == "__main__": # pragma: no cover
|
|||
parser.add_argument(
|
||||
"path",
|
||||
metavar="PATH",
|
||||
nargs="?",
|
||||
help="path to markdown file",
|
||||
help="path to markdown file, or - for stdin",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
|
@ -593,7 +592,7 @@ if __name__ == "__main__": # pragma: no cover
|
|||
|
||||
from rich.console import Console
|
||||
|
||||
if not args.path or args.path == "-":
|
||||
if args.path == "-":
|
||||
markdown_body = sys.stdin.read()
|
||||
else:
|
||||
with open(args.path, "rt", encoding="utf-8") as markdown_file:
|
||||
|
|
|
@ -122,3 +122,9 @@ class Padding(JupyterMixin):
|
|||
measurement = Measurement(measure_min + extra_width, measure_max + extra_width)
|
||||
measurement = measurement.with_maximum(max_width)
|
||||
return measurement
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
from rich import print
|
||||
|
||||
print(Padding("Hello, World", (2, 4), style="on blue"))
|
|
@ -192,15 +192,12 @@ if __name__ == "__main__": # pragma: no cover
|
|||
from .box import ROUNDED, DOUBLE
|
||||
|
||||
p = Panel(
|
||||
Panel.fit(
|
||||
Text.from_markup("[bold magenta]Hello World!"),
|
||||
box=ROUNDED,
|
||||
safe_box=True,
|
||||
style="on red",
|
||||
),
|
||||
title="[b]Hello, World",
|
||||
"Hello, World!",
|
||||
title="rich.Panel",
|
||||
style="white on blue",
|
||||
box=DOUBLE,
|
||||
padding=1,
|
||||
)
|
||||
|
||||
print(p)
|
||||
c.print()
|
||||
c.print(p)
|
||||
|
|
|
@ -192,7 +192,11 @@ class Pretty:
|
|||
no_wrap=pick_bool(self.no_wrap, options.no_wrap),
|
||||
style="pretty",
|
||||
)
|
||||
pretty_text = self.highlighter(pretty_text)
|
||||
pretty_text = (
|
||||
self.highlighter(pretty_text)
|
||||
if pretty_text
|
||||
else Text("__repr__ return empty string", style="dim italic")
|
||||
)
|
||||
if self.indent_guides and not options.ascii_only:
|
||||
pretty_text = pretty_text.with_indent_guides(
|
||||
self.indent_size, style="repr.indent"
|
||||
|
@ -209,7 +213,9 @@ class Pretty:
|
|||
max_length=self.max_length,
|
||||
max_string=self.max_string,
|
||||
)
|
||||
text_width = max(cell_len(line) for line in pretty_str.splitlines())
|
||||
text_width = (
|
||||
max(cell_len(line) for line in pretty_str.splitlines()) if pretty_str else 0
|
||||
)
|
||||
return Measurement(text_width, text_width)
|
||||
|
||||
|
||||
|
|
|
@ -384,9 +384,34 @@ class Segment(NamedTuple):
|
|||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
lines = [[Segment("Hello")]]
|
||||
lines = Segment.set_shape(lines, 50, 4, style=Style.parse("on blue"))
|
||||
for line in lines:
|
||||
print(line)
|
||||
from rich.syntax import Syntax
|
||||
from rich.text import Text
|
||||
from rich.console import Console
|
||||
|
||||
print(Style.parse("on blue") + Style.parse("on red"))
|
||||
code = """from rich.console import Console
|
||||
console = Console()
|
||||
text = Text.from_markup("Hello, [bold magenta]World[/]!")
|
||||
console.print(text)"""
|
||||
|
||||
text = Text.from_markup("Hello, [bold magenta]World[/]!")
|
||||
|
||||
console = Console()
|
||||
|
||||
console.rule("rich.Segment")
|
||||
console.print(
|
||||
"A Segment is the last step in the Rich render process before gemerating text with ANSI codes."
|
||||
)
|
||||
console.print("\nConsider the following code:\n")
|
||||
console.print(Syntax(code, "python", line_numbers=True))
|
||||
console.print()
|
||||
console.print(
|
||||
"When you call [b]print()[/b], Rich [i]renders[/i] the object in to the the following:\n"
|
||||
)
|
||||
fragments = list(console.render(text))
|
||||
console.print(fragments)
|
||||
console.print()
|
||||
console.print("The Segments are then processed to produce the following output:\n")
|
||||
console.print(text)
|
||||
console.print(
|
||||
"\nYou will only need to know this if you are implementing your own Rich renderables."
|
||||
)
|
||||
|
|
|
@ -512,6 +512,7 @@ class Style:
|
|||
if color is not None:
|
||||
theme_color = color.get_truecolor(theme)
|
||||
append(f"color: {theme_color.hex}")
|
||||
append(f"text-decoration-color: {theme_color.hex}")
|
||||
if bgcolor is not None:
|
||||
theme_color = bgcolor.get_truecolor(theme, foreground=False)
|
||||
append(f"background-color: {theme_color.hex}")
|
||||
|
|
|
@ -573,8 +573,7 @@ if __name__ == "__main__": # pragma: no cover
|
|||
parser.add_argument(
|
||||
"path",
|
||||
metavar="PATH",
|
||||
nargs="?",
|
||||
help="path to file",
|
||||
help="path to file, or - for stdin",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
|
@ -646,7 +645,7 @@ if __name__ == "__main__": # pragma: no cover
|
|||
|
||||
console = Console(force_terminal=args.force_color, width=args.width)
|
||||
|
||||
if not args.path or args.path == "-":
|
||||
if args.path == "-":
|
||||
code = sys.stdin.read()
|
||||
syntax = Syntax(
|
||||
code=code,
|
||||
|
|
|
@ -851,7 +851,7 @@ if __name__ == "__main__": # pragma: no cover
|
|||
|
||||
table.expand = True
|
||||
header("expand=True")
|
||||
console.print(table, justify="center")
|
||||
console.print(table)
|
||||
|
||||
table.width = 50
|
||||
header("width=50")
|
||||
|
|
37
rich/text.py
37
rich/text.py
|
@ -1114,20 +1114,27 @@ class Text(JupyterMixin):
|
|||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
from rich import print
|
||||
from rich.console import Console
|
||||
|
||||
text = Text("<span>\n\tHello\n</span>")
|
||||
text.expand_tabs(4)
|
||||
print(text)
|
||||
text = Text(
|
||||
"""\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n"""
|
||||
)
|
||||
text.highlight_words(["Lorem"], "bold")
|
||||
text.highlight_words(["ipsum"], "italic")
|
||||
|
||||
code = """
|
||||
def __add__(self, other: Any) -> "Text":
|
||||
if isinstance(other, (str, Text)):
|
||||
result = self.copy()
|
||||
result.append(other)
|
||||
return result
|
||||
return NotImplemented
|
||||
"""
|
||||
text = Text(code)
|
||||
text = text.with_indent_guides()
|
||||
print(text)
|
||||
console = Console()
|
||||
console.rule("justify='left'")
|
||||
console.print(text, style="red")
|
||||
console.print()
|
||||
|
||||
console.rule("justify='center'")
|
||||
console.print(text, style="green", justify="center")
|
||||
console.print()
|
||||
|
||||
console.rule("justify='right'")
|
||||
console.print(text, style="blue", justify="right")
|
||||
console.print()
|
||||
|
||||
console.rule("justify='full'")
|
||||
console.print(text, style="magenta", justify="full")
|
||||
console.print()
|
|
@ -349,7 +349,7 @@ def test_export_html():
|
|||
console = Console(record=True, width=100)
|
||||
console.print("[b]foo [link=https://example.org]Click[/link]")
|
||||
html = console.export_html()
|
||||
expected = '<!DOCTYPE html>\n<head>\n<meta charset="UTF-8">\n<style>\n.r1 {font-weight: bold}\nbody {\n color: #000000;\n background-color: #ffffff;\n}\n</style>\n</head>\n<html>\n<body>\n <code>\n <pre style="font-family:Menlo,\'DejaVu Sans Mono\',consolas,\'Courier New\',monospace"><span class="r1">foo </span><a href="https://example.org"><span class="r1">Click</span></a>\n</pre>\n </code>\n</body>\n</html>\n'
|
||||
expected = '<!DOCTYPE html>\n<head>\n<meta charset="UTF-8">\n<style>\n.r1 {font-weight: bold}\nbody {\n color: #000000;\n background-color: #ffffff;\n}\n</style>\n</head>\n<html>\n<body>\n <code>\n <pre style="font-family:Menlo,\'DejaVu Sans Mono\',consolas,\'Courier New\',monospace"><span class="r1">foo </span><a class="r1" href="https://example.org">Click</a>\n</pre>\n </code>\n</body>\n</html>\n'
|
||||
assert html == expected
|
||||
|
||||
|
||||
|
@ -357,7 +357,8 @@ def test_export_html_inline():
|
|||
console = Console(record=True, width=100)
|
||||
console.print("[b]foo [link=https://example.org]Click[/link]")
|
||||
html = console.export_html(inline_styles=True)
|
||||
expected = '<!DOCTYPE html>\n<head>\n<meta charset="UTF-8">\n<style>\n\nbody {\n color: #000000;\n background-color: #ffffff;\n}\n</style>\n</head>\n<html>\n<body>\n <code>\n <pre style="font-family:Menlo,\'DejaVu Sans Mono\',consolas,\'Courier New\',monospace"><span style="font-weight: bold">foo </span><a href="https://example.org"><span style="font-weight: bold">Click</span></a>\n</pre>\n </code>\n</body>\n</html>\n'
|
||||
print(repr(html))
|
||||
expected = '<!DOCTYPE html>\n<head>\n<meta charset="UTF-8">\n<style>\n\nbody {\n color: #000000;\n background-color: #ffffff;\n}\n</style>\n</head>\n<html>\n<body>\n <code>\n <pre style="font-family:Menlo,\'DejaVu Sans Mono\',consolas,\'Courier New\',monospace"><span style="font-weight: bold">foo </span><span style="font-weight: bold"><a href="https://example.org">Click</a></span>\n</pre>\n </code>\n</body>\n</html>\n'
|
||||
assert html == expected
|
||||
|
||||
|
||||
|
@ -543,3 +544,23 @@ def test_screen_update():
|
|||
def test_height():
|
||||
console = Console(width=80, height=46)
|
||||
assert console.height == 46
|
||||
|
||||
|
||||
def test_columns_env():
|
||||
console = Console(_environ={"COLUMNS": "314"})
|
||||
assert console.width == 314
|
||||
# width take precedence
|
||||
console = Console(width=40, _environ={"COLUMNS": "314"})
|
||||
assert console.width == 40
|
||||
# Should not fail
|
||||
console = Console(width=40, _environ={"COLUMNS": "broken"})
|
||||
|
||||
|
||||
def test_lines_env():
|
||||
console = Console(_environ={"LINES": "220"})
|
||||
assert console.height == 220
|
||||
# height take precedence
|
||||
console = Console(height=40, _environ={"LINES": "220"})
|
||||
assert console.height == 40
|
||||
# Should not fail
|
||||
console = Console(width=40, _environ={"LINES": "broken"})
|
|
@ -143,3 +143,11 @@ def test_newline():
|
|||
result = console.end_capture()
|
||||
expected = "\n(\n 1,\n)\n"
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_empty_repr():
|
||||
class Foo:
|
||||
def __repr__(self):
|
||||
return ""
|
||||
|
||||
assert pretty_repr(Foo()) == ""
|
|
@ -48,3 +48,6 @@ def test_ratio_resolve():
|
|||
33,
|
||||
34,
|
||||
]
|
||||
assert ratio_resolve(
|
||||
50, [Edge(size=30), Edge(ratio=1, minimum_size=10), Edge(size=30)]
|
||||
) == [30, 10, 30]
|
||||
|
|
|
@ -122,21 +122,20 @@ def test_link_id():
|
|||
|
||||
|
||||
def test_get_html_style():
|
||||
expected = "color: #7f7fbf; background-color: #800000; font-weight: bold; font-style: italic; text-decoration: underline; text-decoration: line-through; text-decoration: overline"
|
||||
assert (
|
||||
Style(
|
||||
reverse=True,
|
||||
dim=True,
|
||||
color="red",
|
||||
bgcolor="blue",
|
||||
bold=True,
|
||||
italic=True,
|
||||
underline=True,
|
||||
strike=True,
|
||||
overline=True,
|
||||
).get_html_style()
|
||||
== expected
|
||||
)
|
||||
expected = "color: #7f7fbf; text-decoration-color: #7f7fbf; background-color: #800000; font-weight: bold; font-style: italic; text-decoration: underline; text-decoration: line-through; text-decoration: overline"
|
||||
html_style = Style(
|
||||
reverse=True,
|
||||
dim=True,
|
||||
color="red",
|
||||
bgcolor="blue",
|
||||
bold=True,
|
||||
italic=True,
|
||||
underline=True,
|
||||
strike=True,
|
||||
overline=True,
|
||||
).get_html_style()
|
||||
print(repr(html_style))
|
||||
assert html_style == expected
|
||||
|
||||
|
||||
def test_chain():
|
||||
|
|
|
@ -21,13 +21,15 @@ def render_tables():
|
|||
color_system=None,
|
||||
)
|
||||
|
||||
table = Table(title="test table", caption="table caption", expand=True)
|
||||
table = Table(title="test table", caption="table caption", expand=False)
|
||||
table.add_column("foo", footer=Text("total"), no_wrap=True, overflow="ellipsis")
|
||||
table.add_column("bar", justify="center")
|
||||
table.add_column("baz", justify="right")
|
||||
|
||||
table.add_row("Averlongwordgoeshere", "banana pancakes", None)
|
||||
|
||||
assert Measurement.get(console, table, 80) == Measurement(41, 48)
|
||||
table.expand = True
|
||||
assert Measurement.get(console, table, 80) == Measurement(41, 48)
|
||||
|
||||
for width in range(10, 60, 5):
|
||||
|
@ -63,6 +65,9 @@ def render_tables():
|
|||
|
||||
table.width = 20
|
||||
assert Measurement.get(console, table, 80) == Measurement(20, 20)
|
||||
table.expand = False
|
||||
assert Measurement.get(console, table, 80) == Measurement(20, 20)
|
||||
table.expand = True
|
||||
console.print(table)
|
||||
|
||||
table.columns[0].no_wrap = True
|
||||
|
|
Loading…
Reference in New Issue