epub-parser 0.1.8 → 0.1.9

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: 0e0b5095d398c04f70b55444777389325b51b34a
4
- data.tar.gz: f34bca3b4e1f8840b4caa58b11ffc00b95855794
3
+ metadata.gz: 1b57da74df66cba76e58cbb0098d7d5618ec1188
4
+ data.tar.gz: 66d1bf92e61f15da35215d0d46638ec7801e5993
5
5
  SHA512:
6
- metadata.gz: bd4a31dca34f82fbc9eca34f53b3b5806c99cb91257c7efe97b1f1eca35edcf9beda7a38ee62eb3a43953587beab6283353fb94e9add1858acdb599750c32ee3
7
- data.tar.gz: 719e99aad4b05a6f784e9c69f438f98319be7c330f70fb79531e41d1ec9b027893de4d01875f0ee3cca23a443606f744c6699c7e635159145bfeeeed07fd41f3
6
+ metadata.gz: 2a499a7de09c4b906b84d63e10e104f3dd00d028f8e4700a979343cbcade7edd06f63d3651422070a55139de64461b4fcf5b3edb46de477d8fe1d5e675509a01
7
+ data.tar.gz: 2b223250e08e3e9061042bbcd7b9e36662ac86542a7144e84bac71081f18b7b591fcf0acb03c6cfec14ac24b1b3fa256ede7ff2fedb6c0d0807ec14a7267387a
data/.travis.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  rvm:
2
- - "1.9.3"
3
2
  - "2.0.0"
4
3
  - "2.1.0"
4
+ - "2.2.0"
data/CHANGELOG.markdown CHANGED
@@ -1,6 +1,18 @@
1
1
  CHANGELOG
2
2
  =========
3
3
 
4
+ 0.1.9
5
+ -----
6
+
7
+ * Introduce [Nokogumbo][] for XHTML Content Documents
8
+ * Stop support for Ruby 1.9
9
+ * Remove `EPUB.included` method. Now including `EPUB` module empowers nothing of EPUB features. Include `EPUB::Book::Features` instead.
10
+ * Add `EPUB::Searcher::XHTML::Seamless` and make it default searcher
11
+ * Add `EPUB::Publication::Package::Manifest#each_nav`
12
+ * Stop to use enumerabler gem
13
+
14
+ [nokogumbo]: https://github.com/rubys/nokogumbo/
15
+
4
16
  0.1.8
5
17
  -----
6
18
 
data/README.markdown CHANGED
@@ -92,7 +92,7 @@ See {file:docs/EpubOpen} for more info.
92
92
 
93
93
  REQUIREMENTS
94
94
  ------------
95
- * Ruby 1.9.3 or later
95
+ * Ruby 2.0.0 or later
96
96
  * `patch` command to install Nokogiri
97
97
  * C compiler to compile Zip/Ruby and Nokogiri
98
98
 
@@ -110,6 +110,16 @@ If you find other gems, please tell me or request a pull request.
110
110
  RECENT CHANGES
111
111
  --------------
112
112
 
113
+ ### 0.1.9
114
+
115
+ * Introduce [Nokogumbo][] for XHTML Content Documents
116
+ * Stop support for Ruby 1.9
117
+ * Remove `EPUB.included` method. Now including `EPUB` module empowers nothing of EPUB features. Include `EPUB::Book::Features` instead.
118
+ * Add `EPUB::Searcher::XHTML::Seamless` and make it default searcher
119
+ * Add `EPUB::Publication::Package::Manifest#each_nav`
120
+
121
+ [nokogumbo]: https://github.com/rubys/nokogumbo/
122
+
113
123
  ### 0.1.8
114
124
 
115
125
  * Explicity #close each zip member file that has been opened via #fopen(Thanks [xunker][]!)
@@ -125,32 +135,6 @@ RECENT CHANGES
125
135
  * [Experimental]Add `EPUB::Searcher` module. See {file:Searcher.markdown} for details
126
136
  * Detect and set character encoding in `EPUB::Publication::Package::Item#read`
127
137
 
128
- ### 0.1.6
129
- * Remove `EPUB.parse` method
130
- * Remove `EPUB::Publication::Package::Metadata#to_hash`
131
- * Add `EPUB::Publication::Package::Metadata::Identifier`
132
- * Remove `MethodDecorators::Deprecated`
133
- * Make `EPUB::Parser::OCF::CONTAINER_FILE` and other constants deprecated
134
- * Make `EPUB::Publication::Package::Metadata::Link#rel` a `Set`
135
- * Add exception class `EPUB::Constants::MediaType::UnsupportedMediaType`
136
- * Make `EPUB::Constants::MediaType::UnsupportedError` deprecated
137
- * Add `EPUB::Publication::Package::Item#find_item_by_relative_iri`
138
- * Add `EPUB::Publication::Package::Item#cover_image?`
139
- * Add `EPUB::Book::Features` module and move methods of `EPUB` module to it.(Thanks, [takahashim][]!)
140
- * Make including `EPUB` deprecated
141
- * Parse `hidden` attribute of `nav` elements
142
- * [Experimental]Add `EPUB::ContentDocument::Navigation::Item#traverse`
143
-
144
- [takahashim]: https://github.com/takahashim
145
-
146
- ### 0.1.5
147
- * Add `ContentDocument::XHTML#title`
148
- * Add `Manifest::Item#xhtml?`
149
- * Add `--words` and `--char` options to `epubinfo` command
150
- * API change: `OCF::Container::Rootfile#full_path` became Addressable::URI object rather than `String`
151
- * Add `ContentDocument::XHTML#rexml` and `#nokogiri`
152
- * Inspect more readably
153
-
154
138
  See {file:CHANGELOG.markdown} for older changelogs and details.
155
139
 
156
140
  TODOS
data/Rakefile CHANGED
@@ -51,18 +51,5 @@ namespace :doc do
51
51
  end
52
52
 
53
53
  namespace :gem do
54
- desc "Build epub-parser-#{EPUB::Parser::VERSION}.gem into the pkg directory."
55
- task :build do
56
- Bundler::GemHelper.new.build_gem
57
- end
58
-
59
- desc "Build and install epub-parser-#{EPUB::Parser::VERSION}.gem into system gems."
60
- task :install do
61
- Bundler::GemHelper.new.install_gem
62
- end
63
-
64
- desc "Create tag v#{EPUB::Parser::VERSION} and build and push epub-parser-#{EPUB::Parser::VERSION}.gem to Rubygems"
65
- task :release => :test do
66
- Bundler::GemHelper.new.release_gem
67
- end
54
+ Bundler::GemHelper.install_tasks
68
55
  end
