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