pytermgui.prettifiers
This module provides some methods to prettify things.
The main export here is prettify
. It uses pytermgui.parser.tim
, and all of its
markup magic to create prettier representations of whatever is given.
View Source
"""This module provides some methods to prettify things. The main export here is `prettify`. It uses `pytermgui.parser.tim`, and all of its markup magic to create prettier representations of whatever is given. """ import builtins from typing import Any from collections import UserDict, UserList from .parser import RE_ANSI, RE_MARKUP, tim from .exceptions import MarkupSyntaxError, AnsiSyntaxError __all__ = ["prettify"] CONTAINER_TYPES = (list, dict, set, tuple, UserDict, UserList) def _prettify_container( target, indent: int, expand_all: bool, force_markup: bool ) -> str: """Prettifies a builtin container. All arguments are analogous to `prettify`. Returns: Pretty string markup. """ if len(target) < 2 and not expand_all: indent = 0 chars = str(target)[0], str(target)[-1] buff = chars[0] indent_str = ("\n" if indent > 0 else "") + indent * " " if isinstance(target, (dict, UserDict)): for i, (key, value) in enumerate(target.items()): if i > 0: buff += ", " buff += indent_str buff += prettify(key, indent=0, parse=False) + ": " pretty = prettify( value, indent=indent, expand_all=expand_all, force_markup=force_markup, parse=False, ) lines = pretty.splitlines() buff += lines[0] for line in lines[1:]: buff += indent_str + line else: for i, item in enumerate(target): if i > 0: buff += ", " pretty = prettify( item, indent=indent, expand_all=expand_all, force_markup=force_markup, parse=False, ) for line in pretty.splitlines(): buff += indent_str + line if indent > 0: buff += ",\n" return buff + chars[1] def _prettify_str(target, force_markup=True) -> str: """Prettifies a string. All arguments are analogous to `prettify`. Returns: Pretty string markup. """ buff = "" if len(RE_ANSI.findall(target)) > 0: if not force_markup: return target target = tim.get_markup(target) old_raise_markup = tim.raise_unknown_markup tim.raise_unknown_markup = True if len(RE_MARKUP.findall(target)) > 0: try: buff = "'" + tim.get_markup(tim.prettify_markup(target)) + "'" except MarkupSyntaxError: target = target.replace("[", r"\[") tim.raise_unknown_markup = old_raise_markup if buff == "": sanitized = target.replace("\x1b", "\\x1b") buff = f"[pprint-str]'{sanitized}'" return buff + "[/]" def prettify( target: Any, indent: int = 2, force_markup: bool = False, expand_all: bool = False, parse: bool = True, ) -> str: """Prettifies any Python object. This uses a set of pre-defined aliases for the styling, and as such is fully customizable. The aliases are: - `pprint-str`: Applied to all strings, so long as they do not contain TIM code. - `pprint-int`: Applied to all integers and booleans. The latter are included as they subclass int. - `pprint-type`: Applied to all types. - `pprint-none`: Applied to NoneType. Note that when using `pytermgui.pretty`, a single `None` return value will not be printed, only when part of a more complex structure. Args: target: The object to prettify. Can be any type. indent: The indentation used for multi-line objects, like containers. When set to 0, these will be collapsed. By default, container types with `len() == 1` are always collapsed, regardless of this value. See `expand_all` to overwrite that behaviour. force_markup: When this is set every ANSI-sequence string will be turned into markup and syntax highlighted. expand_all: When set, objects that would normally be force-collapsed are also going to be expanded. parse: If not set, the return value will be a plain markup string, not yet parsed. Returns: A pretty string of the given target. """ if target in dir(builtins) and not target.startswith("__"): target = builtins.__dict__[target] buff = "" if isinstance(target, CONTAINER_TYPES): buff = _prettify_container( target, indent=indent, expand_all=expand_all, force_markup=force_markup ) elif isinstance(target, str): buff = _prettify_str(target, force_markup=force_markup) elif isinstance(target, int): buff = f"[pprint-int]{target}[/]" elif isinstance(target, type): buff = f"[pprint-type]{target.__name__}[/]" elif target is None: buff = f"[pprint-none]{target}[/]" else: try: iterator = iter(target) except TypeError: return str(target) for inner in iterator: buff += prettify(inner, parse=False) if parse: try: return tim.parse(buff) except (AnsiSyntaxError, MarkupSyntaxError): pass return str(buff) or str(target)
#  
def
prettify(
target: Any,
indent: int = 2,
force_markup: bool = False,
expand_all: bool = False,
parse: bool = True
) -> str:
View Source
def prettify( target: Any, indent: int = 2, force_markup: bool = False, expand_all: bool = False, parse: bool = True, ) -> str: """Prettifies any Python object. This uses a set of pre-defined aliases for the styling, and as such is fully customizable. The aliases are: - `pprint-str`: Applied to all strings, so long as they do not contain TIM code. - `pprint-int`: Applied to all integers and booleans. The latter are included as they subclass int. - `pprint-type`: Applied to all types. - `pprint-none`: Applied to NoneType. Note that when using `pytermgui.pretty`, a single `None` return value will not be printed, only when part of a more complex structure. Args: target: The object to prettify. Can be any type. indent: The indentation used for multi-line objects, like containers. When set to 0, these will be collapsed. By default, container types with `len() == 1` are always collapsed, regardless of this value. See `expand_all` to overwrite that behaviour. force_markup: When this is set every ANSI-sequence string will be turned into markup and syntax highlighted. expand_all: When set, objects that would normally be force-collapsed are also going to be expanded. parse: If not set, the return value will be a plain markup string, not yet parsed. Returns: A pretty string of the given target. """ if target in dir(builtins) and not target.startswith("__"): target = builtins.__dict__[target] buff = "" if isinstance(target, CONTAINER_TYPES): buff = _prettify_container( target, indent=indent, expand_all=expand_all, force_markup=force_markup ) elif isinstance(target, str): buff = _prettify_str(target, force_markup=force_markup) elif isinstance(target, int): buff = f"[pprint-int]{target}[/]" elif isinstance(target, type): buff = f"[pprint-type]{target.__name__}[/]" elif target is None: buff = f"[pprint-none]{target}[/]" else: try: iterator = iter(target) except TypeError: return str(target) for inner in iterator: buff += prettify(inner, parse=False) if parse: try: return tim.parse(buff) except (AnsiSyntaxError, MarkupSyntaxError): pass return str(buff) or str(target)
Prettifies any Python object.
This uses a set of pre-defined aliases for the styling, and as such is fully customizable.
The aliases are:
pprint-str
: Applied to all strings, so long as they do not contain TIM code.pprint-int
: Applied to all integers and booleans. The latter are included as they subclass int.pprint-type
: Applied to all types.pprint-none
: Applied to NoneType. Note that when usingpytermgui.pretty
, a singleNone
return value will not be printed, only when part of a more complex structure.
Args
- target: The object to prettify. Can be any type.
- indent: The indentation used for multi-line objects, like containers. When
set to 0, these will be collapsed. By default, container types with
len() == 1
are always collapsed, regardless of this value. Seeexpand_all
to overwrite that behaviour. - force_markup: When this is set every ANSI-sequence string will be turned into markup and syntax highlighted.
- expand_all: When set, objects that would normally be force-collapsed are also going to be expanded.
- parse: If not set, the return value will be a plain markup string, not yet parsed.
Returns
A pretty string of the given target.