Search code examples
pdfghostscriptpostscript

Insert page number in each page of PDF file via Ghostscript


Currently I'm working in a feature that will insert page number in PDFs via ghostscript. As first approach I tried to follow same commands as I did for inserting watermark in each file's page - as follows:

gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=pdfwrite -sOutputFile=out.pdf watermark.ps in.pdf

In this case, watermark will be printed in every file's page - which is the behaviour I expected. However, for printing page number in each page is an incremental number which will be printed in every page, e.g, for each page a different number should be printed. Currently, my code looks like this:

<<
   /EndPage
   {
     2 eq { pop false }
     {
         gsave      
         /Arial 8 selectfont
         550 820 moveto (page 1) show
         grestore
         true
     } ifelse
   } bind
>> setpagedevice

And the command to call this is almost the same for watermark, just changing the second parameter:

gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=pdfwrite -sOutputFile=out.pdf pages.ps in.pdf

I'm trying to insert parameters to this "pages.ps" file in order to print pages dynamically. Something like this:

550 820 moveto (attr[0]) show

And call via command line like this:

gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=pdfwrite -sOutputFile=out.pdf pages.ps "pageNumber" in.pdf

Unfortunately, this doesn't work!

I'm struggling this for days and any help would be appreciated. Any other approach will be helpful as well.

Cheers!


Solution

  • From your command line, It seems to me that you're trying to pass arguments into the postscript program from the command line. There are a few ways to do this.

    Using ARGUMENTS

    Ghostscript has a special behavior when you invoke with the -- argument.

    $ gs -q -- prog.ps 1 2 3
    

    Then the program can access these arguments as an array of strings called ARGUMENTS.

    %!
    ARGUMENTS ==
    

    This program will print

    [ (1) (2) (3) ]
    

    for the above input.

    Using -d or -s

    This way is probably better for your needs. You can use -sname=string to perform the equivalent of /name (string) def before proceeding with the next element of the command line. Use -s for strings and -d for any other kind of postscript token that needs to be scanned and interpreted.

    So probably you want to do something like this:

    $ gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=pdfwrite -sOutputFile=out.pdf -sattr=pageNumber pages.ps in.pdf
    

    Then page.ps can access this string simply as attr. PostScript array indexing doesn't use [0] like that anyway, instead using the get operator.

    Using -c

    You could also use the -c option to execute a small fragment like -c"/attr (pageNumber) def".