From f732cca08a17007c923ccaae3fbcb47175050bf9 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Thu, 26 May 2011 16:14:32 +0200 Subject: ps output --- pdftool.pl | 69 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file 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 [B<-w> I ] [B<-h> I] [B<-p> I] [B<-W> I] [B<-H> I] [B<-P> I] [B<-s> I] [B<-m> I] [B<-b> I] [B<-c>] [B<--book>] [B<--column>] -[B<-n> I] [B<--screen>] [B<-q>] [I [I]] +[B<-n> I] [B<--screen>] [B<--pdf>] [B<-q>] [I [I]] =head1 DESCRIPTION B 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 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, I, or I<10x14>. The default output paper size is I. 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, B<--Height=>I 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, B<--Paper=>I 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) is "NoTumble", you should either use lpr with +mode (see B) is "NoTumble", you should either use C with the option "Tumble" manually, or consider the B option B<--screen> instead. @@ -163,6 +161,12 @@ your "default" duplex mode (see B). 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'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 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 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 +(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]; } -- cgit v1.2.3