Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add basic support for adding SVG pictures to docx files #1343#1386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
takis wants to merge3 commits intopython-openxml:master
base:master
Choose a base branch
Loading
fromtakis:master

Conversation

takis
Copy link

michaelarfreed, marcuoli, Paul-Rutten-MPS, Quitiweb, and j9d reacted with heart emoji
takis added3 commitsMay 2, 2024 13:15
As SVG files can start with the XML declaration, interpretall XML files as SVG for now.
* encoding header is no longer needed* from __future__ imports no longer needed
@marcuoli
Copy link

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.

@takis
Copy link
Author

Hi@marcuoli,

No, unfortunately not.

I do try to keep my fork in sync with the main repository.

alexisig reacted with thumbs up emoji

@pank
Copy link

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 areinpt rather than pixels.

Example:

importdocxfromdocx.sharedimportInchesimportnumpyasnpimportmatplotlib.pyplotaspltfromioimportBytesIOfromtempfileimportmktempx=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)forsinfig.get_size_inches())p=mktemp(suffix=".svg")fig.savefig(p)# doesn't workdoc=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?
For matplotlib at least, I think dpi is fixed at 72 (e.g.here)

An example of an mpl svg is attached.
test

@pank
Copy link

With this patch I can insert mpl figures. It's written rather verbose, as I don't really know the style ofpython-docx.
@takis would you consider adding this patch or something similar?

From 458df2e57c57be410e6d2486ae67e44cebbd177e Mon Sep 17 00:00:00 2001From: Rasmus <git@pank.eu>Date: Fri, 18 Oct 2024 10:02:49 +0200Subject: [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.pyindex 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```

Copy link

@lsaintlsaint left a comment
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This PR broke a unitest which need to addxmlns: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" 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 myprivate fork

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@lsaintlsaintlsaint left review comments

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

4 participants
@takis@marcuoli@pank@lsaint

[8]ページ先頭

©2009-2025 Movatter.jp