From 36e23bfd4a42ab2e7d0d1f4e413ad30043571229 Mon Sep 17 00:00:00 2001 From: Greg Taylor Date: Mon, 13 Apr 2009 22:44:44 +0000 Subject: [PATCH] Modularizing ANSI parsing. This may break stuff. It's not quite where I want it just yet. --- src/ansi.py | 199 ++++++++++-------- src/cmdtable.py | 1 - src/commands/general.py | 10 +- .../management/commands/edit_helpfiles.py | 5 +- src/objects/models.py | 26 +-- src/script_parents/basicobject.py | 15 +- 6 files changed, 137 insertions(+), 119 deletions(-) diff --git a/src/ansi.py b/src/ansi.py index 62a6efbc33..6f6942aa45 100755 --- a/src/ansi.py +++ b/src/ansi.py @@ -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') \ No newline at end of file diff --git a/src/cmdtable.py b/src/cmdtable.py index 8352394f8b..bb1e69f8cc 100644 --- a/src/cmdtable.py +++ b/src/cmdtable.py @@ -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): """ diff --git a/src/commands/general.py b/src/commands/general.py index 6bfa9e510d..16491490dc 100644 --- a/src/commands/general.py +++ b/src/commands/general.py @@ -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 diff --git a/src/helpsys/management/commands/edit_helpfiles.py b/src/helpsys/management/commands/edit_helpfiles.py index cdd5b6dec4..435c4fe1c5 100644 --- a/src/helpsys/management/commands/edit_helpfiles.py +++ b/src/helpsys/management/commands/edit_helpfiles.py @@ -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] + '.' diff --git a/src/objects/models.py b/src/objects/models.py index 13948cc5bb..5ae5d5ff78 100755 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -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): diff --git a/src/script_parents/basicobject.py b/src/script_parents/basicobject.py index df2ebd9029..5ad3d8ae10 100644 --- a/src/script_parents/basicobject.py +++ b/src/script_parents/basicobject.py @@ -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),)