File: pymailgui-products/unzipped/PyMailGui-PP4E/wraplines.py
""" ############################################################################### split lines on fixed columns or at delimiters before a column; see also: related but different textwrap standard library module (2.3+); 4E caveat: this assumes str; supporting bytes might help avoid some decodes; ############################################################################### """ 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): # 3.0: need // not / 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 ############################################################################### # 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'] sep = '-' * 30 print('all', sep) for line in lines: print(repr(line)) print('simple', sep) for line in wrapLinesSimple(lines): print(repr(line)) print('smart', sep) for line in wrapLinesSmart(lines): print(repr(line)) print('single1', sep) for line in wrapLinesSimple([lines[0]], 60): print(repr(line)) print('single2', sep) for line in wrapLinesSmart([lines[0]], 60): print(repr(line)) print('combined text', sep) for line in wrapLines2(lines): print(repr(line)) print('combined lines', sep) print(wrapText1('\n'.join(lines))) assert ''.join(lines) == ''.join(wrapLinesSimple(lines, 60)) assert ''.join(lines) == ''.join(wrapLinesSmart(lines, 60)) print(len(''.join(lines)), end=' ') print(len(''.join(wrapLinesSimple(lines))), end=' ') print(len(''.join(wrapLinesSmart(lines))), end=' ') print(len(''.join(wrapLinesSmart(lines, 60))), end=' ') input('Press enter') # pause if clicked