gepub 0.6.5.2 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|
+
[](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
|