Pythons `str.format ()`, fill in ANSI characters and colors

In Python 2, I use str.format() to align a bunch of columns of Im text printing to the terminal. Basically, this is his table, but Im doesn't print any borders or anything else - its just lines of text aligned in columns.

  • Without color grading, everything prints as expected.
  • If I wrap a whole line (i.e. one print statement) with ANSI color codes, everything prints as expected.
  • However: If I try to make each column a different color in the row, the alignment will be canceled. Technically alignment is maintained; its filling characters (spaces) that do not require printing; In fact, padding characters seem to be completely removed.

Ive tested the same issue with colorama and xtermcolor . The results were the same. Therefore, I am sure that the problem is due to the fact that str.format() does not play well with ANSI escape sequences in the middle of the line.

But I donโ€™t know what to do about it! :( I would really like to know if there is a workaround for this problem in any case.

Color and alignment are powerful tools for improving readability, and readability is an important part of software usability. It would mean a lot to me if it could be done without manually aligning each column of text.

Little help? โ˜บ

+7
source share
2 answers

Python does not distinguish between "normal" characters and ANSI color codes, which are also characters that the terminal interprets.

In other words, printing '\x1b[92m' to the terminal can change the color of the terminal text, Python does not see anything but a set of 5 characters. If you use print repr(line) instead, python will print a string literal instead, including using escape codes for non-printable ASCII characters (so ESC ASCII code, 27, displays as \x1b ) to see how much has been added.

You need to manually adjust the column alignment to allow these extra characters.

Without your real code, it's hard for us to help, though.

+4
source

This is a very late answer, left as breadcrumbs for anyone who finds this page, trying to format text with built-in ANSI color codes.

byoungb 's comment about making debugging along the length of pre-painted text is exactly right. But if you already have colored text, here is a workaround:

See my ansiwrap module on PyPI. Its main goal is to provide textwrap for text text with ANSI, but it also exports ansilen() , which tells you, "how long will this line be if it does not contain ANSI control codes"? This is very useful when deciding on formatting, column width, and wrapping on pre-colored text. Add width - ansilen(s) spaces to the end or beginning of s left (or, respectively, to the right) to justify s in the column of the desired width . For example:.

 def ansi_ljust(s, width): needed = width - ansilen(s) if needed > 0: return s + ' ' * needed else: return s 

In addition, if you need to split, truncate, or combine colored text at some point, you will find that the nature of ANSI's stateful nature makes this difficult. You may find ansi_terminate_lines() useful; it โ€œcorrectsโ€ the list of substrings, so that each of them has independent stand-alone ANSI codes with an equivalent effect as the source string.

Recent versions of ansicolors also contain an equivalent implementation of ansilen() .

+1
source

All Articles