Adding Page Numbers to PDF Files
(or: Lambda, the Ultimate PDF Programming Language)
2006-08-02 ::
/programming/lisp
(Cue Mission
Impossible theme)
Your task is to combine a number of
Adobe PDF files into one and to
number all pages consecutively. As additional obstacle, not all
pages have the same page size and some pages already contain old
page numbers, in various places.
Your time starts
running... now!
I glued together multiple PDFs with PDFTK, but did not find a suitable tool to remove page numbers and draw new ones on the resulting file. Until I looked at Marc Battyani's neat cl-pdf library, which seemed to have all the ingredients needed. The initial version was developed completely in the REPL, basically in no time, which means I could report back to my boss in time for him to leave and catch the train. Instant local wizard status awarded, too.
Some small amount of glue code later (pdf-page-numbers.lisp), removing the old centered page numbers at coordinates (308,148) and adding new ones in the same place is now as easy as:
(pdf:with-existing-document (#p"old.pdf")
(with-existing-pages ()
(pdf:insert-original-page-content)
(clear-page-numbers 308 148 :font "Times-Bold" :font-size 10.0)
(page-numbers 308 148 :font "Times-Bold" :font-size 10.0))
(pdf:write-document #p"new.pdf"))
Of course, this looks like it could be packaged into a nice function as well. However, in real life we have to deal with all kinds of nastiness (see above) which would render such a function not very useful. I used the following snippet eventually:
(pdf:with-existing-document (#p"/tmp/old.pdf")
(with-existing-pages (:range (iota 94 :start 6)
:numbering (enumerate :from 1))
(pdf:insert-original-page-content)
(let ((x (if (evenp *page-number*) 135 480))
(y (if (<= 50 *page-number* 64) 104 149)))
(clear-page-numbers 308 y :font "Times-Roman" :font-size 10.0)
(page-numbers x y :font "Times-Bold" :font-size 10.0 :justify t)))
(pdf:write-document #p"/tmp/new.pdf"))




