Make default colormaps work.

Overwrite default colormaps only if asked.
Correctly interpret integers in mode().
Test registered colormaps after specials.
Silently ignore duplicated external palettes.
Add a set_special_colormaps function.
Do not sue ANSI_min/max as limits for the whole ANSI range.
Move global variables at the top of the file.
This commit is contained in:
Johann Dreo 2014-04-25 10:56:17 +02:00
commit d3efe7e851
2 changed files with 104 additions and 77 deletions

View file

@ -138,6 +138,8 @@ Gentoo
WARNING: be sure to specify a default colormap that is compatible with the special colormap's mode.
For instance, if you indicate `scale`, you can use `-d red,green,blue`, but `-d 12,13,14` will fail.
Also, if you specify `Scale`, you cannot use `-d red,green,blue`, but `-d Rainbow` will work.
Similarly, external palettes are converted from RGB to 256-ANSI and will thus not work if you use
them as default colormaps for a 8-colors mode special color.
* `-r TYPE(S)`, `--resources TYPE(S)`:
Print the names of available resources. Use a comma-separated list of resources names

View file

@ -23,10 +23,77 @@ import functools
signal.signal( signal.SIGPIPE, signal.SIG_DFL )
###############################################################################
# Global variables
###############################################################################
# Escaped end markers for given color modes
endmarks = {8: ";", 256: ";38;5;"}
# Available styles
styles = {
"normal": 0, "bold": 1, "faint": 2, "italic": 3, "underline": 4,
"blink": 5, "rapid_blink": 6,
"reverse": 7, "conceal": 8
}
# Available color names in 8-colors mode
colors = {
"black": 0, "red": 1, "green": 2, "yellow": 3, "orange":3, "blue": 4,
"magenta": 5, "purple": 5, "cyan": 6, "white": 7, "none": -1
}
themes = {}
# pre-defined colormaps
# 8-colors mode should start with a lower-case letter (and can contains either named or indexed colors)
# 256-colors mode should start with an upper-case letter (and should contains indexed colors)
colormaps = {
# Rainbows
"rainbow" : ["magenta", "blue", "cyan", "green", "yellow", "red"],
"Rainbow" : [92, 93, 57, 21, 27, 33, 39, 45, 51, 50, 49, 48, 47, 46, 82, 118, 154, 190, 226, 220, 214, 208, 202, 196],
# from magenta to red, with white in the middle
"spectrum" : ["magenta", "blue", "cyan", "white", "green", "yellow", "red"],
"Spectrum" : [91, 92, 56, 57, 21, 27, 26, 32, 31, 37, 36, 35, 41, 40, 41, 77, 83, 84, 120, 121, 157, 194, 231, 254, 255, 231, 230, 229, 228, 227, 226, 220, 214, 208, 202, 196]
} # colormaps
colormaps["scale"] = colormaps["spectrum"]
colormaps["Scale"] = colormaps["Spectrum"]
colormaps["hash"] = colormaps["rainbow"]
colormaps["Hash"] = colormaps["Rainbow"]
colormaps["default"] = colormaps["spectrum"]
colormaps["Default"] = colormaps["Spectrum"]
colormap_idx = 0
scale = (0,100)
class UnknownColor(Exception):
pass
class DuplicatedPalette(Exception):
pass
class DuplicatedTheme(Exception):
pass
###############################################################################
# Ressource parsing helpers
###############################################################################
def set_special_colormaps( cmap ):
"""Change all the special colors to a single colormap (which must be a list of colors)."""
colormaps["scale"] = cmap
colormaps["Scale"] = cmap
colormaps["hash"] = cmap
colormaps["Hash"] = cmap
colormaps["default"] = cmap
colormaps["Default"] = cmap
def parse_gimp_palette( filename ):
"""
Parse the given filename as a GIMP palette (.gpl)
@ -90,7 +157,13 @@ def uniq( lst ):
def rgb_to_ansi( r, g, b ):
"""Convert a RGB color to its closest 256-colors ANSI index"""
# ansi_max is the higher possible RGB value for ANSI colors
# Range limits for the *colored* section of ANSI,
# this does not include the *gray* section.
ansi_min = 16
ansi_max = 234
# ansi_max is the higher possible RGB value for ANSI *colors*
# limit RGB values to ansi_max
red,green,blue = tuple([ansi_max if c>ansi_max else c for c in (r,g,b)])
@ -121,65 +194,6 @@ def hex_to_rgb(h):
return tuple( int(h[i:i+lh//3], 16) for i in range(0, lh, lh//3) )
###############################################################################
# Global variables
###############################################################################
# Escaped end markers for given color modes
endmarks = {8: ";", 256: ";38;5;"}
ansi_min = 16
ansi_max = 234
# Available styles
styles = {
"normal": 0, "bold": 1, "faint": 2, "italic": 3, "underline": 4,
"blink": 5, "rapid_blink": 6,
"reverse": 7, "conceal": 8
}
# Available color names in 8-colors mode
colors = {
"black": 0, "red": 1, "green": 2, "yellow": 3, "orange":3, "blue": 4,
"magenta": 5, "purple": 5, "cyan": 6, "white": 7, "none": -1
}
themes = {}
# pre-defined colormaps
# 8-colors mode should start with a lower-case letter (and can contains either named or indexed colors)
# 256-colors mode should start with an upper-case letter (and should contains indexed colors)
colormaps = {
# Rainbows
"rainbow" : ["magenta", "blue", "cyan", "green", "yellow", "red"],
"Rainbow" : [92, 93, 57, 21, 27, 33, 39, 45, 51, 50, 49, 48, 47, 46, 82, 118, 154, 190, 226, 220, 214, 208, 202, 196],
# from magenta to red, with white in the middle
"spectrum" : ["magenta", "blue", "cyan", "white", "green", "yellow", "red"],
"Spectrum" : [91, 92, 56, 57, 21, 27, 26, 32, 31, 37, 36, 35, 41, 40, 41, 77, 83, 84, 120, 121, 157, 194, 231, 254, 255, 231, 230, 229, 228, 227, 226, 220, 214, 208, 202, 196]
} # colormaps
colormaps["scale"] = colormaps["spectrum"]
colormaps["Scale"] = colormaps["Spectrum"]
colormaps["hash"] = colormaps["rainbow"]
colormaps["Hash"] = colormaps["Rainbow"]
colormaps["default"] = colormaps["spectrum"]
colormaps["Default"] = colormaps["Spectrum"]
colormap_idx = 0
scale = (0,100)
class UnknownColor(Exception):
pass
class DuplicatedPalette(Exception):
pass
class DuplicatedTheme(Exception):
pass
###############################################################################
# Load available extern resources
###############################################################################
@ -199,7 +213,7 @@ def load_themes( themes_dir):
themes[name] = importlib.import_module(module)
def load_palettes( palettes_dir ):
def load_palettes( palettes_dir, ignore_duplicates = True ):
global colormaps
logging.debug("search for palettes in: %s" % palettes_dir)
os.chdir( palettes_dir )
@ -212,7 +226,10 @@ def load_palettes( palettes_dir ):
logging.warning("error while parsing palette %s: %s" % ( p,e ) )
continue
if name in colormaps:
raise DuplicatedPalette(name)
if ignore_duplicates:
logging.warning("ignore this duplicated palette name: %s" % name)
else:
raise DuplicatedPalette(name)
# Convert the palette to ANSI
ansi_palette = [ rgb_to_ansi(r,g,b) for r,g,b in palette ]
# Compress it so that there isn't two consecutive identical colors
@ -265,7 +282,12 @@ def load_resources( themes_dir, palettes_dir ):
###############################################################################
def mode( color ):
if color in colors:
if type(color) is int:
if 0 <= color and color <= 255 :
return 256
else:
raise UnknownColor(color)
elif color in colors:
return 8
elif color in colormaps.keys():
if color[0].islower():
@ -279,7 +301,7 @@ def mode( color ):
return 256
elif color[0] == "#":
return 256
elif color.isdigit() and (ansi_min < int(color) and int(color) < ansi_max) :
elif color.isdigit() and (0 <= int(color) and int(color) <= 255) :
return 256
else:
raise UnknownColor(color)
@ -402,7 +424,7 @@ def color_map(name):
color_code = str(30 + colors[color])
else:
color_nb = int(color)
assert( ansi_min <= color_nb <= ansi_max )
assert( 0 <= color_nb <= 255 )
color_code = str(color_nb)
colormap_idx = next_in_map(color)
@ -477,9 +499,6 @@ def colorin(text, color="red", style="normal"):
elif color.lower() == "random":
color_code = color_random( color )
elif color in colormaps.keys():
color_code = color_in_colormaps( color )
elif color.lower() == "scale": # "scale" or "Scale"
color_code = color_scale( color, text )
@ -492,6 +511,12 @@ def colorin(text, color="red", style="normal"):
elif color == "colormap":
color_code = color_map(color)
# Registered colormaps should be tested after special colors,
# because special tags are also registered as colormaps,
# but do not have the same simple behavior.
elif color in colormaps.keys():
color_code = color_in_colormaps( color )
# 8 colors modes
elif color in colors:
color_code = str(30 + colors[color])
@ -818,7 +843,7 @@ def __args_parse__(argv, usage=""):
parser.add_argument("-P", "--palettes-dir", metavar="DIR", action="append",
help="Search for additional palettes (*.gpl files) in the given directory")
parser.add_argument("-d", "--default", metavar="COLORMAP", default="spectrum",
parser.add_argument("-d", "--default", metavar="COLORMAP", default=None,
help="When using special colormaps (`scale` or `hash`), use this COLORMAP. \
This can be either one of the available colormaps or a comma-separated list of colors. \
WARNING: be sure to specify a default colormap that is compatible with the special colormap's mode.")
@ -982,22 +1007,22 @@ if __name__ == "__main__":
logging.debug("user-defined scale: %f,%f" % scale)
# Default color maps
if default_colormap not in colormaps:
cmap = default_colormap.split(",")
if default_colormap:
if default_colormap not in colormaps:
cmap = default_colormap.split(",")
elif default_colormap in colormaps:
cmap = colormaps[default_colormap]
colormaps[color] = cmap
logging.debug("used-defined default colormap: %s" % ",".join([str(i) for i in cmap]) )
elif default_colormap in colormaps:
cmap = colormaps[default_colormap]
set_special_colormaps( cmap )
logging.debug("user-defined special colormap: %s" % ",".join([str(i) for i in cmap]) )
# explicit color map
if as_colormap is True and color not in colormaps:
colormaps["Default"] = color.split(",") # replace the colormap by the given colors
colormaps["default"] = color.split(",") # replace the colormap by the given colors
color = "colormap" # use the keyword to switch to colormap instead of list of colors
logging.debug("used-defined colormap: %s" % ",".join(colormaps["Default"]) )
logging.debug("used-defined default colormap: %s" % ",".join(colormaps["Default"]) )
# if theme
if as_theme: