Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e6a0320

Browse files
committed
hyperlink: add Hyperlink functionality
1 parent 5886a48 commit e6a0320

File tree

4 files changed

+117
-2
lines changed

4 files changed

+117
-2
lines changed

docs/conf.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@
113113
114114
.. |Run| replace:: :class:`Run`
115115
116+
.. |Hyperlink| replace:: :class:`Hyperlink`
117+
116118
.. |Section| replace:: :class:`.Section`
117119
118120
.. |Sections| replace:: :class:`.Sections`

docx/oxml/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None):
129129
register_element_cls('w:tr', CT_Row)
130130

131131
from docx.oxml.text import (
132-
CT_Br, CT_Jc, CT_P, CT_PPr, CT_R, CT_RPr, CT_Text, CT_Underline
132+
CT_Br, CT_Jc, CT_P, CT_PPr, CT_R, CT_RPr, CT_Text, CT_Underline, CT_Hyperlink
133133
)
134134
register_element_cls('w:b', CT_OnOff)
135135
register_element_cls('w:bCs', CT_OnOff)
@@ -149,6 +149,7 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None):
149149
register_element_cls('w:pPr', CT_PPr)
150150
register_element_cls('w:pStyle', CT_String)
151151
register_element_cls('w:r', CT_R)
152+
register_element_cls('w:hyperlink', CT_Hyperlink)
152153
register_element_cls('w:rPr', CT_RPr)
153154
register_element_cls('w:rStyle', CT_String)
154155
register_element_cls('w:rtl', CT_OnOff)

docx/oxml/text.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from ..enum.text import WD_ALIGN_PARAGRAPH, WD_UNDERLINE
99
from .ns import qn
10-
from .simpletypes import ST_BrClear, ST_BrType
10+
from .simpletypes import ST_BrClear, ST_BrType, ST_RelationshipId
1111
from .xmlchemy import (
1212
BaseOxmlElement, OptionalAttribute, OxmlElement, RequiredAttribute,
1313
ZeroOrMore, ZeroOrOne
@@ -35,6 +35,7 @@ class CT_P(BaseOxmlElement):
3535
"""
3636
pPr = ZeroOrOne('w:pPr')
3737
r = ZeroOrMore('w:r')
38+
hyperlink = ZeroOrMore('w:hyperlink')
3839

3940
def _insert_pPr(self, pPr):
4041
self.insert(0, pPr)
@@ -267,6 +268,58 @@ def underline(self, value):
267268
rPr.underline = value
268269

269270

271+
class CT_Hyperlink(BaseOxmlElement):
272+
"""
273+
``<w:hyperlink>`` element, containing the properties and text for a hyperlink.
274+
275+
The ``<w:hyperlink>`` contains a ``<w:r>`` element which holds all the
276+
visible content. The ``<w:hyperlink>`` has an attribute ``r:id`` which
277+
holds an ID relating a URL in the document's relationships.
278+
"""
279+
r = ZeroOrOne('w:r')
280+
rid = RequiredAttribute('r:id', ST_RelationshipId)
281+
282+
@property
283+
def relationship(self):
284+
"""
285+
String contained in ``r:id`` attribute of <w:hyperlink>. It should
286+
point to a URL in the document's relationships.
287+
"""
288+
val = self.get(qn('r:id'))
289+
return val
290+
291+
@relationship.setter
292+
def relationship(self, rId):
293+
self.set(qn('r:id'), rId)
294+
self.set(qn('w:history'), '1')
295+
296+
@property
297+
def text(self):
298+
"""
299+
A string representing the textual content of this run. Returns the
300+
textual content of this ``<w:hyperlink>``'s ``<w:r>`` element.
301+
"""
302+
text = ''
303+
if self.r is not None:
304+
text = self.r.text
305+
return text
306+
307+
@text.setter
308+
def text(self, text):
309+
"""
310+
Set's the text displayed by the hyperlink.
311+
312+
Clear the ``<w:r>`` element and add a new ``<w:t>`` element containing
313+
*text*. It also adds a 'Hyperlink' style to the``<w:r>`` element.
314+
"""
315+
r = self.get_or_add_r()
316+
r.clear_content()
317+
t = r._add_t(text=text)
318+
if len(text.strip()) < len(text):
319+
t.set(qn('xml:space'), 'preserve')
320+
r.style = 'Hyperlink'
321+
322+
270323
class CT_RPr(BaseOxmlElement):
271324
"""
272325
``<w:rPr>`` element, containing the properties for a run.

docx/text.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from .enum.text import WD_BREAK
1010
from .shared import Parented
11+
from docx.opc.constants import RELATIONSHIP_TYPE as RT
1112

1213

1314
def boolproperty(f):
@@ -80,6 +81,23 @@ def add_run(self, text=None, style=None):
8081
run.style = style
8182
return run
8283

84+
def add_hyperlink(self, text=None, url=None):
85+
"""
86+
Append a run to this paragraph containing *text* and having character
87+
style identified by style ID *style*. *text* can contain tab
88+
(``\\t``) characters, which are converted to the appropriate XML form
89+
for a tab. *text* can also include newline (``\\n``) or carriage
90+
return (``\\r``) characters, each of which is converted to a line
91+
break.
92+
"""
93+
h = self._p.add_hyperlink()
94+
hyperlink = Hyperlink(h, self)
95+
if text:
96+
hyperlink.text = text
97+
if url:
98+
hyperlink.url = url
99+
return hyperlink
100+
83101
@property
84102
def alignment(self):
85103
"""
@@ -479,6 +497,47 @@ def web_hidden(self):
479497
"""
480498
return 'webHidden'
481499

500+
class Hyperlink(Parented):
501+
"""
502+
Proxy object wrapping ``<w:hyperlink>`` element, which in turn contains a
503+
``<w:r>`` element. It has two main properties: The *url* it points to and
504+
the *text* that is shown on the page.
505+
"""
506+
def __init__(self, hyperlink, parent):
507+
super(Hyperlink, self).__init__(parent)
508+
self._hyperlink = hyperlink
509+
510+
@property
511+
def url(self):
512+
"""
513+
Read/write. The relationship ID the Hyperlink points to, or |None| if
514+
it has no directly-applied relationship. Setting this property sets
515+
the The ``r:id`` attribute of the ``<w:rPr>`` element inside the
516+
hyperlink.
517+
"""
518+
part = self.part
519+
rId = self._hyperlink.relationship
520+
url = part.target_ref(rId) if rId else ''
521+
return url
522+
523+
@url.setter
524+
def url(self, url):
525+
part = self.part
526+
rId = part.relate_to(url, RT.HYPERLINK, is_external=True)
527+
self._hyperlink.relationship = rId
528+
529+
@property
530+
def text(self):
531+
"""
532+
Read/write. The String content of the hyperlink that is visible on the
533+
page.
534+
"""
535+
return self._hyperlink.text
536+
537+
@text.setter
538+
def text(self, text):
539+
self._hyperlink.text = text
540+
482541

483542
class Text(object):
484543
"""

0 commit comments

Comments
 (0)