diff --git a/README.md b/README.md index 6dcf55a..80ac984 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ colout(1) -- Color Up Arbitrary Command Output `colout` [-h] [-r RESOURCE] -`colout` [-g] [-c] [-l] [-a] [-t] [-T] [-P] [-s] PATTERN [COLOR(S) [STYLE(S)]] +`colout` [-g] [-c] [-l min,max] [-a] [-t] [-T DIR] [-P DIR] [-d COLORMAP] [-s] [--debug] PATTERN [COLOR(S) [STYLE(S)]] ## DESCRIPTION @@ -21,25 +21,32 @@ If you ask for fewer colors, the last one will be duplicated across remaining groups. Available colors are: blue, black, yellow, cyan, green, magenta, white, red, -rainbow, random, Random, scale, none, an RGB hexadecimal triplet or any number -between 0 and 255. +rainbow, random, Random, Spectrum, spectrum, scale, Scale, hash, Hash, none, an +RGB hexadecimal triplet or any number between 0 and 255. Available styles are: normal, bold, faint, italic, underline, blink, -rapid_blink, reverse, conceal or random (some styles may have no effect, depending +rapid\_blink, reverse, conceal or random (some styles may have no effect, depending on your terminal). -`rainbow` will cycle over a 8 colors rainbow at each matching pattern. +`rainbow` will cycle over a 6 colors rainbow at each matching pattern. `Rainbow` will do the same over 24 colors (this requires a terminal that supports the 256 color escape sequences). `Random` will color each matching pattern with a random color among the 255 available in the ANSI table. `random` will do the same in 8 colors mode. -`scale` (8 colors) and `Scale` (36 colors) will parse the numbers characters in -the matching text as a decimal number and apply the rainbow colormap according +`spectrum` and `Spectrum` are like rainbows, but with more colors (8 and 36 +colors). + +`scale` (8 colors) and `Scale` (256 colors) will parse the numbers characters in +the matching text as a decimal number and apply the default colormap according to its position on the scale defined by the `-l` option (see below, "0,100" by default). +`hash` (8 colors) and `Hash` (256 colors) will take a fingerprint of the matching +text and apply the default colormap according to it. This ensure that matching +texts appearing several times will always get the same color. + Before interpreting the matched string as a number, colout will remove any character not supposed to be used to write down numbers. This permits to apply this special color on a large group, while interpreting only its numerical part. @@ -47,7 +54,7 @@ this special color on a large group, while interpreting only its numerical part. If the python3-pygments library is installed, you can use the name of a syntax-coloring "lexer" as a color (for example: "Cpp", "ruby", "xml+django", etc.). -If GIMP palettes files (*.gpl) are available, you can also use their names as a +If GIMP palettes files (\*.gpl) are available, you can also use their names as a colormap (see the `-P` switch below). Note that the RGB colors (either the hex triplets or the palettes's colors) will @@ -120,10 +127,17 @@ Gentoo Interpret PATTERN as a predefined theme (perm, cmake, g++, etc.). * `-T DIR`, `--themes-dir DIR`: - Search for additional themes (colout_*.py files) in this directory. + Search for additional themes (colout\_\*.py files) in this directory. * `-P DIR`, `--palettes-dir DIR`: - Search for additional palettes (*.gpl files) in this directory. + Search for additional palettes (\*.gpl files) in this directory. + +* `-d COLORMAP`, `--default COLORMAP`: + When using special colormaps (`scale` or `hash`), use this COLORMAP instead of the `spectrum` one. + 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. + 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. * `-r TYPE(S)`, `--resources TYPE(S)`: Print the names of available resources. Use a comma-separated list of resources names @@ -160,7 +174,11 @@ Recommended packages: ## LIMITATIONS -Don't use nested groups or colout will duplicate the corresponding input text with each matching colors. +Don't use nested groups or colout will duplicate the corresponding input text +with each matching colors. + +Using a default colormap that is incompatible with the special colormap's mode +will end badly. ## EXAMPLES @@ -228,11 +246,14 @@ Don't use nested groups or colout will duplicate the corresponding input text wi related to the value of the progress (from 0%=blue to 100%=red): `cmake .. && make | colout "^(\[\s*[0-9]+%\])" Scale` +* Color hosts and users in `auth.log`, with consistent colors: + `cat /var/log/auth.log | colout "^(\S+\s+){3}(\S+)\s(\S+\s+){3}(\S+)\s+(\S+\s+){2}(\S+)\s*" none,hash,none,hash,none,hash` + ### Bash alias The following bash function color the output of any command with the -cmake and g77 themes: +cmake and g++ themes: function cm() { diff --git a/colout/colout.py b/colout/colout.py index d774a9d..8ac771b 100755 --- a/colout/colout.py +++ b/colout/colout.py @@ -365,7 +365,8 @@ def colorin(text, color="red", style="normal"): if color[0].islower(): mode = 8 - cmap = colormaps["spectrum"] + # Use the default colormap in lower case = 8-colors mode + cmap = colormap # normalize and scale over the nb of colors in cmap i = int( math.ceil( (f - scale[0]) / (scale[1]-scale[0]) * (len(cmap)-1) ) ) @@ -375,7 +376,7 @@ def colorin(text, color="red", style="normal"): else: mode = 256 - cmap = colormaps["Spectrum"] + cmap = colormap i = int( math.ceil( (f - scale[0]) / (scale[1]-scale[0]) * (len(cmap)-1) ) ) color = cmap[i] color_code = str(color) @@ -391,7 +392,7 @@ def colorin(text, color="red", style="normal"): if color[0].islower(): mode = 8 - cmap = colormaps["rainbow"] + cmap = colormap # normalize and scale over the nb of colors in cmap i = int( math.ceil( (f - scale[0]) / (scale[1]-scale[0]) * (len(cmap)-1) ) ) @@ -401,7 +402,7 @@ def colorin(text, color="red", style="normal"): else: mode = 256 - cmap = colormaps["Rainbow"] + cmap = colormap i = int( math.ceil( (f - scale[0]) / (scale[1]-scale[0]) * (len(cmap)-1) ) ) color = cmap[i] color_code = str(color) @@ -472,7 +473,7 @@ def colorin(text, color="red", style="normal"): if not debug: return start + style_code + endmarks[mode] + color_code + "m" + text + stop else: - return start + style_code + endmarks[mode] + color_code + "m<" + color + ">" + text + "" + stop + return start + style_code + endmarks[mode] + color_code + "m<" + str(color) + ">" + text + "" + stop def colorout(text, match, prev_end, color="red", style="normal", group=0): @@ -731,7 +732,8 @@ def __args_parse__(argv, usage=""): in the pattern instead of over patterns") parser.add_argument("-c", "--colormap", action="store_true", - help="Use the given colors as a colormap (cycle the colors at each match)") + help="Interpret the given COLOR comma-separated list of colors as a colormap \ + (cycle the colors at each match)") babel_warn=" (numbers will be parsed according to your locale)" try: @@ -741,7 +743,7 @@ def __args_parse__(argv, usage=""): babel_warn=" (WARNING: python3-babel is not available, install it \ if you want to be able to parse numbers according to your locale)" - parser.add_argument("-l", "--scale", + parser.add_argument("-l", "--scale", metavar="SCALE", help="When using the 'scale' colormap, parse matches as decimal numbers \ and apply the rainbow colormap linearly between the given SCALE=min,max" + babel_warn) @@ -759,6 +761,11 @@ 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", + 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.") + # This normally should be an option with an argument, but this would end in an error, # as no regexp is supposed to be passed after calling this option, # we use it as the argument to this option. @@ -781,7 +788,7 @@ def __args_parse__(argv, usage=""): return args.pattern[0], args.color, args.style, args.groups, \ args.colormap, args.theme, args.source, args.all, args.scale, args.debug, args.resources, args.palettes_dir, \ - args.themes_dir + args.themes_dir, args.default def write_all( as_all, stream_in, stream_out, function, *args ): @@ -816,7 +823,7 @@ if __name__ == "__main__": # if argparse is available else: pattern, color, style, on_groups, as_colormap, as_theme, as_source, as_all, myscale, \ - debug, resources, palettes_dirs, themes_dirs \ + debug, resources, palettes_dirs, themes_dirs, default_colormap \ = __args_parse__(sys.argv, usage) if debug: @@ -917,8 +924,20 @@ if __name__ == "__main__": scale = tuple([float(i) for i in myscale.split(",")]) logging.debug("user-defined scale: %f,%f" % scale) - # use the generator: output lines as they come - if as_colormap is True and color != "rainbow": + if default_colormap and default_colormap not in colormaps: + colormap = default_colormap.split(",") + logging.debug("used-defined default colormap: %s" % ",".join([str(i) for i in colormap]) ) + elif default_colormap and default_colormap in colormaps: + # Configure the default colormap to be in the same mode than the given color + if color[0].islower(): + cmap = default_colormap.lower() + else: + cmap = default_colormap[0].upper() + default_colormap[1:] + logging.debug("used-defined default colormap: %s" % cmap ) + colormap = colormaps[cmap] + logging.debug("used-defined default colormap: %s" % colormap ) + + if as_colormap is True and color not in colormaps: colormap = 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(colormap) )