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

Feature/325 #326

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@


# List the ports you want to expose and what to do when they are served. See https://www.gitpod.io/docs/43_config_ports/
ports:
- port: 3000
onOpen: open-preview

# List the start up tasks. You can start them in parallel in multiple terminals. See https://www.gitpod.io/docs/44_config_start_tasks/
tasks:
- init: bundle install
6 changes: 6 additions & 0 deletions lib/pdf/reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@ def pages
end
end

# return named detinations fo the document
def named_destinations
pages.first.named_destinations
end


# returns a single PDF::Reader::Page for the specified page.
# Use this instead of pages method when you need to access just a single
# page
Expand Down
54 changes: 54 additions & 0 deletions lib/pdf/reader/page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,60 @@ def attributes
@attributes
end

# Convenience method to retrieve he named destinations present in the document.
# implemented as port of https://github.com/mstamy2/PyPDF2/blob/18a2627adac13124d4122c8b92aaa863ccfb8c29/PyPDF2/pdf.py#L1350-L1389
def named_destinations( tree = nil, retval = nil)
if retval.nil? # if initial call
retval = {}
tree = root[:Dests] # get dests from Catalog
if tree.nil? # if no global dests
names = root[:Names] # get name tree
if names
dests = @objects.deref(names)[:Dests]
if dests
tree = dests
end
end
end
end

return retval if tree.nil?

kids = @objects.deref(tree)[:Kids] # recurse down the tree
if kids
kids.each do |kid|
named_destinations(@objects.deref(kid), retval)
end
end

names = @objects.deref(tree)[:Names]
if names
(0...names.length).step(2) do |i|
key = @objects.deref(names[i])
val = @objects.deref(names[i+1])
val_d = val[:D]
if val_d
dest = _build_destination(key, val_d)
retval[key] = dest
else
# this shoud not happen
# require 'pry';binding.pry
end
end
end

retval
end

private def _build_destination(title, array)
page, typ = array[0..2]
array = array[2..-1]
typ = @objects.deref(typ)

{page: page, typ: typ}
end


# Convenience method to identify the page's orientation.
#
def orientation
Expand Down
20 changes: 20 additions & 0 deletions spec/integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,26 @@
end
end

context "extracts named destinations p" do
let(:filename){pdf_spec_file("pdflatex")}

it "extracts named destinations correctly" do
PDF::Reader.open(filename) do |reader|
named_destinations = reader.named_destinations
expect(named_destinations.count).to eql(90)
expect(named_destinations.keys.first).to eql('Doc-Start')
end
end

it "extracts named destinations correctly via page" do
PDF::Reader.open(filename) do |reader|
named_destinations = reader.page(10).named_destinations
expect(named_destinations.count).to eql(90)
expect(named_destinations.keys.first).to eql('Doc-Start')
end
end
end

context "encrypted_version1_revision2_40bit_rc4_user_pass_apples" do
let(:filename) { pdf_spec_file("encrypted_version1_revision2_40bit_rc4_user_pass_apples") }

Expand Down