data/docs/Home.markdown CHANGED
@@ -56,7 +56,7 @@ And {EPUB::Publication::Package::Manifest::Item Item} provides syntax suger {EPU
56
56
 
57
57
  For several utilities of Item, see {file:docs/Item.markdown} page.
58
58
 
59
- By the way, although `book` above is a {EPUB::Book} object, all features are provided by {EPUB} module. Therefore YourBook class can include the features of {EPUB}:
59
+ By the way, although `book` above is a {EPUB::Book} object, all features are provided by {EPUB::Book::Features} module. Therefore YourBook class can include the features of {EPUB::Book::Features}:
60
60
 
61
61
  require 'epub'
62
62
 
@@ -99,7 +99,7 @@ More documentations are avaiable in:
99
99
  Requirements
100
100
  ------------
101
101
 
102
- * Ruby 1.9.3 or later
102
+ * Ruby 2.0.0 or later
103
103
  * C compiler to compile Zip/Ruby and Nokogiri
104
104
 
105
105
  Note
@@ -10,35 +10,35 @@ Example
10
10
 
11
11
  epub = EPUB::Parser.parse('childrens-literature-20130206.epub')
12
12
  search_word = 'INTRODUCTORY'
13
- results = EPUB::Searcher.search(epub.package, search_word)
14
- # => [#<EPUB::Searcher::Result:0x007f74d2b31548
15
- # @end_steps=[#<EPUB::Searcher::Result::Step:0x007f74d2b7baa8 @index=12, @type=:character>],
13
+ results = EPUB::Searcher.search(epub, search_word)
14
+ # => [#<EPUB::Searcher::Result:0x007f938ed517a8
15
+ # @end_steps=[#<EPUB::Searcher::Result::Step:0x007f938ed51a50 @index=12, @info={}, @type=:character>],
16
16
  # @parent_steps=
17
- # [#<EPUB::Searcher::Result::Step:0x007f74d2b81318 @index=2, @name="spine", @type=:element>,
18
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b7f4c8 @index=1, @type=:itemref>,
19
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b7d560 @index=1, @name="body", @type=:element>,
20
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b7d308 @index=0, @name="nav", @type=:element>,
21
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b7cdb8 @index=1, @name="ol", @type=:element>,
22
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b7cb38 @index=0, @name="li", @type=:element>,
23
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b7c5e8 @index=1, @name="ol", @type=:element>,
24
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b7bf80 @index=1, @name="li", @type=:element>,
25
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b7bd28 @index=0, @name="a", @type=:element>,
26
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b7bb70 @index=0, @type=:text>],
27
- # @start_steps=[#<EPUB::Searcher::Result::Step:0x007f74d2b7baf8 @index=0, @type=:character>]>,
28
- # #<EPUB::Searcher::Result:0x007f74d294e258
29
- # @end_steps=[#<EPUB::Searcher::Result::Step:0x007f74d2b0f8d0 @index=12, @type=:character>],
17
+ # [#<EPUB::Searcher::Result::Step:0x007f938f1c1e78 @index=2, @info={:name=>"spine", :id=>nil}, @type=:element>,
18
+ # #<EPUB::Searcher::Result::Step:0x007f938f1caa78 @index=1, @info={:id=>nil}, @type=:itemref>,
19
+ # #<EPUB::Searcher::Result::Step:0x007f938ed521d0 @index=1, @info={:name=>"body", :id=>nil}, @type=:element>,
20
+ # #<EPUB::Searcher::Result::Step:0x007f938ed52158 @index=0, @info={:name=>"nav", :id=>"toc"}, @type=:element>,
21
+ # #<EPUB::Searcher::Result::Step:0x007f938ed52108 @index=1, @info={:name=>"ol", :id=>"tocList"}, @type=:element>,
22
+ # #<EPUB::Searcher::Result::Step:0x007f938ed52090 @index=0, @info={:name=>"li", :id=>"np-313"}, @type=:element>,
23
+ # #<EPUB::Searcher::Result::Step:0x007f938ed52040 @index=1, @info={:name=>"ol", :id=>nil}, @type=:element>,
24
+ # #<EPUB::Searcher::Result::Step:0x007f938ed51ff0 @index=1, @info={:name=>"li", :id=>"np-317"}, @type=:element>,
25
+ # #<EPUB::Searcher::Result::Step:0x007f938ed51f78 @index=0, @info={:name=>"a", :id=>nil}, @type=:element>,
26
+ # #<EPUB::Searcher::Result::Step:0x007f938ed51f28 @index=0, @info={}, @type=:text>],
27
+ # @start_steps=[#<EPUB::Searcher::Result::Step:0x007f938ed51e88 @index=0, @info={}, @type=:character>]>,
28
+ # #<EPUB::Searcher::Result:0x007f938ef8f5d8
29
+ # @end_steps=[#<EPUB::Searcher::Result::Step:0x007f938ef8f808 @index=12, @info={}, @type=:character>],
30
30
  # @parent_steps=
31
- # [#<EPUB::Searcher::Result::Step:0x007f74d2b81318 @index=2, @name="spine", @type=:element>,
32
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b314f8 @index=2, @type=:itemref>,
33
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b2fb80 @index=1, @name="body", @type=:element>,
34
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b2f900 @index=0, @name="section", @type=:element>,
35
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b10578 @index=3, @name="section", @type=:element>,
36
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b0fb50 @index=1, @name="h3", @type=:element>,
37
- # # #<EPUB::Searcher::Result::Step:0x007f74d2b0f998 @index=0, @type=:text>],
38
- # @start_steps=[#<EPUB::Searcher::Result::Step:0x007f74d2b0f920 @index=0, @type=:character>]>]
31
+ # [#<EPUB::Searcher::Result::Step:0x007f938f1c1e78 @index=2, @info={:name=>"spine", :id=>nil}, @type=:element>,
32
+ # #<EPUB::Searcher::Result::Step:0x007f938ed51730 @index=2, @info={:id=>nil}, @type=:itemref>,
33
+ # #<EPUB::Searcher::Result::Step:0x007f938ef8fce0 @index=1, @info={:name=>"body", :id=>nil}, @type=:element>,
34
+ # #<EPUB::Searcher::Result::Step:0x007f938ef8fc90 @index=0, @info={:name=>"section", :id=>"pgepubid00492"}, @type=:element>,
35
+ # #<EPUB::Searcher::Result::Step:0x007f938ef8fc40 @index=3, @info={:name=>"section", :id=>"pgepubid00498"}, @type=:element>,
36
+ # #<EPUB::Searcher::Result::Step:0x007f938ef8fbf0 @index=1, @info={:name=>"h3", :id=>nil}, @type=:element>,
37
+ # #<EPUB::Searcher::Result::Step:0x007f938ef8fb28 @index=0, @info={}, @type=:text>],
38
+ # @start_steps=[#<EPUB::Searcher::Result::Step:0x007f938ef8fa88 @index=0, @info={}, @type=:character>]>]
39
39
  puts results.collect(&:to_cfi_s)
