def wrap_text(textlist, wraplength=50, indent=0, firstline=0): """ It takes a block of text and wraps it nicely. It accounts for indenting lines of text, wraplengths, and wrapping around ANSI colors. We break on carriage returns (those are easy) and if no carriage returns are available we break on spaces. If the actual line is longer than the wraplength, then we'll break in the line at the wraplength--this will cut words in two. Note: we don't expand tabs or backspaces. Both count as one character. @param textlist: either a string of text needing to be formatted and wrapped, or a textlist needing to be formatted and wrapped. @type textlist: string or list of strings @param wraplength: the maximum length any line can be. we'll wrap at an index equal to or less than this length. @type wraplength: int @param indent: how many spaces to indent every line. @type indent: int @param firstline: 0 if we shouldn't indent the first line, 1 if we should @type firstline: boolean @returns: the wrapped text string @rtype: string """ wrapcount = 0 # how much we've got on the line so far linecount = 0 # which line we're on if wraplength > 2: wraplength = wraplength - 2 # split the formatting from the text if type(textlist) == types.StringType: textlist = ansi.split_ansi_from_text(textlist) for i in range(0, len(textlist)): # if this is a color token, we gloss over it if ansi.is_color_token(textlist[i]): continue # if this is a text token, then we need to factor it into the word # wrapping marker = 0 # this handles the offset for not indenting the first line (if that's # the sort of thing we're into). if firstline: x = _find_next_break(textlist[i], marker, wrapcount, wraplength - indent) else: x = _find_next_break(textlist[i], marker, wrapcount, wraplength) # go through finding breaks and sticking in carriage returns and indents # and things for this text token while x != -1: # insert the carriage return, any indent, and lstrip the line as well # print "'" + textlist[i] + "'", len(textlist[i]), x if textlist[i][x] == "\n": if indent: textlist[i] = (textlist[i][:x + 1] + (indent * ' ') + textlist[i][x + 1:].lstrip()) else: textlist[i] = (textlist[i][:x + 1] + textlist[i][x + 1:]) else: if indent: textlist[i] = (textlist[i][:x + 1] + '\n' + (indent * ' ') + textlist[i][x + 1:].lstrip()) else: textlist[i] = (textlist[i][:x + 1] + '\n' + textlist[i][x + 1:]) marker = x + indent + 2 wrapcount = 0 x = _find_next_break(textlist[i], marker, wrapcount, wraplength - indent) wrapcount = len(textlist[i]) - marker + wrapcount # this next line joins the list with no separator if firstline: return (indent * " ") + ''.join(textlist) else: return ''.join(textlist)
def wrap_text(textlist, wraplength=50, indent=0, firstline=0): """ It takes a block of text and wraps it nicely. It accounts for indenting lines of text, wraplengths, and wrapping around ANSI colors. We break on carriage returns (those are easy) and if no carriage returns are available we break on spaces. If the actual line is longer than the wraplength, then we'll break in the line at the wraplength--this will cut words in two. Note: we don't expand tabs or backspaces. Both count as one character. @param textlist: either a string of text needing to be formatted and wrapped, or a textlist needing to be formatted and wrapped. @type textlist: string or list of strings @param wraplength: the maximum length any line can be. we'll wrap at an index equal to or less than this length. @type wraplength: int @param indent: how many spaces to indent every line. @type indent: int @param firstline: 0 if we shouldn't indent the first line, 1 if we should @type firstline: boolean @returns: the wrapped text string @rtype: string """ wrapcount = 0 # how much we've got on the line so far linecount = 0 # which line we're on if wraplength > 2: wraplength = wraplength - 2 # split the formatting from the text if type(textlist) == types.StringType: textlist = ansi.split_ansi_from_text(textlist) for i in range(0, len(textlist)): # if this is a color token, we gloss over it if ansi.is_color_token(textlist[i]): continue # if this is a text token, then we need to factor it into the word # wrapping marker = 0 # this handles the offset for not indenting the first line (if that's # the sort of thing we're into). if firstline: x = _find_next_break(textlist[i], marker, wrapcount, wraplength - indent) else: x = _find_next_break(textlist[i], marker, wrapcount, wraplength) # go through finding breaks and sticking in carriage returns and indents # and things for this text token while x != -1: # insert the carriage return, any indent, and lstrip the line as well # print "'" + textlist[i] + "'", len(textlist[i]), x if textlist[i][x] == "\n": if indent: textlist[i] = (textlist[i][:x+1] + (indent * ' ') + textlist[i][x+1:].lstrip()) else: textlist[i] = (textlist[i][:x+1] + textlist[i][x+1:]) else: if indent: textlist[i] = (textlist[i][:x+1] + '\n' + (indent * ' ') + textlist[i][x+1:].lstrip()) else: textlist[i] = (textlist[i][:x+1] + '\n' + textlist[i][x+1:]) marker = x + indent + 2 wrapcount = 0 x = _find_next_break(textlist[i], marker, wrapcount, wraplength - indent) wrapcount = len(textlist[i]) - marker + wrapcount # this next line joins the list with no separator if firstline: return (indent * " ") + ''.join(textlist) else: return ''.join(textlist)