Skip to content

Commit

Permalink
Resolves HELIO-2059: Gabii TOC link to last page
Browse files Browse the repository at this point in the history
  • Loading branch information
gkostin1966 committed Aug 13, 2018
1 parent b219058 commit abf9823
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 143 deletions.
3 changes: 3 additions & 0 deletions config/environments/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
config.consider_all_requests_local = true
config.action_controller.perform_caching = false

# Rails.cache should never cache!
config.cache_store = :null_store

# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false

Expand Down
4 changes: 1 addition & 3 deletions lib/e_pub/rendition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ def sections
next unless /toc/i.match?(toc.id)
toc.headers.each do |header|
next if header.text.blank?
next if /.*#.*/.match?(header.href)
idref, index = @unmarshaller_rootfile.content.idref_with_index_from_href(header.href)
args = {
title: header.text,
depth: header.depth,
cfi: "/6/#{index * 2}[#{idref}]!",
# Currently only fixed layout epubs can have downloadable sections.
# For reflowable/non-page-image epubs, we'll need a different process,
# probably something like headless-chrome.
downloadable: @publication.downloadable?,
unmarshaller_chapter: @unmarshaller_rootfile.content.chapter_from_title(header.text)
}
Expand Down
67 changes: 54 additions & 13 deletions lib/e_pub/unmarshaller/content.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,17 @@ def self.null_object
# Instance Methods

def idref_with_index_from_href(href)
idref = ''
@content_doc.xpath(".//manifest/item").each do |item|
next unless /#{href}/.match?(item.attribute('href').value)
idref = item.attribute('id').value
break
end
index = 0
@content_doc.xpath(".//spine/itemref").each do |itemref|
index += 1
next unless idref.to_s == itemref.attribute('idref').value
break
end
[idref, index]
idref = href_idref[href]
idref ||= base_href_idref[href]
idref ||= up_one_href_idref[href]
index = idref_index[idref]
return [idref, index] if idref.present? && index.positive?
# match_data = /(^.*)(#.*)/.match(href)
# return ['', 0] unless match_data
# idref = href_idref[match_data[1]]
# index = idref_index[idref]
# return [idref, index] if idref.present? && index.positive?
['', 0]
end

def chapter_from_title(title)
Expand Down Expand Up @@ -78,6 +76,49 @@ def initialize(rootfile, full_path)
def full_dir
@full_dir ||= File.dirname(@full_path)
end

def href_idref
return @href_idref unless @href_idref.nil?
@href_idref = {}
@content_doc.xpath(".//manifest/item").each do |item|
href = item.attribute('href').value
idref = item.attribute('id').value
@href_idref[href] = idref if href.present? && idref.present?
end
@href_idref
end

def base_href_idref
return @base_href_idref unless @base_href_idref.nil?
@base_href_idref = {}
href_idref.each do |href, idref|
base_href = File.basename(href)
@base_href_idref[base_href] = idref
end
@base_href_idref
end

def up_one_href_idref
return @up_one_href_idref unless @up_one_href_idref.nil?
@up_one_href_idref = {}
href_idref.each do |href, idref|
up_one_href = "../#{href}"
@up_one_href_idref[up_one_href] = idref
end
@up_one_href_idref
end

def idref_index
return @idref_index unless @idref_index.nil?
@idref_index = {}
index = 0
@content_doc.xpath(".//spine/itemref").each do |itemref|
idref = itemref.attribute('idref').value
index += 1
@idref_index[idref] = index if idref.present?
end
@idref_index
end
end

class ContentNullObject < Content
Expand Down
2 changes: 1 addition & 1 deletion lib/spec/e_pub/unmarshaller/chapter_list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
subject { described_class.from_content_chapter_list_full_path(content, full_path) }

let(:content) { double('content') }
let(:full_path) { double('manifest item chapter list href') }
let(:full_path) { double('full path') }

it { is_expected.to be_an_instance_of(EPub::Unmarshaller::ChapterListNullObject) }

Expand Down
122 changes: 64 additions & 58 deletions lib/spec/e_pub/unmarshaller/container_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,75 +16,81 @@
describe '#from_root_path' do
subject { described_class.from_root_path(root_path) }

let(:root_path) { double('root_path', to_str: 'root_path') }
let(:root_path) { double('root_path') }

it { is_expected.to be_an_instance_of(EPub::Unmarshaller::ContainerNullObject) }

context 'Root Path' do
before { allow(root_path).to receive(:instance_of?).with(String).and_return(true) }
context 'Empty String' do
let(:root_path) { '' }

it { is_expected.to be_an_instance_of(EPub::Unmarshaller::ContainerNullObject) }

context 'Directory' do
before { allow(Dir).to receive(:exist?).with(root_path).and_return(true) }

it { is_expected.to be_an_instance_of(described_class) }
it { expect(subject.root_path).to be root_path }
it { expect(subject.rootfiles).to be_empty }

context 'META-INF/container.xml exist' do
before { allow(File).to receive(:open).with(File.join(root_path, 'META-INF/container.xml')).and_return(container_xml) }

context 'no rootfile' do
let(:container_xml) do
<<-XML
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container"
xmlns:rendition="http://www.idpf.org/2013/rendition"
version="1.0">
<rootfiles>
</rootfiles>
</container>
XML
end
context 'Root Path' do
let(:root_path) { 'root_path' }

it { is_expected.to be_an_instance_of(described_class) }
it { expect(subject.rootfiles).to be_empty }
end
it { is_expected.to be_an_instance_of(EPub::Unmarshaller::ContainerNullObject) }

context 'Directory' do
before { allow(Dir).to receive(:exist?).with(root_path).and_return(true) }

it { is_expected.to be_an_instance_of(described_class) }
it { expect(subject.root_path).to be root_path }
it { expect(subject.rootfiles).to be_empty }

context 'META-INF/container.xml exist' do
before { allow(File).to receive(:open).with(File.join(root_path, 'META-INF/container.xml')).and_return(container_xml) }

context 'single rootfile' do
let(:container_xml) do
<<-XML
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container"
xmlns:rendition="http://www.idpf.org/2013/rendition"
version="1.0">
<rootfiles>
<rootfile>
</rootfile>
</rootfiles>
</container>
XML
context 'no rootfile' do
let(:container_xml) do
<<-XML
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container"
xmlns:rendition="http://www.idpf.org/2013/rendition"
version="1.0">
<rootfiles>
</rootfiles>
</container>
XML
end

it { is_expected.to be_an_instance_of(described_class) }
it { expect(subject.rootfiles).to be_empty }
end

context 'single rootfile' do
let(:container_xml) do
<<-XML
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container"
xmlns:rendition="http://www.idpf.org/2013/rendition"
version="1.0">
<rootfiles>
<rootfile>
</rootfile>
</rootfiles>
</container>
XML
end
it { is_expected.to be_an_instance_of(described_class) }
it { expect(subject.rootfiles).to contain_exactly instance_of(EPub::Unmarshaller::Rootfile) }
end
it { is_expected.to be_an_instance_of(described_class) }
it { expect(subject.rootfiles).to contain_exactly instance_of(EPub::Unmarshaller::Rootfile) }
end

context 'multiple rootfiles' do
let(:container_xml) do
<<-XML
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container"
xmlns:rendition="http://www.idpf.org/2013/rendition"
version="1.0">
<rootfiles>
<rootfile>
</rootfile>
<rootfile>
</rootfile>
</rootfiles>
</container>
XML
context 'multiple rootfiles' do
let(:container_xml) do
<<-XML
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container"
xmlns:rendition="http://www.idpf.org/2013/rendition"
version="1.0">
<rootfiles>
<rootfile>
</rootfile>
<rootfile>
</rootfile>
</rootfiles>
</container>
XML
end
it { is_expected.to be_an_instance_of(described_class) }
it { expect(subject.rootfiles).to contain_exactly(instance_of(EPub::Unmarshaller::Rootfile), instance_of(EPub::Unmarshaller::Rootfile)) }
end
it { is_expected.to be_an_instance_of(described_class) }
it { expect(subject.rootfiles).to contain_exactly(instance_of(EPub::Unmarshaller::Rootfile), instance_of(EPub::Unmarshaller::Rootfile)) }
end
end
end
Expand Down
Loading

0 comments on commit abf9823

Please sign in to comment.