diff options
| author | Michael Williamson <mike@zwobble.org> | 2013-12-14 17:33:13 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2013-12-14 17:33:13 +0000 |
| commit | 85cc3f93c01312a907fd017d34bc2e5542cac670 (patch) | |
| tree | 6319244994842c813c73005de7cb971fbfe99061 | |
| parent | f5595b78f59d3f3a04c4e83702114dc2704f808a (diff) | |
Plumbing to get full stack working
| -rw-r--r-- | mammoth/__init__.py | 15 | ||||
| -rw-r--r-- | mammoth/docx/__init__.py | 46 | ||||
| -rw-r--r-- | mammoth/style_reader/document_matcher_reader.py | 2 | ||||
| -rw-r--r-- | mammoth/style_reader/html_path_reader.py | 6 | ||||
| -rw-r--r-- | tests/conversion_tests.py | 2 | ||||
| -rw-r--r-- | tests/mammoth_tests.py | 17 | ||||
| -rw-r--r-- | tests/style_reader_tests.py | 4 |
7 files changed, 79 insertions, 13 deletions
diff --git a/mammoth/__init__.py b/mammoth/__init__.py index 92278f7..3c212ac 100644 --- a/mammoth/__init__.py +++ b/mammoth/__init__.py @@ -1,6 +1,17 @@ from .results import Result -from . import docx, conversion +from . import docx, conversion, style_reader def convert_to_html(fileobj): - return docx.read(fileobj).bind(conversion.convert_document_element_to_html) + return docx.read(fileobj).bind(lambda document: + conversion.convert_document_element_to_html(document, styles=_create_default_styles()) + ) + + +def _create_default_styles(): + lines = filter(None, map(lambda line: line.strip(), _default_styles.split("\n"))) + return map(style_reader.read_style, lines) + +_default_styles = """ +p:unordered-list(1) => ul > li:fresh +""" diff --git a/mammoth/docx/__init__.py b/mammoth/docx/__init__.py index bb26826..de15b78 100644 --- a/mammoth/docx/__init__.py +++ b/mammoth/docx/__init__.py @@ -3,16 +3,54 @@ import zipfile from ..results import Result from .xmlparser import parse_xml 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 _namespaces = [ ("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"), + ("wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"), + ("a", "http://schemas.openxmlformats.org/drawingml/2006/main"), + ("pic", "http://schemas.openxmlformats.org/drawingml/2006/picture"), + ("content-types", "http://schemas.openxmlformats.org/package/2006/content-types"), + ("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships"), + ("relationships", "http://schemas.openxmlformats.org/package/2006/relationships"), ] - def read(fileobj): zip_file = zipfile.ZipFile(fileobj) - document_fileobj = zip_file.open("word/document.xml") - document_xml = parse_xml(document_fileobj, _namespaces) - return read_document_xml_element(document_xml) + + with zip_file.open("[Content_Types].xml") as content_types_fileobj: + content_types = read_content_types_xml_element(_parse_docx_xml(content_types_fileobj)) + + with zip_file.open("word/_rels/document.xml.rels") as relationships_fileobj: + relationships = read_relationships_xml_element(_parse_docx_xml(relationships_fileobj)) + + if _has_entry(zip_file, "word/numbering.xml"): + with zip_file.open("word/numbering.xml") as numbering_fileobj: + numbering = read_numbering_xml_element(_parse_docx_xml(numbering_fileobj)) + else: + numbering = Numbering({}) + + with zip_file.open("word/document.xml") as document_fileobj: + document_xml = _parse_docx_xml(document_fileobj) + return read_document_xml_element( + document_xml, + content_types=content_types, + relationships=relationships, + docx_file=zip_file, + numbering=numbering, + ) + + +def _parse_docx_xml(fileobj): + return parse_xml(fileobj, _namespaces) + +def _has_entry(zip_file, name): + try: + zip_file.getinfo(name) + return True + except KeyError: + return False diff --git a/mammoth/style_reader/document_matcher_reader.py b/mammoth/style_reader/document_matcher_reader.py index 4bc7247..44a9896 100644 --- a/mammoth/style_reader/document_matcher_reader.py +++ b/mammoth/style_reader/document_matcher_reader.py @@ -37,7 +37,7 @@ def _read_style_node(style_node): def _read_list_node(list_node): if list_node.children: return documents.numbering_level( - int(list_node.children[0].children[3].text), + int(list_node.children[0].children[3].text) - 1, is_ordered=list_node.children[0].children[1].text == "ordered-list", ) else: diff --git a/mammoth/style_reader/html_path_reader.py b/mammoth/style_reader/html_path_reader.py index 0f1331b..b508f59 100644 --- a/mammoth/style_reader/html_path_reader.py +++ b/mammoth/style_reader/html_path_reader.py @@ -49,18 +49,18 @@ def _repeated_children_with_separator(node, has_whitespace): yield node.children[0] if has_whitespace: - sequence_node_index = 2 + sequence_node_index = 3 else: sequence_node_index = 1 - sequence_node = node.children[sequence_node_index] + sequence_node = node.children[1] for child in sequence_node.children: yield child.children[sequence_node_index] grammar_text = r""" -html_path = element whitespace* (">" whitespace* element)* +html_path = element (whitespace* ">" whitespace* element)* element = tag_names class_name* fresh? diff --git a/tests/conversion_tests.py b/tests/conversion_tests.py index c0fab30..d9742cc 100644 --- a/tests/conversion_tests.py +++ b/tests/conversion_tests.py @@ -81,7 +81,7 @@ def bulleted_paragraphs_are_converted_using_matching_styles(): result = convert_document_element_to_html( documents.paragraph(children=[ _run_with_text("Hello") - ], numbering=documents.numbering_level(level_index=1, is_ordered=False)), + ], numbering=documents.numbering_level(level_index=0, is_ordered=False)), styles=[ style_reader.read_style("p:unordered-list(1) => ul > li:fresh") ] diff --git a/tests/mammoth_tests.py b/tests/mammoth_tests.py index d1492b3..bfa88b5 100644 --- a/tests/mammoth_tests.py +++ b/tests/mammoth_tests.py @@ -11,3 +11,20 @@ def docx_containing_one_paragraph_is_converted_to_single_p_element(): result = mammoth.convert_to_html(fileobj=fileobj) assert_equal("<p>Walking on imported air</p>", result.value) assert_equal([], result.messages) + + +@istest +def inline_images_are_included_in_output(): + with open(test_path("tiny-picture.docx"), "rb") as fileobj: + result = mammoth.convert_to_html(fileobj=fileobj) + assert_equal("""<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAO\nvgAADr4B6kKxwAAAABNJREFUKFNj/M+ADzDhlWUYqdIAQSwBE8U+X40AAAAASUVORK5CYII=" /></p>""", result.value) + assert_equal([], result.messages) + + +@istest +def simple_list_is_converted_to_list_elements(): + with open(test_path("simple-list.docx"), "rb") as fileobj: + result = mammoth.convert_to_html(fileobj=fileobj) + assert_equal([], result.messages) + assert_equal("<ul><li>Apple</li><li>Banana</li></ul>", result.value) + diff --git a/tests/style_reader_tests.py b/tests/style_reader_tests.py index 0d266d6..32636db 100644 --- a/tests/style_reader_tests.py +++ b/tests/style_reader_tests.py @@ -82,7 +82,7 @@ class ReadDocumentMatcherTests(object): @istest def reads_paragraph_ordered_list(self): assert_equal( - document_matchers.paragraph(numbering=documents.numbering_level(2, is_ordered=True)), + document_matchers.paragraph(numbering=documents.numbering_level(1, is_ordered=True)), read_document_matcher("p:ordered-list(2)") ) @@ -90,7 +90,7 @@ class ReadDocumentMatcherTests(object): @istest def reads_paragraph_unordered_list(self): assert_equal( - document_matchers.paragraph(numbering=documents.numbering_level(2, is_ordered=False)), + document_matchers.paragraph(numbering=documents.numbering_level(1, is_ordered=False)), read_document_matcher("p:unordered-list(2)") ) |
