epub-parser-io 0.1.6a

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.
Files changed (78) hide show
  1. data/.gemtest +0 -0
  2. data/.gitignore +12 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +4 -0
  5. data/.yardopts +10 -0
  6. data/CHANGELOG.markdown +61 -0
  7. data/Gemfile +2 -0
  8. data/MIT-LICENSE +7 -0
  9. data/README.markdown +174 -0
  10. data/Rakefile +68 -0
  11. data/bin/epub-open +25 -0
  12. data/bin/epubinfo +64 -0
  13. data/docs/EpubOpen.markdown +43 -0
  14. data/docs/Epubinfo.markdown +37 -0
  15. data/docs/FixedLayout.markdown +96 -0
  16. data/docs/Home.markdown +128 -0
  17. data/docs/Item.markdown +80 -0
  18. data/docs/Navigation.markdown +58 -0
  19. data/docs/Publication.markdown +54 -0
  20. data/epub-parser.gemspec +49 -0
  21. data/features/epubinfo.feature +6 -0
  22. data/features/step_definitions/epubinfo_steps.rb +5 -0
  23. data/features/support/env.rb +1 -0
  24. data/lib/epub/book/features.rb +85 -0
  25. data/lib/epub/book.rb +7 -0
  26. data/lib/epub/constants.rb +48 -0
  27. data/lib/epub/content_document/navigation.rb +104 -0
  28. data/lib/epub/content_document/xhtml.rb +41 -0
  29. data/lib/epub/content_document.rb +2 -0
  30. data/lib/epub/inspector.rb +45 -0
  31. data/lib/epub/ocf/container.rb +28 -0
  32. data/lib/epub/ocf/encryption.rb +7 -0
  33. data/lib/epub/ocf/manifest.rb +6 -0
  34. data/lib/epub/ocf/metadata.rb +6 -0
  35. data/lib/epub/ocf/rights.rb +6 -0
  36. data/lib/epub/ocf/signatures.rb +6 -0
  37. data/lib/epub/ocf.rb +8 -0
  38. data/lib/epub/parser/content_document.rb +111 -0
  39. data/lib/epub/parser/ocf.rb +73 -0
  40. data/lib/epub/parser/publication.rb +200 -0
  41. data/lib/epub/parser/utils.rb +20 -0
  42. data/lib/epub/parser/version.rb +5 -0
  43. data/lib/epub/parser.rb +103 -0
  44. data/lib/epub/publication/fixed_layout.rb +208 -0
  45. data/lib/epub/publication/package/bindings.rb +31 -0
  46. data/lib/epub/publication/package/guide.rb +51 -0
  47. data/lib/epub/publication/package/manifest.rb +180 -0
  48. data/lib/epub/publication/package/metadata.rb +170 -0
  49. data/lib/epub/publication/package/spine.rb +106 -0
  50. data/lib/epub/publication/package.rb +68 -0
  51. data/lib/epub/publication.rb +2 -0
  52. data/lib/epub.rb +14 -0
  53. data/man/epubinfo.1.ronn +19 -0
  54. data/schemas/epub-nav-30.rnc +10 -0
  55. data/schemas/epub-nav-30.sch +72 -0
  56. data/schemas/epub-xhtml-30.sch +377 -0
  57. data/schemas/ocf-container-30.rnc +16 -0
  58. data/test/fixtures/book/META-INF/container.xml +6 -0
  59. data/test/fixtures/book/OPS/%E6%97%A5%E6%9C%AC%E8%AA%9E.xhtml +10 -0
  60. data/test/fixtures/book/OPS/case-sensitive.xhtml +9 -0
  61. data/test/fixtures/book/OPS/containing space.xhtml +10 -0
  62. data/test/fixtures/book/OPS/containing%20space.xhtml +10 -0
  63. data/test/fixtures/book/OPS/nav.xhtml +28 -0
  64. data/test/fixtures/book/OPS//343/203/253/343/203/274/343/203/210/343/203/225/343/202/241/343/202/244/343/203/253.opf +119 -0
  65. data/test/fixtures/book/OPS//346/227/245/346/234/254/350/252/236.xhtml +10 -0
  66. data/test/fixtures/book/mimetype +1 -0
  67. data/test/helper.rb +9 -0
  68. data/test/test_content_document.rb +92 -0
  69. data/test/test_epub.rb +21 -0
  70. data/test/test_fixed_layout.rb +257 -0
  71. data/test/test_inspect.rb +121 -0
  72. data/test/test_parser.rb +60 -0
  73. data/test/test_parser_content_document.rb +36 -0
  74. data/test/test_parser_fixed_layout.rb +16 -0
  75. data/test/test_parser_ocf.rb +38 -0
  76. data/test/test_parser_publication.rb +247 -0
  77. data/test/test_publication.rb +324 -0
  78. metadata +445 -0
