summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xDemo/tkinter/guido/ManPage.py150
1 files changed, 90 insertions, 60 deletions
diff --git a/Demo/tkinter/guido/ManPage.py b/Demo/tkinter/guido/ManPage.py
index 8c3ad8c..9c341b6 100755
--- a/Demo/tkinter/guido/ManPage.py
+++ b/Demo/tkinter/guido/ManPage.py
@@ -23,72 +23,102 @@ class EditableManPage(ScrolledText):
ScrolledText.__init__(self, master, cnf)
# Define tags for formatting styles
- self.tag_config('bold', {'font': BOLDFONT})
- self.tag_config('italic', {'font': ITALICFONT})
- self.tag_config('underline', {'underline': 1})
-
- # Create mapping from characters to tags
- self.tagmap = {
- 'X': 'bold',
- '_': 'underline',
- '!': 'italic',
- }
-
- # Parse nroff output piped through ul -i and append it to the
- # text widget
+ self.tag_config('X', {'font': BOLDFONT})
+ self.tag_config('!', {'font': ITALICFONT})
+ self.tag_config('_', {'underline': 1})
+
def parsefile(self, fp):
- save_cursor = self['cursor']
- self['cursor'] = 'watch'
- self.update()
- ok = 0
- empty = 0
- nextline = None
+ if hasattr(self, 'buffer'):
+ raise RuntimeError, 'Still busy parsing!'
+ from select import select
+ def avail(fp=fp, tout=0.0, select=select):
+ return select([fp], [], [], tout)[0]
+ height = self.getint(self['height'])
+ self.startparser()
while 1:
- if nextline:
- line = nextline
- nextline = None
- else:
- line = fp.readline()
- if not line:
- break
- if emptyprog.match(line) >= 0:
- empty = 1
- continue
+ if self.lineno < height or \
+ self.lineno%10 == 0 or not avail():
+ self.update()
nextline = fp.readline()
- if nextline and ulprog.match(nextline) >= 0:
- propline = nextline
- nextline = None
- else:
- propline = ''
- if not ok:
- ok = 1
- empty = 0
- continue
- if footerprog.match(line) >= 0:
- ok = 0
- empty = 0
- continue
- if empty:
- self.insert_prop('\n')
- empty = 0
- p = ''
- j = 0
- for i in range(min(len(propline), len(line))):
- if propline[i] != p:
- if j < i:
- self.insert_prop(line[j:i], p)
- j = i
- p = propline[i]
- self.insert_prop(line[j:])
- self['cursor'] = save_cursor
+ if not nextline:
+ break
+ self.parseline(nextline)
+ self.endparser()
+ self.update()
+
+ def startparser(self):
+ self.lineno = 0
+ self.ok = 0
+ self.empty = 0
+ self.buffer = None
+
+ def endparser(self):
+ if self.buffer:
+ self.parseline('')
+ del self.ok, self.empty, self.buffer
+
+ def parseline(self, nextline):
+ if not self.buffer:
+ # Save this line -- we need one line read-ahead
+ self.buffer = nextline
+ return
+ if emptyprog.match(self.buffer) >= 0:
+ # Buffered line was empty -- set a flag
+ self.empty = 1
+ self.buffer = nextline
+ return
+ textline = self.buffer
+ if ulprog.match(nextline) >= 0:
+ # Next line is properties for buffered line
+ propline = nextline
+ self.buffer = None
+ else:
+ # Next line is read-ahead
+ propline = None
+ self.buffer = nextline
+ if not self.ok:
+ # First non blank line after footer must be header
+ # -- skip that too
+ self.ok = 1
+ self.empty = 0
+ return
+ if footerprog.match(textline) >= 0:
+ # Footer -- start skipping until next non-blank line
+ self.ok = 0
+ self.empty = 0
+ return
+ if self.empty:
+ # One or more previous lines were empty
+ # -- insert one blank line in the text
+ self.insert_prop('\n')
+ self.lineno = self.lineno + 1
+ self.empty = 0
+ if not propline:
+ # No properties
+ self.insert_prop(textline)
+ self.lineno = self.lineno + 1
+ return
+ # Search for properties
+ p = ''
+ j = 0
+ for i in range(min(len(propline), len(textline))):
+ if propline[i] != p:
+ if j < i:
+ self.insert_prop(textline[j:i], p)
+ j = i
+ p = propline[i]
+ self.insert_prop(textline[j:])
+ self.lineno = self.lineno + 1
def insert_prop(self, str, prop = ' '):
here = self.index(AtInsert())
- self.insert(AtInsert(), str)
- for tag in self.tagmap.values():
- self.tag_remove(tag, here, AtInsert())
- if self.tagmap.has_key(prop):
- self.tag_add(self.tagmap[prop], here, AtInsert())
+ self.insert(AtInsert(), str[0])
+ tags = self.tag_names(here)
+ for tag in tags:
+ self.tag_remove(tag, here)
+ if prop != ' ':
+ self.tag_add(prop, here)
+ self.insert(AtInsert(), str[1:])
# Readonly Man Page class -- disables editing, otherwise the same
class ReadonlyManPage(EditableManPage):