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 )