Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docxtpl/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ def colspan(m):
flags=re.DOTALL,
)
cell_xml = re.sub(r"<w:gridSpan[^/]*/>", "", cell_xml, count=1)
# a self-closing <w:tcPr/> would leave the inserted gridSpan outside of it
cell_xml = re.sub(
r"<w:tcPr(\s[^>]*)?/>",
lambda mm: "<w:tcPr%s></w:tcPr>" % (mm.group(1) or ""),
cell_xml,
count=1,
)
return re.sub(
r"(<w:tcPr[^>]*>)",
r'\1<w:gridSpan w:val="{{%s}}"/>' % m.group(2),
Expand All @@ -143,6 +150,13 @@ def cellbg(m):
flags=re.DOTALL,
)
cell_xml = re.sub(r"<w:shd[^/]*/>", "", cell_xml, count=1)
# a self-closing <w:tcPr/> would leave the inserted shd outside of it
cell_xml = re.sub(
r"<w:tcPr(\s[^>]*)?/>",
lambda mm: "<w:tcPr%s></w:tcPr>" % (mm.group(1) or ""),
cell_xml,
count=1,
)
return re.sub(
r"(<w:tcPr[^>]*>)",
r'\1<w:shd w:val="clear" w:color="auto" w:fill="{{%s}}"/>' % m.group(2),
Expand Down
42 changes: 42 additions & 0 deletions tests/cellbg_selfclosing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Regression test for #559: pandoc-produced tables collapse empty cell
# properties to a self-closing <w:tcPr/>, which used to make cellbg and
# colspan insert <w:shd>/<w:gridSpan> as a sibling after it instead of
# inside, so Word silently ignored them. No template file needed, the
# checks work on patch_xml output directly.

import re

from docxtpl import DocxTemplate

tpl = DocxTemplate("dummy.docx")


def patched(body):
return tpl.patch_xml("<w:tbl><w:tr><w:tc>%s</w:tc></w:tr></w:tbl>" % body)


def assert_inside_tcpr(xml, element):
m = re.search(r"<w:tcPr[^/>]*>(.*?)</w:tcPr>", xml, flags=re.DOTALL)
assert m, "no expanded <w:tcPr> pair in: %s" % xml
assert element in m.group(1), "%s not inside <w:tcPr>: %s" % (element, xml)


# self-closing <w:tcPr/> (the #559 case)
xml = patched("<w:tcPr/><w:p><w:r><w:t>{% cellbg color %}x</w:t></w:r></w:p>")
assert_inside_tcpr(xml, "<w:shd ")

xml = patched("<w:tcPr/><w:p><w:r><w:t>{% colspan span %}x</w:t></w:r></w:p>")
assert_inside_tcpr(xml, "<w:gridSpan ")

# self-closing with attributes
xml = patched('<w:tcPr w:dummy="1"/><w:p><w:r><w:t>{% cellbg color %}x</w:t></w:r></w:p>')
assert_inside_tcpr(xml, "<w:shd ")

# already expanded <w:tcPr> keeps working as before
xml = patched(
'<w:tcPr><w:tcW w:w="100"/></w:tcPr><w:p><w:r><w:t>{% cellbg color %}x</w:t></w:r></w:p>'
)
assert_inside_tcpr(xml, "<w:shd ")
assert_inside_tcpr(xml, "<w:tcW ")

print("cellbg_selfclosing ok")