Welcome, guest | Sign In | My Account | Store | Cart
import re

def word_wrap(text, width, extent_func):
    '''
    Word wrap function / algorithm for wrapping text using proportional (versus 
    fixed-width) fonts.
    
    `text`: a string of text to wrap
    `width`: the width in pixels to wrap to
    `extent_func`: a function that returns a (w, h) tuple given any string, to
                   specify the size (text extent) of the string when rendered. 
                   the algorithm only uses the width.
    
    Returns a list of strings, one for each line after wrapping.
    '''
    lines = []
    pattern = re.compile(r'(\s+)')
    lookup = dict((c, extent_func(c)[0]) for c in set(text))
    for line in text.splitlines():
        tokens = pattern.split(line)
        tokens.append('')
        widths = [sum(lookup[c] for c in token) for token in tokens]
        start, total = 0, 0
        for index in xrange(0, len(tokens), 2):
            if total + widths[index] > width:
                end = index + 2 if index == start else index
                lines.append(''.join(tokens[start:end]))
                start, total = end, 0
                if end == index + 2:
                    continue
            total += widths[index] + widths[index + 1]
        if start < len(tokens):
            lines.append(''.join(tokens[start:]))
    lines = [line.strip() for line in lines]
    return lines or ['']

if __name__ == '__main__':
    text = (
        'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do '
        'eiusmod tempor incididunt ut labore et dolore magna aliqua.\n\n'
        'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris '
        'nisi ut aliquip ex ea commodo consequat.\n\n'
        'Duis aute irure dolor in reprehenderit in voluptate velit esse '
        'cillum dolore eu fugiat nulla pariatur.\n\n'
        'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui '
        'officia deserunt mollit anim id est laborum.'
    )
    # dummy extent function behaves like a fixed-width font
    def extent_func(text):
        return (1, 0)
    # wrap to 80 columns
    lines = word_wrap(text, 80, extent_func)
    for line in lines:
        print line

History