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.
Files changed (175) hide show
  1. pptx2/__init__.py +152 -0
  2. pptx2/_color.py +75 -0
  3. pptx2/_slide_importer.py +597 -0
  4. pptx2/_svg.py +155 -0
  5. pptx2/_template_applier.py +292 -0
  6. pptx2/_textstyle.py +187 -0
  7. pptx2/accessibility.py +365 -0
  8. pptx2/action.py +270 -0
  9. pptx2/animation.py +2237 -0
  10. pptx2/api.py +49 -0
  11. pptx2/audit.py +258 -0
  12. pptx2/chart/__init__.py +0 -0
  13. pptx2/chart/analytics.py +381 -0
  14. pptx2/chart/axis.py +543 -0
  15. pptx2/chart/category.py +200 -0
  16. pptx2/chart/chart.py +670 -0
  17. pptx2/chart/data.py +864 -0
  18. pptx2/chart/datalabel.py +406 -0
  19. pptx2/chart/legend.py +86 -0
  20. pptx2/chart/marker.py +70 -0
  21. pptx2/chart/palettes.py +129 -0
  22. pptx2/chart/plot.py +462 -0
  23. pptx2/chart/point.py +101 -0
  24. pptx2/chart/quick_layouts.py +325 -0
  25. pptx2/chart/series.py +334 -0
  26. pptx2/chart/xlsx.py +272 -0
  27. pptx2/chart/xmlwriter.py +1845 -0
  28. pptx2/compose/__init__.py +28 -0
  29. pptx2/compose/from_spec.py +1094 -0
  30. pptx2/design/__init__.py +8 -0
  31. pptx2/design/components.py +607 -0
  32. pptx2/design/figures.py +389 -0
  33. pptx2/design/layout.py +370 -0
  34. pptx2/design/recipes.py +1967 -0
  35. pptx2/design/style.py +209 -0
  36. pptx2/design/tokens.py +915 -0
  37. pptx2/diagrams.py +754 -0
  38. pptx2/dml/__init__.py +0 -0
  39. pptx2/dml/chtfmt.py +40 -0
  40. pptx2/dml/color.py +496 -0
  41. pptx2/dml/effect.py +909 -0
  42. pptx2/dml/fill.py +691 -0
  43. pptx2/dml/line.py +287 -0
  44. pptx2/dml/picture.py +212 -0
  45. pptx2/dml/three_d.py +381 -0
  46. pptx2/enum/__init__.py +0 -0
  47. pptx2/enum/action.py +71 -0
  48. pptx2/enum/animation.py +31 -0
  49. pptx2/enum/base.py +218 -0
  50. pptx2/enum/chart.py +574 -0
  51. pptx2/enum/dml.py +740 -0
  52. pptx2/enum/lang.py +685 -0
  53. pptx2/enum/presentation.py +133 -0
  54. pptx2/enum/shapes.py +1029 -0
  55. pptx2/enum/text.py +230 -0
  56. pptx2/exc.py +42 -0
  57. pptx2/formats.py +139 -0
  58. pptx2/geometry.py +420 -0
  59. pptx2/inherit.py +109 -0
  60. pptx2/lint.py +2256 -0
  61. pptx2/math.py +177 -0
  62. pptx2/media.py +197 -0
  63. pptx2/opc/__init__.py +0 -0
  64. pptx2/opc/constants.py +332 -0
  65. pptx2/opc/oxml.py +188 -0
  66. pptx2/opc/package.py +762 -0
  67. pptx2/opc/packuri.py +109 -0
  68. pptx2/opc/serialized.py +296 -0
  69. pptx2/opc/shared.py +20 -0
  70. pptx2/opc/spec.py +45 -0
  71. pptx2/oxml/__init__.py +555 -0
  72. pptx2/oxml/action.py +53 -0
  73. pptx2/oxml/chart/__init__.py +0 -0
  74. pptx2/oxml/chart/axis.py +337 -0
  75. pptx2/oxml/chart/chart.py +481 -0
  76. pptx2/oxml/chart/datalabel.py +253 -0
  77. pptx2/oxml/chart/legend.py +72 -0
  78. pptx2/oxml/chart/marker.py +61 -0
  79. pptx2/oxml/chart/plot.py +365 -0
  80. pptx2/oxml/chart/series.py +425 -0
  81. pptx2/oxml/chart/shared.py +220 -0
  82. pptx2/oxml/coreprops.py +288 -0
  83. pptx2/oxml/dml/__init__.py +0 -0
  84. pptx2/oxml/dml/color.py +135 -0
  85. pptx2/oxml/dml/effect.py +213 -0
  86. pptx2/oxml/dml/fill.py +316 -0
  87. pptx2/oxml/dml/line.py +12 -0
  88. pptx2/oxml/dml/three_d.py +110 -0
  89. pptx2/oxml/ns.py +135 -0
  90. pptx2/oxml/presentation.py +313 -0
  91. pptx2/oxml/shapes/__init__.py +19 -0
  92. pptx2/oxml/shapes/autoshape.py +467 -0
  93. pptx2/oxml/shapes/connector.py +107 -0
  94. pptx2/oxml/shapes/graphfrm.py +347 -0
  95. pptx2/oxml/shapes/groupshape.py +329 -0
  96. pptx2/oxml/shapes/picture.py +270 -0
  97. pptx2/oxml/shapes/shared.py +577 -0
  98. pptx2/oxml/simpletypes.py +1027 -0
  99. pptx2/oxml/slide.py +563 -0
  100. pptx2/oxml/table.py +650 -0
  101. pptx2/oxml/text.py +815 -0
  102. pptx2/oxml/theme.py +36 -0
  103. pptx2/oxml/xmlchemy.py +717 -0
  104. pptx2/package.py +222 -0
  105. pptx2/parts/__init__.py +0 -0
  106. pptx2/parts/chart.py +95 -0
  107. pptx2/parts/coreprops.py +167 -0
  108. pptx2/parts/diagram.py +37 -0
  109. pptx2/parts/embeddedpackage.py +93 -0
  110. pptx2/parts/image.py +275 -0
  111. pptx2/parts/media.py +37 -0
  112. pptx2/parts/presentation.py +136 -0
  113. pptx2/parts/slide.py +371 -0
  114. pptx2/presentation.py +408 -0
  115. pptx2/py.typed +0 -0
  116. pptx2/render.py +586 -0
  117. pptx2/section.py +272 -0
  118. pptx2/shapes/__init__.py +26 -0
  119. pptx2/shapes/autoshape.py +442 -0
  120. pptx2/shapes/base.py +1078 -0
  121. pptx2/shapes/connector.py +297 -0
  122. pptx2/shapes/freeform.py +337 -0
  123. pptx2/shapes/graphfrm.py +316 -0
  124. pptx2/shapes/group.py +264 -0
  125. pptx2/shapes/picture.py +422 -0
  126. pptx2/shapes/placeholder.py +468 -0
  127. pptx2/shapes/shapetree.py +2027 -0
  128. pptx2/shared.py +82 -0
  129. pptx2/skill/SKILL.md +450 -0
  130. pptx2/skill/__init__.py +78 -0
  131. pptx2/skill/__main__.py +64 -0
  132. pptx2/skill/references/animations.md +189 -0
  133. pptx2/skill/references/basics.md +421 -0
  134. pptx2/skill/references/charts.md +254 -0
  135. pptx2/skill/references/compose.md +234 -0
  136. pptx2/skill/references/design.md +366 -0
  137. pptx2/skill/references/effects.md +249 -0
  138. pptx2/skill/references/end-to-end-deck.md +231 -0
  139. pptx2/skill/references/geometry-and-arrows.md +334 -0
  140. pptx2/skill/references/lint.md +275 -0
  141. pptx2/skill/references/math.md +86 -0
  142. pptx2/skill/references/picture-effects.md +129 -0
  143. pptx2/skill/references/render.md +151 -0
  144. pptx2/skill/references/smart-art.md +75 -0
  145. pptx2/skill/references/space-aware-authoring.md +249 -0
  146. pptx2/skill/references/tables.md +244 -0
  147. pptx2/skill/references/theme.md +127 -0
  148. pptx2/skill/references/three-d.md +109 -0
  149. pptx2/skill/references/transitions.md +100 -0
  150. pptx2/slide.py +1244 -0
  151. pptx2/smart_art.py +220 -0
  152. pptx2/spec.py +633 -0
  153. pptx2/table.py +1181 -0
  154. pptx2/table_styles.py +184 -0
  155. pptx2/templates/default.pptx +0 -0
  156. pptx2/templates/docx-icon.emf +0 -0
  157. pptx2/templates/generic-icon.emf +0 -0
  158. pptx2/templates/notes.xml +23 -0
  159. pptx2/templates/notesMaster.xml +352 -0
  160. pptx2/templates/pptx-icon.emf +0 -0
  161. pptx2/templates/theme.xml +321 -0
  162. pptx2/templates/xlsx-icon.emf +0 -0
  163. pptx2/text/__init__.py +0 -0
  164. pptx2/text/fonts.py +482 -0
  165. pptx2/text/layout.py +374 -0
  166. pptx2/text/text.py +1272 -0
  167. pptx2/theme.py +721 -0
  168. pptx2/types.py +36 -0
  169. pptx2/util.py +263 -0
  170. python_pptx2-2.13.0.dist-info/METADATA +351 -0
  171. python_pptx2-2.13.0.dist-info/RECORD +175 -0
  172. python_pptx2-2.13.0.dist-info/WHEEL +5 -0
  173. python_pptx2-2.13.0.dist-info/entry_points.txt +3 -0
  174. python_pptx2-2.13.0.dist-info/licenses/LICENSE +22 -0
  175. python_pptx2-2.13.0.dist-info/top_level.txt +1 -0
