Skip to content

Commit afd1cc3

Browse files
Benjamin Toornstrascanny
authored andcommitted
doc: add Document.bookmarks
1 parent 8dc7a3e commit afd1cc3

5 files changed

Lines changed: 58 additions & 11 deletions

File tree

docs/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@
7777
7878
.. |_Body| replace:: :class:`._Body`
7979
80+
.. |Bookmark| replace:: :class:`.Bookmark`
81+
82+
.. |Bookmarks| replace:: :class:`.Bookmarks`
83+
8084
.. |_Cell| replace:: :class:`._Cell`
8185
8286
.. |_CharacterStyle| replace:: :class:`._CharacterStyle`

docx/bookmark.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# encoding: utf-8
2+
3+
"""Objects related to bookmarks."""
4+
5+
from __future__ import (
6+
absolute_import, division, print_function, unicode_literals
7+
)
8+
9+
10+
class Bookmarks(object):
11+
"""Sequence of |Bookmark| objects."""
12+
13+
def __init__(self, document_part):
14+
self._document_part = document_part

docx/document.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
from __future__ import absolute_import, division, print_function, unicode_literals
66

77
from docx.blkcntnr import BlockItemContainer
8+
9+
from docx.bookmark import Bookmarks
810
from docx.enum.section import WD_SECTION
911
from docx.enum.text import WD_BREAK
1012
from docx.section import Section, Sections
11-
from docx.shared import ElementProxy, Emu
13+
from docx.shared import ElementProxy, Emu, lazyproperty
1214

1315

1416
class Document(ElementProxy):
@@ -18,7 +20,7 @@ class Document(ElementProxy):
1820
a document.
1921
"""
2022

21-
__slots__ = ('_part', '__body')
23+
__slots__ = ("__body", "_bookmarks", "_part")
2224

2325
def __init__(self, element, part):
2426
super(Document, self).__init__(element)
@@ -44,7 +46,7 @@ def add_page_break(self):
4446
paragraph.add_run().add_break(WD_BREAK.PAGE)
4547
return paragraph
4648

47-
def add_paragraph(self, text='', style=None):
49+
def add_paragraph(self, text="", style=None):
4850
"""
4951
Return a paragraph newly added to the end of the document, populated
5052
with *text* and having paragraph style *style*. *text* can contain
@@ -93,6 +95,16 @@ def add_table(self, rows, cols, style=None):
9395
table.style = style
9496
return table
9597

98+
@lazyproperty
99+
def bookmarks(self):
100+
"""|Bookmarks| object providing access to |Bookmark| objects.
101+
102+
A bookmark may exist in the main document story, but also in headers,
103+
footers, footnotes or endnotes. This collection contains all
104+
bookmarks defined in any of these parts.
105+
"""
106+
return Bookmarks(self._part)
107+
96108
@property
97109
def core_properties(self):
98110
"""
@@ -172,9 +184,7 @@ def _block_width(self):
172184
space between the margins of the last section of this document.
173185
"""
174186
section = self.sections[-1]
175-
return Emu(
176-
section.page_width - section.left_margin - section.right_margin
177-
)
187+
return Emu(section.page_width - section.left_margin - section.right_margin)
178188

179189
@property
180190
def _body(self):
@@ -191,6 +201,7 @@ class _Body(BlockItemContainer):
191201
Proxy for ``<w:body>`` element in this document, having primarily a
192202
container role.
193203
"""
204+
194205
def __init__(self, body_elm, parent):
195206
super(_Body, self).__init__(body_elm, parent)
196207
self._body = body_elm

features/doc-access-collections.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ Feature: Access document collections
2929
Then document.tables is a list containing three tables
3030

3131

32-
@wip
3332
Scenario: Document.bookmarks
3433
Given a Document object as document
3534
Then document.bookmarks is a Bookmarks object

tests/test_document.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import pytest
88

9+
from docx.bookmark import Bookmarks
910
from docx.document import _Body, Document
1011
from docx.enum.section import WD_SECTION
1112
from docx.enum.text import WD_BREAK
@@ -93,6 +94,16 @@ def it_can_save_the_document_to_a_file(self, save_fixture):
9394
document.save(file_)
9495
document._part.save.assert_called_once_with(file_)
9596

97+
def it_provides_access_to_its_bookmarks(
98+
self, document_part_, Bookmarks_, bookmarks_):
99+
Bookmarks_.return_value = bookmarks_
100+
document = Document(None, document_part_)
101+
102+
bookmarks = document.bookmarks
103+
104+
Bookmarks_.assert_called_once_with(document_part_)
105+
assert bookmarks is bookmarks_
106+
96107
def it_provides_access_to_its_core_properties(self, core_props_fixture):
97108
document, core_properties_ = core_props_fixture
98109
core_properties = document.core_properties
@@ -272,6 +283,10 @@ def tables_fixture(self, body_prop_, tables_):
272283
def add_paragraph_(self, request):
273284
return method_mock(request, Document, 'add_paragraph')
274285

286+
@pytest.fixture
287+
def _block_width_prop_(self, request):
288+
return property_mock(request, Document, '_block_width')
289+
275290
@pytest.fixture
276291
def _Body_(self, request, body_):
277292
return class_mock(request, 'docx.document._Body', return_value=body_)
@@ -281,12 +296,16 @@ def body_(self, request):
281296
return instance_mock(request, _Body)
282297

283298
@pytest.fixture
284-
def _block_width_prop_(self, request):
285-
return property_mock(request, Document, '_block_width')
299+
def body_prop_(self, request, body_):
300+
return property_mock(request, Document, '_body')
286301

287302
@pytest.fixture
288-
def body_prop_(self, request, body_):
289-
return property_mock(request, Document, '_body', return_value=body_)
303+
def Bookmarks_(self, request):
304+
return class_mock(request, 'docx.document.Bookmarks')
305+
306+
@pytest.fixture
307+
def bookmarks_(self, request):
308+
return instance_mock(request, Bookmarks)
290309

291310
@pytest.fixture
292311
def core_properties_(self, request):

0 commit comments

Comments
 (0)