I would like to align-justify a text. For that, I have used Textwrap in order to fit the maximum amount of words per line with a given width. Now, I need to make sure that every single line has occupied the given width (30) by adding white spaces to fill the line with the following criterium: Large gaps go first, then smaller ones ('Lorem--ipsum--dolor--sit-amet,' (2, 2, 2, 1 spaces)).
import textwrap
def justify(text, width):
max_words_per_line = textwrap.wrap(text, width, break_long_words=False)
# I am stuck here, I have tried using the cycle module but I cannot make it work
max_words_per_line =
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Vestibulum sagittis dolor
mauris, at elementum ligula
tempor eget. In quis rhoncus
nunc, at aliquet orci. Fusce
at dolor sit amet felis
suscipit tristique. Nam a
imperdiet tellus. Nulla eu
vestibulum urna. Vivamus
tincidunt suscipit enim, nec
ultrices nisi volutpat ac.
Maecenas sit amet lacinia
arcu, non dictum justo. Donec
sed quam vel risus faucibus
euismod. Suspendisse rhoncus
rhoncus felis at fermentum.
Donec lorem magna, ultricies a
nunc sit amet, blandit
fringilla nunc. In vestibulum
velit ac felis rhoncus
pellentesque. Mauris at tellus
enim. Aliquam eleifend tempus
dapibus. Pellentesque commodo,
nisi sit amet hendrerit
fringilla, ante odio porta
lacus, ut elementum justo
nulla et dolor.
I desire:
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Vestibulum sagittis dolor
mauris, at elementum ligula
tempor eget. In quis rhoncus
nunc, at aliquet orci. Fusce
at dolor sit amet felis
suscipit tristique. Nam a
imperdiet tellus. Nulla eu
vestibulum urna. Vivamus
tincidunt suscipit enim, nec
ultrices nisi volutpat ac.
Maecenas sit amet lacinia
arcu, non dictum justo. Donec
sed quam vel risus faucibus
euismod. Suspendisse rhoncus
rhoncus felis at fermentum.
Donec lorem magna, ultricies a
nunc sit amet, blandit
fringilla nunc. In vestibulum
velit ac felis rhoncus
pellentesque. Mauris at tellus
enim. Aliquam eleifend tempus
dapibus. Pellentesque commodo,
nisi sit amet hendrerit
fringilla, ante odio porta
lacus, ut elementum justo
nulla et dolor.
data = '''Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Vestibulum sagittis dolor
mauris, at elementum ligula
tempor eget. In quis rhoncus
nunc, at aliquet orci. Fusce
at dolor sit amet felis
suscipit tristique. Nam a
imperdiet tellus. Nulla eu
vestibulum urna. Vivamus
tincidunt suscipit enim, nec
ultrices nisi volutpat ac.
Maecenas sit amet lacinia
arcu, non dictum justo. Donec
sed quam vel risus faucibus
euismod. Suspendisse rhoncus
rhoncus felis at fermentum.
Donec lorem magna, ultricies a
nunc sit amet, blandit
fringilla nunc. In vestibulum
velit ac felis rhoncus
pellentesque. Mauris at tellus
enim. Aliquam eleifend tempus
dapibus. Pellentesque commodo,
nisi sit amet hendrerit
fringilla, ante odio porta
lacus, ut elementum justo
nulla et dolor.'''
from itertools import cycle
for line in data.splitlines():
words = line.split()
_l = [[' '] for i in range(len(words)-1)]
spaces = cycle(_l)
for s, i in zip(spaces, range(30-len(line))):
s[-1] += ' '
for w, _l in zip(words, _l):
print(''.join([w, *_l]), end='')
print(words[-1])
Prints:
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Vestibulum sagittis dolor
mauris, at elementum ligula
tempor eget. In quis rhoncus
nunc, at aliquet orci. Fusce
at dolor sit amet felis
suscipit tristique. Nam a
imperdiet tellus. Nulla eu
vestibulum urna. Vivamus
tincidunt suscipit enim, nec
ultrices nisi volutpat ac.
Maecenas sit amet lacinia
arcu, non dictum justo. Donec
sed quam vel risus faucibus
euismod. Suspendisse rhoncus
rhoncus felis at fermentum.
Donec lorem magna, ultricies a
nunc sit amet, blandit
fringilla nunc. In vestibulum
velit ac felis rhoncus
pellentesque. Mauris at tellus
enim. Aliquam eleifend tempus
dapibus. Pellentesque commodo,
nisi sit amet hendrerit
fringilla, ante odio porta
lacus, ut elementum justo
nulla et dolor.
EDIT: If last line doesn't have to be justified, use this:
from itertools import cycle
lines = data.splitlines()
for line in lines[:-1]:
words = line.split()
_l = [[' '] for i in range(len(words)-1)]
spaces = cycle(_l)
for s, i in zip(spaces, range(30-len(line))):
s[-1] += ' '
for w, _l in zip(words, _l):
print(''.join([w, *_l]), end='')
print(words[-1])
print(lines[-1])
Prints:
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Vestibulum sagittis dolor
mauris, at elementum ligula
tempor eget. In quis rhoncus
nunc, at aliquet orci. Fusce
at dolor sit amet felis
suscipit tristique. Nam a
imperdiet tellus. Nulla eu
vestibulum urna. Vivamus
tincidunt suscipit enim, nec
ultrices nisi volutpat ac.
Maecenas sit amet lacinia
arcu, non dictum justo. Donec
sed quam vel risus faucibus
euismod. Suspendisse rhoncus
rhoncus felis at fermentum.
Donec lorem magna, ultricies a
nunc sit amet, blandit
fringilla nunc. In vestibulum
velit ac felis rhoncus
pellentesque. Mauris at tellus
enim. Aliquam eleifend tempus
dapibus. Pellentesque commodo,
nisi sit amet hendrerit
fringilla, ante odio porta
lacus, ut elementum justo
nulla et dolor.