Skip to content

Commit 1d19d45

Browse files
author
Steve Canny
committed
doc: add Document.add_heading()
1 parent f615c58 commit 1d19d45

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

docx/document.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ def __init__(self, element, part):
2424
self._part = part
2525
self.__body = None
2626

27+
def add_heading(self, text='', level=1):
28+
"""
29+
Return a heading paragraph newly added to the end of the document,
30+
containing *text* and having its paragraph style determined by
31+
*level*. If *level* is 0, the style is set to `Title`. If *level* is
32+
1 (or omitted), `Heading 1` is used. Otherwise the style is set to
33+
`Heading {level}`. Raises |ValueError| if *level* is outside the
34+
range 0-9.
35+
"""
36+
if not 0 <= level <= 9:
37+
raise ValueError("level must be in range 0-9, got %d" % level)
38+
style = 'Title' if level == 0 else 'Heading %d' % level
39+
return self.add_paragraph(text, style)
40+
2741
def add_paragraph(self, text='', style=None):
2842
"""
2943
Return a paragraph newly added to the end of the document, populated

tests/test_document.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,26 @@
1515
from docx.text.paragraph import Paragraph
1616

1717
from .unitutil.cxml import element
18-
from .unitutil.mock import class_mock, instance_mock, property_mock
18+
from .unitutil.mock import (
19+
class_mock, instance_mock, method_mock, property_mock
20+
)
1921

2022

2123
class DescribeDocument(object):
2224

25+
def it_can_add_a_heading(self, add_heading_fixture):
26+
document, text, level, style, paragraph_ = add_heading_fixture
27+
paragraph = document.add_heading(text, level)
28+
document.add_paragraph.assert_called_once_with(text, style)
29+
assert paragraph is paragraph_
30+
31+
def it_raises_on_heading_level_out_of_range(self):
32+
document = Document(None, None)
33+
with pytest.raises(ValueError):
34+
document.add_heading(level=-1)
35+
with pytest.raises(ValueError):
36+
document.add_heading(level=10)
37+
2338
def it_can_add_a_paragraph(self, add_paragraph_fixture):
2439
document, text, style, paragraph_ = add_paragraph_fixture
2540
paragraph = document.add_paragraph(text, style)
@@ -38,6 +53,19 @@ def it_provides_access_to_the_document_body(self, body_fixture):
3853

3954
# fixtures -------------------------------------------------------
4055

56+
@pytest.fixture(params=[
57+
(0, 'Title'),
58+
(1, 'Heading 1'),
59+
(2, 'Heading 2'),
60+
(9, 'Heading 9'),
61+
])
62+
def add_heading_fixture(self, request, add_paragraph_, paragraph_):
63+
level, style = request.param
64+
document = Document(None, None)
65+
text = 'Spam vs. Bacon'
66+
add_paragraph_.return_value = paragraph_
67+
return document, text, level, style, paragraph_
68+
4169
@pytest.fixture(params=[
4270
('', None),
4371
('', 'Heading 1'),
@@ -63,6 +91,10 @@ def part_fixture(self, document_part_):
6391

6492
# fixture components ---------------------------------------------
6593

94+
@pytest.fixture
95+
def add_paragraph_(self, request):
96+
return method_mock(request, Document, 'add_paragraph')
97+
6698
@pytest.fixture
6799
def _Body_(self, request, body_):
68100
return class_mock(request, 'docx.document._Body', return_value=body_)

0 commit comments

Comments
 (0)