Finishing the PyMailGUI Client: User Help Tools - wraplines: Line Split Tools (Page 3 of 6 )
The module in Example 15-7 implements general tools for wrapping long lines, at either a fixed column or the first delimiter at or before a fixed column. PyMailGUI uses this file’s wrapText1 function for text in view, reply, and forward windows, but this code is potentially useful in other programs. Run the file as a script to watch its self-test code at work, and study its functions to see its text-processing logic.
Example 15-7. PP3E\Internet\Email\PyMailGui\wraplines.py
################################################################ # split lines on fixed columns or at delimiters before a column
# see also: related but different textwrap standard library module (2.3+) ###############################################################
defaultsize = 80
def wrapLinesSimple(lineslist, size=defaultsize):
"split at fixed position size"
wraplines = []
for line in lineslist:
while True:
wraplines.append(line[:size]) # OK if len < size
line = line[size:] # split without analysis
if not line: break
return wraplines
def wrapLinesSmart(lineslist, size=defaultsize, delimiters='.,:\t '):
"wrap at first delimiter left of size"
wraplines = []
for line in lineslist:
while True:
if len(line) <= size:
wraplines += [line]
break
else:
for look in range(size-1, size/2, -1):
if line[look] in delimiters:
front, line = line[:look+1], line[look+1:]
break
else:
front, line = line[:size], line[size:]
wraplines += [front]
return wraplines
################################################################ # common use case utilities ###############################################################
def wrapText1(text,
size=defaultsize): # better for line-based txt: mail
"when text read all at once" # keeps original line brks struct
lines = text.split('\n') # split on newlines
| lines = wrapLinesSmart(lines, size) | # wrap lines on delimiters |
| return '\n'.join(lines) | # put back together |
| def wrapText2(text, size=defaultsize): | # more uniform across lines |
| "same, but treat as one long line" | # but loses original line struct |
| text = text.replace('\n', ' ') | # drop newlines if any |
| lines = wrapLinesSmart([text], size) | # wrap single line on delimiters |
| return lines | # caller puts back together |
| def wrapText3(text, size=defaultsize): | |
| "same, but put back together" | |
| lines = wrapText2(text, size) | # wrap as single long line |
| return '\n'.join(lines) + '\n' | # make one string with newlines |
| def wrapLines1(lines, size=defaultsize): | |
| "when newline included at end" | |
| lines = [line[:-1] for line in lines] | # strip off newlines (or .rstrip) |
| lines = wrapLinesSmart(lines, size) | # wrap on delimiters |
| return [(line + '\n') for line in lines] | # put them back |
| def wrapLines2(lines, size=defaultsize): | # more uniform across lines |
| "same, but concat as one long line" | # but loses original structure |
| text = ''.join(lines) | # put together as 1 line |
| lines = wrapText2(text) | # wrap on delimiters |
| return [(line + '\n') for line in lines] | # put newlines on ends |
################################################################ a self-test ###############################################################
if __name__ == '__main__':
lines = ['spam ham ' * 20 + 'spam,ni' * 20,
'spam ham ' * 20,
'spam,ni' * 20,
'spam ham.ni' * 20,
'',
'spam'*80,
' ',
'spam ham eggs']
print 'all', '-'*30
for line in lines: print repr(line)
print 'simple', '-'*30
for line in wrapLinesSimple(lines): print repr(line)
print 'smart', '-'*30
for line in wrapLinesSmart(lines): print repr(line)
print 'single1', '-'*30
for line in wrapLinesSimple([lines[0]], 60): print repr(line)
print 'single2', '-'*30
for line in wrapLinesSmart([lines[0]], 60): print repr(line)
print 'combined text', '-'*30
for line in wrapLines2(lines): print repr(line)
print 'combined lines', '-'*30
print wrapText1('\n'.join(lines))
assert ''.join(lines) == ''.join(wrapLinesSimple(lines, 60))
assert ''.join(lines) == ''.join(wrapLinesSmart(lines, 60))
print len(''.join(lines)),
print len(''.join(wrapLinesSimple(lines))),
print len(''.join(wrapLinesSmart(lines))),
print len(''.join(wrapLinesSmart(lines, 60))),
raw_input('Press enter')
Next: mailcon >>
More Python Articles
More By O'Reilly Media
|
This article is excerpted from chapter 15 of the book Programming Python, Third Edition, written by Mark Lutz (O'Reilly, 2006; ISBN: 0596009259). Check it out today at your favorite bookstore. Buy this book now.
|
|