Using the Inkscape shell from perl

匿名 (未验证) 提交于 2019-12-03 01:01:02

问题:

Inkscape has a shell mode invoked like this

inkscape --shell 

where you can execute commands like this:

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 elements in the file in the return message like this

 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 benefit of this is that you can perform operations on 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 } 

Things work OK if I use open2 and forking 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 find out how to input only one line, and capture only that output without having to restart Inkscape every time.

Thanks

Simone

回答1:

You don't need to fork, open2 handles that by itself. What you need to do is find a way of detecting when inkscape is waiting for input.

Here's a very basic example of how you could achieve that:

#! /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"; 

The read_until_prompt reads from inkscapes output until it finds a > character, and assumes that when it sees one, inkscape is ready.

Note: This is too simple, you will probably need more logic in there to make it work more reliably if a > can appear outside the prompt in the output you're expecting. There is also no error checking at all in the above script, which is bad.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!