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/package.py ADDED
@@ -0,0 +1,222 @@
1
+ """Overall .pptx package."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import IO, Iterator
6
+
7
+ from pptx2.opc.constants import RELATIONSHIP_TYPE as RT
8
+ from pptx2.opc.package import OpcPackage
9
+ from pptx2.opc.packuri import PackURI
10
+ from pptx2.parts.coreprops import CorePropertiesPart
11
+ from pptx2.parts.image import Image, ImagePart
12
+ from pptx2.parts.media import MediaPart
13
+ from pptx2.util import lazyproperty
14
+
15
+
16
+ class Package(OpcPackage):
17
+ """An overall .pptx package."""
18
+
19
+ @lazyproperty
20
+ def core_properties(self) -> CorePropertiesPart:
21
+ """Instance of |CoreProperties| holding read/write Dublin Core doc properties.
22
+
23
+ Creates a default core properties part if one is not present (not common).
24
+ """
25
+ try:
26
+ return self.part_related_by(RT.CORE_PROPERTIES)
27
+ except KeyError:
28
+ core_props = CorePropertiesPart.default(self)
29
+ self.relate_to(core_props, RT.CORE_PROPERTIES)
30
+ return core_props
31
+
32
+ def get_or_add_image_part(self, image_file: str | IO[bytes]):
33
+ """
34
+ Return an |ImagePart| object containing the image in *image_file*. If
35
+ the image part already exists in this package, it is reused,
36
+ otherwise a new one is created.
37
+ """
38
+ return self._image_parts.get_or_add_image_part(image_file)
39
+
40
+ def get_or_add_media_part(self, media):
41
+ """Return a |MediaPart| object containing the media in *media*.
42
+
43
+ If a media part for this media bytestream ("file") is already present
44
+ in this package, it is reused, otherwise a new one is created.
45
+ """
46
+ return self._media_parts.get_or_add_media_part(media)
47
+
48
+ def next_image_partname(self, ext: str) -> PackURI:
49
+ """Return a |PackURI| instance representing the next available image partname.
50
+
51
+ Partname uses the next available sequence number. *ext* is used as the extention on the
52
+ returned partname.
53
+ """
54
+
55
+ def first_available_image_idx():
56
+ image_idxs = sorted(
57
+ [
58
+ part.partname.idx
59
+ for part in self.iter_parts()
60
+ if (
61
+ part.partname.startswith("/ppt/media/image")
62
+ and part.partname.idx is not None
63
+ )
64
+ ]
65
+ )
66
+ for i, image_idx in enumerate(image_idxs):
67
+ idx = i + 1
68
+ if idx < image_idx:
69
+ return idx
70
+ return len(image_idxs) + 1
71
+
72
+ idx = first_available_image_idx()
73
+ return PackURI("/ppt/media/image%d.%s" % (idx, ext))
74
+
75
+ def next_media_partname(self, ext):
76
+ """Return |PackURI| instance for next available media partname.
77
+
78
+ Partname is first available, starting at sequence number 1. Empty
79
+ sequence numbers are reused. *ext* is used as the extension on the
80
+ returned partname.
81
+ """
82
+
83
+ def first_available_media_idx():
84
+ media_idxs = sorted(
85
+ [
86
+ part.partname.idx
87
+ for part in self.iter_parts()
88
+ if part.partname.startswith("/ppt/media/media")
89
+ ]
90
+ )
91
+ for i, media_idx in enumerate(media_idxs):
92
+ idx = i + 1
93
+ if idx < media_idx:
94
+ return idx
95
+ return len(media_idxs) + 1
96
+
97
+ idx = first_available_media_idx()
98
+ return PackURI("/ppt/media/media%d.%s" % (idx, ext))
99
+
100
+ @property
101
+ def presentation_part(self):
102
+ """
103
+ Reference to the |Presentation| instance contained in this package.
104
+ """
105
+ return self.main_document_part
106
+
107
+ @lazyproperty
108
+ def _image_parts(self):
109
+ """
110
+ |_ImageParts| object providing access to the image parts in this
111
+ package.
112
+ """
113
+ return _ImageParts(self)
114
+
115
+ @lazyproperty
116
+ def _media_parts(self):
117
+ """Return |_MediaParts| object for this package.
118
+
119
+ The media parts object provides access to all the media parts in this
120
+ package.
121
+ """
122
+ return _MediaParts(self)
123
+
124
+
125
+ class _ImageParts(object):
126
+ """Provides access to the image parts in a package."""
127
+
128
+ def __init__(self, package):
129
+ super(_ImageParts, self).__init__()
130
+ self._package = package
131
+
132
+ def __iter__(self) -> Iterator[ImagePart]:
133
+ """Generate a reference to each |ImagePart| object in the package."""
134
+ image_parts = []
135
+ for rel in self._package.iter_rels():
136
+ if rel.is_external:
137
+ continue
138
+ if rel.reltype != RT.IMAGE:
139
+ continue
140
+ image_part = rel.target_part
141
+ if image_part in image_parts:
142
+ continue
143
+ image_parts.append(image_part)
144
+ yield image_part
145
+
146
+ def get_or_add_image_part(self, image_file: str | IO[bytes]) -> ImagePart:
147
+ """Return |ImagePart| object containing the image in `image_file`.
148
+
149
+ `image_file` can be either a path to an image file or a file-like object
150
+ containing an image. If an image part containing this same image already exists,
151
+ that instance is returned, otherwise a new image part is created.
152
+ """
153
+ image = Image.from_file(image_file)
154
+ image_part = self._find_by_sha1(image.sha1)
155
+ return image_part if image_part else ImagePart.new(self._package, image)
156
+
157
+ def _find_by_sha1(self, sha1: str) -> ImagePart | None:
158
+ """
159
+ Return an |ImagePart| object belonging to this package or |None| if
160
+ no matching image part is found. The image part is identified by the
161
+ SHA1 hash digest of the image binary it contains.
162
+ """
163
+ for image_part in self:
164
+ # ---skip unknown/unsupported image types, like SVG---
165
+ if not hasattr(image_part, "sha1"):
166
+ continue
167
+ if image_part.sha1 == sha1:
168
+ return image_part
169
+ return None
170
+
171
+
172
+ class _MediaParts(object):
173
+ """Provides access to the media parts in a package.
174
+
175
+ Supports iteration and :meth:`get()` using the media object SHA1 hash as
176
+ its key.
177
+ """
178
+
179
+ def __init__(self, package):
180
+ super(_MediaParts, self).__init__()
181
+ self._package = package
182
+
183
+ def __iter__(self):
184
+ """Generate a reference to each |MediaPart| object in the package."""
185
+ # A media part can appear in more than one relationship (and commonly
186
+ # does in the case of video). Use media_parts to keep track of those
187
+ # that have been "yielded"; they can be skipped if they occur again.
188
+ media_parts = []
189
+ for rel in self._package.iter_rels():
190
+ if rel.is_external:
191
+ continue
192
+ if rel.reltype not in (RT.MEDIA, RT.VIDEO):
193
+ continue
194
+ media_part = rel.target_part
195
+ if media_part in media_parts:
196
+ continue
197
+ media_parts.append(media_part)
198
+ yield media_part
199
+
200
+ def get_or_add_media_part(self, media):
201
+ """Return a |MediaPart| object containing the media in *media*.
202
+
203
+ If this package already contains a media part for the same
204
+ bytestream, that instance is returned, otherwise a new media part is
205
+ created.
206
+ """
207
+ media_part = self._find_by_sha1(media.sha1)
208
+ if media_part is None:
209
+ media_part = MediaPart.new(self._package, media)
210
+ return media_part
211
+
212
+ def _find_by_sha1(self, sha1):
213
+ """Return |MediaPart| object having *sha1* hash or None if not found.
214
+
215
+ All media parts belonging to this package are considered. A media
216
+ part is identified by the SHA1 hash digest of its bytestream
217
+ ("file").
218
+ """
219
+ for media_part in self:
220
+ if media_part.sha1 == sha1:
221
+ return media_part
222
+ return None
File without changes
pptx2/parts/chart.py ADDED
@@ -0,0 +1,95 @@
1
+ """Chart part objects, including Chart and Charts."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from pptx2.chart.chart import Chart
8
+ from pptx2.opc.constants import CONTENT_TYPE as CT
9
+ from pptx2.opc.constants import RELATIONSHIP_TYPE as RT
10
+ from pptx2.opc.package import XmlPart
11
+ from pptx2.parts.embeddedpackage import EmbeddedXlsxPart
12
+ from pptx2.util import lazyproperty
13
+
14
+ if TYPE_CHECKING:
15
+ from pptx2.chart.data import ChartData
16
+ from pptx2.enum.chart import XL_CHART_TYPE
17
+ from pptx2.package import Package
18
+
19
+
20
+ class ChartPart(XmlPart):
21
+ """A chart part.
22
+
23
+ Corresponds to parts having partnames matching ppt/charts/chart[1-9][0-9]*.xml
24
+ """
25
+
26
+ partname_template = "/ppt/charts/chart%d.xml"
27
+
28
+ @classmethod
29
+ def new(cls, chart_type: XL_CHART_TYPE, chart_data: ChartData, package: Package):
30
+ """Return new |ChartPart| instance added to `package`.
31
+
32
+ Returned chart-part contains a chart of `chart_type` depicting `chart_data`.
33
+ """
34
+ chart_part = cls.load(
35
+ package.next_partname(cls.partname_template),
36
+ CT.DML_CHART,
37
+ package,
38
+ chart_data.xml_bytes(chart_type),
39
+ )
40
+ chart_part.chart_workbook.update_from_xlsx_blob(chart_data.xlsx_blob)
41
+ return chart_part
42
+
43
+ @lazyproperty
44
+ def chart(self):
45
+ """|Chart| object representing the chart in this part."""
46
+ return Chart(self._element, self)
47
+
48
+ @lazyproperty
49
+ def chart_workbook(self):
50
+ """
51
+ The |ChartWorkbook| object providing access to the external chart
52
+ data in a linked or embedded Excel workbook.
53
+ """
54
+ return ChartWorkbook(self._element, self)
55
+
56
+
57
+ class ChartWorkbook(object):
58
+ """Provides access to external chart data in a linked or embedded Excel workbook."""
59
+
60
+ def __init__(self, chartSpace, chart_part):
61
+ super(ChartWorkbook, self).__init__()
62
+ self._chartSpace = chartSpace
63
+ self._chart_part = chart_part
64
+
65
+ def update_from_xlsx_blob(self, xlsx_blob):
66
+ """
67
+ Replace the Excel spreadsheet in the related |EmbeddedXlsxPart| with
68
+ the Excel binary in *xlsx_blob*, adding a new |EmbeddedXlsxPart| if
69
+ there isn't one.
70
+ """
71
+ xlsx_part = self.xlsx_part
72
+ if xlsx_part is None:
73
+ self.xlsx_part = EmbeddedXlsxPart.new(xlsx_blob, self._chart_part.package)
74
+ return
75
+ xlsx_part.blob = xlsx_blob
76
+
77
+ @property
78
+ def xlsx_part(self):
79
+ """Optional |EmbeddedXlsxPart| object containing data for this chart.
80
+
81
+ This related part has its rId at `c:chartSpace/c:externalData/@rId`. This value
82
+ is |None| if there is no `<c:externalData>` element.
83
+ """
84
+ xlsx_part_rId = self._chartSpace.xlsx_part_rId
85
+ return None if xlsx_part_rId is None else self._chart_part.related_part(xlsx_part_rId)
86
+
87
+ @xlsx_part.setter
88
+ def xlsx_part(self, xlsx_part):
89
+ """
90
+ Set the related |EmbeddedXlsxPart| to *xlsx_part*. Assume one does
91
+ not already exist.
92
+ """
93
+ rId = self._chart_part.relate_to(xlsx_part, RT.PACKAGE)
94
+ externalData = self._chartSpace.get_or_add_externalData()
95
+ externalData.rId = rId
@@ -0,0 +1,167 @@
1
+ """Core properties part, corresponds to ``/docProps/core.xml`` part in package."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import datetime as dt
6
+ from typing import TYPE_CHECKING
7
+
8
+ from pptx2.opc.constants import CONTENT_TYPE as CT
9
+ from pptx2.opc.package import XmlPart
10
+ from pptx2.opc.packuri import PackURI
11
+ from pptx2.oxml.coreprops import CT_CoreProperties
12
+
13
+ if TYPE_CHECKING:
14
+ from pptx2.package import Package
15
+
16
+
17
+ class CorePropertiesPart(XmlPart):
18
+ """Corresponds to part named `/docProps/core.xml`.
19
+
20
+ Contains the core document properties for this document package.
21
+ """
22
+
23
+ _element: CT_CoreProperties
24
+
25
+ @classmethod
26
+ def default(cls, package: Package):
27
+ """Return default new |CorePropertiesPart| instance suitable as starting point.
28
+
29
+ This provides a base for adding core-properties to a package that doesn't yet
30
+ have any.
31
+ """
32
+ core_props = cls._new(package)
33
+ core_props.title = "PowerPoint Presentation"
34
+ core_props.last_modified_by = "python-pptx"
35
+ core_props.revision = 1
36
+ core_props.modified = dt.datetime.now(dt.timezone.utc).replace(tzinfo=None)
37
+ return core_props
38
+
39
+ @property
40
+ def author(self) -> str:
41
+ return self._element.author_text
42
+
43
+ @author.setter
44
+ def author(self, value: str):
45
+ self._element.author_text = value
46
+
47
+ @property
48
+ def category(self) -> str:
49
+ return self._element.category_text
50
+
51
+ @category.setter
52
+ def category(self, value: str):
53
+ self._element.category_text = value
54
+
55
+ @property
56
+ def comments(self) -> str:
57
+ return self._element.comments_text
58
+
59
+ @comments.setter
60
+ def comments(self, value: str):
61
+ self._element.comments_text = value
62
+
63
+ @property
64
+ def content_status(self) -> str:
65
+ return self._element.contentStatus_text
66
+
67
+ @content_status.setter
68
+ def content_status(self, value: str):
69
+ self._element.contentStatus_text = value
70
+
71
+ @property
72
+ def created(self):
73
+ return self._element.created_datetime
74
+
75
+ @created.setter
76
+ def created(self, value: dt.datetime):
77
+ self._element.created_datetime = value
78
+
79
+ @property
80
+ def identifier(self) -> str:
81
+ return self._element.identifier_text
82
+
83
+ @identifier.setter
84
+ def identifier(self, value: str):
85
+ self._element.identifier_text = value
86
+
87
+ @property
88
+ def keywords(self) -> str:
89
+ return self._element.keywords_text
90
+
91
+ @keywords.setter
92
+ def keywords(self, value: str):
93
+ self._element.keywords_text = value
94
+
95
+ @property
96
+ def language(self) -> str:
97
+ return self._element.language_text
98
+
99
+ @language.setter
100
+ def language(self, value: str):
101
+ self._element.language_text = value
102
+
103
+ @property
104
+ def last_modified_by(self) -> str:
105
+ return self._element.lastModifiedBy_text
106
+
107
+ @last_modified_by.setter
108
+ def last_modified_by(self, value: str):
109
+ self._element.lastModifiedBy_text = value
110
+
111
+ @property
112
+ def last_printed(self):
113
+ return self._element.lastPrinted_datetime
114
+
115
+ @last_printed.setter
116
+ def last_printed(self, value: dt.datetime):
117
+ self._element.lastPrinted_datetime = value
118
+
119
+ @property
120
+ def modified(self):
121
+ return self._element.modified_datetime
122
+
123
+ @modified.setter
124
+ def modified(self, value: dt.datetime):
125
+ self._element.modified_datetime = value
126
+
127
+ @property
128
+ def revision(self):
129
+ return self._element.revision_number
130
+
131
+ @revision.setter
132
+ def revision(self, value: int):
133
+ self._element.revision_number = value
134
+
135
+ @property
136
+ def subject(self) -> str:
137
+ return self._element.subject_text
138
+
139
+ @subject.setter
140
+ def subject(self, value: str):
141
+ self._element.subject_text = value
142
+
143
+ @property
144
+ def title(self) -> str:
145
+ return self._element.title_text
146
+
147
+ @title.setter
148
+ def title(self, value: str):
149
+ self._element.title_text = value
150
+
151
+ @property
152
+ def version(self) -> str:
153
+ return self._element.version_text
154
+
155
+ @version.setter
156
+ def version(self, value: str):
157
+ self._element.version_text = value
158
+
159
+ @classmethod
160
+ def _new(cls, package: Package) -> CorePropertiesPart:
161
+ """Return new empty |CorePropertiesPart| instance."""
162
+ return CorePropertiesPart(
163
+ PackURI("/docProps/core.xml"),
164
+ CT.OPC_CORE_PROPERTIES,
165
+ package,
166
+ CT_CoreProperties.new_coreProperties(),
167
+ )
pptx2/parts/diagram.py ADDED
@@ -0,0 +1,37 @@
1
+ """Diagram part objects for SmartArt diagrams."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pptx2.opc.package import XmlPart
6
+
7
+
8
+ class DiagramDataPart(XmlPart):
9
+ """Part wrapping a ``diagrams/data#.xml`` file (SmartArt data model).
10
+
11
+ Content-type:
12
+ ``application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml``
13
+ """
14
+
15
+
16
+ class DiagramLayoutPart(XmlPart):
17
+ """Part wrapping a ``diagrams/layout#.xml`` file (SmartArt layout definition).
18
+
19
+ Content-type:
20
+ ``application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml``
21
+ """
22
+
23
+
24
+ class DiagramStylePart(XmlPart):
25
+ """Part wrapping a ``diagrams/quickStyle#.xml`` file (SmartArt quick-style).
26
+
27
+ Content-type:
28
+ ``application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml``
29
+ """
30
+
31
+
32
+ class DiagramColorsPart(XmlPart):
33
+ """Part wrapping a ``diagrams/colors#.xml`` file (SmartArt color style).
34
+
35
+ Content-type:
36
+ ``application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml``
37
+ """
@@ -0,0 +1,93 @@
1
+ """Embedded Package part objects.
2
+
3
+ "Package" in this context means another OPC package, i.e. a DOCX, PPTX, or XLSX "file".
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import TYPE_CHECKING
9
+
10
+ from pptx2.enum.shapes import PROG_ID
11
+ from pptx2.opc.constants import CONTENT_TYPE as CT
12
+ from pptx2.opc.package import Part
13
+
14
+ if TYPE_CHECKING:
15
+ from pptx2.package import Package
16
+
17
+
18
+ class EmbeddedPackagePart(Part):
19
+ """A distinct OPC package, e.g. an Excel file, embedded in this PPTX package.
20
+
21
+ Has a partname like: `ppt/embeddings/Microsoft_Excel_Sheet1.xlsx`.
22
+ """
23
+
24
+ @classmethod
25
+ def factory(cls, prog_id: PROG_ID | str, object_blob: bytes, package: Package):
26
+ """Return a new |EmbeddedPackagePart| subclass instance added to *package*.
27
+
28
+ The subclass is determined by `prog_id` which corresponds to the "application"
29
+ used to open the "file-type" of `object_blob`. The returned part contains the
30
+ bytes of `object_blob` and has the content-type also determined by `prog_id`.
31
+ """
32
+ # --- a generic OLE object has no subclass ---
33
+ if not isinstance(prog_id, PROG_ID):
34
+ return cls(
35
+ package.next_partname("/ppt/embeddings/oleObject%d.bin"),
36
+ CT.OFC_OLE_OBJECT,
37
+ package,
38
+ object_blob,
39
+ )
40
+
41
+ # --- A Microsoft Office file-type is a distinguished package object ---
42
+ EmbeddedPartCls = {
43
+ PROG_ID.DOCX: EmbeddedDocxPart,
44
+ PROG_ID.PPTX: EmbeddedPptxPart,
45
+ PROG_ID.XLSX: EmbeddedXlsxPart,
46
+ }[prog_id]
47
+
48
+ return EmbeddedPartCls.new(object_blob, package)
49
+
50
+ @classmethod
51
+ def new(cls, blob: bytes, package: Package):
52
+ """Return new |EmbeddedPackagePart| subclass object.
53
+
54
+ The returned part object contains `blob` and is added to `package`.
55
+ """
56
+ return cls(
57
+ package.next_partname(cls.partname_template),
58
+ cls.content_type,
59
+ package,
60
+ blob,
61
+ )
62
+
63
+
64
+ class EmbeddedDocxPart(EmbeddedPackagePart):
65
+ """A Word .docx file stored in a part.
66
+
67
+ This part-type arises when a Word document appears as an embedded OLE-object shape.
68
+ """
69
+
70
+ partname_template = "/ppt/embeddings/Microsoft_Word_Document%d.docx"
71
+ content_type = CT.WML_DOCUMENT
72
+
73
+
74
+ class EmbeddedPptxPart(EmbeddedPackagePart):
75
+ """A PowerPoint file stored in a part.
76
+
77
+ This part-type arises when a PowerPoint presentation (.pptx file) appears as an
78
+ embedded OLE-object shape.
79
+ """
80
+
81
+ partname_template = "/ppt/embeddings/Microsoft_PowerPoint_Presentation%d.pptx"
82
+ content_type = CT.PML_PRESENTATION
83
+
84
+
85
+ class EmbeddedXlsxPart(EmbeddedPackagePart):
86
+ """An Excel file stored in a part.
87
+
88
+ This part-type arises as the data source for a chart, but may also be the OLE-object
89
+ for an embedded object shape.
90
+ """
91
+
92
+ partname_template = "/ppt/embeddings/Microsoft_Excel_Sheet%d.xlsx"
93
+ content_type = CT.SML_SHEET