40
- # /6/4!/4/2/4/2/4/4/2/1,:0,:12
41
- # /6/6!/4/2/8/4/1,:0,:12
40
+ # /6/4!/4/2[toc]/4[tocList]/2[np-313]/4/4[np-317]/2/1,:0,:12
41
+ # /6/6!/4/2[pgepubid00492]/8[pgepubid00498]/4/1,:0,:12
42
42
  # => nil
43
43
 
44
44
  Search result
@@ -46,10 +46,26 @@ Search result
46
46
 
47
47
  Search result is an array of {EPUB::Searcher::Result} and it may be converted to an EPUBCFI string by {EPUB::Searcher::Result#to_cfi_s}.
48
48
 
49
+ Seamless XHTML Searcher
50
+ -----------------------
51
+
52
+ Now default searcher for XHTML is *seamless* searcher, which ignores tags when searching.
53
+
54
+ You can search words 'search word' from XHTML document below:
55
+
56
+ <html>
57
+ <head>
58
+ <title>Sample document</title>
59
+ </head>
60
+ <body>
61
+ <p><em>search</em> word</p>
62
+ </body>
63
+ </html>
64
+
49
65
  Restricted XHTML Searcher
50
66
  -------------------------
51
67
 
52
- Now searcher for XHTML documents is *restricted*, which means that it can search from only single elements. For instance, it can find 'search word' from XHTML document below:
68
+ You can also use *restricted* searcher, which means that it can search from only single elements. For instance, it can find 'search word' from XHTML document below:
53
69
 
54
70
  <html>
55
71
  <head>
@@ -72,3 +88,7 @@ But cannot from document below:
72
88
  </html>
73
89
 
74
90
  because the words 'search' and 'word' are not in the same element.
91
+
92
+ To use restricted searcher, specify `algorithm` option for `search` method:
93
+
94
+ results = EPUB::Searcher.search(epub, search_word, algorithm: :restricted)
data/epub-parser.gemspec CHANGED
@@ -11,8 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.summary = %q{EPUB 3 Parser}
12
12
  s.description = %q{Parse EPUB 3 book loosely}
13
13
  s.license = 'MIT'
14
-
15
- # s.rubyforge_project = "epub-parser"
14
+ s.required_ruby_version = '> 2'
16
15
 
17
16
  s.files = `git ls-files`.split("\n")
18
17
  .push('test/fixtures/book/OPS/ルートファイル.opf')
@@ -38,13 +37,11 @@ Gem::Specification.new do |s|
38
37
  s.add_development_dependency 'gem-man'
39
38
  s.add_development_dependency 'ronn'
40
39
  s.add_development_dependency 'epzip'
41
- s.add_development_dependency 'epubcheck'
42
- s.add_development_dependency 'epub_validator'
43
40
  s.add_development_dependency 'aruba'
44
41
 
45
- s.add_runtime_dependency 'enumerabler'
46
42
  s.add_runtime_dependency 'zipruby'
47
43
  s.add_runtime_dependency 'nokogiri', '~> 1.6'
44
+ s.add_runtime_dependency 'nokogumbo'
48
45
  s.add_runtime_dependency 'addressable', '>= 2.3.5'
49
- s.add_runtime_dependency 'rchardet'
46
+ s.add_runtime_dependency 'rchardet', '< 1.6'
50
47
  end
data/lib/epub.rb CHANGED
@@ -3,12 +3,3 @@ require 'epub/ocf'
3
3
  require 'epub/publication'
4
4
  require 'epub/content_document'
5
5
  require 'epub/book/features'
6
-
7
- module EPUB
8
- class << self
9
- def included(base)
10
- warn 'Including EPUB module is deprecated. Include EPUB::Book::Features instead.'
11
- base.__send__ :include, EPUB::Book::Features
12
- end
13
- end
14
- end
@@ -17,7 +17,7 @@ module EPUB
17
17
  end
18
18
  end
19
19
 
20
- %w[ title main_title subtitle short_title collection_title edition_title extended_title description date unique_identifier ].each do |met|
20
+ %w[title main_title subtitle short_title collection_title edition_title extended_title description date unique_identifier].each do |met|
21
21
  define_method met do
22
22
  metadata.__send__(met)
23
23
  end
@@ -25,7 +25,7 @@ module EPUB
25
25
 
26
26
  %w[nav].each do |met|
27
27
  define_method met do
28
- manifest.__send__ met
28
+ manifest.__send__(met)
29
29
  end
30
30
  end
31
31
 
@@ -39,7 +39,7 @@ module EPUB
39
39
  if block_given?
40
40
  enum.each &blk
41
41
  else
42
- enum
42
+ enum.each
43
43
  end
44
44
  end
45
45
 
@@ -9,20 +9,20 @@ module EPUB
9
9
  end
10
10
 
11
11
  def toc
12
- navigations.selector {|nav| nav.type == Navigation::Type::TOC}.first
12
+ navigations.find(&:toc?)
13
13
  end
14
14
 
15
15
  def page_list
16
- navigations.selector {|nav| nav.type == Nagivation::Type::PAGE_LIST}.first
16
+ navigations.find(&:page_list?)
17
17
  end
18
18
 
19
19
  def landmarks
20
- navigations.selector {|nav| nav.type == Navigation::Type::LANDMARKS}.first
20
+ navigations.find(&:landmarks?)
21
21
  end
22
22
 
23
23
  # Enumerator version of toc
24
- # Usage: nagivation.enum_for(:contents)
25
24
  def contents
25
+ enum_for(:each_content).to_a
26
26
  end
27
27
 
28
28
  # Enumerator version of page_list
@@ -30,8 +30,13 @@ module EPUB
30
30
  def pages
31
31
  end
32
32
 
33
+ # @todo Enumerator version of landmarks
34
+
33
35
  # iterator for #toc
34
36
  def each_content
37
+ toc.traverse do |content, _|
38
+ yield content
39
+ end
35
40
  end
36
41
 
37
42
  # iterator for #page_list
@@ -89,6 +94,12 @@ module EPUB
89
94
  alias navigations= items=
90
95
  alias heading text
91
96
  alias heading= text=
97
+
98
+ %w[toc page_list landmarks].each do |type|
99
+ define_method "#{type}?" do
100
+ type == Type.const_get(type.upcase)
101
+ end
102
+ end
92
103
  end
93
104
 
94
105
  class ItemList < Array
@@ -34,7 +34,8 @@ module EPUB
34
34
 
35
35
  # @return [Nokogiri::XML::Document] content as Nokogiri::XML::Document object
36
36
  def nokogiri
37
- @nokogiri ||= Nokogiri.XML(raw_document)
37
+ require 'nokogumbo'
38
+ @nokogiri ||= Nokogiri.HTML5(raw_document)
38
39
  end
39
40
  end
40
41
  end
@@ -87,7 +87,7 @@ module EPUB
87
87
  item.text = extract_attribute(a_or_span, 'title').to_s if item.text.nil? || item.text.empty?
88
88
  end
89
89
  item.href = Addressable::URI.parse(extract_attribute(a_or_span, 'href'))
90
- item.item = @item.manifest.items.selector {|it| it.href.request_uri == item.href.request_uri}.first
90
+ item.item = @item.manifest.items.find {|it| it.href.request_uri == item.href.request_uri}
91
91
  end
92
92
  item.items = element.xpath('./xhtml:ol[1]/xhtml:li', EPUB::NAMESPACES).map {|li| parse_navigation_item(li)}
93
93
 
@@ -55,7 +55,7 @@ module EPUB
55
55
  }
