Skip to content

Commit 7ea4d29

Browse files
author
Steve Canny
committed
doc: rewrite Document.add_table()
* Add width parameter to BlockItemContainer.add_table() * Temporarily stub down-call-stack methods and tests with width=None until they are rewritten in next commits * add Document._block_width to calculate width of table (page width less margins).
1 parent 578f6c1 commit 7ea4d29

File tree

5 files changed

+54
-12
lines changed

5 files changed

+54
-12
lines changed

docx/blkcntnr.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ def add_paragraph(self, text='', style=None):
3737
paragraph.style = style
3838
return paragraph
3939

40-
def add_table(self, rows, cols):
40+
def add_table(self, rows, cols, width):
4141
"""
42-
Return a newly added table having *rows* rows and *cols* cols,
43-
appended to the content in this container.
42+
Return a table of *width* having *rows* rows and *cols* columns,
43+
newly appended to the content in this container. *width* is evenly
44+
distributed between the table columns.
4445
"""
4546
from .table import Table
4647
tbl = self._element.add_tbl()

docx/document.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from .enum.section import WD_SECTION
1313
from .enum.text import WD_BREAK
1414
from .section import Section, Sections
15-
from .shared import ElementProxy
15+
from .shared import ElementProxy, Emu
1616

1717

1818
class Document(ElementProxy):
@@ -96,7 +96,7 @@ def add_table(self, rows, cols, style=None):
9696
style object or a paragraph style name. If *style* is |None|, the
9797
table inherits the default table style of the document.
9898
"""
99-
table = self._body.add_table(rows, cols)
99+
table = self._body.add_table(rows, cols, self._block_width)
100100
table.style = style
101101
return table
102102

@@ -167,6 +167,17 @@ def tables(self):
167167
"""
168168
return self._body.tables
169169

170+
@property
171+
def _block_width(self):
172+
"""
173+
Return a |Length| object specifying the width of available "writing"
174+
space between the margins of the last section of this document.
175+
"""
176+
section = self.sections[-1]
177+
return Emu(
178+
section.page_width - section.left_margin - section.right_margin
179+
)
180+
170181
@property
171182
def _body(self):
172183
"""

docx/table.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ def add_table(self, rows, cols):
201201
added after the table because Word requires a paragraph element as
202202
the last element in every cell.
203203
"""
204-
new_table = super(_Cell, self).add_table(rows, cols)
204+
new_table = super(_Cell, self).add_table(rows, cols, 914400)
205205
self.add_paragraph()
206206
return new_table
207207

tests/test_blkcntnr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def it_can_add_a_paragraph(self, add_paragraph_fixture):
3131

3232
def it_can_add_a_table(self, add_table_fixture):
3333
blkcntnr, rows, cols, expected_xml = add_table_fixture
34-
table = blkcntnr.add_table(rows, cols)
34+
table = blkcntnr.add_table(rows, cols, None)
3535
assert blkcntnr._element.xml == expected_xml
3636
assert isinstance(table, Table)
3737

tests/test_document.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
from docx.enum.text import WD_BREAK
1616
from docx.opc.coreprops import CoreProperties
1717
from docx.parts.document import DocumentPart
18-
from docx.section import Sections
18+
from docx.section import Section, Sections
1919
from docx.shape import InlineShape, InlineShapes
20+
from docx.shared import Length
2021
from docx.styles.styles import Styles
2122
from docx.table import Table
2223
from docx.text.paragraph import Paragraph
@@ -75,9 +76,9 @@ def it_can_add_a_section(self, add_section_fixture):
7576
assert section is section_
7677

7778
def it_can_add_a_table(self, add_table_fixture):
78-
document, rows, cols, style, table_ = add_table_fixture
79+
document, rows, cols, style, width, table_ = add_table_fixture
7980
table = document.add_table(rows, cols, style)
80-
document._body.add_table.assert_called_once_with(rows, cols)
81+
document._body.add_table.assert_called_once_with(rows, cols, width)
8182
assert table == table_
8283
assert table.style == style
8384

@@ -125,6 +126,12 @@ def it_provides_access_to_the_document_body(self, body_fixture):
125126
_Body_.assert_called_once_with(body_elm, document)
126127
assert body is body_
127128

129+
def it_determines_block_width_to_help(self, block_width_fixture):
130+
document, expected_value = block_width_fixture
131+
width = document._block_width
132+
assert isinstance(width, Length)
133+
assert width == expected_value
134+
128135
# fixtures -------------------------------------------------------
129136

130137
@pytest.fixture(params=[
@@ -186,11 +193,22 @@ def add_section_fixture(self, request, Section_):
186193
return document, start_type, Section_, section_, expected_xml
187194

188195
@pytest.fixture
189-
def add_table_fixture(self, body_prop_, table_):
196+
def add_table_fixture(self, _block_width_prop_, body_prop_, table_):
190197
document = Document(None, None)
191198
rows, cols, style = 4, 2, 'Light Shading Accent 1'
192199
body_prop_.return_value.add_table.return_value = table_
193-
return document, rows, cols, style, table_
200+
_block_width_prop_.return_value = width = 42
201+
return document, rows, cols, style, width, table_
202+
203+
@pytest.fixture
204+
def block_width_fixture(self, sections_prop_, section_):
205+
document = Document(None, None)
206+
sections_prop_.return_value = [None, section_]
207+
section_.page_width = 6000
208+
section_.left_margin = 1500
209+
section_.right_margin = 1000
210+
expected_value = 3500
211+
return document, expected_value
194212

195213
@pytest.fixture
196214
def body_fixture(self, _Body_, body_):
@@ -261,6 +279,10 @@ def _Body_(self, request, body_):
261279
def body_(self, request):
262280
return instance_mock(request, _Body)
263281

282+
@pytest.fixture
283+
def _block_width_prop_(self, request):
284+
return property_mock(request, Document, '_block_width')
285+
264286
@pytest.fixture
265287
def body_prop_(self, request, body_):
266288
return property_mock(request, Document, '_body', return_value=body_)
@@ -297,6 +319,10 @@ def run_(self, request):
297319
def Section_(self, request):
298320
return class_mock(request, 'docx.document.Section')
299321

322+
@pytest.fixture
323+
def section_(self, request):
324+
return instance_mock(request, Section)
325+
300326
@pytest.fixture
301327
def Sections_(self, request):
302328
return class_mock(request, 'docx.document.Sections')
@@ -305,6 +331,10 @@ def Sections_(self, request):
305331
def sections_(self, request):
306332
return instance_mock(request, Sections)
307333

334+
@pytest.fixture
335+
def sections_prop_(self, request):
336+
return property_mock(request, Document, 'sections')
337+
308338
@pytest.fixture
309339
def styles_(self, request):
310340
return instance_mock(request, Styles)

0 commit comments

Comments
 (0)