epubber 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a6f2cfae818d4167a75a3750def6c2184263f373
4
- data.tar.gz: c6d9fe132755c8af4bd234695ffba0606c8cc34f
3
+ metadata.gz: 1ebe4058b733ff70f76d730d422d3581e9b81fa3
4
+ data.tar.gz: ab4bf44f7f4b7747f46cb48e78afa63bce32044d
5
5
  SHA512:
6
- metadata.gz: 9f53c2e01f585f86850c09f92a64038312bde8971fc3b5f45ab278725536e872177153fe4bcc9f0d564fadb43f924026e051544a93292ebf16338682c5c09d07
7
- data.tar.gz: bf2bc15b8989e972bb34eacc2bbf7c72eec63db9015a20a4ecad897ac5746e7e5f917a206e9d3652c3215b778fa92ed53b2c959087a160271b642fb35ba16334
6
+ metadata.gz: 37d018c5a57e2a3fe08a504d2070ff0e54ba2ab1dad98fe84e49a396a8c64bc17e3ca7834addeccfb01591d95c092ad94cf3e4e876094c9fa72c020befcea785
7
+ data.tar.gz: 34f6c36dec17d26f8fb1fc4a69262c1229cf0f2c4743ab4f012a293817b8d2306762a503bf5cff4e15559af8d098c555b9bc960a755cb243af4e17b23cbbef8e
data/.gitignore CHANGED
@@ -12,3 +12,4 @@
12
12
  *.o
13
13
  *.a
14
14
  mkmf.log
15
+ .DS_Store
data/README.md CHANGED
@@ -26,6 +26,10 @@ path = Epubber.generate do |b|
26
26
  b.description 'This is an example EPUB'
27
27
  b.url 'http://my-url.com'
28
28
 
29
+ b.cover do |c|
30
+ c.file File.new('my-image.jpg')
31
+ end
32
+
29
33
  b.introduction do |i|
30
34
  i.content '<p>This is an introduction.</p>'
31
35
  end
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.7"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "minitest"
24
+ spec.add_development_dependency "pry-byebug"
24
25
 
25
26
  spec.add_runtime_dependency "liquid", "~> 3.0"
26
27
  spec.add_runtime_dependency "rubyzip", ">= 1.0.0"
@@ -4,6 +4,7 @@ require 'epubber/generators/toc'
4
4
  require 'epubber/generators/introduction'
5
5
  require 'epubber/generators/static'
6
6
  require 'epubber/generators/endnotes'
7
+ require 'epubber/generators/cover'
7
8
  require 'epubber/services/persistance'
8
9
  require 'epubber/services/compressor'
9
10
 
@@ -22,11 +23,12 @@ class Epubber::Generator
22
23
 
23
24
  def register_generators(params)
24
25
  add_generator Epubber::Generators::Content.new(params)
26
+ add_generator Epubber::Generators::Cover.new(params)
25
27
  add_generator Epubber::Generators::Introduction.new(params)
26
28
  add_generator Epubber::Generators::Toc.new(params)
27
29
  add_generator Epubber::Generators::Chapters.new(params)
28
- add_generator Epubber::Generators::Static.new(params)
29
30
  add_generator Epubber::Generators::Endnotes.new(params)
31
+ add_generator Epubber::Generators::Static.new(params)
30
32
  end
31
33
 
32
34
  def generate
@@ -0,0 +1,15 @@
1
+ require 'epubber/generators/generator'
2
+
3
+ module Epubber::Generators
4
+ class Cover < Generator
5
+ def generate
6
+ # Because this is an optional generator, don't do anything if there's no
7
+ # introduction in the book
8
+ return if book.cover.nil?
9
+
10
+ content = template.parse file: 'OEBPS/Text/cover.xhtml', context: book_context
11
+ persist file: 'OEBPS/Text/cover.xhtml', content: content
12
+ persist file: "OEBPS/Images/#{book_context['book']['cover']['filename']}", content: book_context['book']['cover']['file']
13
+ end
14
+ end
15
+ end
@@ -11,7 +11,7 @@ module Epubber::Generators
11
11
  protected
12
12
 
13
13
  def book_context
14
- { 'book' => book.contextify }
14
+ @book_context ||= { 'book' => book.contextify }
15
15
  end
16
16
 
17
17
  def template
@@ -4,7 +4,7 @@ module Epubber::Generators
4
4
  class Static < Generator
5
5
  def generate
6
6
  files = ['mimetype', 'META-INF/container.xml', 'META-INF/com.apple.ibooks.display-options.xml',
7
- 'OEBPS/Text/cover.xhtml', 'OEBPS/Styles/style.css']
7
+ 'OEBPS/Styles/style.css']
8
8
  files.each do |file|
9
9
  copy file
10
10
  end
@@ -1,16 +1,17 @@
1
1
  require 'securerandom'
2
- require 'epubber/models/model'
3
2
  require 'epubber/models/concerns/has_chapters'
4
3
  require 'epubber/models/concerns/has_introduction'
5
4
  require 'epubber/models/concerns/has_endnotes'
5
+ require 'epubber/models/concerns/has_cover'
6
6
 
7
7
  # Represents a book with it's chapters.
8
8
  module Epubber::Models
9
- class Book < Model
9
+ class Book
10
10
  # Related models and their DSL goodies
11
11
  include Epubber::Models::Concerns::HasChapters
12
12
  include Epubber::Models::Concerns::HasIntroduction
13
13
  include Epubber::Models::Concerns::HasEndnotes
14
+ include Epubber::Models::Concerns::HasCover
14
15
 
15
16
  def initialize
16
17
  @title = not_specified
@@ -70,7 +71,9 @@ module Epubber::Models
70
71
  context["chapters"] = contextified_chapters
71
72
  context["introduction"] = contextified_introduction
72
73
  context["endnotes"] = contextified_endnotes
73
- return context
74
+ context["cover"] = contextified_cover
75
+
76
+ context
74
77
  end
75
78
 
76
79
  protected
@@ -1,8 +1,10 @@
1
- require 'epubber/models/model'
1
+ require 'epubber/models/concerns/has_html'
2
2
 
3
3
  # Represents a book's chapter
4
4
  module Epubber::Models
5
- class Chapter < Model
5
+ class Chapter
6
+ include Epubber::Models::Concerns::HasHTML
7
+
6
8
  def initialize
7
9
  @id = 0
8
10
  @title = 'Not specified'
@@ -1,23 +1,25 @@
1
1
  require 'epubber/models/chapter'
2
2
 
3
- module Epubber::Models::Concerns
4
- module HasChapters
5
- def chapters
6
- @chapters ||= []
7
- end
3
+ module Epubber::Models
4
+ module Concerns
5
+ module HasChapters
6
+ def chapters
7
+ @chapters ||= []
8
+ end
8
9
 
9
- # Add chapter
10
- def chapter
11
- raise 'No block given' unless block_given?
12
- chapter = Epubber::Models::Chapter.new
13
- yield chapter
14
- chapter.id(chapters.count + 1)
15
- chapters << chapter
16
- end
10
+ # Add chapter
11
+ def chapter
12
+ raise 'No block given' unless block_given?
13
+ chapter = Epubber::Models::Chapter.new
14
+ yield chapter
15
+ chapter.id(chapters.count + 1)
16
+ chapters << chapter
17
+ end
17
18
 
18
- def contextified_chapters
19
- chapters.map do |chapter|
20
- chapter.contextify
19
+ def contextified_chapters
20
+ chapters.map do |chapter|
21
+ chapter.contextify
22
+ end
21
23
  end
22
24
  end
23
25
  end
@@ -0,0 +1,19 @@
1
+ require 'epubber/models/cover'
2
+
3
+ module Epubber::Models
4
+ module Concerns
5
+ module HasCover
6
+ def cover(&block)
7
+ @cover ||= nil
8
+ return @cover unless block_given?
9
+ @cover = Epubber::Models::Cover.new
10
+ yield @cover
11
+ end
12
+
13
+ def contextified_cover
14
+ return nil if cover.nil?
15
+ return cover.contextify
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,17 +1,19 @@
1
1
  require 'epubber/models/endnotes'
2
2
 
3
- module Epubber::Models::Concerns
4
- module HasEndnotes
5
- def endnotes
6
- @endnotes ||= nil
7
- return @endnotes unless block_given?
8
- @endnotes = Epubber::Models::Endnotes.new
9
- yield @endnotes
10
- end
3
+ module Epubber::Models
4
+ module Concerns
5
+ module HasEndnotes
6
+ def endnotes
7
+ @endnotes ||= nil
8
+ return @endnotes unless block_given?
9
+ @endnotes = Epubber::Models::Endnotes.new
10
+ yield @endnotes
11
+ end
11
12
 
12
- def contextified_endnotes
13
- return nil if endnotes.nil?
14
- return endnotes.contextify
13
+ def contextified_endnotes
14
+ return nil if endnotes.nil?
15
+ return endnotes.contextify
16
+ end
15
17
  end
16
18
  end
17
19
  end
@@ -0,0 +1,11 @@
1
+ require 'nokogiri'
2
+
3
+ module Epubber::Models
4
+ module Concerns
5
+ module HasHTML
6
+ def clean_html(html)
7
+ Nokogiri::HTML::DocumentFragment.parse(html).to_xhtml
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,17 +1,19 @@
1
1
  require 'epubber/models/introduction'
2
2
 
3
- module Epubber::Models::Concerns
4
- module HasIntroduction
5
- def introduction(&block)
6
- @introduction ||= nil
7
- return @introduction unless block_given?
8
- @introduction = Epubber::Models::Introduction.new
9
- yield @introduction
10
- end
3
+ module Epubber::Models
4
+ module Concerns
5
+ module HasIntroduction
6
+ def introduction(&block)
7
+ @introduction ||= nil
8
+ return @introduction unless block_given?
9
+ @introduction = Epubber::Models::Introduction.new
10
+ yield @introduction
11
+ end
11
12
 
12
- def contextified_introduction
13
- return nil if introduction.nil?
14
- return introduction.contextify
13
+ def contextified_introduction
14
+ return nil if introduction.nil?
15
+ return introduction.contextify
16
+ end
15
17
  end
16
18
  end
17
19
  end
@@ -0,0 +1,34 @@
1
+ # Represents a book's introduction
2
+ module Epubber::Models
3
+ class Cover
4
+ def initialize
5
+ @file = nil
6
+ end
7
+
8
+ def file(image = nil)
9
+ if image
10
+ @file = image
11
+ else
12
+ @file
13
+ end
14
+ end
15
+
16
+ def filename
17
+ File.basename(@file.path)
18
+ end
19
+
20
+ def file_mime
21
+ if /(?:jpg|jpeg)/ =~ filename
22
+ 'image/jpeg'
23
+ elsif /(?:png)/ =~ filename
24
+ 'image/png'
25
+ else
26
+ raise 'Invalid file type: Only JPG and PNG images are allowed.'
27
+ end
28
+ end
29
+
30
+ def contextify
31
+ { 'filename' => filename, 'file' => file, 'file_mime' => file_mime }
32
+ end
33
+ end
34
+ end
@@ -1,8 +1,10 @@
1
- require 'epubber/models/model'
1
+ require 'epubber/models/concerns/has_html'
2
2
 
3
3
  # Represents a book's introduction
4
4
  module Epubber::Models
