Modularizing ANSI parsing. This may break stuff. It's not quite where I want it just yet.

This commit is contained in:
Greg Taylor 2009-04-13 22:44:44 +00:00
parent d4f80a526e
commit 36e23bfd4a
6 changed files with 137 additions and 119 deletions

View file

@ -1,100 +1,117 @@
import re
"""
ANSI related stuff.
"""
ansi = {}
ansi["beep"] = "\07"
ansi["escape"] = "\033"
ansi["normal"] = "\033[0m"
import re
ansi["underline"] = "\033[4m"
ansi["hilite"] = "\033[1m"
ansi["blink"] = "\033[5m"
ansi["inverse"] = "\033[7m"
ansi["inv_hilite"] = "\033[1;7m"
ansi["inv_blink"] = "\033[7;5m"
ansi["blink_hilite"] = "\033[1;5m"
ansi["inv_blink_hilite"] = "\033[1;5;7m"
class ANSITable(object):
"""
A table of ANSI characters to use when replacing things.
"""
ansi = {}
ansi["beep"] = "\07"
ansi["escape"] = "\033"
ansi["normal"] = "\033[0m"
ansi["underline"] = "\033[4m"
ansi["hilite"] = "\033[1m"
ansi["blink"] = "\033[5m"
ansi["inverse"] = "\033[7m"
ansi["inv_hilite"] = "\033[1;7m"
ansi["inv_blink"] = "\033[7;5m"
ansi["blink_hilite"] = "\033[1;5m"
ansi["inv_blink_hilite"] = "\033[1;5;7m"
# Foreground colors
ansi["black"] = "\033[30m"
ansi["red"] = "\033[31m"
ansi["green"] = "\033[32m"
ansi["yellow"] = "\033[33m"
ansi["blue"] = "\033[34m"
ansi["magenta"] = "\033[35m"
ansi["cyan"] = "\033[36m"
ansi["white"] = "\033[37m"
# Background colors
ansi["back_black"] = "\033[40m"
ansi["back_red"] = "\033[41m"
ansi["back_green"] = "\033[42m"
ansi["back_yellow"] = "\033[43m"
ansi["back_blue"] = "\033[44m"
ansi["back_magenta"] = "\033[45m"
ansi["back_cyan"] = "\033[46m"
ansi["back_white"] = "\033[47m"
# Formatting Characters
ansi["return"] = "\r\n"
ansi["tab"] = "\t"
ansi["space"] = " "
class BaseParser(object):
def parse_ansi(self, string, strip_ansi=False, strip_formatting=False):
"""
Parses a string, subbing color codes as needed.
"""
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"])
# Foreground colors
ansi["black"] = "\033[30m"
ansi["red"] = "\033[31m"
ansi["green"] = "\033[32m"
ansi["yellow"] = "\033[33m"
ansi["blue"] = "\033[34m"
ansi["magenta"] = "\033[35m"
ansi["cyan"] = "\033[36m"
ansi["white"] = "\033[37m"
# Background colors
ansi["back_black"] = "\033[40m"
ansi["back_red"] = "\033[41m"
ansi["back_green"] = "\033[42m"
ansi["back_yellow"] = "\033[43m"
ansi["back_blue"] = "\033[44m"
ansi["back_magenta"] = "\033[45m"
ansi["back_cyan"] = "\033[46m"
ansi["back_white"] = "\033[47m"
# Formatting Characters
ansi["return"] = "\r\n"
ansi["tab"] = "\t"
ansi["space"] = " "
def parse_ansi(string, strip_ansi=False, strip_formatting=False):
class MuxANSIParser(BaseParser):
def __init__(self):
self.ansi_subs = [
(r'%r', ANSITable.ansi["return"]),
(r'%t', ANSITable.ansi["tab"]),
(r'%b', ANSITable.ansi["space"]),
(r'%cf', ANSITable.ansi["blink"]),
(r'%ci', ANSITable.ansi["inverse"]),
(r'%ch', ANSITable.ansi["hilite"]),
(r'%cn', ANSITable.ansi["normal"]),
(r'%cx', ANSITable.ansi["black"]),
(r'%cX', ANSITable.ansi["back_black"]),
(r'%cr', ANSITable.ansi["red"]),
(r'%cR', ANSITable.ansi["back_red"]),
(r'%cg', ANSITable.ansi["green"]),
(r'%cG', ANSITable.ansi["back_green"]),
(r'%cy', ANSITable.ansi["yellow"]),
(r'%cY', ANSITable.ansi["back_yellow"]),
(r'%cb', ANSITable.ansi["blue"]),
(r'%cB', ANSITable.ansi["back_blue"]),
(r'%cm', ANSITable.ansi["magenta"]),
(r'%cM', ANSITable.ansi["back_magenta"]),
(r'%cc', ANSITable.ansi["cyan"]),
(r'%cC', ANSITable.ansi["back_cyan"]),
(r'%cw', ANSITable.ansi["white"]),
(r'%cW', ANSITable.ansi["back_white"]),
]
ANSI_PARSER = MuxANSIParser()
def parse_ansi(string, strip_ansi=False, strip_formatting=False, parser=ANSI_PARSER):
"""
Parses a string, subbing color codes as needed.
"""
if string == None or string == '':
return ''
return parser.parse_ansi(string, strip_ansi=strip_ansi,
strip_formatting=strip_formatting)
# 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 = ansi["return"]
char_tab = ansi["tab"]
char_space = ansi["space"]
ansi_subs = [
(r'%r', char_return),
(r'%t', char_tab),
(r'%b', char_space),
(r'%cf', ansi["blink"]),
(r'%ci', ansi["inverse"]),
(r'%ch', ansi["hilite"]),
(r'%cn', ansi["normal"]),
(r'%cx', ansi["black"]),
(r'%cX', ansi["back_black"]),
(r'%cr', ansi["red"]),
(r'%cR', ansi["back_red"]),
(r'%cg', ansi["green"]),
(r'%cG', ansi["back_green"]),
(r'%cy', ansi["yellow"]),
(r'%cY', ansi["back_yellow"]),
(r'%cb', ansi["blue"]),
(r'%cB', ansi["back_blue"]),
(r'%cm', ansi["magenta"]),
(r'%cM', ansi["back_magenta"]),
(r'%cc', ansi["cyan"]),
(r'%cC', ansi["back_cyan"]),
(r'%cw', ansi["white"]),
(r'%cW', ansi["back_white"]),
]
for sub in 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, ansi["normal"])
print parse_ansi('yay%chyay')

