gepub 0.6.5.2 → 0.6.6
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +29 -0
- data/README.md +30 -55
- data/lib/gepub/bindings.rb +65 -0
- data/lib/gepub/book.rb +23 -12
- data/lib/gepub/builder.rb +1 -1
- data/lib/gepub/item.rb +5 -2
- data/lib/gepub/metadata.rb +11 -2
- data/lib/gepub/package.rb +4 -1
- data/lib/gepub/resource_builder.rb +17 -1
- data/lib/gepub/spine.rb +28 -4
- data/lib/gepub/version.rb +1 -1
- data/lib/gepub.rb +1 -0
- data/spec/bindings_spec.rb +34 -0
- data/spec/builder_spec.rb +42 -0
- data/spec/fixtures/testdata/test2.opf +63 -0
- data/spec/fixtures/testdata/test_with_bindings.opf +67 -0
- data/spec/gepub_spec.rb +14 -0
- data/spec/metadata_spec.rb +6 -0
- data/spec/spine_spec.rb +14 -0
- metadata +16 -8
data/LICENSE.txt
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# LICENSE:
|
2
|
+
|
3
|
+
(The New BSD License)
|
4
|
+
|
5
|
+
Copyright (c) 2010-2012, KOJIMA Satoshi
|
6
|
+
All rights reserved.
|
7
|
+
|
8
|
+
Redistribution and use in source and binary forms, with or without
|
9
|
+
modification, are permitted provided that the following conditions are met:
|
10
|
+
|
11
|
+
* Redistributions of source code must retain the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer.
|
13
|
+
* Redistributions in binary form must reproduce the above copyright
|
14
|
+
notice, this list of conditions and the following disclaimer in the
|
15
|
+
documentation and/or other materials provided with the distribution.
|
16
|
+
* Neither the name of the <organization> nor the
|
17
|
+
names of its contributors may be used to endorse or promote products
|
18
|
+
derived from this software without specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
21
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
22
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
24
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
25
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
26
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
27
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
28
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
29
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# gepub
|
1
|
+
# gepub [<img src="https://secure.travis-ci.org/skoji/gepub.png" />](http://travis-ci.org/skoji/gepub)
|
2
2
|
|
3
3
|
* http://github.com/skoji/gepub
|
4
4
|
|
@@ -14,74 +14,49 @@ a generic EPUB parser/generator library.
|
|
14
14
|
|
15
15
|
* See [issues](https://github.com/skoji/gepub/issues/) for known problems.
|
16
16
|
|
17
|
+
|
17
18
|
## SYNOPSIS:
|
18
19
|
|
19
20
|
### Builder Example
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
```ruby
|
23
|
+
require 'rubygem'
|
24
|
+
require 'gepub'
|
25
|
+
builder = GEPUB::Builder.new {
|
26
|
+
language 'en'
|
27
|
+
unique_identifier 'http:/example.jp/bookid_in_url', 'BookID', 'URL'
|
28
|
+
title 'GEPUB Sample Book'
|
29
|
+
subtitle 'This book is just a sample'
|
28
30
|
|
29
|
-
|
31
|
+
creator 'KOJIMA Satoshi'
|
30
32
|
|
31
|
-
|
33
|
+
contributors 'Denshobu', 'Asagaya Densho', 'Shonan Densho Teidan', 'eMagazine Torutaru'
|
32
34
|
|
33
|
-
|
35
|
+
date '2012-02-29T00:00:00Z'
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
resources(:workdir => '~/epub/sample_book_source/') {
|
38
|
+
cover_image 'img/image1.jpg' => 'image1.jpg'
|
39
|
+
ordered {
|
40
|
+
file 'text/chap1.xhtml'
|
41
|
+
heading 'Chapter 1'
|
40
42
|
|
41
|
-
|
43
|
+
file 'text/chap1-1.xhtml'
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
}
|
46
|
-
}
|
45
|
+
file 'text/chap2.html'
|
46
|
+
heading 'Chapter 2'
|
47
47
|
}
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
}
|
49
|
+
}
|
50
|
+
epubname = File.join(File.dirname(__FILE__), 'example_test_with_builder.epub')
|
51
|
+
builder.generate_epub(epubname)
|
52
|
+
```
|
51
53
|
[more builder examples](https://gist.github.com/1878995)
|
52
|
-
|
53
|
-
[examples in this repository](https://github.com/skoji/gepub/tree/master/examples/)
|
54
|
+
[examples in this repository](https://github.com/skoji/gepub/tree/master/examples/)
|
54
55
|
|
55
56
|
## INSTALL:
|
56
57
|
|
57
58
|
* gem install gepub
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
(
|
62
|
-
|
63
|
-
Copyright (c) 2010-2012, KOJIMA Satoshi
|
64
|
-
All rights reserved.
|
65
|
-
|
66
|
-
Redistribution and use in source and binary forms, with or without
|
67
|
-
modification, are permitted provided that the following conditions are met:
|
68
|
-
|
69
|
-
* Redistributions of source code must retain the above copyright
|
70
|
-
notice, this list of conditions and the following disclaimer.
|
71
|
-
* Redistributions in binary form must reproduce the above copyright
|
72
|
-
notice, this list of conditions and the following disclaimer in the
|
73
|
-
documentation and/or other materials provided with the distribution.
|
74
|
-
* Neither the name of the <organization> nor the
|
75
|
-
names of its contributors may be used to endorse or promote products
|
76
|
-
derived from this software without specific prior written permission.
|
77
|
-
|
78
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
79
|
-
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
80
|
-
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
81
|
-
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
82
|
-
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
83
|
-
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
84
|
-
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
85
|
-
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
86
|
-
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
87
|
-
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
60
|
+
|
61
|
+
|
62
|
+
[![endorse](http://api.coderwall.com/skoji/endorse.png)](http://coderwall.com/skoji)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'nokogiri'
|
3
|
+
module GEPUB
|
4
|
+
class Bindings
|
5
|
+
include XMLUtil
|
6
|
+
class MediaType
|
7
|
+
attr_accessor :handler, :media_type
|
8
|
+
def initialize(handler, media_type)
|
9
|
+
@handler = handler
|
10
|
+
@media_type = media_type
|
11
|
+
end
|
12
|
+
def to_xml(builder)
|
13
|
+
builder.mediaType({'handler' => @handler, 'media-type' => @media_type})
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@media_types = []
|
19
|
+
@handler_by_media_type = {}
|
20
|
+
yield self if block_given?
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.parse(bindings_xml)
|
24
|
+
Bindings.new {
|
25
|
+
|bindings|
|
26
|
+
bindings.instance_eval {
|
27
|
+
if !bindings_xml.nil?
|
28
|
+
@xml = bindings_xml
|
29
|
+
@namespaces = @xml.namespaces
|
30
|
+
@attributes = attr_to_hash(@xml.attributes)
|
31
|
+
@xml.xpath("//#{ns_prefix(OPF_NS)}:bindings/#{ns_prefix(OPF_NS)}:mediaType", @namespaces).map {
|
32
|
+
|mediaType|
|
33
|
+
@media_types << MediaType.new(mediaType['handler'], mediaType['media-type'])
|
34
|
+
@handler_by_media_type[mediaType['media-type']] = mediaType['handler']
|
35
|
+
}
|
36
|
+
end
|
37
|
+
}
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def media_types
|
42
|
+
return @media_types.dup
|
43
|
+
end
|
44
|
+
|
45
|
+
def handler_by_media_type
|
46
|
+
return @handler_by_media_type.dup
|
47
|
+
end
|
48
|
+
|
49
|
+
def add(id, media_type)
|
50
|
+
@media_types << MediaType.new(id, media_type)
|
51
|
+
@handler_by_media_type[media_type] = id
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_xml(builder)
|
55
|
+
if (media_types.size > 0)
|
56
|
+
builder.bindings {
|
57
|
+
@media_types.each {
|
58
|
+
|mediaType|
|
59
|
+
mediaType.to_xml(builder)
|
60
|
+
}
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/gepub/book.rb
CHANGED
@@ -178,10 +178,7 @@ module GEPUB
|
|
178
178
|
@toc.push({ :item => item, :text => text, :id => id})
|
179
179
|
end
|
180
180
|
|
181
|
-
|
182
|
-
# the added item will be referenced by the first argument in the EPUB container.
|
183
|
-
def add_item(href, io_or_filename = nil, id = nil, attributes = {})
|
184
|
-
item = @package.add_item(href,nil,id,attributes)
|
181
|
+
def set_sigleton_methods_to_item(item)
|
185
182
|
toc = @toc
|
186
183
|
metaclass = (class << item;self;end)
|
187
184
|
metaclass.send(:define_method, :toc_text,
|
@@ -194,24 +191,38 @@ module GEPUB
|
|
194
191
|
toc.push(:item => item, :text => text, :id => id)
|
195
192
|
item
|
196
193
|
})
|
194
|
+
bindings = @package.bindings
|
195
|
+
metaclass.send(:define_method, :is_handler_of,
|
196
|
+
Proc.new { |media_type|
|
197
|
+
bindings.add(item.id, media_type)
|
198
|
+
item
|
199
|
+
})
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
# add an item(i.e. html, images, audios, etc) to Book.
|
204
|
+
# the added item will be referenced by the first argument in the EPUB container.
|
205
|
+
def add_item(href, io_or_filename = nil, id = nil, attributes = {})
|
206
|
+
item = @package.add_item(href,nil,id,attributes)
|
207
|
+
set_sigleton_methods_to_item(item)
|
197
208
|
item.add_content io_or_filename unless io_or_filename.nil?
|
198
209
|
item
|
199
210
|
end
|
200
211
|
|
201
212
|
# same as add_item, but the item will be added to spine of the EPUB.
|
202
|
-
|
203
213
|
def add_ordered_item(href, io_or_filename = nil, id = nil, attributes = {})
|
204
214
|
item = @package.add_ordered_item(href,io_or_filename,id,attributes)
|
205
|
-
|
206
|
-
(class << item;self;end).send(:define_method, :toc_text,
|
207
|
-
Proc.new { |text|
|
208
|
-
toc.push(:item => item, :text => text, :id => nil)
|
209
|
-
item
|
210
|
-
})
|
215
|
+
set_sigleton_methods_to_item(item)
|
211
216
|
yield item if block_given?
|
212
217
|
item
|
213
218
|
end
|
214
|
-
|
219
|
+
|
220
|
+
|
221
|
+
# get handler item which defined in bindings for media type,
|
222
|
+
def get_handler_of(media_type)
|
223
|
+
items[@package.bindings.handler_by_media_type[media_type]]
|
224
|
+
end
|
225
|
+
|
215
226
|
def method_missing(name,*args)
|
216
227
|
@package.send(name, *args)
|
217
228
|
end
|
data/lib/gepub/builder.rb
CHANGED
data/lib/gepub/item.rb
CHANGED
@@ -98,6 +98,9 @@ module GEPUB
|
|
98
98
|
if parsed.xpath("//epub:switch", { 'epub' => 'http://www.idpf.org/2007/ops' }).size > 0
|
99
99
|
self.add_property('switch')
|
100
100
|
end
|
101
|
+
if parsed.xpath("//#{prefix}script").size > 0
|
102
|
+
self.add_property('scripted')
|
103
|
+
end
|
101
104
|
end
|
102
105
|
end
|
103
106
|
|
@@ -122,11 +125,11 @@ module GEPUB
|
|
122
125
|
# generate xml to supplied Nokogiri builder.
|
123
126
|
def to_xml(builder, opf_version = '3.0')
|
124
127
|
attr = @attributes.dup
|
125
|
-
|
128
|
+
if opf_version.to_f < 3.0
|
126
129
|
attr.reject!{ |k,v| k == 'properties' }
|
127
130
|
end
|
128
131
|
if !attr['properties'].nil?
|
129
|
-
attr['properties'] = attr['properties'].join(' ')
|
132
|
+
attr['properties'] = attr['properties'].uniq.join(' ')
|
130
133
|
if attr['properties'].size == 0
|
131
134
|
attr.delete 'properties'
|
132
135
|
end
|
data/lib/gepub/metadata.rb
CHANGED
@@ -69,7 +69,7 @@ module GEPUB
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def main_title # should make it obsolete?
|
72
|
-
|
72
|
+
title.to_s
|
73
73
|
end
|
74
74
|
|
75
75
|
def oldstyle_meta
|
@@ -94,7 +94,6 @@ module GEPUB
|
|
94
94
|
end
|
95
95
|
}
|
96
96
|
|
97
|
-
#TODO: should override for 'title'. // for 'main title' not always comes first.
|
98
97
|
define_method(node) {
|
99
98
|
get_first_node(node)
|
100
99
|
}
|
@@ -116,6 +115,16 @@ module GEPUB
|
|
116
115
|
}
|
117
116
|
}
|
118
117
|
|
118
|
+
def title
|
119
|
+
if !@content_nodes['title'].nil?
|
120
|
+
@content_nodes['title'].each do
|
121
|
+
|titlenode|
|
122
|
+
return titlenode if titlenode.title_type.to_s == TITLE_TYPE::MAIN
|
123
|
+
end
|
124
|
+
end
|
125
|
+
get_first_node('title')
|
126
|
+
end
|
127
|
+
|
119
128
|
def get_first_node(node)
|
120
129
|
if !@content_nodes[node].nil? && @content_nodes[node].size > 0
|
121
130
|
@content_nodes[node][0]
|
data/lib/gepub/package.rb
CHANGED
@@ -5,7 +5,7 @@ module GEPUB
|
|
5
5
|
# Holds data in opf file.
|
6
6
|
class Package
|
7
7
|
include XMLUtil
|
8
|
-
attr_accessor :path, :metadata, :manifest, :spine, :epub_backward_compat, :contents_prefix
|
8
|
+
attr_accessor :path, :metadata, :manifest, :spine, :bindings, :epub_backward_compat, :contents_prefix
|
9
9
|
|
10
10
|
class IDPool
|
11
11
|
def initialize
|
@@ -62,6 +62,7 @@ module GEPUB
|
|
62
62
|
@metadata = Metadata.parse(@xml.at_xpath("//#{ns_prefix(OPF_NS)}:metadata"), @attributes['version'], @id_pool)
|
63
63
|
@manifest = Manifest.parse(@xml.at_xpath("//#{ns_prefix(OPF_NS)}:manifest"), @attributes['version'], @id_pool)
|
64
64
|
@spine = Spine.parse(@xml.at_xpath("//#{ns_prefix(OPF_NS)}:spine"), @attributes['version'], @id_pool)
|
65
|
+
@bindings = Bindings.parse(@xml.at_xpath("//#{ns_prefix(OPF_NS)}:bindings"))
|
65
66
|
}
|
66
67
|
}
|
67
68
|
end
|
@@ -82,6 +83,7 @@ module GEPUB
|
|
82
83
|
@metadata = Metadata.new(version)
|
83
84
|
@manifest = Manifest.new(version)
|
84
85
|
@spine = Spine.new(version)
|
86
|
+
@bindings = Bindings.new
|
85
87
|
@epub_backward_compat = true
|
86
88
|
yield self if block_given?
|
87
89
|
end
|
@@ -234,6 +236,7 @@ module GEPUB
|
|
234
236
|
@metadata.to_xml(xml)
|
235
237
|
@manifest.to_xml(xml)
|
236
238
|
@spine.to_xml(xml)
|
239
|
+
@bindings.to_xml(xml)
|
237
240
|
}
|
238
241
|
}
|
239
242
|
builder.to_xml(:encoding => 'utf-8')
|
@@ -71,6 +71,18 @@ module GEPUB
|
|
71
71
|
}
|
72
72
|
end
|
73
73
|
|
74
|
+
def page_spread_left
|
75
|
+
itemref = @book.spine.itemref_by_id[@last_defined_item.item.id]
|
76
|
+
raise 'page_spread_left should be called inside ordered' if (itemref.nil?)
|
77
|
+
itemref.page_spread_left
|
78
|
+
end
|
79
|
+
|
80
|
+
def page_spread_right
|
81
|
+
itemref = @book.spine.itemref_by_id[@last_defined_item.item.id]
|
82
|
+
raise 'page_spread_right should be called inside ordered' if (itemref.nil?)
|
83
|
+
itemref.page_spread_right
|
84
|
+
end
|
85
|
+
|
74
86
|
def glob(arg)
|
75
87
|
files(*Dir.glob(arg))
|
76
88
|
end
|
@@ -140,7 +152,11 @@ module GEPUB
|
|
140
152
|
item2
|
141
153
|
}
|
142
154
|
end
|
143
|
-
|
155
|
+
|
156
|
+
def handles(media_type)
|
157
|
+
@last_defined_item.is_handler_of(media_type)
|
158
|
+
end
|
159
|
+
|
144
160
|
private
|
145
161
|
|
146
162
|
def create_one_file(val)
|
data/lib/gepub/spine.rb
CHANGED
@@ -38,8 +38,26 @@ module GEPUB
|
|
38
38
|
(@attributes['properties'] ||=[]) << property
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
42
|
-
|
41
|
+
def page_spread_right
|
42
|
+
add_property 'page-spread-right'
|
43
|
+
end
|
44
|
+
|
45
|
+
def page_spread_left
|
46
|
+
add_property 'page-spread-left'
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_xml(builder, opf_version)
|
50
|
+
attr = @attributes.dup
|
51
|
+
if opf_version.to_f < 3.0
|
52
|
+
attr.reject!{ |k,v| k == 'properties' }
|
53
|
+
end
|
54
|
+
if !attr['properties'].nil?
|
55
|
+
attr['properties'] = attr['properties'].join(' ')
|
56
|
+
if attr['properties'].size == 0
|
57
|
+
attr.delete 'properties'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
builder.itemref(attr)
|
43
61
|
end
|
44
62
|
end
|
45
63
|
|
@@ -50,7 +68,7 @@ module GEPUB
|
|
50
68
|
@xml = spine_xml
|
51
69
|
@namespaces = @xml.namespaces
|
52
70
|
@attributes = attr_to_hash(@xml.attributes)
|
53
|
-
|
71
|
+
@item_refs = []
|
54
72
|
@xml.xpath("//#{ns_prefix(OPF_NS)}:spine/#{ns_prefix(OPF_NS)}:itemref", @namespaces).map {
|
55
73
|
|itemref|
|
56
74
|
i = Itemref.create(self, attr_to_hash(itemref.attributes))
|
@@ -64,6 +82,7 @@ module GEPUB
|
|
64
82
|
@id_pool = id_pool
|
65
83
|
@attributes = {}
|
66
84
|
@item_refs = []
|
85
|
+
@itemref_by_id = {}
|
67
86
|
@opf_version = opf_version
|
68
87
|
yield self if block_given?
|
69
88
|
end
|
@@ -79,8 +98,13 @@ module GEPUB
|
|
79
98
|
@item_refs.dup
|
80
99
|
end
|
81
100
|
|
101
|
+
def itemref_by_id
|
102
|
+
@itemref_by_id.dup
|
103
|
+
end
|
104
|
+
|
82
105
|
def push(item)
|
83
106
|
@item_refs << i = Itemref.new(item.id, self)
|
107
|
+
@itemref_by_id[item.id] = i
|
84
108
|
i
|
85
109
|
end
|
86
110
|
|
@@ -92,7 +116,7 @@ module GEPUB
|
|
92
116
|
builder.spine(@attributes) {
|
93
117
|
@item_refs.each {
|
94
118
|
|ref|
|
95
|
-
ref.to_xml(builder)
|
119
|
+
ref.to_xml(builder, @opf_version)
|
96
120
|
}
|
97
121
|
}
|
98
122
|
end
|
data/lib/gepub/version.rb
CHANGED
data/lib/gepub.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'nokogiri'
|
5
|
+
|
6
|
+
describe GEPUB::Bindings do
|
7
|
+
context 'parse existing opf' do
|
8
|
+
before do
|
9
|
+
@bindings = GEPUB::Package.parse_opf(File.open(File.dirname(__FILE__) + '/fixtures/testdata/test_with_bindings.opf'), '/package.opf').instance_eval{ @bindings }
|
10
|
+
end
|
11
|
+
it 'should be parsed' do
|
12
|
+
@bindings.media_types.size.should == 2
|
13
|
+
@bindings.media_types[0].handler.should == 'h'
|
14
|
+
@bindings.media_types[0].media_type.should == 'application/x-foreign-type'
|
15
|
+
@bindings.media_types[1].handler.should == 'v'
|
16
|
+
@bindings.media_types[1].media_type.should == 'application/x-other-foreign-type'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'generate new opf' do
|
21
|
+
it 'should generate xml' do
|
22
|
+
bindings = GEPUB::Bindings.new
|
23
|
+
bindings.add('id1', 'application/x-some-type')
|
24
|
+
builder = Nokogiri::XML::Builder.new { |xml|
|
25
|
+
xml.package('xmlns' => "http://www.idpf.org/2007/opf",'version' => "3.0",'unique-identifier' => "pub-id",'xml:lang' => "ja") {
|
26
|
+
bindings.to_xml(xml)
|
27
|
+
}
|
28
|
+
}
|
29
|
+
xml = Nokogiri::XML::Document.parse(builder.to_xml)
|
30
|
+
xml.xpath("//xmlns:mediaType[@handler='id1' and @media-type='application/x-some-type']").size.should == 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/spec/builder_spec.rb
CHANGED
@@ -287,6 +287,18 @@ describe GEPUB::Builder do
|
|
287
287
|
builder.instance_eval{ @book.item_by_href('text/cover.xhtml') }.should_not be_nil
|
288
288
|
builder.instance_eval{ @book.item_by_href('text/cover.xhtml').media_type }.should == 'application/xhtml+xml'
|
289
289
|
end
|
290
|
+
|
291
|
+
it 'should specify bindings handler' do
|
292
|
+
builder = GEPUB::Builder.new {
|
293
|
+
resources {
|
294
|
+
file 'scripts/handler.xhtml' => nil
|
295
|
+
handles 'application/x-some-foregin-type'
|
296
|
+
}
|
297
|
+
}
|
298
|
+
builder.instance_eval{
|
299
|
+
@book.get_handler_of('application/x-some-foregin-type').id == @book.item_by_href('scripts/handler.xhtml').id
|
300
|
+
}
|
301
|
+
end
|
290
302
|
|
291
303
|
it 'should add files to book in spine' do
|
292
304
|
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
@@ -326,6 +338,24 @@ describe GEPUB::Builder do
|
|
326
338
|
builder.instance_eval{ @book.instance_eval { @toc[1][:text] }}.should == 'memo text'
|
327
339
|
end
|
328
340
|
|
341
|
+
it 'should add files and page-spread-property' do
|
342
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
343
|
+
builder = GEPUB::Builder.new {
|
344
|
+
resources(:workdir => workdir) {
|
345
|
+
ordered {
|
346
|
+
file('text/cover.xhtml')
|
347
|
+
page_spread_left
|
348
|
+
file('text/memo.txt')
|
349
|
+
page_spread_right
|
350
|
+
}
|
351
|
+
}
|
352
|
+
}
|
353
|
+
builder.instance_eval{ @book.item_by_href('text/cover.xhtml') }.should_not be_nil
|
354
|
+
builder.instance_eval{ @book.spine.itemref_list[0].properties[0] }.should == 'page-spread-left'
|
355
|
+
builder.instance_eval{ @book.item_by_href('text/memo.txt') }.should_not be_nil
|
356
|
+
builder.instance_eval{ @book.spine.itemref_list[1].properties[0] }.should == 'page-spread-right'
|
357
|
+
end
|
358
|
+
|
329
359
|
it 'should handle fallback chain' do
|
330
360
|
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
331
361
|
builder = GEPUB::Builder.new {
|
@@ -486,6 +516,18 @@ describe GEPUB::Builder do
|
|
486
516
|
}
|
487
517
|
end
|
488
518
|
|
519
|
+
it 'should handle scripted property' do
|
520
|
+
builder = GEPUB::Builder.new {
|
521
|
+
unique_identifier 'uid'
|
522
|
+
resources {
|
523
|
+
file 'scripted.xhtml' => StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"><head><script>alert("scripted");</script></head><body><div><p>text comes here</p></div></body></html>')
|
524
|
+
}
|
525
|
+
}
|
526
|
+
builder.instance_eval {
|
527
|
+
@book.item_by_href('scripted.xhtml').properties[0].should == 'scripted'
|
528
|
+
}
|
529
|
+
end
|
530
|
+
|
489
531
|
it 'should handle optional file' do
|
490
532
|
builder = GEPUB::Builder.new {
|
491
533
|
optional_file 'META-INF/test.xml' => StringIO.new('<test></test>')
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
2
|
+
|
3
|
+
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" unique-identifier="pub-id" xml:lang="ja">
|
4
|
+
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" >
|
5
|
+
<dc:identifier id="pub-id">urn:uuid:1234567890</dc:identifier>
|
6
|
+
<meta refines="#pub-id" property="identifier-type" scheme="xsd:string">uuid</meta>
|
7
|
+
<dc:identifier id="pub-id2">http://example.jp/epub/test/url</dc:identifier>
|
8
|
+
<meta refines="#pub-id2" property="identifier-type" scheme="xsd:string">uri</meta>
|
9
|
+
|
10
|
+
<dc:title id="title">TheTitle</dc:title>
|
11
|
+
<meta refines="#title" property="title-type">main</meta>
|
12
|
+
<meta refines="#title" property="display-seq">2</meta>
|
13
|
+
<dc:title id="series">Series Title</dc:title>
|
14
|
+
<meta refines="#series" property="title-type">collection</meta>
|
15
|
+
<meta refines="#series" property="display-seq">3</meta>
|
16
|
+
<dc:title id="subtitle">subTitle diplaies first</dc:title>
|
17
|
+
<meta refines="#subtitle" property="title-type">subtitle</meta>
|
18
|
+
<meta refines="#subtitle" property="display-seq">1</meta>
|
19
|
+
|
20
|
+
<dc:language id="pub-lang">ja</dc:language>
|
21
|
+
|
22
|
+
<dc:creator id="author1">最初の著者</dc:creator>
|
23
|
+
<meta refines="#author1" property="role" scheme="marc:relators">aut</meta>
|
24
|
+
<meta refines="#author1" property="display-seq">1</meta>
|
25
|
+
<meta refines="#author1" property="file-as">さいしょのちょしゃ</meta>
|
26
|
+
<dc:creator id="author3">三人目</dc:creator>
|
27
|
+
<meta refines="#author3" property="role" scheme="marc:relators">prg</meta>
|
28
|
+
<meta refines="#author3" property="display-seq">3</meta>
|
29
|
+
<meta refines="#author3" property="file-as">さんにんめ</meta>
|
30
|
+
<dc:creator id="author2">ふたりめ</dc:creator>
|
31
|
+
<meta refines="#author2" property="role" scheme="marc:relators">aut</meta>
|
32
|
+
<meta refines="#author2" property="display-seq">2</meta>
|
33
|
+
<meta refines="#author2" property="file-as">ふたりめ</meta>
|
34
|
+
|
35
|
+
|
36
|
+
<dc:publisher id="publisher">小嶋智</dc:publisher>
|
37
|
+
|
38
|
+
<meta property="dcterms:issued" id="issued">2012-02-12T15:00:00Z</meta>
|
39
|
+
<meta property="dcterms:modified" id="modified">2012-02-12T19:00:00Z</meta>
|
40
|
+
<meta name="cover" content="cover-image" />
|
41
|
+
</metadata>
|
42
|
+
|
43
|
+
|
44
|
+
<manifest>
|
45
|
+
<item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />
|
46
|
+
<item id="cover" href="cover/cover.xhtml" media-type="application/xhtml+xml" />
|
47
|
+
<item id="cover-image" href="img/cover.jpg" properties="cover-image" media-type="image/jpeg" />
|
48
|
+
<item id="toc" href="toc.xhtml" media-type="application/xhtml+xml" />
|
49
|
+
<item id="nav" href="nav.xhtml" properties="nav" media-type="application/xhtml+xml" />
|
50
|
+
<item id="chap1" href="chap1.xhtml" media-type="application/xhtml+xml" />
|
51
|
+
<item id="css" href="style/default.css" media-type="text/css" />
|
52
|
+
<item id="object" href="img/test.png" media-type="image/png" />
|
53
|
+
<item id="object2" href="resource/image.jpg" media-type="image/jpg" />
|
54
|
+
</manifest>
|
55
|
+
|
56
|
+
<spine toc="ncx" page-progression-direction="ltr">
|
57
|
+
<itemref idref="cover" linear="no" />
|
58
|
+
<itemref idref="toc" linear="yes" />
|
59
|
+
<itemref idref="chap1" linear="yes" />
|
60
|
+
<itemref idref="nav" linear="no" />
|
61
|
+
</spine>
|
62
|
+
|
63
|
+
</package>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
2
|
+
|
3
|
+
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" unique-identifier="pub-id" xml:lang="ja">
|
4
|
+
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" >
|
5
|
+
<dc:identifier id="pub-id">urn:uuid:1234567890</dc:identifier>
|
6
|
+
<meta refines="#pub-id" property="identifier-type" scheme="xsd:string">uuid</meta>
|
7
|
+
<dc:identifier id="pub-id2">http://example.jp/epub/test/url</dc:identifier>
|
8
|
+
<meta refines="#pub-id2" property="identifier-type" scheme="xsd:string">uri</meta>
|
9
|
+
|
10
|
+
<dc:title id="series">Series Title</dc:title>
|
11
|
+
<meta refines="#series" property="title-type">collection</meta>
|
12
|
+
<meta refines="#series" property="display-seq">2</meta>
|
13
|
+
<dc:title id="title">TheTitle</dc:title>
|
14
|
+
<meta refines="#title" property="title-type">main</meta>
|
15
|
+
<meta refines="#title" property="display-seq">1</meta>
|
16
|
+
|
17
|
+
<dc:language id="pub-lang">ja</dc:language>
|
18
|
+
|
19
|
+
<dc:creator id="author1">最初の著者</dc:creator>
|
20
|
+
<meta refines="#author1" property="role" scheme="marc:relators">aut</meta>
|
21
|
+
<meta refines="#author1" property="display-seq">1</meta>
|
22
|
+
<meta refines="#author1" property="file-as">さいしょのちょしゃ</meta>
|
23
|
+
<dc:creator id="author3">三人目</dc:creator>
|
24
|
+
<meta refines="#author3" property="role" scheme="marc:relators">prg</meta>
|
25
|
+
<meta refines="#author3" property="display-seq">3</meta>
|
26
|
+
<meta refines="#author3" property="file-as">さんにんめ</meta>
|
27
|
+
<dc:creator id="author2">ふたりめ</dc:creator>
|
28
|
+
<meta refines="#author2" property="role" scheme="marc:relators">aut</meta>
|
29
|
+
<meta refines="#author2" property="display-seq">2</meta>
|
30
|
+
<meta refines="#author2" property="file-as">ふたりめ</meta>
|
31
|
+
|
32
|
+
|
33
|
+
<dc:publisher id="publisher">小嶋智</dc:publisher>
|
34
|
+
|
35
|
+
<meta property="dcterms:issued" id="issued">2012-02-12T15:00:00Z</meta>
|
36
|
+
<meta property="dcterms:modified" id="modified">2012-02-12T19:00:00Z</meta>
|
37
|
+
<meta name="cover" content="cover-image" />
|
38
|
+
</metadata>
|
39
|
+
|
40
|
+
|
41
|
+
<manifest>
|
42
|
+
<item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />
|
43
|
+
<item id="cover" href="cover/cover.xhtml" media-type="application/xhtml+xml" />
|
44
|
+
<item id="cover-image" href="img/cover.jpg" properties="cover-image" media-type="image/jpeg" />
|
45
|
+
<item id="toc" href="toc.xhtml" media-type="application/xhtml+xml" />
|
46
|
+
<item id="nav" href="nav.xhtml" properties="nav" media-type="application/xhtml+xml" />
|
47
|
+
<item id="chap1" href="chap1.xhtml" media-type="application/xhtml+xml" />
|
48
|
+
<item id="css" href="style/default.css" media-type="text/css" />
|
49
|
+
<item id="object" href="img/test.png" media-type="image/png" />
|
50
|
+
<item id="object2" href="resource/image.jpg" media-type="image/jpg" />
|
51
|
+
<item id="h" href="h_foo.html" media-type="application/xhtml+xml" properties="scripted" />
|
52
|
+
<item id="v" href="v_foo.html" media-type="application/xhtml+xml" properties="scripted" />
|
53
|
+
</manifest>
|
54
|
+
|
55
|
+
<spine toc="ncx" page-progression-direction="ltr">
|
56
|
+
<itemref idref="cover" linear="no" />
|
57
|
+
<itemref idref="toc" linear="yes" />
|
58
|
+
<itemref idref="chap1" linear="yes" />
|
59
|
+
<itemref idref="nav" linear="no" />
|
60
|
+
</spine>
|
61
|
+
|
62
|
+
<bindings>
|
63
|
+
<mediaType handler="h" media-type="application/x-foreign-type" />
|
64
|
+
<mediaType handler="v" media-type="application/x-other-foreign-type" />
|
65
|
+
</bindings>
|
66
|
+
|
67
|
+
</package>
|
data/spec/gepub_spec.rb
CHANGED
@@ -57,6 +57,13 @@ describe GEPUB::Book do
|
|
57
57
|
'c2')
|
58
58
|
item2.toc_text 'test chapter'
|
59
59
|
|
60
|
+
item3 = @book.add_item('text/handler.xhtml',
|
61
|
+
StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml"><head><title>c2</title><script>alert("foo");</script></head><body><p>this is scripted item</p></body></html>')
|
62
|
+
)
|
63
|
+
item3.add_property('scripted')
|
64
|
+
item3.is_handler_of('application/x-some-media-type')
|
65
|
+
@item3_id = item3.id
|
66
|
+
|
60
67
|
nav_string = <<EOF
|
61
68
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
|
62
69
|
<head></head>
|
@@ -141,6 +148,13 @@ EOF
|
|
141
148
|
spine.at_xpath('xmlns:itemref')['idref'].should == 'c1'
|
142
149
|
end
|
143
150
|
|
151
|
+
it "should have correct bindings in opf" do
|
152
|
+
opf = Nokogiri::XML.parse(@book.opf_xml).root
|
153
|
+
bindings = opf.at_xpath('xmlns:bindings')
|
154
|
+
bindings.at_xpath('xmlns:mediaType')['handler'].should == @item3_id
|
155
|
+
bindings.at_xpath('xmlns:mediaType')['media-type'].should == 'application/x-some-media-type'
|
156
|
+
end
|
157
|
+
|
144
158
|
it "should have correct cover image id" do
|
145
159
|
item = @book.add_item("img/img.jpg").cover_image
|
146
160
|
|
data/spec/metadata_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
+
p# -*- coding: utf-8 -*-
|
2
3
|
require File.dirname(__FILE__) + '/spec_helper.rb'
|
3
4
|
require 'rubygems'
|
4
5
|
require 'nokogiri'
|
@@ -25,6 +26,11 @@ describe GEPUB::Metadata do
|
|
25
26
|
@metadata.title.to_s.should == 'TheTitle'
|
26
27
|
end
|
27
28
|
|
29
|
+
it 'should parse main title with not first display-seq' do
|
30
|
+
metadata = GEPUB::Package.parse_opf(File.open(File.dirname(__FILE__) + '/fixtures/testdata/test2.opf'), '/package.opf').instance_eval{ @metadata }
|
31
|
+
metadata.title.to_s.should == 'TheTitle'
|
32
|
+
end
|
33
|
+
|
28
34
|
it 'should parse title-type' do
|
29
35
|
@metadata.title_list[0].refiner_list('title-type').size.should == 1
|
30
36
|
@metadata.title_list[0].refiner_list('title-type')[0].content.should == 'main'
|
data/spec/spine_spec.rb
CHANGED
@@ -36,6 +36,20 @@ describe GEPUB::Spine do
|
|
36
36
|
xml.at_xpath('//xmlns:spine')['toc'].should == 'ncx'
|
37
37
|
xml.xpath("//xmlns:itemref[@idref='the_id' and @linear='no']").size.should == 1
|
38
38
|
end
|
39
|
+
it 'should generate xml with property' do
|
40
|
+
spine = GEPUB::Spine.new
|
41
|
+
spine.toc = 'ncx'
|
42
|
+
spine.push(GEPUB::Item.new('the_id', 'OEBPS/foo.xhtml')).page_spread_right
|
43
|
+
builder = Nokogiri::XML::Builder.new { |xml|
|
44
|
+
xml.package('xmlns' => "http://www.idpf.org/2007/opf",'version' => "3.0",'unique-identifier' => "pub-id",'xml:lang' => "ja") {
|
45
|
+
spine.to_xml(xml)
|
46
|
+
}
|
47
|
+
}
|
48
|
+
xml = Nokogiri::XML::Document.parse(builder.to_xml)
|
49
|
+
xml.at_xpath('//xmlns:spine')['toc'].should == 'ncx'
|
50
|
+
xml.xpath("//xmlns:itemref[@idref='the_id' and @properties='page-spread-right']").size.should == 1
|
51
|
+
end
|
52
|
+
|
39
53
|
end
|
40
54
|
|
41
55
|
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
|
+
version: 0.6.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70221453301020 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '2'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70221453301020
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: nokogiri
|
27
|
-
requirement: &
|
27
|
+
requirement: &70221453300080 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 1.5.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70221453300080
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rubyzip
|
38
|
-
requirement: &
|
38
|
+
requirement: &70221453299060 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - =
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 0.9.6.1
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70221453299060
|
47
47
|
description: gepub is a generic EPUB parser/generator. Generates and parse EPUB2 and
|
48
48
|
EPUB3
|
49
49
|
email:
|
@@ -57,6 +57,7 @@ files:
|
|
57
57
|
- .gitignore
|
58
58
|
- .travis.yml
|
59
59
|
- Gemfile
|
60
|
+
- LICENSE.txt
|
60
61
|
- README.md
|
61
62
|
- Rakefile
|
62
63
|
- bin/genepub
|
@@ -66,6 +67,7 @@ files:
|
|
66
67
|
- examples/image1.jpg
|
67
68
|
- gepub.gemspec
|
68
69
|
- lib/gepub.rb
|
70
|
+
- lib/gepub/bindings.rb
|
69
71
|
- lib/gepub/book.rb
|
70
72
|
- lib/gepub/builder.rb
|
71
73
|
- lib/gepub/builder_mixin.rb
|
@@ -80,6 +82,7 @@ files:
|
|
80
82
|
- lib/gepub/spine.rb
|
81
83
|
- lib/gepub/version.rb
|
82
84
|
- lib/gepub/xml_util.rb
|
85
|
+
- spec/bindings_spec.rb
|
83
86
|
- spec/builder_spec.rb
|
84
87
|
- spec/example_spec.rb
|
85
88
|
- spec/fixtures/builder/img/cover.jpg
|
@@ -102,6 +105,8 @@ files:
|
|
102
105
|
- spec/fixtures/testdata/1.html
|
103
106
|
- spec/fixtures/testdata/image1.jpg
|
104
107
|
- spec/fixtures/testdata/test.opf
|
108
|
+
- spec/fixtures/testdata/test2.opf
|
109
|
+
- spec/fixtures/testdata/test_with_bindings.opf
|
105
110
|
- spec/gepub_spec.rb
|
106
111
|
- spec/manifest_spec.rb
|
107
112
|
- spec/metadata_spec.rb
|
@@ -133,6 +138,7 @@ signing_key:
|
|
133
138
|
specification_version: 3
|
134
139
|
summary: a generic EPUB library for Ruby.
|
135
140
|
test_files:
|
141
|
+
- spec/bindings_spec.rb
|
136
142
|
- spec/builder_spec.rb
|
137
143
|
- spec/example_spec.rb
|
138
144
|
- spec/fixtures/builder/img/cover.jpg
|
@@ -155,6 +161,8 @@ test_files:
|
|
155
161
|
- spec/fixtures/testdata/1.html
|
156
162
|
- spec/fixtures/testdata/image1.jpg
|
157
163
|
- spec/fixtures/testdata/test.opf
|
164
|
+
- spec/fixtures/testdata/test2.opf
|
165
|
+
- spec/fixtures/testdata/test_with_bindings.opf
|
158
166
|
- spec/gepub_spec.rb
|
159
167
|
- spec/manifest_spec.rb
|
160
168
|
- spec/metadata_spec.rb
|