Search code examples
svginkscape

Inkscape - how to set stroke style from unix command line


I am writing an app which is using svg to plot points on an image. The image is originally coming in as a pdf and I am converting it to a .svg file using Inkscape in unix with the command:

inkscape –l convertedImage.svg baseImage.pdf

Then in my html using the converted image in my svg tag.

<svg>
    <image x=”100” y=”100” width=”500” height=”500”
    xlink:href=”/my/location/convertedImage.svg”></image>
    …
</sig>

My problem is that the image lines are too light after the conversion. If I open the Inkscape GUI, I can select the image and in the 'Stroke Style' tab increase the width by 1px. Doing it this way makes the image look how I would like it too, but I need to be able to do it in a programmatic way because I am running this command over many pdf files every day.

Is there a way I can either:

  1. Include the Stroke Style Width setting in the inkscape unix command?
  2. Somehow set it after the fact in the svg img tag using css?

Solution

  • SVG is an XML format, so you can fix it with an XML transformation like this:

    shell> xsltproc svglinewidth.xsl convertedImage.svg > fixedImage.svg

    where svglinewidth.xsl contains the following:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml"/>
    
        <xsl:param name="stroke-width">1px</xsl:param>
    
        <xsl:template match="*">
            <xsl:copy>
                <xsl:apply-templates select="@*|text()|*"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="@style[contains(., 'stroke-width:')]">
            <xsl:variable name="before" select="substring-before(.,'stroke-width:')"/>
            <xsl:variable name="rest" select="substring-after(.,'stroke-width:')"/>
            <xsl:variable name="after" select="substring-after($rest,';')"/>
            <xsl:attribute name="style">
                <xsl:value-of select="$before"/>
                <xsl:text>stroke-width:</xsl:text>
                <xsl:value-of select="$stroke-width"/>
                <xsl:text>;</xsl:text>
                <xsl:value-of select="$after"/>
            </xsl:attribute>
        </xsl:template>
    
        <xsl:template match="@*|text()">
            <xsl:copy/>
        </xsl:template>
    
    </xsl:stylesheet>
    

    This will replace all occurrences of stroke-width in style attributes with the value stroke-width:1px,

    To specify another width, you can pass a parameter to xsltproc like this:

    shell> xsltproc --stringparam stroke-width 5px svglinewidth.xsl convertedImage.svg > fixedImage.svg

    xsltproc is available for almost any platform. Linuxes have it as package, for Unixes see http://xmlsoft.org/XSLT/xsltproc2.html

    Hope that helps.

    Update: If you don't want to set a fixed stroke-width, but add something to the stroke-width, the following change will do the job:

    1. remove the unit (px) from the xsl:param value, so it reads <xsl:param name="stroke-width">1</xsl:param>
    2. add a new variable just after the existing ones: <xsl:variable name="current" select="substring-before($rest,';')"/>
    3. replace the select attribute of the xsl:value-of tag with $current + $stroke-width, so it looks like: <xsl:value-of select="$current + $stroke-width"/>

    This assumes that there is no unit after stroke-width:in the source SVG. In order to be added, both the old value and the increment must be plain numbers.