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 singleNonereturn 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() == 1are always collapsed, regardless of this value. Seeexpand_allto 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.