Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PdfFileMerger.addBookmark() should return the newly added bookmark #40

Closed
mikaraunio opened this issue Nov 20, 2013 · 2 comments
Closed

Comments

@mikaraunio
Copy link

PdfFileWriter.addBookmark() returns the newly added bookmark, so it can be used as the parent in subsequent addBookmark() calls in order to create nested bookmarks.

For consistency, PdfFileMerger.addBookmark() should function similarly, however it does not, as it doesn't return anything, thus making it impossible to create nested bookmarks with PdfFileMerger.

@mstamy2
Copy link
Collaborator

mstamy2 commented Nov 20, 2013

Hello,
Thanks for pointing this out. It is odd that addBookmark() is written so differently for PdfFileMerger. Both methods seem to work fine, however. In commit 416eac9 I added a return so that nested bookmarks can be created using PdfFileMerger. Now both methods should function the same.

@mstamy2 mstamy2 closed this as completed Nov 23, 2013
@mikaraunio
Copy link
Author

Hi,
Thanks. I tried creating nested bookmarks with commit 416eac9 applied, but there seems to be something weird going on: nesting bookmarks under the first top-level bookmark works as intended, but trying to add a child to any subsequent top-level bookmark results in a TypeError in findBookmark().

Sample code that concatenates a number of one-page PDFs and creates a two-level bookmark structure:

from PyPDF2 import PdfFileMerger

merged = PdfFileMerger()

s = open("1.pdf", "rb")
merged.append(s, pages = (0,1))
parent = merged.addBookmark("One", 0, None)
s.close()

s = open("2.pdf", "rb")
merged.append(s, pages = (0,1))
merged.addBookmark("One / A", 1, parent)
s.close()

s = open("3.pdf", "rb")
merged.append(s, pages = (0,1))
merged.addBookmark("One / B", 2, parent)
s.close()

s = open("4.pdf", "rb")
merged.append(s, pages = (0,1))
parent = merged.addBookmark("Two", 3, None)
s.close()

s = open("5.pdf", "rb")
merged.append(s, pages = (0,1))
merged.addBookmark("Two / A", 4, parent)
s.close()

d = open("out_pdfmerge.pdf", "wb")
merged.write(d)
d.close()

Resulting traceback triggered by merged.addBookmark("Two / A", 4, parent):

Traceback (most recent call last):
  File "merge.py", line 27, in <module>
    merged.addBookmark("Two / A", 4, parent)
  File "/usr/local/lib/python2.6/dist-packages/PyPDF2/merger.py", line 426, in addBookmark
    iloc = self.findBookmark(parent)
  File "/usr/local/lib/python2.6/dist-packages/PyPDF2/merger.py", line 409, in findBookmark
    if b == bookmark or b['/Title'] == bookmark:
TypeError: list indices must be integers, not str

For comparison, the following equivalent code using PdfFileWriter works fine:

from PyPDF2 import PdfFileWriter, PdfFileReader

output = PdfFileWriter()

s1 = PdfFileReader(open("1.pdf", "rb"))
output.addPage(s1.getPage(0))
parent = output.addBookmark("One", 0, None)

s2 = PdfFileReader(open("2.pdf", "rb"))
output.addPage(s2.getPage(0))
output.addBookmark("One / A", 1, parent)

s3 = PdfFileReader(open("3.pdf", "rb"))
output.addPage(s3.getPage(0))
output.addBookmark("One / B", 2, parent)

s4 = PdfFileReader(open("4.pdf", "rb"))
output.addPage(s4.getPage(0))
parent = output.addBookmark("Two", 3, None)

s5 = PdfFileReader(open("5.pdf", "rb"))
output.addPage(s5.getPage(0))
output.addBookmark("Two / A", 4, parent)

d = open("out_pdfwrite.pdf", "wb")
output.write(d)
d.close()

The reason I'd rather use PdfFileMerger in this particular application is that PdfFileWriter seems to require all source files to remain open until the output file is written, which results in prohibitive memory usage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants