8000 hlink: add Hyperlink.runs · python-openxml/python-docx@01061a8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 01061a8

Browse files
committed
hlink: add Hyperlink.runs
1 parent d0499b9 commit 01061a8

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

features/hlk-props.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ Feature: Access hyperlink properties
1919
| one | True |
2020

2121

22-
@wip
2322
Scenario Outline: Hyperlink.runs contains Run for each run in hyperlink
2423
Given a hyperlink having <zero-or-more> runs
2524
Then hyperlink.runs has length <value>

src/docx/text/hyperlink.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77

88
from __future__ import annotations
99

10+
from typing import List
11+
1012
from docx import types as t
1113
from docx.oxml.text.hyperlink import CT_Hyperlink
1214
from docx.shared import Parented
15+
from docx.text.run import Run
1316

1417

1518
class Hyperlink(Parented):
@@ -46,3 +49,14 @@ def contains_page_break(self) -> bool:
4649
rendered page breaks are present.
4750
"""
4851
return bool(self._hyperlink.lastRenderedPageBreaks)
52+
53+
@property
54+
def runs(self) -> List[Run]:
55+
"""List of |Run| instances in this hyperlink.
56+
57+
Together these define the visible text of the hyperlink. The text of a hyperlink
58+
is typically contained in a single run will be broken into multiple runs if for
59+
example part of the hyperlink is bold or the text was changed after the document
60+
was saved.
61+
"""
62+
return [Run(r, self) for r in self._hyperlink.r_lst]

tests/text/test_hyperlink.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,29 @@ def it_knows_whether_it_contains_a_page_break(
4242

4343
assert hyperlink.contains_page_break is expected_value
4444

45+
@pytest.mark.parametrize(
46+
("hlink_cxml", "count"),
47+
[
48+
("w:hyperlink", 0),
49+
("w:hyperlink/w:r", 1),
50+
("w:hyperlink/(w:r,w:r)", 2),
51+
("w:hyperlink/(w:r,w:lastRenderedPageBreak)", 1),
52+
("w:hyperlink/(w:lastRenderedPageBreak,w:r)", 1),
53+
("w:hyperlink/(w:r,w:lastRenderedPageBreak,w:r)", 2),
54+
],
55+
)
56+
def it_provides_access_to_the_runs_it_contains(
57+
self, hlink_cxml: str, count: int, fake_parent: t.StoryChild
58+
):
59+
hlink = cast(CT_Hyperlink, element(hlink_cxml))
60+
hyperlink = Hyperlink(hlink, fake_parent)
61+
62+
runs = hyperlink.runs
63+
64+
actual = [type(item).__name__ for item in runs]
65+
expected = ["Run" for _ in range(count)]
66+
assert actual == expected, f"expected: {expected}, got: {actual}"
67+
4568
# -- fixtures --------------------------------------------------------------------
4669

4770
@pytest.fixture

0 commit comments

Comments
 (0)
0