3

I have a dummy text with numerous lengths.

sample_text = """Nunc tempus metus sem, at posuere nulla volutpat viverra. Sed nec nisl imperdiet, egestas ex et, sodales libero. Suspendisse egestas id dui at aliquet. Nulla a justo neque. Pellentesque non urna iaculis, maximus dolor at, pellentesque eros. Duis mi velit, ornare eu mollis sed, congue eget nisl. Ut suscipit, elit eu mattis vehicula, justo quam vulputate urna, nec tempor augue ligula sed nisl. Phasellus vel augue eu nibh sodales pretium ornare vel felis.Vivamus vitae suscipit orci. """

I am finding a way to justify the text like right alignment. Went through the text wrap docs but it's justified only default left.

import textwrap
wrapper = textwrap.TextWrapper(width=50)
dedented_text = textwrap.dedent(text=sample_text)
print(wrapper.fill(text=dedented_text))

Text wrap provies also many features like shortener, indent etc.

Found another way to justify the text.

str.ljust(s, width[, fillchar])
str.rjust(s, width[, fillchar])
str.center(s, width[, fillchar])

But the above function only works when text len is shorter than width.

Is there any function like above or way to justify the text?

5
  • @JoeFerndz what does docx have to do with this? I believe OP is asking about simple strings... Commented Feb 7, 2021 at 10:37
  • Sorry about the earlier links. Here's a link to SO with similar question. stackoverflow.com/questions/50281190/… Commented Feb 7, 2021 at 10:42
  • I also found this ... stackoverflow.com/questions/17862989/… Commented Feb 7, 2021 at 10:44
  • @JoeFerndz quite similar to the 3rd link but didn't get the right alignment Commented Feb 7, 2021 at 10:53
  • Interesting problem. bookmarked to work on it tomorrow. will see if others have solved it before that. Commented Feb 7, 2021 at 11:08

1 Answer 1

6

Simplistic approach would be:

import re
wrapper = textwrap.TextWrapper(width=50)
dedented_text = textwrap.dedent(text=sample_text)

txt = wrapper.fill(text=dedented_text)
def justify(txt:str, width:int) -> str:
    prev_txt = txt
    while((l:=width-len(txt))>0):
        txt = re.sub(r"(\s+)", r"\1 ", txt, count=l)
        if(txt == prev_txt): break
    return txt.rjust(width)

for l in txt.splitlines():
    print(justify(l, 50))

Few notes:

(1) justify concerns lines, not lines within string - so you should justify text line by line. There's no bulk method AFAIK.

(2) you always justify by stretching spaces - it's just your call which spaces you choose and how do you stretch them - all the examples on the web that I found are different only in terms of the method of stretching spaces they use...

Output:

Nunc  tempus  metus sem, at posuere nulla volutpat
viverra.  Sed  nec  nisl imperdiet, egestas ex et,
sodales  libero.  Suspendisse  egestas  id  dui at
aliquet.  Nulla  a  justo  neque. Pellentesque non
urna iaculis, maximus dolor at, pellentesque eros.
Duis  mi  velit, ornare eu mollis sed, congue eget
nisl.  Ut suscipit, elit eu mattis vehicula, justo
quam  vulputate  urna, nec tempor augue ligula sed
nisl.  Phasellus vel augue eu nibh sodales pretium
ornare  vel  felis.Vivamus  vitae  suscipit  orci.
Sign up to request clarification or add additional context in comments.

2 Comments

Pretty justified code. But I also aforementioned to get right and center alignment. Though got the center alignment but still seeking the right alignment.
Then just replace the last line: print(justify(l, 50)) with print(l.rjust(50)) or center(40) accordingly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.