kindler 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
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: