[reportlab-users] Hebrew Support Patch

Moshe Wagner moshe.wagner at gmail.com
Thu Jun 4 16:07:39 EDT 2009


After using the code I've written some more, I found a few bugs.
So this should be the code for - paragraph.h, in the 'wrap' function:

Still isn't written so well, but should work better:
######################
# Hebrew text patch, Moshe Wagner, June 2009
# <moshe.wagner at gmail.com>


#This code fixes paragraphs with RTL text

# It does it by flipping each line seperatly.
# (Depending on the type of the line)

# If fribidi cant be imported, it does nothing

try:
import pyfribidi

for i in range(len(blPara.lines)):
if blPara.lines[i].__class__.__name__ == FragLine.__name__ \
or blPara.lines[i].__class__.__name__ == ParaLines.__name__:
for j in range(len(blPara.lines[i].words)):
"""When the line is a FragLine or ParaLines, It's
text attribute is flipped.
Then, the order of the words is flipped too,
So that 2 word parts on the same line
will be in the right order """

s = blPara.lines[i].words[j].text
s = pyfribidi.log2vis (s, base_direction = pyfribidi.ON)
blPara.lines[i].words[j].text = s

if len(blPara.lines[i].words) % 2 == 0:
half = int(len(blPara.lines[i].words)/2)
else:
half = int((len(blPara.lines[i].words)+1)/2)

for j in range(half):
t = blPara.lines[i].words[j]
blPara.lines[i].words[j] =
blPara.lines[i].words[len(blPara.lines[i].words)-j-1]

blPara.lines[i].words[len(blPara.lines[i].words)-j-1] = t

elif type(blPara.lines[i]).__name__ == 'tuple':
"""When the line is just a tuple whose second value is the text,
since I coulden't directly change it's value,
it's done by merging the words, flipping them,
and re-entering them one
by one to the second attribute """

s = ""
for j in range(len(blPara.lines[i][1])):
s = s + self.blPara.lines[i][1][j] + " "

while len(blPara.lines[i][1]) > 0:
self.blPara.lines[i][1].pop(0)

s = pyfribidi.log2vis (s, base_direction = pyfribidi.ON)
splits = s.split()

#print splits

for j in range(len(splits)):
self.blPara.lines[i][1].append(splits[j])
else:
print blPara.lines[i].__class__.__name__
#print self.blPara.lines[i][1][1:]
except ImportError:
print "Fribidi module not found; You will not have rtl support for
this paragraph"
######################


On Thu, Jun 4, 2009 at 12:05 AM, Moshe Wagner <moshe.wagner at gmail.com> wrote:

> Hello,

>

> While trying to use reportlab with Hebrew text, I noticed Hebrew isn't

> really supported (The text appears mirrored).

>

> In this list's archive I saw a post saying I should use

> "pyfribidi.log2vis" on my text.

>

> That worked for single lines, but it made paragraphs start from the

> bottom up (as the text really goes from the top left down, flipping it

> makes it seem like it starts at bottom right going up).

>

>

> So I've added, (to reportlab_2_3),  a few lines to 'paragraph.py',

> making it visualise every line after the text has been split up,

> rather than doing that before.

> It seemed to work well, besides a minor issue that when

> full_justified,  the last line of text is on the left, which is what

> should happen for LTR text, but not for RTL.

>

> The code is ignored if pyfribidi isn't installed, but anyway, it

> shouldn't affect any LTR text.

>

> I'm not a great programmer, and neither do I know python or reportlab

> very well, so I can't promise the code is so great, or that it covers

> all cases.

>

> Anyway, here's what I added:

>

> -> In "paragraph.h", in the "wrap" function, right after calling

> "self.breakLine":

> ( the code I ad was version 2_3):

>

> ######################

> # Hebrew text patch, Moshe Wagner, June 2009

> # <moshe.wagner at gmail.com>

>

>

> #This code fixes paragraphs with RTL text

>

> # It does it by joining all the words of each line, flips them with pyfribidi

> #(if needed), then splits them again, and re enters them to the paragraph's text

>

> #If fribidi cant be imported, it does nothing

>

> try:

>        import pyfribidi

>

>        for i in range(len(blPara.lines)):

>                s = ""

>                for j in range(len(blPara.lines[i][1])):

>                        #print self.blPara.lines[i][1][j]

>                        s = s + self.blPara.lines[i][1][j] + " "

>

>                while len(blPara.lines[i][1]) > 0:

>                        self.blPara.lines[i][1].pop(0)

>

>                s = pyfribidi.log2vis (s, base_direction = pyfribidi.ON)

>                splits = s.split()

>

>                #print splits

>

>                for j in range(len(splits)):

>                        self.blPara.lines[i][1].append(splits[j])

>                #print self.blPara.lines[i][1][1:]

> except ImportError:

>        print "Fribidi module not found; You will not have rtl support for

> this paragraph"

> ######################

>

>

> -> And in "canvas.py", in the "drawString" function, right at it's begining:

> ######################

> # Hebrew text patch, Moshe Wagner, June 2009

> # <moshe.wagner at gmail.com>

>

> # Flips the given text with pyfribidi, if it's needed (i.e. Hebrew or Arabic)

> # If it could not be imported, it does nothing

> try:

>        import pyfribidi

>

>        text = pyfribidi.log2vis(text, base_direction = pyfribidi.ON)

>

> except ImportError:

>        print "Fribidi module not found; You will not have rtl support for this line"

> #####################

>

>

> I'd be very glad if you could merge this into the code, no need to

> keep any reference to me.

>

> Thanks,

> Moshe

>



More information about the reportlab-users mailing list