Skip to content

Commit 25f1519

Browse files
author
Steve Canny
committed
tbl: add CT_Tc._span_to_width()
1 parent 954301d commit 25f1519

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

docx/oxml/table.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,11 @@ def vMerge(self):
314314
return None
315315
return tcPr.vMerge_val
316316

317+
@vMerge.setter
318+
def vMerge(self, value):
319+
tcPr = self.get_or_add_tcPr()
320+
tcPr.vMerge_val = value
321+
317322
@property
318323
def width(self):
319324
"""
@@ -367,6 +372,13 @@ def _insert_tcPr(self, tcPr):
367372
self.insert(0, tcPr)
368373
return tcPr
369374

375+
def _move_content_to(self, other_tc):
376+
"""
377+
Append the content of this cell to *other_tc*, leaving this cell with
378+
a single empty ``<w:p>`` element.
379+
"""
380+
raise NotImplementedError
381+
370382
def _new_tbl(self):
371383
return CT_Tbl.new()
372384

@@ -412,6 +424,21 @@ def _span_to_width(self, grid_width, top_tc, vMerge):
412424
the vMerge element on the single remaining cell is set to *vMerge*.
413425
If *vMerge* is |None|, the vMerge element is removed if present.
414426
"""
427+
self._move_content_to(top_tc)
428+
while self.grid_span < grid_width:
429+
self._swallow_next_tc(grid_width, top_tc)
430+
self.vMerge = vMerge
431+
432+
def _swallow_next_tc(self, grid_width, top_tc):
433+
"""
434+
Extend the horizontal span of this `w:tc` element to incorporate the
435+
following `w:tc` element in the row and then delete that following
436+
`w:tc` element. Any content in the following `w:tc` element is
437+
appended to the content of *top_tc*. The width of the following
438+
`w:tc` element is added to this one, if present. Raises
439+
|InvalidSpanError| if the width of the resulting cell is greater than
440+
*grid_width* or if there is no next `<w:tc>` element in the row.
441+
"""
415442
raise NotImplementedError
416443

417444
@property
@@ -515,6 +542,12 @@ def vMerge_val(self):
515542
return None
516543
return vMerge.val
517544

545+
@vMerge_val.setter
546+
def vMerge_val(self, value):
547+
self._remove_vMerge()
548+
if value is not None:
549+
self._add_vMerge().val = value
550+
518551
@property
519552
def width(self):
520553
"""

tests/oxml/test_table.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ def it_can_grow_itself_to_help_merge(self, grow_to_fixture):
6666
tc._grow_to(width, height, top_tc)
6767
assert tc._span_to_width.call_args_list == expected_calls
6868

69+
def it_can_extend_its_horz_span_to_help_merge(self, span_width_fixture):
70+
tc, grid_width, top_tc, vMerge, expected_calls = span_width_fixture
71+
tc._span_to_width(grid_width, top_tc, vMerge)
72+
tc._move_content_to.assert_called_once_with(top_tc)
73+
assert tc._swallow_next_tc.call_args_list == expected_calls
74+
assert tc.vMerge == vMerge
75+
6976
def it_raises_on_tr_above(self, tr_above_raise_fixture):
7077
tc = tr_above_raise_fixture
7178
with pytest.raises(ValueError):
@@ -154,9 +161,20 @@ def span_raise_fixture(self, request):
154161
tbl = self._snippet_tbl(snippet_idx)
155162
tc = tbl.tr_lst[row].tc_lst[col]
156163
tc_2 = tbl.tr_lst[row_2].tc_lst[col_2]
157-
print(tc.top, tc_2.top, tc.bottom, tc_2.bottom)
158164
return tc, tc_2
159165

166+
@pytest.fixture
167+
def span_width_fixture(
168+
self, top_tc_, grid_span_, _move_content_to_, _swallow_next_tc_):
169+
tc = element('w:tc')
170+
grid_span_.side_effect = [1, 3, 4]
171+
grid_width, vMerge = 4, 'continue'
172+
expected_calls = [
173+
call(grid_width, top_tc_),
174+
call(grid_width, top_tc_)
175+
]
176+
return tc, grid_width, top_tc_, vMerge, expected_calls
177+
160178
@pytest.fixture(params=[(0, 0, 0), (4, 0, 0)])
161179
def tr_above_raise_fixture(self, request):
162180
snippet_idx, row_idx, col_idx = request.param
@@ -166,10 +184,18 @@ def tr_above_raise_fixture(self, request):
166184

167185
# fixture components ---------------------------------------------
168186

187+
@pytest.fixture
188+
def grid_span_(self, request):
189+
return property_mock(request, CT_Tc, 'grid_span')
190+
169191
@pytest.fixture
170192
def _grow_to_(self, request):
171193
return method_mock(request, CT_Tc, '_grow_to')
172194

195+
@pytest.fixture
196+
def _move_content_to_(self, request):
197+
return method_mock(request, CT_Tc, '_move_content_to')
198+
173199
@pytest.fixture
174200
def _span_dimensions_(self, request):
175201
return method_mock(request, CT_Tc, '_span_dimensions')
@@ -185,6 +211,10 @@ def _snippet_tbl(self, idx):
185211
"""
186212
return parse_xml(snippet_seq('tbl-cells')[idx])
187213

214+
@pytest.fixture
215+
def _swallow_next_tc_(self, request):
216+
return method_mock(request, CT_Tc, '_swallow_next_tc')
217+
188218
@pytest.fixture
189219
def _tbl_(self, request):
190220
return property_mock(request, CT_Tc, '_tbl')

0 commit comments

Comments
 (0)