2011-10-08 46 views
2

Inkscape中的Inkscape的外殼援引這樣使用從perl的

inkscape --shell 

在那裏你可以這樣執行命令的shell模式:

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

,這將產生一個PNG文件,或者是這樣的:

/home/simone/some_text.svg -S 

它給你在文件中的所有元素的邊界框在這樣的返回消息中

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 

這樣做的好處是,你可以對SVG文件的操作,而無需重新啓動Inkscape的每一次。

我願做這樣的事情:

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

事情工作確定,如果我使用open2和分叉這樣的:

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); 
} 

,但我不能找出如何只輸入一行,並且只捕獲該輸出,而不必每次都重新啓動Inkscape。

感謝

西蒙娜

回答

2

你不需要到餐桌,open2處理,通過自身。你需要做的是找到一種方法來檢測何時inkscape正在等待輸入。

這裏是你如何能做到這一點很簡單的例子:

#! /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_promptinkscape的輸出讀取直到它找到一個>字符,並假定它認爲當一個人,inkscape已準備就緒。

注:這是太簡單了,你可能會需要更多的邏輯在那裏,使其工作更可靠,如果>可以在你期望的輸出提示外出現。在上面的腳本中也沒有錯誤檢查,這是不好的。