forked from python-openxml/python-docx
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add feature: Paragraph.add_hyperlink() python-openxml#74
- Loading branch information
Showing
8 changed files
with
333 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
|
||
Hyperlink | ||
========= | ||
|
||
Word allows hyperlinks to be placed in the document or existing objects to be | ||
turned into hyperlinks. | ||
|
||
Hyperlinks can point to a named object or range within the current document or | ||
to an external resource. Hyperlinks can contain multiple runs of text. | ||
|
||
|
||
Candidate protocol | ||
------------------ | ||
|
||
Add a simple hyperlink with text and url: | ||
|
||
>>> hyperlink = paragraph.add_hyperlink(text='Google', url='http://google.com') | ||
>>> hyperlink.text | ||
'Google' | ||
>>> hyperlink.url | ||
'http://google.com' | ||
>>> hyperlink.anchor | ||
None | ||
>>> len(hyperlink.runs) | ||
1 | ||
|
||
Add multiple runs to a hyperlink: | ||
|
||
>>> hyperlink = paragraph.add_hyperlink(url='http://github.com') | ||
>>> hyperlink.add_run('A') | ||
>>> hyperlink.add_run('formatted').italic = True | ||
>>> hyperlink.add_run('link').bold = True | ||
>>> len(hyperlink.runs) | ||
3 | ||
|
||
Add a hyperlink pointing to a named range in the current document: | ||
|
||
>>> hyperlink = paragraph.add_hyperlink(text='Section 1', anchor='section1') | ||
>>> hyperlink.anchor | ||
'section1' | ||
>>> hyperlink.url | ||
None | ||
|
||
Turning an existing object into a hyperlink: | ||
|
||
>>> existing_object = document.add_paragraph('Some text') | ||
>>> hyperlink = existing_object.hyperlink(url='http://google.com') | ||
>>> hyperlink.text | ||
'Some text' | ||
>>> len(hyperlink.runs) | ||
1 | ||
|
||
|
||
Specimen XML | ||
------------ | ||
|
||
.. highlight:: xml | ||
|
||
A simple hyperlink to an external url:: | ||
|
||
<w:hyperlink r:id="rId9"> | ||
<w:r> | ||
<w:rPr> | ||
<w:rStyle w:val="Hyperlink"/> | ||
</w:rPr> | ||
<w:t>Google</w:t> | ||
</w:r> | ||
</w:hyperlink> | ||
|
||
|
||
The relationship for the above url:: | ||
|
||
<Relationships xmlns="…"> | ||
<Relationship Id="rId9" Mode="External" Target=http://google.com /> | ||
</Relationships> | ||
|
||
A hyperlink to an internal named range:: | ||
|
||
<w:hyperlink r:anchor="section1"> | ||
<w:r> | ||
<w:rPr> | ||
<w:rStyle w:val="Hyperlink"/> | ||
</w:rPr> | ||
<w:t>Google</w:t> | ||
</w:r> | ||
</w:hyperlink> | ||
|
||
A hyperlink with multiple runs of text:: | ||
|
||
<w:hyperlink r:id="rId2"> | ||
<w:r> | ||
<w:rPr> | ||
<w:rStyle w:val="Hyperlink"/> | ||
</w:rPr> | ||
<w:t>A</w:t> | ||
</w:r> | ||
<w:r> | ||
<w:rPr> | ||
<w:rStyle w:val="Hyperlink"/> | ||
<w:i/> | ||
</w:rPr> | ||
<w:t xml:space="preserve">formatted</w:t> | ||
</w:r> | ||
<w:r> | ||
<w:rPr> | ||
<w:rStyle w:val="Hyperlink"/> | ||
<w:b/> | ||
</w:rPr> | ||
<w:t xml:space="preserve">link</w:t> | ||
</w:r> | ||
</w:hyperlink> | ||
|
||
|
||
Resources | ||
--------- | ||
|
||
* `Document Members (Word) on MSDN`_ | ||
* `Hyperlink Members (Word) on MSDN`_ | ||
* `Hyperlinks Members (Word) on MSDN`_ | ||
* `Hyperlink Class (OpenXML.Office2010.CustomUI) on MSDN`_ | ||
* `Hyperlink Class (OpenXML.Wordprocessing) on MSDN`_ | ||
|
||
|
||
.. _Document Members (Word) on MSDN: | ||
http://msdn.microsoft.com/en-us/library/office/ff840898.aspx | ||
|
||
.. _Hyperlink Members (Word) on MSDN: | ||
http://msdn.microsoft.com/en-us/library/office/ff195109.aspx | ||
|
||
.. _Hyperlinks Members (Word) on MSDN: | ||
http://msdn.microsoft.com/en-us/library/office/ff192421.aspx | ||
|
||
.. _Hyperlink Class (OpenXML.Office2010.CustomUI) on MSDN: | ||
http://msdn.microsoft.com/en-us/library/documentformat.openxml.office2010.customui.hyperlink.aspx | ||
|
||
.. _Hyperlink Class (OpenXML.Wordprocessing) on MSDN: | ||
http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.hyperlink.aspx | ||
|
||
|
||
MS API | ||
------ | ||
|
||
The Hyperlinks property on Document holds references to hyperlink | ||
objects in the MS API. | ||
|
||
Hyperlinks contain the following properties: | ||
|
||
* Address | ||
* SubAddress | ||
* EmailSubject | ||
* ExtraInfoRequired | ||
* Range (In python-docx this would be the runs inside the hyperlink) | ||
* ScreenTip | ||
* Shape | ||
* Target (where to open the hyperlink. e.g. "_blank", "_left", "_top", "_self", "_parent" etc) | ||
* TextToDisplay | ||
* Type (msoHyperlinkRange, msoHyperlinkShape or msoHyperlinkInlineShape) | ||
|
||
|
||
Spec references | ||
--------------- | ||
|
||
* 17.16.17 hyperlink (Hyperlink) | ||
* 2.3.61 CT_Hyperlink |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,5 @@ Text | |
font-color | ||
underline | ||
run-content | ||
hyperlink | ||
breaks |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# encoding: utf-8 | ||
|
||
""" | ||
Custom element classes related to hyperlinks (CT_Hyperlink). | ||
""" | ||
|
||
from ..ns import qn | ||
from ..simpletypes import ST_RelationshipId | ||
from ..xmlchemy import ( | ||
BaseOxmlElement, RequiredAttribute, ZeroOrMore | ||
) | ||
|
||
|
||
class CT_Hyperlink(BaseOxmlElement): | ||
""" | ||
``<w:hyperlink>`` element, containing the properties and text for a hyperlink. | ||
The ``<w:hyperlink>`` contains a ``<w:r>`` element which holds all the | ||
visible content. The ``<w:hyperlink>`` has an attribute ``r:id`` which | ||
holds an ID relating a URL in the document's relationships. | ||
""" | ||
r = ZeroOrMore('w:r') | ||
rid = RequiredAttribute('r:id', ST_RelationshipId) | ||
|
||
@property | ||
def relationship(self): | ||
""" | ||
String contained in ``r:id`` attribute of <w:hyperlink>. It should | ||
point to a URL in the document's relationships. | ||
""" | ||
val = self.get(qn('r:id')) | ||
return val | ||
|
||
@relationship.setter | ||
def relationship(self, rId): | ||
self.set(qn('r:id'), rId) | ||
self.set(qn('w:history'), '1') | ||
|
||
def clear_content(self): | ||
""" | ||
Remove all child r elements | ||
""" | ||
r_to_rm = [] | ||
for child in self[:]: | ||
if child.tag == qn('w:r'): | ||
r_to_rm.append(child) | ||
for r in r_to_rm: | ||
self.remove(r) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# encoding: utf-8 | ||
|
||
""" | ||
Hyperlink proxy objects. | ||
""" | ||
|
||
from __future__ import ( | ||
absolute_import, division, print_function, unicode_literals | ||
) | ||
from .run import Run | ||
from ..shared import Parented | ||
from docx.opc.constants import RELATIONSHIP_TYPE as RT | ||
|
||
|
||
class Hyperlink(Parented): | ||
""" | ||
Proxy object wrapping ``<w:hyperlink>`` element, which in turn contains a | ||
``<w:r>`` element. It has two main properties: The *url* it points to and | ||
the *text* that is shown on the page. | ||
""" | ||
def __init__(self, hyperlink, parent): | ||
super(Hyperlink, self).__init__(parent) | ||
self._hyperlink = self.element = hyperlink | ||
|
||
@property | ||
def url(self): | ||
""" | ||
Read/write. The relationship ID the Hyperlink points to, or |None| if | ||
it has no directly-applied relationship. Setting this property sets | ||
the The ``r:id`` attribute of the ``<w:rPr>`` element inside the | ||
hyperlink. | ||
""" | ||
part = self.part | ||
rId = self._hyperlink.relationship | ||
url = part.target_ref(rId) if rId else '' | ||
return url | ||
|
||
@url.setter | ||
def url(self, url): | ||
part = self.part | ||
rId = part.relate_to(url, RT.HYPERLINK, is_external=True) | ||
self._hyperlink.relationship = rId | ||
|
||
@property | ||
def runs(self): | ||
""" | ||
Sequence of |Run| instances corresponding to the <w:r> elements in | ||
this hyperlink. | ||
""" | ||
return [Run(r, self) for r in self._hyperlink.r_lst] | ||
|
||
def add_run(self, text=None, style=None): | ||
""" | ||
Append a run to this hyperlink containing *text* and having character | ||
style identified by style ID *style*. *text* can contain tab | ||
(``\\t``) characters, which are converted to the appropriate XML form | ||
for a tab. *text* can also include newline (``\\n``) or carriage | ||
return (``\\r``) characters, each of which is converted to a line | ||
break. | ||
""" | ||
r = self._hyperlink.add_r() | ||
run = Run(r, self) | ||
if text: | ||
run.text = text | ||
if style: | ||
run.style = style | ||
return run | ||
|
||
@property | ||
def text(self): | ||
text = '' | ||
for run in self.runs: | ||
text += run.text | ||
return text | ||
|
||
@text.setter | ||
def text(self, text): | ||
self._hyperlink.clear_content() | ||
self.add_run(text) | ||
|
||
|
||
class Text(object): | ||
""" | ||
Proxy object wrapping ``<w:t>`` element. | ||
""" | ||
def __init__(self, t_elm): | ||
super(Text, self).__init__() | ||
self._t = t_elm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters