summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2014-06-08 22:25:35 +0100
committerMichael Williamson <mike@zwobble.org>2014-06-08 22:25:35 +0100
commitf37fce68a77630a199737959e9d235d0a1263662 (patch)
tree3a491f30099c8a548d6437b09e04ada4f24f28b8
parent6358a5201b97067e86cd06dff634bcefc6acb856 (diff)
Read style name for paragraphs out of source document
-rw-r--r--mammoth/docx/__init__.py5
-rw-r--r--mammoth/docx/document_xml.py19
-rw-r--r--mammoth/docx/styles_xml.py10
-rw-r--r--tests/docx/document_xml_tests.py17
4 files changed, 43 insertions, 8 deletions
diff --git a/mammoth/docx/__init__.py b/mammoth/docx/__init__.py
index 41c42a8..c0a7ea3 100644
--- a/mammoth/docx/__init__.py
+++ b/mammoth/docx/__init__.py
@@ -7,6 +7,7 @@ from .document_xml import read_document_xml_element
from .content_types_xml import read_content_types_xml_element
from .relationships_xml import read_relationships_xml_element
from .numbering_xml import read_numbering_xml_element, Numbering
+from .styles_xml import read_styles_xml_element
_namespaces = [
@@ -34,6 +35,9 @@ def read(fileobj):
else:
numbering = Numbering({})
+ with _open_entry(zip_file, "word/styles.xml") as styles_fileobj:
+ styles = read_styles_xml_element(_parse_docx_xml(styles_fileobj))
+
with _open_entry(zip_file, "word/document.xml") as document_fileobj:
document_xml = _parse_docx_xml(document_fileobj)
return read_document_xml_element(
@@ -42,6 +46,7 @@ def read(fileobj):
relationships=relationships,
docx_file=zip_file,
numbering=numbering,
+ styles=styles,
)
diff --git a/mammoth/docx/document_xml.py b/mammoth/docx/document_xml.py
index 5023ec5..83d82df 100644
--- a/mammoth/docx/document_xml.py
+++ b/mammoth/docx/document_xml.py
@@ -7,11 +7,17 @@ from .. import lists
from .xmlparser import node_types
-def read_document_xml_element(element, numbering=None, content_types=None, relationships=None, docx_file=None):
- reader = _create_reader(numbering=numbering, content_types=content_types, relationships=relationships, docx_file=docx_file)
+def read_document_xml_element(element, numbering=None, content_types=None, relationships=None, styles=None, docx_file=None):
+ reader = _create_reader(
+ numbering=numbering,
+ content_types=content_types,
+ relationships=relationships,
+ styles=styles,
+ docx_file=docx_file,
+ )
return reader(element)
-def _create_reader(numbering, content_types, relationships, docx_file):
+def _create_reader(numbering, content_types, relationships, styles, docx_file):
_handlers = {}
_ignored_elements = set([
"w:bookmarkStart",
@@ -63,6 +69,12 @@ def _create_reader(numbering, content_types, relationships, docx_file):
style_id = properties \
.find_child_or_null("w:pStyle") \
.attributes.get("w:val")
+
+ if style_id is None:
+ style_name = None
+ else:
+ style_name = styles.find_paragraph_style_by_id(style_id).name
+
numbering_properties = properties.find_child("w:numPr")
if numbering_properties is None:
numbering = None
@@ -73,6 +85,7 @@ def _create_reader(numbering, content_types, relationships, docx_file):
.map(lambda children: documents.paragraph(
children=children,
style_id=style_id,
+ style_name=style_name,
numbering=numbering,
))
diff --git a/mammoth/docx/styles_xml.py b/mammoth/docx/styles_xml.py
index c220740..ab3cc0f 100644
--- a/mammoth/docx/styles_xml.py
+++ b/mammoth/docx/styles_xml.py
@@ -23,16 +23,18 @@ def read_styles_xml_element(element):
for style_element in element.find_children("w:style"):
style = _read_style_element(style_element)
- styles[style.element_type][style.style_id] = style
+ element_type = style_element.attributes["w:type"]
+ style_set = styles.get(element_type)
+ if style_set is not None:
+ style_set[style.style_id] = style
return Styles(paragraph_styles, character_styles)
def _read_style_element(element):
- element_type = element.attributes["w:type"]
style_id = element.attributes["w:styleId"]
name = element.find_child("w:name").attributes["w:val"]
- return Style(element_type=element_type, style_id=style_id, name=name)
+ return Style(style_id=style_id, name=name)
-Style = collections.namedtuple("Style", ["element_type", "style_id", "name"])
+Style = collections.namedtuple("Style", ["style_id", "name"])
diff --git a/tests/docx/document_xml_tests.py b/tests/docx/document_xml_tests.py
index e63cd60..e8757f5 100644
--- a/tests/docx/document_xml_tests.py
+++ b/tests/docx/document_xml_tests.py
@@ -8,6 +8,7 @@ from mammoth.docx.xmlparser import element as xml_element, text as xml_text
from mammoth.docx.document_xml import read_document_xml_element
from mammoth.docx.numbering_xml import Numbering
from mammoth.docx.relationships_xml import Relationships, Relationship
+from mammoth.docx.styles_xml import Styles, Style
@istest
@@ -51,10 +52,24 @@ class ReadXmlElementTests(object):
style_xml = xml_element("w:pStyle", {"w:val": "Heading1"})
properties_xml = xml_element("w:pPr", {}, [style_xml])
paragraph_xml = xml_element("w:p", {}, [properties_xml])
- paragraph = _read_and_get_document_xml_element(paragraph_xml)
+
+ styles = Styles({"Heading1": Style(style_id="Heading1", name="Heading 1")}, {})
+
+ paragraph = _read_and_get_document_xml_element(paragraph_xml, styles=styles)
assert_equal("Heading1", paragraph.style_id)
@istest
+ def paragraph_has_style_name_read_from_paragraph_properties_and_styles(self):
+ style_xml = xml_element("w:pStyle", {"w:val": "Heading1"})
+ properties_xml = xml_element("w:pPr", {}, [style_xml])
+ paragraph_xml = xml_element("w:p", {}, [properties_xml])
+
+ styles = Styles({"Heading1": Style(style_id="Heading1", name="Heading 1")}, {})
+
+ paragraph = _read_and_get_document_xml_element(paragraph_xml, styles=styles)
+ assert_equal("Heading 1", paragraph.style_name)
+
+ @istest
def paragraph_has_no_numbering_if_it_has_no_numbering_properties(self):
element = xml_element("w:p")
assert_equal(None, _read_and_get_document_xml_element(element).numbering)