Skip to content

Commit 2a53dac

Browse files
Benjamin-TBenjamin-T
authored andcommitted
hyperlink testing
1 parent d24633b commit 2a53dac

3 files changed

Lines changed: 62 additions & 29 deletions

File tree

docx/oxml/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,13 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None):
206206
register_element_cls('w:tabs', CT_TabStops)
207207
register_element_cls('w:widowControl', CT_OnOff)
208208

209-
from .text.run import CT_Br, CT_R, CT_Text, CT_SimpleField, CT_FldChar
209+
from .text.run import CT_Br, CT_R, CT_Text, CT_SimpleField, CT_FldChar, CT_Hyperlink
210210
register_element_cls('w:br', CT_Br)
211211
register_element_cls('w:r', CT_R)
212212
register_element_cls('w:t', CT_Text)
213213
register_element_cls('w:fldSimple', CT_SimpleField)
214214
register_element_cls('w:fldChar', CT_FldChar)
215-
215+
register_element_cls('w:hyperlink', CT_Hyperlink)
216216

217217
from docx.oxml.bookmark import CT_Bookmark, CT_MarkupRange # noqa
218218
register_element_cls('w:bookmarkEnd', CT_MarkupRange)

docx/oxml/text/run.py

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
from ..ns import qn
88
from ..simpletypes import ST_BrClear, ST_BrType, ST_OnOff, ST_String, ST_FldCharType
99
from ..xmlchemy import (
10-
BaseOxmlElement, OptionalAttribute, ZeroOrMore, ZeroOrOne, RequiredAttribute
10+
BaseOxmlElement,
11+
OptionalAttribute,
12+
ZeroOrMore,
13+
ZeroOrOne,
14+
RequiredAttribute,
1115
)
1216
from docx.oxml import OxmlElement
1317
from docx.enum.fields import WD_FIELDCODE
@@ -17,48 +21,71 @@ class CT_SimpleField(BaseOxmlElement):
1721
"""
1822
`<w:fldSimple>` element, indicating a simple field character.
1923
"""
24+
2025
instr = RequiredAttribute("w:instr", ST_String)
21-
fldLock = OptionalAttribute('w:fldLock', ST_OnOff)
22-
dirty = OptionalAttribute('w:dirty', ST_OnOff)
26+
fldLock = OptionalAttribute("w:fldLock", ST_OnOff)
27+
dirty = OptionalAttribute("w:dirty", ST_OnOff)
2328

2429
def set_field(self, field_name, properties):
2530
if getattr(WD_FIELDCODE, field_name):
26-
self.instr = field_name + ' ' + properties
31+
self.instr = field_name + " " + properties
32+
2733

2834
class CT_FldChar(BaseOxmlElement):
2935
"""
3036
`<w:fldChar>` element, indicating a simple field character.
3137
"""
38+
3239
fldCharType = RequiredAttribute("w:fldCharType", ST_FldCharType)
3340
instrText = RequiredAttribute("w:instrText", ST_String)
34-
fldLock = OptionalAttribute('w:fldLock', ST_OnOff)
35-
dirty = OptionalAttribute('w:dirty', ST_OnOff)
41+
fldLock = OptionalAttribute("w:fldLock", ST_OnOff)
42+
dirty = OptionalAttribute("w:dirty", ST_OnOff)
3643

3744
def set_field(self, codes):
3845
self.instrText = code
3946

47+
48+
class CT_Hyperlink(BaseOxmlElement):
49+
"""`w:hyperlink` element"""
50+
51+
anchor = RequiredAttribute("w:anchor", ST_String)
52+
53+
54+
def set_anchor(self, bookmark):
55+
self.anchor = bookmark
56+
57+
def set_hyperlink_text(self, text):
58+
new_r = OxmlElement('w:r')
59+
new_r.style = "Hyperlink"
60+
new_r.text = text
61+
self.insert(0, new_r)
62+
63+
4064
class CT_Br(BaseOxmlElement):
4165
"""
4266
``<w:br>`` element, indicating a line, page, or column break in a run.
4367
"""
44-
type = OptionalAttribute('w:type', ST_BrType)
45-
clear = OptionalAttribute('w:clear', ST_BrClear)
68+
69+
type = OptionalAttribute("w:type", ST_BrType)
70+
clear = OptionalAttribute("w:clear", ST_BrClear)
4671

