gepub 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.
- data/History.txt +4 -0
- data/Manifest.txt +13 -0
- data/README.rdoc +110 -0
- data/Rakefile +26 -0
- data/lib/gepub.rb +8 -0
- data/lib/gepub/generator.rb +225 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/gepub_spec.rb +115 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/tasks/rspec.rake +21 -0
- metadata +89 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
= gepub
|
2
|
+
|
3
|
+
* http://github.com/skoji/gepub
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
a good-enough EPUB generator library.
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* GEPUB::Generator provides functionality to create ncx/opf, and epub file.
|
12
|
+
|
13
|
+
* opf: can't specify creators with role
|
14
|
+
* opf: can't specify date with event
|
15
|
+
* opf: unique-identifier's scheme is fixed to 'URL'
|
16
|
+
* ncx: can't nest navPoint elements
|
17
|
+
* ...and many other restrictions
|
18
|
+
|
19
|
+
== SYNOPSIS:
|
20
|
+
|
21
|
+
require 'rubygems'
|
22
|
+
require 'gepub'
|
23
|
+
require 'fileutils'
|
24
|
+
|
25
|
+
epubdir = "testepub"
|
26
|
+
title = "samplepub"
|
27
|
+
FileUtils.rm_rf(epubdir)
|
28
|
+
FileUtils.mkdir(epubdir)
|
29
|
+
|
30
|
+
epub = GEPUB::Generator.new(title)
|
31
|
+
epub.author="the author"
|
32
|
+
epub.publisher="the publisher"
|
33
|
+
epub.date = "2010-05-03"
|
34
|
+
epub.identifier = "http://www.skoji.jp/testepub/2010-05-03"
|
35
|
+
|
36
|
+
# create test contents files
|
37
|
+
|
38
|
+
[ 'coverpage', 'chapter1', 'chapter2' ].each {
|
39
|
+
|name|
|
40
|
+
File.open(epubdir + "/#{name}.html", 'w') {
|
41
|
+
|file|
|
42
|
+
file << <<EOF
|
43
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
44
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
|
45
|
+
<head>
|
46
|
+
<title>sample #{name} </title>
|
47
|
+
</head>
|
48
|
+
<body>
|
49
|
+
<h1>#{name}</h1>
|
50
|
+
<p>here comes the contents for #{name}</p>
|
51
|
+
</body>
|
52
|
+
</html>
|
53
|
+
EOF
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
# coverpage won't appear on toc, so do not call addNav
|
58
|
+
epub.addManifest('cover', "coverpage.html", 'application/xhtml+xml')
|
59
|
+
epub.spine.push('cover')
|
60
|
+
|
61
|
+
|
62
|
+
epub.addManifest('chap1', "chapter1.html", 'application/xhtml+xml')
|
63
|
+
epub.spine.push('chap1')
|
64
|
+
epub.addNav('chap1', 'Chapter 1', "chapter1.html")
|
65
|
+
|
66
|
+
epub.addManifest('chap2', "chapter2.html", 'application/xhtml+xml')
|
67
|
+
epub.spine.push('chap2')
|
68
|
+
epub.addNav('chap1', 'Chapter 2', "chapter2.html")
|
69
|
+
|
70
|
+
|
71
|
+
epub.create(epubdir)
|
72
|
+
epub.create_epub(epubdir, ".")
|
73
|
+
|
74
|
+
== REQUIREMENTS:
|
75
|
+
|
76
|
+
* LibXML
|
77
|
+
|
78
|
+
== INSTALL:
|
79
|
+
|
80
|
+
* rake install_gem
|
81
|
+
|
82
|
+
== LICENSE:
|
83
|
+
|
84
|
+
(The New BSD License)
|
85
|
+
|
86
|
+
Copyright (c) 2010, KOJIMA Satoshi
|
87
|
+
All rights reserved.
|
88
|
+
|
89
|
+
Redistribution and use in source and binary forms, with or without
|
90
|
+
modification, are permitted provided that the following conditions are met:
|
91
|
+
|
92
|
+
* Redistributions of source code must retain the above copyright
|
93
|
+
notice, this list of conditions and the following disclaimer.
|
94
|
+
* Redistributions in binary form must reproduce the above copyright
|
95
|
+
notice, this list of conditions and the following disclaimer in the
|
96
|
+
documentation and/or other materials provided with the distribution.
|
97
|
+
* Neither the name of the <organization> nor the
|
98
|
+
names of its contributors may be used to endorse or promote products
|
99
|
+
derived from this software without specific prior written permission.
|
100
|
+
|
101
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
102
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
103
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
104
|
+
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
105
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
106
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
107
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
108
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
109
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
110
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'hoe', '>= 2.1.0'
|
3
|
+
require 'hoe'
|
4
|
+
require 'fileutils'
|
5
|
+
require './lib/gepub'
|
6
|
+
|
7
|
+
Hoe.plugin :newgem
|
8
|
+
# Hoe.plugin :website
|
9
|
+
# Hoe.plugin :cucumberfeatures
|
10
|
+
|
11
|
+
# Generate all the Rake tasks
|
12
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
13
|
+
$hoe = Hoe.spec 'gepub' do
|
14
|
+
self.developer 'KOJIMA Satoshi', 'skoji@skoji.jp'
|
15
|
+
# self.post_install_message = 'PostInstall.txt'
|
16
|
+
# self.rubyforge_name = self.name # TODO this is default value
|
17
|
+
# self.extra_deps = [['activesupport','>= 2.0.2']]
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'newgem/tasks'
|
22
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
23
|
+
|
24
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
25
|
+
# remove_task :default
|
26
|
+
# task :default => [:spec, :features]
|
data/lib/gepub.rb
ADDED
@@ -0,0 +1,225 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'xml/libxml'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
|
7
|
+
module GEPUB
|
8
|
+
class Generator
|
9
|
+
|
10
|
+
attr_accessor :spine
|
11
|
+
|
12
|
+
def initialize(title)
|
13
|
+
@metadata = Hash.new
|
14
|
+
@manifest = Hash.new
|
15
|
+
@spine = Array.new
|
16
|
+
@toc = Array.new
|
17
|
+
@metadata[:title] = title
|
18
|
+
@manifest['ncx'] = { :href => 'toc.ncx', :mediatype => 'application/x-dtbncx+xml' }
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
def title
|
23
|
+
@metadata[:title]
|
24
|
+
end
|
25
|
+
|
26
|
+
def title=(title)
|
27
|
+
@metadata[:title] = title
|
28
|
+
end
|
29
|
+
|
30
|
+
def author
|
31
|
+
@metadata[:creator]
|
32
|
+
end
|
33
|
+
|
34
|
+
def author=(author)
|
35
|
+
@metadata[:creator] = author
|
36
|
+
end
|
37
|
+
|
38
|
+
def publisher
|
39
|
+
@metadata[:publisher]
|
40
|
+
end
|
41
|
+
|
42
|
+
def publisher=(publisher)
|
43
|
+
@metadata[:publisher] = publisher
|
44
|
+
end
|
45
|
+
|
46
|
+
def date
|
47
|
+
@metadata[:date]
|
48
|
+
end
|
49
|
+
|
50
|
+
def date=(date)
|
51
|
+
@metadata[:date] = date
|
52
|
+
end
|
53
|
+
|
54
|
+
def identifier
|
55
|
+
@metadata[:itentifier]
|
56
|
+
end
|
57
|
+
|
58
|
+
def identifier=(id)
|
59
|
+
@metadata[:identifier] = id
|
60
|
+
end
|
61
|
+
|
62
|
+
def addManifest(id, href, mediatype)
|
63
|
+
@manifest[id] = { :href => href, :mediatype => mediatype }
|
64
|
+
end
|
65
|
+
|
66
|
+
def addNav(id, text, ref)
|
67
|
+
@toc.push({ :id => id, :text => text, :ref => ref})
|
68
|
+
end
|
69
|
+
|
70
|
+
def create(destdir)
|
71
|
+
create_mimetype(destdir)
|
72
|
+
create_container(destdir)
|
73
|
+
create_toc(destdir)
|
74
|
+
create_opf(destdir)
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_epub(destdir, targetdir, epubname = @metadata[:title])
|
78
|
+
realtarget = File::expand_path(targetdir)
|
79
|
+
FileUtils.cd("#{destdir}") {
|
80
|
+
|dir|
|
81
|
+
epubname = "#{realtarget}/#{epubname}.epub"
|
82
|
+
%x(zip -0X \"#{epubname}\" \"mimetype\")
|
83
|
+
%x(zip -r9XD \"#{epubname}\" * -x mimetype)
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def mimetype_contents
|
88
|
+
<<EOF
|
89
|
+
application/epub+zip
|
90
|
+
EOF
|
91
|
+
end
|
92
|
+
def create_mimetype(destdir)
|
93
|
+
File.open(destdir + '/mimetype', 'w') {
|
94
|
+
| file |
|
95
|
+
file << mimetype_contents
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
def container_xml
|
100
|
+
<<EOF
|
101
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
102
|
+
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
|
103
|
+
<rootfiles>
|
104
|
+
<rootfile full-path="content.opf" media-type="application/oebps-package+xml"/>
|
105
|
+
</rootfiles>
|
106
|
+
</container>
|
107
|
+
EOF
|
108
|
+
end
|
109
|
+
|
110
|
+
def create_container(destdir)
|
111
|
+
infdir = destdir + "/META-INF"
|
112
|
+
Dir.mkdir(infdir) if !File.exist?(infdir)
|
113
|
+
|
114
|
+
File.open(infdir + "/container.xml", 'w') {
|
115
|
+
|file|
|
116
|
+
file << container_xml
|
117
|
+
}
|
118
|
+
end
|
119
|
+
|
120
|
+
def opf_xml
|
121
|
+
result = XML::Document.new
|
122
|
+
result.root = XML::Node.new('package')
|
123
|
+
package = result.root
|
124
|
+
XML::Namespace.new(package, nil, 'http://www.idpf.org/2007/opf')
|
125
|
+
package['version'] = '2.0'
|
126
|
+
package['unique-identifier'] = 'BookID'
|
127
|
+
|
128
|
+
|
129
|
+
package << metadataelem = XML::Node.new('metadata')
|
130
|
+
XML::Namespace.new(metadataelem, 'opf', 'http://www.idpf.org/2007/opf')
|
131
|
+
XML::Namespace.new(metadataelem, 'dc', "http://purl.org/dc/elements/1.1/")
|
132
|
+
|
133
|
+
metadataelem << XML::Node.new('dc:language', 'ja')
|
134
|
+
|
135
|
+
@metadata.each { | k, v |
|
136
|
+
metadataelem << node = XML::Node.new("dc:#{k}",v)
|
137
|
+
if (k == :identifier)
|
138
|
+
node['id'] = 'BookID'
|
139
|
+
node['opf:scheme'] = 'URL'
|
140
|
+
end
|
141
|
+
}
|
142
|
+
|
143
|
+
package << manifestelem = XML::Node.new('manifest')
|
144
|
+
@manifest.each {|k,v|
|
145
|
+
manifestelem << node = XML::Node.new("item")
|
146
|
+
node['id'] = "#{k}"
|
147
|
+
node['href'] = "#{v[:href]}"
|
148
|
+
node['media-type'] = "#{v[:mediatype]}"
|
149
|
+
}
|
150
|
+
|
151
|
+
package << spineelem = XML::Node.new('spine')
|
152
|
+
spineelem['toc'] = 'ncx'
|
153
|
+
|
154
|
+
@spine.each {
|
155
|
+
|v|
|
156
|
+
spineelem << node = XML::Node.new('itemref')
|
157
|
+
node['idref'] = "#{v}"
|
158
|
+
}
|
159
|
+
|
160
|
+
result.to_s
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
def create_opf(destdir)
|
165
|
+
File.open(destdir + "/content.opf", 'w') { | file | file << opf_xml }
|
166
|
+
end
|
167
|
+
|
168
|
+
def ncx_xml
|
169
|
+
result = XML::Document.new
|
170
|
+
result.root = XML::Node.new('ncx')
|
171
|
+
root = result.root
|
172
|
+
XML::Namespace.new(root, nil, "http://www.daisy.org/z3986/2005/ncx/")
|
173
|
+
root['version'] = "2005-1"
|
174
|
+
root << head = XML::Node.new('head')
|
175
|
+
head << uid = XML::Node.new('meta')
|
176
|
+
uid['name'] = 'dtb:uid'
|
177
|
+
uid['content'] = "#{@metadata[:identifier]}"
|
178
|
+
|
179
|
+
head << depth = XML::Node.new('meta')
|
180
|
+
depth['name'] = 'dtb:depth'
|
181
|
+
depth['content'] = '1'
|
182
|
+
|
183
|
+
head << totalPageCount = XML::Node.new('meta')
|
184
|
+
totalPageCount['name'] = 'dtb:totalPageCount'
|
185
|
+
totalPageCount['content'] = '0'
|
186
|
+
|
187
|
+
head << maxPageNumber = XML::Node.new('meta')
|
188
|
+
maxPageNumber['name'] = 'dtb:maxPageNumber'
|
189
|
+
maxPageNumber['content'] = '0'
|
190
|
+
|
191
|
+
|
192
|
+
root << docTitle = XML::Node.new('docTitle')
|
193
|
+
docTitle << XML::Node.new('text', "#{@metadata[:title]}")
|
194
|
+
|
195
|
+
root << nav_map = XML::Node.new('navMap')
|
196
|
+
count = 1
|
197
|
+
@toc.each {
|
198
|
+
|x|
|
199
|
+
nav_point = XML::Node.new('navPoint')
|
200
|
+
nav_point['id'] = "#{x[:id]}"
|
201
|
+
nav_point['playOrder'] = "#{count}"
|
202
|
+
|
203
|
+
nav_label = XML::Node.new('navLabel')
|
204
|
+
nav_label << XML::Node.new('text', "#{x[:text]}")
|
205
|
+
|
206
|
+
nav_content = XML::Node.new('content')
|
207
|
+
nav_content['src'] = "#{x[:ref]}"
|
208
|
+
count = count + 1
|
209
|
+
|
210
|
+
nav_map << nav_point
|
211
|
+
nav_point << nav_label
|
212
|
+
nav_point << nav_content
|
213
|
+
}
|
214
|
+
result.to_s
|
215
|
+
end
|
216
|
+
|
217
|
+
def create_toc(destdir)
|
218
|
+
File.open(destdir + "/toc.ncx", 'w') {
|
219
|
+
|file|
|
220
|
+
file << ncx_xml
|
221
|
+
}
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
end
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/gepub.rb'}"
|
9
|
+
puts "Loading gepub gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/spec/gepub_spec.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'xml/libxml'
|
5
|
+
|
6
|
+
# for parsing only elements. DO I REALLY NEED THIS !?
|
7
|
+
class LibXML::XML::Node
|
8
|
+
def next_element
|
9
|
+
r = self.next
|
10
|
+
r = r.next while !r.element?
|
11
|
+
r
|
12
|
+
end
|
13
|
+
|
14
|
+
def first_child_element
|
15
|
+
r = self.first
|
16
|
+
r = r.next_element if !r.element?
|
17
|
+
r
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
describe GEPUB::Generator do
|
23
|
+
before do
|
24
|
+
@generator = GEPUB::Generator.new('thetitle')
|
25
|
+
@generator.author = "theauthor"
|
26
|
+
@generator.publisher = "thepublisher"
|
27
|
+
@generator.date = "2010-05-05"
|
28
|
+
@generator.identifier = "http://example.jp/foobar/"
|
29
|
+
|
30
|
+
@generator.addManifest('c1', 'foobar.html', 'foo/bar')
|
31
|
+
@generator.addNav('c2', 'test chapter', 'foobar2.html')
|
32
|
+
@generator.spine.push('c1')
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should have titile" do
|
36
|
+
@generator.title.should == 'thetitle'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should generate correct ncx" do
|
40
|
+
ncx = LibXML::XML::Parser.string(@generator.ncx_xml).parse
|
41
|
+
ncx.root.name.should == 'ncx'
|
42
|
+
ncx.root.attributes['version'].should == '2005-1'
|
43
|
+
ncx.root.namespaces.namespace.href.should == 'http://www.daisy.org/z3986/2005/ncx/'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should have correct head in ncx" do
|
47
|
+
ncx = LibXML::XML::Parser.string(@generator.ncx_xml).parse
|
48
|
+
ncx.root.namespaces.default_prefix='a'
|
49
|
+
|
50
|
+
ncx.find_first('a:head').should_not be_nil
|
51
|
+
|
52
|
+
ncx.find_first("a:head/a:meta[@name='dtb:uid']")['content'].should == "http://example.jp/foobar/"
|
53
|
+
|
54
|
+
ncx.find_first("a:head/a:meta[@name='dtb:depth']").should_not be_nil
|
55
|
+
ncx.find_first("a:head/a:meta[@name='dtb:totalPageCount']").should_not be_nil
|
56
|
+
ncx.find_first("a:head/a:meta[@name='dtb:maxPageNumber']").should_not be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should have correct ncx doctitle" do
|
60
|
+
ncx = LibXML::XML::Parser.string(@generator.ncx_xml).parse
|
61
|
+
ncx.root.namespaces.default_prefix='a'
|
62
|
+
|
63
|
+
ncx.root.find_first('a:docTitle').should_not be_nil
|
64
|
+
ncx.root.find_first('a:docTitle/a:text').content.should == 'thetitle'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should correct ncx navmap" do
|
68
|
+
ncx = LibXML::XML::Parser.string(@generator.ncx_xml).parse
|
69
|
+
ncx.root.namespaces.default_prefix='a'
|
70
|
+
|
71
|
+
ncx.root.find_first('a:navMap').should_not be_nil
|
72
|
+
nav_point = ncx.root.find_first('a:navMap/a:navPoint')
|
73
|
+
nav_point['id'].should == 'c2'
|
74
|
+
nav_point['playOrder'].should == '1'
|
75
|
+
|
76
|
+
nav_point.find_first('a:navLabel/a:text').content.should == 'test chapter'
|
77
|
+
nav_point.find_first('a:content')['src'] == 'foobar2.html'
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should create correct opf" do
|
82
|
+
opf = LibXML::XML::Parser.string(@generator.opf_xml).parse
|
83
|
+
opf.root.namespaces.default_prefix='a'
|
84
|
+
|
85
|
+
opf.root.name.should == 'package'
|
86
|
+
opf.root.namespaces.namespace.href.should == 'http://www.idpf.org/2007/opf'
|
87
|
+
opf.root['version'] == '2.0'
|
88
|
+
opf.root['unique-identifier'] == 'http://example.jp/foobar/'
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
it "should have correct metadata in opf" do
|
93
|
+
opf = LibXML::XML::Parser.string(@generator.opf_xml).parse
|
94
|
+
opf.root.namespaces.default_prefix='a'
|
95
|
+
|
96
|
+
metadata = opf.find_first('a:metadata')
|
97
|
+
metadata.find_first('dc:language').content.should == 'ja'
|
98
|
+
# TODO checking metadatas...
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should have correct manifest and spine in opf" do
|
102
|
+
opf = LibXML::XML::Parser.string(@generator.opf_xml).parse
|
103
|
+
opf.root.namespaces.default_prefix='a'
|
104
|
+
|
105
|
+
manifest = opf.find_first('a:manifest')
|
106
|
+
manifest.find_first('a:item')['id'].should == 'c1'
|
107
|
+
manifest.find_first('a:item')['href'].should == 'foobar.html'
|
108
|
+
manifest.find_first('a:item')['media-type'].should == 'foo/bar'
|
109
|
+
|
110
|
+
spine = opf.find_first('a:spine')
|
111
|
+
spine['toc'].should == 'ncx'
|
112
|
+
spine.find_first('a:itemref')['idref'].should == 'c1'
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
data/tasks/rspec.rake
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'spec'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
5
|
+
require 'spec'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'spec/rake/spectask'
|
9
|
+
rescue LoadError
|
10
|
+
puts <<-EOS
|
11
|
+
To use rspec for testing you must install rspec gem:
|
12
|
+
gem install rspec
|
13
|
+
EOS
|
14
|
+
exit(0)
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Run the specs under spec/models"
|
18
|
+
Spec::Rake::SpecTask.new do |t|
|
19
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
20
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gepub
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- KOJIMA Satoshi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-05-05 00:00:00 +09:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rubyforge
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.4
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.6.0
|
34
|
+
version:
|
35
|
+
description: a good-enough EPUB generator library.
|
36
|
+
email:
|
37
|
+
- skoji@skoji.jp
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files:
|
43
|
+
- History.txt
|
44
|
+
- Manifest.txt
|
45
|
+
files:
|
46
|
+
- History.txt
|
47
|
+
- Manifest.txt
|
48
|
+
- README.rdoc
|
49
|
+
- Rakefile
|
50
|
+
- lib/gepub.rb
|
51
|
+
- lib/gepub/generator.rb
|
52
|
+
- script/console
|
53
|
+
- script/destroy
|
54
|
+
- script/generate
|
55
|
+
- spec/gepub_spec.rb
|
56
|
+
- spec/spec.opts
|
57
|
+
- spec/spec_helper.rb
|
58
|
+
- tasks/rspec.rake
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://github.com/skoji/gepub
|
61
|
+
licenses: []
|
62
|
+
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options:
|
65
|
+
- --main
|
66
|
+
- README.rdoc
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
version:
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
version:
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project: gepub
|
84
|
+
rubygems_version: 1.3.5
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: a good-enough EPUB generator library.
|
88
|
+
test_files: []
|
89
|
+
|