1

I do not find anything related in the documentation: https://www.ghostscript.com/doc/current/Use.htm

I did find a somewhat related example for inserting watermarks on each page, so it seems like it may be possible.

Is it possible in Ghostscript to add watermark to every page in PDF

However, it's not clear from that example how to insert Javascript.

Dave Molinero
  • 474
  • 1
  • 4
  • 13

2 Answers2

3

Ghostscript's pdfwrite device supports many of the PostScript pdfmark operations (but not all). No there's no documentation on which ones are supported, but broadly speaking everything except the logical structure ones.

The pdfmark reference (available from the Adobe web site, somewhere.....) describes the pdfmark syntax and in combination with the PDF Reference Manual (or the ISO specification) we can see that JavaScript is restricted to Widget Annotations. There's even en example in the pdfmark reference, so I did the obvious, and tried it. The following code does 'something'. I presume its correct but have no way of knowing for sure (that is, the PDF stuff is correct; I have no idea about JavaScript):

[
/Subtype /Widget
/Rect [216 647 361 684]
/F 4
/T (SL Text)
/FT /Tx
/DA (/Helv 14 Tf 0 0 1 rg)
/V (5)
/AA <<
  /K <<
    /S /JavaScript
    /JS (AFNumber_Keystroke\(2, 0, 0, 0, "$", true\);)
  >>
  /F <<
    /S /JavaScript
    /JS (AFNumber_Format\(2, 0, 0, 0, "$", true\);)
  >>
>> /ANN pdfmark

showpage

That draws a light blue rectangle, when you mouse over it draws a black border, when you click it, it displays the value 5. Replace the 5 with a numeric value and press return and it becomes $value.00 on a blue background. Kind of looks right.

Note that the example you linked to above won't help you, that's to do with pure PostScript. In order to add an annotation like this you will need to:

  1. Be using the Ghostscript pdfwrite device
  2. create a command line where you first process the existing PDF file
  3. On the command line after processing the existing PDF file, execute PostScript (using a pdfmark, as above but not the showpage, just the pdfmark section) to define the annotation. You will need to use the -c (introduce PostScript) and -f (end PostScript) switches to do this.
KenS
  • 30,202
  • 3
  • 34
  • 51
  • What do all of the slashed letters mean? I can't seem to find documentation on those. For example: `/AA`, `/K`, `/S`, `/F`? It seems a bit random. – Pete Sep 24 '19 at 15:42
  • They are keys in PDF (or PostScript) terminology and they are defined in the PDF Reference Manual (or ISO specification if you have that). See "Widget Annotations" on page 640 of the PDF 1.7 Reference Manual for details of the keys and their valid values. /F is the Flags value for the annotation (page 608) , /K (page 651) is the Keystroke trigger action in an Alternate Actions (/AA, p648, Trigger events) dictionary and so on. If you hope to use this stuff I'm afraid you are going to have to read and comprehend the specification. – KenS Sep 24 '19 at 16:39
  • Thanks @KenS for the detailed answer. The Widget Annotations are a very good starting point. – Dave Molinero Sep 24 '19 at 16:49
  • @KenS Thanks for the info; half the battle is figuring out which documentation I need to look at. For future readers (including myself), the mentioned reference manual is here: https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdf_reference_archive/pdf_reference_1-7.pdf – Pete Sep 24 '19 at 17:48
  • For future readers: Adobe rearrange their site a *lot*, so the above link may or may not be valid in the future. Google search will find the PDF reference manual, though. – chrisl Oct 01 '19 at 10:08
1

If you want to execute JavaScript on document load you can do it like this (thanks to this useful PDF primer).

[ /_objdef {MyAlert} /type /dict /OBJ pdfmark
[ {MyAlert} << /JavaScript << /Names [ (MyAlertCode) << /S /JavaScript
/JS (app.alert\("Hello world 1."\);app.alert\("Hello world 2."\);) >> ]
>> >>
/PUT pdfmark
[ {Catalog} << /Names {MyAlert} >> /PUT pdfmark

Full steps to reproduce would be:

  1. Make sure Ghostscript is installed on your computer (the gs command)
  2. Put your source PDF in a folder alongside a postscript (.ps) file that contains the code from above.
  3. cd into that folder
  4. Run: gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=newpdf.pdf myps.ps mypdf.pdf (obviously replace myps.ps and mypdf.pdf with your actual file names).
  5. Open newpdf.pdf to verify that it worked!

Other tips:

  • Acrobat doesn't use exactly the same syntax as you might be used to in traditional web development (hence app.alert in the example rather than the traditional alert().) Don't just assume the function you're trying to use exists.
  • You'll need to use backslashes to escape parenthesis in your JavaScript (e.g. app.alert\("Hello World"\)
  • You can set up a Javascript console on Acrobat to help with JS debugging

Resources:

K J
  • 8,045
  • 3
  • 14
  • 36
Pete
  • 7,289
  • 10
  • 39
  • 63