56
56
  metadata.titles = extract_model(elem, id_map, './dc:title', :Title)
57
57
  metadata.languages = extract_model(elem, id_map, './dc:language', :DCMES, %w[id])
58
- %w[ contributor coverage creator date description format publisher relation source subject type ].each do |dcmes|
58
+ %w[contributor coverage creator date description format publisher relation source subject type].each do |dcmes|
59
59
  metadata.__send__ "#{dcmes}s=", extract_model(elem, id_map, "./dc:#{dcmes}")
60
60
  end
61
61
  metadata.rights = extract_model(elem, id_map, './dc:rights')
@@ -82,7 +82,7 @@ module EPUB
82
82
  fallback_map = {}
83
83
  elem.xpath('./opf:item', EPUB::NAMESPACES).each do |e|
84
84
  item = EPUB::Publication::Package::Manifest::Item.new
85
- %w[ id media-type media-overlay ].each do |attr|
85
+ %w[id media-type media-overlay].each do |attr|
86
86
  item.__send__ "#{attr.gsub(/-/, '_')}=", extract_attribute(e, attr)
87
87
  end
88
88
  item.href = Addressable::URI.parse(extract_attribute(e, 'href'))
@@ -102,13 +102,13 @@ module EPUB
102
102
  def parse_spine
103
103
  spine = @package.spine = EPUB::Publication::Package::Spine.new
104
104
  elem = @doc.xpath('/opf:package/opf:spine', EPUB::NAMESPACES).first
105
- %w[ id toc page-progression-direction ].each do |attr|
105
+ %w[id toc page-progression-direction].each do |attr|
106
106
  spine.__send__ "#{attr.gsub(/-/, '_')}=", extract_attribute(elem, attr)
107
107
  end
108
108
 
109
109
  elem.xpath('./opf:itemref', EPUB::NAMESPACES).each do |e|
110
110
  itemref = EPUB::Publication::Package::Spine::Itemref.new
111
- %w[ idref id ].each do |attr|
111
+ %w[idref id].each do |attr|
112
112
  itemref.__send__ "#{attr}=", extract_attribute(e, attr)
113
113
  end
114
114
  itemref.linear = (extract_attribute(e, 'linear') != 'no')
@@ -124,7 +124,7 @@ module EPUB
124
124
  guide = @package.guide = EPUB::Publication::Package::Guide.new
125
125
  @doc.xpath('/opf:package/opf:guide/opf:reference', EPUB::NAMESPACES).each do |ref|
126
126
  reference = EPUB::Publication::Package::Guide::Reference.new
127
- %w[ type title ].each do |attr|
127
+ %w[type title].each do |attr|
128
128
  reference.__send__ "#{attr}=", extract_attribute(ref, attr)
129
129
  end
130
130
  reference.href = Addressable::URI.parse(extract_attribute(ref, 'href'))
@@ -1,5 +1,5 @@
1
1
  module EPUB
2
2
  class Parser
3
- VERSION = "0.1.8"
3
+ VERSION = "0.1.9"
4
4
  end
5
5
  end
@@ -25,7 +25,7 @@ module EPUB
25
25
  end
26
26
  end
27
27
 
28
- attr_accessor :book,
28
+ attr_accessor :book,
29
29
  :version, :prefix, :xml_lang, :dir, :id
30
30
  attr_reader *CONTENT_MODELS
31
31
  alias lang xml_lang
@@ -1,5 +1,3 @@
1
- require 'enumerabler'
2
-
3
1
  module EPUB
4
2
  module Publication
5
3
  class Package
@@ -29,9 +27,9 @@ module EPUB
29
27
  return @item if @item
30
28
 
31
29
  request_uri = href.request_uri
32
- @item = @guide.package.manifest.items.selector do |item|
30
+ @item = @guide.package.manifest.items.find {|item|
33
31
  item.href.request_uri == request_uri
34
- end.first
32
+ }
35
33
  end
36
34
  end
37
35
 
@@ -41,7 +39,7 @@ module EPUB
41
39
  var = instance_variable_get "@#{method_name}"
42
40
  return var if var
43
41
 
44
- var = references.selector {|ref| ref.type == type}.first
42
+ var = references.find {|ref| ref.type == type}
45
43
  instance_variable_set "@#{method_name}", var
46
44
  end
47
45
  end
@@ -1,5 +1,4 @@
1
1
  require 'set'
2
- require 'enumerabler'
3
2
  require 'rchardet'
4
3
  require 'epub/constants'
5
4
  require 'epub/parser/content_document'
@@ -24,8 +23,18 @@ module EPUB
24
23
  self
25
24
  end
26
25
 
26
+ def each_nav
27
+ if block_given?
28
+ each_item do |item|
29
+ yield item if item.nav?
30
+ end
31
+ else
32
+ each_item.lazy.select(&:nav?)
33
+ end
34
+ end
35
+
27
36
  def navs
28
- items.selector(&:nav?)
37
+ items.select(&:nav?)
29
38
  end
30
39
 
31
40
  def nav
@@ -33,12 +42,16 @@ module EPUB
33
42
  end
34
43
 
35
44
  def cover_image
36
- items.selector(&:cover_image?).first
45
+ items.select(&:cover_image?).first
37
46
  end
38
47
 
39
48
  def each_item
40
- @items.each_value do |item|
41
- yield item
49
+ if block_given?
50
+ @items.each_value do |item|
51
+ yield item
52
+ end
53
+ else
54
+ @items.each_value
42
55
  end
