Is there a list of ANSI color escape codes somewhere in the standard libraries?

寵の児 提交于 2021-01-27 17:50:35

问题


I write a lot of little helper scripts, and often these print coloured text in the terminal. For the simplicity of their packaging and distribution, I often want these little scripts to be without any dependencies.

Hence I'm duplicating data like this a lot in scripts:

ansi_colors = {
    None: '\x1b[0m',  # actually black but whatevs
    'red': '\x1b[31m',
    'green' : '\x1b[32m',
    ...
}

Does this data exist anywhere in the core libraries? I dug around and found that curses has some COLOR_* constants, but they are just integers and it's not obvious how those transform into the ANSI escape codes.

I'm already aware of modules like termcolor, colorama, blessings, so please don't suggest to use those - I want to depend to standard libraries only.


回答1:


You can check the man page console_codes(4). What you want is the ECMA-48 Set Graphics Rendition:

The ECMA-48 SGR sequence ESC [ parameters m sets display attributes. Several attributes can be set in the same sequence, separated by semicolons. An empty parameter (between semicolons or string initiator or terminator) is interpreted as a zero.

   param   result
   0       reset all attributes to their defaults
   1       set bold
   2       set half-bright (simulated with color on a color display)
   4       set  underscore (simulated with color on a color display) (the colors used to
           simulate dim or underline are set using ESC ] ...)
   5       set blink
   7       set reverse video
   10      reset selected mapping, display control flag, and toggle meta  flag  (ECMA-48
           says "primary font").
   11      select  null  mapping,  set  display  control  flag,  reset  toggle meta flag
           (ECMA-48 says "first alternate font").
   12      select null mapping, set display control flag, set toggle meta flag  (ECMA-48
           says "second alternate font").  The toggle meta flag causes the high bit of a
           byte to be toggled before the mapping table translation is done.
   21      set normal intensity (ECMA-48 says "doubly underlined")
   22      set normal intensity
   24      underline off
   25      blink off
   27      reverse video off
   30      set black foreground
   31      set red foreground
   32      set green foreground
   33      set brown foreground
   34      set blue foreground
   35      set magenta foreground
   36      set cyan foreground
   37      set white foreground
   38      set underscore on, set default foreground color
   39      set underscore off, set default foreground color
   40      set black background
   41      set red background
   42      set green background
   43      set brown background
   44      set blue background
   45      set magenta background
   46      set cyan background
   47      set white background
   49      set default background color

I don't think they are available as-is in any standard Python module. But if you look carefully, you'll notice that the foreground colors are 30 plus the curses constant, while the background colors are 40 plus the curses constant. So you can write something like this:

import curses
def fcolor(c):
    return '\x1B[{0}m'.format(30 + c)
def bcolor(c):
    return '\x1B[{0}m'.format(40 + c)
def fbcolor(f, b):
    return '\x1B[{0};{1}m'.format(30 + f, 40 + b)

print(fbcolor(curses.COLOR_RED, curses.COLOR_YELLOW) + "hello!")



回答2:


It depends on what you want. ANSI colors technically refers to the 8-color palette implied by ECMA-48 (ISO-6429) which has named constants in curses. Libraries don't store escape sequences; those are in a database. For an ANSI (sic) terminal, those correspond to escape sequences which set graphic rendition (video attributes such as bold, underline, reverse — and color).

termcap, terminfo and curses use a more general notion where you start with a color number and generate the escape sequence which can produce the corresponding color. Terminals can have no colors, multiple colors (8 for instance, but possibly 16, 88, 256 for xterm and similar terminals). The information telling how to do this is stored in the terminal database as named capabilities. To set the ANSI foreground color, you would use setaf, either using a library call or a command-line application such as tput, e.g.,

tput setaf 4

for color 4 (blue). Simple applications use the low-level termcap or terminfo interfaces, usually with terminfo databases. While you might be inclined to format your own escape sequences, theses interfaces provide formatting functions that let you avoid knowing how many colors a terminal might support. The terminal database tells your program, using the TERM environment variable to select the actual terminal description. If you have a terminal supporting more than 8 colors, the escape sequence is not formed by adding 30 or 40 to the color number.

Here is an example using the low-level terminfo interface from Python:

import curses

curses.setupterm()
curses.putp(curses.tparm(curses.tigetstr("setaf"), curses.COLOR_RED))
curses.putp(curses.tparm(curses.tigetstr("setab"), curses.COLOR_YELLOW))
curses.putp("hello!")
curses.putp(curses.tigetstr("sgr0"))
curses.putp("\n")

Further reading:

  • 15.11. curses — Terminal handling for character-cell displays
  • ECMA-48: Control Functions for Coded Character Sets



回答3:


Rodrigo gave a good answer, although the colors are limited to the 8 first colors for foreground. This is my little contribution to handle 16 foreground colors

def fcolor(c):
    if c>7:
        return '\x1B[1;{0}m'.format(22 + c)
    else:
        return '\x1B[0;{0}m'.format(30 + c)
def bcolor(c):
    return '\x1B[{0}m'.format(40 + c)
def fbcolor(f, b):
    if f>7:
        return '\x1B[1;{0};{1}m'.format(22 + f, 40 + b)
    else:
        return '\x1B[0;{0};{1}m'.format(30 + f, 40 + b)


来源:https://stackoverflow.com/questions/37170990/is-there-a-list-of-ansi-color-escape-codes-somewhere-in-the-standard-libraries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!