Class: Kitabu::Exporter::Epub

Inherits:
Base
  • Object
show all
Defined in:
lib/kitabu/exporter/epub.rb

Instance Attribute Summary

Attributes inherited from Base

#root_dir, #source

Instance Method Summary collapse

Methods inherited from Base

#config, #copy_directory, export, #handle_error, #initialize, #name, #render_template, #source_list, #spawn_command, #ui

Constructor Details

This class inherits a constructor from Kitabu::Exporter::Base

Instance Method Details

#assetsObject



121
122
123
124
125
126
127
# File 'lib/kitabu/exporter/epub.rb', line 121

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

#copy_images!Object



50
51
52
# File 'lib/kitabu/exporter/epub.rb', line 50

def copy_images!
  copy_directory("output/images", "output/epub/images")
end

#copy_styles!Object



46
47
48
# File 'lib/kitabu/exporter/epub.rb', line 46

def copy_styles!
  copy_directory("output/styles", "output/epub/styles")
end

#cover_imageObject



129
130
131
132
133
134
# File 'lib/kitabu/exporter/epub.rb', line 129

def cover_image
  path =
    Dir[root_dir.join("templates/epub/cover.{jpg,png,gif}").to_s].first

  return path if path && File.exist?(path)
end

#epubObject



18
19
20
# File 'lib/kitabu/exporter/epub.rb', line 18

def epub
  @epub ||= EeePub::Maker.new
end

#epub_pathObject



153
154
155
# File 'lib/kitabu/exporter/epub.rb', line 153

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

#exportObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/kitabu/exporter/epub.rb', line 26

def export
  super
  copy_styles!
  copy_images!
  set_metadata!
  write_sections!
  write_toc!

  epub.files    sections.map(&:filepath) + assets
  epub.nav      navigation
  epub.toc_page toc_path

  epub.save(epub_path)

  true
rescue StandardError => error
  handle_error(error)
  false
end

#htmlObject



22
23
24
# File 'lib/kitabu/exporter/epub.rb', line 22

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

#html_pathObject



149
150
151
# File 'lib/kitabu/exporter/epub.rb', line 149

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


136
137
138
139
140
141
142
143
# File 'lib/kitabu/exporter/epub.rb', line 136

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

#render_chapter(content) ⇒ Object



116
117
118
119
# File 'lib/kitabu/exporter/epub.rb', line 116

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

#sectionsObject



6
7
8
9
10
11
12
13
14
15
16
# File 'lib/kitabu/exporter/epub.rb', line 6

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

#set_metadata!Object



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/kitabu/exporter/epub.rb', line 54

def set_metadata!
  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]
  epub.cover_page   cover_image if cover_image && File.exist?(cover_image)
end

#template_pathObject



145
146
147
# File 'lib/kitabu/exporter/epub.rb', line 145

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

#tmp_dirObject



157
158
159
# File 'lib/kitabu/exporter/epub.rb', line 157

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

#toc_pathObject



161
162
163
# File 'lib/kitabu/exporter/epub.rb', line 161

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

#write_sections!Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/kitabu/exporter/epub.rb', line 74

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



66
67
68
69
70
71
72
# File 'lib/kitabu/exporter/epub.rb', line 66

def write_toc!
  toc = TOC::Epub.new(navigation)

  File.open(toc_path, "w") do |file|
    file << toc.to_html
  end
end