43
56
  end
44
57
 
@@ -30,7 +30,7 @@ module EPUB
30
30
  titles.sort.join("\n")
31
31
  end
32
32
 
33
- %w[ main short collection edition extended ].each do |type|
33
+ %w[main short collection edition extended].each do |type|
34
34
  define_method "#{type}_title" do
35
35
  titles.select {|title| title.title_type.to_s == type}.sort.join(' ')
36
36
  end
@@ -41,7 +41,7 @@ module EPUB
41
41
  end
42
42
 
43
43
  def description
44
- descriptions.join ' '
44
+ descriptions.join(' ')
45
45
  end
46
46
 
47
47
  def date
@@ -64,7 +64,7 @@ module EPUB
64
64
  end
65
65
 
66
66
  module Refinee
67
- PROPERTIES = %w[ alternate-script display-seq file-as group-position identifier-type meta-auth role title-type ]
67
+ PROPERTIES = %w[alternate-script display-seq file-as group-position identifier-type meta-auth role title-type]
68
68
 
69
69
  attr_writer :refiners
70
70
 
@@ -76,7 +76,7 @@ module EPUB
76
76
  met = voc.gsub(/-/, '_')
77
77
  attr_writer met
78
78
  define_method met do
79
- refiners.selector {|refiner| refiner.property == voc}.first
79
+ refiners.find {|refiner| refiner.property == voc}
80
80
  end
81
81
  end
82
82
  end
@@ -36,7 +36,7 @@ module EPUB
36
36
  # @return [Enumerator] Enumerator which yeilds {Manifest::Item}
37
37
  # referred by each of {#itemrefs}
38
38
  def items
39
- itemrefs.collector {|itemref| itemref.item}
39
+ itemrefs.collect {|itemref| itemref.item}
40
40
  end
41
41
 
42
42
  class Itemref
data/lib/epub/searcher.rb CHANGED
@@ -1,3 +1,13 @@
1
1
  require 'epub/searcher/result'
2
2
  require 'epub/searcher/publication'
3
3
  require 'epub/searcher/xhtml'
4
+
5
+ module EPUB
6
+ module Searcher
7
+ class << self
8
+ def search(epub, word, **options)
9
+ Publication.search(epub.package, word, options)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -4,8 +4,9 @@ module EPUB
4
4
  module Searcher
5
5
  class Publication
6
6
  class << self
7
- def search(package, word)
8
- new(word).search(package)
7
+ # @todo Use named argument in the future
8
+ def search(package, word, **options)
9
+ new(word).search(package, options)
9
10
  end
10
11
  end
11
12
 
@@ -13,14 +14,15 @@ module EPUB
13
14
  @word = word
14
15
  end
15
16
 
16
- def search(package)
17
+ # @todo Use named argument in the future
18
+ def search(package, algorithm: :seamless)
17
19
  results = []
18
20
 
19
21
  spine = package.spine
20
22
  spine_step = Result::Step.new(:element, 2, {:name => 'spine', :id => spine.id})
21
23
  spine.each_itemref.with_index do |itemref, index|
22
24
  itemref_step = Result::Step.new(:itemref, index, {:id => itemref.id})
23
- XHTML::Restricted.search(Nokogiri.XML(itemref.item.read), @word).each do |sub_result|
25
+ XHTML::ALGORITHMS[algorithm].search(Nokogiri.XML(itemref.item.read), @word).each do |sub_result|
24
26
  results << Result.new([spine_step, itemref_step] + sub_result.parent_steps, sub_result.start_steps, sub_result.end_steps)
25
27
  end
26
28
  end
@@ -1,6 +1,37 @@
1
1
  module EPUB
2
2
  module Searcher
3
3
  class Result
4
+ class << self
5
+ # @example
6
+ # Result.aggregate_step_intersection([a, b, c], [a, b, d]) # => [[a, b], [c], [d]]
7
+ # @example
8
+ # Result.aggregate_step_intersection([a, b, c], [a, d, c]) # => [[a], [b, c], [d, c]]
9
+ # # Note that c here is not included in the first element of returned value.
10
+ # @param steps1 [Array<Step>, Array<Array>]
11
+ # @param steps2 [Array<Step>, Array<Array>]
12
+ # @return [Array<Array<Array>>] Thee arrays:
13
+ # 1. "intersection" of +steps1+ and +steps2+. "intersection" here is not the term of mathmatics
14
+ # 2. remaining steps of +steps1+
15
+ # 3. remaining steps of +steps2+
16
+ def aggregate_step_intersection(steps1, steps2)
17
+ intersection = []
18
+ steps1_remaining = []
19
+ steps2_remaining = []
20
+ broken = false
21
+ steps1.zip steps2 do |step1, step2|
22
+ broken = true unless step1 && step2 && step1 == step2
23
+ if broken
24
+ steps1_remaining << step1 unless step1.nil?
25
+ steps2_remaining << step2 unless step2.nil?
26
+ else
27
+ intersection << step1
28
+ end
29
+ end
30
+
31
+ [intersection, steps1_remaining, steps2_remaining]
32
+ end
33
+ end
34
+
4
35
  attr_reader :parent_steps, :start_steps, :end_steps
5
36
 
6
37
  # @param parent_steps [Array<Step>] common steps between start and end
@@ -4,36 +4,38 @@ require 'epub/parser/utils'
4
4
  module EPUB
5
5
  module Searcher
6
6
  class XHTML
7
- class Restricted
8
- class << self
9
- # @param element [Nokogiri::XML::Element, Nokogiri::XML::Document]
10
- # @param word [String]
11
- # @return [Array<Result>]
12
- def search(element, word)
13
- new(word).search(element.respond_to?(:root) ? element.root : element)
14
- end
15
- end
7
+ ALGORITHMS = {}
16
8
 
9
+ class << self
10
+ # @param element [Nokogiri::XML::Element, Nokogiri::XML::Document]
17
11
  # @param word [String]
18
- def initialize(word)
19
- @word = word
12
+ # @return [Array<Result>]
13
+ def search(element, word)
14
+ new(element.respond_to?(:root) ? element.root : element).search(word)
20
15
  end
16
+ end
17
+
18
+ # @param word [String]
19
+ def initialize(element)
20
+ @element = element
21
+ end
21
22
 
23
+ class Restricted < self
22
24
  # @param element [Nokogiri::XML::Element]
23
25
  # @return [Array<Result>]
24
- def search(element)
26
+ def search(word, element=nil)
25
27
  results = []
26
28
 
27
29
  elem_index = 0
28
- element.children.each do |child|
30
+ (element || @element).children.each do |child|
29
31
  if child.element?
