Add support for source code coloring with pygments

Themes/source are available with a switch.
This commit is contained in:
Johann Dreo 2013-03-22 23:59:42 +01:00
commit d444c1868c
2 changed files with 83 additions and 6 deletions

View file

@ -32,6 +32,12 @@ available in the ANSI table. `random` will do the same in 8 colors mode.
When not specified, a *COLOR* defaults to _red_ and a *STYLE* defaults to _bold_.
`colout` comes with some predefined themes to rapidely color well-known outputs
(see the `-t` switch below).
If the python-pygments library is available, `colout` can be used as an interface
to it (see the `-s` switch below).
`colout` is released under the GNU Public License v3.
@ -49,6 +55,14 @@ When not specified, a *COLOR* defaults to _red_ and a *STYLE* defaults to _bold_
* `-c`, `--colormap`:
Use the given list of comma-separated colors as a colormap (cycle the colors at each match).
* `-t`, `--theme`:
Interpret PATTERN as a predefined theme (perm, cmake, g++, etc.)
* `-s`, `--source`:
Interpret PATTERN as a source code readable by the Pygments library. If the first letter of PATTERN
is upper case, use the 256 colors mode, if it is lower case, use the 8 colors mode.
In 256 colors, interpret COLOR as a Pygments style (e.g. "default").
## REGULAR EXPRESSIONS
@ -91,6 +105,8 @@ special characters that would be recognize by your shell.
* Color a make output, line numbers in yellow, errors in bold red, warning in magenta, pragma in green and C++ file base names in cyan:
`make 2>&1 | colout :\([0-9]+\):[0-9]* yellow normal | colout error | colout warning magenta | colout pragma green normal | colout /\(\\w+\)*\.\(h\|cpp\) cyan normal`
Or using themes:
`make 2>&³ | colout -t cmake | colout -t g++`
* Color each word in the head of auth.log with a rainbow color map, starting a new colormap at each new line (the
begining of the command is just bash magic to repeat the string "(\\w+)\\W+":
@ -99,3 +115,8 @@ special characters that would be recognize by your shell.
* Color each line of a file with a different color among a 256 color gradient from cyan to green:
`head /var/log/auth.log | ./colout.py -c "^.*$" 39,38,37,36,35,34`
* Color a source code in 8 colors mode:
`cat colout.py | grep -v "#" | colout python`
* Color a source code in 256 colors mode:
`cat colout.py | colout Python monokai`

View file

@ -235,7 +235,7 @@ def __args_dirty__(argv,usage=""):
# Use a dirty argument picker
# Check for bad usage or an help flag
if len(argv) < 2 \
or len(argv) > 6 \
or len(argv) > 9 \
or argv[1] == "--help" \
or argv[1] == "-h":
print(usage+"\n")
@ -264,8 +264,12 @@ def __args_dirty__(argv,usage=""):
on_groups = bool(argv[5])
if len(argv) == 7:
as_colormap = bool(argv[6])
if len(argv) == 8:
as_theme = bool(argv[7])
if len(argv) == 9:
as_source = bool(argv[8])
return pattern,color,style,on_stderr,on_groups,as_colormap
return pattern,color,style,on_stderr,on_groups,as_colormap,as_theme,as_source
def __args_parse__(argv,usage=""):
@ -298,9 +302,18 @@ def __args_parse__(argv,usage=""):
parser.add_argument("-c", "--colormap", action="store_true",
help="Use the given colors as a colormap (cycle the colors at each match)")
parser.add_argument("-t", "--theme", action="store_true",
help="Interpret REGEX as a theme")
parser.add_argument("-s", "--source", action="store_true",
help="""Interpret REGEX as a source code readable by the Pygments library.
If the first letter of PATTERN is upper case, use the 256 colors mode,
if it is lower case, use the 8 colors mode.
In 256 colors, interpret COLOR as a Pygments style (e.g. "default").""")
args = parser.parse_args()
return args.pattern[0], args.color, args.style, args.stderr, args.groups, args.colormap
return args.pattern[0], args.color, args.style, args.stderr, args.groups, args.colormap, args.theme, args.source
def write( colored, on_stderr=False ):
@ -326,17 +339,18 @@ if __name__ == "__main__":
# if argparse is not installed
except ImportError:
pattern,color,style,on_stderr,on_groups,as_colormap = __args_dirty__(sys.argv,usage)
pattern,color,style,on_stderr,on_groups,as_colormap,as_theme,as_source = __args_dirty__(sys.argv,usage)
# if argparse is available
else:
pattern,color,style,on_stderr,on_groups,as_colormap = __args_parse__(sys.argv,usage)
pattern,color,style,on_stderr,on_groups,as_colormap,as_theme,as_source = __args_parse__(sys.argv,usage)
# use the generator: output lines as they come
if as_colormap == True and color != "rainbow":
colormap = color.split(",") # replace the colormap by the given colors
color = "colormap" # use the keyword to switch to colormap instead of list of colors
# load available themes
themes = {}
import glob
for f in glob.iglob("colout_*.py"):
@ -344,7 +358,23 @@ if __name__ == "__main__":
name = "_".join(module.split("_")[1:])
themes[name] = __import__(module)
if pattern in themes.keys():
# load available pygments lexers
try:
from pygments.lexers import get_all_lexers
from pygments.lexers import get_lexer_by_name
from pygments import highlight
from pygments.formatters import Terminal256Formatter
from pygments.formatters import TerminalFormatter
except ImportError:
pass
else:
lexers = []
for lexer in get_all_lexers():
lexers.append( lexer[1][0] )
# if theme
if as_theme:
assert( pattern in themes.keys() )
while True:
try:
item = sys.stdin.readline()
@ -354,6 +384,32 @@ if __name__ == "__main__":
break
colored = themes[pattern].theme(item)
write(colored)
# if pygments
elif as_source:
assert( pattern.lower() in lexers )
lexer = get_lexer_by_name(pattern.lower())
# Python => 256 colors, python => 8 colors
ask_256 = pattern[0].isupper()
if ask_256:
try:
formatter = Terminal256Formatter(style = color)
except: # style not found
formatter = Terminal256Formatter()
else:
formatter = TerminalFormatter()
while True:
try:
item = sys.stdin.readline()
except KeyboardInterrupt:
break
if not item:
break
colored = highlight( item, lexer, formatter)
write(colored)
# if color
else:
for colored in colorgen( sys.stdin, pattern, color, style, on_groups):
write(colored)