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 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