4772

4873
class CT_R(BaseOxmlElement):
4974
"""
5075
``<w:r>`` element, containing the properties and text for a run.
5176
"""
77+
5278
bookmarkStart = ZeroOrMore("w:bookmarkStart")
5379
bookmarkEnd = ZeroOrMore("w:bookmarkEnd")
54-
rPr = ZeroOrOne('w:rPr')
55-
t = ZeroOrMore('w:t')
56-
br = ZeroOrMore('w:br')
57-
cr = ZeroOrMore('w:cr')
58-
tab = ZeroOrMore('w:tab')
59-
drawing = ZeroOrMore('w:drawing')
60-
fldsimple = ZeroOrMore('w:fldSimple')
61-
fldChar = ZeroOrMore('w:fldChar')
80+
rPr = ZeroOrOne("w:rPr")
81+
t = ZeroOrMore("w:t")
82+
br = ZeroOrMore("w:br")
83+
cr = ZeroOrMore("w:cr")
84+
tab = ZeroOrMore("w:tab")
85+
drawing = ZeroOrMore("w:drawing")
86+
fldsimple = ZeroOrMore("w:fldSimple")
87+
fldChar = ZeroOrMore("w:fldChar")
88+
hyperlink = ZeroOrMore("w:hyperlink")
6289

6390
def _insert_rPr(self, rPr):
6491
self.insert(0, rPr)
@@ -70,7 +97,7 @@ def add_t(self, text):
7097
"""
7198
t = self._add_t(text=text)
7299
if len(text.strip()) < len(text):
73-
t.set(qn('xml:space'), 'preserve')
100+
t.set(qn("xml:space"), "preserve")
74101
return t
75102

76103
def add_drawing(self, inline_or_anchor):
@@ -117,15 +144,15 @@ def text(self):
117144
child elements like ``<w:tab/>`` translated to their Python
118145
equivalent.
119146
"""
120-
text = ''
147+
text = ""
121148
for child in self:
122-
if child.tag == qn('w:t'):
149+
if child.tag == qn("w:t"):
123150
t_text = child.text
124-
text += t_text if t_text is not None else ''
125-
elif child.tag == qn('w:tab'):
126-
text += '\t'
127-
elif child.tag in (qn('w:br'), qn('w:cr')):
128-
text += '\n'
151+
text += t_text if t_text is not None else ""
152+
elif child.tag == qn("w:tab"):
153+
text += "\t"
154+
elif child.tag in (qn("w:br"), qn("w:cr")):
155+
text += "\n"
129156
return text
130157

131158
@text.setter
@@ -149,6 +176,7 @@ class _RunContentAppender(object):
149176
appended. Likewise a newline or carriage return character ('\n', '\r')
150177
causes a ``<w:cr>`` element to be appended.
151178
"""
179+
152180
def __init__(self, r):
153181
self._r = r
154182
self._bfr = []
@@ -180,17 +208,17 @@ def add_char(self, char):
180208
which must be called at the end of text to ensure any pending
181209
``<w:t>`` element is written.
182210
"""
183-
if char == '\t':
211+
if char == "\t":
184212
self.flush()
185213
self._r.add_tab()
186-
elif char in '\r\n':
214+
elif char in "\r\n":
187215
self.flush()
188216
self._r.add_br()
189217
else:
190218
self._bfr.append(char)
191219

192220
def flush(self):
193-
text = ''.join(self._bfr)
221+
text = "".join(self._bfr)
194222
if text:
195223
self._r.add_t(text)
196224
del self._bfr[:]

docx/text/run.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ def add_field(self, field_name, properties):
3030
fld.set_field(field_name, properties)
3131
return fld
3232

33+
def add_hyperlink(self, bookmark_name):
34+
hyp = self._r.add_hyperlink()
35+
hyp.set_anchor(bookmark_name)
36+
return hyp
37+
3338
def add_break(self, break_type=WD_BREAK.LINE):
3439
"""
3540
Add a break element of *break_type* to this run. *break_type* can

0 commit comments

Comments
 (0)