From c15f107ad9629c0c028686b180da1003b3c3ab8c Mon Sep 17 00:00:00 2001 From: Griatch Date: Fri, 24 Jun 2016 23:22:38 +0200 Subject: [PATCH] Add webclient support for blink, underline and inverse ANSI tags. The inverse tag will produce a dotted outline in the webclient; for now this seems to be no obvious way to inverse the background in a way similar to the terminal inverse. Resolves #976. --- evennia/utils/text2html.py | 54 +++++++++++++++---- .../static/webclient/css/webclient.css | 27 +++++++++- 2 files changed, 68 insertions(+), 13 deletions(-) diff --git a/evennia/utils/text2html.py b/evennia/utils/text2html.py index 0bdcb2c9d..05c0d44c9 100644 --- a/evennia/utils/text2html.py +++ b/evennia/utils/text2html.py @@ -30,9 +30,11 @@ class TextToHTMLparser(object): tabstop = 4 # mapping html color name <-> ansi code. hilite = ANSI_HILITE - unhilite = ANSI_UNHILITE - normal = ANSI_NORMAL + unhilite = ANSI_UNHILITE # this will be stripped - there is no css equivalent. + normal = ANSI_NORMAL # " underline = ANSI_UNDERLINE + blink = ANSI_BLINK + inverse = ANSI_INVERSE # this will produce an outline; no obvious css equivalent? colorcodes = [ ('color-000', unhilite + ANSI_BLACK), # pure black ('color-001', unhilite + ANSI_RED), @@ -78,27 +80,30 @@ class TextToHTMLparser(object): bg_colormap = dict((code, clr) for clr, code in colorback) # create stop markers - fgstop = "(?:\033\[1m|\033\[22m)*\033\[3.*?m|\033\[0m|$" - bgstop = "(?:\033\[1m|\033\[22m)*\033\[4.*?m|\033\[0m|$" + fgstop = "(?:\033\[1m|\033\[22m)*\033\[3[0-8].*?m|\033\[0m|$" + bgstop = "(?:\033\[1m|\033\[22m)*\033\[4[0-8].*?m|\033\[0m|$" # extract color markers, tagging the start marker and the text marked - re_fgs = re.compile("((?:\033\[1m|\033\[22m)*\033\[3.*?m)(.*?)(?=" + fgstop + ")") - re_bgs = re.compile("((?:\033\[1m|\033\[22m)*\033\[4.*?m)(.*?)(?=" + bgstop + ")") + re_fgs = re.compile("((?:\033\[1m|\033\[22m)*\033\[3[0-8].*?m)(.*?)(?=" + fgstop + ")") + re_bgs = re.compile("((?:\033\[1m|\033\[22m)*\033\[4[0-8].*?m)(.*?)(?=" + bgstop + ")") 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_hilite = re.compile("(?:%s)(.*)(?=%s|%s)" % (hilite.replace("[", r"\["), fgstop, bgstop)) + re_unhilite = re.compile("(?:%s)(.*)(?=%s|%s)" % (unhilite.replace("[", r"\["), fgstop, bgstop)) + re_uline = re.compile("(?:%s)(.*?)(?=%s|%s)" % (underline.replace("[", r"\["), fgstop, bgstop)) + re_blink = re.compile("(?:%s)(.*?)(?=%s|%s)" % (blink.replace("[", r"\["), fgstop, bgstop)) + re_inverse = re.compile("(?:%s)(.*?)(?=%s|%s)" % (inverse.replace("[", r"\["), fgstop, bgstop)) re_string = re.compile(r'(?P[<&>])|(?P [ \t]+)|(?P\r\n|\r|\n)', re.S|re.M|re.I) re_url = re.compile(r'((?:ftp|www|https?)\W+(?:(?!\.(?:\s|$)|&\w+;)[^"\',;$*^\\(){}<>\[\]\s])+)(\.(?:\s|$)|&\w+;|)') re_mxplink = re.compile(r'\|lc(.*?)\|lt(.*?)\|le', re.DOTALL) def _sub_fg(self, colormatch): code, text = colormatch.groups() - return r'''%s''' % (self.fg_colormap.get(code, code), text) + return r'''%s''' % (self.fg_colormap.get(code, "err"), text) def _sub_bg(self, colormatch): code, text = colormatch.groups() - return r'''%s''' % (self.bg_colormap.get(code, code), text) + return r'''%s''' % (self.bg_colormap.get(code, "err"), text) def re_color(self, text): """ @@ -129,7 +134,8 @@ class TextToHTMLparser(object): text (str): Processed text. """ - return self.re_hilite.sub(r'\1', text) + text = self.re_hilite.sub(r'\1', text) + return self.re_unhilite.sub(r'\1', text) # strip unhilite - there is no equivalent in css. def re_underline(self, text): """ @@ -144,6 +150,30 @@ class TextToHTMLparser(object): """ return self.re_uline.sub(r'\1', text) + def re_blinking(self, text): + """ + Replace ansi blink with custom blink css class + + Args: + text (str): Text to process. + + Returns: + text (str): Processed text. + """ + return self.re_blink.sub(r'\1', text) + + def re_inversing(self, text): + """ + Replace ansi inverse with custom inverse css class + + Args: + text (str): Text to process. + + Returns: + text (str): Processed text. + """ + return self.re_inverse.sub(r'\1', text) + def remove_bells(self, text): """ Remove ansi specials @@ -258,6 +288,8 @@ class TextToHTMLparser(object): result = self.re_color(result) result = self.re_bold(result) result = self.re_underline(result) + result = self.re_blinking(result) + result = self.re_inversing(result) result = self.remove_bells(result) result = self.convert_linebreaks(result) result = self.remove_backspaces(result) diff --git a/evennia/web/webclient/static/webclient/css/webclient.css b/evennia/web/webclient/static/webclient/css/webclient.css index 47d54ca4d..bb7ffcd26 100644 --- a/evennia/web/webclient/static/webclient/css/webclient.css +++ b/evennia/web/webclient/static/webclient/css/webclient.css @@ -21,13 +21,13 @@ body { } -a:link, a:visited { color: inherit } +a:link, a:visited { color: inherit; } a:hover, a:active { color: inherit; font-weight: bold;} /* Set this to e.g. bolder if wanting to have ansi-highlights bolden * stand-alone text.*/ -strong {font-weight:normal;} +strong {font-weight: bold;} div {margin:0px;} @@ -48,6 +48,29 @@ div {margin:0px;} .underline { text-decoration: underline; } +/* Inverse - this will make a dotted outline. is there a more + * ANSI-similar way? */ +.inverse { + outline-style: dotted; + outline-color: invert; +} + +/* Create blinking text */ +.blink { + animation: blink-animation 1s steps(5, start) infinite; + -webkit-animation: blink-animation 1s steps(5, start) infinite; +} +@keyframes blink-animation { + to { + visibility: hidden; + } +} +@-webkit-keyframes blink-animation { + to { + visibility: hidden; + } +} + /* Style specific classes corresponding to formatted, narative text. */