summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xpdftool.pl69
1 files changed, 43 insertions, 26 deletions
diff --git a/pdftool.pl b/pdftool.pl
index b08b4aa..ab52f2c 100755
--- a/pdftool.pl
+++ b/pdftool.pl
@@ -27,13 +27,13 @@ pdftool.pl - a PDF swiss army knife
B<pdftool.pl> [B<-w> I<width> ] [B<-h> I<heigth>] [B<-p> I<paper>]
[B<-W> I<width>] [B<-H> I<heigth>] [B<-P> I<paper>] [B<-s> I<pages>]
[B<-m> I<margin>] [B<-b> I<border>] [B<-c>] [B<--book>] [B<--column>]
-[B<-n> I<num>] [B<--screen>] [B<-q>] [I<infile> [I<outfile>]]
+[B<-n> I<num>] [B<--screen>] [B<--pdf>] [B<-q>] [I<infile> [I<outfile>]]
=head1 DESCRIPTION
B<PDFTool> combines the tools in the PSUtils bundle in a nice way. The
input should be either a Portable Document Format (PDF) file, or a
-PostScript file. The output format is PDF only.
+PostScript file.
If no input file is given, or if a single hyphen-minus (I<->) is given as
file name, B<PDFTool> will read the PDF or PostScript data from the standard
@@ -55,20 +55,20 @@ The document will be treated as follows:
=over 4
-=item * Convert from PDF to PostScript (if necessary, and if possible -
+=item * Convert from PDF to PostScript if necessary (if possible,
that is if all page numbers are relative to the begining of the
-document -, convert only the smallest interval that contains all the selected
+document, convert only the smallest interval that contains all the selected
pages),
-=item * Select the page range,
+=item * Select the page range if necessary,
-=item * Calculate the minimal bounding box
+=item * Calculate the minimal bounding box,
-=item * Rearrange pages for printing books or booklets,
+=item * Rearrange pages for printing books or booklets if necessary,
=item * Put multiple pages per sheets,
-=item * Convert back from PS to PDF.
+=item * "Flatten" the output, and convert back to PDF if necessary.
=back
@@ -112,13 +112,11 @@ I<folio>, I<quarto>, or I<10x14>. The default output paper size is I<a4>.
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> 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> I<paper>, B<--Paper=>I<paper>
Same as the option B<-p>, but for the input file. By default,
@@ -146,7 +144,7 @@ demanding for the CPU. See the note for the border option (B<-b>) above.
=item B<--book>
Rearrange pages for printing books or booklets. If your "default" duplex
-mode (see B<DESCRIPTION>) is "NoTumble", you should either use lpr with
+mode (see B<DESCRIPTION>) is "NoTumble", you should either use C<lpr> with
the option "Tumble" manually, or consider the B<PDFTool> option
B<--screen> instead.
@@ -163,6 +161,12 @@ your "default" duplex mode (see B<DESCRIPTION>). B<--screen> tries to
make the output PDF ready to read on your computer instead. It has no
effect for portrait documents.
+=item B<--pdf>
+
+By default, B<PDFTool>'s output is a PostScript file; use this flag if
+you want a PDF instead. Note that since reading a PDF requires random
+access to the data, you won't be able to pipe the output to C<lpr> then.
+
=item B<--column>
Change the order to "column-major", where successive pages are placed in
@@ -198,8 +202,15 @@ C<< ssh remote pdftool.pl -cpA4 --book -2 -b2cm -m-1cm < in.pdf | \
=head1 REQUIREMENTS
+Requires C<pdftops> available via the command line (only if the input is
+a PDF). Depending on your own version of this program, you might need to
+hack the source yourself to remove the `-origpagesizes' option :-/.
+
Requires PSUtils installed and available via the command line
-http://www.tardis.ed.ac.uk/~ajcd/psutils/.
+(http://www.tardis.ed.ac.uk/~ajcd/psutils/).
+
+Requires GhostScript installed and available via the command C<gs>
+(http://ghostscript.com/).
=head1 AUTHOR
@@ -210,7 +221,8 @@ conditions.
-my $tmpdir = '/tmp';
+my $tmpdir = '/tmp';
+my @gs = ('gs', '-dSAFER');
#
# Options & arguments
@@ -226,6 +238,7 @@ my $column;
my $quiet;
my $man;
my $screen;
+my $pdfout;
GetOptions( "select|s=s" => \$select,
"w|width=s" => \$outwidth,
@@ -238,6 +251,7 @@ GetOptions( "select|s=s" => \$select,
"border|b=s" => \$border,
"crop|c" => \$crop,
"book" => \$book,
+ "pdf" => \$pdfout,
"nup|n=i" => \$nup,
"screen" => \$screen,
"1" => sub { $nup = 1 },
@@ -341,7 +355,7 @@ try {
my ($FD3, $landscape, $rotate) = &psnup ($FD2, @bbox);
- &pstopdf ($FD3, $FOUT, $landscape, $rotate);
+ &pswrite ($FD3, $FOUT, $landscape, $rotate);
}
catch Error with {
@@ -406,7 +420,7 @@ sub pdftops {
pipe $READ, $WRITE or die "Can't pipe: $!";
while (not (defined $filetype) && defined (my $l = <$IN>)) {
- print $WRITE ($l) or die "Can't close: $!";
+ print $WRITE ($l) or die "Can't print: $!";
if (defined $l && $l =~ /^%!PS/) {
$filetype = "PS";
@@ -493,12 +507,13 @@ sub pdftops {
}
# Convert to PS
+ # TODO: use gs & pswrite the day it'll handle fonts correctly
my @cmd = ('pdftops', '-origpagesizes', $infile, '-');
push @cmd, '-f', $first if defined $first;
push @cmd, '-l', $last if defined $last;
push @cmd, '-q' if defined $quiet;
- my $pid = open $OUT, "-|", @cmd;
+ my $pid = open $OUT, '-|', @cmd;
push @pids, [$pid, @cmd];
return $OUT;
@@ -558,8 +573,8 @@ sub psbbox {
# Need to duplicate IN, since it will be closed in the parent process
open *IN, '<&=', $IN or die "Can't fdopen: $!";
- my @cmd = ('gs', '-sDEVICE=bbox', '-dBATCH', '-dNOPAUSE', '-');
- my $pid = open3 "<&IN", ">&OUT", *OUT, @cmd;
+ my @cmd = (@gs, '-sDEVICE=bbox', '-dQUIET', '-dBATCH', '-dNOPAUSE', '-');
+ my $pid = open3 '<&IN', '>&OUT', *OUT, @cmd;
my ($p,$c) = (0,0); # Page & character counter
my ($x0, $y0, $x1, $y1) = (1<<16, 1<<16, -(1<<16), -(1<<16));
@@ -648,7 +663,7 @@ sub psbook {
push @cmd, '-q' if defined $quiet;
*IN = $IN;
- my $pid = open3 "<&IN", $OUT, ">&LOG", @cmd;
+ my $pid = open3 '<&IN', $OUT, '>&LOG', @cmd;
push @pids, [$pid, @cmd];
return $OUT;
@@ -785,7 +800,7 @@ sub psnup {
push @cmd, '-q' if defined $quiet;
*IN = $IN;
- my $pid = open3 "<&IN", $OUT, ">&LOG", @cmd;
+ my $pid = open3 '<&IN', $OUT, '>&LOG', @cmd;
push @pids, [$pid, @cmd];
return ($OUT, $landscape, $rotate);
@@ -796,7 +811,7 @@ sub psnup {
#
# Final file: Convert back to PDF
#
-sub pstopdf {
+sub pswrite {
my ($IN, $OUT, $landscape, $rotate) = @_;
my ($ow,$oh) = ($outwidth,$outheight);
@@ -810,13 +825,15 @@ sub pstopdf {
$pagedevice = "/PageSize [$outwidth $outheight]";
}
- my @cmd = ('gs', "-sDEVICE=pdfwrite", "-sOutputFile=%stdout%", "-dBATCH",
- "-dNOPAUSE", "-dAutoRotatePages=/None",
- "-c", "<< $pagedevice >> setpagedevice",
- "-f", "-");
+ my @device = ('-sDEVICE=pswrite', '-dLanguageLevel=3');
+ @device = ('-sDEVICE=pdfwrite') if defined $pdfout;
+ my @cmd = (@gs, @device, '-dQUIET', '-dBATCH', '-dNOPAUSE',
+ '-sOutputFile=%stdout%', '-dAutoRotatePages=/None',
+ '-c', "<< $pagedevice >> setpagedevice",
+ '-f', '-');
(*IN,*OUT) = ($IN,$OUT);
- my $pid = open3 "<&IN", ">&OUT", ">&LOG", @cmd;
+ my $pid = open3 '<&IN', '>&OUT', '>&LOG', @cmd;
push @pids, [$pid, @cmd];
}