Skip to content

Instantly share code, notes, and snippets.

@Niols
Last active August 29, 2015 14:22
Show Gist options
  • Save Niols/cd3053eb1e22b96bf2f1 to your computer and use it in GitHub Desktop.
Save Niols/cd3053eb1e22b96bf2f1 to your computer and use it in GitHub Desktop.
Align text string using spaces between words to fit specified width
'''
align_string.py
Align string with spaces between words to fit specified width
Author: Denis Barmenkov <denis.barmenkov@gmail.com>
Copyright: this code is free, but if you want to use it,
please keep this multiline comment along with function source.
Thank you.
2005-05-22 13:27 - first revision
2010-03-09 17:01 - added align_paragraph()
2010-03-09 17:56 - added check for paragraph's last line
'''
import re, textwrap
__author__ = 'Denis Barmenkov <denis.barmenkov@gmail.com>'
__source__ = 'http://code.activestate.com/recipes/414870/'
def items_len(l):
return sum([ len(x) for x in l] )
lead_re = re.compile(r'(^\s+)(.*)$')
def align_string(s, width, last_paragraph_line=0):
'''
align string to specified width
'''
# detect and save leading whitespace
m = lead_re.match(s)
if m is None:
left, right, w = '', s, width
else:
left, right, w = m.group(1), m.group(2), width - len(m.group(1))
items = right.split()
# add required space to each words, exclude last item
for i in range(len(items) - 1):
items[i] += ' '
if not last_paragraph_line:
# number of spaces to add
left_count = w - items_len(items)
while left_count > 0 and len(items) > 1:
for i in range(len(items) - 1):
items[i] += ' '
left_count -= 1
if left_count < 1:
break
res = left + ''.join(items)
return res
def align_paragraph(paragraph, width, debug=0):
'''
align paragraph to specified width,
returns list of paragraph lines
'''
lines = list()
if type(paragraph) == type(lines):
lines.extend(paragraph)
elif type(paragraph) == type(''):
lines.append(paragraph)
elif type(paragraph) == type(tuple()):
lines.extend(list(paragraph))
else:
raise TypeError, 'Unsopported paragraph type: %r' % type(paragraph)
flatten_para = ' '.join(lines)
splitted = textwrap.wrap(flatten_para, width)
if debug:
print 'textwrap:\n%s\n' % '\n'.join(splitted)
wrapped = list()
while len(splitted) > 0:
line = splitted.pop(0)
if len(splitted) == 0:
last_paragraph_line = 1
else:
last_paragraph_line = 0
aligned = align_string(line, width, last_paragraph_line)
wrapped.append(aligned)
if debug:
print 'textwrap & align_string:\n%s\n' % '\n'.join(wrapped)
return wrapped
if __name__ == '__main__':
s = 'Contributors whose recipes are used in the book will receive a complimentary copy of the Second Edition. A portion of all royalties will go to the non-profit Python Software Foundation. [Last words]'
align_paragraph(s, width=30, debug=1)
'''
=====================
Script output:
=====================
textwrap:
Contributors whose recipes are
used in the book will receive
a complimentary copy of the
Second Edition. A portion of
all royalties will go to the
non-profit Python Software
Foundation. [Last words]
textwrap & align_string:
Contributors whose recipes are
used in the book will receive
a complimentary copy of the
Second Edition. A portion of
all royalties will go to the
non-profit Python Software
Foundation. [Last words]
'''
@Niols
Copy link
Author

Niols commented Jun 3, 2015

Infos:

Information Value
Author Denis Barmenkov (denis.barmenkov@gmail.com)
Source http://code.activestate.com/recipes/414870/
Python version Python 2.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment