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
pptx/oxml/slide.py ADDED
@@ -0,0 +1,347 @@
1
+ """Slide-related custom element classes, including those for masters."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Callable, cast
6
+
7
+ from pptx.oxml import parse_from_template, parse_xml
8
+ from pptx.oxml.dml.fill import CT_GradientFillProperties
9
+ from pptx.oxml.ns import nsdecls
10
+ from pptx.oxml.simpletypes import XsdString
11
+ from pptx.oxml.xmlchemy import (
12
+ BaseOxmlElement,
13
+ Choice,
14
+ OneAndOnlyOne,
15
+ OptionalAttribute,
16
+ RequiredAttribute,
17
+ ZeroOrMore,
18
+ ZeroOrOne,
19
+ ZeroOrOneChoice,
20
+ )
21
+
22
+ if TYPE_CHECKING:
23
+ from pptx.oxml.shapes.groupshape import CT_GroupShape
24
+
25
+
26
+ class _BaseSlideElement(BaseOxmlElement):
27
+ """Base class for the six slide types, providing common methods."""
28
+
29
+ cSld: CT_CommonSlideData
30
+
31
+ @property
32
+ def spTree(self) -> CT_GroupShape:
33
+ """Return required `p:cSld/p:spTree` grandchild."""
34
+ return self.cSld.spTree
35
+
36
+
37
+ class CT_Background(BaseOxmlElement):
38
+ """`p:bg` element."""
39
+
40
+ _insert_bgPr: Callable[[CT_BackgroundProperties], None]
41
+
42
+ # ---these two are actually a choice, not a sequence, but simpler for
43
+ # ---present purposes this way.
44
+ _tag_seq = ("p:bgPr", "p:bgRef")
45
+ bgPr: CT_BackgroundProperties | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
46
+ "p:bgPr", successors=()
47
+ )
48
+ bgRef = ZeroOrOne("p:bgRef", successors=())
49
+ del _tag_seq
50
+
51
+ def add_noFill_bgPr(self):
52
+ """Return a new `p:bgPr` element with noFill properties."""
53
+ xml = "<p:bgPr %s>\n" " <a:noFill/>\n" " <a:effectLst/>\n" "</p:bgPr>" % nsdecls("a", "p")
54
+ bgPr = cast(CT_BackgroundProperties, parse_xml(xml))
55
+ self._insert_bgPr(bgPr)
56
+ return bgPr
57
+
58
+
59
+ class CT_BackgroundProperties(BaseOxmlElement):
60
+ """`p:bgPr` element."""
61
+
62
+ _tag_seq = (
63
+ "a:noFill",
64
+ "a:solidFill",
65
+ "a:gradFill",
66
+ "a:blipFill",
67
+ "a:pattFill",
68
+ "a:grpFill",
69
+ "a:effectLst",
70
+ "a:effectDag",
71
+ "a:extLst",
72
+ )
73
+ eg_fillProperties = ZeroOrOneChoice(
74
+ (
75
+ Choice("a:noFill"),
76
+ Choice("a:solidFill"),
77
+ Choice("a:gradFill"),
78
+ Choice("a:blipFill"),
79
+ Choice("a:pattFill"),
80
+ Choice("a:grpFill"),
81
+ ),
82
+ successors=_tag_seq[6:],
83
+ )
84
+ del _tag_seq
85
+
86
+ def _new_gradFill(self):
87
+ """Override default to add default gradient subtree."""
88
+ return CT_GradientFillProperties.new_gradFill()
89
+
90
+
91
+ class CT_CommonSlideData(BaseOxmlElement):
92
+ """`p:cSld` element."""
93
+
94
+ _remove_bg: Callable[[], None]
95
+ get_or_add_bg: Callable[[], CT_Background]
96
+
97
+ _tag_seq = ("p:bg", "p:spTree", "p:custDataLst", "p:controls", "p:extLst")
98
+ bg: CT_Background | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
99
+ "p:bg", successors=_tag_seq[1:]
100
+ )
101
+ spTree: CT_GroupShape = OneAndOnlyOne("p:spTree") # pyright: ignore[reportAssignmentType]
102
+ del _tag_seq
103
+ name: str = OptionalAttribute( # pyright: ignore[reportAssignmentType]
104
+ "name", XsdString, default=""
105
+ )
106
+
107
+ def get_or_add_bgPr(self) -> CT_BackgroundProperties:
108
+ """Return `p:bg/p:bgPr` grandchild.
109
+
110
+ If no such grandchild is present, any existing `p:bg` child is first removed and a new
111
+ default `p:bg` with noFill settings is added.
112
+ """
113
+ bg = self.bg
114
+ if bg is None or bg.bgPr is None:
115
+ bg = self._change_to_noFill_bg()
116
+ return cast(CT_BackgroundProperties, bg.bgPr)
117
+
118
+ def _change_to_noFill_bg(self) -> CT_Background:
119
+ """Establish a `p:bg` child with no-fill settings.
120
+
121
+ Any existing `p:bg` child is first removed.
122
+ """
123
+ self._remove_bg()
124
+ bg = self.get_or_add_bg()
125
+ bg.add_noFill_bgPr()
126
+ return bg
127
+
128
+
129
+ class CT_NotesMaster(_BaseSlideElement):
130
+ """`p:notesMaster` element, root of a notes master part."""
131
+
132
+ _tag_seq = ("p:cSld", "p:clrMap", "p:hf", "p:notesStyle", "p:extLst")
133
+ cSld: CT_CommonSlideData = OneAndOnlyOne("p:cSld") # pyright: ignore[reportAssignmentType]
134
+ del _tag_seq
135
+
136
+ @classmethod
137
+ def new_default(cls) -> CT_NotesMaster:
138
+ """Return a new `p:notesMaster` element based on the built-in default template."""
139
+ return cast(CT_NotesMaster, parse_from_template("notesMaster"))
140
+
141
+
142
+ class CT_NotesSlide(_BaseSlideElement):
143
+ """`p:notes` element, root of a notes slide part."""
144
+
145
+ _tag_seq = ("p:cSld", "p:clrMapOvr", "p:extLst")
146
+ cSld: CT_CommonSlideData = OneAndOnlyOne("p:cSld") # pyright: ignore[reportAssignmentType]
147
+ del _tag_seq
148
+
149
+ @classmethod
150
+ def new(cls) -> CT_NotesSlide:
151
+ """Return a new ``<p:notes>`` element based on the default template.
152
+
153
+ Note that the template does not include placeholders, which must be subsequently cloned
154
+ from the notes master.
155
+ """
156
+ return cast(CT_NotesSlide, parse_from_template("notes"))
157
+
158
+
159
+ class CT_Slide(_BaseSlideElement):
160
+ """`p:sld` element, root element of a slide part (XML document)."""
161
+
162
+ _tag_seq = ("p:cSld", "p:clrMapOvr", "p:transition", "p:timing", "p:extLst")
163
+ cSld: CT_CommonSlideData = OneAndOnlyOne("p:cSld") # pyright: ignore[reportAssignmentType]
164
+ clrMapOvr = ZeroOrOne("p:clrMapOvr", successors=_tag_seq[2:])
165
+ timing = ZeroOrOne("p:timing", successors=_tag_seq[4:])
166
+ del _tag_seq
167
+
168
+ @classmethod
169
+ def new(cls) -> CT_Slide:
170
+ """Return new `p:sld` element configured as base slide shape."""
171
+ return cast(CT_Slide, parse_xml(cls._sld_xml()))
172
+
173
+ @property
174
+ def bg(self):
175
+ """Return `p:bg` grandchild or None if not present."""
176
+ return self.cSld.bg
177
+
178
+ def get_or_add_childTnLst(self):
179
+ """Return parent element for a new `p:video` child element.
180
+
181
+ The `p:video` element causes play controls to appear under a video
182
+ shape (pic shape containing video). There can be more than one video
183
+ shape on a slide, which causes the precondition to vary. It needs to
184
+ handle the case when there is no `p:sld/p:timing` element and when
185
+ that element already exists. If the case isn't simple, it just nukes
186
+ what's there and adds a fresh one. This could theoretically remove
187
+ desired existing timing information, but there isn't any evidence
188
+ available to me one way or the other, so I've taken the simple
189
+ approach.
190
+ """
191
+ childTnLst = self._childTnLst
192
+ if childTnLst is None:
193
+ childTnLst = self._add_childTnLst()
194
+ return childTnLst
195
+
196
+ def _add_childTnLst(self):
197
+ """Add `./p:timing/p:tnLst/p:par/p:cTn/p:childTnLst` descendant.
198
+
199
+ Any existing `p:timing` child element is ruthlessly removed and
200
+ replaced.
201
+ """
202
+ self.remove(self.get_or_add_timing())
203
+ timing = parse_xml(self._childTnLst_timing_xml())
204
+ self._insert_timing(timing)
205
+ return timing.xpath("./p:tnLst/p:par/p:cTn/p:childTnLst")[0]
206
+
207
+ @property
208
+ def _childTnLst(self):
209
+ """Return `./p:timing/p:tnLst/p:par/p:cTn/p:childTnLst` descendant.
210
+
211
+ Return None if that element is not present.
212
+ """
213
+ childTnLsts = self.xpath("./p:timing/p:tnLst/p:par/p:cTn/p:childTnLst")
214
+ if not childTnLsts:
215
+ return None
216
+ return childTnLsts[0]
217
+
218
+ @staticmethod
219
+ def _childTnLst_timing_xml():
220
+ return (
221
+ "<p:timing %s>\n"
222
+ " <p:tnLst>\n"
223
+ " <p:par>\n"
224
+ ' <p:cTn id="1" dur="indefinite" restart="never" nodeType="'
225
+ 'tmRoot">\n'
226
+ " <p:childTnLst/>\n"
227
+ " </p:cTn>\n"
228
+ " </p:par>\n"
229
+ " </p:tnLst>\n"
230
+ "</p:timing>" % nsdecls("p")
231
+ )
232
+
233
+ @staticmethod
234
+ def _sld_xml():
235
+ return (
236
+ "<p:sld %s>\n"
237
+ " <p:cSld>\n"
238
+ " <p:spTree>\n"
239
+ " <p:nvGrpSpPr>\n"
240
+ ' <p:cNvPr id="1" name=""/>\n'
241
+ " <p:cNvGrpSpPr/>\n"
242
+ " <p:nvPr/>\n"
243
+ " </p:nvGrpSpPr>\n"
244
+ " <p:grpSpPr/>\n"
245
+ " </p:spTree>\n"
246
+ " </p:cSld>\n"
247
+ " <p:clrMapOvr>\n"
248
+ " <a:masterClrMapping/>\n"
249
+ " </p:clrMapOvr>\n"
250
+ "</p:sld>" % nsdecls("a", "p", "r")
251
+ )
252
+
253
+
254
+ class CT_SlideLayout(_BaseSlideElement):
255
+ """`p:sldLayout` element, root of a slide layout part."""
256
+
257
+ _tag_seq = ("p:cSld", "p:clrMapOvr", "p:transition", "p:timing", "p:hf", "p:extLst")
258
+ cSld: CT_CommonSlideData = OneAndOnlyOne("p:cSld") # pyright: ignore[reportAssignmentType]
259
+ del _tag_seq
260
+
261
+
262
+ class CT_SlideLayoutIdList(BaseOxmlElement):
263
+ """`p:sldLayoutIdLst` element, child of `p:sldMaster`.
264
+
265
+ Contains references to the slide layouts that inherit from the slide master.
266
+ """
267
+
268
+ sldLayoutId_lst: list[CT_SlideLayoutIdListEntry]
269
+
270
+ sldLayoutId = ZeroOrMore("p:sldLayoutId")
271
+
272
+
273
+ class CT_SlideLayoutIdListEntry(BaseOxmlElement):
274
+ """`p:sldLayoutId` element, child of `p:sldLayoutIdLst`.
275
+
276
+ Contains a reference to a slide layout.
277
+ """
278
+
279
+ rId: str = RequiredAttribute("r:id", XsdString) # pyright: ignore[reportAssignmentType]
280
+
281
+
282
+ class CT_SlideMaster(_BaseSlideElement):
283
+ """`p:sldMaster` element, root of a slide master part."""
284
+
285
+ get_or_add_sldLayoutIdLst: Callable[[], CT_SlideLayoutIdList]
286
+
287
+ _tag_seq = (
288
+ "p:cSld",
289
+ "p:clrMap",
290
+ "p:sldLayoutIdLst",
291
+ "p:transition",
292
+ "p:timing",
293
+ "p:hf",
294
+ "p:txStyles",
295
+ "p:extLst",
296
+ )
297
+ cSld: CT_CommonSlideData = OneAndOnlyOne("p:cSld") # pyright: ignore[reportAssignmentType]
298
+ sldLayoutIdLst: CT_SlideLayoutIdList = ZeroOrOne( # pyright: ignore[reportAssignmentType]
299
+ "p:sldLayoutIdLst", successors=_tag_seq[3:]
300
+ )
301
+ del _tag_seq
302
+
303
+
304
+ class CT_SlideTiming(BaseOxmlElement):
305
+ """`p:timing` element, specifying animations and timed behaviors."""
306
+
307
+ _tag_seq = ("p:tnLst", "p:bldLst", "p:extLst")
308
+ tnLst = ZeroOrOne("p:tnLst", successors=_tag_seq[1:])
309
+ del _tag_seq
310
+
311
+
312
+ class CT_TimeNodeList(BaseOxmlElement):
313
+ """`p:tnLst` or `p:childTnList` element."""
314
+
315
+ def add_video(self, shape_id):
316
+ """Add a new `p:video` child element for movie having *shape_id*."""
317
+ video_xml = (
318
+ "<p:video %s>\n"
319
+ ' <p:cMediaNode vol="80000">\n'
320
+ ' <p:cTn id="%d" fill="hold" display="0">\n'
321
+ " <p:stCondLst>\n"
322
+ ' <p:cond delay="indefinite"/>\n'
323
+ " </p:stCondLst>\n"
324
+ " </p:cTn>\n"
325
+ " <p:tgtEl>\n"
326
+ ' <p:spTgt spid="%d"/>\n'
327
+ " </p:tgtEl>\n"
328
+ " </p:cMediaNode>\n"
329
+ "</p:video>\n" % (nsdecls("p"), self._next_cTn_id, shape_id)
330
+ )
331
+ video = parse_xml(video_xml)
332
+ self.append(video)
333
+
334
+ @property
335
+ def _next_cTn_id(self):
336
+ """Return the next available unique ID (int) for p:cTn element."""
337
+ cTn_id_strs = self.xpath("/p:sld/p:timing//p:cTn/@id")
338
+ ids = [int(id_str) for id_str in cTn_id_strs]
339
+ return max(ids) + 1
340
+
341
+
342
+ class CT_TLMediaNodeVideo(BaseOxmlElement):
343
+ """`p:video` element, specifying video media details."""
344
+
345
+ _tag_seq = ("p:cMediaNode",)
346
+ cMediaNode = OneAndOnlyOne("p:cMediaNode")
347
+ del _tag_seq