Add support for source code coloring with pygments
Themes/source are available with a switch.
This commit is contained in:
parent
e583e54bf3
commit
d444c1868c
2 changed files with 83 additions and 6 deletions
21
README.md
21
README.md
|
|
@ -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_.
|
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.
|
`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`:
|
* `-c`, `--colormap`:
|
||||||
Use the given list of comma-separated colors as a colormap (cycle the colors at each match).
|
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
|
## 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:
|
* 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`
|
`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
|
* 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+":
|
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:
|
* 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`
|
`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`
|
||||||
|
|
|
||||||
68
colout.py
68
colout.py
|
|
@ -235,7 +235,7 @@ def __args_dirty__(argv,usage=""):
|
||||||
# Use a dirty argument picker
|
# Use a dirty argument picker
|
||||||
# Check for bad usage or an help flag
|
# Check for bad usage or an help flag
|
||||||
if len(argv) < 2 \
|
if len(argv) < 2 \
|
||||||
or len(argv) > 6 \
|
or len(argv) > 9 \
|
||||||
or argv[1] == "--help" \
|
or argv[1] == "--help" \
|
||||||
or argv[1] == "-h":
|
or argv[1] == "-h":
|
||||||
print(usage+"\n")
|
print(usage+"\n")
|
||||||
|
|
@ -264,8 +264,12 @@ def __args_dirty__(argv,usage=""):
|
||||||
on_groups = bool(argv[5])
|
on_groups = bool(argv[5])
|
||||||
if len(argv) == 7:
|
if len(argv) == 7:
|
||||||
as_colormap = bool(argv[6])
|
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=""):
|
def __args_parse__(argv,usage=""):
|
||||||
|
|
@ -298,9 +302,18 @@ def __args_parse__(argv,usage=""):
|
||||||
parser.add_argument("-c", "--colormap", action="store_true",
|
parser.add_argument("-c", "--colormap", action="store_true",
|
||||||
help="Use the given colors as a colormap (cycle the colors at each match)")
|
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()
|
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 ):
|
def write( colored, on_stderr=False ):
|
||||||
|
|
@ -326,17 +339,18 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
# if argparse is not installed
|
# if argparse is not installed
|
||||||
except ImportError:
|
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
|
# if argparse is available
|
||||||
else:
|
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
|
# use the generator: output lines as they come
|
||||||
if as_colormap == True and color != "rainbow":
|
if as_colormap == True and color != "rainbow":
|
||||||
colormap = color.split(",") # replace the colormap by the given colors
|
colormap = color.split(",") # replace the colormap by the given colors
|
||||||
color = "colormap" # use the keyword to switch to colormap instead of list of colors
|
color = "colormap" # use the keyword to switch to colormap instead of list of colors
|
||||||
|
|
||||||
|
# load available themes
|
||||||
themes = {}
|
themes = {}
|
||||||
import glob
|
import glob
|
||||||
for f in glob.iglob("colout_*.py"):
|
for f in glob.iglob("colout_*.py"):
|
||||||
|
|
@ -344,7 +358,23 @@ if __name__ == "__main__":
|
||||||
name = "_".join(module.split("_")[1:])
|
name = "_".join(module.split("_")[1:])
|
||||||
themes[name] = __import__(module)
|
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:
|
while True:
|
||||||
try:
|
try:
|
||||||
item = sys.stdin.readline()
|
item = sys.stdin.readline()
|
||||||
|
|
@ -354,6 +384,32 @@ if __name__ == "__main__":
|
||||||
break
|
break
|
||||||
colored = themes[pattern].theme(item)
|
colored = themes[pattern].theme(item)
|
||||||
write(colored)
|
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:
|
else:
|
||||||
for colored in colorgen( sys.stdin, pattern, color, style, on_groups):
|
for colored in colorgen( sys.stdin, pattern, color, style, on_groups):
|
||||||
write(colored)
|
write(colored)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue