问题
I have a working docx generator which works fine for European languages, and I'm trying to add complex script support. I found another question with some recipes to try: python-docx add_style with CTL (Complex text layout) language
I managed to get it working so that complex-script text comes out in the correct typeface and size, but I can't get bidirectional (right-to-left) text working. The obvious "x.font.rtl = True" doesn't work, and neither does the spell given in the other post ("lang.set(qn('w:bidi'),'fa-IR')"). I had to take out the line " "rpr.get_or_add_sz()" from his recipe, which left me with an unreadable file, but everything else works without it and I don't think that it's related to this problem.
Here is the style as it appears in the generated document's styles.xml file:
<w:style w:styleId="Hebrew" w:type="paragraph" w:customStyle="1">
<w:name w:val="Hebrew"/>
<w:basedOn w:val="Normal"/>
<w:pPr>
<w:jc w:val="right"/>
</w:pPr>
<w:rPr>
<w:rFonts w:cs="Arial"/>
<w:rtl/>
<w:szCs w:val="24"/>
<w:lang w:bidi="he-IL"/>
</w:rPr>
</w:style>
Can anyone advise me on what to do to get paragraphs in right-to-left languages working?
回答1:
As per the comments above, and with much help from ROAR (thanks, ROAR!) I got everything working.
ROAR's recipe here worked perfectly except that calling rpr.get_or_add_sz() gave me an unreadable .docx file. Leaving it out made everything work and didn't appear to cause any problems. The crucial missing link was to add the following to <w:pPr> in the style:
<w:bidi w:val="1">
<w:jc w:val="both"/>
There is a my_style.get_or_add_pPr() method to get a reference to the <w:pPr> section of the style, and the code is then similar to the code for updating <w:rPr>:
w_nsmap = '{'+ppr.nsmap['w']+'}'
bidi = None
jc = None
for element in ppr:
if element.tag == w_nsmap + 'bidi':
bidi = element
if element.tag == w_nsmap + 'jc':
jc = element
if bidi is None:
bidi = OxmlElement('w:bidi')
if jc is None:
jc = OxmlElement('w:jc')
bidi.set(qn('w:val'),'1')
jc.set(qn('w:val'),'both')
ppr.append(bidi)
ppr.append(jc)
The final thing I needed was to deal with mixed-language text, which I did by breaking the text into multiple runs. The paras of Hebrew text I was dealing with were given the modified style with rtl=True, but I split out any ASCII sequences which started and ended with a letter:
[A-Za-z][\u0020-\u007e]*[A-Aa-z]
into separate runs with rtl=False.
来源:https://stackoverflow.com/questions/55264126/how-to-get-python-docx-working-with-complex-scripts