I'm trying to generate a PDF image from an SVG image using Python. I've tried both CairoSVG and svglib. The problem is that in both cases the generated PDFs do not have any of the embedded CSS styles applied.
Here is a simple SVG file which should render a blue rectangle with a black border:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<style type="text/css"><![CDATA[
rect {
fill: #1f77b4;
stroke: black;
stroke-width: 1;
shape-rendering: crispEdges;
}
]]></style>
</defs>
<rect x="50" y="50" width="100" height="100"></rect>
</svg>
When rendering a PDF of this SVG using CairoSVG, the PDF image is rendered as a black rectangle. Using svglib, there is no stroke or style applied to the rectangle so it is not visible. Is anyone aware of a way to convert an SVG with CSS styles to a PDF image in Python?
(With help from @MonkeyWrench, since he didn't post an answer.)
According to the documentation,
CairoSVG can use lxml to parse the SVG file, and tinycss plus cssselect to apply CSS not included in the style attribute of the tags. If these packages are not available, CSS will only be supported in the style attributes.
To get started, I installed all the dependencies,
$ pip3 install cairosvg lxml tinycss cssselect
Then I created image.svg
with the following contents:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<style type="text/css"><![CDATA[
rect {
fill: #1f77b4;
stroke: black;
stroke-width: 1;
shape-rendering: crispEdges;
}
]]></style>
</defs>
<rect x="50" y="50" width="100" height="100"></rect>
</svg>
Finally, I executed cairosvg
$ cairosvg image.svg -o image.pdf
And sure enough, it was a blue rectangle.
Have you tried using the style attribute instead?
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect x="50" y="20" width="100" height="100"
style="fill:#1f77b4;stroke:black;stroke-width:1;shape-rendering: crispEdges;"
stroke-opacity:0.9"/>
</svg>
It's ultimately the same as you have already, but maybe CairoSVG skips over style elements in your HTML.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With