1

I have the following situation: I have a tool that spits out a number of SVGs¹. I need a script that will convert these into a single Inkscape file such the contents of each original SVG go into a single layer in the final SVG.

I could go to Python and try to parse the SVG structure, but I suspect an easier method exists.

For example: I have 3 SVG files, A.svg, B.svg and C.svg The result should be one SVG file with three layers, first layer containing A.svg, second with B.svg, and so on. Naming and stack of layers is not critical

¹ For some context, the source SVGs are the drawings for the multiple layers of a printed circuit board: I will be adding annotations and using the resulting circuit board in a classroom. The annotations are few but the task has to be repeated for a number of different boards.

1

I just made a 3-layer file to investigate the structure, each layer containing a simple geometric figure.

The result has a header, which ends in

  </metadata>

Then, for each layer, a block (here shown for layer 1):

  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1">
    <CONTENT/>
  </g>

The part of CONTENT would be one of your files, stripped from its header and from its SVG-close-tag.

Ended with the overall SVG-close-tag.

</svg>

Okay, what would be the most comfortable way to use such a script? You have to specify a filename for the final result and the files for the layers. It could be convenient to work with file name patterns in the shell like

layerize.sh result.svg board*.svg

Caution: This is a raw solution which might fail under special conditions and is not sanitized against common errors, like missing or wrong parameters. It might fail with duplicated Group-IDs and so on from different files.

My first approach worked for simple figures, but not for gradients and so on. So I have a new workflow:

  • Open a new, empty SVG file.
  • import all the images you like to distribute over different layers at once. This should include all gradients, filters and definition you need.
  • save this file as "layerstemplate.svg"

Now use this modified script:

#!/bin/bash

result=$1
shift

test -e $result && echo "file exists!" && exit 1

# takes everything, up to the closing "metadata" tag from the template:
header () {
    sed -n '1,/<\/metadata>/p' ./layertemplate.svg
}

count=0
layer () {
    ((count +=1))
    echo -e "   <g
    inkscape:label=\"Layer $count\"
    inkscape:groupmode=\"layer\"
    id=\"layer$count\">"
     sed '1,/<\/metadata>/d;$d' "$1"
     echo -e "  </g>"
}

header > "$result" 
# iterates over all (remaining) parameters
for f 
do
    layer "$f" >> "$result"
done
echo "</svg>" >> "$result"

I did not try it with sources, which use layers themselves and have no idea how I would handle it. So far, I don't plan on improving this further, but feel free to make suggestions, to criticize it and ask questions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.