ansi.py
97 lines
| 2.6 KiB
| text/x-python
|
PythonLexer
Jonathan Frederic
|
r10676 | """Filters for processing ANSI colors within Jinja templates. | ||
""" | ||||
#----------------------------------------------------------------------------- | ||||
# Copyright (c) 2013, the IPython Development Team. | ||||
# | ||||
# Distributed under the terms of the Modified BSD License. | ||||
# | ||||
# The full license is in the file COPYING.txt, distributed with this software. | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
Jonathan Frederic
|
r10485 | import re | ||
Jonathan Frederic
|
r10676 | #----------------------------------------------------------------------------- | ||
# Classes and functions | ||||
#----------------------------------------------------------------------------- | ||||
Jonathan Frederic
|
r10485 | |||
Jonathan Frederic
|
r10676 | def remove_ansi(source): | ||
""" | ||||
Remove ansi from text | ||||
Parameters | ||||
---------- | ||||
source : str | ||||
Source to remove the ansi from | ||||
""" | ||||
return re.sub(r'\033\[(0|\d;\d\d)m', '', source) | ||||
Jonathan Frederic
|
r10485 | |||
Jonathan Frederic
|
r10676 | |||
def ansi2html(text): | ||||
""" | ||||
Conver ansi colors to html colors. | ||||
Parameters | ||||
---------- | ||||
text : str | ||||
Text containing ansi colors to convert to html | ||||
""" | ||||
Jonathan Frederic
|
r10485 | ansi_colormap = { | ||
'30': 'ansiblack', | ||||
'31': 'ansired', | ||||
'32': 'ansigreen', | ||||
'33': 'ansiyellow', | ||||
'34': 'ansiblue', | ||||
'35': 'ansipurple', | ||||
'36': 'ansicyan', | ||||
'37': 'ansigrey', | ||||
'01': 'ansibold', | ||||
} | ||||
# do ampersand first | ||||
Jonathan Frederic
|
r10676 | text = text.replace('&', '&') | ||
Jonathan Frederic
|
r10485 | html_escapes = { | ||
'<': '<', | ||||
'>': '>', | ||||
"'": ''', | ||||
'"': '"', | ||||
'`': '`', | ||||
} | ||||
Jonathan Frederic
|
r10624 | |||
Jonathan Frederic
|
r10485 | for c, escape in html_escapes.iteritems(): | ||
Jonathan Frederic
|
r10676 | text = text.replace(c, escape) | ||
Jonathan Frederic
|
r10485 | |||
ansi_re = re.compile('\x1b' + r'\[([\dA-Fa-f;]*?)m') | ||||
Jonathan Frederic
|
r10676 | m = ansi_re.search(text) | ||
Jonathan Frederic
|
r10485 | opened = False | ||
cmds = [] | ||||
opener = '' | ||||
closer = '' | ||||
while m: | ||||
cmds = m.groups()[0].split(';') | ||||
closer = '</span>' if opened else '' | ||||
Jonathan Frederic
|
r10624 | |||
Jonathan Frederic
|
r10485 | # True if there is there more than one element in cmds, *or* | ||
# if there is only one but it is not equal to a string of zeroes. | ||||
opened = len(cmds) > 1 or cmds[0] != '0' * len(cmds[0]) | ||||
classes = [] | ||||
for cmd in cmds: | ||||
if cmd in ansi_colormap: | ||||
classes.append(ansi_colormap.get(cmd)) | ||||
if classes: | ||||
opener = '<span class="%s">' % (' '.join(classes)) | ||||
else: | ||||
opener = '' | ||||
Jonathan Frederic
|
r10676 | text = re.sub(ansi_re, closer + opener, text, 1) | ||
Jonathan Frederic
|
r10485 | |||
Jonathan Frederic
|
r10676 | m = ansi_re.search(text) | ||
Jonathan Frederic
|
r10485 | |||
if opened: | ||||
Jonathan Frederic
|
r10676 | text += '</span>' | ||
return text | ||||