diff --git a/CHANGELOG.md b/CHANGELOG.md index 2488482a..7ae9e90f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added rich.reconfigure - Added `Color.__rich__` - Added Console.style parameter +- Added Table.highlight parameter to enable highlighting of cells +- Added Panel.highlight parameter to enable highlighting of panel title +- Added highlight to ConsoleOptions ### Fixed diff --git a/rich/console.py b/rich/console.py index d2915e7f..723437c1 100644 --- a/rich/console.py +++ b/rich/console.py @@ -102,6 +102,8 @@ class ConsoleOptions: """Overflow value override for renderable.""" no_wrap: Optional[bool] = False """Disable wrapping for text.""" + highlight: Optional[bool] = None + """Highlight override for render_str.""" @property def ascii_only(self) -> bool: @@ -116,6 +118,7 @@ class ConsoleOptions: justify: JustifyMethod = None, overflow: OverflowMethod = None, no_wrap: bool = None, + highlight: bool = None, ) -> "ConsoleOptions": """Update values, return a copy.""" options = replace(self) @@ -131,6 +134,8 @@ class ConsoleOptions: options.overflow = overflow if no_wrap is not None: options.no_wrap = no_wrap + if highlight is not None: + options.highlight = highlight return options @@ -857,7 +862,9 @@ class Console: if isinstance(renderable, ConsoleRenderable): render_iterable = renderable.__rich_console__(self, _options) elif isinstance(renderable, str): - yield from self.render(self.render_str(renderable), _options) + yield from self.render( + self.render_str(renderable, highlight=options.highlight), _options + ) return else: raise errors.NotRenderableError( @@ -919,6 +926,7 @@ class Console: overflow: OverflowMethod = None, emoji: bool = None, markup: bool = None, + highlight: bool = None, highlighter: HighlighterType = None, ) -> "Text": """Convert a string to a Text instance. This is is called automatically if @@ -931,6 +939,7 @@ class Console: overflow (str, optional): Overflow method: "crop", "fold", or "ellipsis". Defaults to ``None``. emoji (Optional[bool], optional): Enable emoji, or ``None`` to use Console default. markup (Optional[bool], optional): Enable markup, or ``None`` to use Console default. + highlight (Optional[bool], optional): Enable highlighting, or ``None`` to use Console default. highlighter (HighlighterType, optional): Optional highlighter to apply. Returns: ConsoleRenderable: Renderable object. @@ -938,6 +947,7 @@ class Console: """ emoji_enabled = emoji or (emoji is None and self._emoji) markup_enabled = markup or (markup is None and self._markup) + highlight_enabled = highlight or (highlight is None and self._highlight) if markup_enabled: rich_text = render_markup(text, style=style, emoji=emoji_enabled) @@ -951,8 +961,9 @@ class Console: style=style, ) - if highlighter is not None: - highlight_text = highlighter(str(rich_text)) + _highlighter = (highlighter or self.highlighter) if highlight_enabled else None + if _highlighter is not None: + highlight_text = _highlighter(str(rich_text)) highlight_text.copy_styles(rich_text) return highlight_text @@ -1041,10 +1052,7 @@ class Console: if isinstance(renderable, str): append_text( self.render_str( - renderable, - emoji=emoji, - markup=markup, - highlighter=_highlighter, + renderable, emoji=emoji, markup=markup, highlighter=_highlighter ) ) elif isinstance(renderable, ConsoleRenderable): diff --git a/rich/panel.py b/rich/panel.py index efb3d131..c1d3edf1 100644 --- a/rich/panel.py +++ b/rich/panel.py @@ -31,6 +31,7 @@ class Panel(JupyterMixin): border_style (str, optional): The style of the border. Defaults to "none". width (Optional[int], optional): Optional width of panel. Defaults to None to auto-detect. padding (Optional[PaddingDimensions]): Optional padding around renderable. Defaults to 0. + highlight (bool, optional): Enable automatic highlighting of panel title (if str). Defaults to False. """ def __init__( @@ -46,6 +47,7 @@ class Panel(JupyterMixin): border_style: StyleType = "none", width: Optional[int] = None, padding: PaddingDimensions = (0, 1), + highlight: bool = False, ) -> None: self.renderable = renderable self.box = box @@ -57,6 +59,7 @@ class Panel(JupyterMixin): self.border_style = border_style self.width = width self.padding = padding + self.highlight = highlight @classmethod def fit( @@ -131,7 +134,7 @@ class Panel(JupyterMixin): ) width = child_width + 2 - child_options = options.update(width=child_width) + child_options = options.update(width=child_width, highlight=self.highlight) lines = console.render_lines(renderable, child_options, style=style) line_start = Segment(box.mid_left, border_style) diff --git a/rich/table.py b/rich/table.py index 81aa6016..5115106c 100644 --- a/rich/table.py +++ b/rich/table.py @@ -129,6 +129,7 @@ class Table(JupyterMixin): caption_style (Union[str, Style], optional): Style of the caption. Defaults to None. title_justify (str, optional): Justify method for title. Defaults to "center". caption_justify (str, optional): Justify method for caption. Defaults to "center". + highlight (bool, optional): Highlight cell contents (if str). Defaults to False. """ columns: List[Column] @@ -161,6 +162,7 @@ class Table(JupyterMixin): caption_style: StyleType = None, title_justify: "JustifyMethod" = "center", caption_justify: "JustifyMethod" = "center", + highlight: bool = False ) -> None: self.columns: List[Column] = [] @@ -196,6 +198,7 @@ class Table(JupyterMixin): self.caption_style = caption_style self.title_justify = title_justify self.caption_justify = caption_justify + self.highlight = highlight self.row_styles = list(row_styles or []) @classmethod @@ -413,13 +416,15 @@ class Table(JupyterMixin): widths = self._calculate_column_widths(console, max_width - extra_width) table_width = sum(widths) + extra_width - render_options = options.update(width=table_width) + render_options = options.update(width=table_width, highlight=self.highlight) def render_annotation( text: TextType, style: StyleType, justify: "JustifyMethod" = "center" ) -> "RenderResult": render_text = ( - console.render_str(text, style=style) if isinstance(text, str) else text + console.render_str(text, style=style, highlight=False) + if isinstance(text, str) + else text ) return console.render( render_text, options=render_options.update(justify=justify)