View file

@ -16,7 +16,6 @@ add_command on the command table each command belongs to.
"""
from src.helpsys.management.commands.edit_helpfiles import add_help
from src.ansi import ansi
class CommandTable(object):
"""

View file

@ -7,12 +7,12 @@ from django.conf import settings
from src.config.models import ConfigValue
from src.helpsys.models import HelpEntry
from src.objects.models import Object
from src.ansi import ANSITable
from src import defines_global
from src import session_mgr
from src import ansi
from src.util import functions_general
import src.helpsys.management.commands.edit_helpfiles as edit_help
from src.cmdtable import GLOBAL_CMD_TABLE
def cmd_password(command):
@ -306,8 +306,8 @@ def cmd_examine(command):
# Render Contents display.
if con_players or con_things:
s += str("%sContents:%s" % (ansi.ansi["hilite"],
ansi.ansi["normal"])) + newl
s += str("%sContents:%s" % (ANSITable.ansi["hilite"],
ANSITable.ansi["normal"])) + newl
for player in con_players:
s += str(' %s' % player.get_name(fullname=True)) + newl
for thing in con_things:
@ -315,8 +315,8 @@ def cmd_examine(command):
# Render Exists display.
if con_exits:
s += str("%sExits:%s" % (ansi.ansi["hilite"],
ansi.ansi["normal"])) + newl
s += str("%sExits:%s" % (ANSITable.ansi["hilite"],
ANSITable.ansi["normal"])) + newl
for exit in con_exits:
s += str(' %s' % exit.get_name(fullname=True)) + newl

View file