30
32
  child_step = Result::Step.new(:element, elem_index, {:name => child.name, :id => Parser::Utils.extract_attribute(child, 'id')})
31
33
  if child.name == 'img'
32
- if Parser::Utils.extract_attribute(child, 'alt').index(@word)
34
+ if Parser::Utils.extract_attribute(child, 'alt').index(word)
33
35
  results << Result.new([child_step], nil, nil)
34
36
  end
35
37
  else
36
- search(child).each do |sub_result|
38
+ search(word, child).each do |sub_result|
37
39
  results << Result.new([child_step] + sub_result.parent_steps, sub_result.start_steps, sub_result.end_steps)
38
40
  end
39
41
  end
@@ -42,8 +44,8 @@ module EPUB
42
44
  text_index = elem_index
43
45
  char_index = 0
44
46
  text_step = Result::Step.new(:text, text_index)
45
- while char_index = child.text.index(@word, char_index)
46
- results << Result.new([text_step], [Result::Step.new(:character, char_index)], [Result::Step.new(:character, char_index + @word.length)])
47
+ while char_index = child.text.index(word, char_index)
48
+ results << Result.new([text_step], [Result::Step.new(:character, char_index)], [Result::Step.new(:character, char_index + word.length)])
47
49
  char_index += 1
48
50
  end
49
51
  end
@@ -52,6 +54,100 @@ module EPUB
52
54
  results
53
55
  end
54
56
  end
57
+ ALGORITHMS[:restricted] = Restricted
58
+
59
+ class Seamless < self
60
+ def search(word)
61
+ unless @indices
62
+ @indices, @content = build_indices(@element)
63
+ end
64
+ visit(@indices, @content, word)
65
+ end
66
+
67
+ def build_indices(element)
68
+ indices = {}
69
+ content = ''
70
+
71
+ elem_index = 0
72
+ element.children.each do |child|
73
+ if child.element?
74
+ child_step = [:element, elem_index, {:name => child.name, :id => Parser::Utils.extract_attribute(child, 'id')}]
75
+ elem_index += 1
76
+ if child.name == 'img'
77
+ alt = Parser::Utils.extract_attribute(child, 'alt')
78
+ next if alt.nil? || alt.empty?
79
+ indices[content.length] = [child_step]
80
+ content << alt
81
+ else
82
+ # TODO: Consider block level elements
83
+ content_length = content.length
84
+ sub_indices, sub_content = build_indices(child)
85
+ sub_indices.each_pair do |sub_pos, child_steps|
86
+ indices[content_length + sub_pos] = [child_step] + child_steps
87
+ end
88
+ content << sub_content
89
+ end
90
+ elsif child.text? || child.cdata?
91
+ text_index = elem_index
92
+ text_step = [:text, text_index]
93
+ indices[content.length] = [text_step]
94
+ content << child.content
95
+ end
96
+ end
97
+
98
+ [indices, content]
99
+ end
100
+
101
+ private
102
+
103
+ def visit(indices, content, word)
104
+ results = []
105
+ offsets = indices.keys
106
+ i = 0
107
+ while i = content.index(word, i)
108
+ offset = find_offset(offsets, i)
109
+ start_steps = to_result_steps(indices[offset])
110
+ last_step = start_steps.last
111
+ if last_step.info[:name] == 'img'
112
+ parent_steps = start_steps
113
+ start_steps = end_steps = nil
114
+ else
115
+ word_length = word.length
116
+ start_char_step = Result::Step.new(:character, i - offset)
117
+ end_offset = find_offset(offsets, i + word_length, true)
118
+ end_steps = to_result_steps(indices[end_offset])
119
+ end_char_step = Result::Step.new(:character, i + word_length - end_offset)
120
+ parent_steps, start_steps, end_steps = Result.aggregate_step_intersection(start_steps, end_steps)
121
+ start_steps << start_char_step
122
+ end_steps << end_char_step
123
+ end
124
+ results << Result.new(parent_steps, start_steps, end_steps)
125
+ i += 1
126
+ end
127
+
128
+ results
129
+ end
130
+
131
+ # Find max offset greater than or equal to index
132
+ # @param offsets [Array<Integer>] keys of indices
133
+ # @param index [Integer] position of search word in content string
134
+ # @todo: more efficient algorithm
135
+ def find_offset(offsets, index, for_end_position=false)
136
+ comparison_operator = for_end_position ? :< : :<=
137
+ l = offsets.length
138
+ offset_index = (0..l).bsearch {|i|
139
+ o = offsets[l - i]
140
+ next false unless o
141
+ o.send(comparison_operator, index)
142
+ }
143
+ offsets[l - offset_index]
144
+ end
145
+
146
+ def to_result_steps(steps)
147
+ steps.map {|step| Result::Step.new(*step)}
148
+ end
149
+ end
150
+ ALGORITHMS[:seamless] = Seamless
55
151
  end
56
152
  end
57
153
  end
@@ -52,6 +52,27 @@ class TestContentDocument < Test::Unit::TestCase
52
52
  end
53
53
 
54
54
  class TestNavigationDocument < self
55
+ def test_toc_returns_nav_with_type_toc
56
+ navigation = Navigation.new
57
+ toc = Navigation::Navigation.new.tap {|nav| nav.type = 'toc'}
58
+ navigation.navigations << toc
59
+
60
+ assert_same toc, navigation.toc
61
+ end
62
+
63
+ def test_contents_returns_items_of_toc
64
+ manifest = EPUB::Publication::Package::Manifest.new
65
+ item = EPUB::Publication::Package::Manifest::Item.new
66
+ item.media_type = 'application/xhtml+xml'
67
+ item.properties = %w[nav]
68
+ item.href = Addressable::URI.parse('nav.xhtml')
69
+ stub(item).read {File.read(File.expand_path('../fixtures/book/OPS/nav.xhtml', __FILE__))}
70
+ manifest << item
71
+ nav_doc = EPUB::Parser::ContentDocument.new(item).parse
72
+
73
+ assert_equal ['Table of Contents', '一ページ目', '二ページ目', '第一節', '第二節', '第三節', '第四節'], nav_doc.contents.collect(&:text)
74
+ end
75
+
55
76
  def test_item_hidden_returns_true_when_it_has_some_value
56
77
  item = Navigation::Item.new.tap {|item| item.hidden = ''}
57
78
  assert_true item.hidden?
data/test/test_inspect.rb CHANGED
@@ -45,7 +45,7 @@ class TestInspect < Test::Unit::TestCase
45
45
  title.content = 'Book Title'
46
46
  @metadata.titles << title
47
47
 
