diff --git a/dataobjs.py b/dataobjs.py index 1d8ac79..b3e22d4 100644 --- a/dataobjs.py +++ b/dataobjs.py @@ -4,7 +4,7 @@ import re import random from generic import PesterIcon -from parsetools import timeDifference, convertTags, lexMessage +from parsetools import timeDifference, convertTags, lexMessage, parseRegexpFunctions from mispeller import mispeller _groupre = re.compile(r"\\([0-9]+)") @@ -62,23 +62,9 @@ class pesterQuirk(object): return string if not last and len(fr) > 0 and fr[len(fr)-1] == "$": return string - def regexprep(mo): - to = self.quirk["to"] - to = _groupre.sub(r"\\g<\1>", to) - def upperrep(m): - return mo.expand(m.group(1)).upper() - def lowerrep(m): - return mo.expand(m.group(1)).lower() - def scramblerep(m): - return "".join(random.sample(mo.expand(m.group(1)), len(mo.expand(m.group(1))))) - def reverserep(m): - return mo.expand(m.group(1))[::-1] - to = _upperre.sub(upperrep, to) - to = _lowerre.sub(lowerrep, to) - to = _scramblere.sub(scramblerep, to) - to = _reversere.sub(reverserep, to) - return mo.expand(to) - return re.sub(fr, regexprep, string) + to = self.quirk["to"] + pt = parseRegexpFunctions(to) + return re.sub(fr, pt.expand, string) elif self.type == "random": if len(self.quirk["randomlist"]) == 0: return string @@ -89,16 +75,8 @@ class pesterQuirk(object): return string def randomrep(mo): choice = random.choice(self.quirk["randomlist"]) - def upperrep(m): - return mo.expand(m.group(1)).upper() - def lowerrep(m): - return mo.expand(m.group(1)).lower() - def scramblerep(m): - return "".join(random.sample(mo.expand(m.group(1)), len(mo.expand(m.group(1))))) - choice = _upperre.sub(upperrep, choice) - choice = _lowerre.sub(lowerrep, choice) - choice = _upperre.sub(upperrep, choice) - return mo.expand(choice) + pt = parseRegexpFunctions(choice) + return pt.expand(mo) return re.sub(self.quirk["from"], randomrep, string) elif self.type == "spelling": percentage = self.quirk["percentage"]/100.0 diff --git a/irc.py b/irc.py index c0a9e08..b0087cc 100644 --- a/irc.py +++ b/irc.py @@ -93,10 +93,10 @@ class PesterIRC(QtCore.QThread): h = unicode(handle) textl = [unicode(text)] def splittext(l): - if len(l[0]) > 400: - space = l[0].rfind(" ", 0,400) + if len(l[0]) > 450: + space = l[0].rfind(" ", 0,450) if space == -1: - space = 400 + space = 450 a = l[0][0:space+1] b = l[0][space+1:] if len(b) > 0: diff --git a/parsetools.py b/parsetools.py index 2b2b2ce..8dfaec1 100644 --- a/parsetools.py +++ b/parsetools.py @@ -1,4 +1,5 @@ import re +import random from copy import copy from datetime import timedelta from PyQt4 import QtGui @@ -15,6 +16,9 @@ _handlere = re.compile(r"(\s|^)(@[A-Za-z0-9_]+)") _imgre = re.compile(r"""(?i)""") _mecmdre = re.compile(r"^(/me|PESTERCHUM:ME)(\S*)") +_functionre = re.compile(r"(upper\(|lower\(|scramble\(|reverse\(|\)|\\[0-9]+)") +_groupre = re.compile(r"\\([0-9]+)") + def lexer(string, objlist): """objlist is a list: [(objecttype, re),...] list is in order of preference""" stringlist = [string] @@ -205,15 +209,23 @@ def splitMessage(msg, format="ctag"): cbegintags = [] output = [] for o in msg: + oldctag = None okmsg.append(o) if type(o) is colorBegin: cbegintags.append(o) elif type(o) is colorEnd: - cbegintags.pop() + try: + oldctag = cbegintags.pop() + except IndexError: + pass # yeah normally i'd do binary search but im lazy msglen = len(convertTags(okmsg, format)) + 4*(len(cbegintags)) if msglen > 400: okmsg.pop() + if type(o) is colorBegin: + cbegintags.pop() + elif type(o) is colorEnd and oldctag is not None: + cbegintags.append(oldctag) if len(okmsg) == 0: output.append([o]) else: @@ -225,7 +237,10 @@ def splitMessage(msg, format="ctag"): if type(o) is colorBegin: cbegintags.append(o) elif type(o) is colorEnd: - cbegintags.pop() + try: + cbegintags.pop() + except IndexError: + pass tmp.append(o) okmsg = tmp @@ -285,6 +300,75 @@ def timeDifference(td): timetext = "%d HOURS %s" % (hours, when) return timetext +def upperrep(text): + return text.upper() +def lowerrep(text): + return text.lower() +def scramblerep(text): + return "".join(random.sample(text, len(text))) +def reverserep(text): + return text[::-1] +def nonerep(text): + return text + +class parseLeaf(object): + def __init__(self, function, parent): + self.nodes = [] + self.function = function + self.parent = parent + def append(self, node): + self.nodes.append(node) + def expand(self, mo): + print "starting expand" + out = "" + for n in self.nodes: + if type(n) == parseLeaf: + out += n.expand(mo) + elif type(n) == backreference: + out += mo.group(int(n.number)) + else: + out += n + print "out: %s" % (out) + out = self.function(out) + print "returning %s" % (out) + return out +class backreference(object): + def __init__(self, number): + self.number = number + def __str__(self): + return self.number + +def parseRegexpFunctions(to): + parsed = parseLeaf(nonerep, None) + current = parsed + curi = 0 + functiondict = {"upper(": upperrep, "lower(": lowerrep, + "scramble(": scramblerep, "reverse(": reverserep} + while curi < len(to): + tmp = to[curi:] + mo = _functionre.search(tmp) + if mo is not None: + if mo.start() > 0: + current.append(to[curi:curi+mo.start()]) + backr = _groupre.search(mo.group()) + if backr is not None: + current.append(backreference(backr.group(1))) + elif mo.group() in functiondict.keys(): + p = parseLeaf(functiondict[mo.group()], current) + current.append(p) + current = p + elif mo.group() == ")": + if current.parent is not None: + current = current.parent + else: + current.append(")") + curi = mo.end()+curi + else: + current.append(to[curi:]) + curi = len(to) + return parsed + + def img2smiley(string): string = unicode(string) def imagerep(mo):