pptx2/design/style.py ADDED
@@ -0,0 +1,209 @@
1
+ """Token-resolving style facade for shapes.
2
+
3
+ :class:`ShapeStyle` is the high-level "design system" view of a shape:
4
+ callers assign whole tokens to ``shape.style.fill`` / ``shape.style.shadow``
5
+ / etc., and the facade fans the assignment out into the underlying
6
+ :class:`~pptx2.dml.fill.FillFormat`, :class:`~pptx2.dml.line.LineFormat`,
7
+ and :class:`~pptx2.dml.effect.ShadowFormat` calls.
8
+
9
+ This is purely additive — the low-level fill/line/shadow APIs continue to
10
+ work and are the right tool when a caller needs fine-grained control.
11
+ ``shape.style`` exists so recipe code stays declarative::
12
+
13
+ shape.style.fill = tokens.palette["primary"]
14
+ shape.style.line = tokens.palette["primary"]
15
+ shape.style.shadow = tokens.shadows["card"]
16
+ shape.style.text_color = tokens.palette["neutral"]
17
+ shape.style.font = tokens.typography["body"]
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from typing import TYPE_CHECKING, Optional, Tuple, Union
23
+
24
+ from pptx2.design.tokens import ShadowToken, TypographyToken
25
+ from pptx2.dml.color import RGBColor
26
+
27
+ if TYPE_CHECKING:
28
+ from pptx2.shapes.base import BaseShape
29
+
30
+ #: Anything :func:`pptx2.design.tokens._coerce_color` can turn into an RGB
31
+ #: triple — an :class:`RGBColor`, a 6-digit hex string (with or without
32
+ #: a leading ``#``), or a 3-tuple of ints.
33
+ ColorLike = Union[RGBColor, str, Tuple[int, int, int]]
34
+
35
+
36
+ class ShapeStyle:
37
+ """Style facade that resolves design tokens onto the shape's low-level proxies.
38
+
39
+ Attribute *getters* are deliberately not implemented for token-shaped
40
+ properties: the underlying fill/line/shadow APIs are the source of
41
+ truth for what's actually set, and a getter that round-trips a token
42
+ through the shape's XML can't faithfully reconstruct the token's
43
+ name. Use ``shape.fill`` / ``shape.line`` / ``shape.shadow`` for
44
+ reads.
45
+ """
46
+
47
+ def __init__(self, shape: "BaseShape"):
48
+ self._shape = shape
49
+
50
+ # ------------------------------------------------------------------
51
+ # Fill
52
+ # ------------------------------------------------------------------
53
+
54
+ @property
55
+ def fill(self) -> None:
56
+ raise AttributeError(
57
+ "ShapeStyle.fill is write-only; read shape.fill for the underlying proxy"
58
+ )
59
+
60
+ @fill.setter
61
+ def fill(self, value: Optional[ColorLike]) -> None:
62
+ """Apply a solid fill in *value* to the shape.
63
+
64
+ Accepts an :class:`RGBColor` (hex string / 3-tuple are coerced
65
+ the same way as :class:`pptx2.design.tokens.DesignTokens`). Pass
66
+ ``None`` to clear the fill (transparent).
67
+ """
68
+ from pptx2.design.tokens import _coerce_color # noqa: PLC0415
69
+
70
+ fill = self._shape.fill # type: ignore[attr-defined]
71
+ if value is None:
72
+ fill.background()
73
+ return
74
+ rgb = _coerce_color(value)
75
+ fill.solid()
76
+ fill.fore_color.rgb = rgb
77
+
78
+ # ------------------------------------------------------------------
79
+ # Line
80
+ # ------------------------------------------------------------------
81
+
82
+ @property
83
+ def line(self) -> None:
84
+ raise AttributeError(
85
+ "ShapeStyle.line is write-only; read shape.line for the underlying proxy"
86
+ )
87
+
88
+ @line.setter
89
+ def line(self, value: Optional[ColorLike]) -> None:
90
+ """Apply a solid line color. ``None`` clears the line."""
91
+ from pptx2.design.tokens import _coerce_color # noqa: PLC0415
92
+
93
+ line = self._shape.line # type: ignore[attr-defined]
94
+ if value is None:
95
+ line.fill.background()
96
+ return
97
+ rgb = _coerce_color(value)
98
+ line.color.rgb = rgb
99
+
100
+ # ------------------------------------------------------------------
101
+ # Shadow
102
+ # ------------------------------------------------------------------
103
+
104
+ @property
105
+ def shadow(self) -> None:
106
+ raise AttributeError(
107
+ "ShapeStyle.shadow is write-only; read shape.shadow for the underlying proxy"
108
+ )
109
+
110
+ @shadow.setter
111
+ def shadow(self, value: Optional[ShadowToken]) -> None:
112
+ """Apply a :class:`ShadowToken` to the shape's outer shadow.
113
+
114
+ Each unset token attribute is left untouched on the shape, so a
115
+ token that only specifies ``blur_radius`` won't blow away an
116
+ existing distance/direction. ``None`` clears the shadow entirely.
117
+ """
118
+ shadow = self._shape.shadow
119
+ if value is None:
120
+ shadow.blur_radius = None
121
+ shadow.distance = None
122
+ shadow.direction = None
123
+ return
124
+ if not isinstance(value, ShadowToken):
125
+ value = ShadowToken.from_value(value)
126
+ if value.blur_radius is not None:
127
+ shadow.blur_radius = value.blur_radius
128
+ if value.distance is not None:
129
+ shadow.distance = value.distance
130
+ if value.direction is not None:
131
+ shadow.direction = value.direction
132
+ if value.color is not None:
133
+ shadow.color.rgb = value.color
134
+ if value.alpha is not None:
135
+ # Alpha requires an explicit color to attach to. If the
136
+ # token didn't set one and the shape's shadow has no color
137
+ # yet, leave alpha alone (the shadow keeps inheriting its
138
+ # color, including its alpha, from the theme).
139
+ try:
140
+ shadow.color.alpha = value.alpha
141
+ except ValueError:
142
+ pass
143
+
144
+ # ------------------------------------------------------------------
145
+ # Text color / font (for shapes with text frames)
146
+ # ------------------------------------------------------------------
147
+
148
+ @property
149
+ def text_color(self) -> None:
150
+ raise AttributeError(
151
+ "ShapeStyle.text_color is write-only; iterate runs for reads"
152
+ )
153
+
154
+ @text_color.setter
155
+ def text_color(self, value: Optional[ColorLike]) -> None:
156
+ """Set every run's font color in this shape's text frame.
157
+
158
+ Silently no-ops on shapes that don't have a text frame.
159
+ """
160
+ from pptx2.design.tokens import _coerce_color # noqa: PLC0415
161
+
162
+ text_frame = _text_frame(self._shape)
163
+ if text_frame is None:
164
+ return
165
+ rgb = None if value is None else _coerce_color(value)
166
+ for paragraph in text_frame.paragraphs:
167
+ for run in paragraph.runs:
168
+ if rgb is None:
169
+ # Best-effort clear: assigning None to font.color.rgb
170
+ # is a no-op upstream, so leave it untouched.
171
+ continue
172
+ run.font.color.rgb = rgb
173
+
174
+ @property
175
+ def font(self) -> None:
176
+ raise AttributeError(
177
+ "ShapeStyle.font is write-only; iterate runs for reads"
178
+ )
179
+
180
+ @font.setter
181
+ def font(self, value: TypographyToken) -> None:
182
+ """Apply a :class:`TypographyToken` to every run in the text frame.
183
+
184
+ Unset token attributes (``size`` / ``bold`` / ``italic`` /
185
+ ``color``) leave the run's existing values alone.
186
+ """
187
+ if not isinstance(value, TypographyToken):
188
+ value = TypographyToken.from_value(value)
189
+ text_frame = _text_frame(self._shape)
190
+ if text_frame is None:
191
+ return
192
+ for paragraph in text_frame.paragraphs:
193
+ for run in paragraph.runs:
194
+ font = run.font
195
+ font.name = value.family
196
+ if value.size is not None:
197
+ font.size = value.size
198
+ if value.bold is not None:
199
+ font.bold = value.bold
200
+ if value.italic is not None:
201
+ font.italic = value.italic
202
+ if value.color is not None:
203
+ font.color.rgb = value.color
204
+
205
+
206
+ def _text_frame(shape: "BaseShape"):
207
+ if getattr(shape, "has_text_frame", False):
208
+ return shape.text_frame # type: ignore[attr-defined]
209
+ return None