From 426eea154ee18fffb965c008e515e4dcff6d1b8b Mon Sep 17 00:00:00 2001 From: Nick Lanham Date: Tue, 1 Mar 2011 19:11:53 +0100 Subject: [PATCH] add a wrap_string function that works properly --- deluge/ui/console/modes/format_utils.py | 76 +++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/deluge/ui/console/modes/format_utils.py b/deluge/ui/console/modes/format_utils.py index 811c742e7..73a5ec034 100644 --- a/deluge/ui/console/modes/format_utils.py +++ b/deluge/ui/console/modes/format_utils.py @@ -99,3 +99,79 @@ def format_column(col, lim): def format_row(row,column_widths): return "".join([format_column(row[i],column_widths[i]) for i in range(0,len(row))]) + +import re +from collections import deque +_strip_re = re.compile("\{!.*?!\}") +def wrap_string(string,width,min_lines=0,strip_colors=True): + """ + Wrap a string to fit in a particular width. Returns a list of output lines. + + :param string: str, the string to wrap + :param width: int, the maximum width of a line of text + :param min_lines: int, extra lines will be added so the output tuple contains at least min_lines lines + :param strip_colors: boolean, if True, text in {!!} blocks will not be considered as adding to the + width of the line. They will still be present in the output. + """ + ret = [] + s1 = string.split("\n") + + def insert_clr(s,offset,mtchs,clrs): + end_pos = offset+len(s) + while mtchs and (mtchs[0] <= end_pos) and (mtchs[0] >= offset): + mtc = mtchs.popleft()-offset + clr = clrs.popleft() + end_pos += len(clr) + s = "%s%s%s"%(s[:mtc],clr,s[mtc:]) + return s + + for s in s1: + cur_pos = offset = 0 + if strip_colors: + mtchs = deque() + clrs = deque() + for m in _strip_re.finditer(s): + mtchs.append(m.start()) + clrs.append(m.group()) + cstr = _strip_re.sub('',s) + else: + cstr = s + while len(cstr) > width: + sidx = cstr.rfind(" ",0,width-1) + sidx += 1 + if sidx > 0: + if strip_colors: + to_app = cstr[0:sidx] + to_app = insert_clr(to_app,offset,mtchs,clrs) + ret.append(to_app) + offset += len(to_app) + else: + ret.append(cstr[0:sidx]) + cstr = cstr[sidx:] + if not cstr: + cstr = None + break + else: + # can't find a reasonable split, just split at width + if strip_colors: + to_app = cstr[0:width] + to_app = insert_clr(to_app,offset,mtchs,clrs) + ret.append(to_app) + offset += len(to_app) + else: + ret.append(cstr[0:width]) + cstr = cstr[width:] + if not cstr: + cstr = None + break + if cstr != None: + if strip_colors: + ret.append(insert_clr(cstr,offset,mtchs,clrs)) + else: + ret.append(cstr) + + if min_lines>0: + for i in range(len(ret),min_lines): + ret.append(" ") + + return ret