Skip to content

Commit edf8d03

Browse files
DKWoodsSteve Canny
authored and
Steve Canny
committed
tabs: add TabStop.position setter
1 parent bcd4a55 commit edf8d03

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

docx/oxml/text/parfmt.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,16 @@ class CT_TabStops(BaseOxmlElement):
333333
``<w:tabs>`` element, container for a sorted sequence of tab stops.
334334
"""
335335
tab = OneOrMore('w:tab', successors=())
336+
337+
def insert_tab_in_order(self, pos, align, leader):
338+
"""
339+
Insert a newly created `w:tab` child element in *pos* order.
340+
"""
341+
new_tab = self._new_tab()
342+
new_tab.pos, new_tab.val, new_tab.leader = pos, align, leader
343+
for tab in self.tab_lst:
344+
if new_tab.pos < tab.pos:
345+
tab.addprevious(new_tab)
346+
return new_tab
347+
self.append(new_tab)
348+
return new_tab

docx/text/tabstops.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,10 @@ def position(self):
8888
paragraph. May be positive or negative.
8989
"""
9090
return self._tab.pos
91+
92+
@position.setter
93+
def position(self, value):
94+
tab = self._tab
95+
tabs = tab.getparent()
96+
self._tab = tabs.insert_tab_in_order(value, tab.val, tab.leader)
97+
tabs.remove(tab)

features/tab-tabstop-props.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ Feature: Tab stop properties
1414
| out | -457200 |
1515

1616

17-
@wip
1817
Scenario Outline: Set TabStop.position
1918
Given a tab stop 0.5 inches in from the paragraph left edge
2019
When I assign <value> to tab_stop.position

tests/text/test_tabstops.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import pytest
1717

18-
from ..unitutil.cxml import element
18+
from ..unitutil.cxml import element, xml
1919
from ..unitutil.mock import call, class_mock, instance_mock
2020

2121

@@ -25,6 +25,12 @@ def it_knows_its_position(self, position_get_fixture):
2525
tab_stop, expected_value = position_get_fixture
2626
assert tab_stop.position == expected_value
2727

28+
def it_can_change_its_position(self, position_set_fixture):
29+
tab_stop, value, tabs, new_idx, expected_xml = position_set_fixture
30+
tab_stop.position = value
31+
assert tab_stop._tab is tabs[new_idx]
32+
assert tabs.xml == expected_xml
33+
2834
def it_knows_its_alignment(self, alignment_get_fixture):
2935
tab_stop, expected_value = alignment_get_fixture
3036
assert tab_stop.alignment == expected_value
@@ -61,6 +67,31 @@ def position_get_fixture(self, request):
6167
tab_stop = TabStop(element('w:tab{w:pos=720}'))
6268
return tab_stop, Twips(720)
6369

70+
@pytest.fixture(params=[
71+
('w:tabs/w:tab{w:pos=360,w:val=left}',
72+
Twips(720), 0,
73+
'w:tabs/w:tab{w:pos=720,w:val=left}'),
74+
('w:tabs/(w:tab{w:pos=360,w:val=left},w:tab{w:pos=720,w:val=left})',
75+
Twips(180), 0,
76+
'w:tabs/(w:tab{w:pos=180,w:val=left},w:tab{w:pos=720,w:val=left})'),
77+
('w:tabs/(w:tab{w:pos=360,w:val=left},w:tab{w:pos=720,w:val=left})',
78+
Twips(960), 1,
79+
'w:tabs/(w:tab{w:pos=720,w:val=left},w:tab{w:pos=960,w:val=left})'),
80+
('w:tabs/(w:tab{w:pos=-72,w:val=left},w:tab{w:pos=-36,w:val=left})',
81+
Twips(-48), 0,
82+
'w:tabs/(w:tab{w:pos=-48,w:val=left},w:tab{w:pos=-36,w:val=left})'),
83+
('w:tabs/(w:tab{w:pos=-72,w:val=left},w:tab{w:pos=-36,w:val=left})',
84+
Twips(-16), 1,
85+
'w:tabs/(w:tab{w:pos=-36,w:val=left},w:tab{w:pos=-16,w:val=left})'),
86+
])
87+
def position_set_fixture(self, request):
88+
tabs_cxml, value, new_idx, expected_cxml = request.param
89+
tabs = element(tabs_cxml)
90+
tab = tabs.tab_lst[0]
91+
tab_stop = TabStop(tab)
92+
expected_xml = xml(expected_cxml)
93+
return tab_stop, value, tabs, new_idx, expected_xml
94+
6495

6596
class DescribeTabStops(object):
6697

0 commit comments

Comments
 (0)