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.
Files changed (117) hide show
  1. pptx/__init__.py +84 -0
  2. pptx/action.py +270 -0
  3. pptx/api.py +49 -0
  4. pptx/chart/__init__.py +0 -0
  5. pptx/chart/axis.py +523 -0
  6. pptx/chart/category.py +200 -0
  7. pptx/chart/chart.py +280 -0
  8. pptx/chart/data.py +864 -0
  9. pptx/chart/datalabel.py +288 -0
  10. pptx/chart/legend.py +79 -0
  11. pptx/chart/marker.py +70 -0
  12. pptx/chart/plot.py +412 -0
  13. pptx/chart/point.py +101 -0
  14. pptx/chart/series.py +258 -0
  15. pptx/chart/xlsx.py +272 -0
  16. pptx/chart/xmlwriter.py +1840 -0
  17. pptx/dml/__init__.py +0 -0
  18. pptx/dml/chtfmt.py +40 -0
  19. pptx/dml/color.py +301 -0
  20. pptx/dml/effect.py +41 -0
  21. pptx/dml/fill.py +468 -0
  22. pptx/dml/line.py +100 -0
  23. pptx/enum/__init__.py +0 -0
  24. pptx/enum/action.py +71 -0
  25. pptx/enum/base.py +175 -0
  26. pptx/enum/chart.py +492 -0
  27. pptx/enum/dml.py +405 -0
  28. pptx/enum/lang.py +685 -0
  29. pptx/enum/shapes.py +1029 -0
  30. pptx/enum/text.py +371 -0
  31. pptx/exc.py +23 -0
  32. pptx/media.py +197 -0
  33. pptx/opc/__init__.py +0 -0
  34. pptx/opc/constants.py +331 -0
  35. pptx/opc/oxml.py +188 -0
  36. pptx/opc/package.py +762 -0
  37. pptx/opc/packuri.py +109 -0
  38. pptx/opc/serialized.py +296 -0
  39. pptx/opc/shared.py +20 -0
  40. pptx/opc/spec.py +44 -0
  41. pptx/oxml/__init__.py +492 -0
  42. pptx/oxml/action.py +53 -0
  43. pptx/oxml/chart/__init__.py +0 -0
  44. pptx/oxml/chart/axis.py +297 -0
  45. pptx/oxml/chart/chart.py +282 -0
  46. pptx/oxml/chart/datalabel.py +252 -0
  47. pptx/oxml/chart/legend.py +72 -0
  48. pptx/oxml/chart/marker.py +61 -0
  49. pptx/oxml/chart/plot.py +345 -0
  50. pptx/oxml/chart/series.py +254 -0
  51. pptx/oxml/chart/shared.py +219 -0
  52. pptx/oxml/coreprops.py +288 -0
  53. pptx/oxml/dml/__init__.py +0 -0
  54. pptx/oxml/dml/color.py +111 -0
  55. pptx/oxml/dml/fill.py +197 -0
  56. pptx/oxml/dml/line.py +12 -0
  57. pptx/oxml/ns.py +129 -0
  58. pptx/oxml/presentation.py +130 -0
  59. pptx/oxml/shapes/__init__.py +19 -0
  60. pptx/oxml/shapes/autoshape.py +455 -0
  61. pptx/oxml/shapes/connector.py +107 -0
  62. pptx/oxml/shapes/graphfrm.py +342 -0
  63. pptx/oxml/shapes/groupshape.py +280 -0
  64. pptx/oxml/shapes/picture.py +270 -0
  65. pptx/oxml/shapes/shared.py +523 -0
  66. pptx/oxml/simpletypes.py +740 -0
  67. pptx/oxml/slide.py +347 -0
  68. pptx/oxml/table.py +588 -0
  69. pptx/oxml/text.py +748 -0
  70. pptx/oxml/theme.py +29 -0
  71. pptx/oxml/xmlchemy.py +717 -0
  72. pptx/package.py +222 -0
  73. pptx/parts/__init__.py +0 -0
  74. pptx/parts/chart.py +95 -0
  75. pptx/parts/coreprops.py +167 -0
  76. pptx/parts/embeddedpackage.py +93 -0
  77. pptx/parts/image.py +275 -0
  78. pptx/parts/media.py +37 -0
  79. pptx/parts/presentation.py +126 -0
  80. pptx/parts/slide.py +297 -0
  81. pptx/parts/theme.py +13 -0
  82. pptx/presentation.py +113 -0
  83. pptx/py.typed +0 -0
  84. pptx/shapes/__init__.py +26 -0
  85. pptx/shapes/autoshape.py +355 -0
  86. pptx/shapes/base.py +293 -0
  87. pptx/shapes/connector.py +297 -0
  88. pptx/shapes/freeform.py +337 -0
  89. pptx/shapes/graphfrm.py +166 -0
  90. pptx/shapes/group.py +69 -0
  91. pptx/shapes/picture.py +203 -0
  92. pptx/shapes/placeholder.py +407 -0
  93. pptx/shapes/shapetree.py +1190 -0
  94. pptx/shared.py +82 -0
  95. pptx/slide.py +577 -0
  96. pptx/spec.py +632 -0
  97. pptx/table.py +520 -0
  98. pptx/templates/default.pptx +0 -0
  99. pptx/templates/docx-icon.emf +0 -0
  100. pptx/templates/generic-icon.emf +0 -0
  101. pptx/templates/notes.xml +23 -0
  102. pptx/templates/notesMaster.xml +352 -0
  103. pptx/templates/pptx-icon.emf +0 -0
  104. pptx/templates/theme.xml +321 -0
  105. pptx/templates/xlsx-icon.emf +0 -0
  106. pptx/text/__init__.py +0 -0
  107. pptx/text/fonts.py +399 -0
  108. pptx/text/layout.py +325 -0
  109. pptx/text/text.py +770 -0
  110. pptx/theme.py +135 -0
  111. pptx/types.py +36 -0
  112. pptx/util.py +284 -0
  113. ps_python_pptx-1.1.0.dist-info/METADATA +75 -0
  114. ps_python_pptx-1.1.0.dist-info/RECORD +117 -0
  115. ps_python_pptx-1.1.0.dist-info/WHEEL +5 -0
  116. ps_python_pptx-1.1.0.dist-info/licenses/LICENSE +20 -0
  117. ps_python_pptx-1.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,166 @@
1
+ """Graphic Frame shape and related objects.
2
+
3
+ A graphic frame is a common container for table, chart, smart art, and media
4
+ objects.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import TYPE_CHECKING, cast
10
+
11
+ from pptx.enum.shapes import MSO_SHAPE_TYPE
12
+ from pptx.shapes.base import BaseShape
13
+ from pptx.shared import ParentedElementProxy
14
+ from pptx.spec import (
15
+ GRAPHIC_DATA_URI_CHART,
16
+ GRAPHIC_DATA_URI_OLEOBJ,
17
+ GRAPHIC_DATA_URI_TABLE,
18
+ )
19
+ from pptx.table import Table
20
+ from pptx.util import lazyproperty
21
+
22
+ if TYPE_CHECKING:
23
+ from pptx.chart.chart import Chart
24
+ from pptx.dml.effect import ShadowFormat
25
+ from pptx.oxml.shapes.graphfrm import CT_GraphicalObjectData, CT_GraphicalObjectFrame
26
+ from pptx.parts.chart import ChartPart
27
+ from pptx.parts.slide import BaseSlidePart
28
+ from pptx.types import ProvidesPart
29
+
30
+
31
+ class GraphicFrame(BaseShape):
32
+ """Container shape for table, chart, smart art, and media objects.
33
+
34
+ Corresponds to a `p:graphicFrame` element in the shape tree.
35
+ """
36
+
37
+ def __init__(self, graphicFrame: CT_GraphicalObjectFrame, parent: ProvidesPart):
38
+ super().__init__(graphicFrame, parent)
39
+ self._graphicFrame = graphicFrame
40
+
41
+ @property
42
+ def chart(self) -> Chart:
43
+ """The |Chart| object containing the chart in this graphic frame.
44
+
45
+ Raises |ValueError| if this graphic frame does not contain a chart.
46
+ """
47
+ if not self.has_chart:
48
+ raise ValueError("shape does not contain a chart")
49
+ return self.chart_part.chart
50
+
51
+ @property
52
+ def chart_part(self) -> ChartPart:
53
+ """The |ChartPart| object containing the chart in this graphic frame."""
54
+ chart_rId = self._graphicFrame.chart_rId
55
+ if chart_rId is None:
56
+ raise ValueError("this graphic frame does not contain a chart")
57
+ return cast("ChartPart", self.part.related_part(chart_rId))
58
+
59
+ @property
60
+ def has_chart(self) -> bool:
61
+ """|True| if this graphic frame contains a chart object. |False| otherwise.
62
+
63
+ When |True|, the chart object can be accessed using the `.chart` property.
64
+ """
65
+ return self._graphicFrame.graphicData_uri == GRAPHIC_DATA_URI_CHART
66
+
67
+ @property
68
+ def has_table(self) -> bool:
69
+ """|True| if this graphic frame contains a table object, |False| otherwise.
70
+
71
+ When |True|, the table object can be accessed using the `.table` property.
72
+ """
73
+ return self._graphicFrame.graphicData_uri == GRAPHIC_DATA_URI_TABLE
74
+
75
+ @property
76
+ def ole_format(self) -> _OleFormat:
77
+ """_OleFormat object for this graphic-frame shape.
78
+
79
+ Raises `ValueError` on a GraphicFrame instance that does not contain an OLE object.
80
+
81
+ An shape that contains an OLE object will have `.shape_type` of either
82
+ `EMBEDDED_OLE_OBJECT` or `LINKED_OLE_OBJECT`.
83
+ """
84
+ if not self._graphicFrame.has_oleobj:
85
+ raise ValueError("not an OLE-object shape")
86
+ return _OleFormat(self._graphicFrame.graphicData, self._parent)
87
+
88
+ @lazyproperty
89
+ def shadow(self) -> ShadowFormat:
90
+ """Unconditionally raises |NotImplementedError|.
91
+
92
+ Access to the shadow effect for graphic-frame objects is content-specific (i.e. different
93
+ for charts, tables, etc.) and has not yet been implemented.
94
+ """
95
+ raise NotImplementedError("shadow property on GraphicFrame not yet supported")
96
+
97
+ @property
98
+ def shape_type(self) -> MSO_SHAPE_TYPE:
99
+ """Optional member of `MSO_SHAPE_TYPE` identifying the type of this shape.
100
+
101
+ Possible values are `MSO_SHAPE_TYPE.CHART`, `MSO_SHAPE_TYPE.TABLE`,
102
+ `MSO_SHAPE_TYPE.EMBEDDED_OLE_OBJECT`, `MSO_SHAPE_TYPE.LINKED_OLE_OBJECT`.
103
+
104
+ This value is `None` when none of these four types apply, for example when the shape
105
+ contains SmartArt.
106
+ """
107
+ graphicData_uri = self._graphicFrame.graphicData_uri
108
+ if graphicData_uri == GRAPHIC_DATA_URI_CHART:
109
+ return MSO_SHAPE_TYPE.CHART
110
+ elif graphicData_uri == GRAPHIC_DATA_URI_TABLE:
111
+ return MSO_SHAPE_TYPE.TABLE
112
+ elif graphicData_uri == GRAPHIC_DATA_URI_OLEOBJ:
113
+ return (
114
+ MSO_SHAPE_TYPE.EMBEDDED_OLE_OBJECT
115
+ if self._graphicFrame.is_embedded_ole_obj
116
+ else MSO_SHAPE_TYPE.LINKED_OLE_OBJECT
117
+ )
118
+ else:
119
+ return None # pyright: ignore[reportReturnType]
120
+
121
+ @property
122
+ def table(self) -> Table:
123
+ """The |Table| object contained in this graphic frame.
124
+
125
+ Raises |ValueError| if this graphic frame does not contain a table.
126
+ """
127
+ if not self.has_table:
128
+ raise ValueError("shape does not contain a table")
129
+ tbl = self._graphicFrame.graphic.graphicData.tbl
130
+ return Table(tbl, self)
131
+
132
+
133
+ class _OleFormat(ParentedElementProxy):
134
+ """Provides attributes on an embedded OLE object."""
135
+
136
+ part: BaseSlidePart # pyright: ignore[reportIncompatibleMethodOverride]
137
+
138
+ def __init__(self, graphicData: CT_GraphicalObjectData, parent: ProvidesPart):
139
+ super().__init__(graphicData, parent)
140
+ self._graphicData = graphicData
141
+
142
+ @property
143
+ def blob(self) -> bytes | None:
144
+ """Optional bytes of OLE object, suitable for loading or saving as a file.
145
+
146
+ This value is `None` if the embedded object does not represent a "file".
147
+ """
148
+ blob_rId = self._graphicData.blob_rId
149
+ if blob_rId is None:
150
+ return None
151
+ return self.part.related_part(blob_rId).blob
152
+
153
+ @property
154
+ def prog_id(self) -> str | None:
155
+ """str "progId" attribute of this embedded OLE object.
156
+
157
+ The progId is a str like "Excel.Sheet.12" that identifies the "file-type" of the embedded
158
+ object, or perhaps more precisely, the application (aka. "server" in OLE parlance) to be
159
+ used to open this object.
160
+ """
161
+ return self._graphicData.progId
162
+
163
+ @property
164
+ def show_as_icon(self) -> bool | None:
165
+ """True when OLE object should appear as an icon (rather than preview)."""
166
+ return self._graphicData.showAsIcon
pptx/shapes/group.py ADDED
@@ -0,0 +1,69 @@
1
+ """GroupShape and related objects."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from pptx.dml.effect import ShadowFormat
8
+ from pptx.enum.shapes import MSO_SHAPE_TYPE
9
+ from pptx.shapes.base import BaseShape
10
+ from pptx.util import lazyproperty
11
+
12
+ if TYPE_CHECKING:
13
+ from pptx.action import ActionSetting
14
+ from pptx.oxml.shapes.groupshape import CT_GroupShape
15
+ from pptx.shapes.shapetree import GroupShapes
16
+ from pptx.types import ProvidesPart
17
+
18
+
19
+ class GroupShape(BaseShape):
20
+ """A shape that acts as a container for other shapes."""
21
+
22
+ def __init__(self, grpSp: CT_GroupShape, parent: ProvidesPart):
23
+ super().__init__(grpSp, parent)
24
+ self._grpSp = grpSp
25
+
26
+ @lazyproperty
27
+ def click_action(self) -> ActionSetting:
28
+ """Unconditionally raises `TypeError`.
29
+
30
+ A group shape cannot have a click action or hover action.
31
+ """
32
+ raise TypeError("a group shape cannot have a click action")
33
+
34
+ @property
35
+ def has_text_frame(self) -> bool:
36
+ """Unconditionally |False|.
37
+
38
+ A group shape does not have a textframe and cannot itself contain text. This does not
39
+ impact the ability of shapes contained by the group to each have their own text.
40
+ """
41
+ return False
42
+
43
+ @lazyproperty
44
+ def shadow(self) -> ShadowFormat:
45
+ """|ShadowFormat| object representing shadow effect for this group.
46
+
47
+ A |ShadowFormat| object is always returned, even when no shadow is explicitly defined on
48
+ this group shape (i.e. when the group inherits its shadow behavior).
49
+ """
50
+ return ShadowFormat(self._grpSp.grpSpPr)
51
+
52
+ @property
53
+ def shape_type(self) -> MSO_SHAPE_TYPE:
54
+ """Member of :ref:`MsoShapeType` identifying the type of this shape.
55
+
56
+ Unconditionally `MSO_SHAPE_TYPE.GROUP` in this case
57
+ """
58
+ return MSO_SHAPE_TYPE.GROUP
59
+
60
+ @lazyproperty
61
+ def shapes(self) -> GroupShapes:
62
+ """|GroupShapes| object for this group.
63
+
64
+ The |GroupShapes| object provides access to the group's member shapes and provides methods
65
+ for adding new ones.
66
+ """
67
+ from pptx.shapes.shapetree import GroupShapes
68
+
69
+ return GroupShapes(self._element, self)
pptx/shapes/picture.py ADDED
@@ -0,0 +1,203 @@
1
+ """Shapes based on the `p:pic` element, including Picture and Movie."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from pptx.dml.line import LineFormat
8
+ from pptx.enum.shapes import MSO_SHAPE, MSO_SHAPE_TYPE, PP_MEDIA_TYPE
9
+ from pptx.shapes.base import BaseShape
10
+ from pptx.shared import ParentedElementProxy
11
+ from pptx.util import lazyproperty
12
+
13
+ if TYPE_CHECKING:
14
+ from pptx.oxml.shapes.picture import CT_Picture
15
+ from pptx.oxml.shapes.shared import CT_LineProperties
16
+ from pptx.types import ProvidesPart
17
+
18
+
19
+ class _BasePicture(BaseShape):
20
+ """Base class for shapes based on a `p:pic` element."""
21
+
22
+ def __init__(self, pic: CT_Picture, parent: ProvidesPart):
23
+ super(_BasePicture, self).__init__(pic, parent)
24
+ self._pic = pic
25
+
26
+ @property
27
+ def crop_bottom(self) -> float:
28
+ """|float| representing relative portion cropped from shape bottom.
29
+
30
+ Read/write. 1.0 represents 100%. For example, 25% is represented by 0.25. Negative values
31
+ are valid as are values greater than 1.0.
32
+ """
33
+ return self._pic.srcRect_b
34
+
35
+ @crop_bottom.setter
36
+ def crop_bottom(self, value: float):
37
+ self._pic.srcRect_b = value
38
+
39
+ @property
40
+ def crop_left(self) -> float:
41
+ """|float| representing relative portion cropped from left of shape.
42
+
43
+ Read/write. 1.0 represents 100%. A negative value extends the side beyond the image
44
+ boundary.
45
+ """
46
+ return self._pic.srcRect_l
47
+
48
+ @crop_left.setter
49
+ def crop_left(self, value: float):
50
+ self._pic.srcRect_l = value
51
+
52
+ @property
53
+ def crop_right(self) -> float:
54
+ """|float| representing relative portion cropped from right of shape.
55
+
56
+ Read/write. 1.0 represents 100%.
57
+ """
58
+ return self._pic.srcRect_r
59
+
60
+ @crop_right.setter
61
+ def crop_right(self, value: float):
62
+ self._pic.srcRect_r = value
63
+
64
+ @property
65
+ def crop_top(self) -> float:
66
+ """|float| representing relative portion cropped from shape top.
67
+
68
+ Read/write. 1.0 represents 100%.
69
+ """
70
+ return self._pic.srcRect_t
71
+
72
+ @crop_top.setter
73
+ def crop_top(self, value: float):
74
+ self._pic.srcRect_t = value
75
+
76
+ def get_or_add_ln(self):
77
+ """Return the `a:ln` element for this `p:pic`-based image.
78
+
79
+ The `a:ln` element contains the line format properties XML.
80
+ """
81
+ return self._pic.get_or_add_ln()
82
+
83
+ @lazyproperty
84
+ def line(self) -> LineFormat:
85
+ """Provides access to properties of the picture outline, such as its color and width."""
86
+ return LineFormat(self)
87
+
88
+ @property
89
+ def ln(self) -> CT_LineProperties | None:
90
+ """The `a:ln` element for this `p:pic`.
91
+
92
+ Contains the line format properties such as line color and width. |None| if no `a:ln`
93
+ element is present.
94
+ """
95
+ return self._pic.ln
96
+
97
+
98
+ class Movie(_BasePicture):
99
+ """A movie shape, one that places a video on a slide.
100
+
101
+ Like |Picture|, a movie shape is based on the `p:pic` element. A movie is composed of a video
102
+ and a *poster frame*, the placeholder image that represents the video before it is played.
103
+ """
104
+
105
+ @lazyproperty
106
+ def media_format(self) -> _MediaFormat:
107
+ """The |_MediaFormat| object for this movie.
108
+
109
+ The |_MediaFormat| object provides access to formatting properties for the movie.
110
+ """
111
+ return _MediaFormat(self._pic, self)
112
+
113
+ @property
114
+ def media_type(self) -> PP_MEDIA_TYPE:
115
+ """Member of :ref:`PpMediaType` describing this shape.
116
+
117
+ The return value is unconditionally `PP_MEDIA_TYPE.MOVIE` in this case.
118
+ """
119
+ return PP_MEDIA_TYPE.MOVIE
120
+
121
+ @property
122
+ def poster_frame(self):
123
+ """Return |Image| object containing poster frame for this movie.
124
+
125
+ Returns |None| if this movie has no poster frame (uncommon).
126
+ """
127
+ slide_part, rId = self.part, self._pic.blip_rId
128
+ if rId is None:
129
+ return None
130
+ return slide_part.get_image(rId)
131
+
132
+ @property
133
+ def shape_type(self) -> MSO_SHAPE_TYPE:
134
+ """Return member of :ref:`MsoShapeType` describing this shape.
135
+
136
+ The return value is unconditionally `MSO_SHAPE_TYPE.MEDIA` in this
137
+ case.
138
+ """
139
+ return MSO_SHAPE_TYPE.MEDIA
140
+
141
+
142
+ class Picture(_BasePicture):
143
+ """A picture shape, one that places an image on a slide.
144
+
145
+ Based on the `p:pic` element.
146
+ """
147
+
148
+ @property
149
+ def auto_shape_type(self) -> MSO_SHAPE | None:
150
+ """Member of MSO_SHAPE indicating masking shape.
151
+
152
+ A picture can be masked by any of the so-called "auto-shapes" available in PowerPoint,
153
+ such as an ellipse or triangle. When a picture is masked by a shape, the shape assumes the
154
+ same dimensions as the picture and the portion of the picture outside the shape boundaries
155
+ does not appear. Note the default value for a newly-inserted picture is
156
+ `MSO_AUTO_SHAPE_TYPE.RECTANGLE`, which performs no cropping because the extents of the
157
+ rectangle exactly correspond to the extents of the picture.
158
+
159
+ The available shapes correspond to the members of :ref:`MsoAutoShapeType`.
160
+
161
+ The return value can also be |None|, indicating the picture either has no geometry (not
162
+ expected) or has custom geometry, like a freeform shape. A picture with no geometry will
163
+ have no visible representation on the slide, although it can be selected. This is because
164
+ without geometry, there is no "inside-the-shape" for it to appear in.
165
+ """
166
+ prstGeom = self._pic.spPr.prstGeom
167
+ if prstGeom is None: # ---generally means cropped with freeform---
168
+ return None
169
+ return prstGeom.prst
170
+
171
+ @auto_shape_type.setter
172
+ def auto_shape_type(self, member: MSO_SHAPE):
173
+ MSO_SHAPE.validate(member)
174
+ spPr = self._pic.spPr
175
+ prstGeom = spPr.prstGeom
176
+ if prstGeom is None:
177
+ spPr._remove_custGeom() # pyright: ignore[reportPrivateUsage]
178
+ prstGeom = spPr._add_prstGeom() # pyright: ignore[reportPrivateUsage]
179
+ prstGeom.prst = member
180
+
181
+ @property
182
+ def image(self):
183
+ """The |Image| object for this picture.
184
+
185
+ Provides access to the properties and bytes of the image in this picture shape.
186
+ """
187
+ slide_part, rId = self.part, self._pic.blip_rId
188
+ if rId is None:
189
+ raise ValueError("no embedded image")
190
+ return slide_part.get_image(rId)
191
+
192
+ @property
193
+ def shape_type(self) -> MSO_SHAPE_TYPE:
194
+ """Unconditionally `MSO_SHAPE_TYPE.PICTURE` in this case."""
195
+ return MSO_SHAPE_TYPE.PICTURE
196
+
197
+
198
+ class _MediaFormat(ParentedElementProxy):
199
+ """Provides access to formatting properties for a Media object.
200
+
201
+ Media format properties are things like start point, volume, and
202
+ compression type.
203
+ """