#perl #svg #automation #command-line-interface #inkscape
#perl #svg #автоматизация #интерфейс командной строки #inkscape
Вопрос:
Inkscape имеет режим оболочки, вызываемый следующим образом
inkscape --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 каждый раз.
Спасибо
Симона
Ответ №1:
Вам не нужно раскошеливаться, 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 "readyn";
print $is_in "test.svg -Sn";
read_until_prompt($is_out);
print $is_in "quitn";
waitpid $pid, 0;
print "done!n";
read_until_prompt
Считывает данные из inkscape
выходных данных s до тех пор, пока не найдет >
символ, и предполагает, что, когда он его увидит, inkscape
он готов.
Примечание: это слишком просто, вам, вероятно, потребуется больше логики, чтобы заставить его работать более надежно, если a >
может появиться вне приглашения в ожидаемом вами выводе. Кроме того, в приведенном выше скрипте вообще нет проверки ошибок, что плохо.