softcover 1.0.beta12 → 1.0.beta13
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.
- 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
|