Skip to content

Commit 7e8c9de

Browse files
committed
docs: document Bookmarks analysis
1 parent e784a73 commit 7e8c9de

File tree

2 files changed

+192
-0
lines changed

2 files changed

+192
-0
lines changed
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
2+
Bookmarks
3+
=========
4+
5+
WordprocessingML allows for custom specification of bookmarks at different
6+
locations wihin the document. The bookmarks object will therefore be available
7+
from the main document API. The location will be docx.document.
8+
The bookmarks object will be a list like sequence object, it will be possible
9+
to interate through the different bookmarks. A __len__ property is also
10+
required to provide the bookmark a unique id, to go along with a new bookmark.
11+
A boomark is a seperate object which has no particular place, therefore the
12+
both the Bookmark and the Bookmarks objects will be placed in the
13+
docx.text.bookmark location.
14+
15+
A Bookmark object has two properties, a name and an id which has to be
16+
identical within a single bookmark. A Bookmark object can be placed in
17+
a run or a paragraph and consists of a bookmarkStart element and a
18+
bookmarkEnd element.
19+
20+
Bookmarks can be used to mark certain location in the document. Insertion
21+
of a bookmark can be done from either document, paragraph or run level.
22+
23+
Ther are many applications for the bookmark, many are found in the 'tracked
24+
changes' like operations in word. The intended use for this implementation lies
25+
more in the captions and crossrefernces. It could however also be extended to also
26+
include specific cell locations in a table.
27+
28+
Protocol
29+
--------
30+
31+
.. highlight:: python
32+
33+
Getting and setting tab stops::
34+
35+
>>> boomarks = document.bookmarks
36+
>>> boomarks
37+
<docx.text.bookmark.Bookmarks object at 0x000000000>
38+
39+
>>> bookmark = bookmarks.add_bookmark(name='test')
40+
41+
>>> start = bookmark.add_bookmark_start()
42+
>>> end = bookmark.add_bookmark_end()
43+
44+
>>> len(bookmarks)
45+
1
46+
>>> bookmarks.get(name='test')
47+
docx.text.bookmark.Bookmark object at 0x000000001>
48+
>>> bookmarks[0]
49+
docx.text.bookmark.Bookmark object at 0x000000001>
50+
51+
Word Behavior
52+
-------------
53+
54+
When a <w:bookmarkStart> element is present, word inspects whether it has a
55+
name and an id. This id is used to match the corresponding <w:bookmarkEnd>
56+
element. Without the ID the document is non compliant.
57+
58+
Word is capable of redefining the id's, the bookmark names can be found in the
59+
cross reference dialog.
60+
61+
An unclosed bookmark (i.e. only a <w:bookmarkStart> element is inserted, but
62+
the corresponding <W:bookmarkEnd> element is missing.) will be ignored by word.
63+
64+
65+
XML Semantics
66+
-------------
67+
68+
* The bookmark XML element predates the real structured XML element list of
69+
word and has therefore a less strict location structure
70+
71+
* "start" alignment is equivalent to "left", and "end" alignment are equivalent
72+
to "right". (Confirmed with manually edited XML.)
73+
74+
* A "clear" tab stop is not shown in Word's tab bar and default tab behavior
75+
is followed in the document. That is, Word ignores that tab stop
76+
specification completely, acting as if it were not there at all. This
77+
allows a tab stop inherited from a style, for example, to be ignored.
78+
79+
* the id's in the elements need be identical for a bookmark to work:
80+
81+
Specimen XML
82+
------------
83+
84+
.. highlight:: xml
85+
86+
::
87+
88+
<w:p>
89+
<w:r>
90+
<w:t>Example</w:t>
91+
</w:r>
92+
<w:bookmarkStart w:id="0" w:name="sampleBookmark" />
93+
<w:r>
94+
<w:t xml:space="preserve"> text.</w:t>
95+
</w:r>
96+
</w:p>
97+
<w:p>
98+
<w:r>
99+
<w:t>Example</w:t>
100+
</w:r>
101+
<w:bookmarkEnd w:id="0" />
102+
<w:r>
103+
<w:t xml:space="preserve"> text.</w:t>
104+
</w:r>
105+
</w:p>
106+
107+
MS API Protocol
108+
---------------
109+
110+
The MS API defines a `Bookmarks` object which is a collection of
111+
`Bookmark objects`
112+
113+
.. _Bookmarks object:
114+
https://msdn.microsoft.com/en-us/vba/word-vba/articles/bookmarks-object-word
115+
116+
.. _Bookmark objects:
117+
https://msdn.microsoft.com/en-us/vba/word-vba/articles/bookmark-object-word
118+
119+
120+
Schema excerpt
121+
--------------
122+
123+
::
124+
125+
<xsd:complexType name="CT_Body">
126+
<xsd:sequence>
127+
<xsd:choice minOccurs="0" maxOccurs="unbounded">
128+
<xsd:element name="p" type="CT_P"/>
129+
<xsd:element name="tbl" type="CT_Tbl"/>
130+
<xsd:element name="customXml" type="CT_CustomXmlBlock"/>
131+
<xsd:element name="sdt" type="CT_SdtBlock"/>
132+
<xsd:element name="proofErr" type="CT_ProofErr"/>
133+
<xsd:element name="permStart" type="CT_PermStart"/>
134+
<xsd:element name="permEnd" type="CT_Perm"/>
135+
<xsd:element name="ins" type="CT_RunTrackChange"/>
136+
<xsd:element name="del" type="CT_RunTrackChange"/>
137+
<xsd:element name="moveFrom" type="CT_RunTrackChange"/>
138+
<xsd:element name="moveTo" type="CT_RunTrackChange"/>
139+
<xsd:element ref="m:oMathPara" type="CT_OMathPara"/>
140+
<xsd:element ref="m:oMath" type="CT_OMath"/>
141+
<xsd:element name="bookmarkStart" type="CT_Bookmark"/>
142+
<xsd:element name="bookmarkEnd" type="CT_MarkupRange"/>
143+
<xsd:element name="moveFromRangeStart" type="CT_MoveBookmark"/>
144+
<xsd:element name="moveFromRangeEnd" type="CT_MarkupRange"/>
145+
<xsd:element name="moveToRangeStart" type="CT_MoveBookmark"/>
146+
<xsd:element name="moveToRangeEnd" type="CT_MarkupRange"/>
147+
<xsd:element name="commentRangeStart" type="CT_MarkupRange"/>
148+
<xsd:element name="commentRangeEnd" type="CT_MarkupRange"/>
149+
<xsd:element name="customXmlInsRangeStart" type="CT_TrackChange"/>
150+
<xsd:element name="customXmlInsRangeEnd" type="CT_Markup"/>
151+
<xsd:element name="customXmlDelRangeStart" type="CT_TrackChange"/>
152+
<xsd:element name="customXmlDelRangeEnd" type="CT_Markup"/>
153+
<xsd:element name="customXmlMoveFromRangeStart" type="CT_TrackChange"/>
154+
<xsd:element name="customXmlMoveFromRangeEnd" type="CT_Markup"/>
155+
<xsd:element name="customXmlMoveToRangeStart" type="CT_TrackChange"/>
156+
<xsd:element name="customXmlMoveToRangeEnd" type="CT_Markup"/>
157+
<xsd:element name="altChunk" type="CT_AltChunk"/>
158+
</xsd:choice>
159+
<xsd:element name="sectPr" type="CT_SectPr" minOccurs="0" maxOccurs="1"/>
160+
</xsd:sequence>
161+
</xsd:complexType>
162+
163+
<xsd:complexType name="CT_Bookmark">
164+
<xsd:complexContent>
165+
<xsd:extension base="CT_BookmarkRange">
166+
<xsd:attribute name="name" type="ST_String" use="required">
167+
<xsd:annotation>
168+
<xsd:documentation>Bookmark Name</xsd:documentation>
169+
</xsd:annotation>
170+
</xsd:attribute>
171+
</xsd:extension>
172+
</xsd:complexContent>
173+
</xsd:complexType>
174+
175+
<xsd:complexType name="CT_BookmarkRange">
176+
<xsd:complexContent>
177+
<xsd:extension base="CT_MarkupRange">
178+
<xsd:attribute name="colFirst" type="ST_DecimalNumber" use="optional">
179+
<xsd:annotation>
180+
<xsd:documentation>First Table Column Covered By Bookmark</xsd:documentation>
181+
</xsd:annotation>
182+
</xsd:attribute>
183+
<xsd:attribute name="colLast" type="ST_DecimalNumber" use="optional">
184+
<xsd:annotation>
185+
<xsd:documentation>Last Table Column Covered By Bookmark</xsd:documentation>
186+
</xsd:annotation>
187+
</xsd:attribute>
188+
</xsd:extension>
189+
</xsd:complexContent>
190+
</xsd:complexType>
191+

docs/dev/analysis/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Feature Analysis
1919
features/coreprops
2020
features/numbering
2121
features/sections
22+
features/bookmarks
2223

2324

2425
Schema Analysis

0 commit comments

Comments
 (0)