walterdavis-eeepub 0.6.2
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 +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
|