Skip to content

Commit e8fb68e

Browse files
author
Steve Canny
committed
docs: document header/footer feature analysis
1 parent 5f440f8 commit e8fb68e

File tree

2 files changed

+267
-0
lines changed

2 files changed

+267
-0
lines changed
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
2+
Headers and Footers
3+
===================
4+
5+
In a WordprocessingML document, a page header is text that is separated from
6+
the main body of text and appears at the top of a printed page. The page
7+
headers in a document are often the same from page to page, with only small
8+
differences in content, such as a section and/or page number. Such a header
9+
is also known as a *running head*.
10+
11+
In book-printed documents, where pages are intended to bound on the long edge
12+
and presented side-by-side, the header on the right-hand (recto) pages is
13+
often different than that on the left-hand (verso) pages. The need to support
14+
this difference gives rise to the option to have an *even-page* header that
15+
differs from the default *odd-page* header in a document.
16+
17+
A page footer is analogous in every way to a page header except that it
18+
appears at the bottom of a page. It should not be confused with a footnote,
19+
which is not uniform between pages.
20+
21+
In WordprocessingML, a header or footer appears within the margin area of
22+
a page. With a few exceptions, a header or footer can contain all types of
23+
content that can appear in the main body, including text and images. Each
24+
section has its own set of headers and footers, although a section can be
25+
configured to "inherit" headers and footers from the prior section.
26+
27+
Each section can have three distinct header definitions and footer
28+
definitions. These apply to odd pages (the default), even pages, and the
29+
first page of the section. All three are optional.
30+
31+
For brevity in the discussion below I will occasionally use the term *header*
32+
to refer to either a header and footer object, trusting the reader to
33+
understand its applicability to either type of object.
34+
35+
36+
Header and footer parts
37+
-----------------------
38+
39+
Each header or footer definition is a distinct part in the WordprocessingML
40+
package.
41+
42+
A header/footer part is related to the document part by a relationship entry.
43+
That relationship is referenced by a section in the document by its rId key.
44+
45+
A default document will contain no header or footer parts and no
46+
`w:headerReference` or `w:footerReference` elements in its `w:sectPr`
47+
element.
48+
49+
50+
Research TODO
51+
-------------
52+
53+
1. [ ] default blank document baseline
54+
2. [ ] add section break
55+
3. [ ] add section 2 header
56+
57+
A. does Word create a blank default header for section 1?
58+
59+
4. [ ] set odd/even True on document with 2 sections, no header/footers
60+
61+
A. does Word create a blank default header/footer for section 1?
62+
63+
5. [ ] if not, set a header on section 2 and document what happens
64+
6. [ ] try the same on section 1 and see what happens
65+
66+
See if a pattern is discernable.
67+
68+
Hypothesis: Word inserts blank headers and footers only as needed to provide
69+
a running default when the first section has no default. It does this for
70+
both headers and footers whenever it does it at all.
71+
72+
73+
Acceptance Tests
74+
----------------
75+
76+
::
77+
78+
Given a default blank document
79+
Then document.section[0].header is None
80+
And document.section[0].footer is None
81+
82+
83+
Given a document with a single section having a header and footer
84+
Then document.section[0].header is a Header object
85+
And document.section[0].footer is a Footer object
86+
87+
88+
Given a document with two sections having no headers or footers
89+
When I assign True to document.odd_and_even_pages_header_footer
90+
Then document.section[0].even_page_header is a blank Header object
91+
And document.section[0].footer is a blank Footer object
92+
And document.section[1].header is None
93+
And document.section[1].footer is None
94+
95+
96+
Candidate Protocol
97+
------------------
98+
99+
::
100+
101+
>>> document = Document()
102+
>>> section = document.sections[-1]
103+
104+
>>> section.header
105+
None
106+
>>> section.add_header()
107+
<docx.Header object at 0xdeadbeef0>
108+
109+
>>> section.even_page_header
110+
None
111+
>>> section.add_even_page_header()
112+
<docx.Header object at 0xdeadbeef4>
113+
114+
>>> section.first_page_header
115+
None
116+
>>> section.add_first_page_header()
117+
<docx.Header object at 0xdeadbeef8>
118+
119+
120+
MS API
121+
------
122+
123+
.. highlight:: python
124+
125+
WdHeaderFooterIndex Enumeration::
126+
127+
EVEN_PAGES = 3
128+
FIRST_PAGE = 2
129+
PRIMARY = 1
130+
131+
::
132+
133+
section = Document.Sections(1)
134+
footers = section.Footers # a HeadersFooters collection object
135+
default_footer = footers(wdHeaderFooterPrimary)
136+
default_footer.Range.Text = "Footer text"
137+
138+
PageSetup object::
139+
140+
DifferentFirstPageHeaderFooter: Read/write {True, False, WD_UNDEFINED}
141+
OddAndEvenPagesHeaderFooter: Read/write {True, False, WD_UNDEFINED}
142+
143+
144+
Specimen XML
145+
------------
146+
147+
.. highlight:: xml
148+
149+
Baseline blank document (some unrelated details omitted)::
150+
151+
<w:body>
152+
<w:p/>
153+
<w:sectPr>
154+
<w:pgSz w:w="12240" w:h="15840"/>
155+
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800"
156+
w:header="720" w:footer="720" w:gutter="0"/>
157+
</w:sectPr>
158+
</w:body>
159+
160+
<!--
161+
* no relationships to a header or footer part appear in document.xml.rels
162+
* no header or footer parts appear in the package
163+
-->
164+
165+
after adding a header::
166+
167+
<!-- document.xml -->
168+
<w:sectPr>
169+
<w:headerReference w:type="default" r:id="rId8"/>
170+
<w:pgSz w:w="12240" w:h="15840"/>
171+
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800"
172+
w:header="720" w:footer="720" w:gutter="0"/>
173+
</w:sectPr>
174+
175+
<!-- document.xml.rels -->
176+
<Relationship Id="rId8" Type="http://sc...ps/header" Target="header1.xml"/>
177+
178+
after then adding an even-page header::
179+
180+
<!-- document.xml -->
181+
<w:sectPr>
182+
<w:headerReference w:type="even" r:id="rId8"/>
183+
<w:headerReference w:type="default" r:id="rId9"/>
184+
<w:pgSz w:w="12240" w:h="15840"/>
185+
<w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800"
186+
w:header="720" w:footer="720" w:gutter="0"/>
187+
</w:sectPr>
188+
189+
<!-- document.xml.rels -->
190+
<Relationship Id="rId8" Type="http://sc...ps/header" Target="header1.xml"/>
191+
<Relationship Id="rId9" Type="http://sc...ps/header" Target="header2.xml"/>
192+
193+
Implementation sequence
194+
-----------------------
195+
196+
* [ ] Implement skeleton SettingsPart
197+
* [ ] A settings part is constructed by loader using the custom part
198+
* [ ] Access header from section
199+
200+
* [ ] Implement skeleton HeaderPart, consider a HeaderFooterPart base class.
201+
* [ ] A header/footer part is constructed by loader using the custom part
202+
* [ ] Access header from section
203+
204+
Open topics
205+
-----------
206+
207+
* [ ] notion that specifying different even/first header/footers is distinct
208+
from implementing different even/first header/footers. Auto-insertion
209+
of blank items on set different, when needed. Document Word behaviors.
210+
* [ ] settings.xml `w:evenAndOddHeaders`
211+
* [ ] interaction with `w:sectPr/w:titlePg` element for different first-page
212+
header and footer.
213+
* [ ] describe inheritance behavior from user perspective, with examples, of
214+
header/footers and different even and first page header/footers.
215+
* [ ] positioning of header and footer block in `w:pgMar` element
216+
* [ ] part name/location is `word/header1.xml`
217+
218+
* [X] test whether Word will load a file with an even page header but no odd
219+
page header. Yes, works fine.
220+
221+
222+
Differences between a document without and with a header
223+
--------------------------------------------------------
224+
225+
If you create a default document and save it (let's call that test.docx),
226+
then add a header to it like so...
227+
228+
This is a header. x of xx
229+
230+
...the following changes will occur in the package:
231+
232+
1) A part called header1.xml will be added to the package with the following
233+
pathname:
234+
235+
/word/header1.xml
236+
237+
2) A new relationship is specified at word/_rels/document.xml.rels:
238+
239+
::
240+
241+
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml" />*
242+
243+
3) Within the <w:sectPr> element of document.xml, there will be a new element
244+
called headerReference:
245+
246+
::
247+
248+
<w:sectPr>
249+
<w:headerReference w:type="default" r:id="rId2"/>*
250+
...
251+
</w:sectPr>
252+
253+
254+
Different Even/Odd Page Headers and Footers
255+
-------------------------------------------
256+
257+
The `w:evenAndOddHeaders` element in the settings part specifies whether
258+
sections have different headers and footers for even
259+
and odd pages. This setting determines this behavior for all sections in the
260+
document whether they have an even page header/footer defined or not.
261+
A section not having an even-page header or footer defined will inherit it
262+
from the prior section.
263+
264+
When this setting is set to |True|, a blank header and/or footer is created
265+
in the first document section when one is not present and becomes the default
266+
for the sections that follow until a header/footer is explicitly defined.

docs/dev/analysis/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Feature Analysis
1010
.. toctree::
1111
:titlesonly:
1212

13+
features/headerfooter
1314
features/settings
1415
features/text/index
1516
features/table/index

0 commit comments

Comments
 (0)