256 colors support
+ The colors name's are the number 0 through 255. + Old names still work. + Add `magenta` color, wrongly named `purple` before. + Adds `white`, `darkgrey`. + grey/gray spelling Also removed italics as a default option for publisher. Related: #44
This commit is contained in:
parent
87346707be
commit
78c562d640
102
pubs/color.py
102
pubs/color.py
@ -1,46 +1,87 @@
|
||||
"""
|
||||
Small code to handle colored text
|
||||
Code to handle colored text
|
||||
"""
|
||||
|
||||
"""
|
||||
Here is a little explanation about bash color code, useful to understand
|
||||
the code below. See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
|
||||
for a complete referece.
|
||||
|
||||
# 8 colors
|
||||
The code `\033[{c}m` generate a color, with 30 <= c < 38. The order is:
|
||||
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'grey'.
|
||||
|
||||
Additionaly, adding `1;` and `3;` will generate bold and italic text,
|
||||
respectively, so `\033[1;3;31m` would be bold italic red. Bold and italic
|
||||
can also be used independently, so `\033[1m` would create bold text without
|
||||
changing the current color.
|
||||
|
||||
Bold and italic will only be displayed if the terminal allows it *and* the
|
||||
font supports it (thus, no italic with Monaco). Sometimes, bold is replaced
|
||||
by the bright version of the font; some terminals allow the user to decide that.
|
||||
|
||||
# 256 colors
|
||||
256 colors work the same. The code `\033[38;5;{c}` with 0 <= c < 256 will
|
||||
display colors, with 0 <= c < 8 corresponding to the 8 above colors, and
|
||||
8 <= c < 16 their bright version.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def _color_supported(stream):
|
||||
"""Return True is the stream supports colors"""
|
||||
|
||||
COLOR_LIST = {u'black': '0', u'red': '1', u'green': '2', u'yellow': '3', u'blue': '4',
|
||||
u'magenta': '5', u'cyan': '6', u'grey': '7',
|
||||
u'brightblack': '8', u'brightred': '9', u'brightgreen': '10',
|
||||
u'brightyellow': '11', u'brightblue': '12', u'brightmagenta': '13',
|
||||
u'brightcyan': '14', u'brightgrey': '15',
|
||||
u'darkgrey': '8', # == brightblack
|
||||
u'gray': '7', u'darkgray': '8', u'brightgray': '15', # gray/grey spelling
|
||||
u'purple': '5', # for compatibility reasons
|
||||
u'white': '15' # == brightgrey
|
||||
}
|
||||
for c in range(256):
|
||||
COLOR_LIST[str(c)] = str(c)
|
||||
|
||||
|
||||
def _color_supported(stream, force=False):
|
||||
"""Return the number of supported colors"""
|
||||
min_colors = 8 if force else 0
|
||||
if sys.platform == 'win32' and 'ANSICON' not in os.environ:
|
||||
return False
|
||||
return min_colors
|
||||
|
||||
if hasattr(stream, 'isatty') and stream.isatty(): # we have a tty
|
||||
try:
|
||||
import curses
|
||||
curses.setupterm()
|
||||
return curses.tigetnum('colors') >= 8
|
||||
return max(min_colors, curses.tigetnum('colors'))
|
||||
except Exception: # not picky.
|
||||
return False
|
||||
return False
|
||||
pass
|
||||
|
||||
COLOR_LIST = [u'black', u'red', u'green', u'yellow', u'blue', u'purple', u'cyan', u'grey']
|
||||
if force:
|
||||
p = subprocess.Popen(['tput', 'colors'], stdout=subprocess.PIPE)
|
||||
return max(min_colors, int(p.communicate()[0]))
|
||||
return 0
|
||||
|
||||
def generate_colors(stream, color=True, bold=True, italic=True, force_colors=False):
|
||||
"""Generate colors, based on configuration and detected support
|
||||
"""Generate 256 colors, based on configuration and detected support
|
||||
|
||||
:param color: generate colors. If False, bold and italic will not change
|
||||
the current color.
|
||||
:param bold: generate bold colors, if False, bold color are the same as
|
||||
normal colors.
|
||||
:param italic: generate italic colors
|
||||
:param force_colors: generate colors whether support is detected or not. Will not
|
||||
overrride the `color` parameter.
|
||||
"""
|
||||
colors = {name: u'' for name in COLOR_LIST}
|
||||
colors.update({u'b' +name: u'' for name in COLOR_LIST})
|
||||
colors.update({u'i' +name: u'' for name in COLOR_LIST})
|
||||
colors.update({u'bi'+name: u'' for name in COLOR_LIST})
|
||||
colors[u'bold'] = u''
|
||||
colors[u'italic'] = u''
|
||||
colors[u'end'] = u''
|
||||
colors[u''] = u''
|
||||
colors = {u'bold': u'', u'italic': u'', u'end': u'', u'': u''}
|
||||
for name, code in COLOR_LIST.items():
|
||||
colors[name] = u''
|
||||
colors[u'b' +name] = u''
|
||||
colors[u'i' +name] = u''
|
||||
colors[u'bi'+name] = u''
|
||||
|
||||
color_support = force_colors or _color_supported(stream)
|
||||
color_support = _color_supported(stream, force=force_colors) >= 8
|
||||
|
||||
if (color or bold or italic) and color_support:
|
||||
bold_flag, italic_flag = '', ''
|
||||
@ -53,12 +94,13 @@ def generate_colors(stream, color=True, bold=True, italic=True, force_colors=Fal
|
||||
if bold and italic:
|
||||
colors['bolditalic'] = u'\033[1;3m'
|
||||
|
||||
for i, name in enumerate(COLOR_LIST):
|
||||
for name, code in COLOR_LIST.items():
|
||||
if color:
|
||||
colors[name] = u'\x1b[3{}m'.format(i)
|
||||
colors.update({u'b'+name: u'\033[{}3{}m'.format(bold_flag, i) for i, name in enumerate(COLOR_LIST)})
|
||||
colors.update({u'i'+name: u'\033[{}3{}m'.format(italic_flag, i) for i, name in enumerate(COLOR_LIST)})
|
||||
colors.update({u'bi'+name: u'\033[{}{}3{}m'.format(bold_flag, italic_flag, i) for i, name in enumerate(COLOR_LIST)})
|
||||
colors[name] = u'\033[38;5;{}m'.format(code)
|
||||
colors[u'b'+name] = u'\033[{}38;5;{}m'.format(bold_flag, code)
|
||||
colors[u'i'+name] = u'\033[{}38;5;{}m'.format(italic_flag, code)
|
||||
colors[u'bi'+name] = u'\033[{}38;5;{}m'.format(bold_flag, italic_flag, code)
|
||||
|
||||
else:
|
||||
if bold:
|
||||
colors.update({u'b'+name: u'\033[1m' for i, name in enumerate(COLOR_LIST)})
|
||||
@ -68,7 +110,7 @@ def generate_colors(stream, color=True, bold=True, italic=True, force_colors=Fal
|
||||
colors.update({u'bi'+name: u'\033[{}{}m'.format(bold_flag, italic_flag) for i, name in enumerate(COLOR_LIST)})
|
||||
|
||||
if color or bold or italic:
|
||||
colors['end'] = u'\033[0m'
|
||||
colors[u'end'] = u'\033[0m'
|
||||
|
||||
return colors
|
||||
|
||||
@ -90,12 +132,12 @@ def setup(conf, force_colors=False):
|
||||
"""Prepare color for stdout and stderr"""
|
||||
global COLORS_OUT, COLORS_ERR
|
||||
COLORS_OUT = generate_colors(sys.stdout, force_colors=force_colors,
|
||||
color=conf['formating']['color'],
|
||||
bold=conf['formating']['bold'],
|
||||
color =conf['formating']['color'],
|
||||
bold =conf['formating']['bold'],
|
||||
italic=conf['formating']['italics'])
|
||||
COLORS_ERR = generate_colors(sys.stderr, force_colors=force_colors,
|
||||
color=conf['formating']['color'],
|
||||
bold=conf['formating']['bold'],
|
||||
color =conf['formating']['color'],
|
||||
bold =conf['formating']['bold'],
|
||||
italic=conf['formating']['italics'])
|
||||
for key, value in conf['theme'].items():
|
||||
COLORS_OUT[key] = COLORS_OUT.get(value, '')
|
||||
|
@ -61,7 +61,7 @@ tag = string(default='cyan')
|
||||
# bibliographic fields
|
||||
author = string(default='bold')
|
||||
title = string(default='')
|
||||
publisher = string(default='italic')
|
||||
publisher = string(default='')
|
||||
year = string(default='bold')
|
||||
volume = string(default='bold')
|
||||
pages = string(default='')
|
||||
|
Loading…
x
Reference in New Issue
Block a user