source: trunk/essentials/dev-lang/python/Demo/tkinter/guido/ManPage.py@ 3408

Last change on this file since 3408 was 3225, checked in by bird, 19 years ago

Python 2.5

File size: 6.7 KB
Line 
1# Widget to display a man page
2
3import re
4from Tkinter import *
5from Tkinter import _tkinter
6from ScrolledText import ScrolledText
7
8# XXX These fonts may have to be changed to match your system
9BOLDFONT = '*-Courier-Bold-R-Normal-*-120-*'
10ITALICFONT = '*-Courier-Medium-O-Normal-*-120-*'
11
12# XXX Recognizing footers is system dependent
13# (This one works for IRIX 5.2 and Solaris 2.2)
14footerprog = re.compile(
15 '^ Page [1-9][0-9]*[ \t]+\|^.*Last change:.*[1-9][0-9]*\n')
16emptyprog = re.compile('^[ \t]*\n')
17ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')
18
19# Basic Man Page class -- does not disable editing
20class EditableManPage(ScrolledText):
21
22 # Initialize instance
23 def __init__(self, master=None, **cnf):
24 # Initialize base class
25 apply(ScrolledText.__init__, (self, master), cnf)
26
27 # Define tags for formatting styles
28 self.tag_config('X', underline=1)
29 self.tag_config('!', font=BOLDFONT)
30 self.tag_config('_', font=ITALICFONT)
31
32 # Set state to idle
33 self.fp = None
34 self.lineno = 0
35
36 # Test whether we are busy parsing a file
37 def busy(self):
38 return self.fp != None
39
40 # Ensure we're not busy
41 def kill(self):
42 if self.busy():
43 self._endparser()
44
45 # Parse a file, in the background
46 def asyncparsefile(self, fp):
47 self._startparser(fp)
48 self.tk.createfilehandler(fp, _tkinter.READABLE,
49 self._filehandler)
50
51 parsefile = asyncparsefile # Alias
52
53 # I/O handler used by background parsing
54 def _filehandler(self, fp, mask):
55 nextline = self.fp.readline()
56 if not nextline:
57 self._endparser()
58 return
59 self._parseline(nextline)
60
61 # Parse a file, now (cannot be aborted)
62 def syncparsefile(self, fp):
63 from select import select
64 def avail(fp=fp, tout=0.0, select=select):
65 return select([fp], [], [], tout)[0]
66 height = self.getint(self['height'])
67 self._startparser(fp)
68 while 1:
69 nextline = fp.readline()
70 if not nextline:
71 break
72 self._parseline(nextline)
73 self._endparser()
74
75 # Initialize parsing from a particular file -- must not be busy
76 def _startparser(self, fp):
77 if self.busy():
78 raise RuntimeError, 'startparser: still busy'
79 fp.fileno() # Test for file-ness
80 self.fp = fp
81 self.lineno = 0
82 self.ok = 0
83 self.empty = 0
84 self.buffer = None
85 savestate = self['state']
86 self['state'] = NORMAL
87 self.delete('1.0', END)
88 self['state'] = savestate
89
90 # End parsing -- must be busy, need not be at EOF
91 def _endparser(self):
92 if not self.busy():
93 raise RuntimeError, 'endparser: not busy'
94 if self.buffer:
95 self._parseline('')
96 try:
97 self.tk.deletefilehandler(self.fp)
98 except TclError, msg:
99 pass
100 self.fp.close()
101 self.fp = None
102 del self.ok, self.empty, self.buffer
103
104 # Parse a single line
105 def _parseline(self, nextline):
106 if not self.buffer:
107 # Save this line -- we need one line read-ahead