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.
1"""This module provides some methods to prettify things. 2 3The main export here is `prettify`. It uses `pytermgui.parser.tim`, and all of its 4markup magic to create prettier representations of whatever is given. 5""" 6 7from __future__ import annotations 8 9from collections import UserDict, UserList 10from typing import Any 11 12from .fancy_repr import build_fancy_repr, supports_fancy_repr 13from .highlighters import highlight_python 14from .parser import RE_MARKUP, tim 15 16__all__ = ["prettify"] 17 18CONTAINER_TYPES = (list, dict, set, tuple, UserDict, UserList) 19 20 21# Note: This function can be optimized in a lot of ways, primarily the way containers 22# are treated. 23def prettify( # pylint: disable=too-many-branches 24 target: Any, 25 indent: int = 2, 26 force_markup: bool = False, 27 expand_all: bool = False, 28 parse: bool = True, 29) -> str: 30 """Prettifies any Python object. 31 32 This uses a set of pre-defined aliases for the styling, and as such is fully 33 customizable. 34 35 The aliases are: 36 - `str`: Applied to all strings, so long as they do not contain TIM code. 37 - `int`: Applied to all integers and booleans. The latter are included as they 38 subclass int. 39 - `type`: Applied to all types. 40 - `none`: Applied to NoneType. Note that when using `pytermgui.pretty`, a 41 single `None` return value will not be printed, only when part of a more 42 complex structure. 43 44 Args: 45 target: The object to prettify. Can be any type. 46 indent: The indentation used for multi-line objects, like containers. When 47 set to 0, these will be collapsed. By default, container types with 48 `len() == 1` are always collapsed, regardless of this value. See 49 `expand_all` to overwrite that behaviour. 50 force_markup: When this is set every ANSI-sequence string will be turned 51 into markup and syntax highlighted. 52 expand_all: When set, objects that would normally be force-collapsed are 53 also going to be expanded. 54 parse: If not set, the return value will be a plain markup string, not yet 55 parsed. 56 57 Returns: 58 A pretty string of the given target. 59 """ 60 61 if isinstance(target, str): 62 if RE_MARKUP.match(target) is not None: 63 if parse: 64 return f'"{tim.prettify_markup(target)}"' 65 66 return target + "[/]" 67 68 target = repr(target) 69 70 if isinstance(target, CONTAINER_TYPES): 71 if len(target) < 2 and not expand_all: 72 indent = 0 73 74 indent_str = ("\n" if indent > 0 else "") + indent * " " 75 76 chars = str(target)[0], str(target)[-1] 77 buff = chars[0] 78 79 if isinstance(target, (dict, UserDict)): 80 for i, (key, value) in enumerate(target.items()): 81 if i > 0: 82 buff += ", " 83 84 buff += indent_str + highlight_python(f"{key!r}: ") 85 86 pretty = prettify( 87 value, 88 indent=indent, 89 expand_all=expand_all, 90 force_markup=force_markup, 91 parse=False, 92 ) 93 94 lines = pretty.splitlines() 95 buff += lines[0] 96 97 for line in lines[1:]: 98 buff += indent_str + line 99 100 else: 101 for i, value in enumerate(target): 102 if i > 0: 103 buff += ", " 104 105 pretty = prettify( 106 value, 107 indent=indent, 108 expand_all=expand_all, 109 force_markup=force_markup, 110 parse=False, 111 ) 112 113 lines = pretty.splitlines() 114 115 for line in lines: 116 buff += indent_str + line 117 118 if indent > 0: 119 buff += "\n" 120 121 buff += chars[1] 122 123 if force_markup: 124 return buff 125 126 return tim.parse(buff) 127 128 if supports_fancy_repr(target): 129 buff = build_fancy_repr(target) 130 131 else: 132 buff = highlight_python(str(target)) 133 134 return tim.parse(buff) if parse else buff
def
prettify( target: Any, indent: int = 2, force_markup: bool = False, expand_all: bool = False, parse: bool = True) -> str:
24def prettify( # pylint: disable=too-many-branches 25 target: Any, 26 indent: int = 2, 27 force_markup: bool = False, 28 expand_all: bool = False, 29 parse: bool = True, 30) -> str: 31 """Prettifies any Python object. 32 33 This uses a set of pre-defined aliases for the styling, and as such is fully 34 customizable. 35 36 The aliases are: 37 - `str`: Applied to all strings, so long as they do not contain TIM code. 38 - `int`: Applied to all integers and booleans. The latter are included as they 39 subclass int. 40 - `type`: Applied to all types. 41 - `none`: Applied to NoneType. Note that when using `pytermgui.pretty`, a 42 single `None` return value will not be printed, only when part of a more 43 complex structure. 44 45 Args: 46 target: The object to prettify. Can be any type. 47 indent: The indentation used for multi-line objects, like containers. When 48 set to 0, these will be collapsed. By default, container types with 49 `len() == 1` are always collapsed, regardless of this value. See 50 `expand_all` to overwrite that behaviour. 51 force_markup: When this is set every ANSI-sequence string will be turned 52 into markup and syntax highlighted. 53 expand_all: When set, objects that would normally be force-collapsed are 54 also going to be expanded. 55 parse: If not set, the return value will be a plain markup string, not yet 56 parsed. 57 58 Returns: 59 A pretty string of the given target. 60 """ 61 62 if isinstance(target, str): 63 if RE_MARKUP.match(target) is not None: 64 if parse: 65 return f'"{tim.prettify_markup(target)}"' 66 67 return target + "[/]" 68 69 target = repr(target) 70 71 if isinstance(target, CONTAINER_TYPES): 72 if len(target) < 2 and not expand_all: 73 indent = 0 74 75 indent_str = ("\n" if indent > 0 else "") + indent * " " 76 77 chars = str(target)[0], str(target)[-1] 78 buff = chars[0] 79 80 if isinstance(target, (dict, UserDict)): 81 for i, (key, value) in enumerate(target.items()): 82 if i > 0: 83 buff += ", " 84 85 buff += indent_str + highlight_python(f"{key!r}: ") 86 87 pretty = prettify( 88 value, 89 indent=indent, 90 expand_all=expand_all, 91 force_markup=force_markup, 92 parse=False, 93 ) 94 95 lines = pretty.splitlines() 96 buff += lines[0] 97 98 for line in lines[1:]: 99 buff += indent_str + line 100 101 else: 102 for i, value in enumerate(target): 103 if i > 0: 104 buff += ", " 105 106 pretty = prettify( 107 value, 108 indent=indent, 109 expand_all=expand_all, 110 force_markup=force_markup, 111 parse=False, 112 ) 113 114 lines = pretty.splitlines() 115 116 for line in lines: 117 buff += indent_str + line 118 119 if indent > 0: 120 buff += "\n" 121 122 buff += chars[1] 123 124 if force_markup: 125 return buff 126 127 return tim.parse(buff) 128 129 if supports_fancy_repr(target): 130 buff = build_fancy_repr(target) 131 132 else: 133 buff = highlight_python(str(target)) 134 135 return tim.parse(buff) if parse else buff
Prettifies any Python object.
This uses a set of pre-defined aliases for the styling, and as such is fully customizable.
The aliases are:
str
: Applied to all strings, so long as they do not contain TIM code.int
: Applied to all integers and booleans. The latter are included as they subclass int.type
: Applied to all types.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.