1 #! /usr/local/bin/python
3 # Tk man page browser -- currently only shows the Tcl/Tk man pages
12 addpack
.addpack('/ufs/guido/src/python/Demo/guido/tkinter')
13 from ManPage
import ManPage
15 MANNDIR
= '/usr/local/man/mann'
16 MAN3DIR
= '/usr/local/man/man3'
18 def listmanpages(mandir
):
19 files
= os
.listdir(mandir
)
22 if file[-2:-1] == '.' and (file[-1] in 'ln123456789'):
23 names
.append(file[:-2])
29 def __init__(self
, master
=None):
32 self
.frame
= Frame(master
, {
34 Pack
: {'expand': 1, 'fill': 'both'}})
35 self
.master
= self
.frame
.master
36 self
.subframe
= Frame(self
.frame
, {
38 Pack
: {'expand': 0, 'fill': 'both'}})
39 self
.leftsubframe
= Frame(self
.subframe
, {
40 'name': 'leftsubframe',
41 Pack
: {'side': 'left', 'expand': 1, 'fill': 'both'}})
42 self
.rightsubframe
= Frame(self
.subframe
, {
43 'name': 'rightsubframe',
44 Pack
: {'side': 'right', 'expand': 1, 'fill': 'both'}})
45 self
.chaptervar
= StringVar(master
)
46 self
.chapter
= Menubutton(self
.rightsubframe
,
49 'relief': 'raised', 'bd': 2,
50 Pack
: {'side': 'top'}})
51 self
.chaptermenu
= Menu(self
.chapter
, {'name': 'chaptermenu'})
52 self
.chaptermenu
.add_radiobutton({'label': 'C functions',
54 'variable': self
.chaptervar
,
55 'command': self
.newchapter
})
56 self
.chaptermenu
.add_radiobutton({'label': 'Tcl/Tk functions',
58 'variable': self
.chaptervar
,
59 'command': self
.newchapter
})
60 self
.chapter
['menu'] = self
.chaptermenu
61 self
.listbox
= Listbox(self
.rightsubframe
,
63 'relief': 'sunken', 'bd': 2,
65 Pack
: {'expand': 1, 'fill': 'both'}})
66 self
.l1
= Button(self
.leftsubframe
,
68 'text': 'Display manual page named:',
69 'command': self
.entry_cb
,
70 Pack
: {'side': 'top'}})
71 self
.entry
= Entry(self
.leftsubframe
,
73 'relief': 'sunken', 'bd': 2,
76 'expand': 0, 'fill': 'x'}})
77 self
.l2frame
= Frame(self
.leftsubframe
,
79 Pack
: {'expand': 0, 'fill': 'none'}})
80 self
.l2
= Button(self
.l2frame
,
82 'text': 'Search regexp:',
83 'command': self
.search_cb
,
84 Pack
: {'side': 'left'}})
85 self
.casesense
= Checkbutton(self
.l2frame
,
87 'text': 'Case sensitive',
88 'variable': 'casesense',
90 Pack
: {'side': 'left'}})
91 self
.search
= Entry(self
.leftsubframe
,
93 'relief': 'sunken', 'bd': 2,
96 'expand': 0, 'fill': 'x'}})
97 self
.title
= Label(self
.leftsubframe
,
100 Pack
: {'side': 'bottom'}})
101 self
.text
= ManPage(self
.frame
,
103 'relief': 'sunken', 'bd': 2,
104 'wrap': 'none', 'width': 72,
105 Pack
: {'expand': 1, 'fill': 'both'}})
107 self
.entry
.bind('<Return>', self
.entry_cb
)
108 self
.search
.bind('<Return>', self
.search_cb
)
109 self
.listbox
.bind('<Double-1>', self
.listbox_cb
)
111 self
.entry
.bind('<Tab>', self
.entry_tab
)
112 self
.search
.bind('<Tab>', self
.search_tab
)
113 self
.text
.bind('<Tab>', self
.text_tab
)
115 self
.entry
.focus_set()
117 self
.chaptervar
.set(MANNDIR
)
120 def newchapter(self
):
121 mandir
= self
.chaptervar
.get()
123 self
.addlist(listmanpages(mandir
))
125 def addchoice(self
, choice
):
126 if choice
not in self
.choices
:
127 self
.choices
.append(choice
)
131 def addlist(self
, list):
132 self
.choices
[len(self
.choices
):] = list
136 def entry_cb(self
, *e
):
139 def listbox_cb(self
, e
):
140 selection
= self
.listbox
.curselection()
141 if selection
and len(selection
) == 1:
142 name
= self
.listbox
.get(selection
[0])
145 def search_cb(self
, *e
):
146 self
.search_string(self
.search
.get())
148 def entry_tab(self
, e
):
149 self
.search
.focus_set()
151 def search_tab(self
, e
):
152 self
.entry
.focus_set()
154 def text_tab(self
, e
):
155 self
.entry
.focus_set()
157 def updatelist(self
):
158 key
= self
.entry
.get()
159 ok
= filter(lambda name
, key
=key
, n
=len(key
): name
[:n
]==key
,
161 self
.listbox
.delete(0, AtEnd())
164 if item
== key
: exactmatch
= 1
165 self
.listbox
.insert(AtEnd(), item
)
168 elif self
.listbox
.size() == 1:
169 return self
.listbox
.get(0)
170 # Else return None, meaning not a unique selection
173 name
= self
.updatelist()
176 self
.entry
.delete(0, AtEnd())
179 def show_page(self
, name
):
180 file = '%s/%s.?' % (self
.chaptervar
.get(), name
)
181 fp
= os
.popen('nroff -man %s | ul -i' % file, 'r')
183 self
.title
['text'] = name
184 self
.text
.parsefile(fp
)
186 def search_string(self
, search
):
188 print 'Empty search string'
190 if self
.frame
.tk
.getvar('casesense') != '1':
196 prog
= regex
.compile(search
, map)
198 prog
= regex
.compile(search
)
199 except regex
.error
, msg
:
200 print 'Regex error:', msg
202 here
= self
.text
.index(AtInsert())
203 lineno
= string
.atoi(here
[:string
.find(here
, '.')])
204 end
= self
.text
.index(AtEnd())
205 endlineno
= string
.atoi(end
[:string
.find(end
, '.')])
209 if lineno
> endlineno
:
212 endlineno
= wraplineno
215 line
= self
.text
.get('%d.0 linestart' % lineno
,
216 '%d.0 lineend' % lineno
)
217 i
= prog
.search(line
)
219 n
= max(1, len(prog
.group(0)))
221 self
.text
.tag_remove('sel',
226 self
.text
.tag_add('sel',
227 '%d.%d' % (lineno
, i
),
228 '%d.%d' % (lineno
, i
+n
))
229 self
.text
.mark_set(AtInsert(),
230 '%d.%d' % (lineno
, i
))
231 self
.text
.yview_pickplace(AtInsert())
236 sb
= SelectionBox(root
)
238 sb
.show_page(sys
.argv
[1])