mirror of
https://github.com/evennia/evennia.git
synced 2026-03-28 02:36:32 +01:00
Implemented ansi-colour backgrounds in webclient. Added a new @color command for displaying colour spaces. Also changed a number of other features outlined in Issue 309.
This commit is contained in:
parent
e534d5f9a0
commit
ec46465656
7 changed files with 177 additions and 61 deletions
|
|
@ -11,7 +11,7 @@ snippet #577349 on http://code.activestate.com.
|
|||
|
||||
import re
|
||||
import cgi
|
||||
from src.utils import ansi
|
||||
from ansi import *
|
||||
|
||||
class TextToHTMLparser(object):
|
||||
"""
|
||||
|
|
@ -20,47 +20,80 @@ class TextToHTMLparser(object):
|
|||
|
||||
tabstop = 4
|
||||
# mapping html color name <-> ansi code.
|
||||
# note that \[ is used here since they go into regexes.
|
||||
colorcodes = [('white', '\033\[1m\033\[37m'),
|
||||
('cyan', '\033\[1m\033\[36m'),
|
||||
('blue', '\033\[1m\033\[34m'),
|
||||
('red', '\033\[1m\033\[31m'),
|
||||
('magenta', '\033\[1m\033\[35m'),
|
||||
('lime', '\033\[1m\033\[32m'),
|
||||
('yellow', '\033\[1m\033\[33m'),
|
||||
('gray', '\033\[37m'),
|
||||
('teal', '\033\[36m'),
|
||||
('navy', '\033\[34m'),
|
||||
('maroon', '\033\[31m'),
|
||||
('purple', '\033\[35m'),
|
||||
('green', '\033\[32m'),
|
||||
('olive', '\033\[33m')]
|
||||
normalcode = '\033\[0m'
|
||||
bold = '\033\[1m'
|
||||
underline = '\033\[4m'
|
||||
codestop = "|".join(co[1] for co in colorcodes + [("", normalcode), ("", bold), ("", underline), ("", "$")])
|
||||
hilite = ANSI_HILITE
|
||||
normal = ANSI_NORMAL
|
||||
underline = ANSI_UNDERLINE
|
||||
colorcodes = [
|
||||
('red', hilite + ANSI_RED),
|
||||
('maroon', ANSI_RED),
|
||||
('lime', hilite + ANSI_GREEN),
|
||||
('green', ANSI_GREEN),
|
||||
('yellow', hilite + ANSI_YELLOW),
|
||||
('olive', ANSI_YELLOW),
|
||||
('blue', hilite + ANSI_BLUE),
|
||||
('navy', ANSI_BLUE),
|
||||
('magenta', hilite + ANSI_MAGENTA),
|
||||
('purple', ANSI_MAGENTA),
|
||||
('cyan', hilite + ANSI_CYAN),
|
||||
('teal', ANSI_CYAN),
|
||||
('white', hilite + ANSI_WHITE), # pure white
|
||||
('gray', ANSI_WHITE), #light grey
|
||||
('dimgray', hilite + ANSI_BLACK), #dark grey
|
||||
('black', ANSI_BLACK), #pure black
|
||||
]
|
||||
colorback = [
|
||||
('bgred', hilite + ANSI_BACK_RED),
|
||||
('bgmaroon', ANSI_BACK_RED),
|
||||
('bglime', hilite + ANSI_BACK_GREEN),
|
||||
('bggreen', ANSI_BACK_GREEN),
|
||||
('bgyellow', hilite + ANSI_BACK_YELLOW),
|
||||
('bgolive', ANSI_BACK_YELLOW),
|
||||
('bgblue', hilite + ANSI_BACK_BLUE),
|
||||
('bgnavy', ANSI_BACK_BLUE),
|
||||
('bgmagenta', hilite + ANSI_BACK_MAGENTA),
|
||||
('bgpurple', ANSI_BACK_MAGENTA),
|
||||
('bgcyan', hilite + ANSI_BACK_CYAN),
|
||||
('bgteal', ANSI_BACK_CYAN),
|
||||
('bgwhite', hilite + ANSI_BACK_WHITE),
|
||||
('bggray', ANSI_BACK_WHITE),
|
||||
('bgdimgray', hilite + ANSI_BACK_BLACK),
|
||||
('bgblack', ANSI_BACK_BLACK),
|
||||
]
|
||||
|
||||
# make sure to escape [
|
||||
colorcodes = [(c, code.replace("[",r"\[")) for c, code in colorcodes]
|
||||
colorback = [(c, code.replace("[",r"\[")) for c, code in colorback]
|
||||
# create stop markers
|
||||
fgstop = [("", c.replace("[", r"\[")) for c in (normal, hilite, underline)]
|
||||
bgstop = [("", c.replace("[", r"\[")) for c in (normal,)]
|
||||
fgstop = "|".join(co[1] for co in colorcodes + fgstop + [("", "$")])
|
||||
bgstop = "|".join(co[1] for co in colorback + bgstop + [("", "$")])
|
||||
|
||||
# pre-compile regexes
|
||||
re_fgs = [(cname, re.compile("(?:%s)(.*?)(?=%s)" % (code, fgstop))) for cname, code in colorcodes]
|
||||
re_bgs = [(cname, re.compile("(?:%s)(.*?)(?=%s)" % (code, bgstop))) for cname, code in colorback]
|
||||
re_normal = re.compile(normal.replace("[", r"\["))
|
||||
re_hilite = re.compile("(?:%s)(.*)(?=%s)" % (hilite.replace("[", r"\["), fgstop))
|
||||
re_uline = re.compile("(?:%s)(.*?)(?=%s)" % (ANSI_UNDERLINE.replace("[",r"\["), fgstop))
|
||||
re_string = re.compile(r'(?P<htmlchars>[<&>])|(?P<space>^[ \t]+)|(?P<lineend>\r\n|\r|\n)', re.S|re.M|re.I)
|
||||
|
||||
def re_color(self, text):
|
||||
"""Replace ansi colors with html color class names.
|
||||
Let the client choose how it will display colors, if it wishes to."""
|
||||
for colorname, code in self.colorcodes:
|
||||
regexp = "(?:%s)(.*?)(?=%s)" % (code, self.codestop)
|
||||
text = re.sub(regexp, r'''<span class="%s">\1</span>''' % colorname, text)
|
||||
return re.sub(self.normalcode, "", text)
|
||||
"""
|
||||
Replace ansi colors with html color class names.
|
||||
Let the client choose how it will display colors, if it wishes to. """
|
||||
for colorname, regex in self.re_fgs:
|
||||
text = regex.sub(r'''<span class="%s">\1</span>''' % colorname, text)
|
||||
for bgname, regex in self.re_bgs:
|
||||
text = regex.sub(r'''<span class="%s">\1</span>''' % bgname, text)
|
||||
return self.re_normal.sub("", text)
|
||||
|
||||
def re_bold(self, text):
|
||||
"Clean out superfluous hilights rather than set <strong>to make it match the look of telnet."
|
||||
#"Replace ansi hilight with strong text element."
|
||||
#regexp = "(?:%s)(.*?)(?=%s)" % (self.bold, self.codestop)
|
||||
#return re.sub(regexp, r'<strong>\1</strong>', text)
|
||||
return re.sub(self.bold, "", text)
|
||||
return self.re_hilite.sub(r'<strong>\1</strong>', text)
|
||||
|
||||
def re_underline(self, text):
|
||||
"Replace ansi underline with html underline class name."
|
||||
regexp = "(?:%s)(.*?)(?=%s)" % (self.underline, self.codestop)
|
||||
return re.sub(regexp, r'<span class="underline">\1</span>', text)
|
||||
return self.re_uline.sub(r'<span class="underline">\1</span>', text)
|
||||
|
||||
def remove_bells(self, text):
|
||||
"Remove ansi specials"
|
||||
|
|
@ -99,15 +132,13 @@ class TextToHTMLparser(object):
|
|||
t = t.replace(' ', ' ')
|
||||
return t
|
||||
|
||||
def parse(self, text):
|
||||
def parse(self, text, strip_ansi=False):
|
||||
"""
|
||||
Main access function, converts a text containing
|
||||
ansi codes into html statements.
|
||||
"""
|
||||
|
||||
# parse everything to ansi first
|
||||
text = ansi.parse_ansi(text)
|
||||
|
||||
text = parse_ansi(text, strip_ansi=strip_ansi, xterm256=False)
|
||||
# convert all ansi to html
|
||||
result = re.sub(self.re_string, self.do_sub, text)
|
||||
result = self.re_color(result)
|
||||
|
|
@ -118,7 +149,7 @@ class TextToHTMLparser(object):
|
|||
result = self.remove_backspaces(result)
|
||||
result = self.convert_urls(result)
|
||||
# clean out eventual ansi that was missed
|
||||
result = ansi.parse_ansi(result, strip_ansi=True)
|
||||
#result = parse_ansi(result, strip_ansi=True)
|
||||
|
||||
return result
|
||||
|
||||
|
|
@ -128,8 +159,8 @@ HTML_PARSER = TextToHTMLparser()
|
|||
# Access function
|
||||
#
|
||||
|
||||
def parse_html(string, parser=HTML_PARSER):
|
||||
def parse_html(string, strip_ansi=False, parser=HTML_PARSER):
|
||||
"""
|
||||
Parses a string, replace ansi markup with html
|
||||
"""
|
||||
return parser.parse(string)
|
||||
return parser.parse(string, strip_ansi=strip_ansi)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue