Skip to content

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.

prettify(target, indent=2, force_markup=False, expand_all=False, parse=True)

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 using pytermgui.pretty or any of its printers, a single None return value will not be printed, only when part of a more complex structure.

Parameters:

Name Type Description Default
target Any

The object to prettify. Can be any type.

required
indent int

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.

2
force_markup bool

When this is set every ANSI-sequence string will be turned into markup and syntax highlighted.

False
expand_all bool

When set, objects that would normally be force-collapsed are also going to be expanded.

False
parse bool

If not set, the return value will be a plain markup string, not yet parsed.

True

Returns:

Type Description
str

A pretty string of the given target.

Source code in pytermgui/prettifiers.py
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
def prettify(  # pylint: disable=too-many-branches
    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:

    - `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 using `pytermgui.pretty` or any
        of its printers, 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 isinstance(target, str):
        if RE_MARKUP.match(target) is not None:
            try:
                highlighted_target = highlight_tim(target)

                if parse:
                    return f'"{tim.parse(highlighted_target)}"'

                return highlighted_target + "[/]"

            except MarkupSyntaxError:
                pass

        if RE_ANSI.match(target) is not None:
            return target + "\x1b[0m"

        target = repr(target)

    if isinstance(target, CONTAINER_TYPES):
        if len(target) < 2 and not expand_all:
            indent = 0

        indent_str = ("\n" if indent > 0 else "") + indent * " "

        chars = str(target)[0], str(target)[-1]
        buff = chars[0]

        if isinstance(target, (dict, UserDict)):
            for i, (key, value) in enumerate(target.items()):
                if i > 0:
                    buff += ", "

                buff += indent_str + highlight_python(f"{key!r}: ")

                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, value in enumerate(target):
                if i > 0:
                    buff += ", "

                pretty = prettify(
                    value,
                    indent=indent,
                    expand_all=expand_all,
                    force_markup=force_markup,
                    parse=False,
                )

                lines = pretty.splitlines()

                for line in lines:
                    buff += indent_str + line

        if indent > 0:
            buff += "\n"

        buff += chars[1]

        if force_markup:
            return buff

        return tim.parse(buff)

    if supports_fancy_repr(target):
        buff = build_fancy_repr(target)

    else:
        buff = highlight_python(str(target))

    return tim.parse(buff) if parse else buff