diff --git a/pydocx/export/base.py b/pydocx/export/base.py index ecfc487c..349565e6 100644 --- a/pydocx/export/base.py +++ b/pydocx/export/base.py @@ -110,16 +110,24 @@ def export(self): # document (e.g. fields) # In the first pass, discard any generated results self.first_pass = True - for result in self.export_node(document): - pass + self._first_pass_export() - self._convert_complex_fields_into_simple_fields() + self._post_first_pass_processing() # actually render the results self.first_pass = False for result in self.export_node(document): yield result + def _first_pass_export(self): + document = self.main_document_part.document + if document: + for result in self.export_node(document): + pass + + def _post_first_pass_processing(self): + self._convert_complex_fields_into_simple_fields() + def _convert_complex_fields_into_simple_fields(self): if not self.complex_field_runs: return @@ -132,6 +140,13 @@ def _convert_complex_fields_into_simple_fields(self): runs_to_remove_by_field = {} runs_to_remove = set() + # All of the complex field runs need to be wrapped in simple fields, + # and then the runs need to be removed from their original container + # The new simple fields that contain the runs are inserted into the + # structure and the parent links are updated + + # First create all the necessary simple fields and group the runs into + # their simple fields. for run in self.complex_field_runs: for child in run.children: if field is not None and previous_run is not None: @@ -166,6 +181,8 @@ def _convert_complex_fields_into_simple_fields(self): runs_to_remove.add(run) previous_run = run + # Next, remove all of the runs from the run's current parent, and + # inject the field in their place. for field in fields: runs_to_remove = runs_to_remove_by_field.get(field, set()) if not field.children: @@ -180,6 +197,12 @@ def _convert_complex_fields_into_simple_fields(self): previous_parent_new_children.append(child) first_run.parent.children = previous_parent_new_children + # If we don't do this, the field's parent will be None. That will + # break the hierarchy. + field.parent = first_run.parent + + # Update the run parent links to point to the field, since the + # field is now the run's new parent. for run in field.children: run.parent = field diff --git a/tests/export/html/test_field_code.py b/tests/export/html/test_field_code.py index 273f2fdb..cc7c8c31 100644 --- a/tests/export/html/test_field_code.py +++ b/tests/export/html/test_field_code.py @@ -7,11 +7,58 @@ ) -from pydocx.openxml.packaging import MainDocumentPart +from pydocx.openxml.packaging import MainDocumentPart, StyleDefinitionsPart from pydocx.test import DocumentGeneratorTestCase from pydocx.test.utils import WordprocessingDocumentFactory +class HeadingTestCase(DocumentGeneratorTestCase): + def test_styles_are_ignored(self): + style_xml = ''' + + ''' + + document_xml = ''' +
+
diff --git a/tests/export/html/test_simple_field.py b/tests/export/html/test_simple_field.py index 75125e3b..b1ee947c 100644 --- a/tests/export/html/test_simple_field.py +++ b/tests/export/html/test_simple_field.py @@ -9,13 +9,50 @@ from unittest import TestCase -from pydocx.openxml.packaging import MainDocumentPart +from pydocx.openxml.packaging import MainDocumentPart, StyleDefinitionsPart from pydocx.openxml.wordprocessing.simple_field import SimpleField from pydocx.test import DocumentGeneratorTestCase from pydocx.test.utils import WordprocessingDocumentFactory -class HyperlinkSimpleFieldTestCase(DocumentGeneratorTestCase): +class HeadingTestCase(DocumentGeneratorTestCase): + def test_styles_are_ignored(self): + style_xml = ''' + + ''' + + document_xml = ''' +
+