Skip to content

Commit f31cb07

Browse files
committed
hdr: add PartFactory loads HeaderPart
1 parent 5e60b97 commit f31cb07

File tree

5 files changed

+48
-8
lines changed

5 files changed

+48
-8
lines changed

docx/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from docx.opc.parts.coreprops import CorePropertiesPart
1313

1414
from docx.parts.document import DocumentPart
15+
from docx.parts.hdrftr import HeaderPart
1516
from docx.parts.image import ImagePart
1617
from docx.parts.numbering import NumberingPart
1718
from docx.parts.settings import SettingsPart
@@ -27,6 +28,7 @@ def part_class_selector(content_type, reltype):
2728
PartFactory.part_class_selector = part_class_selector
2829
PartFactory.part_type_for[CT.OPC_CORE_PROPERTIES] = CorePropertiesPart
2930
PartFactory.part_type_for[CT.WML_DOCUMENT_MAIN] = DocumentPart
31+
PartFactory.part_type_for[CT.WML_HEADER] = HeaderPart
3032
PartFactory.part_type_for[CT.WML_NUMBERING] = NumberingPart
3133
PartFactory.part_type_for[CT.WML_SETTINGS] = SettingsPart
3234
PartFactory.part_type_for[CT.WML_STYLES] = StylesPart
@@ -35,6 +37,7 @@ def part_class_selector(content_type, reltype):
3537
CT,
3638
CorePropertiesPart,
3739
DocumentPart,
40+
HeaderPart,
3841
NumberingPart,
3942
PartFactory,
4043
SettingsPart,

docx/oxml/__init__.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,20 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None):
8484
register_element_cls('w:numbering', CT_Numbering)
8585
register_element_cls('w:startOverride', CT_DecimalNumber)
8686

87-
from .section import CT_HdrFtrRef, CT_PageMar, CT_PageSz, CT_SectPr, CT_SectType # noqa
88-
register_element_cls('w:headerReference', CT_HdrFtrRef)
89-
register_element_cls('w:pgMar', CT_PageMar)
90-
register_element_cls('w:pgSz', CT_PageSz)
91-
register_element_cls('w:sectPr', CT_SectPr)
92-
register_element_cls('w:type', CT_SectType)
87+
from .section import ( # noqa
88+
CT_HdrFtr,
89+
CT_HdrFtrRef,
90+
CT_PageMar,
91+
CT_PageSz,
92+
CT_SectPr,
93+
CT_SectType,
94+
)
95+
register_element_cls("w:hdr", CT_HdrFtr)
96+
register_element_cls("w:headerReference", CT_HdrFtrRef)
97+
register_element_cls("w:pgMar", CT_PageMar)
98+
register_element_cls("w:pgSz", CT_PageSz)
99+
register_element_cls("w:sectPr", CT_SectPr)
100+
register_element_cls("w:type", CT_SectType)
93101

94102
from .shape import ( # noqa
95103
CT_Blip,

docx/oxml/section.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
)
1818

1919

20+
class CT_HdrFtr(BaseOxmlElement):
21+
"""`w:hdr` and `w:ftr`, the root element for header and footer part respectively"""
22+
23+
p = ZeroOrMore('w:p', successors=())
24+
tbl = ZeroOrMore('w:tbl', successors=())
25+
26+
2027
class CT_HdrFtrRef(BaseOxmlElement):
2128
"""`w:headerReference` and `w:footerReference` elements"""
2229

features/hdr-header-footer.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ Feature: Header and footer behaviors
2727
| with no | True |
2828

2929

30-
@wip
3130
Scenario: _Header inherits content
3231
Given a _Header object with a header definition as header
3332
And the next _Header object with no header definition as header_2

tests/parts/test_hdrftr.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
import pytest
88

9-
from docx.opc.constants import CONTENT_TYPE as CT
9+
from docx.opc.constants import CONTENT_TYPE as CT, RELATIONSHIP_TYPE as RT
10+
from docx.opc.part import PartFactory
1011
from docx.package import Package
1112
from docx.parts.hdrftr import HeaderPart
1213

@@ -16,6 +17,20 @@
1617

1718
class DescribeHeaderPart(object):
1819

20+
def it_is_used_by_loader_to_construct_header_part(
21+
self, package_, HeaderPart_load_, header_part_
22+
):
23+
partname = "header1.xml"
24+
content_type = CT.WML_HEADER
25+
reltype = RT.HEADER
26+
blob = "<w:hdr/>"
27+
HeaderPart_load_.return_value = header_part_
28+
29+
part = PartFactory(partname, content_type, reltype, blob, package_)
30+
31+
HeaderPart_load_.assert_called_once_with(partname, content_type, blob, package_)
32+
assert part is header_part_
33+
1934
def it_can_create_a_new_header_part(
2035
self, package_, _default_header_xml_, parse_xml_, _init_
2136
):
@@ -48,6 +63,14 @@ def it_loads_default_header_XML_from_a_template_to_help(self):
4863
def _default_header_xml_(self, request):
4964
return method_mock(request, HeaderPart, "_default_header_xml", autospec=False)
5065

66+
@pytest.fixture
67+
def HeaderPart_load_(self, request):
68+
return method_mock(request, HeaderPart, "load", autospec=False)
69+
70+
@pytest.fixture
71+
def header_part_(self, request):
72+
return instance_mock(request, HeaderPart)
73+
5174
@pytest.fixture
5275
def _init_(self, request):
5376
return initializer_mock(request, HeaderPart, autospec=True)

0 commit comments

Comments
 (0)