mirror of
https://github.com/evennia/evennia.git
synced 2026-04-03 14:37:17 +02:00
Added m_len and made ANSIString ignore MXP.
This commit is contained in:
parent
b9e560660e
commit
571b1d5fad
3 changed files with 58 additions and 16 deletions
|
|
@ -82,7 +82,7 @@ class ANSIParser(object):
|
|||
"""
|
||||
return self.ansi_map.get(ansimatch.group(), "")
|
||||
|
||||
def sub_xterm256(self, rgbmatch):
|
||||
def sub_xterm256(self, rgbmatch, convert=False):
|
||||
"""
|
||||
This is a replacer method called by `re.sub` with the matched
|
||||
tag. It must return the correct ansi sequence.
|
||||
|
|
@ -102,7 +102,7 @@ class ANSIParser(object):
|
|||
else:
|
||||
red, green, blue = int(rgbtag[0]), int(rgbtag[1]), int(rgbtag[2])
|
||||
|
||||
if self.do_xterm256:
|
||||
if convert:
|
||||
colval = 16 + (red * 36) + (green * 6) + blue
|
||||
#print "RGB colours:", red, green, blue
|
||||
return "\033[%s8;5;%s%s%sm" % (3 + int(background), colval/100, (colval % 100)/10, colval%10)
|
||||
|
|
@ -201,15 +201,16 @@ class ANSIParser(object):
|
|||
if cachekey in _PARSE_CACHE:
|
||||
return _PARSE_CACHE[cachekey]
|
||||
|
||||
self.do_xterm256 = xterm256
|
||||
self.do_mxp = mxp
|
||||
def do_xterm256(part):
|
||||
return self.sub_xterm256(part, xterm256)
|
||||
|
||||
in_string = utils.to_str(string)
|
||||
|
||||
# do string replacement
|
||||
parsed_string = ""
|
||||
parts = self.ansi_escapes.split(in_string) + [" "]
|
||||
for part, sep in zip(parts[::2], parts[1::2]):
|
||||
pstring = self.xterm256_sub.sub(self.sub_xterm256, part)
|
||||
pstring = self.xterm256_sub.sub(do_xterm256, part)
|
||||
pstring = self.ansi_sub.sub(self.sub_ansi, pstring)
|
||||
parsed_string += "%s%s" % (pstring, sep[0].strip())
|
||||
|
||||
|
|
@ -221,8 +222,7 @@ class ANSIParser(object):
|
|||
# inserted in string)
|
||||
return self.strip_raw_codes(parsed_string)
|
||||
|
||||
|
||||
# cache and crop old cache
|
||||
# cache and crop old cache
|
||||
_PARSE_CACHE[cachekey] = parsed_string
|
||||
if len(_PARSE_CACHE) > _PARSE_CACHE_SIZE:
|
||||
_PARSE_CACHE.popitem(last=False)
|
||||
|
|
@ -342,10 +342,6 @@ class ANSIParser(object):
|
|||
ansi_re = r"\033\[[0-9;]+m"
|
||||
ansi_regex = re.compile(ansi_re)
|
||||
|
||||
# merged regex for both ansi and mxp, for use by ansistring
|
||||
mxp_tags = r'\{lc.*?\{lt|\{le'
|
||||
tags_regex = re.compile("%s|%s" % (ansi_re, mxp_tags), re.DOTALL)
|
||||
|
||||
# escapes - these double-chars will be replaced with a single
|
||||
# instance of each
|
||||
ansi_escapes = re.compile(r"(%s)" % "|".join(ANSI_ESCAPES), re.DOTALL)
|
||||
|
|
@ -527,7 +523,7 @@ class ANSIString(unicode):
|
|||
decoded = True
|
||||
if not decoded:
|
||||
# Completely new ANSI String
|
||||
clean_string = to_unicode(parser.parse_ansi(string, strip_ansi=True))
|
||||
clean_string = to_unicode(parser.parse_ansi(string, strip_ansi=True, mxp=True))
|
||||
string = parser.parse_ansi(string, xterm256=True, mxp=True)
|
||||
elif clean_string is not None:
|
||||
# We have an explicit clean string.
|
||||
|
|
@ -781,8 +777,7 @@ class ANSIString(unicode):
|
|||
"""
|
||||
|
||||
code_indexes = []
|
||||
#for match in self.parser.ansi_regex.finditer(self._raw_string):
|
||||
for match in self.parser.tags_regex.finditer(self._raw_string):
|
||||
for match in self.parser.ansi_regex.finditer(self._raw_string):
|
||||
code_indexes.extend(range(match.start(), match.end()))
|
||||
if not code_indexes:
|
||||
# Plain string, no ANSI codes.
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ try:
|
|||
except ImportError:
|
||||
from django.test import TestCase
|
||||
|
||||
from ansi import ANSIString
|
||||
import utils
|
||||
from .ansi import ANSIString
|
||||
from evennia import utils
|
||||
|
||||
|
||||
class ANSIStringTestCase(TestCase):
|
||||
|
|
@ -121,6 +121,20 @@ class ANSIStringTestCase(TestCase):
|
|||
result = u'\x1b[1m\x1b[32mTest\x1b[0m'
|
||||
self.checker(target.capitalize(), result, u'Test')
|
||||
|
||||
def test_mxp_agnostic(self):
|
||||
"""
|
||||
Make sure MXP tags are not treated like ANSI codes, but normal text.
|
||||
"""
|
||||
mxp1 = "{lclook{ltat{le"
|
||||
mxp2 = "Start to {lclook here{ltclick somewhere here{le first"
|
||||
self.assertEqual(15, len(ANSIString(mxp1)))
|
||||
self.assertEqual(53, len(ANSIString(mxp2)))
|
||||
# These would indicate an issue with the tables.
|
||||
self.assertEqual(len(ANSIString(mxp1)), len(ANSIString(mxp1).split("\n")[0]))
|
||||
self.assertEqual(len(ANSIString(mxp2)), len(ANSIString(mxp2).split("\n")[0]))
|
||||
self.assertEqual(mxp1, ANSIString(mxp1))
|
||||
self.assertEqual(mxp2, unicode(ANSIString(mxp2)))
|
||||
|
||||
|
||||
class TestIsIter(TestCase):
|
||||
def test_is_iter(self):
|
||||
|
|
@ -177,3 +191,26 @@ class TestListToString(TestCase):
|
|||
self.assertEqual('1, 2 and 3', utils.list_to_string([1,2,3]))
|
||||
self.assertEqual('"1", "2" and "3"', utils.list_to_string([1,2,3], endsep="and", addquote=True))
|
||||
|
||||
|
||||
class TestMLen(TestCase):
|
||||
"""
|
||||
Verifies that m_len behaves like len in all situations except those
|
||||
where MXP may be involved.
|
||||
"""
|
||||
def test_non_mxp_string(self):
|
||||
self.assertEqual(utils.m_len('Test_string'), 11)
|
||||
|
||||
def test_mxp_string(self):
|
||||
self.assertEqual(utils.m_len('{lclook{ltat{le'), 2)
|
||||
|
||||
def test_mxp_ansi_string(self):
|
||||
self.assertEqual(utils.m_len(ANSIString('{lcl{gook{ltat{le{n')), 2)
|
||||
|
||||
def test_non_mxp_ansi_string(self):
|
||||
self.assertEqual(utils.m_len(ANSIString('{gHello{n')), 5)
|
||||
|
||||
def test_list(self):
|
||||
self.assertEqual(utils.m_len([None, None]), 2)
|
||||
|
||||
def test_dict(self):
|
||||
self.assertEqual(utils.m_len({'hello': True, 'Goodbye': False}), 2)
|
||||
|
|
|
|||
|
|
@ -1245,3 +1245,13 @@ def calledby(callerdepth=1):
|
|||
return "[called by '%s': %s:%s %s]" % (frame[3], path, frame[2], frame[4])
|
||||
|
||||
|
||||
def m_len(target):
|
||||
"""
|
||||
Provides length checking for strings with MXP patterns, and falls
|
||||
back to normal len for other objects.
|
||||
"""
|
||||
# Would create circular import if in module root.
|
||||
from evennia.utils.ansi import ANSI_PARSER
|
||||
if inherits_from(target, basestring):
|
||||
return len(ANSI_PARSER.strip_mxp(target))
|
||||
return len(target)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue