-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathshape.py
More file actions
142 lines (112 loc) · 4.1 KB
/
shape.py
File metadata and controls
142 lines (112 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
"""Objects related to shapes.
A shape is a visual object that appears on the drawing layer of a document.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from docx.enum.shape import WD_INLINE_SHAPE
from docx.oxml.ns import nsmap
from docx.shared import Parented
if TYPE_CHECKING:
from docx.oxml.document import CT_Body
from docx.oxml.shape import CT_Inline
from docx.parts.story import StoryPart
from docx.shared import Length
class InlineShapes(Parented):
"""Sequence of |InlineShape| instances, supporting len(), iteration, and indexed access."""
def __init__(self, body_elm: CT_Body, parent: StoryPart):
super(InlineShapes, self).__init__(parent)
self._body = body_elm
def __getitem__(self, idx: int):
"""Provide indexed access, e.g. 'inline_shapes[idx]'."""
try:
inline = self._inline_lst[idx]
except IndexError:
msg = "inline shape index [%d] out of range" % idx
raise IndexError(msg)
return InlineShape(inline)
def __iter__(self):
return (InlineShape(inline) for inline in self._inline_lst)
def __len__(self):
return len(self._inline_lst)
@property
def _inline_lst(self):
body = self._body
xpath = "//w:p/w:r/w:drawing/wp:inline"
return body.xpath(xpath)
class InlineShape:
"""Proxy for an ``<wp:inline>`` element, representing the container for an inline
graphical object."""
def __init__(self, inline: CT_Inline):
super(InlineShape, self).__init__()
self._inline = inline
@property
def height(self) -> Length:
"""Read/write.
The display height of this inline shape as an |Emu| instance.
"""
return self._inline.extent.cy
@height.setter
def height(self, cy: Length):
self._inline.extent.cy = cy
self._inline.graphic.graphicData.pic.spPr.cy = cy
@property
def type(self):
"""The type of this inline shape as a member of
``docx.enum.shape.WD_INLINE_SHAPE``, e.g. ``LINKED_PICTURE``.
Read-only.
"""
graphicData = self._inline.graphic.graphicData
uri = graphicData.uri
if uri == nsmap["pic"]:
blip = graphicData.pic.blipFill.blip
if blip.link is not None:
return WD_INLINE_SHAPE.LINKED_PICTURE
return WD_INLINE_SHAPE.PICTURE
if uri == nsmap["c"]:
return WD_INLINE_SHAPE.CHART
if uri == nsmap["dgm"]:
return WD_INLINE_SHAPE.SMART_ART
return WD_INLINE_SHAPE.NOT_IMPLEMENTED
@property
def width(self):
"""Read/write.
The display width of this inline shape as an |Emu| instance.
"""
return self._inline.extent.cx
@width.setter
def width(self, cx: Length):
self._inline.extent.cx = cx
self._inline.graphic.graphicData.pic.spPr.cx = cx
@property
def alt_text(self) -> str | None:
"""Read/write alternative-text description for this inline shape.
This corresponds to the 'Description' field in Word's Alt Text pane and is
stored on the ``wp:docPr`` ``descr`` attribute.
"""
docPr = self._inline.docPr
if docPr is None:
return None
return docPr.descr
@alt_text.setter
def alt_text(self, value: str | None) -> None:
docPr = self._inline.docPr
if docPr is None:
return
# Setting to empty/None clears the attribute.
docPr.descr = value if value else None
@property
def alt_title(self) -> str | None:
"""Read/write alternative-text title for this inline shape.
This corresponds to the 'Title' field in Word's Alt Text pane and is
stored on the ``wp:docPr`` ``title`` attribute.
"""
docPr = self._inline.docPr
if docPr is None:
return None
return docPr.title
@alt_title.setter
def alt_title(self, value: str | None) -> None:
docPr = self._inline.docPr
if docPr is None:
return
docPr.title = value if value else None