diff --git a/Demo/tkinter/guido/redemo.py b/Demo/tkinter/guido/redemo.py new file mode 100644 index 00000000000..1502b9df5c7 --- /dev/null +++ b/Demo/tkinter/guido/redemo.py @@ -0,0 +1,183 @@ +"""Basic regular expression demostration facility (Perl style syntax). + +This displays a window with two type-in boxes. In the top box, you +enter a Perl style regular expression. In the bottom box, you enter a +string. The first match in the string of the regular expression is +highlighted with a yellow background (or red if the match is empty -- +then the character at the match is highlighted). The highlighting is +continuously updated. At the bottom are a number of checkboxes which +control the regular expression options used (see the re module for +descriptions). When there's no match, or when the regular expression +is syntactically incorrect, an error message is displayed. + +""" + +from Tkinter import * +import re + +class ReDemo: + + def __init__(self, master): + self.master = master + + self.promptdisplay = Label(self.master, anchor=W, + text="Enter a Perl-style regular expression:") + self.promptdisplay.pack(side=TOP, fill=X) + + self.regexdisplay = Entry(self.master) + self.regexdisplay.pack(fill=X) + self.regexdisplay.focus_set() + + self.addoptions() + + self.statusdisplay = Label(self.master, text="", anchor=W) + self.statusdisplay.pack(side=TOP, fill=X) + + self.labeldisplay = Label(self.master, anchor=W, + text="Enter a string to search:") + self.labeldisplay.pack(fill=X) + self.labeldisplay.pack(fill=X) + + self.showframe = Frame(master) + self.showframe.pack(fill=X, anchor=W) + + self.showvar = StringVar(master) + self.showvar.set("first") + + self.showfirstradio = Radiobutton(self.showframe, + text="Highlight first match", + variable=self.showvar, + value="first", + command=self.recompile) + self.showfirstradio.pack(side=LEFT) + + self.showallradio = Radiobutton(self.showframe, + text="Highlight all matches", + variable=self.showvar, + value="all", + command=self.recompile) + self.showallradio.pack(side=LEFT) + + self.stringdisplay = Text(self.master, width=60, height=4) + self.stringdisplay.pack(fill=BOTH, expand=1) + self.stringdisplay.tag_configure("hit", background="yellow") + + self.grouplabel = Label(self.master, text="Groups:", anchor=W) + self.grouplabel.pack(fill=X) + + self.grouplist = Listbox(self.master) + self.grouplist.pack(expand=1, fill=BOTH) + + self.regexdisplay.bind('', self.recompile) + self.stringdisplay.bind('', self.reevaluate) + + self.compiled = None + self.recompile() + + btags = self.regexdisplay.bindtags() + self.regexdisplay.bindtags(btags[1:] + btags[:1]) + + btags = self.stringdisplay.bindtags() + self.stringdisplay.bindtags(btags[1:] + btags[:1]) + + def addoptions(self): + self.frames = [] + self.boxes = [] + self.vars = [] + for name in ('IGNORECASE', + 'LOCALE', + 'MULTILINE', + 'DOTALL', + 'VERBOSE'): + if len(self.boxes) % 3 == 0: + frame = Frame(self.master) + frame.pack(fill=X) + self.frames.append(frame) + val = getattr(re, name) + var = IntVar() + box = Checkbutton(frame, + variable=var, text=name, + offvalue=0, onvalue=val, + command=self.recompile) + box.pack(side=LEFT) + self.boxes.append(box) + self.vars.append(var) + + def getflags(self): + flags = 0 + for var in self.vars: + flags = flags | var.get() + flags = flags + return flags + + def recompile(self, event=None): + try: + self.compiled = re.compile(self.regexdisplay.get(), + self.getflags()) + bg = self.promptdisplay['background'] + self.statusdisplay.config(text="", background=bg) + except re.error, msg: + self.compiled = None + self.statusdisplay.config( + text="re.error: %s" % str(msg), + background="red") + self.reevaluate() + + def reevaluate(self, event=None): + try: + self.stringdisplay.tag_remove("hit", "1.0", END) + except TclError: + pass + try: + self.stringdisplay.tag_remove("hit0", "1.0", END) + except TclError: + pass + self.grouplist.delete(0, END) + if not self.compiled: + return + self.stringdisplay.tag_configure("hit", background="yellow") + self.stringdisplay.tag_configure("hit0", background="orange") + text = self.stringdisplay.get("1.0", END) + last = 0 + nmatches = 0 + while last <= len(text): + m = self.compiled.search(text, last) + if m is None: + break + first, last = m.span() + if last == first: + last = first+1 + tag = "hit0" + else: + tag = "hit" + pfirst = "1.0 + %d chars" % first + plast = "1.0 + %d chars" % last + self.stringdisplay.tag_add(tag, pfirst, plast) + if nmatches == 0: + self.stringdisplay.yview_pickplace(pfirst) + groups = list(m.groups()) + groups.insert(0, m.group()) + for i in range(len(groups)): + g = "%2d: %s" % (i, `groups[i]`) + self.grouplist.insert(END, g) + nmatches = nmatches + 1 + if self.showvar.get() == "first": + break + + if nmatches == 0: + self.statusdisplay.config(text="(no match)", + background="yellow") + else: + self.statusdisplay.config(text="") + + +# Main function, run when invoked as a stand-alone Python program. + +def main(): + root = Tk() + demo = ReDemo(root) + root.protocol('WM_DELETE_WINDOW', root.quit) + root.mainloop() + +if __name__ == '__main__': + main()