Clarify portability and main program.
[python/dscho.git] / Demo / tkinter / guido / regexdemo.py
blobbfb527f325488821ea63752c02ed914444b7ae5a
1 """Basic regular expression demostration facility.
3 This displays a window with two type-in boxes. In the top box, you enter a
4 regular expression. In the bottom box, you enter a string. The first
5 match in the string of the regular expression is highlighted with a yellow
6 background (or red if the match is empty -- then the character at the match
7 is highlighted). The highlighting is continuously updated. At the bottom
8 are a number of checkboxes which control the regular expression syntax used
9 (see the regex_syntax module for descriptions). When there's no match, or
10 when the regular expression is syntactically incorrect, an error message is
11 displayed.
13 """
15 from Tkinter import *
16 import regex
17 import regex_syntax
19 class RegexDemo:
21 def __init__(self, master):
22 self.master = master
23 self.topframe = Frame(self.master)
24 self.topframe.pack(fill=X)
25 self.promptdisplay = Label(self.topframe, text="Enter a regex:")
26 self.promptdisplay.pack(side=LEFT)
27 self.statusdisplay = Label(self.topframe, text="", anchor=W)
28 self.statusdisplay.pack(side=LEFT, fill=X)
29 self.regexdisplay = Entry(self.master)
30 self.regexdisplay.pack(fill=X)
31 self.regexdisplay.focus_set()
32 self.labeldisplay = Label(self.master, anchor=W,
33 text="Enter a string:")
34 self.labeldisplay.pack(fill=X)
35 self.labeldisplay.pack(fill=X)
36 self.stringdisplay = Text(self.master, width=60, height=4)
37 self.stringdisplay.pack(fill=BOTH, expand=1)
38 self.stringdisplay.tag_configure("hit", background="yellow")
39 self.addoptions()
40 self.regexdisplay.bind('<Key>', self.recompile)
41 self.stringdisplay.bind('<Key>', self.reevaluate)
42 self.compiled = None
43 self.recompile()
44 btags = self.regexdisplay.bindtags()
45 self.regexdisplay.bindtags(btags[1:] + btags[:1])
46 btags = self.stringdisplay.bindtags()
47 self.stringdisplay.bindtags(btags[1:] + btags[:1])
49 def addoptions(self):
50 self.frames = []
51 self.boxes = []
52 self.vars = []
53 for name in ( 'RE_NO_BK_PARENS',
54 'RE_NO_BK_VBAR',
55 'RE_BK_PLUS_QM',
56 'RE_TIGHT_VBAR',
57 'RE_NEWLINE_OR',
58 'RE_CONTEXT_INDEP_OPS'):
59 if len(self.boxes) % 3 == 0:
60 frame = Frame(self.master)
61 frame.pack(fill=X)
62 self.frames.append(frame)
63 val = getattr(regex_syntax, name)
64 var = IntVar()
65 box = Checkbutton(frame,
66 variable=var, text=name,
67 offvalue=0, onvalue=val,
68 command=self.newsyntax)
69 box.pack(side=LEFT)
70 self.boxes.append(box)
71 self.vars.append(var)
73 def newsyntax(self):
74 syntax = 0
75 for var in self.vars:
76 syntax = syntax | var.get()
77 regex.set_syntax(syntax)
78 self.recompile()
80 def recompile(self, event=None):
81 try:
82 self.compiled = regex.compile(self.regexdisplay.get())
83 self.statusdisplay.config(text="")
84 except regex.error, msg:
85 self.compiled = None
86 self.statusdisplay.config(text="regex.error: %s" % str(msg))
87 self.reevaluate()
89 def reevaluate(self, event=None):
90 try:
91 self.stringdisplay.tag_remove("hit", "1.0", END)
92 except TclError:
93 pass
94 if not self.compiled:
95 return
96 text = self.stringdisplay.get("1.0", END)
97 i = self.compiled.search(text)
98 if i < 0:
99 self.statusdisplay.config(text="(no match)")
100 else:
101 self.statusdisplay.config(text="")
102 regs = self.compiled.regs
103 first, last = regs[0]
104 if last == first:
105 last = first+1
106 self.stringdisplay.tag_configure("hit",
107 background="red")
108 else:
109 self.stringdisplay.tag_configure("hit",
110 background="yellow")
111 pfirst = "1.0 + %d chars" % first
112 plast = "1.0 + %d chars" % last
113 self.stringdisplay.tag_add("hit", pfirst, plast)
114 self.stringdisplay.yview_pickplace(pfirst)
118 # Main function, run when invoked as a stand-alone Python program.
120 def main():
121 root = Tk()
122 demo = RegexDemo(root)
123 root.protocol('WM_DELETE_WINDOW', root.quit)
124 root.mainloop()
126 if __name__ == '__main__':
127 main()