diff --git a/CHANGES.rst b/CHANGES.rst index a0706c7..8e69e64 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,8 +1,17 @@ -0.12.0 (2021-07-31) +0.12.0 (2021-08-15) ------------------- - Code has be split into many files for better readability - Use docxcomposer to attach parts when a docx file is given to create a subdoc Images, styles etc... must now be taken in account in subdocs +- Some internal XML IDs are now renumbered to avoid collision, thus images are not randomly disapearing anymore. +- fix #372 +- fix #374 +- fix #375 +- fix #369 +- fix #368 +- fix #347 +- fix #181 +- fix #61 0.11.5 (2021-05-09) ------------------- diff --git a/docs/index.rst b/docs/index.rst index e8bea61..d41afcd 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -229,7 +229,16 @@ Sub-documents ------------- A template variable can contain a complex and built from scratch with python-docx word document. -To do so, get first a sub-document object from template object and use it as a python-docx document object, see example in `tests/subdoc.py`. +To do so, get first a sub-document object from template object and use it as a python-docx document object, +see example in `tests/subdoc.py`. + +Since docxtpl V0.12.0, it is now possible to merge an exsting .docx as a subdoc, just specify its path when +calling method `new_subdoc()` :: + + tpl = DocxTemplate('templates/merge_docx_master_tpl.docx') + sd = tpl.new_subdoc('templates/merge_docx_subdoc.docx') + +see `tests/merge_docx.py` for full code Escaping, newline, new paragraph, Listing ----------------------------------------- diff --git a/docxtpl/__init__.py b/docxtpl/__init__.py index c202d36..280de22 100644 --- a/docxtpl/__init__.py +++ b/docxtpl/__init__.py @@ -4,7 +4,7 @@ Created : 2015-03-12 @author: Eric Lapouyade """ -__version__ = '0.12.0.dev1' +__version__ = '0.12.0' # flake8: noqa from .inline_image import InlineImage @@ -12,4 +12,3 @@ 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 deleted file mode 100644 index 092a885..0000000 --- a/docxtpl/docx_patch.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- 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 ecc6fc4..84a1777 100644 --- a/docxtpl/subdoc.py +++ b/docxtpl/subdoc.py @@ -4,7 +4,6 @@ Created : 2021-07-30 @author: Eric Lapouyade """ -from copy import deepcopy from docx import Document from docx.oxml import CT_SectPr @@ -34,7 +33,6 @@ class SubdocComposer(Composer): for element in doc.element.body: if isinstance(element, CT_SectPr): continue - # element = deepcopy(element) self.add_referenced_parts(doc.part, self.doc.part, element) self.add_styles(doc, element) self.add_numberings(doc, element) diff --git a/docxtpl/template.py b/docxtpl/template.py index 693fd2b..8be23ea 100644 --- a/docxtpl/template.py +++ b/docxtpl/template.py @@ -5,7 +5,6 @@ Created : 2015-03-12 @author: Eric Lapouyade """ - from .subdoc import Subdoc import functools import io @@ -43,6 +42,7 @@ class DocxTemplate(object): self.pics_to_replace = {} self.pic_map = {} self.current_rendering_part = None + self.docx_ids_index = 1000 def __getattr__(self, name): return getattr(self.docx, name) @@ -319,6 +319,10 @@ class DocxTemplate(object): # fix tables if needed tree = self.fix_tables(xml_src) + # fix docPr ID's + self.fix_docpr_ids(tree) + + # Replace body xml tree self.map_tree(tree) # Headers @@ -421,6 +425,12 @@ class DocxTemplate(object): return tree + def fix_docpr_ids(self, tree): + # some Ids may have some collisions : so renumbering all of them : + for elt in tree.xpath('//wp:docPr', namespaces=docx.oxml.ns.nsmap): + self.docx_ids_index += 1 + elt.attrib['id'] = str(self.docx_ids_index) + def new_subdoc(self, docpath=None): return Subdoc(self, docpath) diff --git a/tests/header_footer_inline_image.py b/tests/header_footer_inline_image.py index b2303d0..81fa0eb 100644 --- a/tests/header_footer_inline_image.py +++ b/tests/header_footer_inline_image.py @@ -13,7 +13,12 @@ from docx.shared import Mm tpl = DocxTemplate('templates/header_footer_inline_image_tpl.docx') context = { - 'inline_image': InlineImage(tpl, 'templates/django.png', height=Mm(10)) + 'inline_image': InlineImage(tpl, 'templates/django.png', height=Mm(10)), + 'images': [ + InlineImage(tpl, 'templates/python.png', height=Mm(10)), + InlineImage(tpl, 'templates/python.png', height=Mm(10)), + InlineImage(tpl, 'templates/python.png', height=Mm(10)) + ] } tpl.render(context) tpl.save('output/header_footer_inline_image.docx') diff --git a/tests/templates/header_footer_inline_image_tpl.docx b/tests/templates/header_footer_inline_image_tpl.docx index 87d0cb4..a4b48d5 100644 Binary files a/tests/templates/header_footer_inline_image_tpl.docx and b/tests/templates/header_footer_inline_image_tpl.docx differ diff --git a/tests/templates/merge_docx_master_tpl.docx b/tests/templates/merge_docx_master_tpl.docx index a114fff..9ce2e3a 100644 Binary files a/tests/templates/merge_docx_master_tpl.docx and b/tests/templates/merge_docx_master_tpl.docx differ