Current File : //kunden/bin/psjoin |
#!/usr/bin/perl
# -*- perl -*-
my $version_banner = <<END;
psjoin 2.07
Copyright (c) Tom Sato 2002-2003.
Copyright (c) Reuben Thomas 2013-2020.
Released under the GPL version 3, or (at your option) any later version.
END
use v5.10;
use strict;
use warnings;
BEGIN
{
# Relocatable header
# The functions in this file provide support for relocatability of
# Perl scripts. They should be included near the beginning of each
# Perl script in a relocatable program, by adding @relocatable_pl@
# and causing the script to be expanded with AC_CONFIG_FILES. A
# small amount of additional code must be added and adapted to the
# package by hand; see doc/relocatable-maint.texi (in Gnulib) for
# details.
#
# This code is based on relocatable.sh.in, and design changes (and
# bugs) should probably be cross-checked with it.
#
# Copyright (C) 2013, 2015-2022 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
use Config;
use File::Basename;
use File::Spec::Functions;
use Cwd 'realpath';
# Support for relocatability.
sub find_curr_installdir {
# Determine curr_installdir, even taking into account symlinks.
my $curr_executable = $0;
my $basename = basename($0);
if ($curr_executable eq $basename) {
LOOP: for my $dir (split /$Config{path_sep}/, $ENV{PATH}) {
$dir = "." unless $dir;
for my $ext ('') {
my $filename = catfile($dir, "$curr_executable$ext");
if (-f $filename) {
$curr_executable = $filename;
last LOOP;
}
}
}
}
# Resolve symlinks and canonicalize.
return realpath(dirname($curr_executable));
}
sub find_prefixes {
# Compute the original/current installation prefixes by stripping the
# trailing directories off the original/current installation directories.
my ($orig_installprefix, $curr_installprefix) = @_;
my $orig_last = basename($orig_installprefix);
my $curr_last = basename($curr_installprefix);
if ($orig_last && $curr_last && $orig_last eq $curr_last) {
$orig_installprefix = dirname($orig_installprefix);
$curr_installprefix = dirname($curr_installprefix);
}
return $orig_installprefix, $curr_installprefix;
}
if ("no" eq "yes") {
my $exec_prefix = "/usr";
my $orig_installdir = "/usr/bin"; # see Makefile.am's *_SCRIPTS variables
my ($orig_installprefix, $curr_installprefix) = find_prefixes($orig_installdir, find_curr_installdir());
sub relocate { # the subroutine is defined whether or not the enclosing block is executed
my ($dir) = @_;
if ("no" eq "yes") {
$dir =~ s%^$orig_installprefix/%$curr_installprefix/%;
$dir =~ s,/$,,;
}
return $dir;
}
}
# Relocate the directory variables that we use.
my $pkgdatadir = &relocate("/usr/share/psutils");
# End of relocatable header; "real" Perl starts here.
unshift (@INC, '/usr/share/psutils') unless $ENV{PSUTILS_UNINSTALLED};
}
use File::Basename;
use Getopt::Long;
use PSUtils;
our $program_name = basename($0);
sub usage {
my ($exit_code) = @_;
print STDERR <<END;
Usage: $program_name [OPTION...] FILE...
Concatenate PostScript documents.
-e, --even force each file to an even number of pages
-s, --save try to close unclosed save operators
-n, --nostrip do not strip prolog or trailer from input files
--help display this help and exit
--version display version information and exit
END
exit $exit_code;
}
my $force_even = 0;
my $force_save = 0;
my $nostrip = 0;
my $save = "save %psjoin\n";
my $restore = "restore %psjoin\n";
my ($help_flag, $version_flag);
Getopt::Long::Configure("bundling");
# Having configured bundling, must give short option names explicitly
GetOptions(
"even|e" => \$force_even,
"save|s" => \$force_save,
"nostrip|n|p" => \$nostrip,
"help" => \$help_flag,
"version" => \$version_flag,
) or usage(1);
if ($version_flag) {
print STDERR $version_banner;
exit 0;
}
usage(0) if $help_flag or $#ARGV == -1;
if ($force_save) {
$save = "/#psjoin-save# save def %psjoin\n";
$restore = "#psjoin-save# restore %psjoin\n";
}
my (@prolog, $prolog_inx, @trailer, @comments, @pages);
if ($nostrip) {
$prolog_inx = 9999;
$prolog[$prolog_inx] = "% psjoin: don't strip\n";
$trailer[$prolog_inx] = "% psjoin: don't strip\n";
} else {
for (my $i = 0; $i <= $#ARGV; $i++) {
open(IN, $ARGV[$i]) || die "$0: can't open \"$ARGV[$i]\" ($!)";
my $in_comment = 1;
my $in_prolog = 1;
my $in_trailer = 0;
$comments[$i] = "";
$prolog[$i] = "";
$trailer[$i] = "";
$pages[$i] = 0;
while (<IN>) {
next if /^%%BeginDocument/ .. /^%%EndDocument/;
if ($in_comment) {
next if /^%!PS-Adobe-/;
next if /^%%Title/;
next if /^%%Pages/;
next if /^%%Creator/;
$in_comment = 0 if /^%%EndComments/;
$comments[$i] .= $_;
next;
} elsif ($in_prolog) {
if (/^%%Page:/) {
$in_prolog = 0;
} else {
$prolog[$i] .= $_;
next;
}
}
$in_trailer = 1 if /^%%Trailer/;
if ($in_trailer) {
$trailer[$i] .= $_;
next;
}
$pages[$i]++ if /^%%Page:/;
}
close(IN);
if ($prolog[$i]) {
for (my $j = 0; $j < $i; $j++) {
if ($prolog[$j] eq $prolog[$i]) {
$pages[$j] += $pages[$i];
last;
}
}
}
}
my $largest = 0;
$prolog_inx = 0;
for (my $i = 0; $i <= $#ARGV; $i++) {
my $size = length($prolog[$i]) * $pages[$i];
if ($largest < $size) {
$largest = $size;
$prolog_inx = $i;
}
}
}
my @files = @ARGV;
@files = map basename($_), @ARGV;
print <<END;
%!PS-Adobe-3.0
%%Title: @files
%%Creator: psjoin (from PSUtils)
%%Pages: (atend)
END
print $comments[$prolog_inx] || "";
print "\n$prolog[$prolog_inx]";
for (my $i = 0; $i <= $#ARGV; $i++) {
if ($prolog[$i]) {
$prolog[$i] =~ s/^%%/% %%/;
$prolog[$i] =~ s/\n%%/\n% %%/g;
$trailer[$i] =~ s/^%%/% %%/;
$trailer[$i] =~ s/\n%%/\n% %%/g;
}
}
my $total_pages = 0;
for (my $i = 0; $i <= $#ARGV; $i++) {
say "% psjoin: file: $files[$i]";
if (!defined($prolog[$i]) || $prolog[$i] ne $prolog[$prolog_inx]) {
say "% psjoin: Prolog/Trailer will be inserted in each page";
} else {
say "% psjoin: common Prolog/Trailer will be used";
}
my $in_comment = 1 if !$nostrip;
my $in_prolog = 1 if !$nostrip;
my $in_trailer = 0;
my $saved = 0;
my $pages = 0;
open(IN, $ARGV[$i]) || die "$0: can't open \"$ARGV[$i]\" ($!)";
while (<IN>) {
if (/^%%BeginDocument/ .. /^%%EndDocument/) {
# s/^(%[%!])/% \1/;
print $_;
} else {
if ($in_comment) {
$in_comment = 0 if /^%%EndComments/;
} elsif ($in_prolog) {
if (/^%%Page:/) {
$in_prolog = 0;
} else {
next;
}
}
$in_trailer = 1 if !$nostrip && /^%%Trailer/;
next if $in_trailer;
if (/^%%Page:/) {
if ($saved) {
print $trailer[$i];
print $restore;
$saved = 0;
}
$pages++;
$total_pages++;
say "\n%%Page: ($i-$pages) $total_pages";
if (!defined($prolog[$i]) || $prolog[$i] ne $prolog[$prolog_inx]) {
print $save;
print $prolog[$i] if defined($prolog[$i]);
$saved = 1;
} elsif ($force_save) {
print $save;
}
} else {
s/^(%[%!])/% $1/;
print $_;
}
}
}
close(IN);
if ($force_even && $pages % 2 != 0) {
$pages++;
$total_pages++;
print <<END;
%%Page: ($i-E) $total_pages
% psjoin: empty page inserted to force even pages
showpage
END
}
print $trailer[$i] if defined($trailer[$i]) && $saved;
print $restore if $saved || $force_save;
}
say "\n%%Trailer";
print $trailer[$prolog_inx];
print "\n%%Pages: $total_pages\n%%EOF";