Elegant hack or gross hack? TextWrapper and escape codes

Chris Angelico rosuav at gmail.com
Wed May 27 19:28:31 EDT 2020


Situation: A terminal application. Requirement: Display nicely-wrapped
text. With colour codes in it. And that text might be indented to any
depth.

label = f"{indent}\U0010cc32{code}\U0010cc00 @{tweet['user']['screen_name']}: "
wrapper = textwrap.TextWrapper(
    initial_indent=label,
    subsequent_indent=indent + " " * 12,
    width=shutil.get_terminal_size().columns,
    break_long_words=False, break_on_hyphens=False, # Stop URLs from breaking
)
for line in tweet["full_text"].splitlines():
    print(wrapper.fill(line)
        .replace("\U0010cc32", "\x1b[32m\u2026")
        .replace("\U0010cc00", "\u2026\x1b[0m")
    )
    wrapper.initial_indent = wrapper.subsequent_indent # For
subsequent lines, just indent them


The parameter "indent" is always some number of spaces (possibly
zero). If I simply include the escape codes in the label, their
characters will be counted, and the first line will be shorter. Rather
than mess with how textwrap defines text, I just replace the escape
codes *and one other character* with a placeholder. In the final
display, \U0010cc32 means "colour code 32 and an ellipsis", and
\U0010cc00 means "colour code 0 and an ellipsis", so textwrap
correctly counts them as one character each.

So what do you folks think? Is this a gloriously elegant way to
collapse nonprinting text, or is it a gross hacky mess that's going to
cause problems?

ChrisA


More information about the Python-list mailing list