kindler 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile CHANGED
@@ -1,7 +1,8 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
3
  group :development, :test do
4
- gem 'rspec'
4
+ gem 'rspec'
5
+ gem 'cucumber'
5
6
  # Testing infrastructure
6
7
  gem 'guard'
7
8
  gem 'guard-rspec'
data/Readme.md CHANGED
@@ -1,9 +1,20 @@
1
- ### Prerequisite
2
- #### 1.kindlegen execute file from amazon
3
- #### 2.that's all
1
+ ## Todo
2
+ * support inner reference, inner link can take to that article
4
3
 
4
+ ## Is this gem is what you want?
5
+ There is a alternative gem called [kindlerb](https://github.com/danchoi/kindlerb) can generate mobi books, the gem is also used
6
+ for the website [KindleFeeder](http://kindlefeeder.com/) which is build by [Daniel Choi](http://danielchoi.com/software).
5
7
 
6
- ### Installation
8
+ If you like to generate mobi book by some html files, you have to conform to the structure which author provide. But if you just
9
+ want to generate mobi book in the fly, then you should try this gem.
10
+
11
+ BTW, we share the same internal way to generating mobi book by [KindleGen 2](http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000234621).
12
+
13
+ ## Prerequisite
14
+ ### 1.kindlegen execute file from amazon
15
+ ### 2.that's all
16
+
17
+ ## Installation
7
18
  ```ruby
8
19
  gem 'kindler'
9
20
  ```
@@ -13,10 +24,10 @@ or
13
24
  ```ruby
14
25
  gem 'kindler',:git=>'git@github.com:29decibel/kindler.git'
15
26
  ```
16
- ### A kindle mobi book generator
27
+ ## A kindle mobi book generator
17
28
  which receive a couple of urls then output one mobi file
18
29
 
19
- ### Usage
30
+ ## Usage
20
31
  ```ruby
21
32
  title = 'my_first_mobi_book'
22
33
  book = Kindler::Book.new :title=>title,:author=>'mike'
File without changes
@@ -0,0 +1,8 @@
1
+ Feature: Generate mobi book using dsl
2
+
3
+ Scenario: create simple mobi books
4
+ Given new a Kindle book instance
5
+ When call generate of that book instance
6
+ Then got a mobi book
7
+
8
+
File without changes
File without changes
@@ -1,7 +1,7 @@
1
1
  module Kindler
2
2
  class Railtie < Rails::Railtie
3
3
  config.after_initialize do
4
- # do nothing
4
+ # do nothing
5
5
  end
6
6
  end
7
7
  end
@@ -1,3 +1,3 @@
1
1
  module Kindler
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
data/lib/kindler.rb CHANGED
@@ -8,330 +8,334 @@ require_relative 'kindler/railtie' if defined?(Rails)
8
8
  require_relative "kindler/version"
9
9
 
10
10
  module Kindler
11
- class Book
12
- class KindlerError < StandardError;end
13
- attr_accessor :title,:author,:pages,:pages_by_section,:local_images,:mobi_type
14
- TMP_DIR = 'kindler_generated_mobi'
15
- DEFAULT_SECTION = "All Pages"
16
- PAGE_ATTRIBUTES = %w(wrap title author content section)
11
+ class Book
12
+ class KindlerError < StandardError;end
13
+ attr_accessor :title,:author,:pages,:pages_by_section,:local_images,:mobi_type
14
+ TMP_DIR = 'kindler_generated_mobi'
15
+ DEFAULT_SECTION = "All Pages"
16
+ PAGE_ATTRIBUTES = %w(wrap title author content section)
17
17
 
18
- # availabel options
19
- # @param options [Hash]
20
- # @option title [String] book title
21
- # @option output_dir [String] directory want to generate
22
- # @option debug [Boolean] whether puts debug infos
23
- # @option keep_image [Boolean] whether keep images, default to true
24
- def initialize(options={})
25
- @output_dir = options[:output_dir] || './'
26
- @keep_image = options[:keep_image] || true
27
- @debug = options[:debug]
28
- @title = options[:title] || ''
29
- @author = options[:author] || 'unknown'
30
- @mobi_type = options[:mobi_type] || :magzine
31
- @pages = []
32
- @local_images = []
33
- @pages_by_section = {}
34
- raise KindlerError.new("must provide the book title ") unless title
35
- end
18
+ # availabel options
19
+ # @param options [Hash]
20
+ # @option title [String] book title
21
+ # @option output_dir [String] directory want to generate
22
+ # @option debug [Boolean] whether puts debug infos
23
+ # @option keep_image [Boolean] whether keep images, default to true
24
+ def initialize(options={})
25
+ @output_dir = options[:output_dir] || './'
26
+ @keep_image = options[:keep_image] || true
27
+ @debug = options[:debug]
28
+ @title = options[:title] || ''
29
+ @author = options[:author] || 'unknown'
30
+ @mobi_type = options[:mobi_type] || :magzine
31
+ @pages = []
32
+ @local_images = []
33
+ @pages_by_section = {}
34
+ raise KindlerError.new("must provide the book title ") unless title
35
+ end
36
36
 
37
- def add_page(options={})
38
- raise KindlerError.new('must provide title when add page') unless options[:title]
39
- page = options.reject{|k,v| PAGE_ATTRIBUTES.include?(k)}
40
- page[:wrap] ||= true
41
- page[:section] ||= DEFAULT_SECTION
42
- page[:count] = pages.count + 1
43
- page[:file_name] = "#{page[:count].to_s.rjust(3,'0')}.html"
44
- page[:author] = 'unknown' if (page[:author]==nil or page[:author]=='')
45
- # escape special chars
46
- page[:title] = CGI::escapeHTML(page[:title])
47
- page[:author] = CGI::escapeHTML(page[:author])
48
- pages << page
49
- debug pages
50
- end
37
+ def add_page(options={})
38
+ raise KindlerError.new('must provide title when add page') unless options[:title]
39
+ page = options.reject{|k,v| PAGE_ATTRIBUTES.include?(k)}
40
+ page[:wrap] ||= true
41
+ page[:section] ||= DEFAULT_SECTION
42
+ page[:count] = pages.count + 1
43
+ page[:file_name] = "#{page[:count].to_s.rjust(3,'0')}.html"
44
+ page[:author] = 'unknown' if (page[:author]==nil or page[:author]=='')
45
+ # escape special chars
46
+ page[:title] = CGI::escapeHTML(page[:title])
47
+ page[:author] = CGI::escapeHTML(page[:author])
48
+ pages << page
49
+ debug pages
50
+ end
51
51
 
52
- def generate
53
- make_generated_dirs
54
- localize_images if @keep_image
55
- # reorder count index
56
- if magzine?
57
- sectionize_pages
58
- end
59
- generate_toc
60
- generate_opf
61
- generate_ncx
62
- write_to_disk
63
- kindlegen
64
- end
52
+ def generate
53
+ make_generated_dirs
54
+ localize_images if @keep_image
55
+ # reorder count index
56
+ if magzine?
57
+ sectionize_pages
58
+ end
59
+ generate_toc
60
+ generate_opf
61
+ generate_ncx
62
+ write_to_disk
63
+ kindlegen
64
+ end
65
65
 
66
- def sectionize_pages
67
- self.pages.each do |page|
68
- pages_by_section[page[:section]] ||= []
69
- pages_by_section[page[:section]] << page
70
- end
71
- self.pages = pages_by_section.values.flatten
72
- self.pages.each_with_index do |page,index|
73
- page[:count] = index + 1
74
- page[:file_name] = "#{page[:count].to_s.rjust(3,'0')}.html"
75
- end
76
- end
66
+ def sectionize_pages
67
+ self.pages.each do |page|
68
+ pages_by_section[page[:section]] ||= []
69
+ pages_by_section[page[:section]] << page
70
+ end
71
+ self.pages = pages_by_section.values.flatten
72
+ self.pages.each_with_index do |page,index|
73
+ page[:count] = index + 1
74
+ page[:file_name] = "#{page[:count].to_s.rjust(3,'0')}.html"
75
+ end
76
+ end
77
77
 
78
- # check mobi file is generated already
79
- def mobi_generated?
80
- File.exist? "#{tmp_dir}/#{@title}.mobi"
81
- end
78
+ # check mobi file is generated already
79
+ def generated?
80
+ File.exist? "#{tmp_dir}/#{valid_title}.mobi"
81
+ end
82
82
 
83
- private
84
- # make sure kindlegen is installed
85
- # you can use "sudo brew install " to install it
86
- def kindlegen
87
- debug 'begin generate mobi'
88
- system("kindlegen #{tmp_dir}/#{@title}.opf ")
89
- end
83
+ private
84
+ # make sure kindlegen is installed
85
+ # you can use "sudo brew install " to install it
86
+ def kindlegen
87
+ debug 'begin generate mobi'
88
+ system("kindlegen #{tmp_dir}/#{valid_title}.opf ")
89
+ end
90
90
 
91
- # generate contents.html
92
- def generate_toc
93
- contents = <<-CODE
94
- <html>
95
- <head>
96
- <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
97
- <title>Table of Contents</title>
98
- </head>
99
- <body>
100
- <h1>Contents</h1>
101
- <h4>Main section</h4>
102
- <ul>
103
- CODE
104
- files_count = 1
105
- pages.each do |page|
106
- contents << "<li><a href='#{files_count.to_s.rjust(3,'0')}.html'>#{page[:title]}</a></li>"
107
- files_count += 1
108
- end
109
- # append footer
110
- contents << "</ul></body></html>"
91
+ # generate contents.html
92
+ def generate_toc
93
+ contents = <<-CODE
94
+ <html>
95
+ <head>
96
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
97
+ <title>Table of Contents</title>
98
+ </head>
99
+ <body>
100
+ <h1>Contents</h1>
101
+ <h4>Main section</h4>
102
+ <ul>
103
+ CODE
104
+ files_count = 1
105
+ pages.each do |page|
106
+ contents << "<li><a href='#{files_count.to_s.rjust(3,'0')}.html'>#{page[:title]}</a></li>"
107
+ files_count += 1
108
+ end
109
+ # append footer
110
+ contents << "</ul></body></html>"
111
111
 
112
- @toc = contents
113
- end
112
+ @toc = contents
113
+ end
114
114
 
115
- # generate ncx , which is navigation
116
- def generate_ncx
117
- contents = <<-NCX
118
- <?xml version="1.0" encoding="UTF-8"?>
119
- <!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN" "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">
120
- <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1" xml:lang="en-US">
121
- <head>
122
- <meta name="dtb:uid" content="#{title}"/>
123
- <meta name="dtb:depth" content="1"/>
124
- <meta name="dtb:totalPageCount" content="0"/>
125
- <meta name="dtb:maxPageNumber" content="0"/>
126
- </head>
127
- <docTitle>
128
- <text>#{title}</text>
129
- </docTitle>
130
- <docAuthor>
131
- <text>#{author}</text>
132
- </docAuthor>
133
- <navMap>
134
- NCX
135
- contents << (magzine? ? magzine_ncx : flat_ncx)
136
- contents << "</navMap></ncx>"
137
- @ncx = contents
138
- end
115
+ # generate ncx , which is navigation
116
+ def generate_ncx
117
+ contents = <<-NCX
118
+ <?xml version="1.0" encoding="UTF-8"?>
119
+ <!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN" "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">
120
+ <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1" xml:lang="en-US">
121
+ <head>
122
+ <meta name="dtb:uid" content="#{title}"/>
123
+ <meta name="dtb:depth" content="1"/>
124
+ <meta name="dtb:totalPageCount" content="0"/>
125
+ <meta name="dtb:maxPageNumber" content="0"/>
126
+ </head>
127
+ <docTitle>
128
+ <text>#{title}</text>
129
+ </docTitle>
130
+ <docAuthor>
131
+ <text>#{author}</text>
132
+ </docAuthor>
133
+ <navMap>
134
+ NCX
135
+ contents << (magzine? ? magzine_ncx : flat_ncx)
136
+ contents << "</navMap></ncx>"
137
+ @ncx = contents
138
+ end
139
139
 
140
- def flat_ncx
141
- contents = ''
142
- files_count = 2
143
- pages.each do |page|
144
- nav_point = <<-NAV
145
- <navPoint id="navpoint-#{files_count}" playOrder="#{files_count}">
146
- <navLabel><text>#{page[:title]}</text></navLabel>
147
- <content src="#{(files_count-1).to_s.rjust(3,'0')}.html"/>
148
- </navPoint>
149
- NAV
150
- contents << nav_point
151
- files_count += 1
152
- end
153
- contents
154
- end
140
+ def flat_ncx
141
+ contents = ''
142
+ files_count = 2
143
+ pages.each do |page|
144
+ nav_point = <<-NAV
145
+ <navPoint id="navpoint-#{files_count}" playOrder="#{files_count}">
146
+ <navLabel><text>#{page[:title]}</text></navLabel>
147
+ <content src="#{(files_count-1).to_s.rjust(3,'0')}.html"/>
148
+ </navPoint>
149
+ NAV
150
+ contents << nav_point
151
+ files_count += 1
152
+ end
153
+ contents
154
+ end
155
155
 
156
- def magzine_ncx
157
- contents = ''
156
+ def magzine_ncx
157
+ contents = ''
158
158
 
159
- contents << <<-MAG
160
- <navPoint playOrder="0" class="periodical" id="periodical">
161
- <navLabel>
162
- <text>Table of Contents</text>
163
- </navLabel>
164
- <content src="contents.html"/>
159
+ contents << <<-MAG
160
+ <navPoint playOrder="0" class="periodical" id="periodical">
161
+ <navLabel>
162
+ <text>Table of Contents</text>
163
+ </navLabel>
164
+ <content src="contents.html"/>
165
165
 
166
- MAG
166
+ MAG
167
167
 
168
- play_order = 1
169
- @pages_by_section.each do |section,pages|
170
- next if pages.count==0
171
- # add section header
172
- contents << <<-SECHEADER
173
- <navPoint playOrder="#{play_order}" class="section" id="#{section}">
174
- <navLabel>
175
- <text>#{section}</text>
176
- </navLabel>
177
- <content src="#{pages.first[:file_name]}"/>
178
- SECHEADER
168
+ play_order = 1
169
+ @pages_by_section.each do |section,pages|
170
+ next if pages.count==0
171
+ # add section header
172
+ contents << <<-SECHEADER
173
+ <navPoint playOrder="#{play_order}" class="section" id="#{section}">
174
+ <navLabel>
175
+ <text>#{section}</text>
176
+ </navLabel>
177
+ <content src="#{pages.first[:file_name]}"/>
178
+ SECHEADER
179
179
 
180
- play_order += 1
181
- # add pages nav
182
- pages.each do |page|
183
- contents << <<-PAGE
184
- <navPoint playOrder="#{play_order}" class="article" id="item-#{page[:count].to_s.rjust(3,'0')}">
185
- <navLabel>
186
- <text>#{page[:title]}</text>
187
- </navLabel>
188
- <content src="#{page[:file_name]}"/>
189
- <mbp:meta name="description">#{page[:title]}</mbp:meta>
190
- <mbp:meta name="author">#{page[:author]}</mbp:meta>
191
- </navPoint>
192
- PAGE
193
- play_order += 1
194
- end
195
- # add section footer
196
- contents << "</navPoint>"
197
- end
198
- contents << "</navPoint>"
199
- end
180
+ play_order += 1
181
+ # add pages nav
182
+ pages.each do |page|
183
+ contents << <<-PAGE
184
+ <navPoint playOrder="#{play_order}" class="article" id="item-#{page[:count].to_s.rjust(3,'0')}">
185
+ <navLabel>
186
+ <text>#{page[:title]}</text>
187
+ </navLabel>
188
+ <content src="#{page[:file_name]}"/>
189
+ <mbp:meta name="description">#{page[:title]}</mbp:meta>
190
+ <mbp:meta name="author">#{page[:author]}</mbp:meta>
191
+ </navPoint>
192
+ PAGE
193
+ play_order += 1
194
+ end
195
+ # add section footer
196
+ contents << "</navPoint>"
197
+ end
198
+ contents << "</navPoint>"
199
+ end
200
200
 
201
- def magzine_meta
202
- <<-META
203
- <x-metadata>
204
- <output content-type="application/x-mobipocket-subscription-magazine" encoding="utf-8"/>
205
- </x-metadata>
206
- META
207
- end
201
+ def magzine_meta
202
+ <<-META
203
+ <x-metadata>
204
+ <output content-type="application/x-mobipocket-subscription-magazine" encoding="utf-8"/>
205
+ </x-metadata>
206
+ META
207
+ end
208
208
 
209
- def magzine?
210
- @mobi_type == :magzine
211
- end
209
+ def magzine?
210
+ @mobi_type == :magzine
211
+ end
212
212
 
213
- # generate the opf, manifest of book,including all articles and images and css
214
- def generate_opf
215
- contents = <<-HTML
216
- <?xml version='1.0' encoding='utf-8'?>
217
- <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="#{title}">
218
- <metadata>
219
- <dc-metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
220
- <dc:title>#{title}</dc:title>
221
- <dc:language>en-gb</dc:language>
222
- <meta content="cover-image" name="cover"/>
223
- <dc:creator>Kindler- 29decibel</dc:creator>
224
- <dc:publisher>Kindler- 29decibel</dc:publisher>
225
- <dc:subject>News</dc:subject>
226
- <dc:identifier id="#{title}">#{title}</dc:identifier>
227
- <dc:date>#{Time.now.to_date}</dc:date>
228
- <dc:description>Kindler generated book</dc:description>
229
- </dc-metadata>
230
- #{magzine? ? magzine_meta : ''}
231
- </metadata>
232
- <manifest>
233
- HTML
234
- files_count = 1
235
- pages.each do |page|
236
- doc_id = files_count.to_s.rjust(3,'0')
237
- contents << "<item href='#{doc_id}.html' media-type='application/xhtml+xml' id='#{doc_id}'/>"
238
- files_count += 1
239
- end
240
- contents << "<item href='contents.html' media-type='application/xhtml+xml' id='contents'/>"
241
- contents << "<item href='nav-contents.ncx' media-type='application/x-dtbncx+xml' id='nav-contents'/>"
242
- contents << "</manifest>"
243
- contents << "<spine toc='nav-contents'>"
244
- contents << "<itemref idref='contents'/>"
245
- files_count = 1
246
- pages.each do |page|
247
- contents << "<itemref idref='#{files_count.to_s.rjust(3,'0')}'/>"
248
- files_count += 1
249
- end
250
- contents << "</spine><guide><reference href='contents.html' type='toc' title='Table of Contents'/></guide></package>"
251
- @opf = contents
252
- end
213
+ # generate the opf, manifest of book,including all articles and images and css
214
+ def generate_opf
215
+ contents = <<-HTML
216
+ <?xml version='1.0' encoding='utf-8'?>
217
+ <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="#{title}">
218
+ <metadata>
219
+ <dc-metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
220
+ <dc:title>#{title}</dc:title>
221
+ <dc:language>en-gb</dc:language>
222
+ <meta content="cover-image" name="cover"/>
223
+ <dc:creator>Kindler- 29decibel</dc:creator>
224
+ <dc:publisher>Kindler- 29decibel</dc:publisher>
225
+ <dc:subject>News</dc:subject>
226
+ <dc:identifier id="#{title}">#{title}</dc:identifier>
227
+ <dc:date>#{Time.now.to_date}</dc:date>
228
+ <dc:description>Kindler generated book</dc:description>
229
+ </dc-metadata>
230
+ #{magzine? ? magzine_meta : ''}
231
+ </metadata>
232
+ <manifest>
233
+ HTML
234
+ files_count = 1
235
+ pages.each do |page|
236
+ doc_id = files_count.to_s.rjust(3,'0')
237
+ contents << "<item href='#{doc_id}.html' media-type='application/xhtml+xml' id='#{doc_id}'/>"
238
+ files_count += 1
239
+ end
240
+ contents << "<item href='contents.html' media-type='application/xhtml+xml' id='contents'/>"
241
+ contents << "<item href='nav-contents.ncx' media-type='application/x-dtbncx+xml' id='nav-contents'/>"
242
+ contents << "</manifest>"
243
+ contents << "<spine toc='nav-contents'>"
244
+ contents << "<itemref idref='contents'/>"
245
+ files_count = 1
246
+ pages.each do |page|
247
+ contents << "<itemref idref='#{files_count.to_s.rjust(3,'0')}'/>"
248
+ files_count += 1
249
+ end
250
+ contents << "</spine><guide><reference href='contents.html' type='toc' title='Table of Contents'/></guide></package>"
251
+ @opf = contents
252
+ end
253
253
 
254
- def localize_images
255
- images_count = 1
256
- pages.each do |page|
257
- article = Nokogiri::HTML(page[:content])
258
- article.css('img').each do |img|
259
- begin
260
- image_remote_address = img.attr('src')
261
- unless image_remote_address.start_with?('http')
262
- image_remote_address = "http://#{URI(url).host}#{image_remote_address}"
263
- end
264
- image_local_address = File.join(tmp_dir,"#{images_count}#{File.extname(image_remote_address)}")
265
- # download images
266
- debug "begin fetch image #{image_remote_address}"
267
- debug "save to #{image_local_address}"
268
- File.open(image_local_address,'wb') do |f|
269
- f.write open(image_remote_address).read
270
- end
271
- debug 'Image saved'
272
- # replace local url address
273
- img.attributes['src'].value = "#{images_count}#{File.extname(image_remote_address)}"
274
- page[:content] = article.inner_html
275
- # add to manifest
276
- local_images << "#{images_count}#{File.extname(image_remote_address)}"
277
- images_count += 1
278
- rescue Exception => e
279
- debug "got error when fetch and save image: #{e}"
280
- end
281
- end
282
- end
283
- end
254
+ def localize_images
255
+ images_count = 1
256
+ pages.each do |page|
257
+ article = Nokogiri::HTML(page[:content])
258
+ article.css('img').each do |img|
259
+ begin
260
+ image_remote_address = img.attr('src')
261
+ unless image_remote_address.start_with?('http')
262
+ image_remote_address = "http://#{URI(url).host}#{image_remote_address}"
263
+ end
264
+ image_local_address = File.join(tmp_dir,"#{images_count}#{File.extname(image_remote_address)}")
265
+ # download images
266
+ debug "begin fetch image #{image_remote_address}"
267
+ debug "save to #{image_local_address}"
268
+ File.open(image_local_address,'wb') do |f|
269
+ f.write open(image_remote_address).read
270
+ end
271
+ debug 'Image saved'
272
+ # replace local url address
273
+ img.attributes['src'].value = "#{images_count}#{File.extname(image_remote_address)}"
274
+ page[:content] = article.inner_html
275
+ # add to manifest
276
+ local_images << "#{images_count}#{File.extname(image_remote_address)}"
277
+ images_count += 1
278
+ rescue Exception => e
279
+ debug "got error when fetch and save image: #{e}"
280
+ end
281
+ end
282
+ end
283
+ end
284
284
 
285
- # html file path
286
- def file_path(file_name)
287
- "#{tmp_dir}/#{file_name}"
288
- end
285
+ # html file path
286
+ def file_path(file_name)
287
+ "#{tmp_dir}/#{file_name}"
288
+ end
289
289
 
290
- # wrap readable contents with in html format
291
- def html_wrap(title,content)
292
- result = ''
293
- result << '<html><head>'
294
- result << "<meta content='text/html; charset=utf-8' http-equiv='Content-Type'/>"
295
- result << '</head><body>'
296
- result << "<h3>#{title}</h3>"
297
- result << content
298
- result << '</body></html>'
299
- end
290
+ # wrap readable contents with in html format
291
+ def html_wrap(title,content)
292
+ result = ''
293
+ result << '<html><head>'
294
+ result << "<meta content='text/html; charset=utf-8' http-equiv='Content-Type'/>"
295
+ result << '</head><body>'
296
+ result << "<h3>#{title}</h3>"
297
+ result << content
298
+ result << '</body></html>'
299
+ end
300
300
 
301
- # the dir path to generated files
302
- def tmp_dir
303
- File.join @output_dir,"#{TMP_DIR}_#{@title.gsub(' ','_')}"
304
- end
301
+ # the dir path to generated files
302
+ def tmp_dir
303
+ File.join @output_dir,"#{TMP_DIR}_#{valid_title}"
304
+ end
305
305
 
306
- # create dirs of generated files
307
- def make_generated_dirs
308
- FileUtils.rm_rf tmp_dir if File.exist?(tmp_dir)
309
- FileUtils.mkdir_p tmp_dir unless File.exist?(tmp_dir)
310
- end
306
+ def valid_title
307
+ @v_title ||= @title.gsub(' ','_')
308
+ end
311
309
 
312
- def write_to_disk
313
- File.open("#{tmp_dir}/nav-contents.ncx",'wb') { |f| f.write @ncx }
314
- File.open(file_path('contents.html'),'wb') {|f| f.write @toc }
315
- File.open("#{tmp_dir}/#{title}.opf",'wb') {|f| f.write @opf}
316
- # make html files
317
- files_count = 1
318
- pages.each do |page|
319
- File.open(file_path(page[:file_name]),'wb') do |f|
320
- content_to_write = page[:wrap] ? html_wrap(page[:title],page[:content]) : page[:content]
321
- debug "here is the page #{page[:title]} need to write"
322
- debug content_to_write
323
- f.write content_to_write
324
- end
325
- files_count += 1
326
- end
310
+ # create dirs of generated files
311
+ def make_generated_dirs
312
+ FileUtils.rm_rf tmp_dir if File.exist?(tmp_dir)
313
+ FileUtils.mkdir_p tmp_dir unless File.exist?(tmp_dir)
314
+ end
327
315
 
328
- end
316
+ def write_to_disk
317
+ File.open("#{tmp_dir}/nav-contents.ncx",'wb') { |f| f.write @ncx }
318
+ File.open(file_path('contents.html'),'wb') {|f| f.write @toc }
319
+ File.open("#{tmp_dir}/#{valid_title}.opf",'wb') {|f| f.write @opf}
320
+ # make html files
321
+ files_count = 1
322
+ pages.each do |page|
323
+ File.open(file_path(page[:file_name]),'wb') do |f|
324
+ content_to_write = page[:wrap] ? html_wrap(page[:title],page[:content]) : page[:content]
325
+ debug "here is the page #{page[:title]} need to write"
326
+ debug content_to_write
327
+ f.write content_to_write
328
+ end
329
+ files_count += 1
330
+ end
329
331
 
330
- def debug(str)
331
- return unless @debug
332
- Rails.logger.info(str) if defined?(Rails)
333
- puts str
334
- end
332
+ end
335
333
 
336
- end
334
+ def debug(str)
335
+ return unless @debug
336
+ Rails.logger.info(str) if defined?(Rails)
337
+ puts str
338
+ end
339
+
340
+ end
337
341
  end
@@ -1,58 +1,96 @@
1
1
  require 'spec_helper'
2
- describe "Mobi html file generator" do
3
-
4
- it "should not generate a mobi book" do
5
- title = 'good_book'
6
- book = Kindler::Book.new :title=>title,:author=>'mike',:debug=>true
7
- book.add_page :title=>'page1',:author=>'mike1',:content=>'this is the page 1',:wrap=>true
8
- book.add_page :title=>'page2',:author=>'mike1',:content=>'this is the page 2',:wrap=>true
9
- book.add_page :title=>'page3',:author=>'mike1',:content=>'this is the page 3',:wrap=>true
10
- book.generate
11
- File.exist?(mobi_book_path(title)).should == true
12
- end
13
-
14
- it "should generate book contains images" do
15
- title = 'book_with_image'
16
- book = Kindler::Book.new :title=>title,:author=>'mike',:debug=>true
17
- book.add_page :title=>'page1',:author=>'mike1',:content=>'this is the page 1',:wrap=>true
18
- book.add_page :title=>'page2',:author=>'mike1',:content=>'this is the page 2',:wrap=>true
19
- book.add_page :title=>'page3',:author=>'mike1',:content=>'<img src="http://media2.glamour-sales.com.cn/media/catalog/category/Stroili_banner_02.jpg"></img>this is the page 3',:wrap=>true
20
- book.generate
21
- File.exist?(mobi_book_path(title)).should == true
22
- end
23
-
24
- it "should generate book with sections" do
25
- title = 'first_section_book'
26
- book = Kindler::Book.new :title=>title,:author=>'mike',:debug=>true
27
- book.add_page :title=>'page1',:author=>'mike1',:content=>'this is the page 1',:wrap=>true,:section => 'love'
28
- book.add_page :title=>'page2',:author=>'mike1',:content=>'this is the page 2',:wrap=>true,:section => 'hate'
29
- book.add_page :title=>'page3',:author=>'mike1',:content=>'<img src="http://media2.glamour-sales.com.cn/media/catalog/category/Stroili_banner_02.jpg"></img>this is the page 3',:wrap=>true,:section=>'hate'
30
- book.generate
31
- File.exist?(mobi_book_path(title)).should == true
32
- end
33
-
34
- it "should contains right info at contents html" do
35
- title = 'test_contents'
36
- book = Kindler::Book.new :title=>title,:author=>'mike',:debug=>true
37
- book.add_page :title=>'love page1',:author=>'mike1',:content=>'this is the love page1',:section => 'love'
38
- book.add_page :title=>'love page2',:author=>'mike1',:content=>'this is the love page2',:section => 'love'
39
- book.add_page :title=>'hate page1',:author=>'mike1',:content=>'this is the hate page1',:section => 'hate'
40
- book.add_page :title=>'love page3',:author=>'mike1',:content=>'this is the love page3',:section => 'love'
41
- book.add_page :title=>'hate page2',:author=>'mike1',:content=>'<img src="http://media2.glamour-sales.com.cn/media/catalog/category/Stroili_banner_02.jpg"></img>this is the hate page2',:section=>'hate'
42
- book.generate
43
- book.pages[2][:title].should == 'love page3'
44
- end
45
-
46
- it "should contains right info at ncx file" do
47
-
48
- end
49
-
50
- it "should contains right info at opf file" do
51
-
52
- end
53
-
54
- def mobi_book_path(title,output_dir='.')
55
- File.join(output_dir,"kindler_generated_mobi_#{title}/#{title}.mobi")
56
- end
2
+ describe "Mobi book file generator" do
3
+
4
+ DIR_PREFIX = "kindler_generated_mobi_"
5
+
6
+ it "should have the title,author property" do
7
+ title = 'first-book'
8
+ author = 'mike'
9
+ book = Kindler::Book.new :title=>title,:author=>author,:debug=>true
10
+ book.title.should == title
11
+ book.author.should == author
12
+ end
13
+
14
+ it "should have the generated dir contains book infos" do
15
+ title = 'first-book'
16
+ author = 'mike'
17
+ book = Kindler::Book.new :title=>title,:author=>author,:debug=>true
18
+ book.generate
19
+ book.should be_generated
20
+ end
21
+
22
+ it "should contains the contents.html and ncx file" do
23
+ title = 'first-book'
24
+ author = 'mike'
25
+ book = Kindler::Book.new :title=>title,:author=>author,:debug=>true
26
+ book.add_page :title=>'page1',:author=>'mike1',:content=>'this is the page 1',:wrap=>true
27
+ File.should be_exist("./#{DIR_PREFIX}#{title}/contents.html")
28
+ File.should be_exist("./#{DIR_PREFIX}#{title}/nav-contents.ncx")
29
+ end
30
+
31
+ it "contents file should include the page" do
32
+ title = 'first-book'
33
+ author = 'mike'
34
+ book = Kindler::Book.new :title=>title,:author=>author,:debug=>true
35
+ book.add_page :title=>'page1',:author=>'mike1',:content=>'this is the page 1',:wrap=>true
36
+ book.generate
37
+ contents = File.open("./#{DIR_PREFIX}#{title}/contents.html").readlines
38
+ contents.count.should > 0
39
+ contents.select {|a| a.include?("001.html")}.count.should > 0
40
+ book.should be_generated
41
+ end
42
+
43
+ it "should not generate a mobi book" do
44
+ title = 'good_book'
45
+ book = Kindler::Book.new :title=>title,:author=>'mike',:debug=>true
46
+ book.add_page :title=>'page1',:author=>'mike1',:content=>'this is the page 1',:wrap=>true
47
+ book.add_page :title=>'page2',:author=>'mike1',:content=>'this is the page 2',:wrap=>true
48
+ book.add_page :title=>'page3',:author=>'mike1',:content=>'this is the page 3',:wrap=>true
49
+ book.generate
50
+ book.should be_generated
51
+ end
52
+
53
+ it "should generate book contains images" do
54
+ title = 'book_with_image'
55
+ book = Kindler::Book.new :title=>title,:author=>'mike',:debug=>true
56
+ book.add_page :title=>'page1',:author=>'mike1',:content=>'this is the page 1',:wrap=>true
57
+ book.add_page :title=>'page2',:author=>'mike1',:content=>'this is the page 2',:wrap=>true
58
+ book.add_page :title=>'page3',:author=>'mike1',:content=>'<img src="http://media2.glamour-sales.com.cn/media/catalog/category/Stroili_banner_02.jpg"></img>this is the page 3',:wrap=>true
59
+ book.generate
60
+ book.should be_generated
61
+ File.should be_exist("./#{DIR_PREFIX}#{title}/1.jpg")
62
+ end
63
+
64
+ it "can access pages information before generate" do
65
+ title = 'test_contents'
66
+ book = Kindler::Book.new :title=>title,:author=>'mike',:debug=>true
67
+ book.add_page :title=>'love page1',:author=>'mike1',:content=>'this is the love page1',:section => 'love'
68
+ book.add_page :title=>'love page2',:author=>'mike1',:content=>'this is the love page2',:section => 'love'
69
+ book.add_page :title=>'hate page1',:author=>'mike1',:content=>'this is the hate page1',:section => 'hate'
70
+ book.add_page :title=>'love page3',:author=>'mike1',:content=>'this is the love page3',:section => 'love'
71
+ book.pages.count.should == 4
72
+ end
73
+
74
+
75
+ it "should have two sections" do
76
+ title = 'test_contents'
77
+ book = Kindler::Book.new :title=>title,:author=>'mike',:debug=>true
78
+ book.add_page :title=>'love page1',:author=>'mike1',:content=>'this is the love page1',:section => 'love'
79
+ book.add_page :title=>'love page2',:author=>'mike1',:content=>'this is the love page2',:section => 'love'
80
+ book.add_page :title=>'hate page1',:author=>'mike1',:content=>'this is the hate page1',:section => 'hate'
81
+ book.add_page :title=>'love page3',:author=>'mike1',:content=>'this is the love page3',:section => 'love'
82
+ book.generate
83
+ book.should be_generated
84
+ book.pages_by_section.count.should == 2
85
+ end
86
+
87
+ it "should generate books given title contains space" do
88
+ title = 'title with space'
89
+ book = Kindler::Book.new :title=>title,:author=>'mike',:debug=>true
90
+ book.add_page :title=>'page1',:author=>'mike1',:content=>'this is the page 1',:wrap=>true
91
+ book.add_page :title=>'page2',:author=>'mike1',:content=>'this is the page 2',:wrap=>true
92
+ book.generate
93
+ book.should be_generated
94
+ end
57
95
 
58
96
  end
data/spec/spec_helper.rb CHANGED
@@ -4,4 +4,19 @@ rescue LoadError
4
4
  puts 'Although not required, bundler is recommended for running the tests.'
5
5
  end
6
6
 
7
+ RSpec.configure do |config|
8
+ config.mock_with :rspec
9
+ config.color_enabled = true
10
+
11
+ config.before(:each) do
12
+
13
+ end
14
+
15
+ config.before(:each, :type => :controller) do
16
+ end
17
+
18
+ config.after(:all) do
19
+ end
20
+ end
21
+
7
22
  require 'kindler'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kindler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-05 00:00:00.000000000Z
12
+ date: 2012-04-06 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &2161120240 !ruby/object:Gem::Requirement
16
+ requirement: &2160828000 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2161120240
24
+ version_requirements: *2160828000
25
25
  description: kindler is a rubygem allow you to generate kindle mobi book very easily
26
26
  email:
27
27
  - mike.d.1984@gmail.com
@@ -34,6 +34,10 @@ files:
34
34
  - Guardfile
35
35
  - Rakefile
36
36
  - Readme.md
37
+ - features/basic.feature
38
+ - features/dsl.feature
39
+ - features/step_definitions/basic_step.rb
40
+ - features/step_definitions/dsl_step.rb
37
41
  - kindler.gemspec
38
42
  - lib/kindler.rb
39
43
  - lib/kindler/railtie.rb
@@ -65,6 +69,10 @@ signing_key:
65
69
  specification_version: 3
66
70
  summary: kindler is a rubygem allow you to generate kindle mobi book very easily
67
71
  test_files:
72
+ - features/basic.feature
73
+ - features/dsl.feature
74
+ - features/step_definitions/basic_step.rb
75
+ - features/step_definitions/dsl_step.rb
68
76
  - spec/cases/generator_spec.rb
69
77
  - spec/spec_helper.rb
70
78
  has_rdoc: