gepub 0.6.2 → 0.6.3
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/.gitignore +1 -1
- data/README.md +37 -4
- data/examples/builder_example.rb +32 -0
- data/gepub.gemspec +2 -2
- data/lib/gepub/book.rb +11 -6
- data/lib/gepub/builder.rb +127 -0
- data/lib/gepub/builder_mixin.rb +29 -0
- data/lib/gepub/item.rb +10 -1
- data/lib/gepub/manifest.rb +5 -0
- data/lib/gepub/meta.rb +9 -1
- data/lib/gepub/metadata.rb +8 -1
- data/lib/gepub/package.rb +17 -7
- data/lib/gepub/resource_builder.rb +147 -0
- data/lib/gepub/version.rb +1 -1
- data/lib/gepub.rb +4 -0
- data/spec/builder_spec.rb +356 -0
- data/spec/example_spec.rb +36 -4
- data/spec/fixtures/builder/img/cover.jpg +0 -0
- data/spec/fixtures/builder/resources/noise.m4 +0 -0
- data/spec/fixtures/builder/resources/noise_2.m4a +0 -0
- data/spec/fixtures/builder/text/cover.xhtml +11 -0
- data/spec/fixtures/builder/text/memo.txt +1 -0
- data/spec/fixtures/builder/text/nav.xhtml +12 -0
- metadata +29 -11
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -9,15 +9,48 @@ a generic EPUB parser/generator library.
|
|
9
9
|
## FEATURES/PROBLEMS:
|
10
10
|
|
11
11
|
* GEPUB::Book provides functionality to create EPUB file, and parsing EPUB file
|
12
|
-
*
|
13
|
-
|
14
|
-
* Will provide easy to generate EPUB class, like Nokogiri::XML::Generator.
|
12
|
+
* Handle every metadata in EPUB2/EPUB3.
|
13
|
+
* Soon, I will provide easy to generate EPUB class, like Nokogiri::XML::Generator.
|
15
14
|
|
16
15
|
* See [issues](https://github.com/skoji/gepub/issues/) for known problems.
|
17
16
|
|
18
17
|
## SYNOPSIS:
|
19
18
|
|
20
|
-
|
19
|
+
### Builder Example
|
20
|
+
|
21
|
+
require 'rubygem'
|
22
|
+
require 'gepub'
|
23
|
+
workdir = 'epub/example/'
|
24
|
+
builder = GEPUB::Builder.new {
|
25
|
+
unique_identifier 'http:/example.jp/bookid_in_url', 'BookID', 'URL'
|
26
|
+
language 'en'
|
27
|
+
|
28
|
+
title 'GEPUB Sample Book'
|
29
|
+
subtitle 'This book is just a sample'
|
30
|
+
alt 'ja' => 'これはあくまでサンプルです'
|
31
|
+
|
32
|
+
creator 'KOJIMA Satoshi'
|
33
|
+
alt 'ja' => '小嶋智'
|
34
|
+
|
35
|
+
contributors 'Denshobu', 'Asagaya Densho', 'Shonan Densho Teidan', 'eMagazine Torutaru'
|
36
|
+
|
37
|
+
date '2012-02-29T00:00:00Z'
|
38
|
+
|
39
|
+
resources(:workdir => workdir) {
|
40
|
+
cover_image 'img/image1.jpg' => 'image1.jpg'
|
41
|
+
ordered {
|
42
|
+
file 'text/chap1.xhtml'
|
43
|
+
heading 'Chapter 1'
|
44
|
+
file 'text/chap1-1.xhtml'
|
45
|
+
file 'text/chap2.html'
|
46
|
+
heading 'Chapter 2'
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
epubname = File.join(File.dirname(__FILE__), 'example_test_with_builder.epub')
|
51
|
+
builder.generate_epub(epubname)
|
52
|
+
|
53
|
+
[examples](https://github.com/skoji/gepub/tree/master/examples/)
|
21
54
|
|
22
55
|
## INSTALL:
|
23
56
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygem'
|
3
|
+
require 'gepub'
|
4
|
+
workdir = 'epub/example/'
|
5
|
+
builder = GEPUB::Builder.new {
|
6
|
+
unique_identifier 'http:/example.jp/bookid_in_url', 'BookID', 'URL'
|
7
|
+
language 'en'
|
8
|
+
|
9
|
+
title 'GEPUB Sample Book'
|
10
|
+
subtitle 'This book is just a sample'
|
11
|
+
alt 'ja' => 'これはあくまでサンプルです'
|
12
|
+
|
13
|
+
creator 'KOJIMA Satoshi'
|
14
|
+
alt 'ja' => '小嶋智'
|
15
|
+
|
16
|
+
contributors 'Denshobu', 'Asagaya Densho', 'Shonan Densho Teidan', 'eMagazine Torutaru'
|
17
|
+
|
18
|
+
date '2012-02-29T00:00:00Z'
|
19
|
+
|
20
|
+
resources(:workdir => workdir) {
|
21
|
+
cover_image 'img/image1.jpg' => 'image1.jpg'
|
22
|
+
ordered {
|
23
|
+
file 'text/chap1.xhtml'
|
24
|
+
heading 'Chapter 1'
|
25
|
+
file 'text/chap1-1.xhtml'
|
26
|
+
file 'text/chap2.html'
|
27
|
+
heading 'Chapter 2'
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
epubname = File.join(File.dirname(__FILE__), 'example_test_with_builder.epub')
|
32
|
+
builder.generate_epub(epubname)
|
data/gepub.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ["KOJIMA Satoshi"]
|
9
9
|
s.email = ["skoji@mac.com"]
|
10
10
|
s.homepage = %q{http://github.com/skoji/gepub}
|
11
|
-
s.summary = %q{a generic EPUB
|
12
|
-
s.description = %q{gepub is a EPUB parser/generator. Generates
|
11
|
+
s.summary = %q{a generic EPUB library for Ruby.}
|
12
|
+
s.description = %q{gepub is a generic EPUB parser/generator. Generates and parse EPUB2 and EPUB3}
|
13
13
|
|
14
14
|
s.rubyforge_project = "gepub"
|
15
15
|
|
data/lib/gepub/book.rb
CHANGED
@@ -4,7 +4,6 @@ require 'nokogiri'
|
|
4
4
|
require 'zip/zip'
|
5
5
|
require 'fileutils'
|
6
6
|
|
7
|
-
|
8
7
|
module GEPUB
|
9
8
|
class Book
|
10
9
|
MIMETYPE='mimetype'
|
@@ -81,20 +80,25 @@ module GEPUB
|
|
81
80
|
@toc.push({ :item => item, :text => text, :id => id})
|
82
81
|
end
|
83
82
|
|
84
|
-
def add_item(href,
|
85
|
-
item = @package.add_item(href,
|
83
|
+
def add_item(href, io_or_filename = nil, id = nil, attributes = {})
|
84
|
+
item = @package.add_item(href,io_or_filename,id,attributes)
|
86
85
|
toc = @toc
|
87
86
|
(class << item;self;end).send(:define_method, :toc_text,
|
88
87
|
Proc.new { |text|
|
89
88
|
toc.push(:item => item, :text => text, :id => nil)
|
90
89
|
item
|
91
90
|
})
|
91
|
+
(class << item;self;end).send(:define_method, :toc_text_with_id,
|
92
|
+
Proc.new { |text, id|
|
93
|
+
toc.push(:item => item, :text => text, :id => id)
|
94
|
+
item
|
95
|
+
})
|
92
96
|
yield item if block_given?
|
93
97
|
item
|
94
98
|
end
|
95
99
|
|
96
|
-
def add_ordered_item(href,
|
97
|
-
item = @package.add_ordered_item(href,
|
100
|
+
def add_ordered_item(href, io_or_filename = nil, id = nil, attributes = {})
|
101
|
+
item = @package.add_ordered_item(href,io_or_filename,id,attributes)
|
98
102
|
toc = @toc
|
99
103
|
(class << item;self;end).send(:define_method, :toc_text,
|
100
104
|
Proc.new { |text|
|
@@ -182,8 +186,9 @@ EOF
|
|
182
186
|
doc.ol {
|
183
187
|
@toc.each {
|
184
188
|
|x|
|
189
|
+
id = x[:id].nil? ? "" : "##{x[:id]}"
|
185
190
|
doc.li {
|
186
|
-
doc.a({'href' => x[:item].href} ,x[:text])
|
191
|
+
doc.a({'href' => x[:item].href + id} ,x[:text])
|
187
192
|
}
|
188
193
|
}
|
189
194
|
}
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module GEPUB
|
2
|
+
class Builder
|
3
|
+
include BuilderMixin
|
4
|
+
class MetaItem
|
5
|
+
def initialize(item)
|
6
|
+
@item = item
|
7
|
+
end
|
8
|
+
|
9
|
+
def apply_one_to_multi
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
def alt(alternates = {})
|
14
|
+
@item.add_alternates(alternates)
|
15
|
+
end
|
16
|
+
|
17
|
+
def file_as(name)
|
18
|
+
@item.set_file_as(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def seq(num)
|
22
|
+
@item.set_display_seq(num)
|
23
|
+
end
|
24
|
+
|
25
|
+
def group_position(num)
|
26
|
+
@item.set_group_position(num)
|
27
|
+
end
|
28
|
+
|
29
|
+
def id(val)
|
30
|
+
@item['id'] = val
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(attributes = {}, &block)
|
35
|
+
@last_defined_item = nil
|
36
|
+
@book = Book.new
|
37
|
+
instance_eval &block
|
38
|
+
# TODO check @book's consistency
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
# define base methods.
|
43
|
+
GEPUB::Metadata::CONTENT_NODE_LIST.each {
|
44
|
+
|name|
|
45
|
+
define_method(name) { |val| @last_defined_item = MetaItem.new(@book.send("add_#{name}".to_sym, val, nil)) }
|
46
|
+
}
|
47
|
+
|
48
|
+
GEPUB::TITLE_TYPE::TYPES.each {
|
49
|
+
|type|
|
50
|
+
case type
|
51
|
+
when 'main'
|
52
|
+
methodname = 'title'
|
53
|
+
when 'short'
|
54
|
+
methodname = 'short_title'
|
55
|
+
when 'expanded'
|
56
|
+
methodname = 'expandend_title'
|
57
|
+
else
|
58
|
+
methodname = type
|
59
|
+
end
|
60
|
+
define_method(methodname) { |val| @last_defined_item = MetaItem.new(@book.add_title(val, nil, type)) }
|
61
|
+
}
|
62
|
+
|
63
|
+
def collection(val, count = 1)
|
64
|
+
@last_defined_item =
|
65
|
+
MetaItem.new(@book.add_title(val, nil, GEPUB::TITLE_TYPE::COLLECTION).set_group_position(count.to_s))
|
66
|
+
end
|
67
|
+
|
68
|
+
def creator(val, role = 'aut')
|
69
|
+
MetaItem.new(@book.add_creator(val, nil, role))
|
70
|
+
end
|
71
|
+
|
72
|
+
def creators(*vals)
|
73
|
+
@last_defined_item = vals.map {
|
74
|
+
|v|
|
75
|
+
name = v
|
76
|
+
role = ''
|
77
|
+
name,role = v[0], v[1] if Array === name
|
78
|
+
MetaItem.new(@book.add_creator(name, nil, role))
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
def contributors(*vals)
|
83
|
+
@last_defined_item = vals.map {
|
84
|
+
|v|
|
85
|
+
name = v
|
86
|
+
role = nil
|
87
|
+
name,role = v[0], v[1] if Array === name
|
88
|
+
MetaItem.new(@book.add_contributor(name, nil, role))
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
def publishers(*vals)
|
93
|
+
@last_defined_item = vals.map {
|
94
|
+
|v|
|
95
|
+
MetaItem.new(@book.add_publisher(v, nil))
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
def unique_identifier(val, id = 'BookID', scheme = 'nil')
|
100
|
+
@last_defined_item = MetaItem.new(@book.set_main_id(val, id, scheme))
|
101
|
+
end
|
102
|
+
|
103
|
+
def alts(alt_vals = {})
|
104
|
+
raise "can't specify alts on single item" if ! Array === @last_defined_item
|
105
|
+
@last_defined_item.each_with_index {
|
106
|
+
|item, index|
|
107
|
+
item.alt Hash[*(alt_vals.map{|k,v| [k,v[index]]}.flatten)]
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
def contributor(val, role = nil)
|
112
|
+
MetaItem.new(@book.add_contributor(val, nil, role))
|
113
|
+
end
|
114
|
+
|
115
|
+
def generate_epub(path_to_epub)
|
116
|
+
@book.generate_epub(path_to_epub)
|
117
|
+
end
|
118
|
+
|
119
|
+
def resources(attributes = {}, &block)
|
120
|
+
ResourceBuilder.new(@book, attributes, &block)
|
121
|
+
end
|
122
|
+
|
123
|
+
def generate_epub_stream
|
124
|
+
# TODO should implement
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module GEPUB
|
2
|
+
module BuilderMixin
|
3
|
+
def method_missing(name, *args)
|
4
|
+
if Array === @last_defined_item &&
|
5
|
+
@last_defined_item.size > 0 &&
|
6
|
+
@last_defined_item[0].respond_to?(name.to_sym)
|
7
|
+
|
8
|
+
if !(@last_defined_item[0].apply_one_to_multi ||
|
9
|
+
@last_defined_item.size != 1) &&
|
10
|
+
@last_defined_item.size != args.size
|
11
|
+
warn "appling #{args} to #{@last_defined_item}: length differs."
|
12
|
+
end
|
13
|
+
|
14
|
+
@last_defined_item.each_with_index {
|
15
|
+
|item, i|
|
16
|
+
if item.apply_one_to_multi && args.size == 1
|
17
|
+
item.send(name, args[0])
|
18
|
+
elsif !args[i].nil?
|
19
|
+
item.send(name, args[i])
|
20
|
+
end
|
21
|
+
}
|
22
|
+
elsif @last_defined_item.respond_to?(name.to_sym)
|
23
|
+
@last_defined_item.send(name, *args)
|
24
|
+
else
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/gepub/item.rb
CHANGED
@@ -49,10 +49,19 @@ module GEPUB
|
|
49
49
|
add_property('cover-image')
|
50
50
|
end
|
51
51
|
|
52
|
+
def nav
|
53
|
+
add_property('nav')
|
54
|
+
end
|
55
|
+
|
52
56
|
def add_raw_content(data)
|
53
57
|
@content = data
|
54
58
|
end
|
55
|
-
|
59
|
+
|
60
|
+
def add_content(io_or_filename)
|
61
|
+
io = io_or_filename
|
62
|
+
if io_or_filename.class == String
|
63
|
+
io = File.new(io_or_filename)
|
64
|
+
end
|
56
65
|
io.binmode
|
57
66
|
@content = io.read
|
58
67
|
self
|
data/lib/gepub/manifest.rb
CHANGED
@@ -44,11 +44,16 @@ module GEPUB
|
|
44
44
|
@items.dup
|
45
45
|
end
|
46
46
|
|
47
|
+
def items
|
48
|
+
@items.dup
|
49
|
+
end
|
50
|
+
|
47
51
|
def item_by_href(href)
|
48
52
|
@items_by_href[href]
|
49
53
|
end
|
50
54
|
|
51
55
|
def add_item(id,href,media_type, attributes = {})
|
56
|
+
id ||= @id_pool.generate_key(:prefix=>'item_'+ File.basename(href,'.*'), :without_count => true)
|
52
57
|
@items[id] = item = Item.new(id,href,media_type,self, attributes)
|
53
58
|
@items_by_href[href] = item
|
54
59
|
item
|
data/lib/gepub/meta.rb
CHANGED
@@ -61,7 +61,7 @@ module GEPUB
|
|
61
61
|
self
|
62
62
|
end
|
63
63
|
|
64
|
-
['title-type', 'identifier-type', 'display-seq', 'file-as', 'group-position'].each {
|
64
|
+
['title-type', 'identifier-type', 'display-seq', 'file-as', 'group-position', 'role'].each {
|
65
65
|
|name|
|
66
66
|
methodbase = name.sub('-','_')
|
67
67
|
define_method(methodbase + '=') { |val| refine(name, val); }
|
@@ -78,6 +78,14 @@ module GEPUB
|
|
78
78
|
self
|
79
79
|
end
|
80
80
|
|
81
|
+
def list_alternates
|
82
|
+
list = refiner_list('alternate-script').map {
|
83
|
+
|refiner|
|
84
|
+
[ refiner['xml:lang'], refiner.content ]
|
85
|
+
}
|
86
|
+
Hash[*list.flatten]
|
87
|
+
end
|
88
|
+
|
81
89
|
def to_xml(builder, id_pool, ns = nil, additional_attr = {}, opf_version = '3.0')
|
82
90
|
additional_attr ||= {}
|
83
91
|
if @refiners.size > 0 && opf_version.to_f >= 3.0
|
data/lib/gepub/metadata.rb
CHANGED
@@ -5,7 +5,7 @@ require 'time'
|
|
5
5
|
module GEPUB
|
6
6
|
# metadata constants
|
7
7
|
module TITLE_TYPE
|
8
|
-
['main','subtitle', 'short', 'collection', 'edition','expanded'].each {
|
8
|
+
TYPES = ['main','subtitle', 'short', 'collection', 'edition','expanded'].each {
|
9
9
|
|type|
|
10
10
|
const_set(type.upcase, type)
|
11
11
|
}
|
@@ -145,6 +145,13 @@ module GEPUB
|
|
145
145
|
yield meta if block_given?
|
146
146
|
meta
|
147
147
|
end
|
148
|
+
|
149
|
+
def set_title(content, id = nil, title_type = nil)
|
150
|
+
title_clear
|
151
|
+
add_title(content, id, title_type)
|
152
|
+
yield meta if block_given?
|
153
|
+
meta
|
154
|
+
end
|
148
155
|
|
149
156
|
def add_person(name, content, id = nil, role = 'aut')
|
150
157
|
meta = add_metadata(name, content, id).refine('role', role)
|
data/lib/gepub/package.rb
CHANGED
@@ -29,7 +29,7 @@ module GEPUB
|
|
29
29
|
if param[:without_count]
|
30
30
|
k = prefix + suffix
|
31
31
|
count -= 1
|
32
|
-
param
|
32
|
+
param.delete(:without_count)
|
33
33
|
else
|
34
34
|
k = prefix + count.to_s + suffix
|
35
35
|
end
|
@@ -122,10 +122,9 @@ module GEPUB
|
|
122
122
|
item.add_properties 'cover-image'
|
123
123
|
end
|
124
124
|
|
125
|
-
def add_item(href,
|
126
|
-
id ||= @id_pool.generate_key(:prefix=>'item', :suffix=>'_'+ File.basename(href,'.*'), :without_count => true)
|
125
|
+
def add_item(href, io_or_filename = nil, id = nil, attributes = {})
|
127
126
|
item = @manifest.add_item(id, href, nil, attributes)
|
128
|
-
item.add_content(
|
127
|
+
item.add_content(io_or_filename) unless io_or_filename.nil?
|
129
128
|
@spine.push(item) if @ordered
|
130
129
|
yield item if block_given?
|
131
130
|
item
|
@@ -138,16 +137,27 @@ module GEPUB
|
|
138
137
|
@ordered = nil
|
139
138
|
end
|
140
139
|
|
141
|
-
def add_ordered_item(href,
|
140
|
+
def add_ordered_item(href, io_or_filename = nil, id = nil, attributes = {})
|
142
141
|
raise 'do not call add_ordered_item within ordered block.' if @ordered
|
143
|
-
item = add_item(href,
|
142
|
+
item = add_item(href, io_or_filename, id, attributes)
|
144
143
|
@spine.push(item)
|
145
144
|
|
146
145
|
item
|
147
146
|
end
|
148
147
|
|
148
|
+
def spine_items
|
149
|
+
spine.itemref_list.map {
|
150
|
+
|itemref|
|
151
|
+
@manifest.item_list[itemref.idref]
|
152
|
+
}
|
153
|
+
end
|
149
154
|
|
150
|
-
def
|
155
|
+
def items
|
156
|
+
@manifest.item_list
|
157
|
+
end
|
158
|
+
|
159
|
+
def method_missing(name, *args)
|
160
|
+
return @manifest.send(name.to_sym, *args) if [:item_by_href].member? name
|
151
161
|
Metadata::CONTENT_NODE_LIST.each {
|
152
162
|
|x|
|
153
163
|
case name.to_s
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module GEPUB
|
2
|
+
class ResourceBuilder
|
3
|
+
include BuilderMixin
|
4
|
+
class ResourceItem
|
5
|
+
attr_reader :item
|
6
|
+
def initialize(item)
|
7
|
+
@item = item
|
8
|
+
end
|
9
|
+
|
10
|
+
def apply_one_to_multi
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def media_type(val)
|
15
|
+
@item.set_media_type(val)
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(name, *args)
|
19
|
+
@item.send(name.to_sym, *args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(book, attributes = {}, &block)
|
24
|
+
@last_defined_item = nil
|
25
|
+
@book = book
|
26
|
+
@file_postprocess = {}
|
27
|
+
@file_preprocess = {}
|
28
|
+
@files_postprocess = {}
|
29
|
+
@files_preprocess = {}
|
30
|
+
current_wd = Dir.getwd
|
31
|
+
Dir.chdir(attributes[:workdir]) unless attributes[:workdir].nil?
|
32
|
+
instance_eval &block
|
33
|
+
Dir.chdir current_wd
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def ordered(&block)
|
38
|
+
@book.ordered {
|
39
|
+
instance_eval &block
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def file(val)
|
44
|
+
raise "can't specify multiple files on file keyword" if Hash === val && val.length > 1
|
45
|
+
|
46
|
+
@file_preprocess.each {
|
47
|
+
|k,p|
|
48
|
+
p.call
|
49
|
+
}
|
50
|
+
@last_defined_item = ResourceItem.new(create_one_file(val))
|
51
|
+
@file_postprocess.each {
|
52
|
+
|k,p|
|
53
|
+
p.call
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def files(*arg)
|
58
|
+
arg = arg[0] if arg.size == 1 && Hash === arg[0]
|
59
|
+
@files_preprocess.each {
|
60
|
+
|k,p|
|
61
|
+
p.call
|
62
|
+
}
|
63
|
+
@last_defined_item = arg.map {
|
64
|
+
|val|
|
65
|
+
ResourceItem.new(create_one_file(val))
|
66
|
+
}
|
67
|
+
@files_postprocess.each {
|
68
|
+
|k,p|
|
69
|
+
p.call
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def cover_image(val)
|
74
|
+
file(val)
|
75
|
+
@last_defined_item.cover_image
|
76
|
+
end
|
77
|
+
|
78
|
+
def nav(val)
|
79
|
+
file(val)
|
80
|
+
@last_defined_item.nav
|
81
|
+
end
|
82
|
+
|
83
|
+
def heading(text, id = nil)
|
84
|
+
@last_defined_item.toc_text_with_id(text, id)
|
85
|
+
end
|
86
|
+
|
87
|
+
def with_media_type(*type)
|
88
|
+
raise 'with_media_type needs block.' unless block_given?
|
89
|
+
@file_postprocess['with_media_type'] = Proc.new { media_type(*type) }
|
90
|
+
@files_postprocess['with_media_type'] = Proc.new { media_type(*type) }
|
91
|
+
yield
|
92
|
+
@file_postprocess.delete('with_media_type')
|
93
|
+
@files_postprocess.delete('with_media_type')
|
94
|
+
end
|
95
|
+
|
96
|
+
def fallback_group
|
97
|
+
raise 'fallback_group needs block.' unless block_given?
|
98
|
+
count = 0
|
99
|
+
before = nil
|
100
|
+
|
101
|
+
@files_preprocess['fallback_group'] = Proc.new { raise "can't use files within fallback_group" }
|
102
|
+
|
103
|
+
@file_preprocess['fallback_group'] = Proc.new {
|
104
|
+
before = @last_defined_item
|
105
|
+
}
|
106
|
+
|
107
|
+
@file_postprocess['fallback_group'] = Proc.new {
|
108
|
+
if count > 0
|
109
|
+
before.item.set_fallback(@last_defined_item.item.id)
|
110
|
+
end
|
111
|
+
count += 1
|
112
|
+
}
|
113
|
+
yield
|
114
|
+
@files_preprocess.delete('fallback_group')
|
115
|
+
@file_postprocess.delete('fallback_group')
|
116
|
+
@file_preprocess.delete('fallback_group')
|
117
|
+
end
|
118
|
+
|
119
|
+
def fallback_chain_files(*arg)
|
120
|
+
files(*arg)
|
121
|
+
@last_defined_item.inject(nil) {
|
122
|
+
|item1, item2|
|
123
|
+
if !item1.nil?
|
124
|
+
item1.item.set_fallback(item2.item.id)
|
125
|
+
end
|
126
|
+
item2
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
def create_one_file(val)
|
133
|
+
name = val
|
134
|
+
io = val
|
135
|
+
if Hash === val
|
136
|
+
name = val.first[0]
|
137
|
+
io = val.first[1]
|
138
|
+
end
|
139
|
+
if Array === val
|
140
|
+
name = val[0]
|
141
|
+
io = val[1]
|
142
|
+
end
|
143
|
+
@book.add_item(name, io)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
data/lib/gepub/version.rb
CHANGED
data/lib/gepub.rb
CHANGED
@@ -0,0 +1,356 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
3
|
+
require 'rubygems'
|
4
|
+
describe GEPUB::Builder do
|
5
|
+
context 'metadata generating' do
|
6
|
+
it 'should generate language' do
|
7
|
+
builder = GEPUB::Builder.new {
|
8
|
+
language 'ja'
|
9
|
+
}
|
10
|
+
builder.instance_eval { @book.language }.to_s.should == 'ja'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should generate uid' do
|
14
|
+
builder = GEPUB::Builder.new {
|
15
|
+
unique_identifier 'http://example.jp/as_url', 'BookID', 'url'
|
16
|
+
}
|
17
|
+
builder.instance_eval { @book.identifier }.to_s.should == 'http://example.jp/as_url'
|
18
|
+
builder.instance_eval { @book.identifier_list[0]['id']}.should == 'BookID'
|
19
|
+
builder.instance_eval { @book.identifier_list[0].identifier_type}.to_s.should == 'url'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should generate title' do
|
23
|
+
builder = GEPUB::Builder.new {
|
24
|
+
title 'The Book Title'
|
25
|
+
}
|
26
|
+
builder.instance_eval { @book.title }.to_s.should == 'The Book Title'
|
27
|
+
builder.instance_eval { @book.title.title_type }.to_s.should == 'main'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should generate title with type ' do
|
31
|
+
builder = GEPUB::Builder.new {
|
32
|
+
subtitle 'the sub-title'
|
33
|
+
}
|
34
|
+
builder.instance_eval { @book.title }.to_s.should == 'the sub-title'
|
35
|
+
builder.instance_eval { @book.title.title_type }.to_s.should == 'subtitle'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should generate collection title ' do
|
39
|
+
builder = GEPUB::Builder.new {
|
40
|
+
collection 'the collection', 3
|
41
|
+
}
|
42
|
+
builder.instance_eval { @book.title }.to_s.should == 'the collection'
|
43
|
+
builder.instance_eval { @book.title.title_type }.to_s.should == 'collection'
|
44
|
+
builder.instance_eval { @book.title.group_position }.to_s.should == '3'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should refine title: alternates ' do
|
48
|
+
builder = GEPUB::Builder.new {
|
49
|
+
collection 'the collection', 3
|
50
|
+
alt 'ja' => 'シリーズ'
|
51
|
+
}
|
52
|
+
builder.instance_eval { @book.title }.to_s.should == 'the collection'
|
53
|
+
builder.instance_eval { @book.title.title_type }.to_s.should == 'collection'
|
54
|
+
builder.instance_eval { @book.title.list_alternates['ja'] }.to_s.should == 'シリーズ'
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should refine title: file_as ' do
|
58
|
+
builder = GEPUB::Builder.new {
|
59
|
+
title 'メインタイトル'
|
60
|
+
file_as 'main title'
|
61
|
+
}
|
62
|
+
builder.instance_eval { @book.title }.to_s.should == 'メインタイトル'
|
63
|
+
builder.instance_eval { @book.title.title_type }.to_s.should == 'main'
|
64
|
+
builder.instance_eval { @book.title.file_as }.to_s.should == 'main title'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should refine title: alt and file_as ' do
|
68
|
+
builder = GEPUB::Builder.new {
|
69
|
+
title 'メインタイトル'
|
70
|
+
file_as 'main title'
|
71
|
+
alt 'en' => 'The Main Title'
|
72
|
+
}
|
73
|
+
builder.instance_eval { @book.title }.to_s.should == 'メインタイトル'
|
74
|
+
builder.instance_eval { @book.title.title_type }.to_s.should == 'main'
|
75
|
+
builder.instance_eval { @book.title.file_as }.to_s.should == 'main title'
|
76
|
+
builder.instance_eval { @book.title.list_alternates['en'] }.to_s.should == 'The Main Title'
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should generate creator ' do
|
80
|
+
builder = GEPUB::Builder.new {
|
81
|
+
creator 'The Main Author'
|
82
|
+
}
|
83
|
+
builder.instance_eval { @book.creator }.to_s.should == 'The Main Author'
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should generate creator with role' do
|
87
|
+
builder = GEPUB::Builder.new {
|
88
|
+
creator 'The Illustrator', 'ill'
|
89
|
+
}
|
90
|
+
builder.instance_eval { @book.creator }.to_s.should == 'The Illustrator'
|
91
|
+
builder.instance_eval { @book.creator.role}.to_s.should == 'ill'
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should generate contributor ' do
|
95
|
+
builder = GEPUB::Builder.new {
|
96
|
+
contributor 'contributor', 'edt'
|
97
|
+
}
|
98
|
+
builder.instance_eval { @book.contributor }.to_s.should == 'contributor'
|
99
|
+
builder.instance_eval { @book.contributor.role}.to_s.should == 'edt'
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should generate multiple creators ' do
|
103
|
+
builder = GEPUB::Builder.new {
|
104
|
+
creators 'First Author', 'Second Author', ['Third Person', 'edt']
|
105
|
+
}
|
106
|
+
builder.instance_eval { @book.creator_list }.size.should == 3
|
107
|
+
builder.instance_eval { @book.creator_list[0] }.to_s.should == 'First Author'
|
108
|
+
builder.instance_eval { @book.creator_list[1] }.to_s.should == 'Second Author'
|
109
|
+
builder.instance_eval { @book.creator_list[2] }.to_s.should == 'Third Person'
|
110
|
+
builder.instance_eval { @book.creator_list[2].role }.to_s.should == 'edt'
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should generate multiple creators, and then add file_as at once ' do
|
114
|
+
builder = GEPUB::Builder.new {
|
115
|
+
creators 'First Author', 'Second Author', ['Third Person', 'edt']
|
116
|
+
file_as '1st', '2nd', '3rd'
|
117
|
+
}
|
118
|
+
builder.instance_eval { @book.creator_list }.size.should == 3
|
119
|
+
builder.instance_eval { @book.creator_list[0] }.to_s.should == 'First Author'
|
120
|
+
builder.instance_eval { @book.creator_list[0].file_as }.to_s.should == '1st'
|
121
|
+
builder.instance_eval { @book.creator_list[1] }.to_s.should == 'Second Author'
|
122
|
+
builder.instance_eval { @book.creator_list[1].file_as }.to_s.should == '2nd'
|
123
|
+
builder.instance_eval { @book.creator_list[2] }.to_s.should == 'Third Person'
|
124
|
+
builder.instance_eval { @book.creator_list[2].file_as }.to_s.should == '3rd'
|
125
|
+
builder.instance_eval { @book.creator_list[2].role }.to_s.should == 'edt'
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
it 'should generate multiple creators, and multiple alternates ' do
|
130
|
+
builder = GEPUB::Builder.new {
|
131
|
+
creators 'First Author', 'Second Author', ['Third Person', 'edt']
|
132
|
+
alts(
|
133
|
+
'ja' => ['最初','二番目', '三番目'],
|
134
|
+
'en' => ['first','second','third']
|
135
|
+
)
|
136
|
+
}
|
137
|
+
builder.instance_eval { @book.creator_list }.size.should == 3
|
138
|
+
builder.instance_eval { @book.creator_list[0] }.to_s.should == 'First Author'
|
139
|
+
builder.instance_eval { @book.creator_list[0].list_alternates['ja'] }.to_s.should == '最初'
|
140
|
+
builder.instance_eval { @book.creator_list[0].list_alternates['en'] }.to_s.should == 'first'
|
141
|
+
builder.instance_eval { @book.creator_list[1] }.to_s.should == 'Second Author'
|
142
|
+
builder.instance_eval { @book.creator_list[1].list_alternates['ja'] }.to_s.should == '二番目'
|
143
|
+
builder.instance_eval { @book.creator_list[1].list_alternates['en'] }.to_s.should == 'second'
|
144
|
+
builder.instance_eval { @book.creator_list[2] }.to_s.should == 'Third Person'
|
145
|
+
builder.instance_eval { @book.creator_list[2].list_alternates['ja'] }.to_s.should == '三番目'
|
146
|
+
builder.instance_eval { @book.creator_list[2].list_alternates['en'] }.to_s.should == 'third'
|
147
|
+
builder.instance_eval { @book.creator_list[2].role }.to_s.should == 'edt'
|
148
|
+
end
|
149
|
+
end
|
150
|
+
context 'resources' do
|
151
|
+
it 'should add a file to book' do
|
152
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
153
|
+
builder = GEPUB::Builder.new {
|
154
|
+
resources(:workdir => workdir) {
|
155
|
+
file('text/memo.txt')
|
156
|
+
}
|
157
|
+
}
|
158
|
+
builder.instance_eval{ @book.item_by_href('text/memo.txt') }.should_not be_nil
|
159
|
+
builder.instance_eval{ @book.item_by_href('text/memo.txt').content.chomp }.should == 'just a plain text.'
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should add files to book' do
|
163
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
164
|
+
builder = GEPUB::Builder.new {
|
165
|
+
resources(:workdir => workdir) {
|
166
|
+
files('text/memo.txt','text/cover.xhtml')
|
167
|
+
}
|
168
|
+
}
|
169
|
+
builder.instance_eval{ @book.item_by_href('text/memo.txt') }.should_not be_nil
|
170
|
+
builder.instance_eval{ @book.item_by_href('text/memo.txt').content.chomp }.should == 'just a plain text.'
|
171
|
+
builder.instance_eval{ @book.item_by_href('text/cover.xhtml') }.should_not be_nil
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'should add files to book from IO object' do
|
175
|
+
io = File.new(File.join(File.dirname(__FILE__),'fixtures', 'builder', 'text', 'memo.txt'))
|
176
|
+
builder = GEPUB::Builder.new {
|
177
|
+
resources() {
|
178
|
+
file('text/memo.txt' => io)
|
179
|
+
}
|
180
|
+
}
|
181
|
+
builder.instance_eval{ @book.item_by_href('text/memo.txt') }.should_not be_nil
|
182
|
+
builder.instance_eval{ @book.item_by_href('text/memo.txt').content.chomp }.should == 'just a plain text.'
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should add image file as cover' do
|
186
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
187
|
+
builder = GEPUB::Builder.new {
|
188
|
+
resources(:workdir => workdir) {
|
189
|
+
cover_image 'img/cover.jpg'
|
190
|
+
}
|
191
|
+
}
|
192
|
+
builder.instance_eval{ @book.item_by_href('img/cover.jpg') }.should_not be_nil
|
193
|
+
builder.instance_eval{ @book.item_by_href('img/cover.jpg').properties.member? 'cover-image' }.should == true
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'should add file as nav' do
|
197
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
198
|
+
builder = GEPUB::Builder.new {
|
199
|
+
resources(:workdir => workdir) {
|
200
|
+
nav 'text/nav.xhtml'
|
201
|
+
}
|
202
|
+
}
|
203
|
+
builder.instance_eval{ @book.item_by_href('text/nav.xhtml') }.should_not be_nil
|
204
|
+
builder.instance_eval{ @book.item_by_href('text/nav.xhtml').properties.member? 'nav' }.should == true
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'should specify mediatype' do
|
208
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
209
|
+
builder = GEPUB::Builder.new {
|
210
|
+
resources(:workdir => workdir) {
|
211
|
+
file('resources/noise.m4')
|
212
|
+
media_type('audio/mp4')
|
213
|
+
}
|
214
|
+
}
|
215
|
+
builder.instance_eval{ @book.item_by_href('resources/noise.m4') }.should_not be_nil
|
216
|
+
builder.instance_eval{ @book.item_by_href('resources/noise.m4').media_type }.should == 'audio/mp4'
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'should specify mediatype to files' do
|
220
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
221
|
+
builder = GEPUB::Builder.new {
|
222
|
+
resources(:workdir => workdir) {
|
223
|
+
files('resources/noise.m4', 'resources/noise_2.m4a')
|
224
|
+
media_type('audio/mp4')
|
225
|
+
}
|
226
|
+
}
|
227
|
+
builder.instance_eval{ @book.item_by_href('resources/noise.m4') }.should_not be_nil
|
228
|
+
builder.instance_eval{ @book.item_by_href('resources/noise.m4').media_type }.should == 'audio/mp4'
|
229
|
+
|
230
|
+
builder.instance_eval{ @book.item_by_href('resources/noise_2.m4a') }.should_not be_nil
|
231
|
+
builder.instance_eval{ @book.item_by_href('resources/noise_2.m4a').media_type }.should == 'audio/mp4'
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should specify mediatype to files using with_media_type' do
|
235
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
236
|
+
builder = GEPUB::Builder.new {
|
237
|
+
resources(:workdir => workdir) {
|
238
|
+
with_media_type('audio/mp4') {
|
239
|
+
file('resources/noise.m4')
|
240
|
+
file('resources/noise_2.m4a')
|
241
|
+
}
|
242
|
+
file('text/cover.xhtml')
|
243
|
+
}
|
244
|
+
}
|
245
|
+
builder.instance_eval{ @book.item_by_href('resources/noise.m4') }.should_not be_nil
|
246
|
+
builder.instance_eval{ @book.item_by_href('resources/noise.m4').media_type }.should == 'audio/mp4'
|
247
|
+
|
248
|
+
builder.instance_eval{ @book.item_by_href('resources/noise_2.m4a') }.should_not be_nil
|
249
|
+
builder.instance_eval{ @book.item_by_href('resources/noise_2.m4a').media_type }.should == 'audio/mp4'
|
250
|
+
|
251
|
+
builder.instance_eval{ @book.item_by_href('text/cover.xhtml') }.should_not be_nil
|
252
|
+
builder.instance_eval{ @book.item_by_href('text/cover.xhtml').media_type }.should == 'application/xhtml+xml'
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'should add files to book in spine' do
|
256
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
257
|
+
builder = GEPUB::Builder.new {
|
258
|
+
resources(:workdir => workdir) {
|
259
|
+
ordered {
|
260
|
+
file('text/cover.xhtml')
|
261
|
+
file('text/memo.txt')
|
262
|
+
}
|
263
|
+
}
|
264
|
+
}
|
265
|
+
builder.instance_eval{ @book.item_by_href('text/cover.xhtml') }.should_not be_nil
|
266
|
+
builder.instance_eval{ @book.spine_items[0].href }.should == 'text/cover.xhtml'
|
267
|
+
builder.instance_eval{ @book.item_by_href('text/memo.txt') }.should_not be_nil
|
268
|
+
builder.instance_eval{ @book.spine_items[1].href }.should == 'text/memo.txt'
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'should add files and heading' do
|
272
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
273
|
+
builder = GEPUB::Builder.new {
|
274
|
+
resources(:workdir => workdir) {
|
275
|
+
ordered {
|
276
|
+
file('text/cover.xhtml')
|
277
|
+
heading 'cover page'
|
278
|
+
file('text/memo.txt')
|
279
|
+
heading 'memo text'
|
280
|
+
}
|
281
|
+
}
|
282
|
+
}
|
283
|
+
builder.instance_eval{ @book.item_by_href('text/cover.xhtml') }.should_not be_nil
|
284
|
+
builder.instance_eval{ @book.spine_items[0].href }.should == 'text/cover.xhtml'
|
285
|
+
builder.instance_eval{ @book.item_by_href('text/memo.txt') }.should_not be_nil
|
286
|
+
builder.instance_eval{ @book.spine_items[1].href }.should == 'text/memo.txt'
|
287
|
+
builder.instance_eval{ @book.instance_eval { @toc[0][:item].href }}.should == 'text/cover.xhtml'
|
288
|
+
builder.instance_eval{ @book.instance_eval { @toc[0][:text] }}.should == 'cover page'
|
289
|
+
builder.instance_eval{ @book.instance_eval { @toc[1][:item].href }}.should == 'text/memo.txt'
|
290
|
+
builder.instance_eval{ @book.instance_eval { @toc[1][:text] }}.should == 'memo text'
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'should handle fallback chain' do
|
294
|
+
# in this test, do not supply
|
295
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
296
|
+
builder = GEPUB::Builder.new {
|
297
|
+
resources(:workdir => workdir) {
|
298
|
+
fallback_group {
|
299
|
+
file 'chap3_docbook.xhtml' => nil
|
300
|
+
media_type('application/docbook+xml')
|
301
|
+
file 'chap3.xml' => nil
|
302
|
+
media_type("application/z3986-auth+xml")
|
303
|
+
file 'chap3.xhtml' => nil
|
304
|
+
}
|
305
|
+
}
|
306
|
+
}
|
307
|
+
builder.instance_eval {
|
308
|
+
fallbackid = @book.item_by_href('chap3_docbook.xhtml').fallback
|
309
|
+
@book.items[fallbackid].href.should == 'chap3.xml'
|
310
|
+
|
311
|
+
fallbackid = @book.items[fallbackid].fallback
|
312
|
+
@book.items[fallbackid].href.should == 'chap3.xhtml'
|
313
|
+
}
|
314
|
+
end
|
315
|
+
|
316
|
+
it 'should handle fallback chain with fallback_chain_files' do
|
317
|
+
# in this test, do not supply
|
318
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
319
|
+
builder = GEPUB::Builder.new {
|
320
|
+
resources(:workdir => workdir) {
|
321
|
+
fallback_chain_files 'chap3_docbook.xhtml' => nil, 'chap3.xml' => nil, 'chap3.xhtml' => nil
|
322
|
+
}
|
323
|
+
}
|
324
|
+
builder.instance_eval {
|
325
|
+
fallbackid = @book.item_by_href('chap3_docbook.xhtml').fallback
|
326
|
+
@book.items[fallbackid].href.should == 'chap3.xml'
|
327
|
+
|
328
|
+
fallbackid = @book.items[fallbackid].fallback
|
329
|
+
@book.items[fallbackid].href.should == 'chap3.xhtml'
|
330
|
+
}
|
331
|
+
end
|
332
|
+
|
333
|
+
it 'should handle fallback chain with fallback_chain_files in with_media_type' do
|
334
|
+
# in this test, do not supply
|
335
|
+
workdir = File.join(File.dirname(__FILE__),'fixtures', 'builder')
|
336
|
+
builder = GEPUB::Builder.new {
|
337
|
+
resources(:workdir => workdir) {
|
338
|
+
with_media_type('application/docbook+xml', 'application/z3986-auth+xml', 'application/xhtml+xml') {
|
339
|
+
fallback_chain_files 'chap3_docbook.xhtml' => nil, 'chap3.xml' => nil, 'chap3.xhtml' => nil
|
340
|
+
}
|
341
|
+
}
|
342
|
+
}
|
343
|
+
builder.instance_eval {
|
344
|
+
@book.item_by_href('chap3_docbook.xhtml').media_type.should == 'application/docbook+xml'
|
345
|
+
fallbackid = @book.item_by_href('chap3_docbook.xhtml').fallback
|
346
|
+
@book.items[fallbackid].href.should == 'chap3.xml'
|
347
|
+
@book.items[fallbackid].media_type.should == 'application/z3986-auth+xml'
|
348
|
+
|
349
|
+
fallbackid = @book.items[fallbackid].fallback
|
350
|
+
@book.items[fallbackid].href.should == 'chap3.xhtml'
|
351
|
+
@book.items[fallbackid].media_type.should == 'application/xhtml+xml'
|
352
|
+
}
|
353
|
+
end
|
354
|
+
|
355
|
+
end
|
356
|
+
end
|
data/spec/example_spec.rb
CHANGED
@@ -3,7 +3,42 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
3
3
|
require 'rubygems'
|
4
4
|
|
5
5
|
describe 'GEPUB usage' do
|
6
|
+
context 'On using Builder' do
|
7
|
+
end
|
8
|
+
|
6
9
|
context 'On generating EPUB' do
|
10
|
+
it 'should generate simple EPUB3 with Builder' do
|
11
|
+
workdir = File.join(File.dirname(__FILE__), 'fixtures', 'testdata')
|
12
|
+
builder = GEPUB::Builder.new {
|
13
|
+
unique_identifier 'http:/example.jp/bookid_in_url', 'BookID', 'URL'
|
14
|
+
language 'ja'
|
15
|
+
title 'GEPUBサンプル文書'
|
16
|
+
file_as 'GEPUB Sample Book'
|
17
|
+
alt 'en' => 'GEPUB Sample Book (Japanese)',
|
18
|
+
'el' => 'GEPUB δείγμα (Ιαπωνικά)',
|
19
|
+
'th' => 'GEPUB ตัวอย่าง (ญี่ปุ่น)'
|
20
|
+
|
21
|
+
subtitle 'これはあくまでサンプルです'
|
22
|
+
alt 'en' => 'This book is just a sample'
|
23
|
+
creator '小嶋智'
|
24
|
+
contributors 'Denshobu', 'Asagaya Densho', 'Shonan Densho Teidan', 'eMagazine Torutaru'
|
25
|
+
resources(:workdir => workdir) {
|
26
|
+
cover_image 'img/image1.jpg' => 'image1.jpg'
|
27
|
+
ordered {
|
28
|
+
file 'text/chap1.xhtml' => StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml"><head><title>c1</title></head><body><p>the first page</p></body></html>')
|
29
|
+
heading 'Chapter 1'
|
30
|
+
file 'text/chap1-1.xhtml' => StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml"><head><title>c2</title></head><body><p>the second page</p></body></html>')
|
31
|
+
file 'text/chap2.html' => StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml"><head><title>c3</title></head><body><p>the third page</p></body></html>')
|
32
|
+
heading 'Chapter 2'
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
epubname = File.join(File.dirname(__FILE__), 'example_test_with_builder.epub')
|
37
|
+
builder.generate_epub(epubname)
|
38
|
+
jar = File.join(File.dirname(__FILE__), 'fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar')
|
39
|
+
system 'java' '-jar', jar, epubname
|
40
|
+
end
|
41
|
+
|
7
42
|
it 'should generate simple EPUB3 with rather complicated matadata' do
|
8
43
|
book = GEPUB::Book.new
|
9
44
|
book.set_main_id('http:/example.jp/bookid_in_url', 'BookID', 'URL')
|
@@ -33,10 +68,7 @@ describe 'GEPUB usage' do
|
|
33
68
|
book.add_contributor('電子雑誌トルタル').set_display_seq(4).add_alternates('en' => 'eMagazine Torutaru')
|
34
69
|
|
35
70
|
imgfile = File.join(File.dirname(__FILE__), 'fixtures', 'testdata', 'image1.jpg')
|
36
|
-
|
37
|
-
|io|
|
38
|
-
book.add_item('img/image1.jpg',io).cover_image
|
39
|
-
end
|
71
|
+
book.add_item('img/image1.jpg',imgfile).cover_image
|
40
72
|
|
41
73
|
# within ordered block, add_item will be added to spine.
|
42
74
|
book.ordered {
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
just a plain text.
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
|
2
|
+
<head></head>
|
3
|
+
<body>
|
4
|
+
<nav epub:type="toc" id="toc">
|
5
|
+
<h1>Table of contents</h1>
|
6
|
+
<ol>
|
7
|
+
<li><a href="foobar.xhtml">Chapter 1</a> </li>
|
8
|
+
<li> <a href="barbar.xhtml">Chapter 2</a></li>
|
9
|
+
</ol>
|
10
|
+
</nav>
|
11
|
+
</body>
|
12
|
+
</html>
|
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.3
|
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-02-
|
12
|
+
date: 2012-02-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70335408467760 !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: *70335408467760
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: nokogiri
|
27
|
-
requirement: &
|
27
|
+
requirement: &70335408467260 !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: *70335408467260
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rubyzip
|
38
|
-
requirement: &
|
38
|
+
requirement: &70335408466800 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,9 +43,9 @@ dependencies:
|
|
43
43
|
version: 0.9.6
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
47
|
-
description: gepub is a EPUB parser/generator. Generates
|
48
|
-
|
46
|
+
version_requirements: *70335408466800
|
47
|
+
description: gepub is a generic EPUB parser/generator. Generates and parse EPUB2 and
|
48
|
+
EPUB3
|
49
49
|
email:
|
50
50
|
- skoji@mac.com
|
51
51
|
executables:
|
@@ -60,21 +60,32 @@ files:
|
|
60
60
|
- README.md
|
61
61
|
- Rakefile
|
62
62
|
- bin/gepuber
|
63
|
+
- examples/builder_example.rb
|
63
64
|
- examples/generate_example.rb
|
64
65
|
- examples/image1.jpg
|
65
66
|
- gepub.gemspec
|
66
67
|
- lib/gepub.rb
|
67
68
|
- lib/gepub/book.rb
|
69
|
+
- lib/gepub/builder.rb
|
70
|
+
- lib/gepub/builder_mixin.rb
|
68
71
|
- lib/gepub/gepuber.rb
|
69
72
|
- lib/gepub/item.rb
|
70
73
|
- lib/gepub/manifest.rb
|
71
74
|
- lib/gepub/meta.rb
|
72
75
|
- lib/gepub/metadata.rb
|
73
76
|
- lib/gepub/package.rb
|
77
|
+
- lib/gepub/resource_builder.rb
|
74
78
|
- lib/gepub/spine.rb
|
75
79
|
- lib/gepub/version.rb
|
76
80
|
- lib/gepub/xml_util.rb
|
81
|
+
- spec/builder_spec.rb
|
77
82
|
- spec/example_spec.rb
|
83
|
+
- spec/fixtures/builder/img/cover.jpg
|
84
|
+
- spec/fixtures/builder/resources/noise.m4
|
85
|
+
- spec/fixtures/builder/resources/noise_2.m4a
|
86
|
+
- spec/fixtures/builder/text/cover.xhtml
|
87
|
+
- spec/fixtures/builder/text/memo.txt
|
88
|
+
- spec/fixtures/builder/text/nav.xhtml
|
78
89
|
- spec/fixtures/epubcheck-3.0b4/COPYING.txt
|
79
90
|
- spec/fixtures/epubcheck-3.0b4/README.txt
|
80
91
|
- spec/fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar
|
@@ -118,9 +129,16 @@ rubyforge_project: gepub
|
|
118
129
|
rubygems_version: 1.8.11
|
119
130
|
signing_key:
|
120
131
|
specification_version: 3
|
121
|
-
summary: a generic EPUB
|
132
|
+
summary: a generic EPUB library for Ruby.
|
122
133
|
test_files:
|
134
|
+
- spec/builder_spec.rb
|
123
135
|
- spec/example_spec.rb
|
136
|
+
- spec/fixtures/builder/img/cover.jpg
|
137
|
+
- spec/fixtures/builder/resources/noise.m4
|
138
|
+
- spec/fixtures/builder/resources/noise_2.m4a
|
139
|
+
- spec/fixtures/builder/text/cover.xhtml
|
140
|
+
- spec/fixtures/builder/text/memo.txt
|
141
|
+
- spec/fixtures/builder/text/nav.xhtml
|
124
142
|
- spec/fixtures/epubcheck-3.0b4/COPYING.txt
|
125
143
|
- spec/fixtures/epubcheck-3.0b4/README.txt
|
126
144
|
- spec/fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar
|