#!/usr/bin/perl

#
# pspage - adds page numbers to a postscript file
#

#
# Author:  Christoph Dalitz
# License: freely distributable under GPL
# Version: 1.4
#
# History:
#   15.04.2001  first creation
#   01.02.2002  removed dependency on %%BeginPageSetup
#               bugfix in use of stringwidth and point/cm conversion
#               landscape option added
#   12.02.2002  added special care for embedded EPSF images
#               new options -ltext, -rtext, -ctext
#   13.03.2002  new option -font
#   24.01.2008  new options -xe and -xo for distinguishing between
#               x-position for odd and even pages
#


# global variable intitializations
#---------------------------------------------------

$IN = 72;
$FONT = "Times-Roman";
$FONTSIZE = "12";

# default position parameters for portrait [0] and landscape [1]
# nota bene: values are in inches and suited for letter format!
@XDEF = (4.25, 5.5);
@YDEF = (0.7, 7.7);

# command line parameters
$N = 0;
$ORIENTATION = 0;
$X = -1;
$XO = -1;
$XE = -1;
$Y = -1;
$INFILE = "";
$TEXT = "%p";
$ALIGN = "c";

$PGM = pspage;
$VERSION = "1.4";
$USAGEMSG = "This is " . $PGM . " version " . $VERSION . "\n" .
    "USAGE:\n\t" . $PGM . " [options] [<infile>]\n" .
    "OPTIONS:\n" .
    "\t-?        help message\n" .
    "\t-1 <nr>   first page [" . ($N+1) . "]\n" .
    "\t-y <in>   y position [" . $YDEF[$ORIENTATION] . "]\n" .
    "\t-x <in>   x position [" . $XDEF[$ORIENTATION] . "]\n" .
    "\t-xo <in>  x position on odd pages [" . $XDEF[$ORIENTATION] . "]\n" .
    "\t-xe <in>  x position on even pages [" . $XDEF[$ORIENTATION] . "]\n" .
    "\t-l        landscape orientation (rotates characters)\n" .
    "\t-ltext <text>\n" .
    "\t-rtext <text>\n" .
    "\t-ctext <text>\n" .
    "\t          prints <text> instead of page number\n" .
    "\t          <text> may contain '%p' for the page number\n" .
    "\t          The three options differ in the text alignment:\n" .
    "\t          left (-ltext), right (-rtext) or centerd (-ctext)\n" .
    "\t-font <font>[:<size>]\n" .
    "\t          use <font> with size <size> [$FONT:$FONTSIZE]\n";


# main program
#---------------------------------------------------

#
# parse command line
#
while (@ARGV) {
    my $opt = shift @ARGV;
    if ($opt eq "-?") {     # help message
        print $USAGEMSG;
        exit 0;
    }
    elsif ($opt eq "-1") {  # first page
        $N = (shift(@ARGV) - 1);
    }
    elsif ($opt eq "-x") {  # x position
        $X = shift(@ARGV);
    }
    elsif ($opt eq "-xo") {  # x position odd pages
        $XO = shift(@ARGV);
    }
    elsif ($opt eq "-xe") {  # x position even pages
        $XE = shift(@ARGV);
    }
    elsif ($opt eq "-y") {  # x position
        $Y = shift(@ARGV);
    }
    elsif ($opt eq "-l") {  # landscape orientation
        $ORIENTATION = 1;
    }
    elsif ($opt eq "-ltext") {  # custom text left justified
        $TEXT = shift(@ARGV);
        $ALIGN = "l";
    }
    elsif ($opt eq "-rtext") {  # custom text right justified
        $TEXT = shift(@ARGV);
        $ALIGN = "r";
    }
    elsif ($opt eq "-ctext") {  # custom text centered
        $TEXT = shift(@ARGV);
        $ALIGN = "c";
    }
    elsif ($opt eq "-font") {  # font and (optional) size
        my @arr = split(/:/, shift(@ARGV));
        if (($#arr >= 0) && $arr[0]) { $FONT = $arr[0]; }
        if ($#arr >= 1) {
            if ($arr[1] <= 0) {
                print STDERR "Bad fontsize $arr[1]\n";
                exit 1;
            }
            $FONTSIZE = $arr[1];
        }
    }
    else {                  # input file
        $INFILE = $opt;
        if (! -e $INFILE) {
            print STDERR "Cannot find $INFILE\n";
            exit 1;
        }
    }
}

# set default position values if not explicitly given
if ($X < 0) {
    $X = $XDEF[$ORIENTATION];
}
if ($XO < 0) {
    $XO = $X;
}
if ($XE < 0) {
    $XE = $X;
}
if ($Y < 0) {
    $Y = $YDEF[$ORIENTATION];
}

# counter for reckognizing embedded EPSF images
$insideepsf = 0;

#
# process postscript input
#
if ($INFILE) {
    open(IFH, $INFILE) or die("Cannot open ", $INFILE, "\n");
} else {
    open(IFH, "-") or die("Cannot open STDIN\n");
}
while (<IFH>) {

    # print original line in any case
    print;

    # take care of embedded EPS images
    if (/^\%\%BeginDocument:/) {
        $insideepsf++;
    }
    if (/^\%\%EndDocument/ && ($insideepsf>0)) {
        $insideepsf--;
    }

    # print page number or text
    if (/^\%\%Page:/ && ($insideepsf==0)) {

        # count pages
        $N++;

        # replace escape (%p) in text
        $tmptext = $TEXT;
        $tmptext =~ s/\%p/$N/g;

        # print text at (x,y)
        print "gsave\n";
	if (1 == $N % 2) {
	    printf("/$FONT $FONTSIZE selectfont %.1f %.1f moveto\n",
		   $XO*$IN,$Y*$IN);
	} else {
	    printf("/$FONT $FONTSIZE selectfont %.1f %.1f moveto\n",
		   $XE*$IN,$Y*$IN);
	}
        if ($ORIENTATION == 1) { # landscape mode
            print "90 rotate ";
        }
        # shift start point according alignment
        if ($ALIGN eq "c") { # centered
            print "($tmptext) stringwidth pop -2 div 0 rmoveto ";
        }
        elsif ($ALIGN eq "r") { # right justified
            print "($tmptext) stringwidth pop neg 0 rmoveto ";
        }
        elsif ($ALIGN eq "l") { # left justified
            # no shift required
        }
        print "($tmptext) show\n";
        print "grestore\n";
    }

}
close(IFH);