diff options
| author | Michael Williamson <mike@zwobble.org> | 2013-12-14 16:16:51 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2013-12-14 16:16:51 +0000 |
| commit | 94638afbc228c9005e302ab6bc3d16c4e3e32b1d (patch) | |
| tree | bbde2adf4a67f177711e7ddef2f9704473dd88c3 | |
| parent | 47c7a524e001bd0d9aef872b4a12c0b8efd0d6ff (diff) | |
Add conversion of paragraphs using styles
| -rw-r--r-- | mammoth/__init__.py | 2 | ||||
| -rw-r--r-- | mammoth/conversion.py | 68 | ||||
| -rw-r--r-- | mammoth/document_matchers.py | 1 | ||||
| -rw-r--r-- | tests/conversion_tests.py | 37 |
4 files changed, 82 insertions, 26 deletions
diff --git a/mammoth/__init__.py b/mammoth/__init__.py index df032b2..1fca3d6 100644 --- a/mammoth/__init__.py +++ b/mammoth/__init__.py @@ -4,5 +4,5 @@ from . import docx, conversion def convert_to_html(fileobj): document = docx.read(fileobj).value - html = conversion.convert_document_element_to_html(document) + html = conversion.convert_document_element_to_html(document).value return Result(html, []) diff --git a/mammoth/conversion.py b/mammoth/conversion.py index 0d6dd6d..4a4cf99 100644 --- a/mammoth/conversion.py +++ b/mammoth/conversion.py @@ -1,41 +1,59 @@ -from .results import Result -from . import documents +from . import documents, results, html_paths +from .html_generation import HtmlGenerator, satisfy_html_path -def convert_document_element_to_html(element): - return _converters[type(element)](element) - +def convert_document_element_to_html(element, styles=None): + if styles is None: + styles = [] + html_generator = HtmlGenerator() + converter = DocumentConverter(styles) + converter.convert_element_to_html(element, html_generator) + html_generator.end_all() + return results.success(html_generator.html_string()) -_converters = {} +class DocumentConverter(object): + def __init__(self, styles): + self._styles = styles + self._converters = { + documents.Document: self._convert_document, + documents.Paragraph: self._convert_paragraph, + documents.Run: self._convert_run, + documents.Text: self._convert_text, + } -def _converter(element_type): - def add(func): - _converters[element_type] = func - - return add + def convert_element_to_html(self, element, html_generator): + self._converters[type(element)](element, html_generator) -@_converter(documents.Document) -def convert_document(document): - return _convert_elements_to_html(document.children) + def _convert_document(self, document, html_generator): + self._convert_elements_to_html(document.children, html_generator) -@_converter(documents.Paragraph) -def convert_paragraph(paragraph): - return "<p>{0}</p>".format(_convert_elements_to_html(paragraph.children)) + def _convert_paragraph(self, paragraph, html_generator): + html_path = self._find_html_path_for_paragraph(paragraph) + satisfy_html_path(html_generator, html_path) + self._convert_elements_to_html(paragraph.children, html_generator) -@_converter(documents.Run) -def convert_run(run): - return _convert_elements_to_html(run.children) + def _convert_run(self, run, html_generator): + self._convert_elements_to_html(run.children, html_generator) -@_converter(documents.Text) -def convert_text(text): - return text.value + def _convert_text(self, text, html_generator): + html_generator.text(text.value) -def _convert_elements_to_html(elements): - return "".join(map(convert_document_element_to_html, elements)) + def _convert_elements_to_html(self, elements, html_generator): + for element in elements: + self.convert_element_to_html(element, html_generator) + + + def _find_html_path_for_paragraph(self, paragraph): + for style in self._styles: + document_matcher = style.document_matcher + if document_matcher.element_type == "paragraph" and document_matcher.style_name == paragraph.style_name: + return style.html_path + + return html_paths.path([html_paths.element("p")]) diff --git a/mammoth/document_matchers.py b/mammoth/document_matchers.py index 5cfe92d..e7cd12c 100644 --- a/mammoth/document_matchers.py +++ b/mammoth/document_matchers.py @@ -6,6 +6,7 @@ def paragraph(style_name=None, numbering=None): ParagraphMatcher = collections.namedtuple("ParagraphMatcher", ["style_name", "numbering"]) +ParagraphMatcher.element_type = "paragraph" def run(style_name=None): diff --git a/tests/conversion_tests.py b/tests/conversion_tests.py new file mode 100644 index 0000000..ab90eb0 --- /dev/null +++ b/tests/conversion_tests.py @@ -0,0 +1,37 @@ +from nose.tools import istest, assert_equal + +from mammoth import documents, style_reader +from mammoth.conversion import convert_document_element_to_html + + +@istest +def plain_paragraph_is_converted_to_plain_paragraph(): + result = convert_document_element_to_html( + documents.paragraph(children=[_run_with_text("Hello")]) + ) + assert_equal('<p>Hello</p>', result.value) + + +@istest +def empty_paragraphs_are_ignored(): + result = convert_document_element_to_html( + documents.paragraph(children=[_run_with_text("")]) + ) + assert_equal('', result.value) + + +@istest +def paragraphs_are_converted_by_satisfying_matching_paths(): + result = convert_document_element_to_html( + documents.paragraph(style_name="TipsParagraph", children=[ + _run_with_text("Tip") + ]), + styles=[ + style_reader.read_style("p.TipsParagraph => p.tip") + ] + ) + assert_equal('<p class="tip">Tip</p>', result.value) + + +def _run_with_text(text): + return documents.run(children=[documents.text(text)]) |
