diff --git a/docxtpl/inline_image.py b/docxtpl/inline_image.py
index f860749..5b164b1 100644
--- a/docxtpl/inline_image.py
+++ b/docxtpl/inline_image.py
@@ -4,7 +4,7 @@
@author: Eric Lapouyade
"""
-from docx.oxml import OxmlElement, parse_xml
+from docx.oxml import OxmlElement
from docx.oxml.ns import qn
@@ -19,11 +19,24 @@ class InlineImage(object):
width = None
height = None
anchor = None
-
- def __init__(self, tpl, image_descriptor, width=None, height=None, anchor=None):
+ title = None
+ descr = None
+
+ def __init__(
+ self,
+ tpl,
+ image_descriptor,
+ width=None,
+ height=None,
+ anchor=None,
+ title=None,
+ descr=None,
+ ):
self.tpl, self.image_descriptor = tpl, image_descriptor
self.width, self.height = width, height
self.anchor = anchor
+ self.title = str(title) if title is not None else None
+ self.descr = str(descr) if descr is not None else None
def _add_hyperlink(self, run, url, part):
# Create a relationship for the hyperlink
@@ -49,19 +62,30 @@ def _add_hyperlink(self, run, url, part):
return run
+ def _set_doc_properties(self, run):
+ docPr = run.xpath(".//wp:docPr")[0]
+ cNvPr = run.xpath(".//pic:cNvPr")[0]
+
+ for elt in (docPr, cNvPr):
+ if self.title is not None:
+ elt.set("title", self.title)
+ if self.descr is not None:
+ elt.set("descr", self.descr)
+
def _insert_image(self):
pic = self.tpl.current_rendering_part.new_pic_inline(
self.image_descriptor,
self.width,
self.height,
- ).xml
+ )
+ if self.title is not None or self.descr is not None:
+ self._set_doc_properties(pic)
if self.anchor:
- run = parse_xml(pic)
- if run.xpath(".//a:blip"):
- hyperlink = self._add_hyperlink(
- run, self.anchor, self.tpl.current_rendering_part
+ if pic.xpath(".//a:blip"):
+ pic = self._add_hyperlink(
+ pic, self.anchor, self.tpl.current_rendering_part
)
- pic = hyperlink.xml
+ pic = pic.xml
return (
"%s"
diff --git a/tests/inline_image.py b/tests/inline_image.py
index 48ed670..aa2b046 100644
--- a/tests/inline_image.py
+++ b/tests/inline_image.py
@@ -5,6 +5,9 @@
@author: Eric Lapouyade
"""
+import zipfile
+from xml.etree import ElementTree
+
from docxtpl import DocxTemplate, InlineImage
# for height and width you have to use millimeters (Mm), inches or points(Pt) class :
@@ -14,7 +17,13 @@
tpl = DocxTemplate("templates/inline_image_tpl.docx")
context = {
- "myimage": InlineImage(tpl, "templates/python_logo.png", width=Mm(20)),
+ "myimage": InlineImage(
+ tpl,
+ "templates/python_logo.png",
+ width=Mm(20),
+ title="python-logo-title",
+ descr="python-logo-description",
+ ),
"myimageratio": InlineImage(
tpl, "templates/python_jpeg.jpg", width=Mm(30), height=Mm(60)
),
@@ -49,3 +58,26 @@
jinja_env = jinja2.Environment(autoescape=True)
tpl.render(context, jinja_env)
tpl.save("output/inline_image.docx")
+
+
+with zipfile.ZipFile("output/inline_image.docx") as docx_file:
+ document = ElementTree.fromstring(docx_file.read("word/document.xml"))
+
+namespaces = {
+ "pic": "http://schemas.openxmlformats.org/drawingml/2006/picture",
+ "wp": "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
+}
+
+picture = document.find(".//pic:cNvPr[@name='python_logo.png']", namespaces)
+if picture is None:
+ raise ValueError("Missing python_logo.png image metadata")
+if picture.get("title") != "python-logo-title":
+ raise ValueError("Missing picture title metadata")
+if picture.get("descr") != "python-logo-description":
+ raise ValueError("Missing picture description metadata")
+
+doc_pr = document.find(".//wp:docPr[@title='python-logo-title']", namespaces)
+if doc_pr is None:
+ raise ValueError("Missing wp:docPr title metadata")
+if doc_pr.get("descr") != "python-logo-description":
+ raise ValueError("Missing wp:docPr description metadata")