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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 033a4f5bb876e155ec539601a573de4863929520
4
- data.tar.gz: 3230a32fdc25feb8c0b01fb23b54fec4a44bce19
3
+ metadata.gz: 1177c81d0740d0a59f58d8dde203c7ccfff1ab9e
4
+ data.tar.gz: a50db48e9f39cea1a47134b4767d1037cb8737de
5
5
  SHA512:
6
- metadata.gz: e69446d316a0dc4e8c6cccb58e2499e3f074f6f1fa86350768224c48172f4e416561992f67b85520a73ea01fc1b7da099e0b943836300ec889be019098ac515f
7
- data.tar.gz: 3bfb0a6b45d1b81750292deeed8f7f81dbfbfc4e7442a4a5bef527c110ea2cf5f7325dd9c4a382add8d73027f600d0475c0cab1c8571445924b6d43b21cb4360
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
- file = Dir[path("#{images_dir}/cover.#{ext}")].first
11
- return File.basename(file) if file
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
- File.delete(*Dir['epub/OEBPS/images/**/*.pdf'])
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/cli/cli-index.html)"
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})"
@@ -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')`.
@@ -1,3 +1,3 @@
1
1
  module Softcover
2
- VERSION = "1.0.beta12"
2
+ VERSION = "1.0.beta13"
3
3
  end
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.beta7'
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'
@@ -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
- 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
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
@@ -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
- File.mkdir 'ebooks' unless File.exist?('ebooks')
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.beta12
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-09 00:00:00.000000000 Z
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.beta7
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.beta7
27
+ version: 1.0.beta8
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: msgpack
30
30
  requirement: !ruby/object:Gem::Requirement