Skip to content

Commit b35d24c

Browse files
committed
BugFix in AdvReplace
Fixed a bug in AdvReplace that could lead to semantically unvalid Open XML documents. Tags are now appended inside the parent element when replacing with a/many etree object/s
1 parent 7cd75de commit b35d24c

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

docx.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,24 @@ def clean(document):
498498

499499
return newdocument
500500

501+
def findTypeParent(element, tag):
502+
""" Finds fist parent of element of the given type
503+
504+
@param object element: etree element
505+
@param string the tag parent to search for
506+
507+
@return object element: the found parent or None when not found
508+
"""
509+
510+
p = element
511+
while True:
512+
p = p.getparent()
513+
if p.tag == tag:
514+
return p
515+
516+
# Not found
517+
return None
518+
501519
def advReplace(document,search,replace,bs=3):
502520
'''Replace all occurences of string with a different string, return updated document
503521
@@ -606,15 +624,19 @@ def advReplace(document,search,replace,bs=3):
606624
# The match occurred in THIS element. Puth in the
607625
# whole replaced text
608626
if isinstance(replace, etree._Element):
609-
# If I'm replacing with XML, clear the text in the
610-
# tag and append the element
611-
searchels[i].text = re.sub(search,'',txtsearch)
612-
searchels[i].append(replace)
613-
elif type(replace) == list or type(replace) == tuple:
627+
# Convert to a list and process it later
628+
replace = [ replace, ]
629+
if type(replace) == list or type(replace) == tuple:
614630
# I'm replacing with a list of etree elements
631+
# clear the text in the tag and append the element after the
632+
# parent paragraph
633+
# (because t elements cannot have childs)
634+
p = findTypeParent(searchels[i], '{%s}p' % nsprefixes['w'])
615635
searchels[i].text = re.sub(search,'',txtsearch)
636+
insindex = p.getparent().index(p) + 1
616637
for r in replace:
617-
searchels[i].append(r)
638+
p.getparent().insert(insindex, r)
639+
insindex += 1
618640
else:
619641
# Replacing with pure text
620642
searchels[i].text = re.sub(search,replace,txtsearch)

0 commit comments

Comments
 (0)