48
- title_pattern = RUBY_VERSION >= '2.0' ? '@dc_titles=[#<EPUB::Publication::Package::Metadata::Title' : 'Book Title'
48
+ title_pattern = '@dc_titles=[#<EPUB::Publication::Package::Metadata::Title'
49
49
 
50
50
  assert_match title_pattern, @metadata.inspect
51
51
  end
@@ -23,14 +23,14 @@ class TestPublication < Test::Unit::TestCase
23
23
  refiner = Package::Metadata::Meta.new
24
24
  refinee = Package::Metadata::Meta.new
25
25
  refiner.refines = refinee
26
- assert_same refinee.refiners.first, refiner
26
+ assert_same refinee.refiners.first, refiner
27
27
  end
28
28
 
29
29
  def test_link_refines_setter_connect_refinee_to_the_link
30
30
  refiner = Package::Metadata::Link.new
31
31
  refinee = Package::Metadata::Meta.new
32
32
  refiner.refines = refinee
33
- assert_same refinee.refiners.first, refiner
33
+ assert_same refinee.refiners.first, refiner
34
34
  end
35
35
 
36
36
  def test_title_returns_extended_title_when_it_exists
@@ -184,6 +184,59 @@ class TestPublication < Test::Unit::TestCase
184
184
  class TestManifest < TestPublication
185
185
  include EPUB::Publication
186
186
 
187
+ def setup
188
+ @manifest = EPUB::Publication::Package::Manifest.new
189
+ @nav1 = EPUB::Publication::Package::Manifest::Item.new
190
+ @nav1.id = 'nav1'
191
+ @nav1.properties = %w[nav]
192
+ @nav2 = EPUB::Publication::Package::Manifest::Item.new
193
+ @nav2.id = 'nav2'
194
+ @nav2.properties = %w[nav]
195
+ @item = EPUB::Publication::Package::Manifest::Item.new
196
+ @item.id = 'item'
197
+ @cover_image = EPUB::Publication::Package::Manifest::Item.new
198
+ @cover_image.id = 'cover-image'
199
+ @cover_image.properties = %w[cover-image]
200
+ @manifest << @nav1 << @item << @nav2 << @cover_image
201
+ end
202
+
203
+ def test_each_item_returns_enumerator_when_no_block_given
204
+ assert_instance_of Enumerator, @manifest.each_item
205
+ end
206
+
207
+ def test_each_nav_iterates_over_items_with_nav_property
208
+ navs = [@nav1, @nav2]
209
+ i = 0
210
+ @manifest.each_nav do |nav|
211
+ assert_same navs[i], nav
212
+ i += 1
213
+ end
214
+ end
215
+
216
+ def test_each_nav_returns_iterable_object_when_no_block_given
217
+ navs = [@nav1, @nav2]
218
+
219
+ assert_respond_to @manifest.each_nav, :each
220
+ @manifest.each_nav.with_index do |nav, i|
221
+ assert_same navs[i], nav
222
+ end
223
+ end
224
+
225
+ def test_navs_iterates_over_items_with_nav_property
226
+ navs = [@nav1, @nav2]
227
+ @manifest.navs.each_with_index do |nav, i|
228
+ assert_same navs[i], nav
229
+ end
230
+ end
231
+
232
+ def test_nav_returns_first_item_with_nav_property
233
+ assert_same @nav1, @manifest.nav
234
+ end
235
+
236
+ def test_cover_image_returns_item_with_cover_image_property
237
+ assert_same @cover_image, @manifest.cover_image
238
+ end
239
+
187
240
  class TestItem < TestManifest
188
241
  def test_content_document_returns_nil_when_not_xhtml_nor_svg
189
242
  item = EPUB::Publication::Package::Manifest::Item.new
@@ -46,36 +46,61 @@ class TestSearcher < Test::Unit::TestCase
46
46
  @nav = @doc.search('nav').first
47
47
  end
48
48
 
49
- def test_no_result
50
- assert_empty EPUB::Searcher::XHTML::Restricted.search(@h1, 'no result')
51
- end
49
+ module TestSearch
50
+ def test_no_result
51
+ assert_empty @searcher.search(@h1, 'no result')
52
+ end
52
53
 
53
- def test_simple
54
- assert_equal results([[[[:text, 0]], [[:character, 9]], [[:character, 16]]]]), EPUB::Searcher::XHTML::Restricted.search(@h1, 'Content')
55
- end
54
+ def test_simple
55
+ assert_equal results([[[[:text, 0]], [[:character, 9]], [[:character, 16]]]]), @searcher.search(@h1, 'Content')
56
+ end
56
57
 
57
- def test_multiple_text_result
58
- assert_equal results([[[[:text, 0]], [[:character, 6]], [[:character, 7]]], [[[:text, 0]], [[:character, 10]], [[:character, 11]]]]), EPUB::Searcher::XHTML::Restricted.search(@h1, 'o')
59
- end
58
+ def test_multiple_text_result
59
+ assert_equal results([[[[:text, 0]], [[:character, 6]], [[:character, 7]]], [[[:text, 0]], [[:character, 10]], [[:character, 11]]]]), @searcher.search(@h1, 'o')
60
+ end
60
61
 
61
- def test_text_after_element
62
- elem = Nokogiri.XML('<root><elem>inner</elem>after</root>')
62
+ def test_text_after_element
63
+ elem = Nokogiri.XML('<root><elem>inner</elem>after</root>')
63
64
 
64
- assert_equal results([[[[:text, 1]], [[:character, 0]], [[:character, 5]]]]), EPUB::Searcher::XHTML::Restricted.search(elem, 'after')
65
- end
65
+ assert_equal results([[[[:text, 1]], [[:character, 0]], [[:character, 5]]]]), @searcher.search(elem, 'after')
66
+ end
66
67
 
67
- def test_entity_reference
68
- elem = Nokogiri.XML('<root>before&lt;after</root>')
68
+ def test_entity_reference
69
+ elem = Nokogiri.XML('<root>before&lt;after</root>')
69
70
 
70
- assert_equal results([[[[:text, 0]], [[:character, 6]], [[:character, 7]]]]), EPUB::Searcher::XHTML::Restricted.search(elem, '<')
71
+ assert_equal results([[[[:text, 0]], [[:character, 6]], [[:character, 7]]]]), @searcher.search(elem, '<')
72
+ end
73
+
74
+ def test_nested_result
75
+ assert_equal results([[[[:element, 1, {:name => 'ol', :id => nil}], [:element, 1, {:name => 'li', :id => nil}], [:element, 1, {:name => 'ol', :id => nil}], [:element, 1, {:name => 'li', :id => nil}], [:element, 0, {:name => 'a', :id => nil}], [:text, 0]], [[:character, 0]], [[:character, 3]]]]), @searcher.search(@nav, '第二節')
76
+ end
77
+
78
+ def test_img
79
+ assert_equal [result([[[:element, 1, {:name => 'ol', :id => nil}], [:element, 1, {:name => 'li', :id => nil}], [:element, 1, {:name => 'ol', :id => nil}], [:element, 2, {:name => 'li', :id => nil}], [:element, 0, {:name => 'a', :id => nil}], [:element, 0, {:name => 'img', :id => nil}]], nil, nil])], @searcher.search(@nav, '第三節')
80
+ end
71
81
  end
72
82
 
73
- def test_nested_result
74
- assert_equal results([[[[:element, 1, {:name => 'ol', :id => nil}], [:element, 1, {:name => 'li', :id => nil}], [:element, 1, {:name => 'ol', :id => nil}], [:element, 1, {:name => 'li', :id => nil}], [:element, 0, {:name => 'a', :id => nil}], [:text, 0]], [[:character, 0]], [[:character, 3]]]]), EPUB::Searcher::XHTML::Restricted.search(@nav, '第二節')
83
+ class TestRestricted < self
84
+ include TestSearch
85
+
86
+ def setup
87
+ super
88
+ @searcher = EPUB::Searcher::XHTML::Restricted
89
+ end
75
90
  end
76
91
 
77
- def test_img
78
- assert_equal [result([[[:element, 1, {:name => 'ol', :id => nil}], [:element, 1, {:name => 'li', :id => nil}], [:element, 1, {:name => 'ol', :id => nil}], [:element, 2, {:name => 'li', :id => nil}], [:element, 0, {:name => 'a', :id => nil}], [:element, 0, {:name => 'img', :id => nil}]], nil, nil])], EPUB::Searcher::XHTML::Restricted.search(@nav, '第三節')
92
+ class TestSeamless < self
93
+ include TestSearch
94
+
95
+ def setup
96
+ super
97
+ @searcher = EPUB::Searcher::XHTML::Seamless
98
+ end
99
+
100
+ def test_seamless
101
+ elem = Nokogiri.XML('<root>This <em>includes</em> a child element.</root>')
102
+ assert_equal results([[[], [[:text, 0], [:character, 0]], [[:text, 1], [:character, 17]]]]), @searcher.search(elem, 'This includes a child element.')
103
+ end
79
104
  end
80
105
 
81
106
  class TestResult < self
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epub-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - KITAITI Makoto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-06 00:00:00.000000000 Z
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -179,21 +179,7 @@ dependencies:
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
181
  - !ruby/object:Gem::Dependency
182
- name: epubcheck
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
195
- - !ruby/object:Gem::Dependency
196
- name: epub_validator
182
+ name: aruba
197
183
  requirement: !ruby/object:Gem::Requirement
198
184
  requirements:
199
185
  - - ">="
@@ -207,13 +193,13 @@ dependencies:
207
193
  - !ruby/object:Gem::Version
208
194
  version: '0'
209
195
  - !ruby/object:Gem::Dependency
210
- name: aruba
196
+ name: zipruby
211
197
  requirement: !ruby/object:Gem::Requirement
212
198
  requirements:
213
199
  - - ">="
214
200
  - !ruby/object:Gem::Version
215
201
  version: '0'
216
- type: :development
202
+ type: :runtime
217
203
  prerelease: false
218
204
  version_requirements: !ruby/object:Gem::Requirement
219
205
  requirements:
@@ -221,21 +207,21 @@ dependencies:
221
207
  - !ruby/object:Gem::Version
222
208
  version: '0'
223
209
  - !ruby/object:Gem::Dependency
224
- name: enumerabler
210
+ name: nokogiri
225
211
  requirement: !ruby/object:Gem::Requirement
226
212
  requirements:
227
- - - ">="
213
+ - - "~>"
228
214
  - !ruby/object:Gem::Version
229
- version: '0'
215
+ version: '1.6'
230
216
  type: :runtime
231
217
  prerelease: false
232
218
  version_requirements: !ruby/object:Gem::Requirement
233
219
  requirements:
234
- - - ">="
220
+ - - "~>"
235
221
  - !ruby/object:Gem::Version
236
- version: '0'
222
+ version: '1.6'
237
223
  - !ruby/object:Gem::Dependency
238
- name: zipruby
224
+ name: nokogumbo
239
225
  requirement: !ruby/object:Gem::Requirement
240
226
  requirements:
241
227
  - - ">="
@@ -248,20 +234,6 @@ dependencies:
248
234
  - - ">="
249
235
  - !ruby/object:Gem::Version
250
236
  version: '0'
251
- - !ruby/object:Gem::Dependency
252
- name: nokogiri
253
- requirement: !ruby/object:Gem::Requirement
254
- requirements:
255
- - - "~>"
256
- - !ruby/object:Gem::Version
257
- version: '1.6'
258
- type: :runtime
259
- prerelease: false
260
- version_requirements: !ruby/object:Gem::Requirement
261
- requirements:
262
- - - "~>"
263
- - !ruby/object:Gem::Version
264
- version: '1.6'
265
237
  - !ruby/object:Gem::Dependency
266
238
  name: addressable
267
239
  requirement: !ruby/object:Gem::Requirement
@@ -280,16 +252,16 @@ dependencies:
280
252
  name: rchardet
281
253
  requirement: !ruby/object:Gem::Requirement
282
254
  requirements:
283
- - - ">="
255
+ - - "<"
284
256
  - !ruby/object:Gem::Version
285
- version: '0'
257
+ version: '1.6'
286
258
  type: :runtime
287
259
  prerelease: false
288
260
  version_requirements: !ruby/object:Gem::Requirement
289
261
  requirements:
290
- - - ">="
262
+ - - "<"
291
263
  - !ruby/object:Gem::Version
292
- version: '0'
264
+ version: '1.6'
293
265
  description: Parse EPUB 3 book loosely
294
266
  email:
295
267
  - KitaitiMakoto@gmail.com
@@ -395,9 +367,9 @@ require_paths:
395
367
  - lib
396
368
  required_ruby_version: !ruby/object:Gem::Requirement
397
369
  requirements:
398
- - - ">="
370
+ - - ">"
399
371
  - !ruby/object:Gem::Version
400
- version: '0'
372
+ version: '2'
401
373
  required_rubygems_version: !ruby/object:Gem::Requirement
402
374
  requirements:
403
375
  - - ">="
@@ -405,7 +377,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
405
377
  version: '0'
406
378
  requirements: []
407
379
  rubyforge_project:
408
- rubygems_version: 2.2.2
380
+ rubygems_version: 2.4.6
409
381
  signing_key:
410
382
  specification_version: 4
411
383
  summary: EPUB 3 Parser