|
Hello, Is there a target date for this code to be committed to the master ? I really need this implementation. Thanks for the awesome software. |
Sorry, something went wrong.
|
Hi @marcuoli, No, unfortunately not. I do try to keep my fork in sync with the main repository. |
Sorry, something went wrong.
|
I hope this patch will be merged soon. I'm trying to use your patch, but it doesn't appear to work with matplotlib figures since their sizes are in pt rather than pixels. Example: import docx
from docx.shared import Inches
import numpy as np
import matplotlib.pyplot as plt
from io import BytesIO
from tempfile import mktemp
x = np.linspace(-2*np.pi, 2*np.pi, 100)
fig, ax = plt.subplots()
ax.plot(x, np.sin(x), color="C0")
ax.plot(x, np.cos(x), color="C1")
buf = BytesIO()
fig.savefig(buf, format="svg")
w, h = (Inches(s) for s in fig.get_size_inches())
p = mktemp(suffix=".svg")
fig.savefig(p)
# doesn't work
doc = docx.Document()
doc.add_picture(buf, w, h)
Traceback: File c:\Users\rpr\.conda\envs\funandgames\Lib\site-packages\docx\image\svg.py:43, in Svg._dimensions_from_stream(cls, stream)
40 root = ET.fromstring(data)
41 # FIXME: The width could be expressed as '4cm'
42 # See https://www.w3.org/TR/SVG11/struct.html#NewDocument
---> 43 width = int(root.attrib["width"])
44 height = int(root.attrib["height"])
45 return width, height
I think a pt is 1.33x a pixel in svgs. If so, it might be easy to at least handle pt. But maybe it depends on dpi? |
Sorry, something went wrong.
|
With this patch I can insert mpl figures. It's written rather verbose, as I don't really know the style of python-docx. From 458df2e57c57be410e6d2486ae67e44cebbd177e Mon Sep 17 00:00:00 2001
From: Rasmus <git@pank.eu>
Date: Fri, 18 Oct 2024 10:02:49 +0200
Subject: [PATCH] svg: Handle non-pixels units
---
src/docx/image/svg.py | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/src/docx/image/svg.py b/src/docx/image/svg.py
index 0247a77..4be43e1 100644
--- a/src/docx/image/svg.py
+++ b/src/docx/image/svg.py
@@ -33,13 +33,37 @@ class Svg(BaseImageHeader):
"""
return "svg"
+ @classmethod
+ def _dimension_to_px(cls, s):
+ """Convert SVG unit *s* to pixels.
+
+ Based on the `table`_ on absolute length in W3 CSS Values 3.
+
+ .. table: https://www.w3.org/TR/css-values-3/#absolute-lengths
+ """
+ s = str(s)
+ unit = s.lstrip("0123456789.").casefold()
+ snumber = s[:-len(unit)] if len(unit) > 0 else s
+ number = float(snumber)
+ inch = 96
+ cm = inch/2.54
+ units = {"cm": cm,
+ "mm": cm/10,
+ "q": cm/40, # 'Q' in W3 table
+ "in": inch,
+ "pc": inch/6,
+ "pt": inch/72,
+ "px": 1}
+ # Unitless is pixels
+ number_px = number * units.get(unit, 1)
+ return int(number_px)
+
@classmethod
def _dimensions_from_stream(cls, stream):
stream.seek(0)
data = stream.read()
root = ET.fromstring(data)
- # FIXME: The width could be expressed as '4cm'
- # See https://www.w3.org/TR/SVG11/struct.html#NewDocument
- width = int(root.attrib["width"])
- height = int(root.attrib["height"])
+ # The width could be expressed as '4cm'
+ width = cls._dimension_to_px(root.attrib["width"])
+ height = cls._dimension_to_px(root.attrib["height"])
return width, height
--
2.44.0.windows.1
```
|
Sorry, something went wrong.
There was a problem hiding this comment.
This PR broke a unitest which need to add xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main
to
tests/test_files/snippets/inline.txt.
some of svg files without "width" and "height" not supported yet.
eg:
<svg viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Icons_CheckboxCrossed" overflow="hidden"><path d="M37.076 62.948 48.008 52.201 58.939 62.948 63.146 58.67 52.286 47.994 63.146 37.318 58.939 33.04 48.008 43.787 37.076 33.04 32.87 37.318 43.729 47.994 32.87 58.67 37.076 62.948Z"/><path d="M21 21 21 75 75 75 75 21ZM69 69 27 69 27 27 69 27Z"/></svg>
I have fixed them and added some unittests in my private fork
Sorry, something went wrong.
Original svg images used |
Sorry, something went wrong.
|
@sgtyfianalisisfinanciero AI've written an package that hotpatches python-docx to support svgs based on this thread that I use for work until svg support is merged. Would that be interesting for others? |
Sorry, something went wrong.
|
@pank nervermind, the problem was not with the images or the mpl code that generated it. Trying to elaborate a minimal reproducible example I catched the issue My workflow was something like that:
Removing the saving step solves the issue. I'm clueless about why, but it's fine On the other hand I think your hotfix package would be very interesting for a lot of people. While this get merged, everyone who needed that feature could just uv add git+... your fork, which is nicer than hardcoding your patch (which can easily get hard to find in the conversation) into the .venv folder. |
Sorry, something went wrong.
|
How it goes? |
Sorry, something went wrong.
|
@sgtyfianalisisfinanciero sorry about the delay. I wanted to add tests and read through the code, but didn't manage before my going on vacation. I still haven't managed, but have added the hotpatch package here: https://github.com/pank/python-docx-svg I haven't added it to PyPi, but could do so if that would be useful. It can still be installed via pip. |
Sorry, something went wrong.
|
And more news on this? It seems like the patch has addressed the issue, but is still waiting to be merged? |
Sorry, something went wrong.
See issues #351, #651, #659.
This replaces both earlier pull requests: