ps-python-pptx 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pptx/__init__.py +84 -0
- pptx/action.py +270 -0
- pptx/api.py +49 -0
- pptx/chart/__init__.py +0 -0
- pptx/chart/axis.py +523 -0
- pptx/chart/category.py +200 -0
- pptx/chart/chart.py +280 -0
- pptx/chart/data.py +864 -0
- pptx/chart/datalabel.py +288 -0
- pptx/chart/legend.py +79 -0
- pptx/chart/marker.py +70 -0
- pptx/chart/plot.py +412 -0
- pptx/chart/point.py +101 -0
- pptx/chart/series.py +258 -0
- pptx/chart/xlsx.py +272 -0
- pptx/chart/xmlwriter.py +1840 -0
- pptx/dml/__init__.py +0 -0
- pptx/dml/chtfmt.py +40 -0
- pptx/dml/color.py +301 -0
- pptx/dml/effect.py +41 -0
- pptx/dml/fill.py +468 -0
- pptx/dml/line.py +100 -0
- pptx/enum/__init__.py +0 -0
- pptx/enum/action.py +71 -0
- pptx/enum/base.py +175 -0
- pptx/enum/chart.py +492 -0
- pptx/enum/dml.py +405 -0
- pptx/enum/lang.py +685 -0
- pptx/enum/shapes.py +1029 -0
- pptx/enum/text.py +371 -0
- pptx/exc.py +23 -0
- pptx/media.py +197 -0
- pptx/opc/__init__.py +0 -0
- pptx/opc/constants.py +331 -0
- pptx/opc/oxml.py +188 -0
- pptx/opc/package.py +762 -0
- pptx/opc/packuri.py +109 -0
- pptx/opc/serialized.py +296 -0
- pptx/opc/shared.py +20 -0
- pptx/opc/spec.py +44 -0
- pptx/oxml/__init__.py +492 -0
- pptx/oxml/action.py +53 -0
- pptx/oxml/chart/__init__.py +0 -0
- pptx/oxml/chart/axis.py +297 -0
- pptx/oxml/chart/chart.py +282 -0
- pptx/oxml/chart/datalabel.py +252 -0
- pptx/oxml/chart/legend.py +72 -0
- pptx/oxml/chart/marker.py +61 -0
- pptx/oxml/chart/plot.py +345 -0
- pptx/oxml/chart/series.py +254 -0
- pptx/oxml/chart/shared.py +219 -0
- pptx/oxml/coreprops.py +288 -0
- pptx/oxml/dml/__init__.py +0 -0
- pptx/oxml/dml/color.py +111 -0
- pptx/oxml/dml/fill.py +197 -0
- pptx/oxml/dml/line.py +12 -0
- pptx/oxml/ns.py +129 -0
- pptx/oxml/presentation.py +130 -0
- pptx/oxml/shapes/__init__.py +19 -0
- pptx/oxml/shapes/autoshape.py +455 -0
- pptx/oxml/shapes/connector.py +107 -0
- pptx/oxml/shapes/graphfrm.py +342 -0
- pptx/oxml/shapes/groupshape.py +280 -0
- pptx/oxml/shapes/picture.py +270 -0
- pptx/oxml/shapes/shared.py +523 -0
- pptx/oxml/simpletypes.py +740 -0
- pptx/oxml/slide.py +347 -0
- pptx/oxml/table.py +588 -0
- pptx/oxml/text.py +748 -0
- pptx/oxml/theme.py +29 -0
- pptx/oxml/xmlchemy.py +717 -0
- pptx/package.py +222 -0
- pptx/parts/__init__.py +0 -0
- pptx/parts/chart.py +95 -0
- pptx/parts/coreprops.py +167 -0
- pptx/parts/embeddedpackage.py +93 -0
- pptx/parts/image.py +275 -0
- pptx/parts/media.py +37 -0
- pptx/parts/presentation.py +126 -0
- pptx/parts/slide.py +297 -0
- pptx/parts/theme.py +13 -0
- pptx/presentation.py +113 -0
- pptx/py.typed +0 -0
- pptx/shapes/__init__.py +26 -0
- pptx/shapes/autoshape.py +355 -0
- pptx/shapes/base.py +293 -0
- pptx/shapes/connector.py +297 -0
- pptx/shapes/freeform.py +337 -0
- pptx/shapes/graphfrm.py +166 -0
- pptx/shapes/group.py +69 -0
- pptx/shapes/picture.py +203 -0
- pptx/shapes/placeholder.py +407 -0
- pptx/shapes/shapetree.py +1190 -0
- pptx/shared.py +82 -0
- pptx/slide.py +577 -0
- pptx/spec.py +632 -0
- pptx/table.py +520 -0
- pptx/templates/default.pptx +0 -0
- pptx/templates/docx-icon.emf +0 -0
- pptx/templates/generic-icon.emf +0 -0
- pptx/templates/notes.xml +23 -0
- pptx/templates/notesMaster.xml +352 -0
- pptx/templates/pptx-icon.emf +0 -0
- pptx/templates/theme.xml +321 -0
- pptx/templates/xlsx-icon.emf +0 -0
- pptx/text/__init__.py +0 -0
- pptx/text/fonts.py +399 -0
- pptx/text/layout.py +325 -0
- pptx/text/text.py +770 -0
- pptx/theme.py +135 -0
- pptx/types.py +36 -0
- pptx/util.py +284 -0
- ps_python_pptx-1.1.0.dist-info/METADATA +75 -0
- ps_python_pptx-1.1.0.dist-info/RECORD +117 -0
- ps_python_pptx-1.1.0.dist-info/WHEEL +5 -0
- ps_python_pptx-1.1.0.dist-info/licenses/LICENSE +20 -0
- ps_python_pptx-1.1.0.dist-info/top_level.txt +1 -0
pptx/__init__.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Initialization module for python-pptx package."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
import pptx.exc as exceptions
|
|
9
|
+
from pptx.api import Presentation
|
|
10
|
+
from pptx.opc.constants import CONTENT_TYPE as CT
|
|
11
|
+
from pptx.opc.package import PartFactory
|
|
12
|
+
from pptx.parts.chart import ChartPart
|
|
13
|
+
from pptx.parts.coreprops import CorePropertiesPart
|
|
14
|
+
from pptx.parts.image import ImagePart
|
|
15
|
+
from pptx.parts.media import MediaPart
|
|
16
|
+
from pptx.parts.theme import ThemePart
|
|
17
|
+
from pptx.parts.presentation import PresentationPart
|
|
18
|
+
from pptx.parts.slide import (
|
|
19
|
+
NotesMasterPart,
|
|
20
|
+
NotesSlidePart,
|
|
21
|
+
SlideLayoutPart,
|
|
22
|
+
SlideMasterPart,
|
|
23
|
+
SlidePart,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from pptx.opc.package import Part
|
|
28
|
+
|
|
29
|
+
__version__ = "1.1.0"
|
|
30
|
+
|
|
31
|
+
sys.modules["pptx.exceptions"] = exceptions
|
|
32
|
+
del sys
|
|
33
|
+
|
|
34
|
+
__all__ = ["Presentation"]
|
|
35
|
+
|
|
36
|
+
content_type_to_part_class_map: dict[str, type[Part]] = {
|
|
37
|
+
CT.PML_PRESENTATION_MAIN: PresentationPart,
|
|
38
|
+
CT.PML_PRES_MACRO_MAIN: PresentationPart,
|
|
39
|
+
CT.PML_TEMPLATE_MAIN: PresentationPart,
|
|
40
|
+
CT.PML_SLIDESHOW_MAIN: PresentationPart,
|
|
41
|
+
CT.OPC_CORE_PROPERTIES: CorePropertiesPart,
|
|
42
|
+
CT.PML_NOTES_MASTER: NotesMasterPart,
|
|
43
|
+
CT.PML_NOTES_SLIDE: NotesSlidePart,
|
|
44
|
+
CT.PML_SLIDE: SlidePart,
|
|
45
|
+
CT.PML_SLIDE_LAYOUT: SlideLayoutPart,
|
|
46
|
+
CT.PML_SLIDE_MASTER: SlideMasterPart,
|
|
47
|
+
CT.DML_CHART: ChartPart,
|
|
48
|
+
CT.OFC_THEME: ThemePart,
|
|
49
|
+
CT.BMP: ImagePart,
|
|
50
|
+
CT.GIF: ImagePart,
|
|
51
|
+
CT.JPEG: ImagePart,
|
|
52
|
+
CT.MS_PHOTO: ImagePart,
|
|
53
|
+
CT.PNG: ImagePart,
|
|
54
|
+
CT.TIFF: ImagePart,
|
|
55
|
+
CT.X_EMF: ImagePart,
|
|
56
|
+
CT.X_WMF: ImagePart,
|
|
57
|
+
CT.ASF: MediaPart,
|
|
58
|
+
CT.AVI: MediaPart,
|
|
59
|
+
CT.MOV: MediaPart,
|
|
60
|
+
CT.MP4: MediaPart,
|
|
61
|
+
CT.MPG: MediaPart,
|
|
62
|
+
CT.MS_VIDEO: MediaPart,
|
|
63
|
+
CT.SWF: MediaPart,
|
|
64
|
+
CT.VIDEO: MediaPart,
|
|
65
|
+
CT.WMV: MediaPart,
|
|
66
|
+
CT.X_MS_VIDEO: MediaPart,
|
|
67
|
+
# -- accommodate "image/jpg" as an alias for "image/jpeg" --
|
|
68
|
+
"image/jpg": ImagePart,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
PartFactory.part_type_for.update(content_type_to_part_class_map)
|
|
72
|
+
|
|
73
|
+
del (
|
|
74
|
+
ChartPart,
|
|
75
|
+
CorePropertiesPart,
|
|
76
|
+
ImagePart,
|
|
77
|
+
MediaPart,
|
|
78
|
+
SlidePart,
|
|
79
|
+
SlideLayoutPart,
|
|
80
|
+
SlideMasterPart,
|
|
81
|
+
PresentationPart,
|
|
82
|
+
CT,
|
|
83
|
+
PartFactory,
|
|
84
|
+
)
|
pptx/action.py
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"""Objects related to mouse click and hover actions on a shape or text."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, cast
|
|
6
|
+
|
|
7
|
+
from pptx.enum.action import PP_ACTION
|
|
8
|
+
from pptx.opc.constants import RELATIONSHIP_TYPE as RT
|
|
9
|
+
from pptx.shapes import Subshape
|
|
10
|
+
from pptx.util import lazyproperty
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from pptx.oxml.action import CT_Hyperlink
|
|
14
|
+
from pptx.oxml.shapes.shared import CT_NonVisualDrawingProps
|
|
15
|
+
from pptx.oxml.text import CT_TextCharacterProperties
|
|
16
|
+
from pptx.parts.slide import SlidePart
|
|
17
|
+
from pptx.shapes.base import BaseShape
|
|
18
|
+
from pptx.slide import Slide, Slides
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ActionSetting(Subshape):
|
|
22
|
+
"""Properties specifying how a shape or run reacts to mouse actions."""
|
|
23
|
+
|
|
24
|
+
# -- The Subshape base class provides access to the Slide Part, which is needed to access
|
|
25
|
+
# -- relationships, which is where hyperlinks live.
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
xPr: CT_NonVisualDrawingProps | CT_TextCharacterProperties,
|
|
30
|
+
parent: BaseShape,
|
|
31
|
+
hover: bool = False,
|
|
32
|
+
):
|
|
33
|
+
super(ActionSetting, self).__init__(parent)
|
|
34
|
+
# xPr is either a cNvPr or rPr element
|
|
35
|
+
self._element = xPr
|
|
36
|
+
# _hover determines use of `a:hlinkClick` or `a:hlinkHover`
|
|
37
|
+
self._hover = hover
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def action(self):
|
|
41
|
+
"""Member of :ref:`PpActionType` enumeration, such as `PP_ACTION.HYPERLINK`.
|
|
42
|
+
|
|
43
|
+
The returned member indicates the type of action that will result when the
|
|
44
|
+
specified shape or text is clicked or the mouse pointer is positioned over the
|
|
45
|
+
shape during a slide show.
|
|
46
|
+
|
|
47
|
+
If there is no click-action or the click-action value is not recognized (is not
|
|
48
|
+
one of the official `MsoPpAction` values) then `PP_ACTION.NONE` is returned.
|
|
49
|
+
"""
|
|
50
|
+
hlink = self._hlink
|
|
51
|
+
|
|
52
|
+
if hlink is None:
|
|
53
|
+
return PP_ACTION.NONE
|
|
54
|
+
|
|
55
|
+
action_verb = hlink.action_verb
|
|
56
|
+
|
|
57
|
+
if action_verb == "hlinkshowjump":
|
|
58
|
+
relative_target = hlink.action_fields["jump"]
|
|
59
|
+
return {
|
|
60
|
+
"firstslide": PP_ACTION.FIRST_SLIDE,
|
|
61
|
+
"lastslide": PP_ACTION.LAST_SLIDE,
|
|
62
|
+
"lastslideviewed": PP_ACTION.LAST_SLIDE_VIEWED,
|
|
63
|
+
"nextslide": PP_ACTION.NEXT_SLIDE,
|
|
64
|
+
"previousslide": PP_ACTION.PREVIOUS_SLIDE,
|
|
65
|
+
"endshow": PP_ACTION.END_SHOW,
|
|
66
|
+
}[relative_target]
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
None: PP_ACTION.HYPERLINK,
|
|
70
|
+
"hlinksldjump": PP_ACTION.NAMED_SLIDE,
|
|
71
|
+
"hlinkpres": PP_ACTION.PLAY,
|
|
72
|
+
"hlinkfile": PP_ACTION.OPEN_FILE,
|
|
73
|
+
"customshow": PP_ACTION.NAMED_SLIDE_SHOW,
|
|
74
|
+
"ole": PP_ACTION.OLE_VERB,
|
|
75
|
+
"macro": PP_ACTION.RUN_MACRO,
|
|
76
|
+
"program": PP_ACTION.RUN_PROGRAM,
|
|
77
|
+
}.get(action_verb, PP_ACTION.NONE)
|
|
78
|
+
|
|
79
|
+
@lazyproperty
|
|
80
|
+
def hyperlink(self) -> Hyperlink:
|
|
81
|
+
"""
|
|
82
|
+
A |Hyperlink| object representing the hyperlink action defined on
|
|
83
|
+
this click or hover mouse event. A |Hyperlink| object is always
|
|
84
|
+
returned, even if no hyperlink or other click action is defined.
|
|
85
|
+
"""
|
|
86
|
+
return Hyperlink(self._element, self._parent, self._hover)
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def target_slide(self) -> Slide | None:
|
|
90
|
+
"""
|
|
91
|
+
A reference to the slide in this presentation that is the target of
|
|
92
|
+
the slide jump action in this shape. Slide jump actions include
|
|
93
|
+
`PP_ACTION.FIRST_SLIDE`, `LAST_SLIDE`, `NEXT_SLIDE`,
|
|
94
|
+
`PREVIOUS_SLIDE`, and `NAMED_SLIDE`. Returns |None| for all other
|
|
95
|
+
actions. In particular, the `LAST_SLIDE_VIEWED` action and the `PLAY`
|
|
96
|
+
(start other presentation) actions are not supported.
|
|
97
|
+
|
|
98
|
+
A slide object may be assigned to this property, which makes the
|
|
99
|
+
shape an "internal hyperlink" to the assigened slide::
|
|
100
|
+
|
|
101
|
+
slide, target_slide = prs.slides[0], prs.slides[1]
|
|
102
|
+
shape = slide.shapes[0]
|
|
103
|
+
shape.target_slide = target_slide
|
|
104
|
+
|
|
105
|
+
Assigning |None| removes any slide jump action. Note that this is
|
|
106
|
+
accomplished by removing any action present (such as a hyperlink),
|
|
107
|
+
without first checking that it is a slide jump action.
|
|
108
|
+
"""
|
|
109
|
+
slide_jump_actions = (
|
|
110
|
+
PP_ACTION.FIRST_SLIDE,
|
|
111
|
+
PP_ACTION.LAST_SLIDE,
|
|
112
|
+
PP_ACTION.NEXT_SLIDE,
|
|
113
|
+
PP_ACTION.PREVIOUS_SLIDE,
|
|
114
|
+
PP_ACTION.NAMED_SLIDE,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
if self.action not in slide_jump_actions:
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
if self.action == PP_ACTION.FIRST_SLIDE:
|
|
121
|
+
return self._slides[0]
|
|
122
|
+
elif self.action == PP_ACTION.LAST_SLIDE:
|
|
123
|
+
return self._slides[-1]
|
|
124
|
+
elif self.action == PP_ACTION.NEXT_SLIDE:
|
|
125
|
+
next_slide_idx = self._slide_index + 1
|
|
126
|
+
if next_slide_idx >= len(self._slides):
|
|
127
|
+
raise ValueError("no next slide")
|
|
128
|
+
return self._slides[next_slide_idx]
|
|
129
|
+
elif self.action == PP_ACTION.PREVIOUS_SLIDE:
|
|
130
|
+
prev_slide_idx = self._slide_index - 1
|
|
131
|
+
if prev_slide_idx < 0:
|
|
132
|
+
raise ValueError("no previous slide")
|
|
133
|
+
return self._slides[prev_slide_idx]
|
|
134
|
+
elif self.action == PP_ACTION.NAMED_SLIDE:
|
|
135
|
+
assert self._hlink is not None
|
|
136
|
+
rId = self._hlink.rId
|
|
137
|
+
slide_part = cast("SlidePart", self.part.related_part(rId))
|
|
138
|
+
return slide_part.slide
|
|
139
|
+
|
|
140
|
+
@target_slide.setter
|
|
141
|
+
def target_slide(self, slide: Slide | None):
|
|
142
|
+
self._clear_click_action()
|
|
143
|
+
if slide is None:
|
|
144
|
+
return
|
|
145
|
+
hlink = self._element.get_or_add_hlinkClick()
|
|
146
|
+
hlink.action = "ppaction://hlinksldjump"
|
|
147
|
+
hlink.rId = self.part.relate_to(slide.part, RT.SLIDE)
|
|
148
|
+
|
|
149
|
+
def _clear_click_action(self):
|
|
150
|
+
"""Remove any existing click action."""
|
|
151
|
+
hlink = self._hlink
|
|
152
|
+
if hlink is None:
|
|
153
|
+
return
|
|
154
|
+
rId = hlink.rId
|
|
155
|
+
if rId:
|
|
156
|
+
self.part.drop_rel(rId)
|
|
157
|
+
self._element.remove(hlink)
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def _hlink(self) -> CT_Hyperlink | None:
|
|
161
|
+
"""
|
|
162
|
+
Reference to the `a:hlinkClick` or `a:hlinkHover` element for this
|
|
163
|
+
click action. Returns |None| if the element is not present.
|
|
164
|
+
"""
|
|
165
|
+
if self._hover:
|
|
166
|
+
assert isinstance(self._element, CT_NonVisualDrawingProps)
|
|
167
|
+
return self._element.hlinkHover
|
|
168
|
+
return self._element.hlinkClick
|
|
169
|
+
|
|
170
|
+
@lazyproperty
|
|
171
|
+
def _slide(self):
|
|
172
|
+
"""
|
|
173
|
+
Reference to the slide containing the shape having this click action.
|
|
174
|
+
"""
|
|
175
|
+
return self.part.slide
|
|
176
|
+
|
|
177
|
+
@lazyproperty
|
|
178
|
+
def _slide_index(self):
|
|
179
|
+
"""
|
|
180
|
+
Position in the slide collection of the slide containing the shape
|
|
181
|
+
having this click action.
|
|
182
|
+
"""
|
|
183
|
+
return self._slides.index(self._slide)
|
|
184
|
+
|
|
185
|
+
@lazyproperty
|
|
186
|
+
def _slides(self) -> Slides:
|
|
187
|
+
"""
|
|
188
|
+
Reference to the slide collection for this presentation.
|
|
189
|
+
"""
|
|
190
|
+
return self.part.package.presentation_part.presentation.slides
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class Hyperlink(Subshape):
|
|
194
|
+
"""Represents a hyperlink action on a shape or text run."""
|
|
195
|
+
|
|
196
|
+
def __init__(
|
|
197
|
+
self,
|
|
198
|
+
xPr: CT_NonVisualDrawingProps | CT_TextCharacterProperties,
|
|
199
|
+
parent: BaseShape,
|
|
200
|
+
hover: bool = False,
|
|
201
|
+
):
|
|
202
|
+
super(Hyperlink, self).__init__(parent)
|
|
203
|
+
# xPr is either a cNvPr or rPr element
|
|
204
|
+
self._element = xPr
|
|
205
|
+
# _hover determines use of `a:hlinkClick` or `a:hlinkHover`
|
|
206
|
+
self._hover = hover
|
|
207
|
+
|
|
208
|
+
@property
|
|
209
|
+
def address(self) -> str | None:
|
|
210
|
+
"""Read/write. The URL of the hyperlink.
|
|
211
|
+
|
|
212
|
+
URL can be on http, https, mailto, or file scheme; others may work. Returns |None| if no
|
|
213
|
+
hyperlink is defined, including when another action such as `RUN_MACRO` is defined on the
|
|
214
|
+
object. Assigning |None| removes any action defined on the object, whether it is a hyperlink
|
|
215
|
+
action or not.
|
|
216
|
+
"""
|
|
217
|
+
hlink = self._hlink
|
|
218
|
+
|
|
219
|
+
# there's no URL if there's no click action
|
|
220
|
+
if hlink is None:
|
|
221
|
+
return None
|
|
222
|
+
|
|
223
|
+
# a click action without a relationship has no URL
|
|
224
|
+
rId = hlink.rId
|
|
225
|
+
if not rId:
|
|
226
|
+
return None
|
|
227
|
+
|
|
228
|
+
return self.part.target_ref(rId)
|
|
229
|
+
|
|
230
|
+
@address.setter
|
|
231
|
+
def address(self, url: str | None):
|
|
232
|
+
# implements all three of add, change, and remove hyperlink
|
|
233
|
+
self._remove_hlink()
|
|
234
|
+
|
|
235
|
+
if url:
|
|
236
|
+
rId = self.part.relate_to(url, RT.HYPERLINK, is_external=True)
|
|
237
|
+
hlink = self._get_or_add_hlink()
|
|
238
|
+
hlink.rId = rId
|
|
239
|
+
|
|
240
|
+
def _get_or_add_hlink(self) -> CT_Hyperlink:
|
|
241
|
+
"""Get the `a:hlinkClick` or `a:hlinkHover` element for the Hyperlink object.
|
|
242
|
+
|
|
243
|
+
The actual element depends on the value of `self._hover`. Create the element if not present.
|
|
244
|
+
"""
|
|
245
|
+
if self._hover:
|
|
246
|
+
return cast("CT_NonVisualDrawingProps", self._element).get_or_add_hlinkHover()
|
|
247
|
+
return self._element.get_or_add_hlinkClick()
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def _hlink(self) -> CT_Hyperlink | None:
|
|
251
|
+
"""Reference to the `a:hlinkClick` or `h:hlinkHover` element for this click action.
|
|
252
|
+
|
|
253
|
+
Returns |None| if the element is not present.
|
|
254
|
+
"""
|
|
255
|
+
if self._hover:
|
|
256
|
+
return cast("CT_NonVisualDrawingProps", self._element).hlinkHover
|
|
257
|
+
return self._element.hlinkClick
|
|
258
|
+
|
|
259
|
+
def _remove_hlink(self):
|
|
260
|
+
"""Remove the a:hlinkClick or a:hlinkHover element.
|
|
261
|
+
|
|
262
|
+
Also drops any relationship it might have.
|
|
263
|
+
"""
|
|
264
|
+
hlink = self._hlink
|
|
265
|
+
if hlink is None:
|
|
266
|
+
return
|
|
267
|
+
rId = hlink.rId
|
|
268
|
+
if rId:
|
|
269
|
+
self.part.drop_rel(rId)
|
|
270
|
+
self._element.remove(hlink)
|
pptx/api.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Directly exposed API classes, Presentation for now.
|
|
2
|
+
|
|
3
|
+
Provides some syntactic sugar for interacting with the pptx.presentation.Package graph and also
|
|
4
|
+
provides some insulation so not so many classes in the other modules need to be named as internal
|
|
5
|
+
(leading underscore).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
from typing import IO, TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
from pptx.opc.constants import CONTENT_TYPE as CT
|
|
14
|
+
from pptx.package import Package
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from pptx import presentation
|
|
18
|
+
from pptx.parts.presentation import PresentationPart
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def Presentation(pptx: str | IO[bytes] | None = None) -> presentation.Presentation:
|
|
22
|
+
"""
|
|
23
|
+
Return a |Presentation| object loaded from *pptx*, where *pptx* can be
|
|
24
|
+
either a path to a ``.pptx`` file (a string) or a file-like object. If
|
|
25
|
+
*pptx* is missing or ``None``, the built-in default presentation
|
|
26
|
+
"template" is loaded.
|
|
27
|
+
"""
|
|
28
|
+
if pptx is None:
|
|
29
|
+
pptx = _default_pptx_path()
|
|
30
|
+
|
|
31
|
+
presentation_part = Package.open(pptx).main_document_part
|
|
32
|
+
|
|
33
|
+
if not _is_pptx_package(presentation_part):
|
|
34
|
+
tmpl = "file '%s' is not a PowerPoint file, content type is '%s'"
|
|
35
|
+
raise ValueError(tmpl % (pptx, presentation_part.content_type))
|
|
36
|
+
|
|
37
|
+
return presentation_part.presentation
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _default_pptx_path() -> str:
|
|
41
|
+
"""Return the path to the built-in default .pptx package."""
|
|
42
|
+
_thisdir = os.path.split(__file__)[0]
|
|
43
|
+
return os.path.join(_thisdir, "templates", "default.pptx")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _is_pptx_package(prs_part: PresentationPart):
|
|
47
|
+
"""Return |True| if *prs_part* is a valid main document part, |False| otherwise."""
|
|
48
|
+
valid_content_types = (CT.PML_PRESENTATION_MAIN, CT.PML_PRES_MACRO_MAIN)
|
|
49
|
+
return prs_part.content_type in valid_content_types
|
pptx/chart/__init__.py
ADDED
|
File without changes
|