eeepub3 0.0.1
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.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/LICENSE +0 -0
- data/README.md +4 -0
- data/Rakefile +22 -0
- data/eeepub3.gemspec +24 -0
- data/lib/eeepub.rb +15 -0
- data/lib/eeepub/container_item.rb +116 -0
- data/lib/eeepub/easy.rb +100 -0
- data/lib/eeepub/maker.rb +156 -0
- data/lib/eeepub/ncx.rb +67 -0
- data/lib/eeepub/ocf.rb +131 -0
- data/lib/eeepub/opf.rb +154 -0
- data/spec/eeepub/container_item_spec.rb +20 -0
- data/spec/eeepub/easy_spec.rb +66 -0
- data/spec/eeepub/maker_spec.rb +131 -0
- data/spec/eeepub/ncx_spec.rb +80 -0
- data/spec/eeepub/ocf_spec.rb +50 -0
- data/spec/eeepub/opf_spec.rb +267 -0
- data/spec/eeepub_spec.rb +4 -0
- data/spec/spec_helper.rb +14 -0
- metadata +147 -0
data/lib/eeepub/ncx.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
module EeePub
|
2
|
+
class NCX < ContainerItem
|
3
|
+
attr_accessor :uid,
|
4
|
+
:depth,
|
5
|
+
:total_page_count,
|
6
|
+
:max_page_number,
|
7
|
+
:doc_title,
|
8
|
+
:nav_map
|
9
|
+
|
10
|
+
attr_alias :title, :doc_title
|
11
|
+
attr_alias :nav, :nav_map
|
12
|
+
|
13
|
+
default_value :depth, 1
|
14
|
+
default_value :total_page_count, 0
|
15
|
+
default_value :max_page_number, 0
|
16
|
+
default_value :doc_title, 'Untitled'
|
17
|
+
|
18
|
+
def build_xml(builder)
|
19
|
+
builder.ncx 'xmlns:ncx' => 'http://www.daisy.org/z3986/2005/ncx/', :version => '2005-1', :xmlns => 'http://www.daisy.org/z3986/2005/ncx/', 'xml:lang' => 'en' do
|
20
|
+
build_head(builder)
|
21
|
+
builder.docTitle { builder.text doc_title }
|
22
|
+
build_nav_map(builder)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_head(builder)
|
27
|
+
builder.head do
|
28
|
+
{
|
29
|
+
:uid => uid,
|
30
|
+
:depth => depth,
|
31
|
+
:totalPageCount => total_page_count,
|
32
|
+
:maxPageNumber => max_page_number
|
33
|
+
}.each do |k, v|
|
34
|
+
builder.meta :name => "dtb:#{k}", :content => v
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def build_nav_map(builder)
|
40
|
+
builder.navMap do
|
41
|
+
builder_nav_point(builder, nav_map)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def builder_nav_point(builder, nav_point, play_order = 1)
|
46
|
+
case nav_point
|
47
|
+
when Array
|
48
|
+
nav_point.each do |point|
|
49
|
+
play_order = builder_nav_point(builder, point, play_order)
|
50
|
+
end
|
51
|
+
when Hash
|
52
|
+
id = nav_point[:id] || "navPoint-#{play_order}"
|
53
|
+
builder.navPoint :id => id, :playOrder => play_order do
|
54
|
+
builder.navLabel { builder.text nav_point[:label] }
|
55
|
+
builder.content :src => nav_point[:content]
|
56
|
+
play_order += 1
|
57
|
+
if nav_point[:nav]
|
58
|
+
play_order = builder_nav_point(builder, nav_point[:nav], play_order)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
else
|
62
|
+
raise "nav_point must be Array or Hash"
|
63
|
+
end
|
64
|
+
play_order
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/eeepub/ocf.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'zip'
|
2
|
+
|
3
|
+
module EeePub
|
4
|
+
# Class to create OCF
|
5
|
+
class OCF
|
6
|
+
# Class for 'container.xml' of OCF
|
7
|
+
class Container < ContainerItem
|
8
|
+
attr_accessor :rootfiles
|
9
|
+
|
10
|
+
# @param [String or Array or Hash]
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# # with String
|
14
|
+
# EeePub::OCF::Container.new('container.opf')
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# # with Array
|
18
|
+
# EeePub::OCF::Container.new(['container.opf', 'other.opf'])
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# # with Hash
|
22
|
+
# EeePub::OCF::Container.new(
|
23
|
+
# :rootfiles => [
|
24
|
+
# {:full_path => 'container.opf', :media_type => 'application/oebps-package+xml'}
|
25
|
+
# ]
|
26
|
+
# )
|
27
|
+
def initialize(arg)
|
28
|
+
case arg
|
29
|
+
when String
|
30
|
+
set_values(
|
31
|
+
:rootfiles => [
|
32
|
+
{:full_path => arg, :media_type => guess_media_type(arg)}
|
33
|
+
]
|
34
|
+
)
|
35
|
+
when Array
|
36
|
+
# TODO: spec
|
37
|
+
set_values(
|
38
|
+
:rootfiles => arg.keys.map { |k|
|
39
|
+
filename = arg[k]
|
40
|
+
{:full_path => filename, :media_type => guess_media_type(filename)}
|
41
|
+
}
|
42
|
+
)
|
43
|
+
when Hash
|
44
|
+
set_values(arg)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def build_xml(builder)
|
51
|
+
builder.container :xmlns => "urn:oasis:names:tc:opendocument:xmlns:container", :version => "1.0" do
|
52
|
+
builder.rootfiles do
|
53
|
+
rootfiles.each do |i|
|
54
|
+
builder.rootfile convert_to_xml_attributes(i)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
attr_accessor :dir, :container
|
62
|
+
|
63
|
+
# @param [Hash<Symbol, Object>] values the values of symbols and objects for OCF
|
64
|
+
#
|
65
|
+
# @example
|
66
|
+
# EeePub::OCF.new(
|
67
|
+
# :dir => '/path/to/dir',
|
68
|
+
# :container => 'container.opf'
|
69
|
+
# )
|
70
|
+
def initialize(values)
|
71
|
+
values.each do |k, v|
|
72
|
+
self.send(:"#{k}=", v)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Set container
|
77
|
+
#
|
78
|
+
# @param [EeePub::OCF::Container or args for EeePub::OCF::Container]
|
79
|
+
def container=(arg)
|
80
|
+
if arg.is_a?(EeePub::OCF::Container)
|
81
|
+
@container = arg
|
82
|
+
else
|
83
|
+
# TODO: spec
|
84
|
+
@container = EeePub::OCF::Container.new(arg)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Save as OCF
|
89
|
+
#
|
90
|
+
# @param [String] output_path the output file path of ePub
|
91
|
+
def save(output_path)
|
92
|
+
output_path = File.expand_path(output_path)
|
93
|
+
|
94
|
+
create_epub do
|
95
|
+
mimetype = Zip::ZipOutputStream::open(output_path) do |os|
|
96
|
+
os.put_next_entry("mimetype", nil, nil, Zip::ZipEntry::STORED, Zlib::NO_COMPRESSION)
|
97
|
+
os << "application/epub+zip"
|
98
|
+
end
|
99
|
+
zipfile = Zip::ZipFile.open(output_path)
|
100
|
+
Dir.glob('**/*').each do |path|
|
101
|
+
zipfile.add(path, path)
|
102
|
+
end
|
103
|
+
zipfile.commit
|
104
|
+
end
|
105
|
+
FileUtils.remove_entry_secure dir
|
106
|
+
end
|
107
|
+
|
108
|
+
# Stream OCF
|
109
|
+
#
|
110
|
+
# @return [String] streaming output of the zip/epub file.
|
111
|
+
def render
|
112
|
+
create_epub do
|
113
|
+
temp_file = Tempfile.new("ocf")
|
114
|
+
self.save(temp_file.path)
|
115
|
+
return temp_file.read
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
def create_epub
|
121
|
+
FileUtils.chdir(dir) do
|
122
|
+
meta_inf = 'META-INF'
|
123
|
+
FileUtils.mkdir_p(meta_inf)
|
124
|
+
|
125
|
+
container.save(File.join(meta_inf, 'container.xml'))
|
126
|
+
yield
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/lib/eeepub/opf.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
module EeePub
|
2
|
+
class OPF < ContainerItem
|
3
|
+
attr_accessor :unique_identifier,
|
4
|
+
:title,
|
5
|
+
:language,
|
6
|
+
:identifier,
|
7
|
+
:date,
|
8
|
+
:subject,
|
9
|
+
:description,
|
10
|
+
:relation,
|
11
|
+
:creator,
|
12
|
+
:publisher,
|
13
|
+
:rights,
|
14
|
+
:manifest,
|
15
|
+
:spine,
|
16
|
+
:guide,
|
17
|
+
:cover,
|
18
|
+
:ncx,
|
19
|
+
:toc
|
20
|
+
|
21
|
+
default_value :toc, 'ncx'
|
22
|
+
default_value :unique_identifier, 'BookId'
|
23
|
+
default_value :title, 'Untitled'
|
24
|
+
default_value :language, 'en'
|
25
|
+
|
26
|
+
attr_alias :files, :manifest
|
27
|
+
|
28
|
+
def identifier
|
29
|
+
case @identifier
|
30
|
+
when Array
|
31
|
+
@identifier
|
32
|
+
when String
|
33
|
+
[{:value => @identifier, :id => unique_identifier}]
|
34
|
+
when Hash
|
35
|
+
@identifier[:id] = unique_identifier
|
36
|
+
[@identifier]
|
37
|
+
else
|
38
|
+
@identifier
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def spine
|
43
|
+
@spine ||
|
44
|
+
complete_manifest.
|
45
|
+
select { |i| i[:media_type] == 'application/xhtml+xml' }.
|
46
|
+
map { |i| i[:id]}
|
47
|
+
end
|
48
|
+
|
49
|
+
def build_xml(builder)
|
50
|
+
builder.package :xmlns => 'http://www.idpf.org/2007/opf',
|
51
|
+
'unique-identifier' => 'uid',
|
52
|
+
'xml:lang' => 'en-US',
|
53
|
+
'prefix'=> 'cc: http://creativecommons.org/ns#',
|
54
|
+
'version' => '3.0' do
|
55
|
+
|
56
|
+
build_metadata(builder)
|
57
|
+
build_manifest(builder)
|
58
|
+
build_spine(builder)
|
59
|
+
build_guide(builder)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def build_metadata(builder)
|
64
|
+
builder.metadata 'xmlns:dc' => "http://purl.org/dc/elements/1.1/" do
|
65
|
+
identifier.each do |i|
|
66
|
+
attrs = {}
|
67
|
+
attrs['opf:scheme'] = i[:scheme] if i[:scheme]
|
68
|
+
attrs[:id] = i[:id] if i[:id]
|
69
|
+
builder.dc :identifier, i[:value], attrs
|
70
|
+
end
|
71
|
+
|
72
|
+
[:title, :language, :subject, :description, :relation, :creator, :publisher, :date, :rights].each do |i|
|
73
|
+
value = self.send(i)
|
74
|
+
next unless value
|
75
|
+
|
76
|
+
[value].flatten.each do |v|
|
77
|
+
case v
|
78
|
+
when Hash
|
79
|
+
builder.dc i, v[:value], convert_to_xml_attributes(v.reject {|k, v| k == :value})
|
80
|
+
else
|
81
|
+
builder.dc i, v
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
builder.meta({:property => 'dcterms:modified'}, Time.now.strftime('%FT%TZ'))
|
86
|
+
builder.meta(:name => 'cover', :content => self.cover) if self.cover
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def build_manifest(builder)
|
91
|
+
builder.manifest do
|
92
|
+
complete_manifest.each do |i|
|
93
|
+
if i[:media_type] == 'application/xhtml+xml'
|
94
|
+
builder.item :id => i[:id], :href => i[:href], 'media-type' => i[:media_type], 'properties' => i[:properties] || 'scripted'
|
95
|
+
else
|
96
|
+
builder.item :id => i[:id], :href => i[:href], 'media-type' => i[:media_type]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def build_spine(builder)
|
103
|
+
builder.spine :toc => toc do
|
104
|
+
spine.each do |i|
|
105
|
+
builder.itemref :idref => i
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def build_guide(builder)
|
111
|
+
return if guide.nil? || guide.empty?
|
112
|
+
|
113
|
+
builder.guide do
|
114
|
+
guide.each do |i|
|
115
|
+
builder.reference convert_to_xml_attributes(i)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def complete_manifest
|
121
|
+
item_id_cache = {}
|
122
|
+
|
123
|
+
result = manifest.map do |i|
|
124
|
+
case i
|
125
|
+
when String
|
126
|
+
id = create_unique_item_id(i, item_id_cache)
|
127
|
+
href = i
|
128
|
+
media_type = guess_media_type(i)
|
129
|
+
when Hash
|
130
|
+
id = i[:id] || create_unique_item_id(i[:href], item_id_cache)
|
131
|
+
href = i[:href]
|
132
|
+
media_type = i[:media_type] || guess_media_type(i[:href])
|
133
|
+
end
|
134
|
+
{:id => id, :href => href, :media_type => media_type}
|
135
|
+
end
|
136
|
+
|
137
|
+
result += [{:id => 'nav', :href => 'nav.html', :media_type => 'application/xhtml+xml', :properties => 'nav'}]
|
138
|
+
result += [{:id => 'ncx', :href => ncx, :media_type => 'application/x-dtbncx+xml'}] if ncx
|
139
|
+
result
|
140
|
+
end
|
141
|
+
|
142
|
+
def create_unique_item_id(filename, id_cache)
|
143
|
+
basename = File.basename(filename)
|
144
|
+
unless id_cache[basename]
|
145
|
+
id_cache[basename] = 0
|
146
|
+
name = basename
|
147
|
+
else
|
148
|
+
name = "#{basename}-#{id_cache[basename]}"
|
149
|
+
end
|
150
|
+
id_cache[basename] += 1
|
151
|
+
name
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "EeePub::ContainerItem" do
|
4
|
+
|
5
|
+
context 'guess media type' do
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@container_item = EeePub::ContainerItem.new []
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should be application/xhtml+xml' do
|
12
|
+
media_type = 'application/xhtml+xml'
|
13
|
+
['test.htm', 'test.html', 'test.xhtm', 'test.xhtml'].each do |file_name|
|
14
|
+
@container_item.send(:guess_media_type, file_name).should == media_type
|
15
|
+
end
|
16
|
+
@container_item.send(:guess_media_type, "test.xml").should_not == media_type
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "EeePub::Easy" do
|
4
|
+
before do
|
5
|
+
@easy = EeePub::Easy.new do
|
6
|
+
title 'sample'
|
7
|
+
creator 'jugyo'
|
8
|
+
identifier 'http://example.com/book/foo', :scheme => 'URL'
|
9
|
+
uid 'http://example.com/book/foo'
|
10
|
+
end
|
11
|
+
|
12
|
+
@easy.sections << ['1. foo', <<HTML]
|
13
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
14
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
15
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
|
16
|
+
<head>
|
17
|
+
<title>foo</title>
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<p>
|
21
|
+
foo foo foo foo foo foo
|
22
|
+
</p>
|
23
|
+
</body>
|
24
|
+
</html>
|
25
|
+
HTML
|
26
|
+
|
27
|
+
@easy.sections << ['2. bar', <<HTML]
|
28
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
29
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
30
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
|
31
|
+
<head>
|
32
|
+
<title>bar</title>
|
33
|
+
</head>
|
34
|
+
<body>
|
35
|
+
<p>
|
36
|
+
bar bar bar bar bar bar
|
37
|
+
</p>
|
38
|
+
</body>
|
39
|
+
</html>
|
40
|
+
HTML
|
41
|
+
|
42
|
+
@easy.assets << 'image.png'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'spec for prepare' do
|
46
|
+
Dir.mktmpdir do |dir|
|
47
|
+
mock(FileUtils).cp('image.png', dir)
|
48
|
+
|
49
|
+
@easy.send(:prepare, dir)
|
50
|
+
|
51
|
+
file1 = File.join(dir, 'section_0.html')
|
52
|
+
file2 = File.join(dir, 'section_1.html')
|
53
|
+
File.exists?(file1).should be_true
|
54
|
+
File.exists?(file2).should be_true
|
55
|
+
File.read(file1).should == @easy.sections[0][1]
|
56
|
+
File.read(file2).should == @easy.sections[1][1]
|
57
|
+
|
58
|
+
@easy.instance_variable_get(:@nav).should == [
|
59
|
+
{:label => '1. foo', :content => 'section_0.html'},
|
60
|
+
{:label => '2. bar', :content => 'section_1.html'}
|
61
|
+
]
|
62
|
+
|
63
|
+
@easy.instance_variable_get(:@files).should == [file1, file2, 'image.png']
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "EeePub::Maker" do
|
4
|
+
before do
|
5
|
+
@maker = EeePub::Maker.new do
|
6
|
+
title 'sample'
|
7
|
+
creator 'jugyo'
|
8
|
+
publisher 'jugyo.org'
|
9
|
+
date "2010-05-06"
|
10
|
+
language 'en'
|
11
|
+
subject 'epub sample'
|
12
|
+
description 'this is epub sample'
|
13
|
+
rights 'xxx'
|
14
|
+
relation 'xxx'
|
15
|
+
identifier 'http://example.com/book/foo', :scheme => 'URL'
|
16
|
+
uid 'http://example.com/book/foo'
|
17
|
+
ncx_file 'toc.ncx'
|
18
|
+
opf_file 'content.opf'
|
19
|
+
cover 'cover.jpg'
|
20
|
+
files ['foo.html', 'bar.html']
|
21
|
+
nav [
|
22
|
+
{:label => '1. foo', :content => 'foo.html'},
|
23
|
+
{:label => '1. bar', :content => 'bar.html'}
|
24
|
+
]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it { @maker.instance_variable_get(:@titles).should == ['sample'] }
|
29
|
+
it { @maker.instance_variable_get(:@creators).should == ['jugyo'] }
|
30
|
+
it { @maker.instance_variable_get(:@publishers).should == ['jugyo.org'] }
|
31
|
+
it { @maker.instance_variable_get(:@dates).should == ["2010-05-06"] }
|
32
|
+
it { @maker.instance_variable_get(:@identifiers).should == [{:value => 'http://example.com/book/foo', :scheme => 'URL', :id => nil}] }
|
33
|
+
it { @maker.instance_variable_get(:@uid).should == 'http://example.com/book/foo' }
|
34
|
+
it { @maker.instance_variable_get(:@ncx_file).should == 'toc.ncx' }
|
35
|
+
it { @maker.instance_variable_get(:@opf_file).should == 'content.opf' }
|
36
|
+
it { @maker.instance_variable_get(:@cover).should == 'cover.jpg' }
|
37
|
+
it { @maker.instance_variable_get(:@files).should == ['foo.html', 'bar.html'] }
|
38
|
+
it {
|
39
|
+
@maker.instance_variable_get(:@nav).should == [
|
40
|
+
{:label => '1. foo', :content => 'foo.html'},
|
41
|
+
{:label => '1. bar', :content => 'bar.html'}
|
42
|
+
]
|
43
|
+
}
|
44
|
+
|
45
|
+
it 'should save' do
|
46
|
+
stub(FileUtils).cp.with_any_args
|
47
|
+
mock(Dir).mktmpdir { '/tmp' }
|
48
|
+
mock(EeePub::NCX).new(
|
49
|
+
:title => "sample",
|
50
|
+
:nav => [
|
51
|
+
{:label => '1. foo', :content => 'foo.html'},
|
52
|
+
{:label => '1. bar', :content => 'bar.html'}
|
53
|
+
],
|
54
|
+
:uid=>{:value=>"http://example.com/book/foo", :scheme=>"URL", :id=>"http://example.com/book/foo"}
|
55
|
+
) { stub!.save }
|
56
|
+
mock(EeePub::OPF).new(
|
57
|
+
:title => ["sample"],
|
58
|
+
:creator => ["jugyo"],
|
59
|
+
:date => ["2010-05-06"],
|
60
|
+
:language => ['en'],
|
61
|
+
:subject => ['epub sample'],
|
62
|
+
:description => ['this is epub sample'],
|
63
|
+
:rights => ['xxx'],
|
64
|
+
:relation => ['xxx'],
|
65
|
+
:ncx => "toc.ncx",
|
66
|
+
:cover => 'cover.jpg',
|
67
|
+
:publisher => ["jugyo.org"],
|
68
|
+
:unique_identifier=>"http://example.com/book/foo",
|
69
|
+
:identifier => [{:value => "http://example.com/book/foo", :scheme => "URL", :id => "http://example.com/book/foo"}],
|
70
|
+
:manifest => ['foo.html', 'bar.html']
|
71
|
+
) { stub!.save }
|
72
|
+
mock(EeePub::OCF).new(
|
73
|
+
:container => "content.opf",
|
74
|
+
:dir => '/tmp'
|
75
|
+
) { stub!.save }
|
76
|
+
|
77
|
+
@maker.save('test.epub')
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "files as hash" do
|
81
|
+
before do
|
82
|
+
@maker = EeePub::Maker.new do
|
83
|
+
title 'sample'
|
84
|
+
creator 'jugyo'
|
85
|
+
publisher 'jugyo.org'
|
86
|
+
date "2010-05-06"
|
87
|
+
language 'en'
|
88
|
+
subject 'epub sample'
|
89
|
+
description 'this is epub sample'
|
90
|
+
rights 'xxx'
|
91
|
+
relation 'xxx'
|
92
|
+
identifier 'http://example.com/book/foo', :scheme => 'URL'
|
93
|
+
uid 'http://example.com/book/foo'
|
94
|
+
ncx_file 'toc.ncx'
|
95
|
+
opf_file 'content.opf'
|
96
|
+
cover 'cover.jpg'
|
97
|
+
files [{'foo.html' => 'foo/bar'}, {'bar.html' => 'foo/bar/baz'}]
|
98
|
+
nav [
|
99
|
+
{:label => '1. foo', :content => 'foo.html'},
|
100
|
+
{:label => '1. bar', :content => 'bar.html'}
|
101
|
+
]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should save' do
|
106
|
+
stub(FileUtils).cp.with_any_args
|
107
|
+
stub(FileUtils).mkdir_p.with_any_args
|
108
|
+
mock(Dir).mktmpdir { '/tmp' }
|
109
|
+
mock(EeePub::NCX).new.with_any_args { stub!.save }
|
110
|
+
mock(EeePub::OPF).new(
|
111
|
+
:title => ["sample"],
|
112
|
+
:creator => ["jugyo"],
|
113
|
+
:date => ["2010-05-06"],
|
114
|
+
:language => ['en'],
|
115
|
+
:subject => ['epub sample'],
|
116
|
+
:description => ['this is epub sample'],
|
117
|
+
:rights => ['xxx'],
|
118
|
+
:relation => ['xxx'],
|
119
|
+
:ncx => "toc.ncx",
|
120
|
+
:cover => 'cover.jpg',
|
121
|
+
:publisher => ["jugyo.org"],
|
122
|
+
:unique_identifier=>"http://example.com/book/foo",
|
123
|
+
:identifier => [{:value => "http://example.com/book/foo", :scheme => "URL", :id=>"http://example.com/book/foo"}],
|
124
|
+
:manifest => ["foo/bar/foo.html", "foo/bar/baz/bar.html"]
|
125
|
+
) { stub!.save }
|
126
|
+
mock(EeePub::OCF).new.with_any_args { stub!.save }
|
127
|
+
|
128
|
+
@maker.save('test.epub')
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|