mirror of
https://github.com/evennia/evennia.git
synced 2026-04-03 22:47:16 +02:00
Implement ANSIString.strip() .lstrip() and .rstrip() as tag-aware methods. This handles the last prblem with #1117.
This commit is contained in:
parent
596bfff35a
commit
f00fbb9d88
3 changed files with 118 additions and 24 deletions
|
|
@ -977,6 +977,29 @@ class ANSIString(with_metaclass(ANSIMeta, unicode)):
|
|||
break
|
||||
return s
|
||||
|
||||
def __mul__(self, other):
|
||||
"""
|
||||
Multiplication method. Implemented for performance reasons.
|
||||
|
||||
"""
|
||||
if not isinstance(other, int):
|
||||
return NotImplemented
|
||||
raw_string = self._raw_string * other
|
||||
clean_string = self._clean_string * other
|
||||
code_indexes = self._code_indexes[:]
|
||||
char_indexes = self._char_indexes[:]
|
||||
for i in range(1, other + 1):
|
||||
code_indexes.extend(
|
||||
self._shifter(self._code_indexes, i * len(self._raw_string)))
|
||||
char_indexes.extend(
|
||||
self._shifter(self._char_indexes, i * len(self._raw_string)))
|
||||
return ANSIString(
|
||||
raw_string, code_indexes=code_indexes, char_indexes=char_indexes,
|
||||
clean_string=clean_string)
|
||||
|
||||
def __rmul__(self, other):
|
||||
return self.__mul__(other)
|
||||
|
||||
def split(self, by=None, maxsplit=-1):
|
||||
"""
|
||||
Stolen from PyPy's pure Python string implementation, tweaked for
|
||||
|
|
@ -1010,29 +1033,6 @@ class ANSIString(with_metaclass(ANSIMeta, unicode)):
|
|||
return [part for part in res if part != ""]
|
||||
return res
|
||||
|
||||
def __mul__(self, other):
|
||||
"""
|
||||
Multiplication method. Implemented for performance reasons.
|
||||
|
||||
"""
|
||||
if not isinstance(other, int):
|
||||
return NotImplemented
|
||||
raw_string = self._raw_string * other
|
||||
clean_string = self._clean_string * other
|
||||
code_indexes = self._code_indexes[:]
|
||||
char_indexes = self._char_indexes[:]
|
||||
for i in range(1, other + 1):
|
||||
code_indexes.extend(
|
||||
self._shifter(self._code_indexes, i * len(self._raw_string)))
|
||||
char_indexes.extend(
|
||||
self._shifter(self._char_indexes, i * len(self._raw_string)))
|
||||
return ANSIString(
|
||||
raw_string, code_indexes=code_indexes, char_indexes=char_indexes,
|
||||
clean_string=clean_string)
|
||||
|
||||
def __rmul__(self, other):
|
||||
return self.__mul__(other)
|
||||
|
||||
def rsplit(self, by=None, maxsplit=-1):
|
||||
"""
|
||||
Stolen from PyPy's pure Python string implementation, tweaked for
|
||||
|
|
@ -1066,6 +1066,88 @@ class ANSIString(with_metaclass(ANSIMeta, unicode)):
|
|||
return [part for part in res if part != ""]
|
||||
return res
|
||||
|
||||
def strip(self, chars=None):
|
||||
"""
|
||||
Strip from both ends, taking ANSI markers into account.
|
||||
"""
|
||||
clean = self._clean_string
|
||||
raw = self._raw_string
|
||||
|
||||
# count continuous sequence of chars from left and right
|
||||
nlen = len(clean)
|
||||
nlstripped = nlen - len(clean.lstrip(chars))
|
||||
nrstripped = nlen - len(clean.rstrip(chars))
|
||||
|
||||
# within the stripped regions, only retain parts of the raw
|
||||
# string *not* matching the clean string (these are ansi/mxp tags)
|
||||
lstripped = ""
|
||||
ic, ir1 = 0, 0
|
||||
while nlstripped:
|
||||
if ic >= nlstripped:
|
||||
break
|
||||
elif raw[ir1] != clean[ic]:
|
||||
lstripped += raw[ir1]
|
||||
else:
|
||||
ic += 1
|
||||
ir1 += 1
|
||||
rstripped = ""
|
||||
ic, ir2 = nlen-1, len(raw)-1
|
||||
while nrstripped:
|
||||
if nlen - ic > nrstripped:
|
||||
break
|
||||
elif raw[ir2] != clean[ic]:
|
||||
rstripped += raw[ir2]
|
||||
else:
|
||||
ic -= 1
|
||||
ir2 -= 1
|
||||
rstripped = rstripped[::-1]
|
||||
return ANSIString(lstripped + raw[ir1:ir2+1] + rstripped)
|
||||
|
||||
|
||||
def lstrip(self, chars=None):
|
||||
"""
|
||||
Strip from the left, taking ANSI markers into account.
|
||||
"""
|
||||
clean = self._clean_string
|
||||
raw = self._raw_string
|
||||
|
||||
# count continuous sequence of chars from left and right
|
||||
nlen = len(clean)
|
||||
nlstripped = nlen - len(clean.lstrip(chars))
|
||||
# within the stripped regions, only retain parts of the raw
|
||||
# string *not* matching the clean string (these are ansi/mxp tags)
|
||||
lstripped = ""
|
||||
ic, ir1 = 0, 0
|
||||
while nlstripped:
|
||||
if ic >= nlstripped:
|
||||
break
|
||||
elif raw[ir1] != clean[ic]:
|
||||
lstripped += raw[ir1]
|
||||
else:
|
||||
ic += 1
|
||||
ir1 += 1
|
||||
return ANSIString(lstripped + raw[ir1:])
|
||||
|
||||
def rstrip(self, chars=None):
|
||||
"""
|
||||
Strip from the right, taking ANSI markers into account.
|
||||
"""
|
||||
clean = self._clean_string
|
||||
raw = self._raw_string
|
||||
nlen = len(clean)
|
||||
nrstripped = nlen - len(clean.rstrip(chars))
|
||||
rstripped = ""
|
||||
ic, ir2 = nlen-1, len(raw)-1
|
||||
while nrstripped:
|
||||
if nlen - ic > nrstripped:
|
||||
break
|
||||
elif raw[ir2] != clean[ic]:
|
||||
rstripped += raw[ir2]
|
||||
else:
|
||||
ic -= 1
|
||||
ir2 -= 1
|
||||
return ANSIString(raw[:ir2+1] + rstripped)
|
||||
|
||||
def join(self, iterable):
|
||||
"""
|
||||
Joins together strings in an iterable.
|
||||
|
|
|
|||
|
|
@ -576,7 +576,8 @@ class EvCell(object):
|
|||
hfill_char = self.hfill_char
|
||||
width = self.width
|
||||
if align == "l":
|
||||
return [(line.lstrip(" ") + " " if line.startswith(" ") and not line.startswith(" ") else line) + hfill_char * (width - m_len(line)) for line in data]
|
||||
lines= [(line.lstrip(" ") + " " if line.startswith(" ") and not line.startswith(" ") else line) + hfill_char * (width - m_len(line)) for line in data]
|
||||
return lines
|
||||
elif align == "r":
|
||||
return [hfill_char * (width - m_len(line)) + (" " + line.rstrip(" ") if line.endswith(" ") and not line.endswith(" ") else line) for line in data]
|
||||
else: # center, 'c'
|
||||
|
|
|
|||
|
|
@ -152,6 +152,17 @@ class ANSIStringTestCase(TestCase):
|
|||
]
|
||||
self.table_check(c, char_table, code_table)
|
||||
|
||||
def test_strip(self):
|
||||
"""
|
||||
Test the ansi-aware .strip() methods
|
||||
"""
|
||||
a = ANSIString(" |r Test of stuff |b with spaces |n ")
|
||||
b = ANSIString("|r|b")
|
||||
self.assertEqual(a.strip(), ANSIString("|rTest of stuff |b with spaces|n"))
|
||||
self.assertEqual(a.lstrip(), ANSIString("|rTest of stuff |b with spaces |n "))
|
||||
self.assertEqual(a.rstrip(), ANSIString(" |r Test of stuff |b with spaces|n"))
|
||||
self.assertEqual(b.strip(), b)
|
||||
|
||||
|
||||
class TestIsIter(TestCase):
|
||||
def test_is_iter(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue