gepub 0.6.4.6 → 0.6.5.1

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.
data/gepub.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_development_dependency "rspec", ">= 2"
22
- s.add_runtime_dependency "nokogiri", ">= 1.5.0"
23
- s.add_runtime_dependency "rubyzip", ">= 0.9.6"
21
+ s.add_development_dependency "rspec", "~> 2"
22
+ s.add_runtime_dependency "nokogiri", "~> 1.5.0"
23
+ s.add_runtime_dependency "rubyzip", "= 0.9.6.1"
24
24
  end
data/lib/gepub/book.rb CHANGED
@@ -7,19 +7,23 @@ require 'fileutils'
7
7
  # = GEPUB
8
8
  # Author:: KOJIMA Satoshi
9
9
  # namespace for gepub library.
10
- # GEPUB::Book for parsing/generating, GEPUB::Builder for generating.
11
- # GEPUB::Item holds data of resources like xhtml text, css, scripts, images, videos, etc.
10
+ # The core class is GEPUB::Book. It holds metadata and contents of EPUB file. metadata and contents can be accessed
11
+ # through GEPUB::Meta and GEPUB::Item.
12
+ # For generating EPUB file, use GEPUB::Builder.
13
+ # GEPUB::Item holds information and data of resources like xhtml text, css, scripts, images, videos, etc.
12
14
  # GEPUB::Meta holds metadata(title, creator, publisher, etc.) with its information (alternate script, display sequence, etc.)
13
15
 
14
16
  module GEPUB
15
- # Book is the basic class to hold data in EPUB files.
17
+ # Book is the class to hold data in EPUB files.
16
18
  #
17
- # It can generate and parse EPUB2/EPUB3 files. For generating a new EPUB file,
18
- # consider to use GEPUB::Builder. Builder is specialized for generating EPUB,
19
- # very easy to use and can handle almost every metadata of EPUB3.
19
+ # It can generate and parse EPUB2/EPUB3 files.
20
+ #
21
+ # If you want to generate a new EPUB file, consider using GEPUB::Builder instead
22
+ # of using Book directly.
23
+ # Builder is a wrapper class of Book specialized for generating EPUB.
20
24
  #
21
25
  # Book delegates many methods to objects in other class, so you can't find
22
- # them in Book#methods or in ri/rdoc documentation. Their description is below.
26
+ # them in Book#methods or in ri/rdoc documentation. Their descriptions are below.
23
27
  #
24
28
  # == \Package Attributes
25
29
  # === Book#version (delegated to Package#version)
@@ -133,7 +137,7 @@ module GEPUB
133
137
  end
134
138
  }
135
139
  book = Book.new(package.path)
136
- book.instance_eval { @package = package; @stray_files = files }
140
+ book.instance_eval { @package = package; @optional_files = files }
137
141
  book
138
142
  }
139
143
  end
@@ -150,6 +154,22 @@ module GEPUB
150
154
  yield book if block_given?
151
155
  end
152
156
 
157
+
158
+ # Get optional(not required in EPUB specification) files in the container.
159
+ def optional_files
160
+ @optional_files || {}
161
+ end
162
+
163
+ # Add an optional file to the container
164
+ def add_optional_file(path, io_or_filename)
165
+ io = io_or_filename
166
+ if io_or_filename.class == String
167
+ io = File.new(io_or_filename)
168
+ end
169
+ io.binmode
170
+ (@optional_files ||= {})[path] = io.read
171
+ end
172
+
153
173
  # add navigation text (which will appear on navigation document or table of contents) to an item.
154
174
  # DEPRECATED: please use Item#toc_text or Item#toc_text_with_id, or Builder#heading
155
175
 
@@ -236,22 +256,30 @@ module GEPUB
236
256
  end
237
257
 
238
258
  # write EPUB to stream specified by the argument.
239
- def write_to_epub_container(epub)
259
+ def write_to_epub_container(epub)
240
260
  epub.put_next_entry('mimetype', '', '', Zip::ZipEntry::STORED)
241
261
  epub << "application/epub+zip"
242
- epub.put_next_entry('META-INF/container.xml')
243
- epub << container_xml.force_to_bin
244
262
 
245
- epub.put_next_entry(@package.path)
246
- epub << opf_xml.force_to_bin
263
+ entries = {}
264
+ optional_files.each {
265
+ |k, content|
266
+ entries[k] = content
267
+ }
247
268
 
269
+ entries['META-INF/container.xml'] = container_xml
270
+ entries[@package.path] = opf_xml
248
271
  @package.manifest.item_list.each {
249
272
  |k, item|
250
273
  if item.content != nil
251
- epub.put_next_entry(@package.contents_prefix + item.href)
252
- epub << item.content.force_to_bin
274
+ entries[@package.contents_prefix + item.href] = item.content
253
275
  end
254
276
  }
277
+
278
+ entries.sort_by { |k,v| k }.each {
279
+ |k,v|
280
+ epub.put_next_entry(k)
281
+ epub << v.force_to_bin
282
+ }
255
283
  end
256
284
 
257
285
  # generates and returns StringIO contains EPUB.
data/lib/gepub/builder.rb CHANGED
@@ -1,4 +1,152 @@
1
+ # -*- coding: utf-8 -*-
1
2
  module GEPUB
3
+ #
4
+ # Builder is a wrapper class of Book. It provides DSL to create new EPUB file.
5
+ #
6
+ # = Synopsys
7
+ # # -*- coding: utf-8 -*-
8
+ # # GEPUB::Builder example.
9
+ # require 'ruby gem'
10
+ # require 'gepub'
11
+ #
12
+ # builder = GEPUB::Builder.new {
13
+ # # In the root block, you can define metadata.
14
+ # # You can define title, creator(s), contributor(s), publisher(s), date, unique_identifier, identifier, language.
15
+ # # Title can be specified with title, subtitle, collection, short_title, expanded_title, edition.
16
+ # # You can also define description, format, relation, right, source, subject, type.
17
+ # # You can 'refine' last-defined metadata by refiner/attributes methods
18
+ # # Refiner methods contains : file_as, alt
19
+ #
20
+ #
21
+ # language 'ja'
22
+ #
23
+ # title 'タイトル'
24
+ # alt 'en' => 'main title'
25
+ # file_as 'main title'
26
+ #
27
+ # subtitle 'サブタイトル'
28
+ # alt 'en' => 'subtitle'
29
+ #
30
+ # # collection title and position in the collection:
31
+ # collection 'gepub sample book series', 2
32
+ #
33
+ # #specifying creator
34
+ # creator 'author1','aut'
35
+ # alt 'ja' =>'日本語名' ,'en' =>'english name for author1'
36
+ # id 'the_first_author'
37
+ #
38
+ # #specifying multiple creator
39
+ # creators 'author1', 'author2', ['editor1', 'edt']
40
+ #
41
+ # contributor 'contributor'
42
+ # contributors 'contributor1', 'contributor2'
43
+ # # easy way to write alt {'ja' =>'日本語 for contributor1'}, {'ja' => '日本語 for contributor2'}
44
+ # alts 'ja' => ['日本語 for contributor1','日本語 for contributor2']
45
+ #
46
+ # publisher '出版社'
47
+ # alt 'en' => 'ThePublisher'
48
+ #
49
+ # date '2012-02-21T00:00:00Z'
50
+ #
51
+ # unique_identifier 'the_unique_id_in_uuid', 'uuid'
52
+ # identifier 'http://other_id','url'
53
+ # identifier 'http://another_id','url'
54
+ #
55
+ # # in resources block, you can define resources by its relative path and datasource.
56
+ # # item creator methods are: files, file.
57
+ # resources(:workdir => '~/epub_source') {
58
+ # # Reads from file. in EPUB container, they are placed at the same path.
59
+ # file 'img/image0.jpg'
60
+ # files('img/image.jpg','img/image2.jpg')
61
+ # glob 'img/*.jpg' # means files(Dir.glob('img/*.jpg'))
62
+ #
63
+ # # Reads from file. will be placed at path indicated by key.
64
+ # files('img/image.jpg' => 'imgage.jpg')
65
+ #
66
+ # # Read from IO object.
67
+ # files('img/image.png' => supplied_io, 'img/image2.png' => supplied_io2)
68
+ #
69
+ # # this will be end in error:
70
+ # # files(io1, io2)
71
+ #
72
+ # # specify remote resource.
73
+ # # only referenced from the EPUB package.
74
+ # file 'http://example.com/video/remote_video.qt'
75
+ # media_type('video/quicktime')
76
+ #
77
+ # # specify media type.
78
+ # file 'resources/pv.mp4'
79
+ # media_type('video/mp4')
80
+ #
81
+ # files('audio/voice1.mp4','audio/music1.mp4')
82
+ # media_type('audio/mp4') # applied to all items in the line above.
83
+ #
84
+ # # media_type to some file
85
+ # with_media_type('video/mp4') {
86
+ # file 'resources/v1.mp4'
87
+ # file 'resources/v2.mp4'
88
+ # file 'resources/v3.mp4'
89
+ # }
90
+ #
91
+ # # with_media_type and media_type
92
+ # with_media_type('video/mp4') {
93
+ # file 'resources/v1.mp4'
94
+ # file 'resources/v2.mp4'
95
+ # file 'resources/a4.mp4'
96
+ # media_type 'audio/mp4' # override with_media_type
97
+ # }
98
+ #
99
+ # # Read from IO object: loop
100
+ # # supplied_IOs = { 'path' => io, 'path' => io... }
101
+ # supplied_IOs.each {
102
+ # |name, io|
103
+ # file name => io
104
+ # }
105
+ #
106
+ # file 'css/default.css'
107
+ #
108
+ # # indicate property.
109
+ # # this is cover image.
110
+ # cover_image 'img/cover.jpg'
111
+ #
112
+ # # this is navigation document.
113
+ # nav 'text/toc.xhtml'
114
+ #
115
+ # # ordered item. will be added to spine.
116
+ # ordered {
117
+ # # specify texts on table of contents for auto-generated toc.
118
+ # # (if you supply navigation document with method 'nav', 'heading' has no effect.)
119
+ # file('text/chap1.xhtml')
120
+ # heading 'Chapter 1'
121
+ # file 'text/chap2.xhtml'
122
+ #
123
+ # # fallback chain: style 1
124
+ # fallback_group {
125
+ # file 'chap3_docbook.xhtml'
126
+ # mimetype('application/docbook+xml')
127
+ # file 'chap3.xml'
128
+ # mimetype "application/z3986-auth+xml"
129
+ # file 'chap3.xhtml'
130
+ # }
131
+ #
132
+ # # fallback chain: style 2
133
+ # fallback_chain_files 'chap4_docbook.xhtml', 'chap4.xml', 'chap4.xhtml'
134
+ # mimetype('application/docbook+xml','application/z3986-auth+xml' 'application/xhtml+xml')
135
+ #
136
+ # # fallback chain: style 3 + with_mimetype
137
+ # with_mimetype('application/docbook+xml','application/z3986-auth+xml' 'application/xhtml+xml') {
138
+ # fallback_chain_files 'chap5_docbook.xhtml', 'chap5.xml', 'chap5.xhtml'
139
+ # fallback_chain_files 'chap6_docbook.xhtml', 'chap6.xml', 'chap6.xhtml'
140
+ # fallback_chain_files 'chap7_docbook.xhtml', 'chap7.xml', 'chap7.xhtml'
141
+ # }
142
+ #
143
+ # }
144
+ # }
145
+ # }
146
+ #
147
+ # builder.generate_epub('sample.epub')
148
+
149
+
2
150
  class Builder
3
151
  include BuilderMixin
4
152
  class MetaItem
@@ -112,6 +260,21 @@ module GEPUB
112
260
  MetaItem.new(@book.add_contributor(val, nil, role))
113
261
  end
114
262
 
263
+ # set optional file.
264
+ # val should be String or Hash.
265
+ # if val is String, file is read from the File specified by string and stored in EPUB to the path specified by string.
266
+ # if val is Hash, file is read from the value and stored in EPUB to the path specified by the key.
267
+ def optional_file(val)
268
+ path = val
269
+ io = val if String === val
270
+ if Hash === val
271
+ raise 'argument to optional_file should be length 1' if val.size != 1
272
+ path = val.first[0]
273
+ io = val.first[1]
274
+ end
275
+ @book.add_optional_file(path, io)
276
+ end
277
+
115
278
  def generate_epub(path_to_epub)
116
279
  @book.generate_epub(path_to_epub)
117
280
  end
data/lib/gepub/item.rb CHANGED
@@ -1,4 +1,10 @@
1
1
  module GEPUB
2
+ #
3
+ # an Object to hold metadata and content of item in manifest.
4
+ #
5
+ # following methods are created dynamically.
6
+ # #id, #id=, #set_id, #href, #href=, #set_href, #media_type, #media_type=, #set_media_type,
7
+ # #fallback, #fallback=, #set_fallback, #media_overlay, #media_overlay=, #set_media_overlay
2
8
  class Item
3
9
  attr_accessor :content
4
10
  def self.create(parent, attributes = {})
@@ -6,6 +12,12 @@ module GEPUB
6
12
  attributes.reject { |k,v| ['id','href','media-type'].member?(k) })
7
13
  end
8
14
 
15
+ #
16
+ # create Item.
17
+ #
18
+ # if mediatype is not specified, it will be guessed from extension name.
19
+ # Item can't guess media type for videos and audios, so you should specify one.
20
+ #
9
21
  def initialize(itemid, itemhref, itemmediatype = nil, parent = nil, attributes = {})
10
22
  if attributes['properties'].class == String
11
23
  attributes['properties'] = attributes['properties'].split(' ')
@@ -14,7 +26,6 @@ module GEPUB
14
26
  @attributes['media-type'] = guess_mediatype if media_type.nil?
15
27
  @parent = parent
16
28
  @parent.register_item(self) unless @parent.nil?
17
- @content_callback = []
18
29
  self
19
30
  end
20
31
 
@@ -25,14 +36,16 @@ module GEPUB
25
36
  define_method(methodbase) { @attributes[name] }
26
37
  }
27
38
 
39
+ # get item's id
28
40
  def itemid
29
41
  id
30
42
  end
31
43
 
44
+ # get mediatype of the item.
32
45
  def mediatype
33
46
  media_type
34
47
  end
35
-
48
+
36
49
  def [](x)
37
50
  @attributes[x]
38
51
  end
@@ -40,28 +53,61 @@ module GEPUB
40
53
  def []=(x,y)
41
54
  @attributes[x] = y
42
55
  end
43
-
56
+
57
+ # add value to properties attribute.
44
58
  def add_property(property)
45
59
  (@attributes['properties'] ||=[]) << property
46
60
  self
47
61
  end
48
62
 
63
+ # set 'cover-image' property to the Item.
64
+ # On generating EPUB, EPUB2-style cover image meta item will be added.
49
65
  def cover_image
50
66
  add_property('cover-image')
51
67
  end
52
68
 
69
+ # set 'nav' property to the Item.
53
70
  def nav
54
71
  add_property('nav')
55
72
  end
56
73
 
57
- def add_raw_content(data)
58
- @content = data
74
+ # guess and set content property from contents.
75
+ def guess_content_property
76
+ if File.extname(self.href) =~ /.x?html/
77
+ @attributes['properties'] = (@attributes['properties'] || []).reject {
78
+ |x| x == 'svg' || x == 'mathml' || x == 'switch' || x == 'remote-resources'
79
+ }
80
+ parsed = Nokogiri::XML::Document.parse(@content)
81
+ ns_prefix = parsed.namespaces.invert['http://www.w3.org/1999/xhtml']
82
+ if ns_prefix.nil?
83
+ prefix = ''
84
+ else
85
+ prefix = "#{ns_prefix}:"
86
+ end
87
+ videos = parsed.xpath("//#{prefix}video[starts-with(@src,'http')]")
88
+ audios = parsed.xpath("//#{prefix}audio[starts-with(@src,'http')]")
89
+ if videos.size > 0 || audios.size > 0
90
+ self.add_property('remote-resources')
91
+ end
92
+ if parsed.xpath("//p:math", { 'p' => 'http://www.w3.org/1998/Math/MathML' }).size > 0
93
+ self.add_property('mathml')
94
+ end
95
+ if parsed.xpath("//s:svg", { 's' => 'http://www.w3.org/2000/svg' }).size > 0
96
+ self.add_property('svg')
97
+ end
98
+ if parsed.xpath("//epub:switch", { 'epub' => 'http://www.idpf.org/2007/ops' }).size > 0
99
+ self.add_property('switch')
100
+ end
101
+ end
59
102
  end
60
103
 
61
- def push_content_callback(&block)
62
- @content_callback << block
104
+ # add content data to the item.
105
+ def add_raw_content(data)
106
+ @content = data
107
+ guess_content_property
63
108
  end
64
109
 
110
+ # add content form io or file to the item
65
111
  def add_content(io_or_filename)
66
112
  io = io_or_filename
67
113
  if io_or_filename.class == String
@@ -69,23 +115,11 @@ module GEPUB
69
115
  end
70
116
  io.binmode
71
117
  @content = io.read
72
- if File.extname(self.href) =~ /.x?html/
73
- parsed = Nokogiri::XML::Document.parse(@content)
74
- ns_prefix = parsed.namespaces.invert['http://www.w3.org/1999/xhtml']
75
- if ns_prefix.nil?
76
- prefix = ''
77
- else
78
- prefix = "#{ns_prefix}:"
79
- end
80
- videos = parsed.xpath("//#{prefix}video[starts-with(@src,'http')]")
81
- audios = parsed.xpath("//#{prefix}audio[starts-with(@src,'http')]")
82
- if videos.size > 0 || audios.size > 0
83
- self.add_property('remote-resources')
84
- end
85
- end
118
+ guess_content_property
86
119
  self
87
120
  end
88
121
 
122
+ # generate xml to supplied Nokogiri builder.
89
123
  def to_xml(builder, opf_version = '3.0')
90
124
  attr = @attributes.dup
91
125
  if opf_version.to_f < 3.0
@@ -93,6 +127,9 @@ module GEPUB
93
127
  end
94
128
  if !attr['properties'].nil?
95
129
  attr['properties'] = attr['properties'].join(' ')
130
+ if attr['properties'].size == 0
131
+ attr.delete 'properties'
132
+ end
96
133
  end
97
134
  builder.item(attr)
98
135
  end
@@ -0,0 +1,11 @@
1
+ require 'zip/zip'
2
+
3
+ module Zip
4
+ class ZipCentralDirectory
5
+ def write_to_stream(io) #:nodoc:
6
+ offset = io.tell
7
+ @entrySet.each { |entry| entry.write_c_dir_entry(io) }
8
+ write_e_o_c_d(io, offset)
9
+ end
10
+ end
11
+ end
data/lib/gepub/version.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  module GEPUB
2
- VERSION = "0.6.4.6"
2
+ # GEPUB gem version
3
+ VERSION = "0.6.5.1"
3
4
  end
data/lib/gepub.rb CHANGED
@@ -18,7 +18,7 @@ else
18
18
  end
19
19
  end
20
20
 
21
-
21
+ require 'gepub/rubyzip_patch'
22
22
  require 'gepub/version'
23
23
  require 'gepub/xml_util'
24
24
  require 'gepub/meta'
data/spec/builder_spec.rb CHANGED
@@ -437,5 +437,65 @@ describe GEPUB::Builder do
437
437
  }
438
438
  # this should not raise 'No such file or directory'
439
439
  end
440
+
441
+ it 'should handle mathml' do
442
+ builder = GEPUB::Builder.new {
443
+ unique_identifier 'uid'
444
+ resources {
445
+ file 'mathml.xhtml' => StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"><head></head><body><div><p><math xmlns="http://www.w3.org/1998/Math/MathML"></math></p></div></body></html>')
446
+ }
447
+ }
448
+ builder.instance_eval {
449
+ @book.item_by_href('mathml.xhtml').properties[0].should == 'mathml'
450
+ }
451
+ end
452
+
453
+ it 'should handle svg' do
454
+ builder = GEPUB::Builder.new {
455
+ unique_identifier 'uid'
456
+ resources {
457
+ file 'svg.xhtml' => StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"><head></head><body><div><p><svg xmlns="http://www.w3.org/2000/svg"></svg></p></div></body></html>')
458
+ }
459
+ }
460
+ builder.instance_eval {
461
+ @book.item_by_href('svg.xhtml').properties[0].should == 'svg'
462
+ }
463
+ end
464
+
465
+ it 'should handle epub:switch' do
466
+ builder = GEPUB::Builder.new {
467
+ unique_identifier 'uid'
468
+ resources {
469
+ file 'switch.xhtml' => StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"><head></head><body><div><p>
470
+ <epub:switch>
471
+ <epub:case required-namespace="http://www.xml-cml.org/schema">
472
+ <cml xmlns="http://www.xml-cml.org/schema">
473
+ <molecule id="sulfuric-acid">
474
+ <formula id="f1" concise="H 2 S 1 O 4"/>
475
+ </molecule>
476
+ </cml>
477
+ </epub:case>
478
+ <epub:default>
479
+ <p>H<sub>2</sub>SO<sub>4</sub></p>
480
+ </epub:default>
481
+ </epub:switch></p></div></body></html>')
482
+ }
483
+ }
484
+ builder.instance_eval {
485
+ @book.item_by_href('switch.xhtml').properties[0].should == 'switch'
486
+ }
487
+ end
488
+
489
+ it 'should handle optional file' do
490
+ builder = GEPUB::Builder.new {
491
+ optional_file 'META-INF/test.xml' => StringIO.new('<test></test>')
492
+ }
493
+ builder.instance_eval {
494
+ @book.optional_files.size.should == 1
495
+ }
496
+ builder.instance_eval {
497
+ @book.optional_files['META-INF/test.xml']
498
+ }.should_not be_nil
499
+ end
440
500
  end
441
501
  end
data/spec/gepub_spec.rb CHANGED
@@ -189,6 +189,12 @@ EOF
189
189
  jar = File.join(File.dirname(__FILE__), 'fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar')
190
190
  system 'java', '-jar', jar, epubname
191
191
  end
192
-
192
+ it 'should generate epub with extra file' do
193
+ epubname = File.join(File.dirname(__FILE__), 'testepub3.epub')
194
+ @book.add_optional_file('META-INF/foobar.xml', StringIO.new('<foo></foo>'))
195
+ @book.generate_epub(epubname)
196
+ jar = File.join(File.dirname(__FILE__), 'fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar')
197
+ system 'java', '-jar', jar, epubname
198
+ end
193
199
 
194
200
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gepub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4.6
4
+ version: 0.6.5.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,41 +9,41 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-04 00:00:00.000000000 Z
12
+ date: 2012-03-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70096651811060 !ruby/object:Gem::Requirement
16
+ requirement: &70119775057080 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ! '>='
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
21
  version: '2'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70096651811060
24
+ version_requirements: *70119775057080
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: nokogiri
27
- requirement: &70096651810400 !ruby/object:Gem::Requirement
27
+ requirement: &70119775056340 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
- - - ! '>='
30
+ - - ~>
31
31
  - !ruby/object:Gem::Version
32
32
  version: 1.5.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70096651810400
35
+ version_requirements: *70119775056340
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rubyzip
38
- requirement: &70096651809700 !ruby/object:Gem::Requirement
38
+ requirement: &70119775055860 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
- - - ! '>='
41
+ - - =
42
42
  - !ruby/object:Gem::Version
43
- version: 0.9.6
43
+ version: 0.9.6.1
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70096651809700
46
+ version_requirements: *70119775055860
47
47
  description: gepub is a generic EPUB parser/generator. Generates and parse EPUB2 and
48
48
  EPUB3
49
49
  email:
@@ -76,6 +76,7 @@ files:
76
76
  - lib/gepub/metadata.rb
77
77
  - lib/gepub/package.rb
78
78
  - lib/gepub/resource_builder.rb
79
+ - lib/gepub/rubyzip_patch.rb
79
80
  - lib/gepub/spine.rb
80
81
  - lib/gepub/version.rb
81
82
  - lib/gepub/xml_util.rb