softcover 1.0.beta12 → 1.0.beta13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/softcover/book_manifest.rb +5 -0
- data/lib/softcover/builders/epub.rb +28 -4
- data/lib/softcover/commands/check.rb +1 -1
- data/lib/softcover/utils.rb +5 -0
- data/lib/softcover/version.rb +1 -1
- data/softcover.gemspec +1 -1
- data/spec/builders/epub_spec.rb +5 -0
- data/spec/commands/publisher_spec.rb +140 -140
- data/spec/webmock_helpers.rb +2 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1177c81d0740d0a59f58d8dde203c7ccfff1ab9e
|
4
|
+
data.tar.gz: a50db48e9f39cea1a47134b4767d1037cb8737de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f8239af807f5195d74493d4067e93fab1b448c58a87df4a568cf0f7e4cc09d5c7160e4865d40416a9845c21c5971f2fd5dd41ae3b0dc37f2f749acf82079793
|
7
|
+
data.tar.gz: 877e95ef95a97eb584530e0a8a52e52d5becdb8597b9eb44c0540c35ff2d31c264fd97226a012065cb45693a37865f0c1ad7f6c880c26a9e117610f3a1cbb8cc
|
@@ -252,6 +252,11 @@ class Softcover::BookManifest < OpenStruct
|
|
252
252
|
end
|
253
253
|
end
|
254
254
|
|
255
|
+
# Returns the name of the HTML file containing the full book.
|
256
|
+
def full_html_file
|
257
|
+
path("html/#{slug}.html")
|
258
|
+
end
|
259
|
+
|
255
260
|
# Returns chapters for the PDF.
|
256
261
|
def pdf_chapter_names
|
257
262
|
chaps = chapters.reject { |chapter| chapter.slug.match(/frontmatter/) }.
|
@@ -7,8 +7,12 @@ module Softcover
|
|
7
7
|
def cover_img
|
8
8
|
extensions = %w[jpg jpeg png tiff]
|
9
9
|
extensions.each do |ext|
|
10
|
-
|
11
|
-
|
10
|
+
origin = "images/cover.#{ext}"
|
11
|
+
target = "#{images_dir}/cover.#{ext}"
|
12
|
+
if File.exist?(origin)
|
13
|
+
FileUtils.cp(origin, target)
|
14
|
+
return File.basename(target)
|
15
|
+
end
|
12
16
|
end
|
13
17
|
return false
|
14
18
|
end
|
@@ -39,6 +43,7 @@ module Softcover
|
|
39
43
|
self.manifest = Softcover::BookManifest.new(opts)
|
40
44
|
end
|
41
45
|
remove_html
|
46
|
+
remove_images
|
42
47
|
create_directories
|
43
48
|
write_mimetype
|
44
49
|
write_container_xml
|
@@ -64,11 +69,17 @@ module Softcover
|
|
64
69
|
FileUtils.rm(Dir.glob(path('epub/OEBPS/*.html')))
|
65
70
|
end
|
66
71
|
|
72
|
+
# Removes images in case they are stale.
|
73
|
+
def remove_images
|
74
|
+
rm_r images_dir
|
75
|
+
end
|
76
|
+
|
67
77
|
def create_directories
|
68
78
|
mkdir('epub')
|
69
79
|
mkdir(path('epub/OEBPS'))
|
70
80
|
mkdir(path('epub/OEBPS/styles'))
|
71
81
|
mkdir(path('epub/META-INF'))
|
82
|
+
mkdir(images_dir)
|
72
83
|
mkdir('ebooks')
|
73
84
|
end
|
74
85
|
|
@@ -276,11 +287,24 @@ module Softcover
|
|
276
287
|
end
|
277
288
|
|
278
289
|
# Copies the image files from the HTML version of the document.
|
279
|
-
# We remove PDF images, which are valid in PDF documents but not in EPUB.
|
280
290
|
def copy_image_files
|
291
|
+
# Copy over all images to guarantee the same directory structure.
|
281
292
|
FileUtils.cp_r(File.join('html', 'images'),
|
282
293
|
File.join('epub', 'OEBPS'))
|
283
|
-
|
294
|
+
# Parse the full HTML file with Nokogiri to get images actually used.
|
295
|
+
html = File.read(manifest.full_html_file)
|
296
|
+
html_image_filenames = Nokogiri::HTML(html).css('img').map do |node|
|
297
|
+
node.attributes['src'].value
|
298
|
+
end
|
299
|
+
# Form the corresponding EPUB image paths.
|
300
|
+
used_image_filenames = html_image_filenames.map do |filename|
|
301
|
+
"epub/OEBPS/#{filename}"
|
302
|
+
end.to_set
|
303
|
+
# Delete unused images.
|
304
|
+
Dir.glob("epub/OEBPS/images/**/*").each do |image|
|
305
|
+
next if File.directory?(image)
|
306
|
+
rm image unless used_image_filenames.include?(image)
|
307
|
+
end
|
284
308
|
end
|
285
309
|
|
286
310
|
# Make the EPUB, which is basically just a zipped HTML file.
|
@@ -79,7 +79,7 @@ module Softcover
|
|
79
79
|
url = 'http://calibre-ebook.com/'
|
80
80
|
message = "Calibre (#{url})\n"
|
81
81
|
message += " ∟ Enable Calibre command-line tools"
|
82
|
-
message += " (http://manual.calibre-ebook.com/
|
82
|
+
message += " (http://manual.calibre-ebook.com/generated/en/cli-index.html)"
|
83
83
|
when :java
|
84
84
|
url = 'http://www.java.com/en/download/help/index_installing.xml'
|
85
85
|
"Java (#{url})"
|
data/lib/softcover/utils.rb
CHANGED
@@ -194,6 +194,11 @@ module Softcover::Utils
|
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
|
+
# Removes a directory recursively.
|
198
|
+
def rm_r(directory)
|
199
|
+
FileUtils.rm_r(directory) if File.directory?(directory)
|
200
|
+
end
|
201
|
+
|
197
202
|
# Returns the system-independent file path.
|
198
203
|
# It's nicer to write `path('foo/bar/baz')` than
|
199
204
|
# `File.join('foo', 'bar', 'baz')`.
|
data/lib/softcover/version.rb
CHANGED
data/softcover.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.add_dependency 'polytexnic', '~> 1.0.
|
21
|
+
gem.add_dependency 'polytexnic', '~> 1.0.beta8'
|
22
22
|
gem.add_dependency 'msgpack', '~> 0.4.2'
|
23
23
|
gem.add_dependency 'nokogiri', '~> 1.6.0'
|
24
24
|
gem.add_dependency 'thor', '~> 0.18.1'
|
data/spec/builders/epub_spec.rb
CHANGED
@@ -195,6 +195,7 @@ end
|
|
195
195
|
|
196
196
|
describe Softcover::Builders::Epub do
|
197
197
|
context "for a Markdown book" do
|
198
|
+
let(:unused_image) { File.basename(path('html/images/testimonial_1.png')) }
|
198
199
|
before(:all) do
|
199
200
|
generate_book(markdown: true)
|
200
201
|
@builder = Softcover::Builders::Epub.new
|
@@ -215,5 +216,9 @@ describe Softcover::Builders::Epub do
|
|
215
216
|
it "should remove the generated LaTeX files" do
|
216
217
|
expect(Dir.glob(path('chapters/*.tex'))).to be_empty
|
217
218
|
end
|
219
|
+
|
220
|
+
it "should not include an image not used in the document" do
|
221
|
+
expect(path("epub/OEBPS/images/#{unused_image}")).not_to exist
|
222
|
+
end
|
218
223
|
end
|
219
224
|
end
|
@@ -1,140 +1,140 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Softcover::Commands::Publisher do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
end
|
1
|
+
# require 'spec_helper'
|
2
|
+
|
3
|
+
# describe Softcover::Commands::Publisher do
|
4
|
+
# let(:book) { Softcover::Utils.current_book }
|
5
|
+
# before(:all) { generate_book }
|
6
|
+
# after(:all) { remove_book }
|
7
|
+
|
8
|
+
# let(:publish_options) { { remove_unused_media_bundles: true } }
|
9
|
+
|
10
|
+
# describe "#publish" do
|
11
|
+
# context "publishing from non book directory" do
|
12
|
+
# before do
|
13
|
+
# chdir_to_non_book
|
14
|
+
# end
|
15
|
+
|
16
|
+
# it "rejects the publish" do
|
17
|
+
# expect(subject.publish!).to be_false
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
# context "publishing from book directory" do
|
22
|
+
# before do
|
23
|
+
# chdir_to_book
|
24
|
+
# stub_create_book book
|
25
|
+
# stub_media_upload book
|
26
|
+
# end
|
27
|
+
|
28
|
+
# it "publishes" do
|
29
|
+
# expect(subject.publish!(publish_options)).to be_true
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
|
34
|
+
# describe "#unpublish" do
|
35
|
+
# context "unpublishing from non book directory" do
|
36
|
+
# before do
|
37
|
+
# chdir_to_non_book
|
38
|
+
# end
|
39
|
+
|
40
|
+
# it "rejects the unpublish" do
|
41
|
+
# expect(subject.unpublish!).to be_false
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
|
45
|
+
# context "unpublishing from book directory" do
|
46
|
+
# before do
|
47
|
+
# chdir_to_book
|
48
|
+
# stub_create_book book
|
49
|
+
# stub_media_upload book
|
50
|
+
# subject.publish! publish_options
|
51
|
+
# stub_destroy_book book
|
52
|
+
# end
|
53
|
+
|
54
|
+
# it "unpublishes" do
|
55
|
+
# expect(subject.unpublish!).to be_true
|
56
|
+
# end
|
57
|
+
|
58
|
+
# it "removes book config" do
|
59
|
+
# subject.unpublish!
|
60
|
+
# expect(Softcover::BookConfig.exists?).to be_false
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
|
64
|
+
# context "unpublishing from book directory with invalid ID" do
|
65
|
+
# before do
|
66
|
+
# chdir_to_book
|
67
|
+
# stub_create_book book
|
68
|
+
# stub_media_upload book
|
69
|
+
# subject.publish!(publish_options)
|
70
|
+
# Softcover::BookConfig['id'] = 0
|
71
|
+
# stub_destroy_book_not_found book
|
72
|
+
# end
|
73
|
+
|
74
|
+
# it "does not unpublish" do
|
75
|
+
# expect(subject.unpublish!).to be_false
|
76
|
+
# end
|
77
|
+
# end
|
78
|
+
|
79
|
+
# context "unpublishing outside book directory" do
|
80
|
+
# before do
|
81
|
+
# chdir_to_book
|
82
|
+
# stub_create_book book
|
83
|
+
# stub_media_upload book
|
84
|
+
# subject.publish! publish_options
|
85
|
+
# Dir.chdir(File.dirname(__FILE__))
|
86
|
+
# end
|
87
|
+
|
88
|
+
# context "with valid slug option" do
|
89
|
+
# before { stub_destroy_book_by_slug book }
|
90
|
+
|
91
|
+
# it "unpublishes" do
|
92
|
+
# expect(subject.unpublish!(book.slug)).to be_true
|
93
|
+
# end
|
94
|
+
# end
|
95
|
+
|
96
|
+
# context "with invalid slug option" do
|
97
|
+
# let(:slug) { "error" }
|
98
|
+
# before { stub_destroy_book_by_invalid_slug slug }
|
99
|
+
|
100
|
+
# it "does not unpublish" do
|
101
|
+
# expect(subject.unpublish!(slug)).to be_false
|
102
|
+
# end
|
103
|
+
# end
|
104
|
+
# end
|
105
|
+
# end
|
106
|
+
|
107
|
+
# describe "#publish_media" do
|
108
|
+
# before do
|
109
|
+
# chdir_to_book
|
110
|
+
# book.id = 1
|
111
|
+
# stub_media_upload book
|
112
|
+
# end
|
113
|
+
|
114
|
+
# # it "should start with 0 processed_media" do
|
115
|
+
# # expect(book.processed_media.length).to eq 0
|
116
|
+
# # end
|
117
|
+
|
118
|
+
# # it "processes media" do
|
119
|
+
# # subject.publish_media!
|
120
|
+
# # expect(book.processed_media.length).to be > 0
|
121
|
+
# # end
|
122
|
+
|
123
|
+
# # it "daemonizes" do
|
124
|
+
# # subject.should_receive(:fork) do |&blk|
|
125
|
+
# # blk.call
|
126
|
+
# # end
|
127
|
+
# # subject.publish_media! daemon: true
|
128
|
+
# # expect(book.processed_media.length).to be > 0
|
129
|
+
# # end
|
130
|
+
|
131
|
+
# # it "watches" do
|
132
|
+
# # subject.should_receive(:loop) do |&blk|
|
133
|
+
# # blk.call
|
134
|
+
# # end
|
135
|
+
# # subject.publish_media! watch: true
|
136
|
+
# # expect(book.processed_media.length).to be > 0
|
137
|
+
# # end
|
138
|
+
|
139
|
+
# end
|
140
|
+
# end
|
data/spec/webmock_helpers.rb
CHANGED
@@ -195,7 +195,8 @@ module WebmockHelpers
|
|
195
195
|
File.write(File.join('html', 'chapter-1_fragment.html'), 'test')
|
196
196
|
File.write(File.join('html', 'test_fragment.html'), 'test')
|
197
197
|
File.write(File.join('html', "#{name}.html"), 'test')
|
198
|
-
|
198
|
+
mkdir path('html/images')
|
199
|
+
mkdir 'ebooks'
|
199
200
|
Softcover::FORMATS.each do |format|
|
200
201
|
dir = format == 'html' ? 'html' : 'ebooks'
|
201
202
|
File.write(File.join(dir, "test-book.#{format}"), 'test')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: softcover
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.beta13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Hartl
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-10-
|
12
|
+
date: 2014-10-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: polytexnic
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 1.0.
|
20
|
+
version: 1.0.beta8
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 1.0.
|
27
|
+
version: 1.0.beta8
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: msgpack
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|