Skip to content

Commit f1ca7b4

Browse files
author
Steve Canny
committed
style: add Document.styles_part
1 parent bf21050 commit f1ca7b4

3 files changed

Lines changed: 79 additions & 0 deletions

File tree

docx/api.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from docx.opc.constants import CONTENT_TYPE as CT, RELATIONSHIP_TYPE as RT
1515
from docx.package import Package
1616
from docx.parts.numbering import NumberingPart
17+
from docx.parts.styles import StylesPart
1718
from docx.shared import lazyproperty
1819

1920

@@ -146,6 +147,19 @@ def save(self, path_or_stream):
146147
"""
147148
self._package.save(path_or_stream)
148149

150+
@lazyproperty
151+
def styles_part(self):
152+
"""
153+
Instance of |StylesPart| for this document. Creates an empty styles
154+
part if one is not present.
155+
"""
156+
try:
157+
return self._document_part.part_related_by(RT.STYLES)
158+
except KeyError:
159+
styles_part = StylesPart.new()
160+
self._document_part.relate_to(styles_part, RT.STYLES)
161+
return styles_part
162+
149163
@property
150164
def tables(self):
151165
"""

docx/parts/styles.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# encoding: utf-8
2+
3+
"""
4+
Provides StylesPart and related objects
5+
"""
6+
7+
from __future__ import (
8+
absolute_import, division, print_function, unicode_literals
9+
)
10+
11+
from ..opc.package import Part
12+
13+
14+
class StylesPart(Part):
15+
"""
16+
Proxy for the styles.xml part containing style definitions for a document
17+
or glossary.
18+
"""
19+
@classmethod
20+
def new(cls):
21+
"""
22+
Return newly created empty styles part, containing only the root
23+
``<w:styles>`` element.
24+
"""
25+
raise NotImplementedError

tests/test_api.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from docx.package import Package
1717
from docx.parts.document import DocumentPart, InlineShapes
1818
from docx.parts.numbering import NumberingPart
19+
from docx.parts.styles import StylesPart
1920
from docx.table import Table
2021
from docx.text import Paragraph, Run
2122

@@ -142,6 +143,24 @@ def it_creates_numbering_part_on_first_access_if_not_present(
142143
)
143144
assert numbering_part is numbering_part_
144145

146+
def it_provides_access_to_the_styles_part(self, styles_part_get_fixture):
147+
document, document_part_, styles_part_ = styles_part_get_fixture
148+
styles_part = document.styles_part
149+
document_part_.part_related_by.assert_called_once_with(RT.STYLES)
150+
assert styles_part is styles_part_
151+
152+
def it_creates_styles_part_on_first_access_if_not_present(
153+
self, styles_part_create_fixture):
154+
document, StylesPart_, document_part_, styles_part_ = (
155+
styles_part_create_fixture
156+
)
157+
styles_part = document.styles_part
158+
StylesPart_.new.assert_called_once_with()
159+
document_part_.relate_to.assert_called_once_with(
160+
styles_part_, RT.STYLES
161+
)
162+
assert styles_part is styles_part_
163+
145164
# fixtures -------------------------------------------------------
146165

147166
@pytest.fixture(params=[0, 1, 2, 5, 9])
@@ -307,6 +326,27 @@ def save_fixture(self, request, open_, package_):
307326
document = Document()
308327
return document, package_, file_
309328

329+
@pytest.fixture
330+
def StylesPart_(self, request, styles_part_):
331+
StylesPart_ = class_mock(request, 'docx.api.StylesPart')
332+
StylesPart_.new.return_value = styles_part_
333+
return StylesPart_
334+
335+
@pytest.fixture
336+
def styles_part_(self, request):
337+
return instance_mock(request, StylesPart)
338+
339+
@pytest.fixture
340+
def styles_part_create_fixture(
341+
self, document, StylesPart_, document_part_, styles_part_):
342+
document_part_.part_related_by.side_effect = KeyError
343+
return document, StylesPart_, document_part_, styles_part_
344+
345+
@pytest.fixture
346+
def styles_part_get_fixture(self, document, document_part_, styles_part_):
347+
document_part_.part_related_by.return_value = styles_part_
348+
return document, document_part_, styles_part_
349+
310350
@pytest.fixture
311351
def table_(self, request):
312352
return instance_mock(request, Table, style=None)

0 commit comments

Comments
 (0)