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