bindery 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,18 +19,22 @@ module Bindery
19
19
  def chapter(title, filename, options={}, &block)
20
20
  div('chapter', title, filename, options, &block)
21
21
  end
22
-
22
+
23
23
  def section(title, filename, options={}, &block)
24
24
  div('section', title, filename, options, &block)
25
25
  end
26
-
26
+
27
27
  def part(title, filename, options={}, &block)
28
28
  div('part', title, filename, options, &block)
29
29
  end
30
-
30
+
31
31
  def appendix(title, filename, options={}, &block)
32
32
  div('appendix', title, filename, options, &block)
33
33
  end
34
-
34
+
35
+ def index(title, filename, options={}, &block)
36
+ div('index', title, filename, options, &block)
37
+ end
38
+
35
39
  end
36
40
  end
@@ -6,14 +6,14 @@ module Bindery
6
6
  attr_accessor :options
7
7
 
8
8
  include ContentMethods
9
-
9
+
10
10
  def initialize(div_type, title, file, options)
11
11
  self.div_type = div_type
12
12
  self.title = title
13
13
  self.file = file
14
14
  self.options = options
15
15
  end
16
-
16
+
17
17
  def valid?
18
18
  true
19
19
  # ??? title specified? Is this required by the spec? Think about
@@ -25,17 +25,17 @@ module Bindery
25
25
  # chapters that would break up the text flow?
26
26
  # file exists, readable
27
27
  # file content properly formed? Does that matter? Can we
28
- # verify it?
28
+ # verify it?
29
29
  end
30
30
 
31
31
  def divisions
32
32
  @divisions ||= []
33
33
  end
34
-
34
+
35
35
  def body_only?
36
36
  options.fetch(:body_only, true)
37
37
  end
38
-
38
+
39
39
  def include_images?
40
40
  options.fetch(:include_images, true)
41
41
  end
@@ -2,10 +2,11 @@ require 'builder'
2
2
  require 'zip'
3
3
  require 'bindery/extensions/zip_file'
4
4
  require 'nokogiri'
5
+ require 'uri'
5
6
 
6
7
  module Bindery
7
8
  module Formats
8
-
9
+
9
10
  # Builds an EPUB book file from the book description.
10
11
  #
11
12
  # The {EPUB Wikipedia entry}[http://en.wikipedia.org/wiki/EPUB] provides a nice, concise overview of the EPUB format.
@@ -20,25 +21,25 @@ module Bindery
20
21
  # * Details of the format of other files allowed in EPUB documents are found in
21
22
  # {Open Publication Structure (OPS) 2.0.1 - Recommended Specification}[http://idpf.org/epub/20/spec/OPS_2.0.1_draft.htm].
22
23
  class Epub
23
-
24
+
24
25
  MimeTypes = {
25
26
  '.jpg' => 'image/jpeg',
26
27
  '.png' => 'image/png',
27
28
  '.gif' => 'image/gif',
28
29
  }
29
-
30
+
30
31
  class ManifestEntry < Struct.new(:file_name, :xml_id, :mime_type)
31
32
  end
32
-
33
+
33
34
  attr_accessor :book, :manifest_entries
34
-
35
+
35
36
  def initialize(book)
36
37
  self.book = book
37
38
  book.extend BookMethods
38
39
  book.divisions.each{|division| division.extend DivisionMethods}
39
40
  self.manifest_entries = []
40
41
  end
41
-
42
+
42
43
  def generate
43
44
  File.delete(book.epub_output_file) if File.exist?(book.epub_output_file)
44
45
  Zip::ZipFile.open(book.epub_output_file, Zip::ZipFile::CREATE) do |zipfile|
@@ -46,12 +47,12 @@ module Bindery
46
47
  zipfile.write_uncompressed_file 'mimetype', mimetype
47
48
  zipfile.mkdir 'META-INF'
48
49
  zipfile.write_file 'META-INF/container.xml', container
49
-
50
+
50
51
  # also frontmatter, backmatter
51
52
  book.divisions.each do |division|
52
53
  write_division(division, zipfile)
