NAME

PDF::Collage - PDF manipulation with scissors and glue

VERSION

This document describes PDF::Collage version 0.001001.

Build Status Perl Version Current CPAN version Kwalitee CPAN Testers CPAN Testers Matrix

SYNOPSIS

use PDF::Collage qw< collage >;

# $input might be... many things
my $collage = collage($input);
my $pdf = $collage->render(\%data);
$pdf->saveas('/path/to/somefile.pdf');

DESCRIPTION

PDF::Collage helps generate an object wrapping either a PDF::Collage::Template or a PDF::Collage::TemplatesCollection (collectively referred as renderable object).

These allow eventually generate PDF::Builder objects, after applying the supported transformations; this allows the generated PDF to be saved (e.g. using the saveas method of the PDF::Builder object).

The Do What I Mean interface "collage" is a one-stop-shop for getting one such object; it accepts a variety of inputs, including TAR bundles (or their directory counterparts).

This distribution supports two basic types of inputs:

Single Template Example

The details about the format for single templates can be found in the documentation for PDF::Collage::Template.

The following is an example of a possible sequence of commands, which take page 5 from a pre-existing PDF file available in the filesystem and put some text over it in selected positions.

[  # a template is basically a sequence of commands in an array

   {  # set defaults for other commands
      op => 'set-defaults',
      font => 'DejaVuSans.ttf',
      'font-size' => 12,
      level => 'INFO',
   },

   {
      op => 'log',
      message => 'starting operations...',
      level   => 'WARN', # override defaults
   },

   {  # add-page by defaults appends to the end
      op => 'add-page',
      from => 'existing-file.pdf', # relative to current dir
      'from-page' => 5,
   },

   {
      op => 'add-text',
      x => 10,
      y => 20,
      text => 'this is verbatim text',
   },

   {  # text-template, rendered via Template::Perlish
      op => 'add-text',
      x => 10,
      y => 40,
      'text-template' => '[% foo %] is [% bar.baz %]',
   },

   {  # text-variable, rendered via Template::Perlish
      op => 'add-text',
      x => 10,
      y => 60,
      'text-variable' => 'bar.baz',
   },

   {
      op => 'add-image',
      path => 'logo.png',   # relative to current dir
      x => 10,
      y => 150,
      width => 50,
      height => 50,
   },

   {
      op => 'log',
      message => 'that's all folks!',
   },
]

The template can refer anything in the filesystem, hence it's up to the user to make sure that the elements are properly available in the specific paths (in the example above, it would be the PDF file existing-file.pdf and the image file logo.png, both assumed to be in the current directory).

Refer to "Templates Collection" for something more cohesive.

Templates Collection

A templates collection is... a collection of templates. It allows carrying around multiple templates at once, as well as artifacts that are deemed important to have around, e.g. because they are referred from the commands. As such, a collection might technically contain a single template.

A collection always needs a Data::Resolver-compatible function to work properly. Details are in the documentation for PDF::Collage::TemplatesCollection, here's an example of the structure of the keys that it should support:

definitions/bar.json
definitions/foo.json
definitions/galook.json
existing-file.pdf
logo.png

Every key ending with .json and starting with definitions/, optionally prefixed with ./ (to cope with possible variations in TAR archives) is considered a file containing the instructions valid for a single template.

The name part (in the example bar, foo, and galook) is the selector, which can be used to retrieve that specific sequence of commands from the collection via "get" in PDF::Collage::TemplatesCollection, getting back a PDF::Collage::Template object.

To retrieve elements from the resolver, e.g. to get a page from the existing-file.pdf or the image logo.png, it's possible to use two functions that are injected in the Template::Perlish namespace, namely as_data and as_file, depending on the needs. The following fragment is a command for taking page 5 from the document accessible through the resolver and the image too:

{
   op => 'add-page',
   'from-page' => 5,
   from => '[%= as_file("existing-file.pdf") %]',
},

{
   op => 'add-image',
   path => '[%= as_file("logo.png") %]',
   x => 10,
   y => 150,
   width => 50,
   height => 50,
},

Note that it's necessary to open the template part with [%= to get the filename back into the data.

By default, the injected function as_file will try to keep the extension, derived from the provided key assuming it's a filename-like string. Everything after the first dot is kept. It's possible to disable this renaming (if and when it occurs) by passing a second parameter with a false value, like in as_file($key, 0).

INTERFACE

This module has a function-oriented interface.

collage

my $pc = collage($input);
my $pc = collage(auto => $input);      # same as above
my $pc = collage(resolver => $data_resolver_instance); # Data::Resolver
my $pc = collage(dir => $path_to_dir);
my $pc = collage(tar => $path_to_tar);
my $pc = collage(definition => \%hash_definition);
my $pc = collage(definition => \@array_definition);
my $pc = collage(definition => $json_hash_or_array);

This is a Do What I Mean catchall function to generate an instance of either PDF::Collage::Template or PDF::Collage::TemplatesCollection.

The function acts as a dispatcher to one of the other functions: "collage_from_definition", "collage_from_dir", "collage_from_resolver", and "collage_from_tar".

collage_from_definition

my $pc = collage_from_definition($definition);

Generate a renderable object from a $definition.

If the definition is a string starting with either { or [, it is considered a valid JSON string and decoded as such, then processed as follows.

If the definition is an array reference, it is turned into an hash reference with a single key commands, associated to the array reference as value.

If the definition is an hash reference, it is considered a suitable input for instantiating an object from PDF::Collage::Template, which is returned back.

collage_from_dir

my $pc = collage_from_dir($path, %other_args);

This function is a thin wrapper around "collage_from_resolver"; it first instantiates a Data::Resolver object of factory type resolver_from_dir, using the provided $path and %other_args, then passes the resulting object to "collage_from_resolver".

collage_from_resolver

my $pc = collage_from_resolver($resolver);

Instantiate a PDF::Collage::TemplatesCollection object passing $resolver as the value associated to key resolver.

collage_from_tar

my $pc = collage_from_tar($path, %other_args);

This function is a thin wrapper around "collage_from_resolver"; it first instantiates a Data::Resolver object of factory type resolver_from_tar, using the provided $path and %other_args, then passes the resulting object to "collage_from_resolver".

BUGS AND LIMITATIONS

Minimum perl version 5.24.

Report bugs through GitHub (patches welcome) at https://github.com/polettix/PDF-Collage.

AUTHOR

Flavio Poletti <flavio@polettix.it>

COPYRIGHT AND LICENSE

Copyright 2023 by Flavio Poletti <flavio@polettix.it>

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.