Skip to content

Commit 664905c

Browse files
author
Steve Canny
committed
doc: add Document.add_section()
1 parent c617f18 commit 664905c

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

docx/document.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
)
1010

1111
from .blkcntnr import BlockItemContainer
12+
from .enum.section import WD_SECTION
1213
from .enum.text import WD_BREAK
14+
from .section import Section
1315
from .shared import ElementProxy
1416

1517

@@ -75,6 +77,17 @@ def add_picture(self, image_path_or_stream, width=None, height=None):
7577
run = self.add_paragraph().add_run()
7678
return run.add_picture(image_path_or_stream, width, height)
7779

80+
def add_section(self, start_type=WD_SECTION.NEW_PAGE):
81+
"""
82+
Return a |Section| object representing a new section added at the end
83+
of the document. The optional *start_type* argument must be a member
84+
of the :ref:`WdSectionStart` enumeration, and defaults to
85+
``WD_SECTION.NEW_PAGE`` if not provided.
86+
"""
87+
new_sectPr = self._element.body.add_section_break()
88+
new_sectPr.start_type = start_type
89+
return Section(new_sectPr)
90+
7891
@property
7992
def part(self):
8093
"""

tests/test_document.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111
import pytest
1212

1313
from docx.document import _Body, Document
14+
from docx.enum.section import WD_SECTION
1415
from docx.enum.text import WD_BREAK
1516
from docx.parts.document import DocumentPart
1617
from docx.shape import InlineShape
1718
from docx.text.paragraph import Paragraph
1819
from docx.text.run import Run
1920

20-
from .unitutil.cxml import element
21+
from .unitutil.cxml import element, xml
2122
from .unitutil.mock import (
2223
class_mock, instance_mock, method_mock, property_mock
2324
)
@@ -58,6 +59,17 @@ def it_can_add_a_picture(self, add_picture_fixture):
5859
run_.add_picture.assert_called_once_with(path, width, height)
5960
assert picture is picture_
6061

62+
def it_can_add_a_section(self, add_section_fixture):
63+
document, start_type, Section_ = add_section_fixture[:3]
64+
section_, expected_xml = add_section_fixture[3:]
65+
66+
section = document.add_section(start_type)
67+
68+
assert document.element.xml == expected_xml
69+
sectPr = document.element.xpath('w:body/w:sectPr')[0]
70+
Section_.assert_called_once_with(sectPr)
71+
assert section is section_
72+
6173
def it_provides_access_to_the_document_part(self, part_fixture):
6274
document, part_ = part_fixture
6375
assert document.part is part_
@@ -109,6 +121,25 @@ def add_picture_fixture(self, request, add_paragraph_, run_, picture_):
109121
run_.add_picture.return_value = picture_
110122
return document, path, width, height, run_, picture_
111123

124+
@pytest.fixture(params=[
125+
('w:sectPr', WD_SECTION.EVEN_PAGE,
126+
'w:sectPr/w:type{w:val=evenPage}'),
127+
('w:sectPr/w:type{w:val=evenPage}', WD_SECTION.ODD_PAGE,
128+
'w:sectPr/w:type{w:val=oddPage}'),
129+
('w:sectPr/w:type{w:val=oddPage}', WD_SECTION.NEW_PAGE,
130+
'w:sectPr'),
131+
])
132+
def add_section_fixture(self, request, Section_):
133+
sentinel, start_type, new_sentinel = request.param
134+
document_cxml = 'w:document/w:body/(w:p,%s)' % sentinel
135+
document = Document(element(document_cxml), None)
136+
expected_xml = xml(
137+
'w:document/w:body/(w:p,w:p/w:pPr/%s,%s)' %
138+
(sentinel, new_sentinel)
139+
)
140+
section_ = Section_.return_value
141+
return document, start_type, Section_, section_, expected_xml
142+
112143
@pytest.fixture
113144
def body_fixture(self, _Body_, body_):
114145
document_elm = element('w:document/w:body')
@@ -154,3 +185,7 @@ def picture_(self, request):
154185
@pytest.fixture
155186
def run_(self, request):
156187
return instance_mock(request, Run)
188+
189+
@pytest.fixture
190+
def Section_(self, request):
191+
return class_mock(request, 'docx.document.Section')

0 commit comments

Comments
 (0)