Skip to content

Commit eb310ff

Browse files
committed
Replace in link text and link target
Replacements are being made in text and target of hyperlinks, including in header and footer.
1 parent cb643f0 commit eb310ff

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

src/python_docx_replace/__init__.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from python_docx_replace.exceptions import EndTagNotFound, InitialTagNotFound, TableIndexNotFound
44
from python_docx_replace.paragraph import Paragraph
5+
from docx.opc.constants import RELATIONSHIP_TYPE
6+
57

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

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

3033

3134
def docx_blocks(doc: Any, **kwargs: bool) -> None:
@@ -145,3 +148,18 @@ def _search_for_lost_end_tag(doc: Any, initial: str, end: str) -> None:
145148
paragraph = Paragraph(p)
146149
if paragraph.contains(end):
147150
raise InitialTagNotFound(initial, end)
151+
152+
def _replace_in_links(doc: Any, key: str, value: str):
153+
# Make replacements in hyperlink targets
154+
rel_dicts = []
155+
rel_dicts.append(doc.part.rels)
156+
157+
for section in doc.sections:
158+
rel_dicts.append(section.header.part.rels)
159+
rel_dicts.append(section.footer.part.rels)
160+
161+
for rels in rel_dicts:
162+
for rel_id, rel in rels.items():
163+
if rel.reltype == RELATIONSHIP_TYPE.HYPERLINK:
164+
if key in rel._target:
165+
rel._target = rel._target.replace(key, value)

src/python_docx_replace/paragraph.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ def replace_key(self, key, value) -> None:
4949
self._simple_replace_key(key, value)
5050
if key in self.p.text:
5151
self._complex_replace_key(key, value)
52+
# Make replacements in hyperlink texts
53+
for link in self.p._element.xpath(".//w:hyperlink"):
54+
try:
55+
inner_run = link.xpath("w:r", namespaces=link.nsmap)[0]
56+
except IndexError:
57+
continue
58+
if key in inner_run.text:
59+
inner_run.text = inner_run.text.replace(key, value)
5260

5361
def replace_block(self, initial, end, keep_block) -> None:
5462
block_handler = BlockHandler(self.p)

0 commit comments

Comments
 (0)