Class: Bookmaker::Parser::Epub

Inherits:
Base
  • Object
show all
Defined in:
lib/bookmaker/parser/epub.rb

Instance Attribute Summary

Attributes inherited from Base

#root_dir, #source

Instance Method Summary collapse

Methods inherited from Base

#config, #entries, #initialize, #name, parse, #read_content, #render_template, #spawn_command

Constructor Details

This class inherits a constructor from Bookmaker::Parser::Base

Instance Method Details

#assetsObject



97
98
99
100
101
102
103
# File 'lib/bookmaker/parser/epub.rb', line 97

def assets
  @assets ||= begin
    assets = Dir[root_dir.join("templates/epub/*.css")]
    assets += Dir[root_dir.join("images/**/*.{jpg,png,gif}")]
    assets
  end
end

#cover_imageObject



105
106
107
108
# File 'lib/bookmaker/parser/epub.rb', line 105

def cover_image
  path = Dir[root_dir.join("images/cover.{jpg,png,gif}").to_s].first
  return File.basename(path) if path && File.exist?(path)
end

#cover_pageObject



41
42
43
# File 'lib/bookmaker/parser/epub.rb', line 41

def cover_page
  Dir[root_dir.join("templates/epub/cover.html")]
end

#epubObject



14
# File 'lib/bookmaker/parser/epub.rb', line 14

def epub; @epub ||= EeePub.make ;end

#epub_pathObject



127
128
129
# File 'lib/bookmaker/parser/epub.rb', line 127

def epub_path
  root_dir.join("output/#{name}.epub")
end

#htmlObject



15
# File 'lib/bookmaker/parser/epub.rb', line 15

def html; @html ||= Nokogiri::HTML(html_path.read); end

#html_pathObject



123
124
125
# File 'lib/bookmaker/parser/epub.rb', line 123

def html_path
  root_dir.join("output/#{name}.html")
end


110
111
112
113
114
115
116
117
# File 'lib/bookmaker/parser/epub.rb', line 110

def navigation
  sections.map do |section|
    {
      :label => section.html.css("h2:first-of-type").text,
      :content => section.filename
    }
  end
end

#parseObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/bookmaker/parser/epub.rb', line 16

def parse
  puts "-- Exporting EPUB"
  epub.title        config["title"]
  epub.language     config["language"]
  epub.creator      config["authors"].to_sentence
  epub.publisher    config["publisher"]
  epub.date         config["published_at"]
  epub.uid          config["uid"]
  epub.identifier   config["identifier"]["id"], :scheme => config["identifier"]["type"]
  if cover_image.nil?
    puts "   - Consider adding a cover images in /images."
  else
    epub.cover      cover_image
  end
  write_sections!
  write_toc!
  epub.files    cover_page + sections.map(&:filepath) + assets
  epub.nav      navigation
  
  epub.save(epub_path)
  true
rescue Exception
  p $!, $@
  false
end

#render_chapter(content) ⇒ Object



92
93
94
95
# File 'lib/bookmaker/parser/epub.rb', line 92

def render_chapter(content)
  locals = config.merge(:content => content)
  render_template(template_path, locals)
end

#sectionsObject



4
5
6
7
8
9
10
11
12
13
# File 'lib/bookmaker/parser/epub.rb', line 4

def sections
  @sections ||= html.css("div.chapter").each_with_index.map do |chapter, index|
    OpenStruct.new({
      :index    => index,
      :filename => "section_#{index}.html",
      :filepath => tmp_dir.join("section_#{index}.html").to_s,
      :html     => Nokogiri::HTML(chapter.inner_html)
    })
  end
end

#template_pathObject



119
120
121
# File 'lib/bookmaker/parser/epub.rb', line 119

def template_path
  root_dir.join("templates/epub/page.erb")
end

#tmp_dirObject



131
132
133
# File 'lib/bookmaker/parser/epub.rb', line 131

def tmp_dir
  root_dir.join("output/tmp")
end

#toc_pathObject



135
136
137
# File 'lib/bookmaker/parser/epub.rb', line 135

def toc_path
  tmp_dir.join("toc.html")
end

#write_sections!Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/bookmaker/parser/epub.rb', line 51

def write_sections!
  # First we need to get all ids, which are used as
  # the anchor target.
  links = sections.inject({}) do |buffer, section|
    section.html.css("[id]").each do |element|
      anchor = "##{element["id"]}"
      buffer[anchor] = "#{section.filename}#{anchor}"
    end

    buffer
  end

  # Then we can normalize all links and
  # manipulate other paths.
  #
  sections.each do |section|
    section.html.css("a[href^='#']").each do |link|
      href = link["href"]
      link.set_attribute("href", links.fetch(href, href))
    end

    # Replace all srcs.
    #
    section.html.css("[src]").each do |element|
      src = File.basename(element["src"]).gsub(/\.svg$/, ".png")
      element.set_attribute("src", src)
      element.set_attribute("alt", "")
      element.node_name = "img"
    end

    FileUtils.mkdir_p(tmp_dir)

    # Save file to disk.
    #
    File.open(section.filepath, "w") do |file|
      body = section.html.css("body").to_xhtml.gsub(%r[<body>(.*?)</body>]m, "\\1")
      file << render_chapter(body)
    end
  end
end

#write_toc!Object



44
45
46
47
48
49
# File 'lib/bookmaker/parser/epub.rb', line 44

def write_toc!
  toc = TOC::Epub.new(navigation)
  File.open(toc_path, "w") do |file|
    file << toc.to_html
  end
end