class Epuber::Compiler::NavGenerator

Constants

LANDMARKS_MAP

resource page www.idpf.org/epub/301/spec/epub-contentdocs.html#sec-xhtml-nav-def-types-landmarks

NCX_NAMESPACES
XHTML_IBOOKS_NAMESPACES
XHTML_NAMESPACES

Public Instance Methods

generate_nav() click to toggle source

Generates XML for toc document, the structure differs depend on epub_version

Use method to_s to generate nice string from XML document

@return [Nokogiri::XML::Document]

# File lib/epuber/compiler/nav_generator.rb, line 40
def generate_nav
  generate_xml do
    if @target.epub_version >= 3
      generate_xhtml_content
    else
      generate_ncx_content
    end
  end
end

Private Instance Methods

contains_item_with_title(toc_items) click to toggle source
# File lib/epuber/compiler/nav_generator.rb, line 132
def contains_item_with_title(toc_items)
  toc_items.any? { |a| a.title || contains_item_with_title(a.sub_items) }
end
generate_ncx_content() click to toggle source
# File lib/epuber/compiler/nav_generator.rb, line 89
def generate_ncx_content
  @xml.doc.create_internal_subset('ncx',
                                  '-//NISO//DTD ncx 2005-1//EN',
                                  'http://www.daisy.org/z3986/2005/ncx-2005-1.dtd')

  @xml.ncx(nav_namespaces, version: '2005-1') do
    # head
    @xml.head do
      @xml.meta(name: 'dtb:uid', content: @target.identifier || "urn:isbn:#{@target.isbn}")
    end

    # title
    @xml.docTitle do
      @xml.text_(@book.title)
    end

    @nav_nav_point_id = 1

    # nav map
    @xml.navMap do
      visit_toc_items(@target.root_toc.sub_items)
    end
  end
end
generate_xhtml_content() click to toggle source

@return nil

# File lib/epuber/compiler/nav_generator.rb, line 67
def generate_xhtml_content
  @xml.doc.create_internal_subset('html', nil, nil)
  @xml.html(nav_namespaces) do
    @xml.head do
      @xml.title_(@book.title)
    end
    @xml.body do
      # toc
      @xml.nav('epub:type' => 'toc') do
        visit_toc_items(@target.root_toc.sub_items)
      end

      # landmarks
      @xml.nav('epub:type' => 'landmarks') do
        @xml.ol do
          landmarks_visit_toc_item(@target.root_toc)
        end
      end
    end
  end
end
landmarks_visit_toc_item(toc_item) click to toggle source

@param [Epuber::Book::TocItem] toc_item

# File lib/epuber/compiler/nav_generator.rb, line 178
def landmarks_visit_toc_item(toc_item)
  landmarks = toc_item.landmarks
  landmarks.each do |landmark|
    dict = LANDMARKS_MAP[landmark]

    raise "Unknown landmark `#{landmark.inspect}`, supported are #{LANDMARKS_MAP.keys}" if dict.nil?

    types = Array(dict[:type])


    # filter out ibooks specific when the target is not ibooks
    types = types.reject { |type| type.to_s.start_with?('ibooks:') } unless @target.ibooks?

    result_file_path = pretty_path_for_toc_item(toc_item, fragment: false)

    types.each do |type|
      @xml.li do
        @xml.a(dict[:text], 'epub:type' => type, 'href' => result_file_path)
      end
    end
  end

  landmarks_visit_toc_items(toc_item.sub_items)
end
landmarks_visit_toc_items(toc_items) click to toggle source

@param [Array<Epuber::Book::TocItem>] toc_items

# File lib/epuber/compiler/nav_generator.rb, line 170
def landmarks_visit_toc_items(toc_items)
  toc_items.each do |child_item|
    landmarks_visit_toc_item(child_item)
  end
end
nav_namespaces() click to toggle source

@return [Hash<String, String>]

visit_toc_item(toc_item) click to toggle source

@param [Epuber::Book::TocItem] toc_item

# File lib/epuber/compiler/nav_generator.rb, line 138
def visit_toc_item(toc_item)
  result_file_path = pretty_path_for_toc_item(toc_item)

  if toc_item.title.nil?
    visit_toc_items(toc_item.sub_items)
  elsif @target.epub_version >= 3
    @xml.li do
      node_builder = @xml.a(href: result_file_path)
      node_builder.node.inner_html = toc_item.title

      visit_toc_items(toc_item.sub_items)
    end
  else
    @xml.navPoint(id: "navPoint_#{@nav_nav_point_id}") do
      @xml.navLabel do
        node_builder = @xml.text_
        node_builder.node.inner_html = toc_item.title
      end
      @xml.content(src: result_file_path)

      @nav_nav_point_id += 1

      visit_toc_items(toc_item.sub_items)
    end
  end
end
visit_toc_items(toc_items) click to toggle source

@param [Array<Epuber::Book::TocItem>] toc_items

# File lib/epuber/compiler/nav_generator.rb, line 116
def visit_toc_items(toc_items)
  iterate_lambda = lambda do
    toc_items.each do |child_item|
      visit_toc_item(child_item)
    end
  end

  if @target.epub_version >= 3 && toc_items.length.positive? && contains_item_with_title(toc_items)
    @xml.ol do
      iterate_lambda.call
    end
  else
    iterate_lambda.call
  end
end