python colored text without modifying the string

Question:

I have a python string:

my_string = 'thisisjustadummystringfortestingpurposes'

I want to print some regions of the string with color red, so I use ANSI escape codes:

  • red: ‘x1b[31m’
  • black: ‘x1b[0m’

Then what I do is, I create a new string with the ANSI codes inserted.

Example:

my_color_seq = seq[:5]       # 0:5 will be black
my_color_seq += 'x1b[31m'   # start red
my_color_seq += seq[5:10]    # 5:10 will be red
my_color_seq += 'x1b[0m'    # start black
my_color_seq += seq[10:]     # 10: will be black

print(my_color_seq)

This code works and correctly prints the region 5:10 red.
I have even created a loop where I can use a list of indexes and lengths for the regions that I want colored with red.

Now the problem is that in my colored string contain non visible characters (the ANSI codes), so the index of the characters is no longer what it seems to be.

Imagine that I want to now process again the colored string by painting some other fragments in blue. I can no longer trust the indexes since my string is now larger than it seems.

Of course I can update the indexes to point the correct locations in the new string, but I was just wondering if there is an easier way of doing this.

Asked By: user2261062

||

Answers:

You could make a wrapper around the string coloring, and print the returned values while keeping the original string intact:

Not shown in the example, but you can slice the original string, to selectively pass the substrings to the wrapper, with appropriate kwarg values, and re-assemble the returned values in a new string that can be further processes, or printed.

def colorize(token, bold_and_al='', fg_color='', bg_color=''):
    prefix = 'x1b['
    suffix = 'm'
    reset = 'x1b[0m'

    return 'x1b[' + bold_and_al + ";" + fg_color + ";" + bg_color + "m" + token + reset


a = 'thisisjustadummystringfortestingpurposes'
print(colorize(a, bold_and_al='1', fg_color='34', bg_color='42'))

Edit:

Adding the example proposed by @MadPhysicist in the comments, to illustrate how the colorize wrapper could be used.:

print(''.join([colorize(a[:5], bold_and_al='1', fg_color='34', bg_color='42'), a[5:10], colorize(a[10:], bold_and_al='1', fg_color='32', bg_color='44')]))
Answered By: Reblochon Masque
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.