5
- class Endnotes < Model
5
+ class Endnotes
6
+ include Epubber::Models::Concerns::HasHTML
7
+
6
8
  def initialize
7
9
  @content = '<p>Not specified</p>'
8
10
  end
@@ -1,8 +1,10 @@
1
- require 'epubber/models/model'
1
+ require 'epubber/models/concerns/has_html'
2
2
 
3
3
  # Represents a book's introduction
4
4
  module Epubber::Models
5
- class Introduction < Model
5
+ class Introduction
6
+ include Epubber::Models::Concerns::HasHTML
7
+
6
8
  def initialize
7
9
  @content = '<p>Not specified</p>'
8
10
  end
@@ -20,7 +20,11 @@ module Epubber::Services
20
20
  protected
21
21
 
22
22
  def write(file, content)
23
- File.write path(file), content
23
+ if content.is_a?(File)
24
+ FileUtils.cp content.path, File.dirname(path(file))
25
+ else
26
+ File.write path(file), content
27
+ end
24
28
  end
25
29
 
26
30
  def create_path_for(file)
@@ -1,3 +1,3 @@
1
1
  module Epubber
2
- VERSION = "0.1.5"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -15,7 +15,7 @@
15
15
  </head>
16
16
  <body>
17
17
  <div id="cover-image">
18
- <img alt="[BOOK'S TITLE]" src="../Images/cover.jpg" />
18
+ <img alt="{{ book.title }}" src="../Images/{{ book.cover.filename }}" />
19
19
  </div>
20
20
  </body>
21
21
  </html>
@@ -49,7 +49,7 @@
49
49
  <!-- Language code: http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes -->
50
50
  <dc:language>{{ book.language }}</dc:language>
51
51
 
52
- <meta name="cover" content="[COVER_NAME].jpg" />
52
+ <meta name="cover" content="{{ book.cover.filename }}" />
53
53
 
54
54
  <!-- UUID generator: http://www.famkruithof.net/uuid/uuidgen -->
55
55
  <dc:identifier opf:scheme="UUID">urn:uuid:{{ book.uuid }}</dc:identifier>
@@ -64,10 +64,10 @@
64
64
  -->
65
65
 
66
66
  <manifest>
67
- <!--
68
- <item href="Images/cover.jpg" id="cover.jpg" media-type="image/jpeg" />
69
- -->
70
- <item href="Text/cover.xhtml" id="cover" media-type="application/xhtml+xml" />
67
+ {% if book.cover %}
68
+ <item href="Images/{{ book.cover.filename }}" id="{{ book.cover.filename }}" media-type="{{ book.cover.file_mime }}" />
69
+ <item href="Text/cover.xhtml" id="cover" media-type="application/xhtml+xml" />
70
+ {% endif %}
71
71
  <item href="toc.ncx" id="ncx" media-type="application/x-dtbncx+xml" />
72
72
  <item href="Styles/style.css" id="css" media-type="text/css" />
73
73
  <!--
@@ -115,8 +115,10 @@
115
115
 
116
116
  -->
117
117
  <spine toc="ncx">
118
+ {% if book.cover %}
119
+ <itemref idref="cover" />
120
+ {% endif %}
118
121
  <!--
119
- <itemref idref="cover" />
120
122
  <itemref idref="frontmatter" />
121
123
  -->
122
124
  <itemref idref="toc" />
@@ -152,9 +154,9 @@
152
154
 
153
155
  -->
154
156
  <guide>
155
- <!--
156
- <reference href="Text/cover.xhtml" title="Cover" type="cover" />
157
- -->
157
+ {% if book.cover %}
158
+ <reference href="Text/cover.xhtml" title="Cover" type="cover" />
159
+ {% endif %}
158
160
  <reference href="Text/toc.xhtml" title="Table of Contents" type="toc" />
159
161
  <!--
160
162
  <reference href="Text/frontmatter.xhtml" type="copyright-page" />
@@ -13,13 +13,16 @@
13
13
  <text>{{ book.title }}</text>
14
14
  </docTitle>
15
15
  <navMap>
16
+ {% if book.cover %}
17
+ <navPoint id="navpoint-cover">
18
+ <navLabel>
19
+ <text>Cover</text>
20
+ </navLabel>
21
+ <content src="Text/cover.xhtml" />
22
+ </navPoint>
23
+ {% endif %}
24
+
16
25
  <!--
17
- <navPoint id="navpoint-cover">
18
- <navLabel>
19
- <text>Cover</text>
20
- </navLabel>
21
- <content src="Text/cover.xhtml" />
22
- </navPoint>
23
26
  <navPoint id="navpoint-frontmatter">
24
27
  <navLabel>
25
28
  <text>Front Matter</text>
@@ -1,4 +1,5 @@
1
1
  require 'minitest/autorun'
2
+ require 'pry-byebug'
2
3
  require 'epubber'
3
4
 
4
5
  class EpubberTest < Minitest::Test
@@ -7,6 +8,10 @@ class EpubberTest < Minitest::Test
7
8
  b.title 'My First EPUB book'
8
9
  b.author 'Ramirez, Federico'
9
10
 
11
+ b.cover do |c|
12
+ c.file File.new("#{File.dirname(__FILE__)}/assets/test-cover.png")
13
+ end
14
+
10
15
  b.introduction do |i|
11
16
  i.content "<p>This is the introduction, and it's optional. What is this book about?</p>"
12
17
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epubber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Federico Ramirez
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: liquid
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -111,6 +125,7 @@ files:
111
125
  - lib/epubber/generator.rb
112
126
  - lib/epubber/generators/chapters.rb
113
127
  - lib/epubber/generators/content.rb
128
+ - lib/epubber/generators/cover.rb
114
129
  - lib/epubber/generators/endnotes.rb
115
130
  - lib/epubber/generators/generator.rb
116
131
  - lib/epubber/generators/introduction.rb
@@ -119,11 +134,13 @@ files:
119
134
  - lib/epubber/models/book.rb
120
135
  - lib/epubber/models/chapter.rb
121
136
  - lib/epubber/models/concerns/has_chapters.rb
137
+ - lib/epubber/models/concerns/has_cover.rb
122
138
  - lib/epubber/models/concerns/has_endnotes.rb
139
+ - lib/epubber/models/concerns/has_html.rb
123
140
  - lib/epubber/models/concerns/has_introduction.rb
141
+ - lib/epubber/models/cover.rb
124
142
  - lib/epubber/models/endnotes.rb
125
143
  - lib/epubber/models/introduction.rb
126
- - lib/epubber/models/model.rb
127
144
  - lib/epubber/services/compressor.rb
128
145
  - lib/epubber/services/persistance.rb
129
146
  - lib/epubber/services/template.rb
@@ -143,6 +160,7 @@ files:
143
160
  - lib/templates/OEBPS/content.opf
144
161
  - lib/templates/OEBPS/toc.ncx
145
162
  - lib/templates/mimetype
163
+ - test/assets/test-cover.png
146
164
  - test/test_epubber.rb
147
165
  homepage: https://github.com/gosukiwi/epubber
148
166
  licenses:
@@ -169,4 +187,5 @@ signing_key:
169
187
  specification_version: 4
170
188
  summary: Generate EPUB files programatically
171
189
  test_files:
190
+ - test/assets/test-cover.png
172
191
  - test/test_epubber.rb
@@ -1,11 +0,0 @@
1
- require 'nokogiri'
2
-
3
- module Epubber::Models
4
- class Model
5
- # Because the EPUB format always uses XHTML, let's make sure things like
6
- # `<br>` gets transformed to `<br />`.
7
- def clean_html(html)
8
- Nokogiri::HTML::DocumentFragment.parse(html).to_xhtml
9
- end
10
- end
11
- end