53
54
  end
54
-
55
+
55
56
  zipfile.mkdir 'css'
56
57
  zipfile.write_file 'css/book.css', stylesheet
57
58
 
@@ -59,13 +60,13 @@ module Bindery
59
60
  zipfile.write_file 'book.ncx', ncx
60
61
  end
61
62
  end
62
-
63
+
63
64
  def mimetype
64
65
  # the mimetype file must be the first file in the archive
65
66
  # it must be ASCII, uncompressed, and unencrypted
66
67
  'application/epub+zip'
67
68
  end
68
-
69
+
69
70
  def container
70
71
  %q{|<?xml version="1.0" encoding="UTF-8" ?>
71
72
  |<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
@@ -75,23 +76,23 @@ module Bindery
75
76
  |</container>
76
77
  |}.strip_margin
77
78
  end
78
-
79
+
79
80
  def opf
80
81
  xm = Builder::XmlMarkup.new(:indent => 2)
81
82
  xm.instruct!
82
83
  xm.package('version'=>'2.0', 'xmlns'=>'http://www.idpf.org/2007/opf', 'unique-identifier'=>'BookId') {
83
-
84
+
84
85
  xm.metadata('xmlns:dc'=>'http://purl.org/dc/elements/1.1/', 'xmlns:opf'=>'http://www.idpf.org/2007/opf') {
85
86
  # required elements
86
87
  xm.dc :title, book.full_title
87
88
  xm.dc :language, book.language
88
89
  xm.dc :identifier, book.url, ident_options('opf:scheme'=>'URL') if book.url
89
- xm.dc :identifier, book.isbn, ident_options('opf:scheme'=>'ISBN') if book.isbn
90
-
90
+ xm.dc :identifier, book.isbn, ident_options('opf:scheme'=>'ISBN') if book.isbn
91
+
91
92
  # optional elements
92
93
  xm.dc :creator, book.author, 'opf:role'=>'aut' if book.author
93
94
  }
94
-
95
+
95
96
  xm.manifest {
96
97
  book.divisions.each{|division| division.write_item(xm)}
97
98
  # also frontmatter, backmatter
@@ -102,17 +103,17 @@ module Bindery
102
103
  # xm.item 'id'=>'myfont', 'href'=>'css/myfont.otf', 'media-type'=>'application/x-font-opentype'
103
104
  xm.item 'id'=>'ncx', 'href'=>'book.ncx', 'media-type'=>'application/x-dtbncx+xml'
104
105
  }
105
-
106
+
106
107
  xm.spine('toc'=>'ncx') {
107
108
  book.divisions.each{|division| division.write_itemref(xm)}
108
109
  }
109
-
110
+
110
111
  # xm.guide {
111
112
  # xm.reference 'type'='loi', 'title'=>'List of Illustrations', 'href'=>'appendix.html#figures'
112
113
  # }
113
114
  }
114
115
  end
115
-
116
+
116
117
  def ncx
117
118
  xm = Builder::XmlMarkup.new(:indent => 2)
118
119
  xm.instruct!
@@ -124,18 +125,18 @@ module Bindery
124
125
  xm.meta 'name'=>'dtb:totalPageCount', 'content'=>0
125
126
  xm.meta 'name'=>'dtb:maxPageNumber', 'content'=>0
126
127
  }
127
-
128
+
128
129
  xm.docTitle {
129
130
  xm.text book.full_title
130
131
  }
131
-
132
+
132
133
  xm.docAuthor {
133
134
  xm.text book.author
134
135
  }
