walterdavis-eeepub 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.md +76 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/examples/files/bar.html +42 -0
- data/examples/files/foo.html +42 -0
- data/examples/simple_epub.rb +26 -0
- data/lib/eeepub/container_item.rb +108 -0
- data/lib/eeepub/easy.rb +101 -0
- data/lib/eeepub/maker.rb +127 -0
- data/lib/eeepub/ncx.rb +68 -0
- data/lib/eeepub/ocf.rb +107 -0
- data/lib/eeepub/opf.rb +149 -0
- data/lib/eeepub.rb +15 -0
- data/spec/eeepub/easy_spec.rb +67 -0
- data/spec/eeepub/maker_spec.rb +129 -0
- data/spec/eeepub/ncx_spec.rb +80 -0
- data/spec/eeepub/ocf_spec.rb +43 -0
- data/spec/eeepub/opf_spec.rb +265 -0
- data/spec/eeepub_spec.rb +4 -0
- data/spec/spec_helper.rb +12 -0
- metadata +137 -0
data/lib/eeepub/ocf.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
module EeePub
|
2
|
+
# Class to create OCF
|
3
|
+
class OCF
|
4
|
+
# Class for 'container.xml' of OCF
|
5
|
+
class Container < ContainerItem
|
6
|
+
attr_accessor :rootfiles
|
7
|
+
|
8
|
+
# @param [String or Array or Hash]
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # with String
|
12
|
+
# EeePub::OCF::Container.new('container.opf')
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # with Array
|
16
|
+
# EeePub::OCF::Container.new(['container.opf', 'other.opf'])
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# # with Hash
|
20
|
+
# EeePub::OCF::Container.new(
|
21
|
+
# :rootfiles => [
|
22
|
+
# {:full_path => 'container.opf', :media_type => 'application/oebps-package+xml'}
|
23
|
+
# ]
|
24
|
+
# )
|
25
|
+
def initialize(arg)
|
26
|
+
case arg
|
27
|
+
when String
|
28
|
+
set_values(
|
29
|
+
:rootfiles => [
|
30
|
+
{:full_path => arg, :media_type => guess_media_type(arg)}
|
31
|
+
]
|
32
|
+
)
|
33
|
+
when Array
|
34
|
+
# TODO: spec
|
35
|
+
set_values(
|
36
|
+
:rootfiles => arg.keys.map { |k|
|
37
|
+
filename = arg[k]
|
38
|
+
{:full_path => filename, :media_type => guess_media_type(filename)}
|
39
|
+
}
|
40
|
+
)
|
41
|
+
when Hash
|
42
|
+
set_values(arg)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def build_xml(builder)
|
49
|
+
builder.container :xmlns => "urn:oasis:names:tc:opendocument:xmlns:container", :version => "1.0" do
|
50
|
+
builder.rootfiles do
|
51
|
+
rootfiles.each do |i|
|
52
|
+
builder.rootfile convert_to_xml_attributes(i)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
attr_accessor :dir, :container
|
60
|
+
|
61
|
+
# @param [Hash<Symbol, Object>] values the values of symbols and objects for OCF
|
62
|
+
#
|
63
|
+
# @example
|
64
|
+
# EeePub::OCF.new(
|
65
|
+
# :dir => '/path/to/dir',
|
66
|
+
# :container => 'container.opf'
|
67
|
+
# )
|
68
|
+
def initialize(values)
|
69
|
+
values.each do |k, v|
|
70
|
+
self.send(:"#{k}=", v)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Set container
|
75
|
+
#
|
76
|
+
# @param [EeePub::OCF::Container or args for EeePub::OCF::Container]
|
77
|
+
def container=(arg)
|
78
|
+
if arg.is_a?(EeePub::OCF::Container)
|
79
|
+
@container = arg
|
80
|
+
else
|
81
|
+
# TODO: spec
|
82
|
+
@container = EeePub::OCF::Container.new(arg)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Save as OCF
|
87
|
+
#
|
88
|
+
# @param [String] output_path the output file path of ePub
|
89
|
+
def save(output_path)
|
90
|
+
output_path = File.expand_path(output_path)
|
91
|
+
|
92
|
+
FileUtils.chdir(dir) do
|
93
|
+
File.open('mimetype', 'w') do |f|
|
94
|
+
f << 'application/epub+zip'
|
95
|
+
end
|
96
|
+
|
97
|
+
meta_inf = 'META-INF'
|
98
|
+
FileUtils.mkdir_p(meta_inf)
|
99
|
+
|
100
|
+
container.save(File.join(meta_inf, 'container.xml'))
|
101
|
+
|
102
|
+
%x(zip -X9 \"#{output_path}\" mimetype)
|
103
|
+
%x(zip -Xr9D \"#{output_path}\" * -xi mimetype)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/eeepub/opf.rb
ADDED
@@ -0,0 +1,149 @@
|
|
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
|
+
:author,
|
13
|
+
:publisher,
|
14
|
+
:rights,
|
15
|
+
:manifest,
|
16
|
+
:spine,
|
17
|
+
:guide,
|
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' => unique_identifier,
|
52
|
+
'version' => "2.0" do
|
53
|
+
|
54
|
+
build_metadata(builder)
|
55
|
+
build_manifest(builder)
|
56
|
+
build_spine(builder)
|
57
|
+
build_guide(builder)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def build_metadata(builder)
|
62
|
+
builder.metadata 'xmlns:dc' => "http://purl.org/dc/elements/1.1/",
|
63
|
+
'xmlns:dcterms' => "http://purl.org/dc/terms/",
|
64
|
+
'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
|
65
|
+
'xmlns:opf' => "http://www.idpf.org/2007/opf" do
|
66
|
+
|
67
|
+
identifier.each do |i|
|
68
|
+
attrs = {}
|
69
|
+
attrs['opf:scheme'] = i[:scheme] if i[:scheme]
|
70
|
+
attrs[:id] = i[:id] if i[:id]
|
71
|
+
builder.dc :identifier, i[:value], attrs
|
72
|
+
end
|
73
|
+
|
74
|
+
[:title, :language, :subject, :description, :relation, :creator, :author, :publisher, :date, :rights].each do |i|
|
75
|
+
value = self.send(i)
|
76
|
+
next unless value
|
77
|
+
|
78
|
+
[value].flatten.each do |v|
|
79
|
+
case v
|
80
|
+
when Hash
|
81
|
+
builder.dc i, v[:value], convert_to_xml_attributes(v.reject {|k, v| k == :value})
|
82
|
+
else
|
83
|
+
builder.dc i, v
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def build_manifest(builder)
|
91
|
+
builder.manifest do
|
92
|
+
complete_manifest.each do |i|
|
93
|
+
builder.item :id => i[:id], :href => i[:href], 'media-type' => i[:media_type]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def build_spine(builder)
|
99
|
+
builder.spine :toc => toc do
|
100
|
+
spine.each do |i|
|
101
|
+
builder.itemref :idref => i
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def build_guide(builder)
|
107
|
+
return if guide.nil? || guide.empty?
|
108
|
+
|
109
|
+
builder.guide do
|
110
|
+
guide.each do |i|
|
111
|
+
builder.reference convert_to_xml_attributes(i)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def complete_manifest
|
117
|
+
item_id_cache = {}
|
118
|
+
|
119
|
+
result = manifest.map do |i|
|
120
|
+
case i
|
121
|
+
when String
|
122
|
+
id = create_unique_item_id(i, item_id_cache)
|
123
|
+
href = i
|
124
|
+
media_type = guess_media_type(i)
|
125
|
+
when Hash
|
126
|
+
id = i[:id] || create_unique_item_id(i[:href], item_id_cache)
|
127
|
+
href = i[:href]
|
128
|
+
media_type = i[:media_type] || guess_media_type(i[:href])
|
129
|
+
end
|
130
|
+
{:id => id, :href => href, :media_type => media_type}
|
131
|
+
end
|
132
|
+
|
133
|
+
result += [{:id => 'ncx', :href => ncx, :media_type => 'application/x-dtbncx+xml'}] if ncx
|
134
|
+
result
|
135
|
+
end
|
136
|
+
|
137
|
+
def create_unique_item_id(filename, id_cache)
|
138
|
+
basename = File.basename(filename)
|
139
|
+
unless id_cache[basename]
|
140
|
+
id_cache[basename] = 0
|
141
|
+
name = basename
|
142
|
+
else
|
143
|
+
name = "#{basename}-#{id_cache[basename]}"
|
144
|
+
end
|
145
|
+
id_cache[basename] += 1
|
146
|
+
name
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
data/lib/eeepub.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'eeepub/container_item'
|
2
|
+
require 'eeepub/opf'
|
3
|
+
require 'eeepub/ocf'
|
4
|
+
require 'eeepub/ncx'
|
5
|
+
require 'eeepub/maker'
|
6
|
+
require 'eeepub/easy'
|
7
|
+
|
8
|
+
module EeePub
|
9
|
+
# Make ePub
|
10
|
+
#
|
11
|
+
# @param [Proc] block the block for initialize EeePub::Maker
|
12
|
+
def self.make(&block)
|
13
|
+
EeePub::Maker.new(&block)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,67 @@
|
|
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
|
+
author 'foo bar'
|
9
|
+
identifier 'http://example.com/book/foo', :scheme => 'URL'
|
10
|
+
uid 'http://example.com/book/foo'
|
11
|
+
end
|
12
|
+
|
13
|
+
@easy.sections << ['1. foo', <<HTML]
|
14
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
15
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
16
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
|
17
|
+
<head>
|
18
|
+
<title>foo</title>
|
19
|
+
</head>
|
20
|
+
<body>
|
21
|
+
<p>
|
22
|
+
foo foo foo foo foo foo
|
23
|
+
</p>
|
24
|
+
</body>
|
25
|
+
</html>
|
26
|
+
HTML
|
27
|
+
|
28
|
+
@easy.sections << ['2. bar', <<HTML]
|
29
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
30
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
31
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
|
32
|
+
<head>
|
33
|
+
<title>bar</title>
|
34
|
+
</head>
|
35
|
+
<body>
|
36
|
+
<p>
|
37
|
+
bar bar bar bar bar bar
|
38
|
+
</p>
|
39
|
+
</body>
|
40
|
+
</html>
|
41
|
+
HTML
|
42
|
+
|
43
|
+
@easy.assets << 'image.png'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'spec for prepare' do
|
47
|
+
Dir.mktmpdir do |dir|
|
48
|
+
mock(FileUtils).cp('image.png', dir)
|
49
|
+
|
50
|
+
@easy.send(:prepare, dir)
|
51
|
+
|
52
|
+
file1 = File.join(dir, 'section_0.html')
|
53
|
+
file2 = File.join(dir, 'section_1.html')
|
54
|
+
File.exists?(file1).should be_true
|
55
|
+
File.exists?(file2).should be_true
|
56
|
+
File.read(file1).should == @easy.sections[0][1]
|
57
|
+
File.read(file2).should == @easy.sections[1][1]
|
58
|
+
|
59
|
+
@easy.instance_variable_get(:@nav).should == [
|
60
|
+
{:label => '1. foo', :content => 'section_0.html'},
|
61
|
+
{:label => '2. bar', :content => 'section_1.html'}
|
62
|
+
]
|
63
|
+
|
64
|
+
@easy.instance_variable_get(:@files).should == [file1, file2, 'image.png']
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,129 @@
|
|
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
|
+
author 'foo bar'
|
9
|
+
publisher 'jugyo.org'
|
10
|
+
date "2010-05-06"
|
11
|
+
language 'en'
|
12
|
+
subject 'epub sample'
|
13
|
+
description 'this is epub sample'
|
14
|
+
rights 'xxx'
|
15
|
+
relation 'xxx'
|
16
|
+
identifier 'http://example.com/book/foo', :scheme => 'URL'
|
17
|
+
uid 'http://example.com/book/foo'
|
18
|
+
ncx_file 'toc.ncx'
|
19
|
+
opf_file 'content.opf'
|
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(:@authors).should == ['foo bar'] }
|
31
|
+
it { @maker.instance_variable_get(:@publishers).should == ['jugyo.org'] }
|
32
|
+
it { @maker.instance_variable_get(:@dates).should == ["2010-05-06"] }
|
33
|
+
it { @maker.instance_variable_get(:@identifiers).should == [{:value => 'http://example.com/book/foo', :scheme => 'URL'}] }
|
34
|
+
it { @maker.instance_variable_get(:@uid).should == 'http://example.com/book/foo' }
|
35
|
+
it { @maker.instance_variable_get(:@ncx_file).should == 'toc.ncx' }
|
36
|
+
it { @maker.instance_variable_get(:@opf_file).should == 'content.opf' }
|
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 {|i| i.call('/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 => "http://example.com/book/foo"
|
55
|
+
) { stub!.save }
|
56
|
+
mock(EeePub::OPF).new(
|
57
|
+
:title => ["sample"],
|
58
|
+
:creator => ["jugyo"],
|
59
|
+
:author => ["foo bar"],
|
60
|
+
:date => ["2010-05-06"],
|
61
|
+
:language => ['en'],
|
62
|
+
:subject => ['epub sample'],
|
63
|
+
:description => ['this is epub sample'],
|
64
|
+
:rights => ['xxx'],
|
65
|
+
:relation => ['xxx'],
|
66
|
+
:ncx => "toc.ncx",
|
67
|
+
:publisher => ["jugyo.org"],
|
68
|
+
:identifier => [{:value => "http://example.com/book/foo", :scheme => "URL"}],
|
69
|
+
:manifest => ['foo.html', 'bar.html']
|
70
|
+
) { stub!.save }
|
71
|
+
mock(EeePub::OCF).new(
|
72
|
+
:container => "content.opf",
|
73
|
+
:dir => '/tmp'
|
74
|
+
) { stub!.save }
|
75
|
+
|
76
|
+
@maker.save('test.epub')
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "files as hash" do
|
80
|
+
before do
|
81
|
+
@maker = EeePub::Maker.new do
|
82
|
+
title 'sample'
|
83
|
+
creator 'jugyo'
|
84
|
+
author 'foo bar'
|
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
|
+
files [{'foo.html' => 'foo/bar'}, {'bar.html' => 'foo/bar/baz'}]
|
97
|
+
nav [
|
98
|
+
{:label => '1. foo', :content => 'foo.html'},
|
99
|
+
{:label => '1. bar', :content => 'bar.html'}
|
100
|
+
]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should save' do
|
105
|
+
stub(FileUtils).cp.with_any_args
|
106
|
+
stub(FileUtils).mkdir_p.with_any_args
|
107
|
+
mock(Dir).mktmpdir {|i| i.call('/tmp')}
|
108
|
+
mock(EeePub::NCX).new.with_any_args { stub!.save }
|
109
|
+
mock(EeePub::OPF).new(
|
110
|
+
:title => ["sample"],
|
111
|
+
:creator => ["jugyo"],
|
112
|
+
:author => ["foo bar"],
|
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
|
+
:publisher => ["jugyo.org"],
|
121
|
+
:identifier => [{:value => "http://example.com/book/foo", :scheme => "URL"}],
|
122
|
+
:manifest => ["foo/bar/foo.html", "foo/bar/baz/bar.html"]
|
123
|
+
) { stub!.save }
|
124
|
+
mock(EeePub::OCF).new.with_any_args { stub!.save }
|
125
|
+
|
126
|
+
@maker.save('test.epub')
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
describe "EeePub::NCX" do
|
7
|
+
before do
|
8
|
+
@ncx = EeePub::NCX.new(
|
9
|
+
:uid => 'uid',
|
10
|
+
:nav_map => [
|
11
|
+
{:label => 'foo', :content => 'foo.html'},
|
12
|
+
{:label => 'bar', :content => 'bar.html'}
|
13
|
+
]
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should set default values' do
|
18
|
+
@ncx.depth.should == 1
|
19
|
+
@ncx.total_page_count.should == 0
|
20
|
+
@ncx.max_page_number.should == 0
|
21
|
+
@ncx.doc_title.should == 'Untitled'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should make xml' do
|
25
|
+
doc = Nokogiri::XML(@ncx.to_xml)
|
26
|
+
head = doc.at('head')
|
27
|
+
head.should_not be_nil
|
28
|
+
|
29
|
+
head.at("//xmlns:meta[@name='dtb:uid']")['content'].should == @ncx.uid
|
30
|
+
head.at("//xmlns:meta[@name='dtb:depth']")['content'].should == @ncx.depth.to_s
|
31
|
+
head.at("//xmlns:meta[@name='dtb:totalPageCount']")['content'].should == @ncx.total_page_count.to_s
|
32
|
+
head.at("//xmlns:meta[@name='dtb:maxPageNumber']")['content'].should == @ncx.max_page_number.to_s
|
33
|
+
head.at("//xmlns:docTitle/xmlns:text").inner_text.should == @ncx.doc_title
|
34
|
+
|
35
|
+
nav_map = doc.at('navMap')
|
36
|
+
nav_map.should_not be_nil
|
37
|
+
nav_map.search('navPoint').each_with_index do |nav_point, index|
|
38
|
+
expect = @ncx.nav_map[index]
|
39
|
+
nav_point.attribute('id').value.should == "navPoint-#{index + 1}"
|
40
|
+
nav_point.attribute('playOrder').value.should == (index + 1).to_s
|
41
|
+
nav_point.at('navLabel').at('text').inner_text.should == expect[:label]
|
42
|
+
nav_point.at('content').attribute('src').value.should == expect[:content]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'nested nav_map' do
|
47
|
+
before do
|
48
|
+
@ncx.nav = [
|
49
|
+
{:label => 'foo', :content => 'foo.html',
|
50
|
+
:nav => [
|
51
|
+
{:label => 'foo-1', :content => 'foo-1.html'},
|
52
|
+
{:label => 'foo-2', :content => 'foo-2.html'}
|
53
|
+
],
|
54
|
+
},
|
55
|
+
{:label => 'bar', :content => 'bar.html'}
|
56
|
+
]
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should make xml' do
|
60
|
+
doc = Nokogiri::XML(@ncx.to_xml)
|
61
|
+
nav_map = doc.at('navMap')
|
62
|
+
|
63
|
+
nav_map.search('navMap/navPoint').each_with_index do |nav_point, index|
|
64
|
+
expect = @ncx.nav_map[index]
|
65
|
+
nav_point.attribute('id').value.should == "navPoint-#{index + 1}"
|
66
|
+
nav_point.attribute('playOrder').value.should == (index + 1).to_s
|
67
|
+
nav_point.at('navLabel').at('text').inner_text.should == expect[:label]
|
68
|
+
nav_point.at('content').attribute('src').value.should == expect[:content]
|
69
|
+
end
|
70
|
+
|
71
|
+
nav_map.search('navPoint/navPoint').each_with_index do |nav_point, index|
|
72
|
+
expect = @ncx.nav[0][:nav][index]
|
73
|
+
nav_point.attribute('id').value.should == "navPoint-#{index + 2}"
|
74
|
+
nav_point.attribute('playOrder').value.should == (index + 2).to_s
|
75
|
+
nav_point.at('navLabel').at('text').inner_text.should == expect[:label]
|
76
|
+
nav_point.at('content').attribute('src').value.should == expect[:content]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
describe "EeePub::OCF" do
|
7
|
+
before do
|
8
|
+
@tmpdir = File.join(Dir.tmpdir, 'eeepub_test')
|
9
|
+
FileUtils.mkdir_p(@tmpdir)
|
10
|
+
@container = EeePub::OCF::Container.new('foo.opf')
|
11
|
+
@ocf = EeePub::OCF.new(:dir => @tmpdir, :container => @container)
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
FileUtils.rm_rf(@tmpdir)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should return rootfiles' do
|
19
|
+
@container.rootfiles.should == [{:full_path => 'foo.opf', :media_type => 'application/oebps-package+xml'}]
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should specify container as String' do
|
23
|
+
ocf = EeePub::OCF.new(:dir => @tmpdir, :container => 'foo.opf')
|
24
|
+
ocf.container.rootfiles == [{:full_path => 'foo.opf', :media_type => 'application/oebps-package+xml'}]
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should make xml' do
|
28
|
+
doc = Nokogiri::XML(@container.to_xml)
|
29
|
+
rootfiles = doc.at('rootfiles')
|
30
|
+
rootfiles.should_not be_nil
|
31
|
+
rootfiles.search('rootfile').each_with_index do |rootfile, index|
|
32
|
+
expect = @container.rootfiles[index]
|
33
|
+
rootfile.attribute('full-path').value.should == expect[:full_path]
|
34
|
+
rootfile.attribute('media-type').value.should == expect[:media_type]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should make epub' do
|
39
|
+
output_path = File.join('eeepub_test.epub')
|
40
|
+
@ocf.save(output_path)
|
41
|
+
File.exists?(output_path)
|
42
|
+
end
|
43
|
+
end
|