python-pptx2 2.13.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.
- pptx2/__init__.py +152 -0
- pptx2/_color.py +75 -0
- pptx2/_slide_importer.py +597 -0
- pptx2/_svg.py +155 -0
- pptx2/_template_applier.py +292 -0
- pptx2/_textstyle.py +187 -0
- pptx2/accessibility.py +365 -0
- pptx2/action.py +270 -0
- pptx2/animation.py +2237 -0
- pptx2/api.py +49 -0
- pptx2/audit.py +258 -0
- pptx2/chart/__init__.py +0 -0
- pptx2/chart/analytics.py +381 -0
- pptx2/chart/axis.py +543 -0
- pptx2/chart/category.py +200 -0
- pptx2/chart/chart.py +670 -0
- pptx2/chart/data.py +864 -0
- pptx2/chart/datalabel.py +406 -0
- pptx2/chart/legend.py +86 -0
- pptx2/chart/marker.py +70 -0
- pptx2/chart/palettes.py +129 -0
- pptx2/chart/plot.py +462 -0
- pptx2/chart/point.py +101 -0
- pptx2/chart/quick_layouts.py +325 -0
- pptx2/chart/series.py +334 -0
- pptx2/chart/xlsx.py +272 -0
- pptx2/chart/xmlwriter.py +1845 -0
- pptx2/compose/__init__.py +28 -0
- pptx2/compose/from_spec.py +1094 -0
- pptx2/design/__init__.py +8 -0
- pptx2/design/components.py +607 -0
- pptx2/design/figures.py +389 -0
- pptx2/design/layout.py +370 -0
- pptx2/design/recipes.py +1967 -0
- pptx2/design/style.py +209 -0
- pptx2/design/tokens.py +915 -0
- pptx2/diagrams.py +754 -0
- pptx2/dml/__init__.py +0 -0
- pptx2/dml/chtfmt.py +40 -0
- pptx2/dml/color.py +496 -0
- pptx2/dml/effect.py +909 -0
- pptx2/dml/fill.py +691 -0
- pptx2/dml/line.py +287 -0
- pptx2/dml/picture.py +212 -0
- pptx2/dml/three_d.py +381 -0
- pptx2/enum/__init__.py +0 -0
- pptx2/enum/action.py +71 -0
- pptx2/enum/animation.py +31 -0
- pptx2/enum/base.py +218 -0
- pptx2/enum/chart.py +574 -0
- pptx2/enum/dml.py +740 -0
- pptx2/enum/lang.py +685 -0
- pptx2/enum/presentation.py +133 -0
- pptx2/enum/shapes.py +1029 -0
- pptx2/enum/text.py +230 -0
- pptx2/exc.py +42 -0
- pptx2/formats.py +139 -0
- pptx2/geometry.py +420 -0
- pptx2/inherit.py +109 -0
- pptx2/lint.py +2256 -0
- pptx2/math.py +177 -0
- pptx2/media.py +197 -0
- pptx2/opc/__init__.py +0 -0
- pptx2/opc/constants.py +332 -0
- pptx2/opc/oxml.py +188 -0
- pptx2/opc/package.py +762 -0
- pptx2/opc/packuri.py +109 -0
- pptx2/opc/serialized.py +296 -0
- pptx2/opc/shared.py +20 -0
- pptx2/opc/spec.py +45 -0
- pptx2/oxml/__init__.py +555 -0
- pptx2/oxml/action.py +53 -0
- pptx2/oxml/chart/__init__.py +0 -0
- pptx2/oxml/chart/axis.py +337 -0
- pptx2/oxml/chart/chart.py +481 -0
- pptx2/oxml/chart/datalabel.py +253 -0
- pptx2/oxml/chart/legend.py +72 -0
- pptx2/oxml/chart/marker.py +61 -0
- pptx2/oxml/chart/plot.py +365 -0
- pptx2/oxml/chart/series.py +425 -0
- pptx2/oxml/chart/shared.py +220 -0
- pptx2/oxml/coreprops.py +288 -0
- pptx2/oxml/dml/__init__.py +0 -0
- pptx2/oxml/dml/color.py +135 -0
- pptx2/oxml/dml/effect.py +213 -0
- pptx2/oxml/dml/fill.py +316 -0
- pptx2/oxml/dml/line.py +12 -0
- pptx2/oxml/dml/three_d.py +110 -0
- pptx2/oxml/ns.py +135 -0
- pptx2/oxml/presentation.py +313 -0
- pptx2/oxml/shapes/__init__.py +19 -0
- pptx2/oxml/shapes/autoshape.py +467 -0
- pptx2/oxml/shapes/connector.py +107 -0
- pptx2/oxml/shapes/graphfrm.py +347 -0
- pptx2/oxml/shapes/groupshape.py +329 -0
- pptx2/oxml/shapes/picture.py +270 -0
- pptx2/oxml/shapes/shared.py +577 -0
- pptx2/oxml/simpletypes.py +1027 -0
- pptx2/oxml/slide.py +563 -0
- pptx2/oxml/table.py +650 -0
- pptx2/oxml/text.py +815 -0
- pptx2/oxml/theme.py +36 -0
- pptx2/oxml/xmlchemy.py +717 -0
- pptx2/package.py +222 -0
- pptx2/parts/__init__.py +0 -0
- pptx2/parts/chart.py +95 -0
- pptx2/parts/coreprops.py +167 -0
- pptx2/parts/diagram.py +37 -0
- pptx2/parts/embeddedpackage.py +93 -0
- pptx2/parts/image.py +275 -0
- pptx2/parts/media.py +37 -0
- pptx2/parts/presentation.py +136 -0
- pptx2/parts/slide.py +371 -0
- pptx2/presentation.py +408 -0
- pptx2/py.typed +0 -0
- pptx2/render.py +586 -0
- pptx2/section.py +272 -0
- pptx2/shapes/__init__.py +26 -0
- pptx2/shapes/autoshape.py +442 -0
- pptx2/shapes/base.py +1078 -0
- pptx2/shapes/connector.py +297 -0
- pptx2/shapes/freeform.py +337 -0
- pptx2/shapes/graphfrm.py +316 -0
- pptx2/shapes/group.py +264 -0
- pptx2/shapes/picture.py +422 -0
- pptx2/shapes/placeholder.py +468 -0
- pptx2/shapes/shapetree.py +2027 -0
- pptx2/shared.py +82 -0
- pptx2/skill/SKILL.md +450 -0
- pptx2/skill/__init__.py +78 -0
- pptx2/skill/__main__.py +64 -0
- pptx2/skill/references/animations.md +189 -0
- pptx2/skill/references/basics.md +421 -0
- pptx2/skill/references/charts.md +254 -0
- pptx2/skill/references/compose.md +234 -0
- pptx2/skill/references/design.md +366 -0
- pptx2/skill/references/effects.md +249 -0
- pptx2/skill/references/end-to-end-deck.md +231 -0
- pptx2/skill/references/geometry-and-arrows.md +334 -0
- pptx2/skill/references/lint.md +275 -0
- pptx2/skill/references/math.md +86 -0
- pptx2/skill/references/picture-effects.md +129 -0
- pptx2/skill/references/render.md +151 -0
- pptx2/skill/references/smart-art.md +75 -0
- pptx2/skill/references/space-aware-authoring.md +249 -0
- pptx2/skill/references/tables.md +244 -0
- pptx2/skill/references/theme.md +127 -0
- pptx2/skill/references/three-d.md +109 -0
- pptx2/skill/references/transitions.md +100 -0
- pptx2/slide.py +1244 -0
- pptx2/smart_art.py +220 -0
- pptx2/spec.py +633 -0
- pptx2/table.py +1181 -0
- pptx2/table_styles.py +184 -0
- pptx2/templates/default.pptx +0 -0
- pptx2/templates/docx-icon.emf +0 -0
- pptx2/templates/generic-icon.emf +0 -0
- pptx2/templates/notes.xml +23 -0
- pptx2/templates/notesMaster.xml +352 -0
- pptx2/templates/pptx-icon.emf +0 -0
- pptx2/templates/theme.xml +321 -0
- pptx2/templates/xlsx-icon.emf +0 -0
- pptx2/text/__init__.py +0 -0
- pptx2/text/fonts.py +482 -0
- pptx2/text/layout.py +374 -0
- pptx2/text/text.py +1272 -0
- pptx2/theme.py +721 -0
- pptx2/types.py +36 -0
- pptx2/util.py +263 -0
- python_pptx2-2.13.0.dist-info/METADATA +351 -0
- python_pptx2-2.13.0.dist-info/RECORD +175 -0
- python_pptx2-2.13.0.dist-info/WHEEL +5 -0
- python_pptx2-2.13.0.dist-info/entry_points.txt +3 -0
- python_pptx2-2.13.0.dist-info/licenses/LICENSE +22 -0
- python_pptx2-2.13.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
# pyright: reportPrivateUsage=false
|
|
2
|
+
|
|
3
|
+
"""lxml custom element classes for shape-related XML elements."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Callable, cast
|
|
8
|
+
|
|
9
|
+
from pptx2.enum.shapes import MSO_AUTO_SHAPE_TYPE, PP_PLACEHOLDER
|
|
10
|
+
from pptx2.oxml import parse_xml
|
|
11
|
+
from pptx2.oxml.ns import nsdecls
|
|
12
|
+
from pptx2.oxml.shapes.shared import BaseShapeElement
|
|
13
|
+
from pptx2.oxml.simpletypes import (
|
|
14
|
+
ST_Coordinate,
|
|
15
|
+
ST_PathShadeType,
|
|
16
|
+
ST_PositiveCoordinate,
|
|
17
|
+
XsdBoolean,
|
|
18
|
+
XsdString,
|
|
19
|
+
)
|
|
20
|
+
from pptx2.oxml.text import CT_TextBody
|
|
21
|
+
from pptx2.oxml.xmlchemy import (
|
|
22
|
+
BaseOxmlElement,
|
|
23
|
+
OneAndOnlyOne,
|
|
24
|
+
OptionalAttribute,
|
|
25
|
+
RequiredAttribute,
|
|
26
|
+
ZeroOrMore,
|
|
27
|
+
ZeroOrOne,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if TYPE_CHECKING:
|
|
31
|
+
from pptx2.oxml.shapes.shared import (
|
|
32
|
+
CT_ApplicationNonVisualDrawingProps,
|
|
33
|
+
CT_NonVisualDrawingProps,
|
|
34
|
+
CT_ShapeProperties,
|
|
35
|
+
)
|
|
36
|
+
from pptx2.util import Length
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class CT_AdjPoint2D(BaseOxmlElement):
|
|
40
|
+
"""`a:pt` custom element class."""
|
|
41
|
+
|
|
42
|
+
x: Length = RequiredAttribute("x", ST_Coordinate) # pyright: ignore[reportAssignmentType]
|
|
43
|
+
y: Length = RequiredAttribute("y", ST_Coordinate) # pyright: ignore[reportAssignmentType]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class CT_CustomGeometry2D(BaseOxmlElement):
|
|
47
|
+
"""`a:custGeom` custom element class."""
|
|
48
|
+
|
|
49
|
+
get_or_add_pathLst: Callable[[], CT_Path2DList]
|
|
50
|
+
|
|
51
|
+
_tag_seq = ("a:avLst", "a:gdLst", "a:ahLst", "a:cxnLst", "a:rect", "a:pathLst")
|
|
52
|
+
pathLst: CT_Path2DList | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
|
|
53
|
+
"a:pathLst", successors=_tag_seq[6:]
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class CT_GeomGuide(BaseOxmlElement):
|
|
58
|
+
"""`a:gd` custom element class.
|
|
59
|
+
|
|
60
|
+
Defines a "guide", corresponding to a yellow diamond-shaped handle on an autoshape.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
name: str = RequiredAttribute("name", XsdString) # pyright: ignore[reportAssignmentType]
|
|
64
|
+
fmla: str = RequiredAttribute("fmla", XsdString) # pyright: ignore[reportAssignmentType]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class CT_GeomGuideList(BaseOxmlElement):
|
|
68
|
+
"""`a:avLst` custom element class."""
|
|
69
|
+
|
|
70
|
+
_add_gd: Callable[[], CT_GeomGuide]
|
|
71
|
+
|
|
72
|
+
gd_lst: list[CT_GeomGuide]
|
|
73
|
+
|
|
74
|
+
gd = ZeroOrMore("a:gd")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class CT_NonVisualDrawingShapeProps(BaseShapeElement):
|
|
78
|
+
"""`p:cNvSpPr` custom element class."""
|
|
79
|
+
|
|
80
|
+
spLocks = ZeroOrOne("a:spLocks")
|
|
81
|
+
txBox: bool | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
|
|
82
|
+
"txBox", XsdBoolean
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class CT_Path2D(BaseOxmlElement):
|
|
87
|
+
"""`a:path` custom element class.
|
|
88
|
+
|
|
89
|
+
Used both as a 2D drawing path child of `a:pathLst` (geometry) and as the
|
|
90
|
+
non-linear shade-property child of `a:gradFill`. The gradient-only
|
|
91
|
+
`path` attribute (``"circle" | "rect" | "shape"``) is exposed alongside
|
|
92
|
+
the geometry-only `w`/`h` attributes — neither overlaps in valid OOXML.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
_add_close: Callable[[], CT_Path2DClose]
|
|
96
|
+
_add_lnTo: Callable[[], CT_Path2DLineTo]
|
|
97
|
+
_add_moveTo: Callable[[], CT_Path2DMoveTo]
|
|
98
|
+
|
|
99
|
+
close = ZeroOrMore("a:close", successors=())
|
|
100
|
+
lnTo = ZeroOrMore("a:lnTo", successors=())
|
|
101
|
+
moveTo = ZeroOrMore("a:moveTo", successors=())
|
|
102
|
+
w: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
|
|
103
|
+
"w", ST_PositiveCoordinate
|
|
104
|
+
)
|
|
105
|
+
h: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
|
|
106
|
+
"h", ST_PositiveCoordinate
|
|
107
|
+
)
|
|
108
|
+
path: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
|
|
109
|
+
"path", ST_PathShadeType
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def add_close(self) -> CT_Path2DClose:
|
|
113
|
+
"""Return a newly created `a:close` element.
|
|
114
|
+
|
|
115
|
+
The new `a:close` element is appended to this `a:path` element.
|
|
116
|
+
"""
|
|
117
|
+
return self._add_close()
|
|
118
|
+
|
|
119
|
+
def add_lnTo(self, x: Length, y: Length) -> CT_Path2DLineTo:
|
|
120
|
+
"""Return a newly created `a:lnTo` subtree with end point *(x, y)*.
|
|
121
|
+
|
|
122
|
+
The new `a:lnTo` element is appended to this `a:path` element.
|
|
123
|
+
"""
|
|
124
|
+
lnTo = self._add_lnTo()
|
|
125
|
+
pt = lnTo._add_pt()
|
|
126
|
+
pt.x, pt.y = x, y
|
|
127
|
+
return lnTo
|
|
128
|
+
|
|
129
|
+
def add_moveTo(self, x: Length, y: Length):
|
|
130
|
+
"""Return a newly created `a:moveTo` subtree with point `(x, y)`.
|
|
131
|
+
|
|
132
|
+
The new `a:moveTo` element is appended to this `a:path` element.
|
|
133
|
+
"""
|
|
134
|
+
moveTo = self._add_moveTo()
|
|
135
|
+
pt = moveTo._add_pt()
|
|
136
|
+
pt.x, pt.y = x, y
|
|
137
|
+
return moveTo
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class CT_Path2DClose(BaseOxmlElement):
|
|
141
|
+
"""`a:close` custom element class."""
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class CT_Path2DLineTo(BaseOxmlElement):
|
|
145
|
+
"""`a:lnTo` custom element class."""
|
|
146
|
+
|
|
147
|
+
_add_pt: Callable[[], CT_AdjPoint2D]
|
|
148
|
+
|
|
149
|
+
pt = ZeroOrOne("a:pt", successors=())
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class CT_Path2DList(BaseOxmlElement):
|
|
153
|
+
"""`a:pathLst` custom element class."""
|
|
154
|
+
|
|
155
|
+
_add_path: Callable[[], CT_Path2D]
|
|
156
|
+
|
|
157
|
+
path = ZeroOrMore("a:path", successors=())
|
|
158
|
+
|
|
159
|
+
def add_path(self, w: Length, h: Length):
|
|
160
|
+
"""Return a newly created `a:path` child element."""
|
|
161
|
+
path = self._add_path()
|
|
162
|
+
path.w, path.h = w, h
|
|
163
|
+
return path
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class CT_Path2DMoveTo(BaseOxmlElement):
|
|
167
|
+
"""`a:moveTo` custom element class."""
|
|
168
|
+
|
|
169
|
+
_add_pt: Callable[[], CT_AdjPoint2D]
|
|
170
|
+
|
|
171
|
+
pt = ZeroOrOne("a:pt", successors=())
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class CT_PresetGeometry2D(BaseOxmlElement):
|
|
175
|
+
"""`a:prstGeom` custom element class."""
|
|
176
|
+
|
|
177
|
+
_add_avLst: Callable[[], CT_GeomGuideList]
|
|
178
|
+
_remove_avLst: Callable[[], None]
|
|
179
|
+
|
|
180
|
+
avLst: CT_GeomGuideList | None = ZeroOrOne("a:avLst") # pyright: ignore[reportAssignmentType]
|
|
181
|
+
prst: MSO_AUTO_SHAPE_TYPE = RequiredAttribute( # pyright: ignore[reportAssignmentType]
|
|
182
|
+
"prst", MSO_AUTO_SHAPE_TYPE
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
@property
|
|
186
|
+
def gd_lst(self) -> list[CT_GeomGuide]:
|
|
187
|
+
"""Sequence of `a:gd` element children of `a:avLst`. Empty if none are present."""
|
|
188
|
+
avLst = self.avLst
|
|
189
|
+
if avLst is None:
|
|
190
|
+
return []
|
|
191
|
+
return avLst.gd_lst
|
|
192
|
+
|
|
193
|
+
def rewrite_guides(self, guides: list[tuple[str, int]]):
|
|
194
|
+
"""Replace any `a:gd` element children of `a:avLst` with ones forme from `guides`."""
|
|
195
|
+
self._remove_avLst()
|
|
196
|
+
avLst = self._add_avLst()
|
|
197
|
+
for name, val in guides:
|
|
198
|
+
gd = avLst._add_gd()
|
|
199
|
+
gd.name = name
|
|
200
|
+
gd.fmla = "val %d" % val
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class CT_Shape(BaseShapeElement):
|
|
204
|
+
"""`p:sp` custom element class."""
|
|
205
|
+
|
|
206
|
+
get_or_add_txBody: Callable[[], CT_TextBody]
|
|
207
|
+
|
|
208
|
+
nvSpPr: CT_ShapeNonVisual = OneAndOnlyOne("p:nvSpPr") # pyright: ignore[reportAssignmentType]
|
|
209
|
+
spPr: CT_ShapeProperties = OneAndOnlyOne("p:spPr") # pyright: ignore[reportAssignmentType]
|
|
210
|
+
txBody: CT_TextBody | None = ZeroOrOne("p:txBody", successors=("p:extLst",)) # pyright: ignore
|
|
211
|
+
|
|
212
|
+
def add_path(self, w: Length, h: Length) -> CT_Path2D:
|
|
213
|
+
custGeom = self.spPr.custGeom
|
|
214
|
+
if custGeom is None:
|
|
215
|
+
raise ValueError("shape must be freeform")
|
|
216
|
+
pathLst = custGeom.get_or_add_pathLst()
|
|
217
|
+
return pathLst.add_path(w=w, h=h)
|
|
218
|
+
|
|
219
|
+
def get_or_add_ln(self):
|
|
220
|
+
"""Return the `a:ln` grandchild element, newly added if not present."""
|
|
221
|
+
return self.spPr.get_or_add_ln()
|
|
222
|
+
|
|
223
|
+
@property
|
|
224
|
+
def has_custom_geometry(self):
|
|
225
|
+
"""True if this shape has custom geometry, i.e. is a freeform shape.
|
|
226
|
+
|
|
227
|
+
A shape has custom geometry if it has a `p:spPr/a:custGeom`
|
|
228
|
+
descendant (instead of `p:spPr/a:prstGeom`).
|
|
229
|
+
"""
|
|
230
|
+
return self.spPr.custGeom is not None
|
|
231
|
+
|
|
232
|
+
@property
|
|
233
|
+
def is_autoshape(self):
|
|
234
|
+
"""True if this shape is an auto shape.
|
|
235
|
+
|
|
236
|
+
A shape is an auto shape if it has a `a:prstGeom` element and does not have a txBox="1"
|
|
237
|
+
attribute on cNvSpPr.
|
|
238
|
+
"""
|
|
239
|
+
prstGeom = self.prstGeom
|
|
240
|
+
if prstGeom is None:
|
|
241
|
+
return False
|
|
242
|
+
return self.nvSpPr.cNvSpPr.txBox is not True
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def is_textbox(self):
|
|
246
|
+
"""True if this shape is a text box.
|
|
247
|
+
|
|
248
|
+
A shape is a text box if it has a `txBox` attribute on cNvSpPr that resolves to |True|.
|
|
249
|
+
The default when the txBox attribute is missing is |False|.
|
|
250
|
+
"""
|
|
251
|
+
return self.nvSpPr.cNvSpPr.txBox is True
|
|
252
|
+
|
|
253
|
+
@property
|
|
254
|
+
def ln(self):
|
|
255
|
+
"""`a:ln` grand-child element or |None| if not present."""
|
|
256
|
+
return self.spPr.ln
|
|
257
|
+
|
|
258
|
+
@staticmethod
|
|
259
|
+
def new_autoshape_sp(
|
|
260
|
+
id_: int, name: str, prst: str, left: int, top: int, width: int, height: int
|
|
261
|
+
) -> CT_Shape:
|
|
262
|
+
"""Return a new `p:sp` element tree configured as a base auto shape."""
|
|
263
|
+
xml = (
|
|
264
|
+
"<p:sp %s>\n"
|
|
265
|
+
" <p:nvSpPr>\n"
|
|
266
|
+
' <p:cNvPr id="%s" name="%s"/>\n'
|
|
267
|
+
" <p:cNvSpPr/>\n"
|
|
268
|
+
" <p:nvPr/>\n"
|
|
269
|
+
" </p:nvSpPr>\n"
|
|
270
|
+
" <p:spPr>\n"
|
|
271
|
+
" <a:xfrm>\n"
|
|
272
|
+
' <a:off x="%s" y="%s"/>\n'
|
|
273
|
+
' <a:ext cx="%s" cy="%s"/>\n'
|
|
274
|
+
" </a:xfrm>\n"
|
|
275
|
+
' <a:prstGeom prst="%s">\n'
|
|
276
|
+
" <a:avLst/>\n"
|
|
277
|
+
" </a:prstGeom>\n"
|
|
278
|
+
" </p:spPr>\n"
|
|
279
|
+
" <p:style>\n"
|
|
280
|
+
' <a:lnRef idx="1">\n'
|
|
281
|
+
' <a:schemeClr val="accent1"/>\n'
|
|
282
|
+
" </a:lnRef>\n"
|
|
283
|
+
' <a:fillRef idx="3">\n'
|
|
284
|
+
' <a:schemeClr val="accent1"/>\n'
|
|
285
|
+
" </a:fillRef>\n"
|
|
286
|
+
' <a:effectRef idx="2">\n'
|
|
287
|
+
' <a:schemeClr val="accent1"/>\n'
|
|
288
|
+
" </a:effectRef>\n"
|
|
289
|
+
' <a:fontRef idx="minor">\n'
|
|
290
|
+
' <a:schemeClr val="lt1"/>\n'
|
|
291
|
+
" </a:fontRef>\n"
|
|
292
|
+
" </p:style>\n"
|
|
293
|
+
" <p:txBody>\n"
|
|
294
|
+
' <a:bodyPr rtlCol="0" anchor="ctr"/>\n'
|
|
295
|
+
" <a:lstStyle/>\n"
|
|
296
|
+
" <a:p>\n"
|
|
297
|
+
' <a:pPr algn="ctr"/>\n'
|
|
298
|
+
' <a:endParaRPr lang="en-US"/>\n'
|
|
299
|
+
" </a:p>\n"
|
|
300
|
+
" </p:txBody>\n"
|
|
301
|
+
"</p:sp>" % (nsdecls("a", "p"), "%d", "%s", "%d", "%d", "%d", "%d", "%s")
|
|
302
|
+
) % (id_, name, left, top, width, height, prst)
|
|
303
|
+
return cast(CT_Shape, parse_xml(xml))
|
|
304
|
+
|
|
305
|
+
@staticmethod
|
|
306
|
+
def new_freeform_sp(shape_id: int, name: str, x: int, y: int, cx: int, cy: int):
|
|
307
|
+
"""Return new `p:sp` element tree configured as freeform shape.
|
|
308
|
+
|
|
309
|
+
The returned shape has a `a:custGeom` subtree but no paths in its
|
|
310
|
+
path list.
|
|
311
|
+
"""
|
|
312
|
+
xml = (
|
|
313
|
+
"<p:sp %s>\n"
|
|
314
|
+
" <p:nvSpPr>\n"
|
|
315
|
+
' <p:cNvPr id="%s" name="%s"/>\n'
|
|
316
|
+
" <p:cNvSpPr/>\n"
|
|
317
|
+
" <p:nvPr/>\n"
|
|
318
|
+
" </p:nvSpPr>\n"
|
|
319
|
+
" <p:spPr>\n"
|
|
320
|
+
" <a:xfrm>\n"
|
|
321
|
+
' <a:off x="%s" y="%s"/>\n'
|
|
322
|
+
' <a:ext cx="%s" cy="%s"/>\n'
|
|
323
|
+
" </a:xfrm>\n"
|
|
324
|
+
" <a:custGeom>\n"
|
|
325
|
+
" <a:avLst/>\n"
|
|
326
|
+
" <a:gdLst/>\n"
|
|
327
|
+
" <a:ahLst/>\n"
|
|
328
|
+
" <a:cxnLst/>\n"
|
|
329
|
+
' <a:rect l="l" t="t" r="r" b="b"/>\n'
|
|
330
|
+
" <a:pathLst/>\n"
|
|
331
|
+
" </a:custGeom>\n"
|
|
332
|
+
" </p:spPr>\n"
|
|
333
|
+
" <p:style>\n"
|
|
334
|
+
' <a:lnRef idx="1">\n'
|
|
335
|
+
' <a:schemeClr val="accent1"/>\n'
|
|
336
|
+
" </a:lnRef>\n"
|
|
337
|
+
' <a:fillRef idx="3">\n'
|
|
338
|
+
' <a:schemeClr val="accent1"/>\n'
|
|
339
|
+
" </a:fillRef>\n"
|
|
340
|
+
' <a:effectRef idx="2">\n'
|
|
341
|
+
' <a:schemeClr val="accent1"/>\n'
|
|
342
|
+
" </a:effectRef>\n"
|
|
343
|
+
' <a:fontRef idx="minor">\n'
|
|
344
|
+
' <a:schemeClr val="lt1"/>\n'
|
|
345
|
+
" </a:fontRef>\n"
|
|
346
|
+
" </p:style>\n"
|
|
347
|
+
" <p:txBody>\n"
|
|
348
|
+
' <a:bodyPr rtlCol="0" anchor="ctr"/>\n'
|
|
349
|
+
" <a:lstStyle/>\n"
|
|
350
|
+
" <a:p>\n"
|
|
351
|
+
' <a:pPr algn="ctr"/>\n'
|
|
352
|
+
' <a:endParaRPr lang="en-US"/>\n'
|
|
353
|
+
" </a:p>\n"
|
|
354
|
+
" </p:txBody>\n"
|
|
355
|
+
"</p:sp>" % (nsdecls("a", "p"), "%d", "%s", "%d", "%d", "%d", "%d")
|
|
356
|
+
) % (shape_id, name, x, y, cx, cy)
|
|
357
|
+
return cast(CT_Shape, parse_xml(xml))
|
|
358
|
+
|
|
359
|
+
@staticmethod
|
|
360
|
+
def new_placeholder_sp(
|
|
361
|
+
id_: int, name: str, ph_type: PP_PLACEHOLDER, orient: str, sz, idx
|
|
362
|
+
) -> CT_Shape:
|
|
363
|
+
"""Return a new `p:sp` element tree configured as a placeholder shape."""
|
|
364
|
+
sp = cast(
|
|
365
|
+
CT_Shape,
|
|
366
|
+
parse_xml(
|
|
367
|
+
f"<p:sp {nsdecls('a', 'p')}>\n"
|
|
368
|
+
f" <p:nvSpPr>\n"
|
|
369
|
+
f' <p:cNvPr id="{id_}" name="{name}"/>\n'
|
|
370
|
+
f" <p:cNvSpPr>\n"
|
|
371
|
+
f' <a:spLocks noGrp="1"/>\n'
|
|
372
|
+
f" </p:cNvSpPr>\n"
|
|
373
|
+
f" <p:nvPr/>\n"
|
|
374
|
+
f" </p:nvSpPr>\n"
|
|
375
|
+
f" <p:spPr/>\n"
|
|
376
|
+
f"</p:sp>"
|
|
377
|
+
),
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
ph = sp.nvSpPr.nvPr.get_or_add_ph()
|
|
381
|
+
ph.type = ph_type
|
|
382
|
+
ph.idx = idx
|
|
383
|
+
ph.orient = orient
|
|
384
|
+
ph.sz = sz
|
|
385
|
+
|
|
386
|
+
placeholder_types_that_have_a_text_frame = (
|
|
387
|
+
PP_PLACEHOLDER.TITLE,
|
|
388
|
+
PP_PLACEHOLDER.CENTER_TITLE,
|
|
389
|
+
PP_PLACEHOLDER.SUBTITLE,
|
|
390
|
+
PP_PLACEHOLDER.BODY,
|
|
391
|
+
PP_PLACEHOLDER.OBJECT,
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
if ph_type in placeholder_types_that_have_a_text_frame:
|
|
395
|
+
sp.append(CT_TextBody.new())
|
|
396
|
+
|
|
397
|
+
return sp
|
|
398
|
+
|
|
399
|
+
@staticmethod
|
|
400
|
+
def new_textbox_sp(id_, name, left, top, width, height):
|
|
401
|
+
"""Return a new `p:sp` element tree configured as a base textbox shape."""
|
|
402
|
+
tmpl = CT_Shape._textbox_sp_tmpl()
|
|
403
|
+
xml = tmpl % (id_, name, left, top, width, height)
|
|
404
|
+
sp = parse_xml(xml)
|
|
405
|
+
return sp
|
|
406
|
+
|
|
407
|
+
@property
|
|
408
|
+
def prst(self):
|
|
409
|
+
"""Value of `prst` attribute of `a:prstGeom` element or |None| if not present."""
|
|
410
|
+
prstGeom = self.prstGeom
|
|
411
|
+
if prstGeom is None:
|
|
412
|
+
return None
|
|
413
|
+
return prstGeom.prst
|
|
414
|
+
|
|
415
|
+
@property
|
|
416
|
+
def prstGeom(self) -> CT_PresetGeometry2D:
|
|
417
|
+
"""Reference to `a:prstGeom` child element.
|
|
418
|
+
|
|
419
|
+
|None| if this shape doesn't have one, for example, if it's a placeholder shape.
|
|
420
|
+
"""
|
|
421
|
+
return self.spPr.prstGeom
|
|
422
|
+
|
|
423
|
+
def _new_txBody(self):
|
|
424
|
+
return CT_TextBody.new_p_txBody()
|
|
425
|
+
|
|
426
|
+
@staticmethod
|
|
427
|
+
def _textbox_sp_tmpl():
|
|
428
|
+
return (
|
|
429
|
+
"<p:sp %s>\n"
|
|
430
|
+
" <p:nvSpPr>\n"
|
|
431
|
+
' <p:cNvPr id="%s" name="%s"/>\n'
|
|
432
|
+
' <p:cNvSpPr txBox="1"/>\n'
|
|
433
|
+
" <p:nvPr/>\n"
|
|
434
|
+
" </p:nvSpPr>\n"
|
|
435
|
+
" <p:spPr>\n"
|
|
436
|
+
" <a:xfrm>\n"
|
|
437
|
+
' <a:off x="%s" y="%s"/>\n'
|
|
438
|
+
' <a:ext cx="%s" cy="%s"/>\n'
|
|
439
|
+
" </a:xfrm>\n"
|
|
440
|
+
' <a:prstGeom prst="rect">\n'
|
|
441
|
+
" <a:avLst/>\n"
|
|
442
|
+
" </a:prstGeom>\n"
|
|
443
|
+
" <a:noFill/>\n"
|
|
444
|
+
" </p:spPr>\n"
|
|
445
|
+
" <p:txBody>\n"
|
|
446
|
+
' <a:bodyPr wrap="none">\n'
|
|
447
|
+
" <a:spAutoFit/>\n"
|
|
448
|
+
" </a:bodyPr>\n"
|
|
449
|
+
" <a:lstStyle/>\n"
|
|
450
|
+
" <a:p/>\n"
|
|
451
|
+
" </p:txBody>\n"
|
|
452
|
+
"</p:sp>" % (nsdecls("a", "p"), "%d", "%s", "%d", "%d", "%d", "%d")
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
class CT_ShapeNonVisual(BaseShapeElement):
|
|
457
|
+
"""`p:nvSpPr` custom element class."""
|
|
458
|
+
|
|
459
|
+
cNvPr: CT_NonVisualDrawingProps = OneAndOnlyOne( # pyright: ignore[reportAssignmentType]
|
|
460
|
+
"p:cNvPr"
|
|
461
|
+
)
|
|
462
|
+
cNvSpPr: CT_NonVisualDrawingShapeProps = OneAndOnlyOne( # pyright: ignore[reportAssignmentType]
|
|
463
|
+
"p:cNvSpPr"
|
|
464
|
+
)
|
|
465
|
+
nvPr: CT_ApplicationNonVisualDrawingProps = ( # pyright: ignore[reportAssignmentType]
|
|
466
|
+
OneAndOnlyOne("p:nvPr")
|
|
467
|
+
)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"""lxml custom element classes for XML elements related to the Connector shape."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, cast
|
|
6
|
+
|
|
7
|
+
from pptx2.oxml import parse_xml
|
|
8
|
+
from pptx2.oxml.ns import nsdecls
|
|
9
|
+
from pptx2.oxml.shapes.shared import BaseShapeElement
|
|
10
|
+
from pptx2.oxml.simpletypes import ST_DrawingElementId, XsdUnsignedInt
|
|
11
|
+
from pptx2.oxml.xmlchemy import BaseOxmlElement, OneAndOnlyOne, RequiredAttribute, ZeroOrOne
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from pptx2.oxml.shapes.shared import CT_ShapeProperties
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CT_Connection(BaseShapeElement):
|
|
18
|
+
"""A `a:stCxn` or `a:endCxn` element.
|
|
19
|
+
|
|
20
|
+
Specifies a connection between an end-point of a connector and a shape connection point.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
id = RequiredAttribute("id", ST_DrawingElementId)
|
|
24
|
+
idx = RequiredAttribute("idx", XsdUnsignedInt)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class CT_Connector(BaseShapeElement):
|
|
28
|
+
"""A line/connector shape `p:cxnSp` element"""
|
|
29
|
+
|
|
30
|
+
_tag_seq = ("p:nvCxnSpPr", "p:spPr", "p:style", "p:extLst")
|
|
31
|
+
nvCxnSpPr = OneAndOnlyOne("p:nvCxnSpPr")
|
|
32
|
+
spPr: CT_ShapeProperties = OneAndOnlyOne("p:spPr") # pyright: ignore[reportAssignmentType]
|
|
33
|
+
del _tag_seq
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def new_cxnSp(
|
|
37
|
+
cls,
|
|
38
|
+
id_: int,
|
|
39
|
+
name: str,
|
|
40
|
+
prst: str,
|
|
41
|
+
x: int,
|
|
42
|
+
y: int,
|
|
43
|
+
cx: int,
|
|
44
|
+
cy: int,
|
|
45
|
+
flipH: bool,
|
|
46
|
+
flipV: bool,
|
|
47
|
+
) -> CT_Connector:
|
|
48
|
+
"""Return a new `p:cxnSp` element tree configured as a base connector."""
|
|
49
|
+
flip = (' flipH="1"' if flipH else "") + (' flipV="1"' if flipV else "")
|
|
50
|
+
return cast(
|
|
51
|
+
CT_Connector,
|
|
52
|
+
parse_xml(
|
|
53
|
+
f"<p:cxnSp {nsdecls('a', 'p')}>\n"
|
|
54
|
+
f" <p:nvCxnSpPr>\n"
|
|
55
|
+
f' <p:cNvPr id="{id_}" name="{name}"/>\n'
|
|
56
|
+
f" <p:cNvCxnSpPr/>\n"
|
|
57
|
+
f" <p:nvPr/>\n"
|
|
58
|
+
f" </p:nvCxnSpPr>\n"
|
|
59
|
+
f" <p:spPr>\n"
|
|
60
|
+
f" <a:xfrm{flip}>\n"
|
|
61
|
+
f' <a:off x="{x}" y="{y}"/>\n'
|
|
62
|
+
f' <a:ext cx="{cx}" cy="{cy}"/>\n'
|
|
63
|
+
f" </a:xfrm>\n"
|
|
64
|
+
f' <a:prstGeom prst="{prst}">\n'
|
|
65
|
+
f" <a:avLst/>\n"
|
|
66
|
+
f" </a:prstGeom>\n"
|
|
67
|
+
f" </p:spPr>\n"
|
|
68
|
+
f" <p:style>\n"
|
|
69
|
+
f' <a:lnRef idx="2">\n'
|
|
70
|
+
f' <a:schemeClr val="accent1"/>\n'
|
|
71
|
+
f" </a:lnRef>\n"
|
|
72
|
+
f' <a:fillRef idx="0">\n'
|
|
73
|
+
f' <a:schemeClr val="accent1"/>\n'
|
|
74
|
+
f" </a:fillRef>\n"
|
|
75
|
+
f' <a:effectRef idx="1">\n'
|
|
76
|
+
f' <a:schemeClr val="accent1"/>\n'
|
|
77
|
+
f" </a:effectRef>\n"
|
|
78
|
+
f' <a:fontRef idx="minor">\n'
|
|
79
|
+
f' <a:schemeClr val="tx1"/>\n'
|
|
80
|
+
f" </a:fontRef>\n"
|
|
81
|
+
f" </p:style>\n"
|
|
82
|
+
f"</p:cxnSp>"
|
|
83
|
+
),
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class CT_ConnectorNonVisual(BaseOxmlElement):
|
|
88
|
+
"""
|
|
89
|
+
`p:nvCxnSpPr` element, container for the non-visual properties of
|
|
90
|
+
a connector, such as name, id, etc.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
cNvPr = OneAndOnlyOne("p:cNvPr")
|
|
94
|
+
cNvCxnSpPr = OneAndOnlyOne("p:cNvCxnSpPr")
|
|
95
|
+
nvPr = OneAndOnlyOne("p:nvPr")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class CT_NonVisualConnectorProperties(BaseOxmlElement):
|
|
99
|
+
"""
|
|
100
|
+
`p:cNvCxnSpPr` element, container for the non-visual properties specific
|
|
101
|
+
to a connector shape, such as connections and connector locking.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
_tag_seq = ("a:cxnSpLocks", "a:stCxn", "a:endCxn", "a:extLst")
|
|
105
|
+
stCxn = ZeroOrOne("a:stCxn", successors=_tag_seq[2:])
|
|
106
|
+
endCxn = ZeroOrOne("a:endCxn", successors=_tag_seq[3:])
|
|
107
|
+
del _tag_seq
|