diff --git a/Pipfile b/Pipfile index 45e04ae..f8acf69 100644 --- a/Pipfile +++ b/Pipfile @@ -9,4 +9,4 @@ name = "pypi" docxtpl = {editable = true, path = "."} [requires] -python_version = "3.9" +python_version = "3" diff --git a/Pipfile.lock b/Pipfile.lock index 47c708b..df4d11e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "386706742fa1989e0f0bd8fd5cfca85a2b70f29277202755af3e02ca7eb456c8" + "sha256": "5eaa2dbead309d30cb958a343252bd1390ad6afa2c8757f3a42f47d0789c06e5" }, "pipfile-spec": 6, "requires": { - "python_version": "3.9" + "python_version": "3" }, "sources": [ { @@ -19,9 +19,9 @@ "develop": { "docxcompose": { "hashes": [ - "sha256:9b99f878469de72482e68a60521591f59a469e747ac7c46bb0ae6d682671d3e6" + "sha256:0dbf458eae260fee87f306b00f3797ecd058cf9d0aeb6e68a7057727f32bf452" ], - "version": "==1.3.2" + "version": "==1.3.3" }, "docxtpl": { "editable": true, @@ -56,6 +56,7 @@ "sha256:542d454665a3e277f76954418124d67516c5f88e51a900365ed54a9806122b83", "sha256:5a0a14e264069c03e46f926be0d8919f4105c1623d620e7ec0e612a2e9bf1c04", "sha256:5c8c163396cc0df3fd151b927e74f6e4acd67160d6c33304e805b84293351d16", + "sha256:64812391546a18896adaa86c77c59a4998f33c24788cadc35789e55b727a37f4", "sha256:66e575c62792c3f9ca47cb8b6fab9e35bab91360c783d1606f758761810c9791", "sha256:6f12e1427285008fd32a6025e38e977d44d6382cf28e7201ed10d6c1698d2a9a", "sha256:74f7d8d439b18fa4c385f3f5dfd11144bb87c1da034a466c5b5577d23a1d9b51", @@ -70,6 +71,7 @@ "sha256:b007cbb845b28db4fb8b6a5cdcbf65bacb16a8bd328b53cbc0698688a68e1caa", "sha256:bc4313cbeb0e7a416a488d72f9680fffffc645f8a838bd2193809881c67dd106", "sha256:bccbfc27563652de7dc9bdc595cb25e90b59c5f8e23e806ed0fd623755b6565d", + "sha256:c1a40c06fd5ba37ad39caa0b3144eb3772e813b5fb5b084198a985431c2f1e8d", "sha256:c47ff7e0a36d4efac9fd692cfa33fbd0636674c102e9e8d9b26e1b93a94e7617", "sha256:c4f05c5a7c49d2fb70223d0d5bcfbe474cf928310ac9fa6a7c6dddc831d0b1d4", "sha256:cdaf11d2bd275bf391b5308f86731e5194a21af45fbaaaf1d9e8147b9160ea92", @@ -94,30 +96,50 @@ "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b", "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567", "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff", + "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724", "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74", + "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646", "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35", + "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6", + "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6", + "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad", "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26", + "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38", + "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac", "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7", + "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6", "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75", "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f", "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135", "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8", + "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a", "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a", + "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9", + "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864", "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914", "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18", "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8", "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2", "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d", + "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b", "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b", "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f", "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb", "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833", + "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28", "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415", "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902", + "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d", "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9", "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d", + "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145", "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066", + "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c", + "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1", "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f", + "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53", + "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134", + "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85", "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5", "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94", "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509", @@ -138,7 +160,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" } } diff --git a/docxtpl/__init__.py b/docxtpl/__init__.py index 4206160..c202d36 100644 --- a/docxtpl/__init__.py +++ b/docxtpl/__init__.py @@ -4,7 +4,7 @@ Created : 2015-03-12 @author: Eric Lapouyade """ -__version__ = '0.12.0.dev0' +__version__ = '0.12.0.dev1' # flake8: noqa from .inline_image import InlineImage @@ -12,3 +12,4 @@ from .listing import Listing from .richtext import RichText, R from .subdoc import Subdoc from .template import DocxTemplate +import docxtpl.docx_patch \ No newline at end of file diff --git a/docxtpl/docx_patch.py b/docxtpl/docx_patch.py new file mode 100644 index 0000000..092a885 --- /dev/null +++ b/docxtpl/docx_patch.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +""" +Created : 2021-08-14 + +@author: Eric Lapouyade +""" + + +from docx.parts.story import BaseStoryPart + + +class DocxTplBaseStoryPart: + next_id_cptr = 0 + + @property + def docx_next_id(self): + id_str_lst = self._element.xpath('//@id') + used_ids = [int(id_str) for id_str in id_str_lst if id_str.isdigit()] + if not used_ids: + DocxTplBaseStoryPart.next_id_cptr += 1 # global counter + return DocxTplBaseStoryPart.next_id_cptr + return max(used_ids) + 1 + + +# Patch python_docx next_id() to have no collision on default value +BaseStoryPart.next_id = DocxTplBaseStoryPart.docx_next_id diff --git a/docxtpl/subdoc.py b/docxtpl/subdoc.py index 4f5aaa1..ecc6fc4 100644 --- a/docxtpl/subdoc.py +++ b/docxtpl/subdoc.py @@ -34,7 +34,7 @@ class SubdocComposer(Composer): for element in doc.element.body: if isinstance(element, CT_SectPr): continue - element = deepcopy(element) + # element = deepcopy(element) self.add_referenced_parts(doc.part, self.doc.part, element) self.add_styles(doc, element) self.add_numberings(doc, element) @@ -74,19 +74,19 @@ class Subdoc(object): self.docx = tpl.get_docx() self.subdocx = Document(docpath) if docpath: - compose = SubdocComposer(tpl) + compose = SubdocComposer(self.docx) compose.attach_parts(self.subdocx) else: self.subdocx._part = self.docx._part def __getattr__(self, name): - return super().getattr(self.subdocx, 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) + 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)) + self.subdocx.element.body, encoding='unicode', pretty_print=False)) return xml def __unicode__(self): diff --git a/tests/inline_image.py b/tests/inline_image.py index 77980fb..5134d64 100644 --- a/tests/inline_image.py +++ b/tests/inline_image.py @@ -44,4 +44,4 @@ context = { # testing that it works also when autoescape has been forced to True jinja_env = jinja2.Environment(autoescape=True) tpl.render(context, jinja_env) -tpl.save('templates/merge_docx_subdoc.docx') +tpl.save('output/inline_image.docx') diff --git a/tests/templates/merge_docx_master_tpl.docx b/tests/templates/merge_docx_master_tpl.docx index 5e66ae5..a114fff 100644 Binary files a/tests/templates/merge_docx_master_tpl.docx and b/tests/templates/merge_docx_master_tpl.docx differ diff --git a/tests/templates/merge_docx_subdoc.docx b/tests/templates/merge_docx_subdoc.docx index 9ebc51b..bff4784 100644 Binary files a/tests/templates/merge_docx_subdoc.docx and b/tests/templates/merge_docx_subdoc.docx differ