Skip to content

Commit 3a447d3

Browse files
ApteryksSteve Canny
authored and
Steve Canny
committed
tbl: add _Cell.merge()
1 parent b347549 commit 3a447d3

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

docx/oxml/table.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,14 @@ def grid_span(self):
225225
return 1
226226
return tcPr.grid_span
227227

228+
def merge(self, other_tc):
229+
"""
230+
Return the top-left ``<w:tc>`` element of the span formed by merging
231+
the rectangular region defined by using this tc element and
232+
*other_tc* as diagonal corners.
233+
"""
234+
raise NotImplementedError
235+
228236
@classmethod
229237
def new(cls):
230238
"""

docx/table.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,17 @@ def add_table(self, rows, cols):
179179
self.add_paragraph()
180180
return new_table
181181

182+
def merge(self, other_cell):
183+
"""
184+
Return a merged cell created by spanning the rectangular region
185+
demarcated by using the extents of this cell and *other_cell* as
186+
diagonal corners. Raises |InvalidSpanError| if the cells do not
187+
define a rectangular region.
188+
"""
189+
tc, tc_2 = self._tc, other_cell._tc
190+
merged_tc = tc.merge(tc_2)
191+
return _Cell(merged_tc, self._parent)
192+
182193
@property
183194
def paragraphs(self):
184195
"""

tests/test_table.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import pytest
1010

1111
from docx.oxml import parse_xml
12+
from docx.oxml.table import CT_Tc
1213
from docx.shared import Inches
1314
from docx.table import _Cell, _Column, _Columns, _Row, _Rows, Table
1415
from docx.text import Paragraph
@@ -289,6 +290,14 @@ def it_can_add_a_table(self, add_table_fixture):
289290
assert cell._tc.xml == expected_xml
290291
assert isinstance(table, Table)
291292

293+
def it_can_merge_itself_with_other_cells(self, merge_fixture):
294+
cell, other_cell, merged_tc_ = merge_fixture
295+
merged_cell = cell.merge(other_cell)
296+
cell._tc.merge.assert_called_once_with(other_cell._tc)
297+
assert isinstance(merged_cell, _Cell)
298+
assert merged_cell._tc is merged_tc_
299+
assert merged_cell._parent is cell._parent
300+
292301
# fixtures -------------------------------------------------------
293302

294303
@pytest.fixture(params=[
@@ -317,6 +326,12 @@ def add_table_fixture(self, request):
317326
expected_xml = xml(after_tc_cxml)
318327
return cell, expected_xml
319328

329+
@pytest.fixture
330+
def merge_fixture(self, tc_, tc_2_, parent_, merged_tc_):
331+
cell, other_cell = _Cell(tc_, parent_), _Cell(tc_2_, parent_)
332+
tc_.merge.return_value = merged_tc_
333+
return cell, other_cell, merged_tc_
334+
320335
@pytest.fixture
321336
def paragraphs_fixture(self):
322337
return _Cell(element('w:tc/(w:p, w:p)'), None)
@@ -383,6 +398,24 @@ def width_set_fixture(self, request):
383398
expected_xml = xml(expected_cxml)
384399
return cell, new_value, expected_xml
385400

401+
# fixture components ---------------------------------------------
402+
403+
@pytest.fixture
404+
def merged_tc_(self, request):
405+
return instance_mock(request, CT_Tc)
406+
407+
@pytest.fixture
408+
def parent_(self, request):
409+
return instance_mock(request, Table)
410+
411+
@pytest.fixture
412+
def tc_(self, request):
413+
return instance_mock(request, CT_Tc)
414+
415+
@pytest.fixture
416+
def tc_2_(self, request):
417+
return instance_mock(request, CT_Tc)
418+
386419

387420
class Describe_Column(object):
388421

0 commit comments

Comments
 (0)