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/dml/__init__.py ADDED
File without changes
pptx2/dml/chtfmt.py ADDED
@@ -0,0 +1,40 @@
1
+ """|ChartFormat| and related objects.
2
+
3
+ |ChartFormat| acts as proxy for the `spPr` element, which provides visual shape properties such as
4
+ line and fill for chart elements.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from pptx2.dml.fill import FillFormat
10
+ from pptx2.dml.line import LineFormat
11
+ from pptx2.shared import ElementProxy
12
+ from pptx2.util import lazyproperty
13
+
14
+
15
+ class ChartFormat(ElementProxy):
16
+ """
17
+ The |ChartFormat| object provides access to visual shape properties for
18
+ chart elements like |Axis|, |Series|, and |MajorGridlines|. It has two
19
+ properties, :attr:`fill` and :attr:`line`, which return a |FillFormat|
20
+ and |LineFormat| object respectively. The |ChartFormat| object is
21
+ provided by the :attr:`format` property on the target axis, series, etc.
22
+ """
23
+
24
+ @lazyproperty
25
+ def fill(self):
26
+ """
27
+ |FillFormat| instance for this object, providing access to fill
28
+ properties such as fill color.
29
+ """
30
+ spPr = self._element.get_or_add_spPr()
31
+ return FillFormat.from_fill_parent(spPr)
32
+
33
+ @lazyproperty
34
+ def line(self):
35
+ """
36
+ The |LineFormat| object providing access to the visual properties of
37
+ this object, such as line color and line style.
38
+ """
39
+ spPr = self._element.get_or_add_spPr()
40
+ return LineFormat(spPr)
pptx2/dml/color.py ADDED
@@ -0,0 +1,496 @@
1
+ """DrawingML objects related to color, ColorFormat being the most prominent."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Callable
6
+
7
+ from pptx2.enum.dml import MSO_COLOR_TYPE, MSO_FILL, MSO_THEME_COLOR
8
+ from pptx2.oxml.dml.color import (
9
+ CT_HslColor,
10
+ CT_PresetColor,
11
+ CT_SchemeColor,
12
+ CT_ScRgbColor,
13
+ CT_SRgbColor,
14
+ CT_SystemColor,
15
+ )
16
+
17
+ if TYPE_CHECKING:
18
+ from pptx2.dml.fill import FillFormat
19
+
20
+
21
+ class ColorFormat(object):
22
+ """
23
+ Provides access to color settings such as RGB color, theme color, and
24
+ luminance adjustments.
25
+ """
26
+
27
+ def __init__(self, eg_colorChoice_parent, color):
28
+ super(ColorFormat, self).__init__()
29
+ self._xFill = eg_colorChoice_parent
30
+ self._color = color
31
+
32
+ @property
33
+ def alpha(self):
34
+ """Read/write float in [0.0, 1.0] giving the per-color alpha.
35
+
36
+ `1.0` is fully opaque (the default when no `<a:alpha>` element is
37
+ present); `0.0` is fully transparent. Maps to the `<a:alpha>` child of
38
+ the underlying color element. Assigning |None| removes any explicit
39
+ alpha, restoring full opacity.
40
+ """
41
+ return self._color.alpha
42
+
43
+ @alpha.setter
44
+ def alpha(self, value):
45
+ if isinstance(self._color, _NoneColor):
46
+ raise ValueError(
47
+ "can't set alpha when color.type is None."
48
+ " Set color.rgb or .theme_color first."
49
+ )
50
+ if value is not None:
51
+ self._validate_alpha_value(value)
52
+ self._color.alpha = value
53
+
54
+ @property
55
+ def brightness(self):
56
+ """
57
+ Read/write float value between -1.0 and 1.0 indicating the brightness
58
+ adjustment for this color, e.g. -0.25 is 25% darker and 0.4 is 40%
59
+ lighter. 0 means no brightness adjustment.
60
+ """
61
+ return self._color.brightness
62
+
63
+ @brightness.setter
64
+ def brightness(self, value):
65
+ self._validate_brightness_value(value)
66
+ self._color.brightness = value
67
+
68
+ @classmethod
69
+ def from_colorchoice_parent(cls, eg_colorChoice_parent):
70
+ xClr = eg_colorChoice_parent.eg_colorChoice
71
+ color = _Color(xClr)
72
+ color_format = cls(eg_colorChoice_parent, color)
73
+ return color_format
74
+
75
+ @property
76
+ def rgb(self):
77
+ """
78
+ |RGBColor| value of this color, or None if no RGB color is explicitly
79
+ defined for this font. Setting this value to an |RGBColor| instance
80
+ causes its type to change to MSO_COLOR_TYPE.RGB. If the color was a
81
+ theme color with a brightness adjustment, the brightness adjustment
82
+ is removed when changing it to an RGB color.
83
+ """
84
+ return self._color.rgb
85
+
86
+ @rgb.setter
87
+ def rgb(self, rgb):
88
+ # Accept any documented "color-like" value (RGBColor, '#RRGGBB' hex
89
+ # string with or without '#', or 3-tuple of ints). Historically
90
+ # this setter required RGBColor — leaving callers with a category
91
+ # of "did the wrong source surface accept hex?" footgun.
92
+ from pptx2._color import coerce_color
93
+
94
+ if not isinstance(rgb, RGBColor):
95
+ try:
96
+ rgb = coerce_color(rgb)
97
+ except (TypeError, ValueError) as exc:
98
+ # Preserve the historical exception type for callers that
99
+ # caught ValueError.
100
+ raise ValueError(str(exc)) from exc
101
+ # change to rgb color format if not already
102
+ if not isinstance(self._color, _SRgbColor):
103
+ srgbClr = self._xFill.get_or_change_to_srgbClr()
104
+ self._color = _SRgbColor(srgbClr)
105
+ # call _SRgbColor instance to do the setting
106
+ self._color.rgb = rgb
107
+
108
+ @property
109
+ def theme_color(self):
110
+ """Theme color value of this color.
111
+
112
+ Value is a member of :ref:`MsoThemeColorIndex`, e.g.
113
+ ``MSO_THEME_COLOR.ACCENT_1``. Raises AttributeError on access if the
114
+ color is not type ``MSO_COLOR_TYPE.SCHEME``. Assigning a member of
115
+ :ref:`MsoThemeColorIndex` causes the color's type to change to
116
+ ``MSO_COLOR_TYPE.SCHEME``.
117
+ """
118
+ return self._color.theme_color
119
+
120
+ @theme_color.setter
121
+ def theme_color(self, mso_theme_color_idx):
122
+ # change to theme color format if not already
123
+ if not isinstance(self._color, _SchemeColor):
124
+ schemeClr = self._xFill.get_or_change_to_schemeClr()
125
+ self._color = _SchemeColor(schemeClr)
126
+ self._color.theme_color = mso_theme_color_idx
127
+
128
+ @property
129
+ def type(self):
130
+ """
131
+ Read-only. A value from :ref:`MsoColorType`, either RGB or SCHEME,
132
+ corresponding to the way this color is defined, or None if no color
133
+ is defined at the level of this font.
134
+ """
135
+ return self._color.color_type
136
+
137
+ def _validate_brightness_value(self, value):
138
+ if value < -1.0 or value > 1.0:
139
+ raise ValueError("brightness must be number in range -1.0 to 1.0")
140
+ if isinstance(self._color, _NoneColor):
141
+ msg = (
142
+ "can't set brightness when color.type is None. Set color.rgb"
143
+ " or .theme_color first."
144
+ )
145
+ raise ValueError(msg)
146
+
147
+ @staticmethod
148
+ def _validate_alpha_value(value):
149
+ if value < 0.0 or value > 1.0:
150
+ raise ValueError("alpha must be number in range 0.0 to 1.0")
151
+
152
+
153
+ class _LazyColorFormat(ColorFormat):
154
+ """Color accessor that defers solid-fill materialization until a color is assigned.
155
+
156
+ Reads (`type`, `rgb`, `theme_color`, `brightness`) on a non-solid fill return the
157
+ "no explicit color" sentinel without mutating the underlying XML, which preserves
158
+ theme inheritance. Writes to `rgb` or `theme_color` switch the fill to solid first
159
+ (matching the pre-fix behavior); `brightness` writes still require a color to be
160
+ set first and raise the original `ValueError` otherwise.
161
+
162
+ Callers supply two thunks: `peek_fill` returns the existing |FillFormat| or |None|
163
+ if there is none, without mutating the underlying XML; `ensure_fill` returns a
164
+ |FillFormat|, creating the host element if necessary (used only on write paths).
165
+ """
166
+
167
+ def __init__(
168
+ self,
169
+ peek_fill: Callable[[], FillFormat | None],
170
+ ensure_fill: Callable[[], FillFormat],
171
+ ):
172
+ # -- intentionally bypass ColorFormat.__init__: this proxy resolves the
173
+ # -- underlying _xFill/_color lazily through `peek_fill` / `ensure_fill`.
174
+ self._peek_fill = peek_fill
175
+ self._ensure_fill = ensure_fill
176
+
177
+ @property
178
+ def alpha(self) -> float:
179
+ cf = self._color_or_none()
180
+ return cf.alpha if cf is not None else 1.0
181
+
182
+ @alpha.setter
183
+ def alpha(self, value: float | None):
184
+ # -- alpha is a modifier on an existing color, not a color choice itself
185
+ # -- (cf. brightness). It deliberately does NOT auto-materialize a solid
186
+ # -- fill the way `rgb` and `theme_color` do, because "transparent
187
+ # -- nothing" is not a meaningful color. Set `rgb` or `theme_color` first.
188
+ cf = self._color_or_none()
189
+ if cf is None:
190
+ raise ValueError(
191
+ "can't set alpha when color.type is None."
192
+ " Set color.rgb or .theme_color first."
193
+ )
194
+ cf.alpha = value
195
+
196
+ @property
197
+ def brightness(self) -> float:
198
+ cf = self._color_or_none()
199
+ return cf.brightness if cf is not None else 0
200
+
201
+ @brightness.setter
202
+ def brightness(self, value: float):
203
+ cf = self._color_or_none()
204
+ if cf is None:
205
+ raise ValueError(
206
+ "can't set brightness when color.type is None."
207
+ " Set color.rgb or .theme_color first."
208
+ )
209
+ cf.brightness = value
210
+
211
+ @property
212
+ def rgb(self) -> RGBColor | None:
213
+ cf = self._color_or_none()
214
+ return cf.rgb if cf is not None else None
215
+
216
+ @rgb.setter
217
+ def rgb(self, value: "RGBColor | str | tuple[int, int, int]"):
218
+ # The downstream ColorFormat.rgb setter accepts color-like values
219
+ # (hex strings, 3-tuples, or RGBColor); pass through unchanged.
220
+ self._ensure_solid().rgb = value
221
+
222
+ @property
223
+ def theme_color(self) -> MSO_THEME_COLOR:
224
+ cf = self._color_or_none()
225
+ return cf.theme_color if cf is not None else MSO_THEME_COLOR.NOT_THEME_COLOR
226
+
227
+ @theme_color.setter
228
+ def theme_color(self, value: MSO_THEME_COLOR):
229
+ self._ensure_solid().theme_color = value
230
+
231
+ @property
232
+ def type(self) -> MSO_COLOR_TYPE | None:
233
+ cf = self._color_or_none()
234
+ return cf.type if cf is not None else None
235
+
236
+ def _color_or_none(self) -> ColorFormat | None:
237
+ fill = self._peek_fill()
238
+ if fill is None or fill.type != MSO_FILL.SOLID:
239
+ return None
240
+ return fill.fore_color
241
+
242
+ def _ensure_solid(self) -> ColorFormat:
243
+ fill = self._ensure_fill()
244
+ if fill.type != MSO_FILL.SOLID:
245
+ fill.solid()
246
+ return fill.fore_color
247
+
248
+
249
+ class _Color(object):
250
+ """
251
+ Object factory for color object of the appropriate type, also the base
252
+ class for all color type classes such as SRgbColor.
253
+ """
254
+
255
+ def __new__(cls, xClr):
256
+ color_cls = {
257
+ type(None): _NoneColor,
258
+ CT_HslColor: _HslColor,
259
+ CT_PresetColor: _PrstColor,
260
+ CT_SchemeColor: _SchemeColor,
261
+ CT_ScRgbColor: _ScRgbColor,
262
+ CT_SRgbColor: _SRgbColor,
263
+ CT_SystemColor: _SysColor,
264
+ }[type(xClr)]
265
+ return super(_Color, cls).__new__(color_cls)
266
+
267
+ def __init__(self, xClr):
268
+ super(_Color, self).__init__()
269
+ self._xClr = xClr
270
+
271
+ @property
272
+ def alpha(self):
273
+ """Float in [0.0, 1.0]; `1.0` (fully opaque) when no `<a:alpha>` is set."""
274
+ alpha_elm = self._xClr.alpha
275
+ if alpha_elm is None:
276
+ return 1.0
277
+ return alpha_elm.val
278
+
279
+ @alpha.setter
280
+ def alpha(self, value):
281
+ self._xClr.clear_alpha()
282
+ if value is None or value == 1.0:
283
+ return
284
+ self._xClr.add_alpha(value)
285
+
286
+ @property
287
+ def brightness(self):
288
+ lumMod, lumOff = self._xClr.lumMod, self._xClr.lumOff
289
+ # a tint is lighter, a shade is darker
290
+ # only tints have lumOff child
291
+ if lumOff is not None:
292
+ brightness = lumOff.val
293
+ return brightness
294
+ # which leaves shades, if lumMod is present
295
+ if lumMod is not None:
296
+ brightness = lumMod.val - 1.0
297
+ return brightness
298
+ # there's no brightness adjustment if no lum{Mod|Off} elements
299
+ return 0
300
+
301
+ @brightness.setter
302
+ def brightness(self, value):
303
+ if value > 0:
304
+ self._tint(value)
305
+ elif value < 0:
306
+ self._shade(value)
307
+ else:
308
+ self._xClr.clear_lum()
309
+
310
+ @property
311
+ def color_type(self): # pragma: no cover
312
+ tmpl = ".color_type property must be implemented on %s"
313
+ raise NotImplementedError(tmpl % self.__class__.__name__)
314
+
315
+ @property
316
+ def rgb(self):
317
+ """
318
+ Raises TypeError on access unless overridden by subclass.
319
+ """
320
+ tmpl = "no .rgb property on color type '%s'"
321
+ raise AttributeError(tmpl % self.__class__.__name__)
322
+
323
+ @property
324
+ def theme_color(self):
325
+ """
326
+ Raises TypeError on access unless overridden by subclass.
327
+ """
328
+ return MSO_THEME_COLOR.NOT_THEME_COLOR
329
+
330
+ def _shade(self, value):
331
+ lumMod_val = 1.0 - abs(value)
332
+ color_elm = self._xClr.clear_lum()
333
+ color_elm.add_lumMod(lumMod_val)
334
+
335
+ def _tint(self, value):
336
+ lumOff_val = value
337
+ lumMod_val = 1.0 - lumOff_val
338
+ color_elm = self._xClr.clear_lum()
339
+ color_elm.add_lumMod(lumMod_val)
340
+ color_elm.add_lumOff(lumOff_val)
341
+
342
+
343
+ class _HslColor(_Color):
344
+ @property
345
+ def color_type(self):
346
+ return MSO_COLOR_TYPE.HSL
347
+
348
+
349
+ class _NoneColor(_Color):
350
+ @property
351
+ def alpha(self):
352
+ return 1.0
353
+
354
+ @alpha.setter
355
+ def alpha(self, value):
356
+ raise AttributeError(
357
+ "no .alpha property on color type '%s'" % self.__class__.__name__
358
+ )
359
+
360
+ @property
361
+ def color_type(self):
362
+ return None
363
+
364
+ @property
365
+ def theme_color(self):
366
+ """
367
+ Raise TypeError on attempt to access .theme_color when no color
368
+ choice is present.
369
+ """
370
+ tmpl = "no .theme_color property on color type '%s'"
371
+ raise AttributeError(tmpl % self.__class__.__name__)
372
+
373
+
374
+ class _PrstColor(_Color):
375
+ @property
376
+ def color_type(self):
377
+ return MSO_COLOR_TYPE.PRESET
378
+
379
+
380
+ class _SchemeColor(_Color):
381
+ def __init__(self, schemeClr):
382
+ super(_SchemeColor, self).__init__(schemeClr)
383
+ self._schemeClr = schemeClr
384
+
385
+ @property
386
+ def color_type(self):
387
+ return MSO_COLOR_TYPE.SCHEME
388
+
389
+ @property
390
+ def theme_color(self):
391
+ """
392
+ Theme color value of this color, one of those defined in the
393
+ MSO_THEME_COLOR enumeration, e.g. MSO_THEME_COLOR.ACCENT_1. None if
394
+ no theme color is explicitly defined for this font. Setting this to a
395
+ value in MSO_THEME_COLOR causes the color's type to change to
396
+ ``MSO_COLOR_TYPE.SCHEME``.
397
+ """
398
+ return self._schemeClr.val
399
+
400
+ @theme_color.setter
401
+ def theme_color(self, mso_theme_color_idx):
402
+ self._schemeClr.val = mso_theme_color_idx
403
+
404
+
405
+ class _ScRgbColor(_Color):
406
+ @property
407
+ def color_type(self):
408
+ return MSO_COLOR_TYPE.SCRGB
409
+
410
+
411
+ class _SRgbColor(_Color):
412
+ def __init__(self, srgbClr):
413
+ super(_SRgbColor, self).__init__(srgbClr)
414
+ self._srgbClr = srgbClr
415
+
416
+ @property
417
+ def color_type(self):
418
+ return MSO_COLOR_TYPE.RGB
419
+
420
+ @property
421
+ def rgb(self):
422
+ """
423
+ |RGBColor| value of this color, corresponding to the value in the
424
+ required ``val`` attribute of the ``<a:srgbColr>`` element.
425
+ """
426
+ return RGBColor.from_hex(self._srgbClr.val)
427
+
428
+ @rgb.setter
429
+ def rgb(self, rgb):
430
+ self._srgbClr.val = str(rgb)
431
+
432
+
433
+ class _SysColor(_Color):
434
+ @property
435
+ def color_type(self):
436
+ return MSO_COLOR_TYPE.SYSTEM
437
+
438
+
439
+ class RGBColor(tuple):
440
+ """
441
+ Immutable value object defining a particular RGB color.
442
+ """
443
+
444
+ def __new__(cls, r, g, b):
445
+ msg = "RGBColor() takes three integer values 0-255"
446
+ for val in (r, g, b):
447
+ if not isinstance(val, int) or val < 0 or val > 255:
448
+ raise ValueError(msg)
449
+ return super(RGBColor, cls).__new__(cls, (r, g, b))
450
+
451
+ def __str__(self):
452
+ """
453
+ Return a hex string rgb value, like '3C2F80'
454
+ """
455
+ return "%02X%02X%02X" % self
456
+
457
+ @classmethod
458
+ def from_hex(cls, hex_str: str) -> "RGBColor":
459
+ """Return a new instance from an RGB hex string, with or without a leading ``'#'``.
460
+
461
+ Accepts both ``'#3C2F80'`` and ``'3C2F80'``. Prefer this over
462
+ :meth:`from_string` for new code; ``from_string`` is slated for
463
+ removal in a future major release.
464
+ """
465
+ if hex_str.startswith("#"):
466
+ hex_str = hex_str[1:]
467
+ # Call the underlying parser directly to avoid the
468
+ # ``DeprecationWarning`` emitted by ``from_string``.
469
+ r = int(hex_str[:2], 16)
470
+ g = int(hex_str[2:4], 16)
471
+ b = int(hex_str[4:], 16)
472
+ return cls(r, g, b)
473
+
474
+ @classmethod
475
+ def from_string(cls, rgb_hex_str):
476
+ """Return a new instance from an RGB color hex string like ``'3C2F80'``.
477
+
478
+ .. deprecated::
479
+ Prefer :meth:`from_hex` (which accepts hex with or without a
480
+ leading ``'#'``) for new code. ``from_string`` will be
481
+ removed in a future major release; until then it emits a
482
+ :class:`DeprecationWarning` on call.
483
+ """
484
+ import warnings
485
+
486
+ warnings.warn(
487
+ "RGBColor.from_string is deprecated and will be removed in a "
488
+ "future major release; use RGBColor.from_hex (which accepts "
489
+ "hex strings with or without a leading '#') instead.",
490
+ DeprecationWarning,
491
+ stacklevel=2,
492
+ )
493
+ r = int(rgb_hex_str[:2], 16)
494
+ g = int(rgb_hex_str[2:4], 16)
495
+ b = int(rgb_hex_str[4:], 16)
496
+ return cls(r, g, b)