diff --git a/conservancy_beancount/reports/core.py b/conservancy_beancount/reports/core.py index 7c4f666cb9bdccf092e797a59dbf8e69d3965a7a..c1e1a31bda0adfa37469cde75a22a77d203dd503 100644 --- a/conservancy_beancount/reports/core.py +++ b/conservancy_beancount/reports/core.py @@ -16,6 +16,7 @@ import abc import collections +import copy import datetime import itertools import operator @@ -558,14 +559,24 @@ class BaseODS(BaseSpreadsheet[RT, ST], metaclass=abc.ABCMeta): # methods to manipulate document settings or styles. def copy_element(self, elem: odf.element.Element) -> odf.element.Element: - qattrs = dict(self.iter_qattributes(elem)) - retval = odf.element.Element(qname=elem.qname, qattributes=qattrs) + retval = odf.element.Element( + qname=elem.qname, + qattributes=copy.copy(elem.attributes), + ) try: orig_name = retval.getAttribute('name') except ValueError: orig_name = None if orig_name is not None: retval.setAttribute('name', f'{orig_name}{next(self._name_counter)}') + for child in elem.childNodes: + # Order is important: need to check the deepest subclasses first. + if isinstance(child, odf.element.CDATASection): + retval.addCDATA(child.data) + elif isinstance(child, odf.element.Text): + retval.addText(child.data) + else: + retval.addElement(self.copy_element(child)) return retval def ensure_child(self, diff --git a/tests/test_reports_spreadsheet.py b/tests/test_reports_spreadsheet.py index b14ec45c522452b4873e2bbebcefc2390dd343e8..34dee426838c45c9d6f570e14995780349e9188b 100644 --- a/tests/test_reports_spreadsheet.py +++ b/tests/test_reports_spreadsheet.py @@ -623,3 +623,21 @@ def test_ods_writer_string_cell(ods_writer, cell_source, style_name): assert cell.getAttribute('valuetype') == 'string' assert cell.getAttribute('stylename') == style_name assert get_text(cell) == str(cell_source) + +def test_ods_writer_copy_element(ods_writer): + child1 = odf.text.P() + child1.addElement(odf.text.A(href='linkhref', text='linktext')) + child2 = odf.text.P(text='para2') + cell = odf.table.TableCell(stylename='cellsty') + cell.addElement(child1) + cell.addElement(child2) + actual = ods_writer.copy_element(cell) + assert actual is not cell + assert actual.getAttribute('stylename') == 'cellsty' + actual1, actual2 = actual.childNodes + assert actual1 is not child1 + assert actual2 is not child2 + actual_a, = actual1.childNodes + assert actual_a.getAttribute('href') == 'linkhref' + assert actual_a.text == 'linktext' + assert actual2.text == 'para2'