summaryrefslogtreecommitdiffstats
path: root/pdftool.pl
diff options
context:
space:
mode:
Diffstat (limited to 'pdftool.pl')
-rwxr-xr-xpdftool.pl145
1 files changed, 71 insertions, 74 deletions
diff --git a/pdftool.pl b/pdftool.pl
index 49c6e5a..2cf8a7f 100755
--- a/pdftool.pl
+++ b/pdftool.pl
@@ -77,7 +77,7 @@ pages),
=over 8
-=item B<-s, --select=>I<pages>
+=item B<-s> I<pages>, B<--select=>I<pages>
Specify the pages which are to be selected.
I<Pages> is a comma separated list of page ranges, each of which
@@ -89,56 +89,56 @@ The prefix character `_' indicates that the page number is relative
to the end of the document, counting backwards. If just this
character with no page number is used, a blank page will be inserted.
-=item B<-w, --width=>I<length>
+=item B<-w> I<length>, B<--width=>I<length>
Specify the width of the output file. If the height is not specified as
-well, it will be ignored. The known units are B<pt>, B<in>, B<cm> and
-B<mm>. The default unit is B<pt>.
+well, it will be ignored. The known units are I<pt>, I<in>, I<cm> and
+I<mm>. The default unit is I<pt>.
-=item B<-h, --height=>I<length>
+=item B<-h> I<length>, B<--height=>I<length>
Specify the height of the output file. If the width is not specified as
-well, it will be ignored. The known units are B<pt>, B<in>, B<cm> and
-B<mm>. The default unit is B<pt>.
+well, it will be ignored. The known units are I<pt>, I<in>, I<cm> and
+I<mm>. The default unit is I<pt>.
-=item B<-p, --paper=>I<paper>
+=item B<-p> I<paper>, B<--paper=>I<paper>
Specify the paper size of the output file, as an alternative to B<-w>
-and B<-h>. Can be set to B<a0>, B<a1>, B<a2>, B<a3>, B<a4>, B<a5>, B<b5>,
-B<letter>, B<legal>, B<ledger>, B<tabloid>, B<statement>, B<executive>,
-B<folio>, B<quarto>, or B<10x14>. The default output paper size is B<a4>.
+and B<-h>. Can be set to I<a0>, I<a1>, I<a2>, I<a3>, I<a4>, I<a5>, I<b5>,
+I<letter>, I<legal>, I<ledger>, I<tabloid>, I<statement>, I<executive>,
+I<folio>, I<quarto>, or I<10x14>. The default output paper size is I<a4>.
-=item B<-W, --Width=>I<length>
+=item B<-W> I<length>, B<--Width=>I<length>
Same as the option B<-w>, but for the input file. This option is ignored if
the crop option (B<-c>) is set.
-=item B<-H, --Height=>I<length>
+=item B<-H> I<length>, B<--Height=>I<length>
Same as the option B<-h>, but for the input file. This option is ignored if
the crop option (B<-c>) is set.
-=item B<-P, --Paper=>I<paper>
+=item B<-P> I<paper>, B<--Paper=>I<paper>
Same as the option B<-p>, but for the input file. By default,
B<PDFTool> will try to guess this value from the header of the file,
and will fail if the information is missing. This option is ignored if the
crop option (B<-c>) is set.
-=item B<-b, --border=>I<length>
+=item B<-b> I<length>, B<--border=>I<length>
-Add a margin around each logical page on a sheet. Possible units are B<pt>,
-B<in>, B<cm> and B<mm>. The default unit is B<pt>. The default border is
-B<1cm> if the crop option (B<-c>) is set, and B<0> otherwise.
+Add a margin around each logical page on a sheet. Possible units are I<pt>,
+I<in>, I<cm> and I<mm>. The default unit is I<pt>. The default border is
+I<1cm> if the crop option (B<-c>) is set, and I<0> otherwise.
-=item B<-m, --margin=>I<length>
+=item B<-m> I<length>, B<--margin=>I<length>
-Add a margin around the whole page. Possible units are B<pt>, B<in>, B<cm>
-and B<mm>. The default unit is B<pt>. The default margin is B<0>.
+Add a margin around the whole page. Possible units are I<pt>, I<in>, I<cm>
+and I<mm>. The default unit is I<pt>. The default margin is I<0>.
-=item B<-c, --crop>
+=item B<-c>, B<--crop>
If this option is set, the PostScript code will interpreted to calculate the
maximal effective bounding box. This operation may take time and be quite
@@ -151,12 +151,9 @@ mode (see B<DESCRIPTION>) is "NoTumble", you should either use lpr with
the option "Tumble" manually, or consider the B<PDFTool> option
B<--screen> instead.
-=item B<-n, --nup=>I<num>
-
-Put multiple logical pages onto each physical sheet of paper. The inner
-margin might be same as the outer one (depending on the booklet option
-B<-b>), see B<-m> for details.
+=item B<-n> I<num>, B<--nup=>I<num>
+Put multiple logical pages onto each physical sheet of paper.
If I<num> is less than 10, the option B<->I<num> may be used as an
alternative.
@@ -169,10 +166,10 @@ effect for portrait documents.
=item B<--column>
-Change the order to `column-major', where successive pages are placed in
+Change the order to "column-major", where successive pages are placed in
columns down the paper.
-=item B<-q, --quiet>
+=item B<-q>, B<--quiet>
B<PDFTool> normally prints the page numbers of the pages output; this
option suppresses this.
@@ -194,7 +191,8 @@ Display the manual page.
=head1 EXAMPLES
The following comand can be used to remotely crop a PDF file, convert it
-to A4 paper, and rearrange the pages to print a booklet:
+to A4 paper, and rearrange the pages to print a booklet with custom
+margins:
C<< ssh remote pdftool.pl -cpA4 --book -2 -b2cm -m-1cm < in.pdf | \
lpr -o Duplex=DumplexTumble >>
@@ -379,15 +377,15 @@ my $return = 0;
try {
&pdftops();
-
+
&psselect() if defined $select;
-
+
my @bbox = &psbbox();
-
+
&psbook() if defined $book;
-
+
my ($landscape,$rotate) = &psnup (@bbox);
-
+
&pstopdf ($landscape,$rotate);
}
@@ -403,18 +401,18 @@ catch Error with {
}
finally {
-
+
# Avoid zombies
map { my ($pid, @cmd) = @$_;
my ($r,$v) = (waitpid ($pid, 0), $?);
warn "Can't run `" . &printcmd (@cmd) . "'"
if ($r != -1 and $v >> 8);
} @pids;
-
+
# Close opened file handles
map { close $_ or die "Can't close: $!" }
( *READ, *FIN, *FOUT );
-
+
# Delete auxiliary files
unlink @auxfiles;
@@ -441,20 +439,20 @@ sub pdftops {
unless (defined $infile && $inseek) {
# Need to copy the whole input to an auxiliary file, since
# conversion from PDF to PS requires random access to the data
-
+
$infile = "$tmpdir/pdftool-stdin-$$." . lc $filetype;
-
+
open FINAUX, '>', $infile
or die "Can't write into `$infile': $!";
push @auxfiles, $infile;
-
+
# cat > $infile
while (<FIN>) {
print FINAUX or die "Can't print: $!";
}
close FINAUX;
}
-
+
my ($first, $last);
# pdftops doesn't provide any way to have page numbers relative to
# the end of the document, hence there is no detection of the
@@ -476,7 +474,7 @@ sub pdftops {
$last = $rmax if defined $last && $rmax > $last;
}
}
-
+
# Calculate the new page range
my @newselect;
for (split /,/, $select) {
@@ -488,10 +486,10 @@ sub pdftops {
}
push @newselect, "$rmin$sep$rmax";
}
-
+
$select = join ',', @newselect;
- }
-
+ }
+
# Convert to PS
my @cmd = ('pdftops', '-origpagesizes', "$infile", '-');
push @cmd, '-f', $first if defined $first;
@@ -535,33 +533,33 @@ sub psbbox {
if (defined $crop) {
# Calculate the maximal bounding box
-
+
unless (seek IN, 0, 1) {
# The input is not seekable: have to create a seekable auxiliary
# file
-
+
my $auxfile = "$tmpdir/pdftool-stdin-$$.ps";
-
+
open AUXFD, '>', "$auxfile"
or die "Can't write into `$auxfile': $!";
push @auxfiles, $auxfile;
-
+
# cat > $auxfile
while (<IN>) {
print AUXFD or die "Can't print: $!";
}
close AUXFD or die "Can't close: $!";
close IN or die "Can't close: $!";
-
+
open IN, '<', "$auxfile" or die "Can't read `$auxfile': $!";
}
-
+
# Need to duplicate IN, since it will be closed in the parent process
open *GSIN, '<&IN';
-
+
my @cmd = ('gs', '-sDEVICE=bbox', '-dBATCH', '-dNOPAUSE', '-');
my $pid = open3 "<&GSIN", ">&GSOUT", *GSOUT, @cmd;
-
+
my ($p,$c) = (0,0); # Page & character counter
my ($x0, $y0, $x1, $y1) = (1<<16, 1<<16, -(1<<16), -(1<<16));
while (<GSOUT>) {
@@ -583,51 +581,51 @@ sub psbbox {
}
close GSOUT or die "Can't close: $!";
print LOG "\n" or die "Can't close: $!" unless defined $quiet;
-
+
# No zombie processes
waitpid $pid, 0;
die "Can't run `" . &printcmd (@cmd) . "'" if $? >> 8;
-
+
die "Error while calculating bounding box"
if ($x0 >= $x1 || $y0 >= $y1);
@bbox = ($x0, $y0, $x1, $y1);
-
+
# Let's go back to the beginning of the input
seek IN, 0, 0 or die "$!";
-
+
} elsif (defined $inwidth and defined $inheight) {
@bbox = (0, 0, $inwidth, $inheight);
} else {
# Guess page size from the input file
-
+
# To avoid to seek into IN, it gonna be copied from WRITE to READ
# in background, once the Bounding Box has been read
pipe *READ, *WRITE or die "Can't pipe: $!";
-
+
while (not (@bbox) && defined (my $l = <IN>)) {
print WRITE $l or die "Can't close: $!";
@bbox = ($1, $2, $3, $4)
if ($l =~ m/^\%\%BoundingBox: (\d+) (\d+) (\d+) (\d+)/);
}
-
+
die "Cannot guess input page size!" unless @bbox;
-
+
unless (my $pid = fork) {
# Child: cat IN > WRITE in background
die "Can't fork: $!" unless defined $pid;
close READ or die "Can't close: $!";;
-
+
while (<IN>) {
print WRITE or die "Can't close: $!";
}
exit;
}
# Parent
-
+
close WRITE or die "Can't close: $!";
close IN or die "Can't close: $!";
-
+
open *IN, "<&READ" or die "Can't dup: $!";
}
return @bbox;
@@ -670,13 +668,12 @@ sub psnup {
$landscape = 1;
}
-
+
#
- # Finding the best layout is an optimisation problem. We try all of
- # the combinations of width*height in both normal and rotated form,
- # and minimise the wasted space.
+ # Find the best layout is an optimisation problem. We try all of the
+ # combinations of width*height in both normal and rotated form, and
+ # minimise the wasted space.
#
-
my ($ow,$oh) = ($outwidth-2*$margin, $outheight-2*$margin);
my ($iw, $ih) = ($bbox[2]-$bbox[0], $bbox[3]-$bbox[1]);
@@ -718,7 +715,7 @@ sub psnup {
}
}
- # fail if nothing better than worst tolerance was found
+ # Fail if nothing better than worst tolerance was found
die "Can't find acceptable layout for $nup-up" if $best == $tolerance;
@@ -769,7 +766,7 @@ sub psnup {
}
($ow,$oh) = ($oh,$ow) if $rotate%2;
-
+
my $pagespecs;
if (defined $screen || $ow < $oh) {
$pagespecs = $nup . ':' . join ('+', @ospecs);
@@ -777,7 +774,7 @@ sub psnup {
$pagespecs = 2*$nup . ':' . join ('+', @ospecs)
. ',' . join ('+', @especs);
}
-
+
my @cmd = ('pstops', '-w', $bbox[2], '-h', $bbox[3], $pagespecs);
push @cmd, '-q' if defined $quiet;
@@ -808,7 +805,7 @@ sub pstopdf {
} else {
$pagedevice = "/PageSize [$outwidth $outheight]";
}
-
+
my @cmd = ('gs', "-sDEVICE=pdfwrite", "-sOutputFile=%stdout%", "-dBATCH",
"-dNOPAUSE", "-dAutoRotatePages=/None",
"-c", "<< $pagedevice >> setpagedevice",