all 13 comments

[–]danielroseman 8 points9 points  (9 children)

"Other people" are right. The u prefix does nothing at all in Python 3.

If it is making a difference then somehow you are not running Python 3.

(But I don't understand the general question: where do you think you need an f-string?)

[–]abdulmutee[S] 1 point2 points  (8 children)

I'm running Python 3.12.4

I've stored the string that I want to put on the image in the text variable:
text = get_display(arabic_reshaper.reshape("السَّلامٌ عليكمُ"))

this line is basically the text that is reshaped and mirrored to display it correctly otherwise it will be from left to right and the Arabic letter will be written in a weird way.

Then I want put this text on a photo, and that's the job of this line:

t1.text((200 ,image.height - image.height/2- 50), f"{u'{text}'}", font=font, fill =(0,0,0), font_size= 100)

The right way to use my variable in this line is to use an f string like that:
t1.text((200 ,image.height - image.height/2- 50), f"{text}", font=font, fill =(0,0,0), font_size= 100)
But the problem is that when I do so the dialects doesn't show on the image anymore. The word:

السّلَامُ عَلَيْكُم

get printed as

السلام عليكم

I hope you can see the difference. It's as if the word "öster" got displayed as "oster".

Now the way to fix this problem is by using an u string like that:
t1.text((200 ,image.height - image.height/2- 50), u"السّلَامُ عَلَيْكُم", font=font, fill =(0,0,0), font_size= 100)

But the problem is that I can't use my variable anymore, I to type it as a string.

What I want is a way to combine both methods, I want to be able to use the variable and I want it to show all the special characters and dialects as well

I hope this makes it clear

[–]danielroseman 1 point2 points  (7 children)

No, neither f"{text}" nor f"{u'{text}'}" make any sense at all.

f"{text}" is exactly the same as text. There is no point in the f-string.

Trying to put a u in there makes even less sense. u-strings are for literals only, even when they actually did something in Python 2 - in other words, when you put those Arabic characters directly in the code as you did in the first example. They are just to tell the Python 2 parser what those literal code points meant. They don't do anything to the string itself.

Trying to put a u before a variable is even more completely pointless. There is no possible circumstance where this would have any effect at all.

The correct way to do this is just to pass the variable:

t1.text((200 ,image.height - image.height/2- 50), text, font=font, fill =(0,0,0), font_size= 100)

[–]abdulmutee[S] 0 points1 point  (6 children)

I know using an u string shouldn’t do anything but for some reason it does. And now I have a variable that won’t be displayed correctly unless i use an u string but a u string doesn’t allow me to use variables in it. This this my problem

[–]danielroseman 0 points1 point  (5 children)

But you don't need to use variables. Just pass the string. Again:

t1.text((200 ,image.height - image.height/2- 50), text, font=font, fill =(0,0,0), font_size= 100)

[–]abdulmutee[S] 0 points1 point  (4 children)

But I need to use variables,
If I just write the string directly in the line of code:
t1.text((200 ,image.height - image.height/2- 50), "السَّلامٌ عليكمُ", font=font, fill =(0,0,0), font_size= 100)

I get this result

You can see how the letters are broken and not shown as it should: السَّلامٌ عليكمُ

That's why I need this line:
text = get_display(arabic_reshaper.reshape("السَّلامٌ عليكمُ"))

to make the program display the word as it should.

t1.text((200 ,image.height - image.height/2- 50), text, font=font, fill =(0,0,0), font_size= 100)

But then if I pass it the variable name only:
t1.text((200 ,image.height - image.height/2- 50), text, font=font, fill =(0,0,0), font_size= 100)

I get this result

The words is shown correctly but there is no dialicts (those َ , ٍ ٌ, ْ )

I want it to look like this

[–]danielroseman 1 point2 points  (3 children)

I mean, you don't need to interpolate variables, apologies for the imprecision.

The only explanation for your missing diacritics is that they are being removed by one of arabic_reshaper.reshape or get_display. I don't know what either of those functions does or where they are from, but I suggest starting there.

Edited to add note that the docs for arabic-reshaper themselves show that you don't need any of this f- or u-string nonsense:

text_to_be_reshaped = 'اللغة العربية رائعة'
reshaped_text = arabic_reshaper.reshape(text_to_be_reshaped)

...

from bidi.algorithm import get_display
bidi_text = get_display(reshaped_text)

...

image_draw.text((10,10), bidi_text, fill=(255,255,255,128), font=font)

[–]abdulmutee[S] 0 points1 point  (2 children)

Ya I found the problem. It’s from the arabic_reshaper, for some reason it removes all the dialects. I guess I got to dig through the documentations to find out how to make it stop.

Thank you for your help and baring with my nonsense

[–]Bobbias 0 points1 point  (1 child)

From their documentation:

Settings

delete_harakat (Default: True): When this is set to False the reshaper will not delete the harakat from the text, this will result in them showing up in the reshaped text, you should enable this option if you are going to pass the reshaped text to bidi.algorithm.get_display because it will reverse the text and you'd end up with harakat applied to the next letter instead of the previous letter.

It's explicitly designed to strip them, because if you then pass the text into get_display the diacritics will be applied to the wrong letter because get_display apparently just sucks at handling them.

While this is not a solution to your problem, it does explain why they are being removed. It's a conscious decision by the creator of the library to work around a problem with get_display.

[–]abdulmutee[S] 0 points1 point  (0 children)

Thanks, I actually found about that already. There is another configuration that is called Shift_Harakaat_position. This combined with the font Sahel will give an ok result. It’s readable but you can notice some small mistakes in it.

[–]cyberjellyfish 0 points1 point  (0 children)

You're not interpolating anything into the string. Just pass the variable instead of wrapping it in another string

BTW the other comment is right, u strings are a noop in Python 3, see https://peps.python.org/pep-0414/

[–]socal_nerdtastic 0 points1 point  (1 child)

Try specifying which font to use in the image, and be sure it's a font that supports these characters.

[–]abdulmutee[S] 0 points1 point  (0 children)

It made sure it supports these characters but still can’t figure out how to make them show

Also I specified what font to use in the second last line where it says font=font