Commit fdfa2b51 authored by Guido van Rossum's avatar Guido van Rossum

parsefile() now calls self.update() while filling the buffer,

so you can read the top of the man page while the rest is being parsed
parent 97aeca15
...@@ -23,72 +23,102 @@ class EditableManPage(ScrolledText): ...@@ -23,72 +23,102 @@ class EditableManPage(ScrolledText):
ScrolledText.__init__(self, master, cnf) ScrolledText.__init__(self, master, cnf)
# Define tags for formatting styles # Define tags for formatting styles
self.tag_config('bold', {'font': BOLDFONT}) self.tag_config('X', {'font': BOLDFONT})
self.tag_config('italic', {'font': ITALICFONT}) self.tag_config('!', {'font': ITALICFONT})
self.tag_config('underline', {'underline': 1}) self.tag_config('_', {'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
def parsefile(self, fp): def parsefile(self, fp):
save_cursor = self['cursor'] if hasattr(self, 'buffer'):
self['cursor'] = 'watch' raise RuntimeError, 'Still busy parsing!'
self.update() from select import select
ok = 0 def avail(fp=fp, tout=0.0, select=select):
empty = 0 return select([fp], [], [], tout)[0]
nextline = None height = self.getint(self['height'])
self.startparser()
while 1: while 1:
if nextline: if self.lineno < height or \
line = nextline self.lineno%10 == 0 or not avail():
nextline = None self.update()
else:
line = fp.readline()
if not line:
break
if emptyprog.match(line) >= 0:
empty = 1
continue
nextline = fp.readline() nextline = fp.readline()
if nextline and ulprog.match(nextline) >= 0: if not nextline:
propline = nextline break
nextline = None self.parseline(nextline)
else: self.endparser()
propline = '' self.update()
if not ok:
ok = 1 def startparser(self):
empty = 0 self.lineno = 0
continue self.ok = 0
if footerprog.match(line) >= 0: self.empty = 0
ok = 0 self.buffer = None
empty = 0
continue def endparser(self):
if empty: if self.buffer:
self.insert_prop('\n') self.parseline('')
empty = 0 del self.ok, self.empty, self.buffer
p = ''
j = 0 def parseline(self, nextline):
for i in range(min(len(propline), len(line))): if not self.buffer:
if propline[i] != p: # Save this line -- we need one line read-ahead
if j < i: self.buffer = nextline
self.insert_prop(line[j:i], p) return
j = i if emptyprog.match(self.buffer) >= 0:
p = propline[i] # Buffered line was empty -- set a flag
self.insert_prop(line[j:]) self.empty = 1
self['cursor'] = save_cursor 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 = ' '): def insert_prop(self, str, prop = ' '):
here = self.index(AtInsert()) here = self.index(AtInsert())
self.insert(AtInsert(), str) self.insert(AtInsert(), str[0])
for tag in self.tagmap.values(): tags = self.tag_names(here)
self.tag_remove(tag, here, AtInsert()) for tag in tags:
if self.tagmap.has_key(prop): self.tag_remove(tag, here)
self.tag_add(self.tagmap[prop], here, AtInsert()) if prop != ' ':
self.tag_add(prop, here)
self.insert(AtInsert(), str[1:])
# Readonly Man Page class -- disables editing, otherwise the same # Readonly Man Page class -- disables editing, otherwise the same
class ReadonlyManPage(EditableManPage): class ReadonlyManPage(EditableManPage):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment