Search code examples
pythonarabicbidi

how to fix the reversed Lines when using arabic-reshaper and python-bidi (in multiple lines situation)?


When I am using arabic-reshaper and python-bidi I faced a bad result that the lines start presenting from the last one.


Solution

  • I made a function to round on this problem since there is no way to solve it in another way, bidi is reversing the characters to put the first at the end and so on, that's because the Arabic language starts from right to left and that way bidi will fake the result to appear in the right shape, but whene the text has to go into more than one line that will be wrong to present the first word at the end! so I have to let it do that then I have to reverse the result as reversed lines this time depending on how many words the line could contain, I am calculating that through passing two arguments, w_w for the width of the widget (or the other place) where the text will appear and (f_w) which means the character width of the used font.

    Then after cumulating each line, I reverse the line presentation, that's it! and here is the function I made:

    import arabic_reshaper
    import bidi.algorithm
        
    def getAR(arWord, w_w=0, f_w=0):
        arWord = arWord.strip()
        if len(arWord) <= 0: return ''
        startList0 = bidi.algorithm.get_display(arabic_reshaper.reshape(arWord))
        if (not w_w) or (not f_w):
            return startList0
        else:
            # return startList0
            startList = startList0.split(' ')[::-1]
            if len(startList) == 0: return ''
            if len(startList) == 1: return str(startList[0])
            n = floor( w_w / f_w )
            for i in startList:
                if len(i) > n: return startList0
            tempS = ''
            resultList = []
            for i in range(0, len(startList)):
                if (tempS != ''): tempS = ' ' + tempS
                if (len(tempS) + (len(startList[i])) > n):
                    tempS = tempS + "\n"
                    resultList.append(tempS)
                    tempS = startList[i]
                else:
                    tempS = startList[i] + tempS
                    if i == (len(startList)-1):
                        resultList.append(tempS)
            return ''.join(resultList)
    

    you will use it like this :

    w_w = ... # calculat it yourself, the width of where you will put the text.
    f_w = ... # calculat it yourself, the width of the character in the font you are using. 
    paragraph = "...  ..."
    widget.text = getAr(paragraph, w_w=w_w, f_w=f_w)
    

    enter image description here