Created
June 3, 2013 20:36
-
-
Save gavinwahl/5701185 to your computer and use it in GitHub Desktop.
Splits up a string into pages of a maximum length. Includes pages numbers. Tries not to split in the middle of a word. Good for SMS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from math import ceil | |
def split_up(s, length=160): | |
""" | |
Splits the string s into pages of no longer than length. Includes | |
pages numbers. Tries not to split in the middle of a word. | |
>>> split_up("abc", 5) | |
['abc'] | |
>>> split_up("abcdef", 5) | |
['a 1/6', 'b 2/6', 'c 3/6', 'd 4/6', 'e 5/6', 'f 6/6'] | |
>>> split_up("%s %s" % ("a" * 150, "b" * 150), 160) # doctest: +ELLIPSIS | |
['aaa...aaa 1/2', 'bbb...bbb 2/2'] | |
>>> split_up("a" * 160) == ["a" * 160] | |
True | |
>>> split_up("a" * 161) # doctest: +ELLIPSIS | |
['aaa...aaa 1/2', 'aaaaa 2/2'] | |
""" | |
if len(s) <= length: | |
return [s] | |
length -= 4 # correct for the length of the page number, len(' 1/3') == 4 | |
total_pages = int(ceil(len(s)/float(length))) | |
assert total_pages < 10, 'only a single digit will work' | |
words = s.split() | |
words.reverse() | |
pages = [] | |
for i in range(total_pages): | |
page = [] | |
needed = length | |
while needed and words: | |
word = words.pop() | |
if len(word) > needed: | |
if page: | |
# Put the word back, it'll go on the next page. | |
words.append(word) | |
break | |
else: | |
# There is no choice but to split a word. go ahead | |
# and split the word. Put the extra characters we | |
# couldn't use back into consideration for the next | |
# page. | |
extra = word[needed:] | |
word = word[:needed] | |
words.append(extra) | |
page.append(word) | |
needed -= len(word) | |
page_num = i + 1 # one-based page numbers | |
pages.append('%s %s/%s' % (' '.join(page), page_num, total_pages)) | |
return pages |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment