mirror of
https://github.com/httpie/cli.git
synced 2025-02-20 03:20:50 +01:00
Refactor the color system
This commit is contained in:
parent
8173cb0337
commit
ad5f01635b
@ -18,7 +18,7 @@ from .config import DEFAULT_CONFIG_DIR, Config, ConfigFileError
|
|||||||
from .encoding import UTF8
|
from .encoding import UTF8
|
||||||
|
|
||||||
from .utils import repr_dict
|
from .utils import repr_dict
|
||||||
from .output.ui.palette import GenericColor
|
from .output.ui.palette import RichColor
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
@ -31,9 +31,9 @@ class LogLevel(str, Enum):
|
|||||||
|
|
||||||
|
|
||||||
LOG_LEVEL_COLORS = {
|
LOG_LEVEL_COLORS = {
|
||||||
LogLevel.INFO: GenericColor.PINK,
|
LogLevel.INFO: RichColor.PINK,
|
||||||
LogLevel.WARNING: GenericColor.ORANGE,
|
LogLevel.WARNING: RichColor.ORANGE,
|
||||||
LogLevel.ERROR: GenericColor.RED,
|
LogLevel.ERROR: RichColor.RED,
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_LEVEL_DISPLAY_THRESHOLDS = {
|
LOG_LEVEL_DISPLAY_THRESHOLDS = {
|
||||||
@ -191,10 +191,10 @@ class Environment:
|
|||||||
force_terminal: bool
|
force_terminal: bool
|
||||||
) -> 'Console':
|
) -> 'Console':
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from httpie.output.ui.rich_palette import _make_rich_color_theme
|
from httpie.output.ui.palette import make_rich_theme_from_style
|
||||||
|
|
||||||
style = getattr(self.args, 'style', None)
|
style = getattr(self.args, 'style', None)
|
||||||
theme = _make_rich_color_theme(style)
|
theme = make_rich_theme_from_style(style)
|
||||||
# Rich infers the rest of the knowledge (e.g encoding)
|
# Rich infers the rest of the knowledge (e.g encoding)
|
||||||
# dynamically by looking at the file/stderr.
|
# dynamically by looking at the file/stderr.
|
||||||
return Console(
|
return Console(
|
||||||
|
3
httpie/output/ui/palette/__init__.py
Normal file
3
httpie/output/ui/palette/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from httpie.output.ui.palette.pie import AUTO_STYLE, SHADE_TO_PIE_STYLE, PieStyle, PieColor, ColorString, get_color # noqa
|
||||||
|
from httpie.output.ui.palette.rich import RichColor, make_rich_theme_from_style
|
||||||
|
from httpie.output.ui.palette.utils import ColorString
|
18
httpie/output/ui/palette/custom_styles.py
Normal file
18
httpie/output/ui/palette/custom_styles.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from httpie.output.ui.palette.rich import RichColor
|
||||||
|
from httpie.output.ui.palette.utils import ColorString
|
||||||
|
|
||||||
|
RICH_BOLD = ColorString('bold')
|
||||||
|
|
||||||
|
# Rich-specific color code declarations
|
||||||
|
# <https://github.com/Textualize/rich/blob/fcd684dd3a482977cab620e71ccaebb94bf13ac9/rich/default_styles.py>
|
||||||
|
RICH_CUSTOM_STYLES = {
|
||||||
|
'progress.description': RICH_BOLD | RichColor.WHITE,
|
||||||
|
'progress.data.speed': RICH_BOLD | RichColor.GREEN,
|
||||||
|
'progress.percentage': RICH_BOLD | RichColor.AQUA,
|
||||||
|
'progress.download': RICH_BOLD | RichColor.AQUA,
|
||||||
|
'progress.remaining': RICH_BOLD | RichColor.ORANGE,
|
||||||
|
'bar.complete': RICH_BOLD | RichColor.PURPLE,
|
||||||
|
'bar.finished': RICH_BOLD | RichColor.GREEN,
|
||||||
|
'bar.pulse': RICH_BOLD | RichColor.PURPLE,
|
||||||
|
'option': RICH_BOLD | RichColor.PINK,
|
||||||
|
}
|
@ -1,18 +1,12 @@
|
|||||||
from dataclasses import dataclass, field
|
from enum import Enum
|
||||||
from enum import Enum, auto
|
from typing import Optional
|
||||||
from typing import Optional, List
|
from httpie.output.ui.palette.utils import ColorString
|
||||||
|
|
||||||
|
|
||||||
PYGMENTS_BRIGHT_BLACK = 'ansibrightblack'
|
PYGMENTS_BRIGHT_BLACK = 'ansibrightblack'
|
||||||
|
|
||||||
AUTO_STYLE = 'auto' # Follows terminal ANSI color styles
|
AUTO_STYLE = 'auto' # Follows terminal ANSI color styles
|
||||||
|
|
||||||
|
|
||||||
class Styles(Enum):
|
|
||||||
PIE = auto()
|
|
||||||
ANSI = auto()
|
|
||||||
|
|
||||||
|
|
||||||
class PieStyle(str, Enum):
|
class PieStyle(str, Enum):
|
||||||
UNIVERSAL = 'pie'
|
UNIVERSAL = 'pie'
|
||||||
DARK = 'pie-dark'
|
DARK = 'pie-dark'
|
||||||
@ -24,34 +18,11 @@ PIE_STYLE_TO_SHADE = {
|
|||||||
PieStyle.UNIVERSAL: '600',
|
PieStyle.UNIVERSAL: '600',
|
||||||
PieStyle.LIGHT: '700',
|
PieStyle.LIGHT: '700',
|
||||||
}
|
}
|
||||||
|
|
||||||
SHADE_TO_PIE_STYLE = {
|
SHADE_TO_PIE_STYLE = {
|
||||||
shade: style for style, shade in PIE_STYLE_TO_SHADE.items()
|
shade: style for style, shade in PIE_STYLE_TO_SHADE.items()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ColorString(str):
|
|
||||||
def __or__(self, other: str) -> 'ColorString':
|
|
||||||
"""Combine a style with a property.
|
|
||||||
|
|
||||||
E.g: PieColor.BLUE | BOLD | ITALIC
|
|
||||||
"""
|
|
||||||
if isinstance(other, str):
|
|
||||||
# In case of PieColor.BLUE | SOMETHING
|
|
||||||
# we just create a new string.
|
|
||||||
return ColorString(self + ' ' + other)
|
|
||||||
elif isinstance(other, GenericColor):
|
|
||||||
# If we see a GenericColor, then we'll wrap it
|
|
||||||
# in with the desired property in a different class.
|
|
||||||
return _StyledGenericColor(other, styles=self.split())
|
|
||||||
elif isinstance(other, _StyledGenericColor):
|
|
||||||
# And if it is already wrapped, we'll just extend the
|
|
||||||
# list of properties.
|
|
||||||
other.styles.extend(self.split())
|
|
||||||
return other
|
|
||||||
else:
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
|
|
||||||
class PieColor(ColorString, Enum):
|
class PieColor(ColorString, Enum):
|
||||||
"""Styles that are available only in Pie themes."""
|
"""Styles that are available only in Pie themes."""
|
||||||
|
|
||||||
@ -71,42 +42,6 @@ class PieColor(ColorString, Enum):
|
|||||||
YELLOW = 'yellow'
|
YELLOW = 'yellow'
|
||||||
|
|
||||||
|
|
||||||
class GenericColor(Enum):
|
|
||||||
"""Generic colors that are safe to use everywhere."""
|
|
||||||
|
|
||||||
# <https://rich.readthedocs.io/en/stable/appendix/colors.html>
|
|
||||||
|
|
||||||
WHITE = {Styles.PIE: PieColor.WHITE, Styles.ANSI: 'white'}
|
|
||||||
BLACK = {Styles.PIE: PieColor.BLACK, Styles.ANSI: 'black'}
|
|
||||||
GREEN = {Styles.PIE: PieColor.GREEN, Styles.ANSI: 'green'}
|
|
||||||
ORANGE = {Styles.PIE: PieColor.ORANGE, Styles.ANSI: 'yellow'}
|
|
||||||
YELLOW = {Styles.PIE: PieColor.YELLOW, Styles.ANSI: 'bright_yellow'}
|
|
||||||
BLUE = {Styles.PIE: PieColor.BLUE, Styles.ANSI: 'blue'}
|
|
||||||
PINK = {Styles.PIE: PieColor.PINK, Styles.ANSI: 'bright_magenta'}
|
|
||||||
PURPLE = {Styles.PIE: PieColor.PURPLE, Styles.ANSI: 'magenta'}
|
|
||||||
RED = {Styles.PIE: PieColor.RED, Styles.ANSI: 'red'}
|
|
||||||
AQUA = {Styles.PIE: PieColor.AQUA, Styles.ANSI: 'cyan'}
|
|
||||||
GREY = {Styles.PIE: PieColor.GREY, Styles.ANSI: 'bright_black'}
|
|
||||||
|
|
||||||
def apply_style(
|
|
||||||
self, style: Styles, *, style_name: Optional[str] = None
|
|
||||||
) -> str:
|
|
||||||
"""Apply the given style to a particular value."""
|
|
||||||
exposed_color = self.value[style]
|
|
||||||
if style is Styles.PIE:
|
|
||||||
assert style_name is not None
|
|
||||||
shade = PIE_STYLE_TO_SHADE[PieStyle(style_name)]
|
|
||||||
return get_color(exposed_color, shade)
|
|
||||||
else:
|
|
||||||
return exposed_color
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class _StyledGenericColor:
|
|
||||||
color: 'GenericColor'
|
|
||||||
styles: List[str] = field(default_factory=list)
|
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyDictCreation
|
# noinspection PyDictCreation
|
||||||
COLOR_PALETTE = {
|
COLOR_PALETTE = {
|
||||||
# Copy the brand palette
|
# Copy the brand palette
|
||||||
@ -252,10 +187,6 @@ COLOR_PALETTE.update(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def boldify(color: PieColor) -> str:
|
|
||||||
return f'bold {color}'
|
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyDefaultArgument
|
# noinspection PyDefaultArgument
|
||||||
def get_color(
|
def get_color(
|
||||||
color: PieColor, shade: str, *, palette=COLOR_PALETTE
|
color: PieColor, shade: str, *, palette=COLOR_PALETTE
|
111
httpie/output/ui/palette/rich.py
Normal file
111
httpie/output/ui/palette/rich.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
from collections import ChainMap
|
||||||
|
from typing import TYPE_CHECKING, Any, Optional, List
|
||||||
|
from enum import Enum, auto
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from rich.theme import Theme
|
||||||
|
|
||||||
|
from httpie.output.ui.palette.pie import (
|
||||||
|
PIE_STYLE_TO_SHADE,
|
||||||
|
PieStyle,
|
||||||
|
PieColor,
|
||||||
|
get_color,
|
||||||
|
) # noqa
|
||||||
|
|
||||||
|
|
||||||
|
class RichTheme(Enum):
|
||||||
|
"""Represents the color theme to use within rich."""
|
||||||
|
PIE = auto()
|
||||||
|
ANSI = auto()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_style_name(cls, style_name: str) -> 'RichTheme':
|
||||||
|
try:
|
||||||
|
PieStyle(style_name)
|
||||||
|
except ValueError:
|
||||||
|
return RichTheme.ANSI
|
||||||
|
else:
|
||||||
|
return RichTheme.PIE
|
||||||
|
|
||||||
|
|
||||||
|
class RichColor(Enum):
|
||||||
|
"""Generic colors that are safe to use everywhere within rich."""
|
||||||
|
|
||||||
|
# <https://rich.readthedocs.io/en/stable/appendix/colors.html>
|
||||||
|
|
||||||
|
WHITE = {RichTheme.PIE: PieColor.WHITE, RichTheme.ANSI: 'white'}
|
||||||
|
BLACK = {RichTheme.PIE: PieColor.BLACK, RichTheme.ANSI: 'black'}
|
||||||
|
GREEN = {RichTheme.PIE: PieColor.GREEN, RichTheme.ANSI: 'green'}
|
||||||
|
ORANGE = {RichTheme.PIE: PieColor.ORANGE, RichTheme.ANSI: 'yellow'}
|
||||||
|
YELLOW = {RichTheme.PIE: PieColor.YELLOW, RichTheme.ANSI: 'bright_yellow'}
|
||||||
|
BLUE = {RichTheme.PIE: PieColor.BLUE, RichTheme.ANSI: 'blue'}
|
||||||
|
PINK = {RichTheme.PIE: PieColor.PINK, RichTheme.ANSI: 'bright_magenta'}
|
||||||
|
PURPLE = {RichTheme.PIE: PieColor.PURPLE, RichTheme.ANSI: 'magenta'}
|
||||||
|
RED = {RichTheme.PIE: PieColor.RED, RichTheme.ANSI: 'red'}
|
||||||
|
AQUA = {RichTheme.PIE: PieColor.AQUA, RichTheme.ANSI: 'cyan'}
|
||||||
|
GREY = {RichTheme.PIE: PieColor.GREY, RichTheme.ANSI: 'bright_black'}
|
||||||
|
|
||||||
|
def apply_theme(
|
||||||
|
self, style: RichTheme, *, style_name: Optional[str] = None
|
||||||
|
) -> str:
|
||||||
|
"""Apply the given style to a particular value."""
|
||||||
|
exposed_color = self.value[style]
|
||||||
|
if style is RichTheme.PIE:
|
||||||
|
assert style_name is not None
|
||||||
|
shade = PIE_STYLE_TO_SHADE[PieStyle(style_name)]
|
||||||
|
return get_color(exposed_color, shade)
|
||||||
|
else:
|
||||||
|
return exposed_color
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class _StyledRichColor:
|
||||||
|
color: RichColor
|
||||||
|
styles: List[str] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
|
class _RichColorCaster(dict):
|
||||||
|
"""
|
||||||
|
Translate RichColor to a regular string on the attribute access
|
||||||
|
phase.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _translate(self, key: Any) -> Any:
|
||||||
|
if isinstance(key, RichColor):
|
||||||
|
return key.name.lower()
|
||||||
|
else:
|
||||||
|
return key
|
||||||
|
|
||||||
|
def __getitem__(self, key: Any) -> Any:
|
||||||
|
return super().__getitem__(self._translate(key))
|
||||||
|
|
||||||
|
def get(self, key: Any) -> Any:
|
||||||
|
return super().get(self._translate(key))
|
||||||
|
|
||||||
|
|
||||||
|
def make_rich_theme_from_style(style_name: Optional[str] = None) -> 'Theme':
|
||||||
|
from rich.style import Style
|
||||||
|
from rich.theme import Theme
|
||||||
|
from httpie.output.ui.palette.custom_styles import RICH_CUSTOM_STYLES
|
||||||
|
|
||||||
|
rich_theme = RichTheme.from_style_name(style_name)
|
||||||
|
|
||||||
|
theme = Theme()
|
||||||
|
for color, color_set in ChainMap(
|
||||||
|
RichColor.__members__, RICH_CUSTOM_STYLES
|
||||||
|
).items():
|
||||||
|
if isinstance(color_set, _StyledRichColor):
|
||||||
|
properties = dict.fromkeys(color_set.styles, True)
|
||||||
|
color_set = color_set.color
|
||||||
|
else:
|
||||||
|
properties = {}
|
||||||
|
|
||||||
|
theme.styles[color.lower()] = Style(
|
||||||
|
color=color_set.apply_theme(rich_theme, style_name=style_name),
|
||||||
|
**properties,
|
||||||
|
)
|
||||||
|
|
||||||
|
# E.g translate RichColor.BLUE into blue on key access
|
||||||
|
theme.styles = _RichColorCaster(theme.styles)
|
||||||
|
return theme
|
23
httpie/output/ui/palette/utils.py
Normal file
23
httpie/output/ui/palette/utils.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
class ColorString(str):
|
||||||
|
def __or__(self, other: str) -> 'ColorString':
|
||||||
|
"""Combine a style with a property.
|
||||||
|
|
||||||
|
E.g: PieColor.BLUE | BOLD | ITALIC
|
||||||
|
"""
|
||||||
|
from httpie.output.ui.palette.rich import RichColor, _StyledRichColor
|
||||||
|
|
||||||
|
if isinstance(other, str):
|
||||||
|
# In case of PieColor.BLUE | SOMETHING
|
||||||
|
# we just create a new string.
|
||||||
|
return ColorString(self + ' ' + other)
|
||||||
|
elif isinstance(other, RichColor):
|
||||||
|
# If we see a GenericColor, then we'll wrap it
|
||||||
|
# in with the desired property in a different class.
|
||||||
|
return _StyledRichColor(other, styles=self.split())
|
||||||
|
elif isinstance(other, _StyledRichColor):
|
||||||
|
# And if it is already wrapped, we'll just extend the
|
||||||
|
# list of properties.
|
||||||
|
other.styles.extend(self.split())
|
||||||
|
return other
|
||||||
|
else:
|
||||||
|
return NotImplemented
|
@ -10,17 +10,17 @@ from rich.text import Text
|
|||||||
|
|
||||||
from httpie.cli.constants import SEPARATOR_GROUP_ALL_ITEMS
|
from httpie.cli.constants import SEPARATOR_GROUP_ALL_ITEMS
|
||||||
from httpie.cli.options import Argument, ParserSpec, Qualifiers
|
from httpie.cli.options import Argument, ParserSpec, Qualifiers
|
||||||
from httpie.output.ui.palette import GenericColor
|
from httpie.output.ui.palette import RichColor
|
||||||
|
|
||||||
SEPARATORS = '|'.join(map(re.escape, SEPARATOR_GROUP_ALL_ITEMS))
|
SEPARATORS = '|'.join(map(re.escape, SEPARATOR_GROUP_ALL_ITEMS))
|
||||||
|
|
||||||
STYLE_METAVAR = GenericColor.YELLOW
|
STYLE_METAVAR = RichColor.YELLOW
|
||||||
STYLE_SWITCH = GenericColor.GREEN
|
STYLE_SWITCH = RichColor.GREEN
|
||||||
STYLE_PROGRAM_NAME = GenericColor.GREEN # .boldify()
|
STYLE_PROGRAM_NAME = RichColor.GREEN # .boldify()
|
||||||
STYLE_USAGE_OPTIONAL = GenericColor.GREY
|
STYLE_USAGE_OPTIONAL = RichColor.GREY
|
||||||
STYLE_USAGE_REGULAR = GenericColor.WHITE
|
STYLE_USAGE_REGULAR = RichColor.WHITE
|
||||||
STYLE_USAGE_ERROR = GenericColor.RED
|
STYLE_USAGE_ERROR = RichColor.RED
|
||||||
STYLE_USAGE_MISSING = GenericColor.YELLOW
|
STYLE_USAGE_MISSING = RichColor.YELLOW
|
||||||
STYLE_BOLD = 'bold'
|
STYLE_BOLD = 'bold'
|
||||||
|
|
||||||
MAX_CHOICE_CHARS = 80
|
MAX_CHOICE_CHARS = 80
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
from collections import ChainMap
|
|
||||||
from typing import TYPE_CHECKING, Any, Optional
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from rich.theme import Theme
|
|
||||||
|
|
||||||
from httpie.output.ui.palette import GenericColor, PieStyle, Styles, ColorString, _StyledGenericColor # noqa
|
|
||||||
|
|
||||||
RICH_BOLD = ColorString('bold')
|
|
||||||
|
|
||||||
# Rich-specific color code declarations
|
|
||||||
# <https://github.com/Textualize/rich/blob/fcd684dd3a482977cab620e71ccaebb94bf13ac9/rich/default_styles.py>
|
|
||||||
CUSTOM_STYLES = {
|
|
||||||
'progress.description': RICH_BOLD | GenericColor.WHITE,
|
|
||||||
'progress.data.speed': RICH_BOLD | GenericColor.GREEN,
|
|
||||||
'progress.percentage': RICH_BOLD | GenericColor.AQUA,
|
|
||||||
'progress.download': RICH_BOLD | GenericColor.AQUA,
|
|
||||||
'progress.remaining': RICH_BOLD | GenericColor.ORANGE,
|
|
||||||
'bar.complete': RICH_BOLD | GenericColor.PURPLE,
|
|
||||||
'bar.finished': RICH_BOLD | GenericColor.GREEN,
|
|
||||||
'bar.pulse': RICH_BOLD | GenericColor.PURPLE,
|
|
||||||
'option': RICH_BOLD | GenericColor.PINK,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class _GenericColorCaster(dict):
|
|
||||||
"""
|
|
||||||
Translate GenericColor to a regular string on the attribute access
|
|
||||||
phase.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _translate(self, key: Any) -> Any:
|
|
||||||
if isinstance(key, GenericColor):
|
|
||||||
return key.name.lower()
|
|
||||||
else:
|
|
||||||
return key
|
|
||||||
|
|
||||||
def __getitem__(self, key: Any) -> Any:
|
|
||||||
return super().__getitem__(self._translate(key))
|
|
||||||
|
|
||||||
def get(self, key: Any) -> Any:
|
|
||||||
return super().get(self._translate(key))
|
|
||||||
|
|
||||||
|
|
||||||
def _make_rich_color_theme(style_name: Optional[str] = None) -> 'Theme':
|
|
||||||
from rich.style import Style
|
|
||||||
from rich.theme import Theme
|
|
||||||
|
|
||||||
try:
|
|
||||||
PieStyle(style_name)
|
|
||||||
except ValueError:
|
|
||||||
style = Styles.ANSI
|
|
||||||
else:
|
|
||||||
style = Styles.PIE
|
|
||||||
|
|
||||||
theme = Theme()
|
|
||||||
for color, color_set in ChainMap(
|
|
||||||
GenericColor.__members__, CUSTOM_STYLES
|
|
||||||
).items():
|
|
||||||
if isinstance(color_set, _StyledGenericColor):
|
|
||||||
properties = dict.fromkeys(color_set.styles, True)
|
|
||||||
color_set = color_set.color
|
|
||||||
else:
|
|
||||||
properties = {}
|
|
||||||
|
|
||||||
theme.styles[color.lower()] = Style(
|
|
||||||
color=color_set.apply_style(style, style_name=style_name),
|
|
||||||
**properties,
|
|
||||||
)
|
|
||||||
|
|
||||||
# E.g translate GenericColor.BLUE into blue on key access
|
|
||||||
theme.styles = _GenericColorCaster(theme.styles)
|
|
||||||
return theme
|
|
@ -6,7 +6,7 @@ from contextlib import contextmanager
|
|||||||
from rich.console import Console, RenderableType
|
from rich.console import Console, RenderableType
|
||||||
from rich.highlighter import Highlighter
|
from rich.highlighter import Highlighter
|
||||||
|
|
||||||
from httpie.output.ui.rich_palette import _make_rich_color_theme
|
from httpie.output.ui.palette import make_rich_theme_from_style
|
||||||
|
|
||||||
|
|
||||||
def render_as_string(renderable: RenderableType) -> str:
|
def render_as_string(renderable: RenderableType) -> str:
|
||||||
@ -14,7 +14,7 @@ def render_as_string(renderable: RenderableType) -> str:
|
|||||||
return a *style-less* version of it as a string."""
|
return a *style-less* version of it as a string."""
|
||||||
|
|
||||||
with open(os.devnull, 'w') as null_stream:
|
with open(os.devnull, 'w') as null_stream:
|
||||||
fake_console = Console(file=null_stream, record=True, theme=_make_rich_color_theme())
|
fake_console = Console(file=null_stream, record=True, theme=make_rich_theme_from_style())
|
||||||
fake_console.print(renderable)
|
fake_console.print(renderable)
|
||||||
return fake_console.export_text()
|
return fake_console.export_text()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user