135
-
136
+
136
137
  xm.navMap {
137
138
  play_order = 0
138
-
139
+
139
140
  # also frontmatter, backmatter
140
141
  book.divisions.each do |division|
141
142
  play_order += 1
@@ -174,7 +175,7 @@ module Bindery
174
175
  write_division(div, zipfile)
175
176
  end
176
177
  end
177
-
178
+
178
179
  def include_images(doc, zipfile)
179
180
  # TODO: where else can images appear? Style sheets?
180
181
  zipfile.mkdir('images') unless zip_dir_exists?(zipfile, 'images')
@@ -195,12 +196,12 @@ module Bindery
195
196
  end
196
197
  end
197
198
  end
198
-
199
+
199
200
  def add_manifest_entry(file_name)
200
201
  xml_id, ext = File.base_parts(file_name.gsub('/', '-'))
201
202
  manifest_entries << ManifestEntry.new(file_name, xml_id, MimeTypes[ext])
202
203
  end
203
-
204
+
204
205
  def cover
205
206
  xm = Builder::XmlMarkup.new(:indent => 2)
206
207
  xm.instruct!
@@ -223,7 +224,7 @@ module Bindery
223
224
  }
224
225
  }
225
226
  end
226
-
227
+
227
228
  def stylesheet
228
229
  # This is a start, but needs work.
229
230
  %q{|@page {
@@ -257,7 +258,7 @@ module Bindery
257
258
  |h3.section_title {text-align: center;}
258
259
  |}.strip_margin
259
260
  end
260
-
261
+
261
262
  def ident_options(opts)
262
263
  if book.isbn
263
264
  return opts.merge('id'=>'BookId') if opts['opf:scheme'] == 'ISBN'
@@ -266,18 +267,19 @@ module Bindery
266
267
  end
267
268
  opts
268
269
  end
269
-
270
+
270
271
  def zip_dir_exists?(zipfile, dirname)
271
272
  dirname = "#{dirname}/" unless dirname =~ %r{/$}
272
273
  zipfile.entries.any?{|e| e.directory? && e.name == dirname}
273
274
  end
274
-
275
+
275
276
  def zip_file_exists?(zipfile, filename)
276
277
  zipfile.entries.any?{|e| e.name == filename}
277
278
  end
278
-
279
+
279
280
  def make_image_file_name(zipfile, url)
280
- stem, ext = File.base_parts(url)
281
+ uri = URI(url)
282
+ stem, ext = File.base_parts(uri.path)
281
283
  filename = "images/#{stem}#{ext}"
282
284
  n = 0
283
285
  while zip_file_exists?(zipfile, filename)
@@ -286,31 +288,31 @@ module Bindery
286
288
  end
287
289
  filename
288
290
  end
289
-
291
+
290
292
  module BookMethods
291
293
  def epub_output_file
292
294
  @epub_output_file ||= "#{output}.epub"
293
295
  end
294
-
296
+
295
297
  def depth
296
298
  (divisions.map(&:depth) + [0]).max
297
299
  end
298
-
300
+
299
301
  def ident
300
302
  isbn || url
301
303
  end
302
304
  end
303
-
305
+
304
306
  module DivisionMethods
305
307
 
306
308
  def self.extended(obj)
307
309
  obj.divisions.each{|division| division.extend DivisionMethods}
308
310
  end
309
-
311
+
310
312
  def epub_id
311
313
  @epub_id ||= File.stemname(file)
312
314
  end
313
-
315
+
314
316
  def epub_output_file
315
317
  @epub_output_file ||= "#{epub_id}.xhtml"
316
318
  end
@@ -346,14 +348,14 @@ module Bindery
346
348
  end
347
349
 
348
350
  end
349
-
351
+
350
352
  module MetadataMethods
351
353
  def to_xml(builder)
352
354
  builder.meta(options.merge(:name => name, :content => value))
353
355
  %{<dc:#{name}>#{value}</dc:#{name}>}
354
356
  end
355
357
  end
356
-
358
+
357
359
  module DublinMetadataMethods
358
360
  def to_xml(builder)
359
361
  builder.dc name, value, options
@@ -1,3 +1,3 @@
1
1
  module Bindery
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bindery
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-16 00:00:00.000000000 Z
12
+ date: 2016-06-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: builder
@@ -173,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
173
  version: '0'
174
174
  segments:
175
175
  - 0
176
- hash: -394401607600380017
176
+ hash: 4117656268896811284
177
177
  requirements: []
178
178
  rubyforge_project: bindery
179
179
  rubygems_version: 1.8.23