Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create outlines/TOC for existing PDF in Python

I'm using pyPdf to merge several PDF files into one. This works great, but I would also need to add a table of contents/outlines/bookmarks to the PDF file that is generated.

pyPdf seems to have only read support for outlines. Reportlab would allow me to create them, but the opensource version does not support loading PDF files, so that doesn't work to add outlines to an existing file.

Is there any way I can add outlines to an existing PDF using Python, or any library that would allow that?

like image 890
jphoude Avatar asked May 27 '11 20:05

jphoude


People also ask

How do you create an outline on a PDF?

3 Easy Ways to Create an Outline in PDF Reader ProClick the Outline icon in the left panel -> right-click and tap Add Item to add an outline. Option 3: Select the field you want to add an outline to -> right-click and tap Add Outline Item to add an outline.


3 Answers

https://github.com/yutayamamoto/pdfoutline I made a python library just for adding an outline to an existing PDF file.

like image 61
Yuta Avatar answered Oct 05 '22 23:10

Yuta


It looks like PyPDF2 can do the job. See the addBookmark method in the documentation: https://pythonhosted.org/PyPDF2/PdfFileMerger.html

like image 45
Watusimoto Avatar answered Oct 06 '22 01:10

Watusimoto


We had a similar problem in WeasyPrint: cairo produces the PDF files but does not support bookmarks/outlines or hyperlinks. In the end we bit the bullet, read the PDF spec, and did it ourselves.

WeasyPrint’s pdf.py has a simple PDF parser and writer that can add/override PDF "objects" to an existing documents. It uses the PDF "update" mechanism and only append at the end of the file.

This module was made for internal use only but I’m open to refactoring it to make it easier to use in other projects.

However the parser takes a few shortcuts and can not parse all valid PDF files. It may need to be adapted if PyPDF’s output is not as nice as cairo’s. From the module’s docstring:

Rather than trying to parse any valid PDF, we make some assumptions that hold for cairo in order to simplify the code:

  • All newlines are '\n', not '\r' or '\r\n'
  • Except for number 0 (which is always free) there is no "free" object.
  • Most white space separators are made of a single 0x20 space.
  • Indirect dictionary objects do not contain '>>' at the start of a line except to mark the end of the object, followed by 'endobj'. (In other words, '>>' markers for sub-dictionaries are indented.)
  • The Page Tree is flat: all kids of the root page node are page objects, not page tree nodes.
like image 35
Simon Sapin Avatar answered Oct 06 '22 00:10

Simon Sapin