@@ -0,0 +1,121 @@
1
+ require_relative 'helper'
2
+ require 'epub'
3
+
4
+ class TestInspect < Test::Unit::TestCase
5
+ class TestPackage < TestInspect
6
+ include EPUB::Publication
7
+
8
+ def setup
9
+ @package = Package.new
10
+ end
11
+
12
+ def test_package_inspects_object_id
13
+ assert_match (@package.__id__ << 1).to_s(16), @package.inspect
14
+ end
15
+
16
+ def test_package_inspects_attributes
17
+ @package.xml_lang = "zh"
18
+ @package.prefix = {'foaf' => 'http://xmlns.com/foaf/spec/'}
19
+
20
+ assert_match %Q|@xml_lang="zh"|, @package.inspect
21
+ assert_match %Q|@prefix={"foaf"=>"http://xmlns.com/foaf/spec/"}|, @package.inspect
22
+ end
23
+
24
+ def test_package_inspects_content_models
25
+ @package.metadata = Package::Metadata.new
26
+
27
+ assert_match '@metadata=#<EPUB::Publication::Package::Metadata:', @package.inspect
28
+ end
29
+
30
+ class TestMetadata < TestPackage
31
+ Metadata = Package::Metadata
32
+
33
+ def setup
34
+ super
35
+ @metadata = Metadata.new
36
+ @package.metadata = @metadata
37
+ end
38
+
39
+ def test_inspects_package_simply
40
+ assert_match /@package=\#<EPUB::Publication::Package:[^ ]+>/, @metadata.inspect
41
+ end
42
+
43
+ def test_inspects_attributes
44
+ title = Metadata::Title.new
45
+ title.content = 'Book Title'
46
+ @metadata.titles << title
47
+
48
+ title_pattern = RUBY_VERSION >= '2.0' ? '@dc_titles=[#<EPUB::Publication::Package::Metadata::Title' : 'Book Title'
49
+
50
+ assert_match title_pattern, @metadata.inspect
51
+ end
52
+
53
+ def test_dcmes_inspect_includes_class_name
54
+ meta = Package::Metadata::Title.new
55
+ meta.content = 'Book Title'
56
+
57
+ title_pattern = RUBY_VERSION >= '2.0' ? '#<EPUB::Publication::Package::Metadata::Title' : 'Book Title'
58
+
59
+ assert_match title_pattern, meta.inspect
60
+ end
61
+
62
+ def test_dcmes_inspect_includes_instance_variables
63
+ meta = Package::Metadata::DCMES.new
64
+ meta.lang = 'en-US'
65
+ meta.dir = 'rtl'
66
+
67
+ if RUBY_VERSION >= '2.0'
68
+ assert_match /@lang/, meta.inspect
69
+ assert_match /en\-US/, meta.inspect
70
+ assert_match /@dir/, meta.inspect
71
+ assert_match /rtl/, meta.inspect
72
+ else
73
+ assert_equal '', meta.inspect
74
+ end
75
+ end
76
+
77
+ def test_meta_inspect_includes_class_name
78
+ meta = Package::Metadata::Meta.new
79
+
80
+ assert_match /Package::Metadata::Meta/, meta.inspect
81
+ end
82
+
83
+ def test_meta_inspect_includes_instance_variables
84
+ meta = Package::Metadata::Meta.new
85
+ meta.id = 'meta-id'
86
+ meta.content = 'meta content'
87
+
88
+ assert_match /@id/, meta.inspect
89
+ assert_match /meta\-id/, meta.inspect
90
+ assert_match /@content/, meta.inspect
91
+ assert_match /meta content/, meta.inspect
92
+ end
93
+ end
94
+
95
+ class TestManifest < TestPackage
96
+ Manifest = Package::Manifest
97
+
98
+ def setup
99
+ super
100
+ @manifest = Manifest.new
101
+ @package.manifest = @manifest
102
+ end
103
+
104
+ def test_inspects_package_simply
105
+ assert_match /@package=\#<EPUB::Publication::Package:[^ ]+>/, @manifest.inspect
106
+ end
107
+
108
+ class TestItem < TestManifest
109
+ def setup
110
+ super
111
+ @item = Manifest::Item.new
112
+ @manifest << @item
113
+ end
114
+
115
+ def test_inspects_manifest_simply
116
+ assert_match /\#<EPUB::Publication::Package::Manifest:[^ ]+>/, @item.inspect
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,60 @@
1
+ require File.expand_path 'helper', File.dirname(__FILE__)
2
+
3
+ class MyBook
4
+ include EPUB::Book::Features
5
+ end
6
+
7
+ class TestParser < Test::Unit::TestCase
8
+ def setup
9
+ @parser = EPUB::Parser.new 'test/fixtures/book.epub'
10
+ end
11
+
12
+ def test_parse
13
+ assert_instance_of EPUB::Book, @parser.parse
14
+
15
+ book = Object.new
16
+ book.extend EPUB::Book::Features
17
+ assert_nothing_raised do
18
+ EPUB::Parser.parse('test/fixtures/book.epub', book: book)
19
+ end
20
+ assert_kind_of EPUB::Book::Features, EPUB::Parser.parse('test/fixtures/book.epub', book: book)
21
+
22
+ assert_nothing_raised do
23
+ EPUB::Parser.parse('test/fixtures/book.epub', class: MyBook)
24
+ end
25
+ assert_kind_of EPUB::Book::Features, EPUB::Parser.parse('test/fixtures/book.epub', class: MyBook)
26
+ end
27
+
28
+ class TestBook < TestParser
29
+ def setup
30
+ super
31
+ @book = @parser.parse
32
+ end
33
+
34
+ def test_each_page_on_spine_iterates_items_in_spines_order
35
+ @book.each_page_on_spine do |page|
36
+ assert_instance_of EPUB::Publication::Package::Manifest::Item, page
37
+ end
38
+ end
39
+
40
+ def test_each_content_iterates_items_in_manifest
41
+ @book.each_content do |page|
42
+ assert_instance_of EPUB::Publication::Package::Manifest::Item, page
43
+ end
44
+ end
45
+
46
+ def test_each_content_returns_enumerator_when_no_block_passed
47
+ contents = @book.each_content
48
+
49
+ assert_respond_to contents, :each
50
+ end
51
+
52
+ def test_enumerator_returned_by_each_content_iterates_items_in_spines_order
53
+ contents = @book.each_content
54
+
55
+ contents.each do |page|
56
+ assert_instance_of EPUB::Publication::Package::Manifest::Item, page
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+ require_relative 'helper'
3
+
4
+ class TestParserContentDocument < Test::Unit::TestCase
5
+ def setup
6
+ @manifest = EPUB::Publication::Package::Manifest.new
7
+ %w[item-1.xhtml item-2.xhtml nav.xhtml].each.with_index do |href, index|
8
+ item = EPUB::Publication::Package::Manifest::Item.new
9
+ item.id = index
10
+ item.href = Addressable::URI.parse(href)
11
+ @manifest << item
12
+ end
13
+
14
+ @dir = 'test/fixtures/book'
15
+ @parser = EPUB::Parser::ContentDocument.new(@manifest.items.last)
16
+ end
17
+
18
+ def test_parse_navigations
19
+ doc = Nokogiri.XML open("#{@dir}/OPS/nav.xhtml")
20
+ navs = @parser.parse_navigations doc
21
+ nav = navs.first
22
+
23
+ assert_equal 1, navs.length
24
+ assert_equal 'Table of Contents', nav.heading
25
+ assert_equal 'toc', nav.type
26
+
27
+ assert_equal 2, nav.items.length
28
+ assert_equal @manifest.items.first, nav.items.first.item
29
+ assert_equal @manifest.items[1], nav.items[1].items[0].item
30
+ assert_equal @manifest.items[1], nav.items[1].items[1].item
31
+
32
+ assert_equal '第四節', nav.items.last.items.last.text
33
+
34
+ assert_true nav.hidden?
35
+ end
36
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'helper'
2
+ require 'epub/parser'
3
+
4
+ class TestParserFixedLayout < Test::Unit::TestCase
5
+ def test_using_fixed_layout_is_true_when_rendition_property_in_package_prefix
6
+ parser = EPUB::Parser::Publication.new(<<OPF, 'dummy/rootfile.opf')
7
+ <package version="3.0"
8
+ unique-identifier="pub-id"
9
+ xmlns="http://www.idpf.org/2007/opf"
10
+ prefix="rendition: http://www.idpf.org/vocab/rendition/#">
11
+ </package>
12
+ OPF
13
+ package = parser.parse_package
14
+ assert_true package.using_fixed_layout?
15
+ end
16
+ end
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path 'helper', File.dirname(__FILE__)
3
+
4
+ class TestParserOCF < Test::Unit::TestCase
5
+ def setup
6
+ file = 'test/fixtures/book.epub'
7
+ @zip = Zip::Archive.open(file)
8
+ @parser = EPUB::Parser::OCF.new(@zip)
9
+ @container_xml = @zip.fopen('META-INF/container.xml').read
10
+ end
11
+
12
+ def teardown
13
+ @zip.close
14
+ end
15
+
16
+ def test_parsed_container_has_one_rootfile
17
+ assert_equal 1, @parser.parse_container(@container_xml).rootfiles.length
18
+ end
19
+
20
+ def test_parse_container_can_find_primary_rootfile
21
+ container = @parser.parse_container(@container_xml)
22
+
23
+ assert_equal 'OPS/ルートファイル.opf', container.rootfile.full_path.to_s
24
+ end
25
+
26
+ def test_parse_encryption_do_nothing_excluding_to_have_content
27
+ encryption = @parser.parse_encryption('content')
28
+
29
+ assert_equal 'content', encryption.content
30
+ end
31
+
32
+ def test_parse
33
+ assert_nothing_raised do
34
+ @parser.parse
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,247 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path 'helper', File.dirname(__FILE__)
3
+
4
+ class TestParserPublication < Test::Unit::TestCase
5
+ def setup
6
+ file = 'test/fixtures/book.epub'
7
+ rootfile = 'OPS/ルートファイル.opf'
8
+ @zip = Zip::Archive.open(file)
9
+ opf = @zip.fopen(rootfile).read
10
+ @parser = EPUB::Parser::Publication.new(opf, rootfile)
11
+ @package = @parser.parse_package
12
+ end
13
+
14
+ def teardown
15
+ @zip.close
16
+ end
17
+
18
+ def test_parse_package
19
+ assert_equal '3.0', @package.version
20
+ end
21
+
22
+ def test_has_unique_identifier
23
+ @package.metadata = @parser.parse_metadata
24
+ assert_equal 'pub-id', @package.unique_identifier.id
25
+ assert_equal 'da265185-8da8-462d-a146-17dd388f61fc', @package.unique_identifier.to_s
26
+ end
27
+
28
+ def test_has_prefixes_for_vocabulary
29
+ expected = {'foaf' => 'http://xmlns.com/foaf/spec/',
30
+ 'dbp' => 'http://dbpedia.org/ontology/'}
31
+ assert_equal expected, @package.prefix
32
+ end
33
+
34
+ def test_has_empty_hash_as_prefix_when_no_prefix_attribute
35
+ parser = EPUB::Parser::Publication.new('<package></package>', '')
36
+ package = parser.parse_package
37
+ assert_empty package.prefix
38
+ end
39
+
40
+ class TestParseMetadata < TestParserPublication
41
+ def setup
42
+ super
43
+ @metadata = @parser.parse_metadata
44
+ end
45
+
46
+ def test_has_identifier
47
+ assert_equal 'da265185-8da8-462d-a146-17dd388f61fc', @metadata.identifiers.first.content
48
+ end
49
+
50
+ def test_identifier_has_scheme_when_qualified_by_attribute
51
+ assert_equal 'ISBN', @metadata.identifiers[1].scheme
52
+ end
53
+
54
+ def test_has_unique_identifier
55
+ assert_equal 'da265185-8da8-462d-a146-17dd388f61fc', @metadata.unique_identifier.to_s
56
+ end
57
+
58
+ def test_has_five_titles
59
+ assert_equal 5, @metadata.titles.length
60
+ end
61
+
62
+ def test_returns_extended_title_as_title_attribute_if_exists
63
+ assert_equal 'The Great Cookbooks of the World:
64
+ Mon premier guide de cuisson, un Mémoire.
65
+ The New French Cuisine Masters, Volume Two.
66
+ Special Anniversary Edition', @metadata.title
67
+ end
68
+
69
+ def test_titles_has_order
70
+ titles = @metadata.titles
71
+ assert titles[0] > titles[1]
72
+ assert titles[1] < titles[2]
73
+ assert titles[2] < titles[3]
74
+ assert titles[3] > titles[4]
75
+ end
76
+ end
77
+
78
+ class TestParseManifest < TestParserPublication
79
+ def setup
80
+ super
81
+ @manifest = @parser.parse_manifest
82
+ end
83
+
84
+ def test_manifest_has_16_items
85
+ assert_equal 16, @manifest.items.length
86
+ end
87
+
88
+ def test_item_has_relative_path_as_href_attribute
89
+ assert_equal 'nav.xhtml', @manifest['nav'].href.to_s
90
+ end
91
+
92
+ def test_fallback_attribute_of_item_should_be_item_object
93
+ fallback = @manifest['manifest-item-2'].fallback
94
+
95
+ assert_instance_of EPUB::Publication::Package::Manifest::Item, fallback
96
+ assert_equal 'manifest-item-fallback', fallback.id
97
+ end
98
+
99
+ def test_item_is_readable
100
+ item = EPUB::Parser.parse('test/fixtures/book.epub').package.manifest.items.first
101
+ doc = Nokogiri.XML item.read
102
+
103
+ assert_equal 'html', doc.root.name
104
+ end
105
+
106
+ def test_item_unescape_href_when_reading_file
107
+ item = EPUB::Parser.parse('test/fixtures/book.epub').package.manifest['containing-encoded-space']
108
+ doc = Nokogiri.HTML(item.read)
109
+ assert_equal 'Containing Space', (doc/'title').first.content
110
+ end
111
+
112
+ def test_iri_of_item_is_case_sensitive
113
+ manifest = EPUB::Parser.parse('test/fixtures/book.epub').package.manifest
114
+
115
+ assert_not_equal manifest['large-file-name'].read, manifest['small-file-name'].read
116
+ end
117
+
118
+ def test_item_can_traverse_fallback_chain
119
+ assert_equal [@manifest['manifest-item-2'], @manifest['manifest-item-fallback'], @manifest['manifest-item-fallback2']],
120
+ @manifest['manifest-item-2'].fallback_chain
121
+ end
122
+
123
+ def test_item_always_has_fallback_chain_including_itself
124
+ item = @manifest['manifest-item-1']
125
+
126
+ assert_equal [item], item.fallback_chain
127
+ end
128
+
129
+ def test_item_can_use_fallback_chain_when_not_core_media_type_by_default
130
+ item = @manifest['manifest-item-2']
131
+ fallback = item.fallback
132
+ result = item.use_fallback_chain do |current|
133
+ current
134
+ end
135
+
136
+ assert_equal fallback, result
137
+ end
138
+
139
+ def test_item_can_custome_supported_media_type_in_use_fallback_chain
140
+ item = @manifest['manifest-item-2']
141
+ result = item.use_fallback_chain supported: 'application/pdf' do |current|
142
+ current
143
+ end
144
+
145
+ assert_equal item, result
146
+ end
147
+
148
+ def test_item_can_custome_not_supported_media_type_in_use_fallback_chain
149
+ item = @manifest['manifest-item-2']
150
+ fallback = item.fallback.fallback
151
+ result = item.use_fallback_chain unsupported: 'image/svg+xml' do |current|
152
+ current
153
+ end
154
+
155
+ assert_equal fallback, result
156
+ end
157
+
158
+ def test_item_with_absolute_iri_as_href_must_keep_it
159
+ item = @manifest['external-css']
160
+ assert_equal 'http://example.net/stylesheets/common.css', item.href.to_s
161
+ end
162
+ end
163
+
164
+ class TestParseSpine < TestParserPublication
165
+ def setup
166
+ super
167
+ @spine = @parser.parse_spine
168
+ end
169
+
170
+ def atest_each_itemref_yields_itemref_in_order_on_spine_element
171
+ expected = %w[nav manifest-item-1 manifest-item-2 containing-space japanese-filename].map {|idref|
172
+ itemref = EPUB::Publication::Package::Spine::Itemref.new
173
+ itemref.id = nil
174
+ itemref.spine = @spine
175
+ itemref.idref = idref
176
+ itemref.linear = true
177
+ itemref.properties = []
178
+ itemref
179
+ }
180
+ assert_equal expected, @spine.each_itemref.to_a
181
+ end
182
+ end
183
+
184
+ class TestParseGuide < TestParserPublication
185
+ def setup
186
+ super
187
+ @guide = @parser.parse_guide
188
+ end
189
+
190
+ def test_guide_has_one_reference
191
+ assert_equal 1, @guide.references.length
192
+ end
193
+
194
+ def test_guide_has_cover_reference
195
+ assert @guide.cover
196
+ assert_equal 'cover', @guide.cover.type
197
+ end
198
+
199
+ def test_reference_refers_item
200
+ @parser.parse_manifest
201
+
202
+ assert_instance_of EPUB::Publication::Package::Manifest::Item, @guide.cover.item
203
+ end
204
+ end
205
+
206
+ class TestParseBindings < TestParserPublication
207
+ def setup
208
+ super
209
+ @package.manifest = @parser.parse_manifest
210
+ @bindings = @parser.parse_bindings
211
+ @bindings.package = @package
212
+ end
213
+
214
+ def test_has_one_bindings
215
+ assert @bindings
216
+ end
217
+
218
+ def test_bindings_has_one_media_type
219
+ assert_equal 1, @bindings.media_types.length
220
+ end
221
+
222
+ def test_bindings_is_accessible_like_hash
223
+ media_type = @bindings.media_types.first
224
+ assert_equal media_type, @bindings['application/x-demo-slideshow']
225
+ assert_nil @bindings['non-existing-media-type']
226
+ end
227
+
228
+ def test_media_type_has_media_type_attribute
229
+ assert_equal 'application/x-demo-slideshow', @bindings.media_types.first.media_type
230
+ end
231
+
232
+ def test_media_type_has_handler_attribute
233
+ assert_not_nil @bindings.media_types.first.handler
234
+ end
235
+
236
+ def test_media_type_refers_item_as_handler
237
+ assert_kind_of EPUB::Publication::Package::Manifest::Item, @bindings.media_types.first.handler
238
+ end
239
+
240
+ def test_use_fallback_chain_use_bindings
241
+ item = @package.manifest['slideshow']
242
+ item.use_fallback_chain do |slideshow|
243
+ assert_equal 'impl', slideshow.id
244
+ end
245
+ end
246
+ end
247
+ end