Skip to content

Commit

Permalink
MAINT: Make PdfFileMerger.addBookmark() behave life PdfFileWriters' (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
khalida authored Apr 24, 2022
1 parent 6729b80 commit 07848e5
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 19 deletions.
70 changes: 52 additions & 18 deletions PyPDF2/merger.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,36 +498,70 @@ def findBookmark(self, bookmark, root=None):

return None

def addBookmark(self, title, pagenum, parent=None):

def addBookmark(self, title, pagenum, parent=None, color=None, bold=False, italic=False, fit='/Fit', *args):
"""
Add a bookmark to this PDF file.
:param str title: Title to use for this bookmark.
:param int pagenum: Page number this bookmark will point to.
:param parent: A reference to a parent bookmark to create nested
bookmarks.
:param tuple color: Color of the bookmark as a red, green, blue tuple
from 0.0 to 1.0
:param bool bold: Bookmark is bold
:param bool italic: Bookmark is italic
:param str fit: The fit of the destination page. See
:meth:`addLink()<addLin>` for details.
"""
if parent is None:
iloc = [len(self.bookmarks)-1]
elif isinstance(parent, list):
iloc = parent
if len(self.output.getObject(self.output._pages)['/Kids']) > 0:
pageRef = self.output.getObject(self.output._pages)['/Kids'][pagenum]
else:
iloc = self.findBookmark(parent)
pageRef = self.output.getObject(self.output._pages)

dest = Bookmark(TextStringObject(title), NumberObject(pagenum), NameObject('/FitH'), NumberObject(826))
action = DictionaryObject()
zoomArgs = []
for a in args:
if a is not None:
zoomArgs.append(NumberObject(a))
else:
zoomArgs.append(NullObject())
dest = Destination(NameObject("/"+title + " bookmark"), pageRef, NameObject(fit), *zoomArgs)
destArray = dest.getDestArray()
action.update({
NameObject('/D') : destArray,
NameObject('/S') : NameObject('/GoTo')
})
actionRef = self.output._addObject(action)

outlineRef = self.output.getOutlineRoot()

if parent is None:
self.bookmarks.append(dest)
else:
bmparent = self.bookmarks
for i in iloc[:-1]:
bmparent = bmparent[i]
npos = iloc[-1]+1
if npos < len(bmparent) and isinstance(bmparent[npos], list):
bmparent[npos].append(dest)
else:
bmparent.insert(npos, [dest])
return dest
parent = outlineRef

bookmark = TreeObject()

bookmark.update({
NameObject('/A'): actionRef,
NameObject('/Title'): createStringObject(title),
})

if color is not None:
bookmark.update({NameObject('/C'): ArrayObject([FloatObject(c) for c in color])})

format = 0
if italic:
format += 1
if bold:
format += 2
if format:
bookmark.update({NameObject('/F'): NumberObject(format)})

bookmarkRef = self.output._addObject(bookmark)
parent = parent.getObject()
parent.addChild(bookmarkRef, self.output)

return bookmarkRef

def addNamedDestination(self, title, pagenum):
"""
Expand Down
2 changes: 1 addition & 1 deletion Tests/test_merger.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def test_merge():
# Check if bookmarks are correct
pdfr = PyPDF2.PdfFileReader(tmp_path)
assert [el.title for el in pdfr.getOutlines() if isinstance(el, Destination)] == [
"A bookmark",
"Foo",
"Bar",
"Baz",
Expand All @@ -61,7 +62,6 @@ def test_merge():
"Bar",
"Baz",
"True",
"A bookmark",
]

# Clean up
Expand Down

0 comments on commit 07848e5

Please sign in to comment.