PDF-Collage
view release on metacpan or search on metacpan
script/pdf-collage view on Meta::CPAN
'list|list-selectors|l',
{
getopt => 'output|o=s',
default => '-',
},
'selector|S=s',
'source|s=s@',
],
\@args,
);
# $config: hash reference with configuration
# @args: residual arguments
my $pdfc = get_collage($config);
return list_selectors($pdfc) if $config->{list};
for my $record (collect_records($config, \@args)->@*) {
# get selector for this specific record
my $selector = $config->{selector} // undef;
$selector = render($selector, $record) if defined $selector;
# get template from computed selector and render the PDF
my $template = get_template($pdfc, $selector);
my $pdf = $template->render($record);
# get the output channel and send the PDF content to it
my $output = render($config->{output}, $record);
output_pdf($pdf, $output);
} ## end for my $record (collect_records...)
return 0;
} ## end sub main
sub collect_records ($config, $args) {
my $common = {};
my @records;
for my $input (($config->{data} // [])->@*) {
my $addon = decode_json(slurp_raw($input));
if (ref($addon) eq 'ARRAY') {
push @records, $addon->@*;
}
else {
merge_hash_in_place($common, $addon);
}
} ## end for my $input (($config...))
for my $additional (($args // [])->@*) {
my ($first) = $additional =~ m{(\S)}mxs;
$first //= '';
if ($first eq '{') { # JSON hash
merge_hash_in_place($common, decode_json($additional));
}
elsif ($first eq '[') {
push @records, decode_json($additional)->@*;
}
else {
my ($key, $sep, $val) = split m{(\#?= | ::?)}mxs, $additional, 2;
length($sep // '') > 0
or die "invalid input value definition: no separator\n";
s{\A\s+|\s+\z}{}gmxs for ($key, $val);
$val = decode_base64($val) if length($sep) == 2;
${traverse(\$common, $key)} = $val;
} ## end else [ if ($first eq '{') (})]
} ## end for my $additional (($args...))
@records = ({}) unless @records;
$_ = merge_hash_in_place(dclone($common), $_) for @records;
return \@records;
} ## end sub collect_records
sub get_collage ($config) {
my $sources = $config->{source} // [];
my $n_sources = $sources->@*;
$n_sources > 0 or die "no input source templates\n";
my $is_json = qr{(?mxs:\A \s* [\[\{] )};
my @res; # list of sources as resolvers
for my $source ($sources->@*) {
if ($source =~ $is_json) { # JSON, immediate stuff
die "only one single plain template allowed\n"
if $n_sources > 1;
return collage(definition => $source);
}
if ($source eq '-') {
die "only one single plain template allowed\n"
if $n_sources > 1;
my $stuff = slurp_raw('-');
die "only JSON from standard input\n" if $stuff !~ $is_json;
return collage(definition => $stuff);
}
elsif (-d $source) {
push @res, resolver_from_dir(root => $source, throw => 1);
}
elsif (-r $source) {
my $first_byte = slurp_raw($source, 10);
if ($first_byte =~ $is_json) {
die "only one single plain template allowed\n"
if $n_sources > 1;
return collage(definition => slurp_raw($source));
}
push @res, resolver_from_tar(archive => $source, throw => 1);
} ## end else [ if (-d $source) ]
else {
die "cannot use source '$source'\n";
}
} ## end for my $source ($sources...)
my $resolver =
@res == 1
? $res[0]
: resolver_from_alternatives(alternatives => \@res, throw => 1);
return collage(resolver => $resolver);
} ## end sub get_collage
sub get_options ($specs, $ARGV) {
( run in 0.650 second using v1.01-cache-2.11-cpan-71847e10f99 )