阿拉伯语文本未正确包装在reportlab的Paragraph中

时间:2013-06-18 10:10:21

标签: python arabic right-to-left reportlab paragraph

假设我有这个阿拉伯语片段:

إذاأخذنابعينالإعتبارطبيعةتقلبالمناخوالمتغيراتالبينيةالسنويةوتلكعلىالمدىالطويلإضافةإلىعدمدقةالقياساتوالحساباتالمتبعة

在英语中,这应该是这样的:“如果我们考虑到气候变率和年际变化的性质以及长期增加的测量和计算的准确度不足...... “。

现在我想把它呈现为Reportlab PDF doc(python):

arabic_text = u'إذا أخذنا بعين الإعتبار طبيعة تقلب المناخ و المتغيرات البينية السنوية و تلك على المدى الطويل إضافة إلى عدم دقة القياسات والحسابات المتبعة'
arabic_text = arabic_reshaper.reshape(arabic_text) # join characters
arabic_text = get_display(arabic_text) # change orientation by using bidi

pdf_file=open('disclaimer.pdf','w')
pdf_doc = SimpleDocTemplate(pdf_file, pagesize=A4)
pdfmetrics.registerFont(TTFont('Arabic-normal', '../fonts/KacstOne.ttf'))
style = ParagraphStyle(name='Normal', fontName='Arabic-normal', fontSize=12, leading=12. * 1.2)
style.alignment=TA_RIGHT
pdf_doc.build([Paragraph(arabic_text, style)])
pdf_file.close()

结果在这里https://www.dropbox.com/s/gdyt6930jlad8id/disclaimer.pdf。您可以看到文本本身是正确且可读的(至少对于Google翻译而言),但未按预期包装RTL脚本。

3 个答案:

答案 0 :(得分:1)

如果您使用this branch of Report lab that adds RTL support

并从代码中删除此行:

arabic_text = get_display(arabic_text) # change orientation by using bidi

您的代码将正常运行

因为已经使用PyFriBiDi解析了分支 正如您所见here

  

来自社区的一些用户尤其是Ury Marshak,Moshe Wagner和Hosam Aly为PyFriBibi与ReportLab合作做出了批量贡献。我们为此开发创建了一个SVN分支,它可以在...

中找到

(该页面上的SVN链接不再有效,所以你应该使用我已经包含的bitbucket链接!)

我已设法运行代码的修改版本并生成正确的结果:

from libs import arabic_reshaper
from bidi.algorithm import get_display
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.pdfbase import pdfmetrics
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_RIGHT
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase.ttfonts import TTFont
arabic_text = u'إذا أخذنا بعين الإعتبار طبيعة تقلب المناخ و المتغيرات البينية السنوية و تلك على المدى الطويل إضافة إلى عدم دقة القياسات والحسابات المتبعة'
arabic_text = arabic_reshaper.reshape(arabic_text) # join characters
# arabic_text = get_display(arabic_text) # change orientation by using bidi

pdf_file=open('disclaimer.pdf','w')
pdf_doc = SimpleDocTemplate(pdf_file, pagesize=A4)
pdfmetrics.registerFont(TTFont('Arabic-normal', 'fonts/misc/KacstOne.ttf'))
style = ParagraphStyle(name='Normal', fontName='Arabic-normal', fontSize=12, leading=12. * 1.2)
style.alignment=TA_RIGHT
pdf_doc.build([Paragraph(arabic_text, style)])
pdf_file.close()

答案 1 :(得分:0)

使用wordwrap模块和<br>标记来分割线条;这并不完美,因为每个段落的顶部都有一个空行,但它是一些用例的简单解决方案

import textwrap
def ShowArabictext(Text):


#style_comment.alignment = TA_RIGHT
wrkText=Text

isArabic=False
isBidi=False

for c in wrkText:
    cat=unicodedata.bidirectional(c)

    if cat=="AL" or cat=="AN":
        isArabic=True
        isBidi=True
        break
    elif cat=="R" or cat=="RLE" or cat=="RLO":
        isBidi=True

if isArabic:

    #wrkText=arabic_table(wrkText)    

    wrkText=textwrap.wrap( wrkText,70)
    wrkTexttemp=[]
    l=u''
    i=0
    for w in wrkText:
        # break each line with html markup allowed in reportlab 
        l=l+u'<br></br>'+arabic_rtlize.process.shape(arabic_reshaper.reshape(w ))

    wrkText=l



if isBidi:
    wrkText=get_display(wrkText)

return [wrkText,isArabic,isBidi]

答案 2 :(得分:0)

使用以下代码。它将正确包装。

import arabic_reshaper
from bidi.algorithm import get_display
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.pdfbase import pdfmetrics
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_RIGHT
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.pdfmetrics import stringWidth
from reportlab.lib.units import inch

def text_wraping(text,aW):
    text_width = stringWidth(text, style.fontName, style.fontSize)
    space_width = stringWidth(' ', style.fontName, style.fontSize)
    if text_width > aW:
        lines = []
        text = arabic_text.split(' ')
        text.reverse()
        line = ''
        for word in text:
            line_width = stringWidth(line, style.fontName, style.fontSize)
            word_width = stringWidth(word, style.fontName, style.fontSize)
            if (line_width < aW) and (line_width + word_width + space_width < aW):
                line += word + ' '
            else:
                line = line.split(' ')
                line.reverse()
                tmp = ' '
                line = tmp.join(line)
                lines.append(line)
                line = word + ' '
        line = line.split(' ')
        line.reverse()
        tmp = ' '
        line = tmp.join(line)
        lines.append(line)
    return(lines)

pdf_doc = SimpleDocTemplate('disclaimer.pdf', pagesize=A4)
pdfmetrics.registerFont(TTFont('Aims', 'Aims.ttf'))
style = ParagraphStyle(name='Normal', fontName='Aims', fontSize=12, leading=12. * 1.2,wordWrap='RTL')
style.alignment=TA_RIGHT
aW = A4[0]-2*inch  # change this line to the specified width for example paragraph width or table width
arabic_text = 'إذا أخذنا بعين الإعتبار طبيعة تقلب المناخ و المتغيرات البينية السنوية و تلك على المدى الطويل إضافة إلى عدم دقة القياسات والحسابات المتبعة'
arabic_text = arabic_reshaper.reshape(arabic_text) # join characters
arabic_text = get_display(arabic_text) # change orientation by using bidi
lines = text_wraping(arabic_text,aW)
elements = []
for line in lines:
    elements.append(Paragraph(line,style))
pdf_doc.build(elements)