diff --git a/docxtpl/subdoc.py b/docxtpl/subdoc.py index e8da093..331e85d 100644 --- a/docxtpl/subdoc.py +++ b/docxtpl/subdoc.py @@ -5,6 +5,8 @@ @author: Eric Lapouyade """ +from copy import deepcopy + from docx import Document from docx.oxml import CT_SectPr from docx.opc.constants import RELATIONSHIP_TYPE as RT @@ -13,7 +15,6 @@ from docxcompose.composer import Composer from docxcompose.utils import NS from lxml import etree -import re class SubdocComposer(Composer): @@ -82,16 +83,19 @@ def __getattr__(self, name): return getattr(self.subdocx, name) def _get_xml(self): - if self.subdocx.element.body.sectPr is not None: - self.subdocx.element.body.remove(self.subdocx.element.body.sectPr) - xml = re.sub( - r"]*>", - "", - etree.tostring( - self.subdocx.element.body, encoding="unicode", pretty_print=False - ), - ) - return xml + body = self.subdocx.element.body + if body.sectPr is not None: + body.remove(body.sectPr) + if len(body) == 0: + return "" + + destination_body = self.docx.element.body + wrapper = etree.Element(destination_body.tag, nsmap=destination_body.nsmap) + for element in body: + wrapper.append(deepcopy(element)) + + xml = etree.tostring(wrapper, encoding="unicode", pretty_print=False) + return xml.partition(">")[2].rpartition("%s' % (W_NS, fragment)).encode("utf-8") +) +assert len(fragment_body) == 10000 +assert all(element.tag == "{%s}p" % W_NS for element in fragment_body) diff --git a/tests/runtests.py b/tests/runtests.py index b0a3bf3..f6bdc2a 100644 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -1,17 +1,48 @@ +from hashlib import sha256 +import json +from pathlib import Path import subprocess -import glob -import os +import sys -tests = sorted(glob.glob("[A-Za-z]*.py")) -excludes = ["runtests.py"] -output_dir = os.path.join(os.path.dirname(__file__), "output") -if not os.path.exists(output_dir): - os.mkdir(output_dir) +def file_sha256(path): + digest = sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + +tests_dir = Path(__file__).resolve().parent +repo_root = tests_dir.parent +launcher_path = Path(__file__).resolve() +tests = sorted( + path + for path in tests_dir.glob("[A-Za-z]*.py") + if path.name != launcher_path.name +) + +(tests_dir / "output").mkdir(exist_ok=True) +records = [] for test in tests: - if test not in excludes: - print("%s ..." % test) - subprocess.call(["python", "./%s" % test]) + relative_path = test.relative_to(repo_root).as_posix() + test_sha256 = file_sha256(test) + print("RUN %s %s" % (relative_path, test_sha256), flush=True) + subprocess.run( + [sys.executable, str(test)], + cwd=str(tests_dir), + check=True, + ) + print("PASS %s %s" % (relative_path, test_sha256), flush=True) + records.append({"path": relative_path, "sha256": test_sha256}) -print("Done.") +completion = { + "status": "passed", + "count": len(records), + "launcher": { + "path": launcher_path.relative_to(repo_root).as_posix(), + "sha256": file_sha256(launcher_path), + }, + "tests": records, +} +print(json.dumps(completion, sort_keys=True, separators=(",", ":")), flush=True) diff --git a/tests/templates/pandoc_subdoc.docx b/tests/templates/pandoc_subdoc.docx new file mode 100644 index 0000000..0816b38 Binary files /dev/null and b/tests/templates/pandoc_subdoc.docx differ