Update to 2.7.3
[profile/ivi/python.git] / Tools / scripts / redemo.py
1 #!/usr/bin/env python
2 """Basic regular expression demostration facility (Perl style syntax)."""
3
4 from Tkinter import *
5 import re
6
7 class ReDemo:
8
9     def __init__(self, master):
10         self.master = master
11
12         self.promptdisplay = Label(self.master, anchor=W,
13                 text="Enter a Perl-style regular expression:")
14         self.promptdisplay.pack(side=TOP, fill=X)
15
16         self.regexdisplay = Entry(self.master)
17         self.regexdisplay.pack(fill=X)
18         self.regexdisplay.focus_set()
19
20         self.addoptions()
21
22         self.statusdisplay = Label(self.master, text="", anchor=W)
23         self.statusdisplay.pack(side=TOP, fill=X)
24
25         self.labeldisplay = Label(self.master, anchor=W,
26                 text="Enter a string to search:")
27         self.labeldisplay.pack(fill=X)
28         self.labeldisplay.pack(fill=X)
29
30         self.showframe = Frame(master)
31         self.showframe.pack(fill=X, anchor=W)
32
33         self.showvar = StringVar(master)
34         self.showvar.set("first")
35
36         self.showfirstradio = Radiobutton(self.showframe,
37                                          text="Highlight first match",
38                                           variable=self.showvar,
39                                           value="first",
40                                           command=self.recompile)
41         self.showfirstradio.pack(side=LEFT)
42
43         self.showallradio = Radiobutton(self.showframe,
44                                         text="Highlight all matches",
45                                         variable=self.showvar,
46                                         value="all",
47                                         command=self.recompile)
48         self.showallradio.pack(side=LEFT)
49
50         self.stringdisplay = Text(self.master, width=60, height=4)
51         self.stringdisplay.pack(fill=BOTH, expand=1)
52         self.stringdisplay.tag_configure("hit", background="yellow")
53
54         self.grouplabel = Label(self.master, text="Groups:", anchor=W)
55         self.grouplabel.pack(fill=X)
56
57         self.grouplist = Listbox(self.master)
58         self.grouplist.pack(expand=1, fill=BOTH)
59
60         self.regexdisplay.bind('<Key>', self.recompile)
61         self.stringdisplay.bind('<Key>', self.reevaluate)
62
63         self.compiled = None
64         self.recompile()
65
66         btags = self.regexdisplay.bindtags()
67         self.regexdisplay.bindtags(btags[1:] + btags[:1])
68
69         btags = self.stringdisplay.bindtags()
70         self.stringdisplay.bindtags(btags[1:] + btags[:1])
71
72     def addoptions(self):
73         self.frames = []
74         self.boxes = []
75         self.vars = []
76         for name in ('IGNORECASE',
77                      'LOCALE',
78                      'MULTILINE',
79                      'DOTALL',
80                      'VERBOSE'):
81             if len(self.boxes) % 3 == 0:
82                 frame = Frame(self.master)
83                 frame.pack(fill=X)
84                 self.frames.append(frame)
85             val = getattr(re, name)
86             var = IntVar()
87             box = Checkbutton(frame,
88                     variable=var, text=name,
89                     offvalue=0, onvalue=val,
90                     command=self.recompile)
91             box.pack(side=LEFT)
92             self.boxes.append(box)
93             self.vars.append(var)
94
95     def getflags(self):
96         flags = 0
97         for var in self.vars:
98             flags = flags | var.get()
99         flags = flags
100         return flags
101
102     def recompile(self, event=None):
103         try:
104             self.compiled = re.compile(self.regexdisplay.get(),
105                                        self.getflags())
106             bg = self.promptdisplay['background']
107             self.statusdisplay.config(text="", background=bg)
108         except re.error, msg:
109             self.compiled = None
110             self.statusdisplay.config(
111                     text="re.error: %s" % str(msg),
112                     background="red")
113         self.reevaluate()
114
115     def reevaluate(self, event=None):
116         try:
117             self.stringdisplay.tag_remove("hit", "1.0", END)
118         except TclError:
119             pass
120         try:
121             self.stringdisplay.tag_remove("hit0", "1.0", END)
122         except TclError:
123             pass
124         self.grouplist.delete(0, END)
125         if not self.compiled:
126             return
127         self.stringdisplay.tag_configure("hit", background="yellow")
128         self.stringdisplay.tag_configure("hit0", background="orange")
129         text = self.stringdisplay.get("1.0", END)
130         last = 0
131         nmatches = 0
132         while last <= len(text):
133             m = self.compiled.search(text, last)
134             if m is None:
135                 break
136             first, last = m.span()
137             if last == first:
138                 last = first+1
139                 tag = "hit0"
140             else:
141                 tag = "hit"
142             pfirst = "1.0 + %d chars" % first
143             plast = "1.0 + %d chars" % last
144             self.stringdisplay.tag_add(tag, pfirst, plast)
145             if nmatches == 0:
146                 self.stringdisplay.yview_pickplace(pfirst)
147                 groups = list(m.groups())
148                 groups.insert(0, m.group())
149                 for i in range(len(groups)):
150                     g = "%2d: %r" % (i, groups[i])
151                     self.grouplist.insert(END, g)
152             nmatches = nmatches + 1
153             if self.showvar.get() == "first":
154                 break
155
156         if nmatches == 0:
157             self.statusdisplay.config(text="(no match)",
158                                       background="yellow")
159         else:
160             self.statusdisplay.config(text="")
161
162
163 # Main function, run when invoked as a stand-alone Python program.
164
165 def main():
166     root = Tk()
167     demo = ReDemo(root)
168     root.protocol('WM_DELETE_WINDOW', root.quit)
169     root.mainloop()
170
171 if __name__ == '__main__':
172     main()