Forked from
nomad-lab / python-common
324 commits behind the upstream repository.
-
Henning Glawe authoredHenning Glawe authored
match_highlighter.py 2.35 KiB
from builtins import range
from builtins import object
import logging
from operator import itemgetter
import re
logger = logging.getLogger("nomadcore.match_highlighter")
class ANSI(object):
RESET='\033[0m'
RESET_COLOR='\033[39;49m'
BEGIN_INVERT='\033[7m'
END_INVERT='\033[27m'
FG_RED='\033[31m'
class MatchHighlighter(object):
"""ANSI-Color highlighting for capturing groups in regex matches"""
def __init__(self, highlightMode):
self.highlightMode=highlightMode
def highlight(self,match,lineOrig):
# shortcut: there is nothing to highlight
if (not match) or (self.highlightMode==0):
return(lineOrig)
# list with the highlight switching events
# tuples: (pos, event, ansi)
# event:
# matchstart=-1
# close= 0
# open= 1
# matchend= 2
# ansi: escape code
ansiSwitch = list()
# mark whole area of match by fg/bg inversion
ansiSwitch.append([match.start(),-1,ANSI.BEGIN_INVERT])
ansiSwitch.append([match.end(), 2,ANSI.END_INVERT])
# capture groups
ngroups=len(match.groups())
for groupi in range(1,ngroups+1):
s,e=match.span(groupi)
# logger.error("i:%d %3d %3d '%s'" % (groupi, s, e,
# match.group(groupi)))
if match.group(groupi) is not None:
ansiSwitch.append([s,1,ANSI.FG_RED])
ansiSwitch.append([e,0,ANSI.RESET_COLOR])
# sort by position, then by event
ansiSwitch=sorted(ansiSwitch, key=itemgetter(0,1))
if ansiSwitch[-1][0]>len(lineOrig):
raise Exception('line_exceed',"match exceeds line")
# append line remainder if necessary
if ansiSwitch[-1][0]<len(lineOrig):
ansiSwitch.append([len(lineOrig),3,''])
# logger.error(ansiSwitch)
# construct highlighted Line
lastPos=0
highlightedLine=''
for i in range(len(ansiSwitch)):
if ansiSwitch[i][0]>lastPos:
highlightedLine+=lineOrig[lastPos:ansiSwitch[i][0]]
lastPos=ansiSwitch[i][0]
highlightedLine+=ansiSwitch[i][2]
# always insert reset at end or before final newline
highlightedLine=re.sub(r"(\n)$",ANSI.RESET + "\g<1>",highlightedLine)
return(highlightedLine)