I've got a word document that has an empty 1 by 3 table (or a table with any dimension for that matter) in the header. I want to be able to manipulate the cells of the table using python-docx library. The language of the document is Farsi and naturally all the text in Farsi must start from right to left. Here is how the code looks like:
from docx import Document
document = Document("test.docx")
c = document.sections[0].header.tables[0].rows[0].cells[0]
c.text = "سلام"
document.save("output.docx")
The problem is no matter what kind of trick I use to change the text direction, I can't get it to work. I've tried using the WD_TABLE_DIRECTION.RTL
flag to change the direction of the table or changing the direction of the run using run.font.rtl = True
or even using special unicode characters such as u'\u202B'
and u'\u202C'
to change the direction, but to no success.
I even tried altering the xml related to the header but honestly that's beyond me and all my attempts were unfortunately unsuccessful.
I'm writing this question late at night and I cannot express the amount of hatred I have for my native language right now. So any help would be appreciated.
If you set _Cell.text
using python.docx then that first removes all cell content and then set into the cell a new paragraph containing one new text-run containing the text. But the bidi
rectional setting to make the paragraph's text direction right to left is part of the paragraph properties which get removed while removing the cell content. And the new created paragraph will be a default paragraph without bidi
rectional setting.
So instead of c.text = "سلام"
you should try to find the first paragraph in cell - there always should be one - and clear this paragraph. Then get paragraph properties of that found paragraph and check whether it has w:bidi
set. If not, set it. Then add a new text-run to the paragraph, copy possibly existing run properties from paragraph properties or create new run properties and set w:rtl
to that run properties. Finally set run.text = "سلام"
.
Complete example:
from docx import Document
from copy import copy
from docx.oxml import OxmlElement
document = Document('test_in.docx')
cell = document.sections[0].header.tables[0].rows[0].cells[0]
#c.text = "سلام"
paragraph = cell.paragraphs[0]
paragraph.clear()
ct_ppr = paragraph.paragraph_format._element.pPr
ct_ppr_has_bidi = len(ct_ppr.xpath("./w:bidi")) > 0
if not ct_ppr_has_bidi:
ct_bidi = OxmlElement("w:bidi")
ct_ppr.append(ct_bidi)
run = paragraph.add_run()
ct_ppr_has_rPr = len(ct_ppr.xpath("./w:rPr")) > 0
if ct_ppr_has_rPr:
ct_rpr = copy(ct_ppr.xpath("./w:rPr")[0])
else:
ct_rpr = OxmlElement("w:rPr")
ct_rtl = OxmlElement("w:rtl")
ct_rpr.append(ct_rtl)
run._element.append(ct_rpr)
run.text = "سلام"
document.save('output.docx')