Skip to content

Commit e7553c2

Browse files
author
Steve Canny
committed
run: rewrite Run.add_picture()
1 parent 71c657d commit e7553c2

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

docx/parts/document.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ def inline_shapes(self):
8080
"""
8181
return InlineShapes(self._element.body, self)
8282

83+
def new_pic_inline(self, image_descriptor, width, height):
84+
"""
85+
Return a newly-created `w:inline` element containing the image
86+
specified by *image_descriptor* and scaled based on the values of
87+
*width* and *height*.
88+
"""
89+
raise NotImplementedError
90+
8391
@property
8492
def next_id(self):
8593
"""

docx/text/run.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from ..enum.style import WD_STYLE_TYPE
1010
from ..enum.text import WD_BREAK
11+
from ..shape import InlineShape
1112
from ..shared import ElementProxy, Parented
1213

1314

@@ -57,7 +58,9 @@ def add_picture(self, image_path_or_stream, width=None, height=None):
5758
(dpi) value specified in the image file, defaulting to 72 dpi if no
5859
value is specified, as is often the case.
5960
"""
60-
raise NotImplementedError
61+
inline = self.part.new_pic_inline(image_path_or_stream, width, height)
62+
self._r.add_drawing(inline)
63+
return InlineShape(inline)
6164

6265
def add_tab(self):
6366
"""

tests/text/test_run.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from docx.enum.style import WD_STYLE_TYPE
1212
from docx.enum.text import WD_BREAK, WD_UNDERLINE
1313
from docx.parts.document import DocumentPart
14+
from docx.shape import InlineShape
1415
from docx.shared import Pt
1516
from docx.text.run import Font, Run
1617

@@ -84,6 +85,17 @@ def it_can_add_a_tab(self, add_tab_fixture):
8485
run.add_tab()
8586
assert run._r.xml == expected_xml
8687

88+
def it_can_add_a_picture(self, add_picture_fixture):
89+
run, image, width, height, inline = add_picture_fixture[:5]
90+
expected_xml, InlineShape_, picture_ = add_picture_fixture[5:]
91+
92+
picture = run.add_picture(image, width, height)
93+
94+
run.part.new_pic_inline.assert_called_once_with(image, width, height)
95+
assert run._r.xml == expected_xml
96+
InlineShape_.assert_called_once_with(inline)
97+
assert picture is picture_
98+
8799
def it_can_remove_its_content_but_keep_formatting(self, clear_fixture):
88100
run, expected_xml = clear_fixture
89101
_run = run.clear()
@@ -118,6 +130,20 @@ def add_break_fixture(self, request):
118130
expected_xml = xml(expected_cxml)
119131
return run, break_type, expected_xml
120132

133+
@pytest.fixture
134+
def add_picture_fixture(self, part_prop_, document_part_, InlineShape_,
135+
picture_):
136+
run = Run(element('w:r/wp:x'), None)
137+
image = 'foobar.png'
138+
width, height, inline = 1111, 2222, element('wp:inline{id=42}')
139+
expected_xml = xml('w:r/(wp:x,w:drawing/wp:inline{id=42})')
140+
document_part_.new_pic_inline.return_value = inline
141+
InlineShape_.return_value = picture_
142+
return (
143+
run, image, width, height, inline, expected_xml, InlineShape_,
144+
picture_
145+
)
146+
121147
@pytest.fixture(params=[
122148
('w:r/w:t"foo"', 'w:r/(w:t"foo", w:tab)'),
123149
])
@@ -304,12 +330,20 @@ def Font_(self, request, font_):
304330
def font_(self, request):
305331
return instance_mock(request, Font)
306332

333+
@pytest.fixture
334+
def InlineShape_(self, request):
335+
return class_mock(request, 'docx.text.run.InlineShape')
336+
307337
@pytest.fixture
308338
def part_prop_(self, request, document_part_):
309339
return property_mock(
310340
request, Run, 'part', return_value=document_part_
311341
)
312342

343+
@pytest.fixture
344+
def picture_(self, request):
345+
return instance_mock(request, InlineShape)
346+
313347
@pytest.fixture
314348
def Text_(self, request):
315349
return class_mock(request, 'docx.text.run._Text')

0 commit comments

Comments
 (0)