rewrite highbeam
This commit is contained in:
@@ -1,161 +1,106 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
function usage {
|
import argparse
|
||||||
echo -e ' High Beam Highlighter
|
import json
|
||||||
- a trial to create a very generic modifyable
|
import os
|
||||||
syntax highlighter.
|
import re
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
Example rules: ( ~/.highbeamrc )
|
# Define color codes
|
||||||
--------------------
|
E = "\x1b["
|
||||||
RULES=(
|
colors = {
|
||||||
"[0-9]" "$c" # Show numbers with Cyan color. NOTE: since the colors are represented with numbers, having this later in the rules will break coloring!
|
"K": f"{E}1;30m",
|
||||||
"$USER[ ]\+$USER" "$BC$K" # Use quotes to have rules with spaces. This colors the "ls -la" usernames. background cyan, black text
|
"R": f"{E}1;31m",
|
||||||
status "$g" # simple word matching, coloring green
|
"G": f"{E}1;32m",
|
||||||
"^d[^ ]*" "$G" # color words at the beginning of line, starting with d. color bright green
|
"B": f"{E}1;34m",
|
||||||
"q.\{0,3\}r" "$Y" # q*r with maximum 3 characters in between. color bright yellow
|
"Y": f"{E}1;33m",
|
||||||
|
"M": f"{E}1;35m",
|
||||||
|
"C": f"{E}1;36m",
|
||||||
|
"W": f"{E}1;37m",
|
||||||
|
"k": f"{E}30m",
|
||||||
|
"r": f"{E}31m",
|
||||||
|
"g": f"{E}32m",
|
||||||
|
"b": f"{E}34m",
|
||||||
|
"y": f"{E}33m",
|
||||||
|
"m": f"{E}35m",
|
||||||
|
"c": f"{E}36m",
|
||||||
|
"w": f"{E}37m",
|
||||||
|
"u": f"{E}4m",
|
||||||
|
"U": f"{E}4m",
|
||||||
|
"Z": f"{E}0m",
|
||||||
|
"BK": f"{E}40m",
|
||||||
|
"BR": f"{E}41m",
|
||||||
|
"BG": f"{E}42m",
|
||||||
|
"BB": f"{E}44m",
|
||||||
|
"BY": f"{E}43m",
|
||||||
|
"BM": f"{E}45m",
|
||||||
|
"BC": f"{E}46m",
|
||||||
|
"BW": f"{E}47m",
|
||||||
|
}
|
||||||
|
simple_colors = "GYCMW"
|
||||||
|
|
||||||
|
|
||||||
|
def highlight_text(text, rules, simple_words, regex_patterns, case_sensitive):
|
||||||
|
flags = 0 if case_sensitive else re.IGNORECASE
|
||||||
|
|
||||||
|
# Apply simple highlights
|
||||||
|
for i, word in enumerate(simple_words):
|
||||||
|
color = simple_colors[i % len(simple_colors)]
|
||||||
|
text = re.sub(rf"{re.escape(word)}", f"{colors[color]}{word}{colors['Z']}", text)
|
||||||
|
|
||||||
|
# Apply regex highlights
|
||||||
|
for pattern, replacement in rules:
|
||||||
|
for code in colors:
|
||||||
|
replacement = replacement.replace("{" + code + "}", colors[code])
|
||||||
|
text = re.sub(pattern, f"{replacement}\\g<0>{colors['Z']}", text, flags=flags)
|
||||||
|
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def load_rules(config_file):
|
||||||
|
rules = []
|
||||||
|
try:
|
||||||
|
with open(config_file, "r") as f:
|
||||||
|
rules = json.load(f)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error reading config file: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
return rules
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="High Beam Highlighter",
|
||||||
|
usage=""" cat code.py | highbeam -s def for lambda -r rules {B}{U}
|
||||||
|
|
||||||
|
Example ~/.highbeamrc:
|
||||||
|
[ {"pattern":"view", "color":"{G}"}, {"pattern":"^qo[^ ]*", "color":"{U}{Y}"} ]""",
|
||||||
)
|
)
|
||||||
--------------------
|
parser.add_argument("-c", action="store_true", help="Be case sensitive")
|
||||||
Rules can be also exressed as a space separated list variable:
|
parser.add_argument("-f", default="~/.highbeamrc", help="Define config file (default ~/.highbeamrc)")
|
||||||
export HB_RULES='\''"[0-9]" "$C" "g" "$Y"'\''
|
parser.add_argument("-s", nargs="+", help="Simple highlight words")
|
||||||
HB_RULES are appended to other rules
|
parser.add_argument("-r", nargs="+", help='Define rules with a string, ex. "-r word {G} ^error {R}" ')
|
||||||
|
|
||||||
Bright colors: $R $G $B $Y $M $C $W $K
|
args = parser.parse_args()
|
||||||
Dark colors: $r $g $b $y $m $c $w $k
|
config_file = os.path.expanduser(args.f)
|
||||||
Modify to bright version by prefixing with $H (e.g. $H$g)
|
rules = []
|
||||||
Background colors: $BR $BG $BB $BY $BC $BM $BW
|
if os.path.exists(config_file):
|
||||||
Underline: $U
|
rules = load_rules(config_file)
|
||||||
|
|
||||||
Usage: highbeam [-c] [-h] [-f config]
|
simple_words = args.s if args.s else []
|
||||||
-c Be case sensitive
|
regex_patterns = args.r if args.r else []
|
||||||
-D Print current rules, not the input
|
|
||||||
-s Simple highlight a string (as argument)
|
|
||||||
-h Help
|
|
||||||
-f Define config file (default ~/.highbeamrc)
|
|
||||||
-r Define rules with a string, replaces the other rules
|
|
||||||
-r '\''"land[^[:space:]]\+" "$G" "sky" "$B"'\''
|
|
||||||
|
|
||||||
'
|
# Convert regex patterns to rules
|
||||||
|
for i in range(0, len(regex_patterns), 2):
|
||||||
}
|
if i + 1 < len(regex_patterns):
|
||||||
|
rules.append((regex_patterns[i], regex_patterns[i + 1]))
|
||||||
E='\x1b['
|
else:
|
||||||
H="${E}1m"
|
raise ValueError("Regex patterns missing color code")
|
||||||
Z="${E}0m"
|
|
||||||
|
|
||||||
# list of text colors:
|
|
||||||
K="${E}1;30m"
|
|
||||||
R="${E}1;31m"
|
|
||||||
G="${E}1;32m"
|
|
||||||
B="${E}1;34m"
|
|
||||||
Y="${E}1;33m"
|
|
||||||
M="${E}1;35m"
|
|
||||||
C="${E}1;36m"
|
|
||||||
W="${E}1;37m"
|
|
||||||
k="${E}30m"
|
|
||||||
r="${E}31m"
|
|
||||||
g="${E}32m"
|
|
||||||
b="${E}34m"
|
|
||||||
y="${E}33m"
|
|
||||||
m="${E}35m"
|
|
||||||
c="${E}36m"
|
|
||||||
w="${E}37m"
|
|
||||||
|
|
||||||
# list of BG colors:
|
|
||||||
BR="${E}41m"
|
|
||||||
BG="${E}42m"
|
|
||||||
BB="${E}44m"
|
|
||||||
BY="${E}43m"
|
|
||||||
BM="${E}45m"
|
|
||||||
BC="${E}46m"
|
|
||||||
BW="${E}47m"
|
|
||||||
|
|
||||||
# lines
|
|
||||||
U="${E}4m"
|
|
||||||
|
|
||||||
CONF_FILE=~/.highbeamrc
|
|
||||||
CONF_LINE=""
|
|
||||||
FLAGS="ig"
|
|
||||||
PRINT=0
|
|
||||||
while getopts chf:r:s:D opt
|
|
||||||
do case "$opt" in
|
|
||||||
c)
|
|
||||||
FLAGS="g"
|
|
||||||
;;
|
|
||||||
h)
|
|
||||||
usage
|
|
||||||
exit
|
|
||||||
;;
|
|
||||||
f)
|
|
||||||
CONF_FILE=$OPTARG
|
|
||||||
;;
|
|
||||||
r)
|
|
||||||
CONF_LINE=( $( eval echo $OPTARG ) )
|
|
||||||
;;
|
|
||||||
s)
|
|
||||||
HB_RULES='"'"$OPTARG"'" "$U$Y"' exec "$0"
|
|
||||||
exit $?
|
|
||||||
;;
|
|
||||||
D)
|
|
||||||
PRINT=1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
[[ -z "$CONF_LINE" ]] && {
|
|
||||||
# user rules:
|
|
||||||
[[ -e "${CONF_FILE}" ]] && {
|
|
||||||
. "${CONF_FILE}" || {
|
|
||||||
echo You may have wrong format in "${CONF_FILE}" >&2
|
|
||||||
usage >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (( rIndex=0; rIndex<${#RULES[@]}; rIndex++ ));
|
|
||||||
do REGEX="$REGEX -e 's/\(${RULES[$rIndex]}\)/${RULES[$(( $rIndex + 1 ))]}\1${Z}/${FLAGS}'"
|
|
||||||
rIndex=$(( $rIndex + 1 ))
|
|
||||||
done
|
|
||||||
} || {
|
|
||||||
# string fed rules
|
|
||||||
for (( rIndex=0; rIndex<${#CONF_LINE[@]}; rIndex++ ));
|
|
||||||
do REGEX="$REGEX -e 's/\(${CONF_LINE[$rIndex]}\)/${CONF_LINE[$(( $rIndex + 1 ))]}\1${Z}/${FLAGS}'"
|
|
||||||
rIndex=$(( $rIndex + 1 ))
|
|
||||||
done
|
|
||||||
}
|
|
||||||
# env variable fed rules
|
|
||||||
[[ -z "$HB_RULES" ]] || {
|
|
||||||
CONF_ENV=( $( eval echo "$HB_RULES" ) )
|
|
||||||
for (( rIndex=0; rIndex<${#CONF_ENV[@]}; rIndex++ ));
|
|
||||||
do REGEX="$REGEX -e 's/\(${CONF_ENV[$rIndex]}\)/${CONF_ENV[$(( $rIndex + 1 ))]}\1${Z}/${FLAGS}'"
|
|
||||||
rIndex=$(( $rIndex + 1 ))
|
|
||||||
done
|
|
||||||
}
|
|
||||||
[[ $PRINT -eq 1 ]] && {
|
|
||||||
echo "From $CONF_FILE:"
|
|
||||||
for (( rIndex=0; rIndex<${#RULES[@]}; rIndex++ ));
|
|
||||||
do printf "%s\\t%s" "${RULES[$rIndex]}" "${RULES[$(( $rIndex + 1 ))]}"
|
|
||||||
rIndex=$(( $rIndex + 1 ))
|
|
||||||
done
|
|
||||||
echo "From argument switches:"
|
|
||||||
for (( rIndex=0; rIndex<${#CONF_LINE[@]}; rIndex++ ));
|
|
||||||
do printf "%s\\t%s" "${CONF_LINE[$rIndex]}" "${CONF_LINE[$(( $rIndex + 1 ))]}"
|
|
||||||
rIndex=$(( $rIndex + 1 ))
|
|
||||||
done
|
|
||||||
echo "From HB_RULES environment:"
|
|
||||||
for (( rIndex=0; rIndex<${#CONF_ENV[@]}; rIndex++ ));
|
|
||||||
do printf "%s\\t%s" "${CONF_ENV[$rIndex]}" "${CONF_ENV[$(( $rIndex + 1 ))]}"
|
|
||||||
rIndex=$(( $rIndex + 1 ))
|
|
||||||
done
|
|
||||||
#~ echo ${CONF_ENV[@]}
|
|
||||||
#~ echo $HB_RULES
|
|
||||||
#~ echo $REGEX
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
[[ -z "$REGEX" ]] && {
|
|
||||||
cat -
|
|
||||||
} || {
|
|
||||||
eval sed $REGEX || echo Maybe errors in your rules: "$REGEX" >&2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for text in sys.stdin:
|
||||||
|
print(highlight_text(text, rules, simple_words, regex_patterns, args.c), end="")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user