@ -5,9 +5,8 @@ well as creating auto-docs of commands based on their doc strings.
The system supports help-markup for multiple help entries as well
as a dynamically updating help index.
"""
from src.helpsys.models import HelpEntry
from src.ansi import ansi
from src.ansi import ANSITable
#
# Helper functions
@ -120,7 +119,7 @@ def _format_footer(top, text, topic_dict, staff_dict):
other_topics = other_topics = filter(lambda o: o != top and not staff_dict[o],
topic_dict.keys())
if other_topics:
footer = ansi['normal'] + "\n\r Related Topics: "
footer = ANSITable.ansi['normal'] + "\n\r Related Topics: "
for t in other_topics:
footer += t + ', '
footer = footer[:-2] + '.'

View file

@ -11,9 +11,9 @@ from src.objects.managers.commchannel import CommChannelManager
from src.objects.managers.object import ObjectManager
from src.objects.managers.attribute import AttributeManager
from src.config.models import ConfigValue
from src.ansi import ANSITable, parse_ansi
from src import scripthandler
from src import defines_global
from src import ansi
from src import session_mgr
from src import logger
# Import as the absolute path to avoid local variable clashes.
@ -83,9 +83,9 @@ class Attribute(models.Model):
Best described as a __str__ method for in-game. Renders the attribute's
name and value as per MUX.
"""
return "%s%s%s: %s" % (ansi.ansi["hilite"],
return "%s%s%s: %s" % (ANSITable.ansi["hilite"],
self.get_name(),
ansi.ansi["normal"],
ANSITable.ansi["normal"],
self.get_value())
class AttributeAdmin(admin.ModelAdmin):
@ -195,7 +195,7 @@ class Object(models.Model):
sessions = self.get_sessions()
for session in sessions:
session.msg(ansi.parse_ansi(message))
session.msg(parse_ansi(message))
def execute_cmd(self, command_str, session=None):
"""
@ -364,8 +364,8 @@ class Object(models.Model):
"""
Rename an object.
"""
self.name = ansi.parse_ansi(new_name, strip_ansi=True)
self.ansi_name = ansi.parse_ansi(new_name, strip_formatting=True)
self.name = parse_ansi(new_name, strip_ansi=True)
self.ansi_name = parse_ansi(new_name, strip_formatting=True)
self.save()
# If it's a player, we need to update their user object as well.
@ -396,10 +396,10 @@ class Object(models.Model):
dbref_string = ""
if fullname:
return "%s%s" % (ansi.parse_ansi(name_string, strip_ansi=no_ansi),
return "%s%s" % (parse_ansi(name_string, strip_ansi=no_ansi),
dbref_string)
else:
return "%s%s" % (ansi.parse_ansi(name_string.split(';')[0],
return "%s%s" % (parse_ansi(name_string.split(';')[0],
strip_ansi=no_ansi), dbref_string)
def set_description(self, new_desc):
@ -425,7 +425,7 @@ class Object(models.Model):
if no_parsing:
retval = self.description
else:
retval = ansi.parse_ansi(self.description)
retval = parse_ansi(self.description)
# Default to a 78 character wrap.
if wrap_text:
@ -1018,7 +1018,7 @@ class CommChannel(models.Model):
Returns the channel's header text, or what is shown before each channel
message.
"""
return ansi.parse_ansi(self.ansi_name)
return parse_ansi(self.ansi_name)
def get_owner(self):
"""
@ -1030,15 +1030,15 @@ class CommChannel(models.Model):
"""
Rename a channel
"""
self.name = ansi.parse_ansi(new_name, strip_ansi=True)
self.header = "[%s]" % (ansi.parse_ansi(new_name),)
self.name = parse_ansi(new_name, strip_ansi=True)
self.header = "[%s]" % (parse_ansi(new_name),)
self.save()
def set_header(self, new_header):
"""
Sets a channel's header text.
"""
self.header = ansi.parse_ansi(new_header)
self.header = parse_ansi(new_header)
self.save()
def set_owner(self, new_owner):

View file

@ -7,7 +7,7 @@ NOTE: This file should NOT be directly modified. Sub-class the BasicObject
class in game/gamesrc/parents/base/basicobject.py and change the
SCRIPT_DEFAULT_OBJECT variable in settings.py to point to the new class.
"""
from src import ansi
from src.ansi import ANSITable
class EvenniaBasicObject(object):
def __init__(self, scripted_obj, *args, **kwargs):
@ -103,15 +103,18 @@ class EvenniaBasicObject(object):
con_things.append(obj)
if not con_players == []:
retval += "\n\r%sPlayers:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],)
retval += "\n\r%sPlayers:%s" % (ANSITable.ansi["hilite"],
ANSITable.ansi["normal"])
for player in con_players:
retval +='\n\r%s' %(player.get_name(show_dbref=show_dbrefs),)
retval +='\n\r%s' % (player.get_name(show_dbref=show_dbrefs),)
if not con_things == []:
retval += "\n\r%sContents:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],)
retval += "\n\r%sContents:%s" % (ANSITable.ansi["hilite"],
ANSITable.ansi["normal"])
for thing in con_things:
retval += '\n\r%s' %(thing.get_name(show_dbref=show_dbrefs),)
retval += '\n\r%s' % (thing.get_name(show_dbref=show_dbrefs),)
if not con_exits == []:
retval += "\n\r%sExits:%s" % (ansi.ansi["hilite"], ansi.ansi["normal"],)
retval += "\n\r%sExits:%s" % (ANSITable.ansi["hilite"],
ANSITable.ansi["normal"])
for exit in con_exits:
retval += '\n\r%s' %(exit.get_name(show_dbref=show_dbrefs),)