Using Inkscape Shell from perl

Inkscape has a shell mode called this way.

inkscape --shell 

where you can execute commands as follows:

 some_svg_file.svg -e some_png_output.png -y 1.0 -b #ffffff -D -d 150 

which will generate a PNG file, or like this:

 /home/simone/some_text.svg -S 

which gives you the bounding box of all the elements in the file in the returned message, such as

  svg2,0.72,-12.834,122.67281,12.942 layer1,0.72,-12.834,122.67281,12.942 text2985,0.72,-12.834,122.67281,12.942 tspan2987,0.72,-12.834,122.67281,12.942 

The advantage of this is that you can perform operations with SVG files without having to restart Inkscape every time.

I would like to do something like this:

 sub do_inkscape { my ($file, $commands) = @_; # capture output return $output } 

Everything works fine if I use open2 and formatting like this:

 use IPC::Open2; $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'inkscape --shell'); $\ = "\n"; $/ = ">"; my $out; open my $fh, '>', \$out; if (!defined($kidpid = fork())) { die "cannot fork: $!"; } elsif ($kidpid == 0) { while (<>) { print CHLD_IN $_; } } else { while (<CHLD_OUT>) { chop; s/\s*$//gmi; print "\"$_\""; } waitpid($kidpid, 0); } 

but I can't figure out how to enter just one line, and capture only that output without having to restart Inkscape every time.

thanks

Simone

+2
source share
1 answer

You do not need to use fork, open2 handles this on its own. What you need to do is find a way to detect when inkscape waiting for input.

Here is a very simple example of how you could achieve this:

 #! /usr/bin/perl use strict; use warnings; use IPC::Open2; sub read_until_prompt($) { my ($fh) = (@_); my $done = 0; while (!$done) { my $in; read($fh, $in, 1); if ($in eq '>') { $done = 1; } else { print $in; } } } my ($is_in, $is_out); my $pid = open2($is_out, $is_in, 'inkscape --shell'); read_until_prompt($is_out); print "ready\n"; print $is_in "test.svg -S\n"; read_until_prompt($is_out); print $is_in "quit\n"; waitpid $pid, 0; print "done!\n"; 

read_until_prompt reads the output from inkscape until it finds the > character, and suppose that when it sees it, inkscape ready.

Note. It's too simple, you probably need more logic to make it work more reliably if > can appear outside the hint in the output you expect. Also, no error was found in the above script error. This is bad.

+2
source

All Articles