#! /usr/bin/perl use Getopt::Long; use IPC::Open2; use warnings; use strict; Getopt::Long::Configure ("bundling"); my $pdf2ps = 'pdftops'; my $pscrop = 'psnup2.pl -s1 -l1'; my $psresize = 'psresize'; my $psnup = 'psnup'; my $psbook = 'psbook'; my $ps2pdf = 'ps2pdf'; my $tmpdir = '/tmp'; my $papersize; my $nup = 1; my $margin = 1; #TODO: units my $crop; my $book; GetOptions( "nup|n=i" => \$nup, "1" => sub { $nup = 1 }, "2" => sub { $nup = 2 }, "4" => sub { $nup = 4 }, "8" => sub { $nup = 8 }, "crop|c" => \$crop, "book|b" => \$book, "papersize|p=s" => \$papersize, "margin|m=s" => \$margin ); die "I can handle only one file at the same time :P" if $#ARGV > 0; die "How should I put a non-positive number of pages per sheet?" if $nup <= 0; unless (defined $papersize) { $papersize = `paperconf` or die "Can't guess papersize"; chomp $papersize; } for (my $n = $nup; $n > 1; $n /= 2) { die "nup should be a power of two" unless $n % 2 == 0; } my $filename = $ARGV[0]; $filename = "-" unless defined $filename; my $filename2 = $filename; $filename2 = "(stdin)" if $filename eq "-"; my ($mresize, $mcrop, $mnup) = (0,0,0); if (defined $crop) { $mresize = 0; if (not defined $book && $nup > 1) { $mcrop = $margin/2; $mnup = $mcrop; } else { $mcrop = $margin; $mnup = 0; } } else { if (not defined $book && $nup > 1) { $mresize = $margin/2; $mnup = $mresize; } else { $mresize = $margin; $mnup = 0; } } open(FILE, $filename) or die "Can't read `$filename'"; my $filetype; my $fstline = ; if (defined $fstline && $fstline =~ /%!PS.*/) { $filetype = "PS"; } elsif (defined $fstline && $fstline =~ /%PDF.*/) { $filetype = "PDF"; } else { die "Can't recognize the type of `$filename2'"; } # auxiliary files, to remove my @auxfiles; # auxiliary file descriptors, to close my @auxfds; if ($filename eq "-") { # Need to copy the whole input to an auxiliary file, since # conversion from pdf to ps requires random access to the data $filename = "$tmpdir/pdftool-stdin-" . int(rand 2**16) . lc ".$filetype"; open(AUXFD, '>', "$filename") or die "Can't read write into `$filename'"; push @auxfiles, "$filename"; # cat > $filename print AUXFD $fstline; while () { print AUXFD $_; } close(AUXFD); } close(FILE); # Convert to ps, or read the input file if ($filetype eq "PDF") { open(PSFILE, '|-', "$pdf2ps $filename -") or die "Error with `$pdf2ps $filename -'"; } else { open(PSFILE, '<', "$filename") or die "Can't open `$filename'"; } push @auxfds, fileno PSFILE; # Resize file to our papersize open2(*PSRESIZE, "<&PSFILE", "psresize -p$papersize") or die "Error with `psresize -p$papersize'"; #push @auxfds, fileno \*PSRESIZE; open("<&PSRESIZE", "cat"); exit 0; # pscrop *PSCROP = *PSRESIZE; # psbook *PSBOOK = *PSCROP; # psnup # TODO: sometimes unecessary open2(*PSNUP, "<&PSBOOK", "psnup -p$papersize -m$mnup -$nup") or die "Error with `psnup -p$papersize -m$mnup -$nup'"; # TODO: not always stdout open2(">&STDOUT", "<&PSBOOK", "ps2pdf -sPAPERSIZE=$papersize - -") or die "Error with `ps2pdf -sPAPERSIZE=$papersize - -'"; # close auxiliary filehandles map {close $_} @auxfds; # delete auxiliary files unlink @auxfiles; #TODO: better do forget stdin, I guess #if ($filename eq "-" && $filetype eq "PDF") { #} #if ($filetype eq "PDF") { # $command .= "$pdf2ps $filename - | "; #} else { # $command .= "cat $filename | "; #} # # ##$command .= "$psresize -p$papersize /tmp/paf.ps | "; ## useless, since the argument of $pscrop has to be seekable # #if (defined $crop) { # $command .= "$pscrop -m$margin /tmp/paf.ps | "; #} else { # $command .= "cat /tmp/paf.ps | "; #} # #$command .= "$psnup -p$papersize -m${margin}cm -$nup | "; # #$command .= "$psbook | " if defined $book; # #$command .= "$ps2pdf -sPAPERSIZE=$papersize - - "; # # #$command .= "> /tmp/pouf.pdf"; # #print "$command", "\n"; #system $command; #system ($pdfviewer, "/tmp/pouf.pdf");