Adding extra margin to a PDF

I wanted to add my own little margin notes to any PDF file (using LaTeX and the multistamp feature of PDFTk). However, because the PDF was arbitrary, I could not write on the existing margin. Instead, I had to add an extra margin at the side. But none of the standard tools supports that, and using pypdf and similar toolsets loses the metadata like bookmarks. Here is a quick hack to expand the relevant page boxes:

#!env python2.7

import os
import os.path
import subprocess
import re

# Margin in points.
margin = 150

def addmargin(fn_src, fn_dst):
    fn_tmp = fn_dst + '.tmp'

    subprocess.call(['pdftk', fn_src, 'output', fn_dst, 'uncompress'])

    # We leave rotate pages alone, as they usually contain tables or images.
    rotate = 0
    # We leave Bleed and Art alone. 
    box = re.compile(r'^/(Media|Crop|Trim)Box\s+\[(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\]$')
    rot = re.compile(r'^/Rotate\s+(.+)$')

    infile  = open(fn_dst, 'rb')
    outfile = open(fn_tmp, 'wb')

    # This is a hack, but what the hell.
    for line in infile:
        lr = rot.match(line)
        if lr:
            print line
            rotate = int(lr.group(1))
        elif rotate == 0:
            lm = box.match(line)
            if lm:
                print line
                (btype, bl, bt, br, bb) = lm.groups()
                line = '/%sBox[%s %s %.3f %s]\n' % (btype, bl, bt, float(br) + margin, bb)
        outfile.write(line)

    outfile.close()
    infile.close()

    subprocess.call(['pdftk', fn_tmp, "output", fn_dst, "compress"])
    os.remove(fn_tmp)

if __name__ == '__main__':
    addmargin("in.pdf", "out.pdf")
  

Adding rotation support is left as an exercise for the reader.

I also made a custom version of pdftk to disable scaling of the stamp, because I controlled the stamp PDF in such a way that each page was a perfect fit on the original page. The positions of text elements on the original page were available due to pdftotext -bbox-extended -xmlmeta. The xmlmeta option is not part of the regular PDFTk distribution: We enriched our version of pdftotext (poppler) to have a more complete xml output to do that.