3 # Tk man page browser -- currently only shows the Tcl/Tk man pages
10 from ManPage
import ManPage
12 MANNDIRLIST
= ['/depot/sundry/man/mann','/usr/local/man/mann']
13 MAN3DIRLIST
= ['/depot/sundry/man/man3','/usr/local/man/man3']
16 for dir in MANNDIRLIST
:
17 if os
.path
.exists(dir):
22 for dir in MAN3DIRLIST
:
23 if os
.path
.exists(dir):
27 if not foundmanndir
or not foundman3dir
:
28 sys
.stderr
.write('\n')
31 Failed to find mann directory.
32 Please add the correct entry to the MANNDIRLIST
33 at the top of %s script.""" % \
35 sys
.stderr
.write("%s\n\n" % msg
)
38 Failed to find man3 directory.
39 Please add the correct entry to the MAN3DIRLIST
40 at the top of %s script.""" % \
42 sys
.stderr
.write("%s\n\n" % msg
)
48 def listmanpages(mandir
):
49 files
= os
.listdir(mandir
)
52 if file[-2:-1] == '.' and (file[-1] in 'ln123456789'):
53 names
.append(file[:-2])
59 def __init__(self
, master
=None):
62 self
.frame
= Frame(master
, name
="frame")
63 self
.frame
.pack(expand
=1, fill
=BOTH
)
64 self
.master
= self
.frame
.master
65 self
.subframe
= Frame(self
.frame
, name
="subframe")
66 self
.subframe
.pack(expand
=0, fill
=BOTH
)
67 self
.leftsubframe
= Frame(self
.subframe
, name
='leftsubframe')
68 self
.leftsubframe
.pack(side
=LEFT
, expand
=1, fill
=BOTH
)
69 self
.rightsubframe
= Frame(self
.subframe
, name
='rightsubframe')
70 self
.rightsubframe
.pack(side
=RIGHT
, expand
=1, fill
=BOTH
)
71 self
.chaptervar
= StringVar(master
)
72 self
.chapter
= Menubutton(self
.rightsubframe
, name
='chapter',
73 text
='Directory', relief
=RAISED
,
75 self
.chapter
.pack(side
=TOP
)
76 self
.chaptermenu
= Menu(self
.chapter
, name
='chaptermenu')
77 self
.chaptermenu
.add_radiobutton(label
='C functions',
79 variable
=self
.chaptervar
,
80 command
=self
.newchapter
)
81 self
.chaptermenu
.add_radiobutton(label
='Tcl/Tk functions',
83 variable
=self
.chaptervar
,
84 command
=self
.newchapter
)
85 self
.chapter
['menu'] = self
.chaptermenu
86 self
.listbox
= Listbox(self
.rightsubframe
, name
='listbox',
87 relief
=SUNKEN
, borderwidth
=2,
89 self
.listbox
.pack(expand
=1, fill
=BOTH
)
90 self
.l1
= Button(self
.leftsubframe
, name
='l1',
91 text
='Display manual page named:',
92 command
=self
.entry_cb
)
93 self
.l1
.pack(side
=TOP
)
94 self
.entry
= Entry(self
.leftsubframe
, name
='entry',
95 relief
=SUNKEN
, borderwidth
=2,
97 self
.entry
.pack(expand
=0, fill
=X
)
98 self
.l2frame
= Frame(self
.leftsubframe
, name
='l2frame')
99 self
.l2frame
.pack(expand
=0, fill
=NONE
)
100 self
.l2
= Button(self
.l2frame
, name
='l2',
101 text
='Search regexp:',
102 command
=self
.search_cb
)
103 self
.l2
.pack(side
=LEFT
)
104 self
.casevar
= BooleanVar()
105 self
.casesense
= Checkbutton(self
.l2frame
, name
='casesense',
106 text
='Case sensitive',
107 variable
=self
.casevar
,
109 self
.casesense
.pack(side
=LEFT
)
110 self
.search
= Entry(self
.leftsubframe
, name
='search',
111 relief
=SUNKEN
, borderwidth
=2,
113 self
.search
.pack(expand
=0, fill
=X
)
114 self
.title
= Label(self
.leftsubframe
, name
='title',
116 self
.title
.pack(side
=BOTTOM
)
117 self
.text
= ManPage(self
.frame
, name
='text',
118 relief
=SUNKEN
, borderwidth
=2,
120 selectbackground
='pink')
121 self
.text
.pack(expand
=1, fill
=BOTH
)
123 self
.entry
.bind('<Return>', self
.entry_cb
)
124 self
.search
.bind('<Return>', self
.search_cb
)
125 self
.listbox
.bind('<Double-1>', self
.listbox_cb
)
127 self
.entry
.bind('<Tab>', self
.entry_tab
)
128 self
.search
.bind('<Tab>', self
.search_tab
)
129 self
.text
.bind('<Tab>', self
.text_tab
)
131 self
.entry
.focus_set()
133 self
.chaptervar
.set(MANNDIR
)
136 def newchapter(self
):
137 mandir
= self
.chaptervar
.get()
139 self
.addlist(listmanpages(mandir
))
141 def addchoice(self
, choice
):
142 if choice
not in self
.choices
:
143 self
.choices
.append(choice
)
147 def addlist(self
, list):
148 self
.choices
[len(self
.choices
):] = list
152 def entry_cb(self
, *e
):
155 def listbox_cb(self
, e
):
156 selection
= self
.listbox
.curselection()
157 if selection
and len(selection
) == 1:
158 name
= self
.listbox
.get(selection
[0])
161 def search_cb(self
, *e
):
162 self
.search_string(self
.search
.get())
164 def entry_tab(self
, e
):
165 self
.search
.focus_set()
167 def search_tab(self
, e
):
168 self
.entry
.focus_set()
170 def text_tab(self
, e
):
171 self
.entry
.focus_set()
173 def updatelist(self
):
174 key
= self
.entry
.get()
175 ok
= filter(lambda name
, key
=key
, n
=len(key
): name
[:n
]==key
,
179 self
.listbox
.delete(0, AtEnd())
182 if item
== key
: exactmatch
= 1
183 self
.listbox
.insert(AtEnd(), item
)
186 n
= self
.listbox
.size()
188 return self
.listbox
.get(0)
189 # Else return None, meaning not a unique selection
192 name
= self
.updatelist()
195 self
.entry
.delete(0, AtEnd())
198 def show_page(self
, name
):
199 file = '%s/%s.?' % (self
.chaptervar
.get(), name
)
200 fp
= os
.popen('nroff -man %s | ul -i' % file, 'r')
202 self
.title
['text'] = name
203 self
.text
.parsefile(fp
)
205 def search_string(self
, search
):
208 print 'Empty search string'
210 if not self
.casevar
.get():
216 prog
= regex
.compile(search
, map)
218 prog
= regex
.compile(search
)
219 except regex
.error
, msg
:
221 print 'Regex error:', msg
223 here
= self
.text
.index(AtInsert())
224 lineno
= string
.atoi(here
[:string
.find(here
, '.')])
225 end
= self
.text
.index(AtEnd())
226 endlineno
= string
.atoi(end
[:string
.find(end
, '.')])
231 if lineno
> endlineno
:
234 endlineno
= wraplineno
237 line
= self
.text
.get('%d.0 linestart' % lineno
,
238 '%d.0 lineend' % lineno
)
239 i
= prog
.search(line
)
242 n
= max(1, len(prog
.group(0)))
244 self
.text
.tag_remove('sel',
249 self
.text
.tag_add('sel',
250 '%d.%d' % (lineno
, i
),
251 '%d.%d' % (lineno
, i
+n
))
252 self
.text
.mark_set(AtInsert(),
253 '%d.%d' % (lineno
, i
))
254 self
.text
.yview_pickplace(AtInsert())
261 sb
= SelectionBox(root
)
263 sb
.show_page(sys
.argv
[1])