Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Testing
/test/hello2.docx

# Mac / IDE
.DS_Store
.idea
Expand Down
18 changes: 18 additions & 0 deletions src/python_docx_replace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from python_docx_replace.exceptions import EndTagNotFound, InitialTagNotFound, TableIndexNotFound
from python_docx_replace.paragraph import Paragraph
from docx.opc.constants import RELATIONSHIP_TYPE


__all__ = ["docx_replace", "docx_blocks", "docx_remove_table"]

Expand All @@ -26,6 +28,7 @@ def docx_replace(doc, **kwargs: str) -> None:
for p in Paragraph.get_all(doc):
paragraph = Paragraph(p)
paragraph.replace_key(key, str(value))
_replace_in_links(doc, key, str(value))


def docx_blocks(doc: Any, **kwargs: bool) -> None:
Expand Down Expand Up @@ -145,3 +148,18 @@ def _search_for_lost_end_tag(doc: Any, initial: str, end: str) -> None:
paragraph = Paragraph(p)
if paragraph.contains(end):
raise InitialTagNotFound(initial, end)

def _replace_in_links(doc: Any, key: str, value: str):
# Make replacements in hyperlink targets
rel_dicts = []
rel_dicts.append(doc.part.rels)

for section in doc.sections:
rel_dicts.append(section.header.part.rels)
rel_dicts.append(section.footer.part.rels)

for rels in rel_dicts:
for rel_id, rel in rels.items():
if rel.reltype == RELATIONSHIP_TYPE.HYPERLINK:
if key in rel._target:
rel._target = rel._target.replace(key, value)
8 changes: 8 additions & 0 deletions src/python_docx_replace/paragraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ def replace_key(self, key, value) -> None:
self._simple_replace_key(key, value)
if key in self.p.text:
self._complex_replace_key(key, value)
# Make replacements in hyperlink texts
for link in self.p._element.xpath(".//w:hyperlink"):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having this code here, I think it'd be better to move it to a specific method, like self._replace_hyperlinks(key, value)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, makes sense. Done.

try:
inner_run = link.xpath("w:r", namespaces=link.nsmap)[0]
except IndexError:
continue
if key in inner_run.text:
inner_run.text = inner_run.text.replace(key, value)

def replace_block(self, initial, end, keep_block) -> None:
block_handler = BlockHandler(self.p)
Expand Down
2 changes: 1 addition & 1 deletion test/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
def manual_test():
doc = Document("test/hello.docx")

docx_replace(doc, name="Ivan Bicalho")
docx_replace(doc, name="Ivan Bicalho", github_name="ivanbicalho")
docx_blocks(doc, block=True)
docx_remove_table(doc, 0)

Expand Down
Binary file modified test/hello.docx
Binary file not shown.