-
-
Notifications
You must be signed in to change notification settings - Fork 696
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for inline SVG #75
Comments
Yes, I’d say this is a missing feature. I wonder if you could get away with WeasyPrint giving a parsed subtree to CairoSVG, but it gets more tricky when document stylesheets apply to inline SVG elements. In the meantime as a work-around, you could either use |
Hmm, yes, I hadn't thought of document styles... The To be honest, I'd probably be super-happy if WeasyPrint passed the SVG subtree to CairoSVG for rendering, ignoring document styles -- it wouldn't necessarily be conformant, but it'd be a huge step forward in any case. I suspect that inline styles are the norm for SVG images at the moment anyway. |
Would it not be possible to pre-caclulate and flatten the CSS onto element style attributes of the inline SVG? |
@graingert maybe. This only reinforces my opinion that CairoSVG and WeasyPrint should be one and the same code base :) |
Although absolute and fixed positioning would be broken. It does look like CairoSVG and WeasyPrint should be one and the same. |
The data URL approach definitely works and is indeed trivial. In Django the code is: Define a template filter:
Use it in a template:
|
Please add inline SVG support. This will make things easier for people who do not have any Python experience and hence do not want to add just another new technology to their stack. |
@SimonSapin would it be possible to use |
@diethardsteiner There is no disagreement that this feature is desired. It’s mostly a matter of "someone" doing the work. @graingert I don’t see why premailer wouldn’t work, but I don’t see either how it helps at all with inline SVG not being supported by WeasyPrint. Note that "inline" means different things in the context of premailer ( |
This only fixes the issue that using passing a subtree would cause. |
Oh, I see. Yes, I suppose we could extract a subtree, "flatten" sytelsheets into |
@SimonSapin Ok thanks for your feedback |
@SimonSapin where in the code is both the html tree and the cario context available? |
@graingert The cairo context for the document (as opposed to contexts for intermediate surfaces used at various points) is created in the |
@SimonSapin is it possible to just keep hold of the SVG fragments during the layout processing? So we can at least get it working by pretending the SVG is just an embedded image? |
I don’t have an answer to that right now, sorry. (I’m not as involved in WeasyPrint as I used to be, so I won’t be spending a lot of time to work on this or think about how it could be done.) What I remember is that I thought that the CSS rendering and SVG rendering really should share their style system. (The thing that takes stylesheets and a DOM-like tree, matches selectors, runs the cascade, and gives one computed values for every property for every element.) Right now they’re completely separate (and somewhat duplicated) in WeasyPrint and CairoSVG. But last I talked about merging the code bases, @liZe didn’t like the idea :) |
This is the code we are using for our specific use-case to inline the svgs generated by angular-nvd3. (The selector for svgs was trickier due to namespacing, but I'm sure someone could figure it out). The issue is that it doesnt account for styling information, but got us to what we needed. +from base64 import b64encode
+from lxml import etree
+
+ def svg_embed(html):
+ """For the child of nvd3 nodes (svg) munge them into b64encoded data
+ as a workaround for https://github.com/Kozea/WeasyPrint/issues/75"""
+ root = html.root_element
+ svgs = root.findall('.//nvd3')
+ for svg in svgs:
+ child = svg.getchildren()[0]
+ encoded = b64encode(etree.tostring(child)).decode()
+ encoded_data = "data:image/svg+xml;charset=utf-8;base64," + encoded
+ encoded_child = etree.fromstring('<img src="%s"/>' % encoded_data)
+ svg.replace(child, encoded_child)
+ return html
+
- rendered = HTML(string=html, base_url=base_url).render()
+ rendered = svg_embed(HTML(string=html, base_url=base_url)).render() |
@liZe is there any possibility for this? |
Finding If anyone is interested in implementing that, I can give some advice, it's a good way to start hacking WeasyPrint. |
The feature has been added in version 53.0. There are lots of limitations and bugs related to this initial support, but things will improve with time. Please try version 53, and open new issues with the specific problems you may meet! |
At the moment, to use SVG within WeasyPrint, you need to embed it (generally via an tag). It'd be really useful if WeasyPrint could handle inline SVG as well.
In other words, one should be able to do the following:
and get a red square.
In our particular scenario, we're generating HTML for WeasyPrint by performing an XSLT transformation on an XML document -- and in some scenarios, we're hoping to generate SVG graphics (bar charts and the like) dynamically as part of this.
The text was updated successfully, but these errors were encountered: