Cleaned up the ansi.py module and made it better match the the style rest of the code.

This commit is contained in:
Griatch 2010-09-05 20:59:32 +00:00
parent e125763ea5
commit 7e736d19e2
5 changed files with 91 additions and 93 deletions

View file

@ -84,6 +84,7 @@ def instantiate(cmd):
return cmd() return cmd()
return cmd return cmd
class CmdSet(object): class CmdSet(object):
""" """
This class describes a unique cmdset that understands priorities. CmdSets This class describes a unique cmdset that understands priorities. CmdSets

View file

@ -150,9 +150,3 @@ class HelpEntry(SharedMemoryModel):
def __unicode__(self): def __unicode__(self):
return u'%s' % self.key return u'%s' % self.key
def get_entrytext_ingame(self):
"""
Gets the entry text for in-game viewing.
"""
return ansi.parse_ansi(self.entrytext)

View file

@ -48,7 +48,6 @@ from src.server import sessionhandler
from src.players import manager from src.players import manager
from src.typeclasses.models import Attribute, TypedObject from src.typeclasses.models import Attribute, TypedObject
from src.permissions import permissions from src.permissions import permissions
from src.utils.ansi import parse_ansi
from src.utils import logger from src.utils import logger
#------------------------------------------------------------ #------------------------------------------------------------
@ -248,12 +247,11 @@ class PlayerDB(TypedObject):
"Delete permission from old ones" "Delete permission from old ones"
return permissions.del_perm(self, perm) return permissions.del_perm(self, perm)
# #
# PlayerDB class access methods # PlayerDB class access methods
# #
def msg(self, message, from_obj=None): def msg(self, message, from_obj=None, markup=True):
""" """
This duplicates the same-named method on the Character. This duplicates the same-named method on the Character.
It forwards messages to the character or uses It forwards messages to the character or uses
@ -268,8 +266,9 @@ class PlayerDB(TypedObject):
except Exception: except Exception:
pass pass
if self.at_msg_receive(message, from_obj): if self.at_msg_receive(message, from_obj):
for session in self.sessions: for session in object.__getattribute__(self, 'sessions'):
session.msg(parse_ansi(message)) session.msg(message, markup)
def emit_to(self, message, from_obj=None): def emit_to(self, message, from_obj=None):
""" """
Deprecated. Use msg instead. Deprecated. Use msg instead.

View file

@ -125,11 +125,7 @@ class SessionProtocol(StatefulTelnetProtocol):
except Exception, e: except Exception, e:
self.sendLine(str(e)) self.sendLine(str(e))
return return
if markup: self.sendLine(ansi.parse_ansi(message, strip_ansi=not markup))
message = ansi.parse_ansi(message)
else:
message = ansi.clean_ansi(message)
self.sendLine(message)
def get_character(self): def get_character(self):
""" """

View file

@ -1,11 +1,25 @@
""" """
ANSI - gives colour to text. ANSI - Gives colour to text.
Use the codes defined in ANSIPARSER in your text
to apply colour to text according to the ANSI standard.
Examples:
This is %crRed text%cn and this is normal again.
This is {rRed text{n and this is normal again.
Mostly you should not need to call parse_ansi() explicitly;
it is run by Evennia just before returning data to/from the
user.
""" """
import re import re
class ANSITable(object): class ANSITable(object):
""" """
A table of ANSI characters to use when replacing things. A table defining the
standard ANSI command sequences.
""" """
ansi = {} ansi = {}
ansi["beep"] = "\07" ansi["beep"] = "\07"
@ -46,41 +60,19 @@ class ANSITable(object):
ansi["tab"] = "\t" ansi["tab"] = "\t"
ansi["space"] = " " ansi["space"] = " "
class BaseParser(object):
def parse_ansi(self, string, strip_ansi=False, strip_formatting=False): class ANSIParser(object):
""" """
Parses a string, subbing color codes as needed. A class that parses ansi markup
to ANSI command sequences
""" """
if string == None or string == '':
return ''
# Convert to string to prevent problems with lists, ints, and other types.
string = str(string)
# if strip_formatting:
# char_return = ""
# char_tab = ""
# char_space = ""
# else:
# char_return = ANSITable.ansi["return"]
# char_tab = ANSITable.ansi["tab"]
# char_space = ANSITable.ansi["space"]
for sub in self.ansi_subs:
p = re.compile(sub[0], re.DOTALL)
if strip_ansi:
string = p.sub("", string)
else:
string = p.sub(sub[1], string)
if strip_ansi:
return '%s' % (string)
else:
return '%s%s' % (string, ANSITable.ansi["normal"])
class MuxANSIParser(BaseParser):
def __init__(self): def __init__(self):
self.ansi_subs = [ "Sets the mappings"
# MUX-style mappings %cr %cn etc
mux_ansi_map = [
(r'%r', ANSITable.ansi["return"]), (r'%r', ANSITable.ansi["return"]),
(r'%t', ANSITable.ansi["tab"]), (r'%t', ANSITable.ansi["tab"]),
(r'%b', ANSITable.ansi["space"]), (r'%b', ANSITable.ansi["space"]),
@ -106,16 +98,11 @@ class MuxANSIParser(BaseParser):
(r'%cW', ANSITable.ansi["back_white"]), (r'%cW', ANSITable.ansi["back_white"]),
] ]
class ExtendedANSIParser(MuxANSIParser): # Expanded mapping {r {n etc
"""
Extends the standard mux colour commands with {-style commands
(shortcuts for writing light/dark text without background)
"""
def __init__(self):
super(ExtendedANSIParser, self).__init__()
hilite = ANSITable.ansi['hilite'] hilite = ANSITable.ansi['hilite']
normal = ANSITable.ansi['normal'] normal = ANSITable.ansi['normal']
self.ansi_subs.extend( [ ext_ansi_map = [
(r'{r', hilite + ANSITable.ansi['red']), (r'{r', hilite + ANSITable.ansi['red']),
(r'{R', normal + ANSITable.ansi['red']), (r'{R', normal + ANSITable.ansi['red']),
(r'{g', hilite + ANSITable.ansi['green']), (r'{g', hilite + ANSITable.ansi['green']),
@ -133,23 +120,44 @@ class ExtendedANSIParser(MuxANSIParser):
(r'{x', hilite + ANSITable.ansi['black']), #dark grey (r'{x', hilite + ANSITable.ansi['black']), #dark grey
(r'{X', normal + ANSITable.ansi['black']), #pure black (r'{X', normal + ANSITable.ansi['black']), #pure black
(r'{n', normal) #reset (r'{n', normal) #reset
] ) ]
#ANSI_PARSER = MuxANSIParser() self.ansi_map = mux_ansi_map + ext_ansi_map
ANSI_PARSER = ExtendedANSIParser()
def parse_ansi(string, strip_ansi=False, strip_formatting=False, parser=ANSI_PARSER): # prepare regex matching
self.ansi_sub = [(re.compile(sub[0], re.DOTALL), sub[1])
for sub in self.ansi_map]
# prepare matching ansi codes overall
self.ansi_regex = re.compile("\033\[[0-9;]+m")
def parse_ansi(self, string, strip_ansi=False):
"""
Parses a string, subbing color codes according to
the stored mapping.
strip_ansi flag instead removes all ansi markup.
"""
if not string:
return ''
string = str(string)
for sub in self.ansi_sub:
# go through all available mappings and translate them
string = sub[0].sub(sub[1], string)
if strip_ansi:
# remove all ANSI escape codes
string = self.ansi_regex.sub("", string)
return string
ANSI_PARSER = ANSIParser()
#
# Access function
#
def parse_ansi(string, strip_ansi=False, parser=ANSI_PARSER):
""" """
Parses a string, subbing color codes as needed. Parses a string, subbing color codes as needed.
""" """
return parser.parse_ansi(string, strip_ansi=strip_ansi, return parser.parse_ansi(string, strip_ansi=strip_ansi)
strip_formatting=strip_formatting)
def clean_ansi(string):
"""
Cleans all ansi symbols from a string
"""
# convert all to their ansi counterpart
string = parse_ansi(string)
# next, strip it all away
regex = re.compile("\033\[[0-9;]+m")
return regex.sub("", string) #replace all matches with empty strings