Skip to content

Commit dbd5993

Browse files
committed
New try
1 parent 464667a commit dbd5993

File tree

5 files changed

+59
-32
lines changed

5 files changed

+59
-32
lines changed

docx/document.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from .section import Section, Sections
1515
from docx.shared import ElementProxy, Emu
1616
from docx.text.bookmarks import Bookmark, Bookmarks
17-
from docx.oxml.xmlchemy import BaseOxmlElement, ZeroOrOne, ZeroOrMore
17+
from docx.oxml.xmlchemy import ZeroOrOne, ZeroOrMore
1818

1919

2020
class Document(ElementProxy):
@@ -23,23 +23,24 @@ class Document(ElementProxy):
2323
Use :func:`docx.Document` to open or create a document.
2424
"""
2525

26-
__slots__ = ('_part', '__body')
26+
__slots__ = ('_part', '__body', '_Bookmarks')
2727

2828
def __init__(self, element, part):
2929
super(Document, self).__init__(element)
3030
self._part = part
3131
self.__body = None
32+
self._Bookmarks = Bookmarks(self._element.body)
3233

33-
def bookmark(self):
34-
return Bookmarks(self._element.body)
35-
# def add_bookmark_start(self, name):
36-
# paragraph = self.add_paragraph()
37-
# return paragraph.add_bookmark_start(id, name)
34+
def start_bookmark(self, name):
35+
bookmarkstart = self._body.add_bookmarkStart(name)
36+
return Bookmark(bookmarkstart)
3837

39-
# def add_bookmark_end(self, name):
40-
# id = 1
41-
# paragraph = self.add_paragraph()
42-
# return paragraph.add_bookmark_end(id)
38+
def end_bookmark(self):
39+
bookmarkend = self._body.add_bookmarkEnd()
40+
return Bookmark(bookmarkend)
41+
42+
def bookmarks(self):
43+
return self._Bookmarks # (self._element.body)
4344

4445
def add_heading(self, text='', level=1):
4546
"""
@@ -218,6 +219,7 @@ class _Body(BlockItemContainer):
218219
def __init__(self, body_elm, parent):
219220
super(_Body, self).__init__(body_elm, parent)
220221
self._body = body_elm
222+
self._parent = parent
221223

222224
def clear_content(self):
223225
"""
@@ -227,3 +229,15 @@ def clear_content(self):
227229
"""
228230
self._body.clear_content()
229231
return self
232+
233+
def add_bookmarkStart(self, name):
234+
bookmarkStart = self._body._add_bookmarkStart()
235+
bookmarkStart.name = name
236+
bookmarkStart.bmrk_id = self._parent._Bookmarks._next_id
237+
return Bookmark(bookmarkStart)
238+
239+
def add_bookmarkEnd(self):
240+
open_id = self._parent._Bookmarks._unclosed_bookmark
241+
bookmarkEnd = self._body._add_bookmarkEnd()
242+
bookmarkEnd.bmrk_id = open_id
243+
return Bookmark(bookmarkEnd)

docx/oxml/document.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ class CT_Document(BaseOxmlElement):
1313
``<w:document>`` element, the root element of a document.xml file.
1414
"""
1515
body = ZeroOrOne('w:body')
16-
bookmarkStart = ZeroOrMore('w:bookmarkStart')
17-
bookmarkEnd = ZeroOrMore('w:bookmarkEnd')
16+
1817
@property
1918
def sectPr_lst(self):
2019
"""
@@ -31,10 +30,10 @@ class CT_Body(BaseOxmlElement):
3130
"""
3231
p = ZeroOrMore('w:p', successors=('w:sectPr',))
3332
tbl = ZeroOrMore('w:tbl', successors=('w:sectPr',))
33+
bookmarkStart = ZeroOrMore('w:bookmarkStart', successors=('w:sectPr',))
34+
bookmarkEnd = ZeroOrMore('w:bookmarkEnd', successors=('w:sectPr',))
3435
sectPr = ZeroOrOne('w:sectPr', successors=())
35-
bookmarkStart = ZeroOrMore('w:bookmarkStart')
36-
bookmarkEnd = ZeroOrMore('w:bookmarkEnd')
37-
36+
3837
def add_section_break(self):
3938
"""
4039
Return the current ``<w:sectPr>`` element after adding a clone of it

docx/oxml/text/paragraph.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class CT_P(BaseOxmlElement):
1515
"""
1616
pPr = ZeroOrOne('w:pPr')
1717
r = ZeroOrMore('w:r')
18-
bookmarkStart = ZeroOrMore('w:bookmarkStart')
19-
bookmarkEnd = ZeroOrMore('w:bookmarkEnd')
18+
bookmarkStart = ZeroOrMore('w:bookmarkStart', successors=('w:sectPr',))
19+
bookmarkEnd = ZeroOrMore('w:bookmarkEnd', successors=('w:sectPr',))
2020

2121
def _insert_pPr(self, pPr):
2222
self.insert(0, pPr)

docx/oxml/text/run.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ class CT_R(BaseOxmlElement):
2929
cr = ZeroOrMore('w:cr')
3030
tab = ZeroOrMore('w:tab')
3131
drawing = ZeroOrMore('w:drawing')
32-
bookmarkStart = ZeroOrMore('w:bookmarkStart')
33-
bookmarkEnd = ZeroOrMore('w:bookmarkEnd')
32+
bookmarkStart = ZeroOrMore('w:bookmarkStart', successors=('w:sectPr',))
33+
bookmarkEnd = ZeroOrMore('w:bookmarkEnd', successors=('w:sectPr',))
3434

3535
def _insert_rPr(self, rPr):
3636
self.insert(0, rPr)

docx/text/bookmarks.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,26 +35,40 @@ def get(self, name, default=None):
3535
return Bookmark(bookmarkStart)
3636
return default
3737

38-
def add_bookmark(self):
39-
return Bookmark(self._element)
40-
4138
@property
4239
def _bookmarkStarts(self):
4340
return self._document.xpath('.//w:bookmarkStart')
4441

42+
@property
43+
def _bookmarkEnds(self):
44+
return self._document.xpath('.//w:bookmarkEnd')
45+
46+
@property
47+
def _next_id(self):
48+
return str(len(self._bookmarkStarts))
49+
50+
51+
@property
52+
def _unclosed_bookmark(self):
53+
open_b = set(Bookmark(bmrk)._id for bmrk in self._bookmarkStarts)
54+
closed = set(Bookmark(bmrk)._id for bmrk in self._bookmarkEnds)
55+
check = open_b - closed
56+
if len(self._bookmarkStarts) == 0:
57+
raise ValueError('BookmarkEnd requested without a bookmarkStart present')
58+
if len(check) == 0:
59+
raise ValueError('No open bookmark found')
60+
else:
61+
return check.pop()
4562

4663
class Bookmark(ElementProxy):
4764
def __init__(self, doc_element):
4865
super(Bookmark, self).__init__(doc_element)
4966
self._element = doc_element
5067

51-
def add_bookmark_start(self, id, name):
52-
bmrk = self._element._add_bookmarkStart()
53-
bmrk.name = name
54-
bmrk.bmrk_id = str(id)
55-
return self._element.append(bmrk)
68+
@property
69+
def _id(self):
70+
return self._element.bmrk_id
5671

57-
def add_bookmark_end(self, id):
58-
bmrk = self._element._add_bookmarkEnd()
59-
bmrk.bmrk_id = str(1)
60-
return self._element.append(bmrk)
72+
@property
73+
def _name(self):
74+
return self._element.name

0 commit comments

Comments
 (0)