gepub 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -1
- data/.travis.yml +6 -0
- data/README.rdoc +9 -55
- data/bin/gepuber +11 -6
- data/examples/generate_example.rb +52 -0
- data/examples/image1.jpg +0 -0
- data/gepub.gemspec +3 -4
- data/lib/gepub/book.rb +154 -176
- data/lib/gepub/gepuber.rb +6 -2
- data/lib/gepub/item.rb +66 -7
- data/lib/gepub/manifest.rb +78 -0
- data/lib/gepub/meta.rb +119 -0
- data/lib/gepub/metadata.rb +230 -0
- data/lib/gepub/package.rb +232 -0
- data/lib/gepub/spine.rb +112 -0
- data/lib/gepub/version.rb +1 -1
- data/lib/gepub/xml_util.rb +25 -0
- data/lib/gepub.rb +16 -0
- data/spec/example_spec.rb +53 -0
- data/spec/fixtures/epubcheck-3.0b4/COPYING.txt +19 -0
- data/spec/fixtures/epubcheck-3.0b4/README.txt +61 -0
- data/spec/fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar +0 -0
- data/spec/fixtures/epubcheck-3.0b4/jing_license.txt +12 -0
- data/spec/fixtures/epubcheck-3.0b4/lib/commons-compress-1.2.jar +0 -0
- data/spec/fixtures/epubcheck-3.0b4/lib/cssparser-0.9.6.jar +0 -0
- data/spec/fixtures/epubcheck-3.0b4/lib/jing.jar +0 -0
- data/spec/fixtures/epubcheck-3.0b4/lib/sac-1.3.jar +0 -0
- data/spec/fixtures/epubcheck-3.0b4/lib/saxon9he.jar +0 -0
- data/spec/fixtures/testdata/image1.jpg +0 -0
- data/spec/fixtures/testdata/test.opf +60 -0
- data/spec/gepub_spec.rb +57 -17
- data/spec/gepuber_spec.rb +8 -8
- data/spec/manifest_spec.rb +36 -0
- data/spec/metadata_spec.rb +170 -0
- data/spec/package_spec.rb +98 -0
- data/spec/spine_spec.rb +41 -0
- metadata +53 -23
- data/examples/example.rb +0 -49
data/spec/gepub_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
3
|
require 'rubygems'
|
3
4
|
require 'nokogiri'
|
@@ -39,25 +40,42 @@ end
|
|
39
40
|
|
40
41
|
describe GEPUB::Book do
|
41
42
|
before do
|
42
|
-
@book = GEPUB::Book.new('
|
43
|
-
@book.
|
43
|
+
@book = GEPUB::Book.new('OEPBS/package.opf')
|
44
|
+
@book.title = 'thetitle'
|
45
|
+
@book.creator = "theauthor"
|
44
46
|
@book.contributor = "contributors contributors!"
|
45
47
|
@book.publisher = "thepublisher"
|
46
48
|
@book.date = "2010-05-05"
|
47
49
|
@book.identifier = "http://example.jp/foobar/"
|
48
|
-
@book.
|
49
|
-
item1 = @book.
|
50
|
+
@book.language = 'ja'
|
51
|
+
item1 = @book.add_item('text/foobar.xhtml',nil, 'c1')
|
50
52
|
item1.add_content(StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml"><head><title>c1</title></head><body><p>the first page</p></body></html>'))
|
51
53
|
@book.spine.push(item1)
|
52
54
|
|
53
|
-
item2 = @book.add_ordered_item('text/barbar.
|
55
|
+
item2 = @book.add_ordered_item('text/barbar.xhtml',
|
54
56
|
StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml"><head><title>c2</title></head><body><p>second page, whith is test chapter.</p></body></html>'),
|
55
|
-
|
56
|
-
|
57
|
+
'c2')
|
58
|
+
item2.toc_text 'test chapter'
|
59
|
+
|
60
|
+
nav_string = <<EOF
|
61
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
|
62
|
+
<head></head>
|
63
|
+
<body>
|
64
|
+
<nav epub:type="toc" id="toc">
|
65
|
+
<h1>Table of contents</h1>
|
66
|
+
<ol>
|
67
|
+
<li><a href="foobar.xhtml">Chapter 1</a> </li>
|
68
|
+
<li> <a href="barbar.xhtml">Chapter 2</a></li>
|
69
|
+
</ol>
|
70
|
+
</nav>
|
71
|
+
</body>
|
72
|
+
</html>
|
73
|
+
EOF
|
74
|
+
item3 = @book.add_ordered_item('text/nav.html', StringIO.new(nav_string), 'nav').add_property('nav')
|
57
75
|
end
|
58
76
|
|
59
77
|
it "should have titile" do
|
60
|
-
@book.title.should == 'thetitle'
|
78
|
+
@book.title.to_s.should == 'thetitle'
|
61
79
|
end
|
62
80
|
|
63
81
|
it "should generate correct ncx" do
|
@@ -99,9 +117,9 @@ describe GEPUB::Book do
|
|
99
117
|
it "should create correct opf" do
|
100
118
|
opf = Nokogiri::XML.parse(@book.opf_xml).root
|
101
119
|
opf.name.should == 'package'
|
102
|
-
opf.namespaces['xmlns'] == 'http://www.idpf.org/2007/opf'
|
103
|
-
opf['version'] == '
|
104
|
-
opf['unique-identifier'] == '
|
120
|
+
opf.namespaces['xmlns'].should == 'http://www.idpf.org/2007/opf'
|
121
|
+
opf['version'].should == '3.0'
|
122
|
+
opf['unique-identifier'].should == 'BookId'
|
105
123
|
end
|
106
124
|
|
107
125
|
it "should have correct metadata in opf" do
|
@@ -115,9 +133,8 @@ describe GEPUB::Book do
|
|
115
133
|
opf = Nokogiri::XML.parse(@book.opf_xml).root
|
116
134
|
|
117
135
|
manifest = opf.at_xpath('xmlns:manifest')
|
118
|
-
manifest.at_xpath('xmlns:item')['
|
119
|
-
manifest.at_xpath('xmlns:item')['
|
120
|
-
manifest.at_xpath('xmlns:item')['media-type'].should == 'application/xhtml+xml'
|
136
|
+
manifest.at_xpath('xmlns:item[@id="c1"]')['href'].should == 'text/foobar.xhtml'
|
137
|
+
manifest.at_xpath('xmlns:item[@id="c1"]')['media-type'].should == 'application/xhtml+xml'
|
121
138
|
|
122
139
|
spine = opf.at_xpath('xmlns:spine')
|
123
140
|
spine['toc'].should == 'ncx'
|
@@ -125,8 +142,7 @@ describe GEPUB::Book do
|
|
125
142
|
end
|
126
143
|
|
127
144
|
it "should have correct cover image id" do
|
128
|
-
item = @book.
|
129
|
-
@book.specify_cover_image(item)
|
145
|
+
item = @book.add_item("img/img.jpg").cover_image
|
130
146
|
|
131
147
|
opf = Nokogiri::XML.parse(@book.opf_xml).root
|
132
148
|
|
@@ -138,7 +154,31 @@ describe GEPUB::Book do
|
|
138
154
|
it "should generate correct epub" do
|
139
155
|
epubname = File.join(File.dirname(__FILE__), 'testepub.epub')
|
140
156
|
@book.generate_epub(epubname)
|
141
|
-
|
157
|
+
jar = File.join(File.dirname(__FILE__), 'fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar')
|
158
|
+
system 'java', '-jar', jar, epubname
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should generate correct epub2.0" do
|
162
|
+
epubname = File.join(File.dirname(__FILE__), 'testepub2.epub')
|
163
|
+
|
164
|
+
@book = GEPUB::Book.new('OEPBS/package.opf', { 'version' => '2.0'} )
|
165
|
+
@book.title = 'thetitle'
|
166
|
+
@book.creator = "theauthor"
|
167
|
+
@book.contributor = "contributors contributors!"
|
168
|
+
@book.publisher = "thepublisher"
|
169
|
+
@book.date = "2010-05-05"
|
170
|
+
@book.identifier = "http://example.jp/foobar/"
|
171
|
+
@book.language = 'ja'
|
172
|
+
item1 = @book.add_item('text/foobar.xhtml',nil, 'c1')
|
173
|
+
item1.add_content(StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml"><head><title>c1</title></head><body><p>the first page</p></body></html>'))
|
174
|
+
@book.spine.push(item1)
|
175
|
+
item2 = @book.add_ordered_item('text/barbar.xhtml',
|
176
|
+
StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml"><head><title>c2</title></head><body><p>second page, whith is test chapter.</p></body></html>'),
|
177
|
+
'c2')
|
178
|
+
item2.toc_text 'test chapter'
|
179
|
+
@book.generate_epub(epubname)
|
180
|
+
jar = File.join(File.dirname(__FILE__), 'fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar')
|
181
|
+
system 'java', '-jar', jar, epubname
|
142
182
|
end
|
143
183
|
|
144
184
|
end
|
data/spec/gepuber_spec.rb
CHANGED
@@ -8,16 +8,16 @@ describe GEPUB::Gepuber do
|
|
8
8
|
gepuber = GEPUB::Gepuber.new({})
|
9
9
|
gepuber.texts.should == ['[0-9]*.{xhtml,html}']
|
10
10
|
gepuber.resources.should == ['*.css', 'img/*']
|
11
|
-
gepuber.title.should == ""
|
11
|
+
gepuber.title.to_s.should == ""
|
12
12
|
gepuber.table_of_contents.should == {}
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should read config hash" do
|
16
16
|
conf =
|
17
17
|
{
|
18
|
-
:
|
18
|
+
:language => 'ja',
|
19
19
|
:title => 'theTitle',
|
20
|
-
:
|
20
|
+
:creator => 'theAuthor',
|
21
21
|
:publisher => 'thePublisher',
|
22
22
|
:date => '2011-03-11',
|
23
23
|
:identifier => 'http://skoji.jp/gepuber/2011-03-11.0.0',
|
@@ -34,11 +34,11 @@ describe GEPUB::Gepuber do
|
|
34
34
|
}
|
35
35
|
|
36
36
|
gepuber = GEPUB::Gepuber.new(conf )
|
37
|
-
gepuber.title.should == "theTitle"
|
38
|
-
gepuber.
|
39
|
-
gepuber.
|
40
|
-
gepuber.publisher.should == "thePublisher"
|
41
|
-
gepuber.date.should == "2011-03-11"
|
37
|
+
gepuber.title.to_s.should == "theTitle"
|
38
|
+
gepuber.language.to_s.should == "ja"
|
39
|
+
gepuber.creator.to_s.should == "theAuthor"
|
40
|
+
gepuber.publisher.to_s.should == "thePublisher"
|
41
|
+
gepuber.date.to_s.should == "2011-03-11"
|
42
42
|
gepuber.identifier.should == 'http://skoji.jp/gepuber/2011-03-11.0.0'
|
43
43
|
gepuber.epubname.should == 'gepub_00'
|
44
44
|
gepuber.coverimg.should == 'cover.gif'
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'nokogiri'
|
5
|
+
|
6
|
+
describe GEPUB::Manifest do
|
7
|
+
context 'parse existing opf' do
|
8
|
+
before do
|
9
|
+
@manifest = GEPUB::Package.parse_opf(File.open(File.dirname(__FILE__) + '/fixtures/testdata/test.opf'), '/package.opf').instance_eval{ @manifest }
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should be parsed' do
|
13
|
+
@manifest.item_list.size.should == 9
|
14
|
+
@manifest.item_list['ncx'].href.should == 'toc.ncx'
|
15
|
+
@manifest.item_list['ncx'].media_type.should == 'application/x-dtbncx+xml'
|
16
|
+
@manifest.item_list['cover'].href.should == 'cover/cover.xhtml'
|
17
|
+
@manifest.item_list['cover'].media_type.should == 'application/xhtml+xml'
|
18
|
+
@manifest.item_list['cover-image'].href.should == 'img/cover.jpg'
|
19
|
+
@manifest.item_list['cover-image'].media_type.should == 'image/jpeg'
|
20
|
+
@manifest.item_list['cover-image'].properties[0].should == 'cover-image'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
context 'generate new opf' do
|
24
|
+
it 'should generate xml' do
|
25
|
+
manifest = GEPUB::Manifest.new
|
26
|
+
manifest.add_item('ncx', 'toc.ncx', 'application/x-dtbncx+xml')
|
27
|
+
builder = Nokogiri::XML::Builder.new { |xml|
|
28
|
+
xml.package('xmlns' => "http://www.idpf.org/2007/opf",'version' => "3.0",'unique-identifier' => "pub-id",'xml:lang' => "ja") {
|
29
|
+
manifest.to_xml(xml)
|
30
|
+
}
|
31
|
+
}
|
32
|
+
xml = Nokogiri::XML::Document.parse(builder.to_xml)
|
33
|
+
xml.xpath("//xmlns:item[@id='ncx' and @href='toc.ncx' and @media-type='application/x-dtbncx+xml']").size.should == 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'nokogiri'
|
5
|
+
|
6
|
+
describe GEPUB::Metadata do
|
7
|
+
it 'should be initialized' do
|
8
|
+
metadata = GEPUB::Metadata.new
|
9
|
+
metadata.ns_prefix(GEPUB::XMLUtil::DC_NS).should == 'dc'
|
10
|
+
metadata.ns_prefix(GEPUB::XMLUtil::OPF_NS).should be_nil
|
11
|
+
end
|
12
|
+
it 'should be initialized with version 2.0' do
|
13
|
+
metadata = GEPUB::Metadata.new('2.0')
|
14
|
+
metadata.ns_prefix(GEPUB::XMLUtil::DC_NS).should == 'dc'
|
15
|
+
metadata.ns_prefix(GEPUB::XMLUtil::OPF_NS).should == 'opf'
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'Parse Existing OPF' do
|
19
|
+
before do
|
20
|
+
@metadata = GEPUB::Package.parse_opf(File.open(File.dirname(__FILE__) + '/fixtures/testdata/test.opf'), '/package.opf').instance_eval{ @metadata }
|
21
|
+
end
|
22
|
+
it 'should parse title' do
|
23
|
+
@metadata.main_title.should == 'TheTitle'
|
24
|
+
@metadata.title_list.size.should == 2
|
25
|
+
@metadata.title.to_s.should == 'TheTitle'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should parse title-type' do
|
29
|
+
@metadata.title_list[0].refiner_list('title-type').size.should == 1
|
30
|
+
@metadata.title_list[0].refiner_list('title-type')[0].content.should == 'main'
|
31
|
+
@metadata.title_list[1].refiner_list('title-type').size.should == 1
|
32
|
+
@metadata.title_list[1].refiner_list('title-type')[0].content.should == 'collection'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should parse identifier' do
|
36
|
+
@metadata.identifier_list.size.should == 2
|
37
|
+
@metadata.identifier.to_s.should == 'urn:uuid:1234567890'
|
38
|
+
@metadata.identifier_list[0].content.should == 'urn:uuid:1234567890'
|
39
|
+
@metadata.identifier_list[0].refiner('identifier-type').to_s.should == 'uuid'
|
40
|
+
@metadata.identifier_list[1].content.should == 'http://example.jp/epub/test/url'
|
41
|
+
@metadata.identifier_list[1].refiner('identifier-type').to_s.should == 'uri'
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should parse OPF2.0 meta node' do
|
45
|
+
@metadata.oldstyle_meta.size.should == 1
|
46
|
+
@metadata.oldstyle_meta[0].name == 'meta'
|
47
|
+
@metadata.oldstyle_meta[0]['name'] == 'cover'
|
48
|
+
@metadata.oldstyle_meta[0]['content'] == 'cover-image'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'Generate New OPF' do
|
53
|
+
it 'should write and read identifier' do
|
54
|
+
metadata = GEPUB::Metadata.new
|
55
|
+
metadata.add_identifier 'the_set_identifier', 'pub-id'
|
56
|
+
metadata.identifier.to_s.should == 'the_set_identifier'
|
57
|
+
metadata.identifier_list[0]['id'].should == 'pub-id'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should write and read identifier with identifier-type' do
|
61
|
+
metadata = GEPUB::Metadata.new
|
62
|
+
metadata.add_identifier 'http://example.jp/book/url', 'pub-id', 'uri'
|
63
|
+
metadata.identifier.to_s.should == 'http://example.jp/book/url'
|
64
|
+
metadata.identifier_list[0]['id'].should == 'pub-id'
|
65
|
+
metadata.identifier_list[0].identifier_type.to_s.should == 'uri'
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should write and read title' do
|
69
|
+
metadata = GEPUB::Metadata.new
|
70
|
+
metadata.add_title('The Main Title')
|
71
|
+
metadata.title.to_s.should == 'The Main Title'
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should write and read title with type' do
|
75
|
+
metadata = GEPUB::Metadata.new
|
76
|
+
metadata.add_title('The Main Title', 'maintitle', GEPUB::TITLE_TYPE::MAIN)
|
77
|
+
metadata.title.to_s.should == 'The Main Title'
|
78
|
+
metadata.title.title_type.to_s.should == 'main'
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should write and read multipletitle with type' do
|
82
|
+
metadata = GEPUB::Metadata.new
|
83
|
+
metadata.add_title('The Main Title', 'maintitle', GEPUB::TITLE_TYPE::MAIN)
|
84
|
+
metadata.add_title('The Book Series', 'series', GEPUB::TITLE_TYPE::COLLECTION).set_group_position(1)
|
85
|
+
metadata.title.to_s.should == 'The Main Title'
|
86
|
+
metadata.title.title_type.to_s.should == 'main'
|
87
|
+
|
88
|
+
metadata.title_list[1].to_s.should == 'The Book Series'
|
89
|
+
metadata.title_list[1].title_type.to_s.should == 'collection'
|
90
|
+
metadata.title_list[1].group_position.to_s.should == '1'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should handle alternate-script metadata of creator, not using method chain' do
|
94
|
+
metadata = GEPUB::Metadata.new
|
95
|
+
metadata.add_creator('TheCreator', 'author', 'aut').set_display_seq(1).set_file_as('Creator, The').add_alternates({ 'ja-JP' => '作成者' })
|
96
|
+
metadata.creator.to_s.should == 'TheCreator'
|
97
|
+
metadata.creator.to_s('ja').should == '作成者'
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should handle alternate-script metadata of creator, not using method chain' do
|
101
|
+
metadata = GEPUB::Metadata.new
|
102
|
+
m = metadata.add_creator('TheCreator', 'author', 'aut')
|
103
|
+
m.display_seq = 1
|
104
|
+
m.file_as = 'Creator, The'
|
105
|
+
m.add_alternates({ 'ja-JP' => '作成者' })
|
106
|
+
|
107
|
+
metadata.creator.to_s.should == 'TheCreator'
|
108
|
+
metadata.creator.to_s('ja').should == '作成者'
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should detect duplicate id' do
|
112
|
+
metadata = GEPUB::Metadata.new
|
113
|
+
metadata.add_creator('TheCreator', 'id', 'aut')
|
114
|
+
lambda { metadata.add_title('TheTitle', 'id') }.should raise_error(RuntimeError, "id 'id' is already in use.")
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should generate empty metadata xml' do
|
118
|
+
metadata = GEPUB::Metadata.new
|
119
|
+
builder = Nokogiri::XML::Builder.new { |xml|
|
120
|
+
xml.package('xmlns' => "http://www.idpf.org/2007/opf",'version' => "3.0",'unique-identifier' => "pub-id",'xml:lang' => "ja") {
|
121
|
+
metadata.to_xml(xml)
|
122
|
+
}
|
123
|
+
}
|
124
|
+
xml = Nokogiri::XML::Document.parse(builder.to_xml).at_xpath('//xmlns:metadata', { 'xmlns' => GEPUB::XMLUtil::OPF_NS})
|
125
|
+
xml.namespaces['xmlns:dc'].should == GEPUB::XMLUtil::DC_NS
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should generate metadata with id xml' do
|
129
|
+
metadata = GEPUB::Metadata.new
|
130
|
+
metadata.add_identifier('the_uid', nil)
|
131
|
+
builder = Nokogiri::XML::Builder.new { |xml|
|
132
|
+
xml.package('xmlns' => "http://www.idpf.org/2007/opf",'version' => "3.0",'unique-identifier' => "pub-id",'xml:lang' => "ja") {
|
133
|
+
metadata.to_xml(xml)
|
134
|
+
}
|
135
|
+
}
|
136
|
+
Nokogiri::XML::Document.parse(builder.to_xml).at_xpath('//dc:identifier', metadata.instance_eval {@namespaces}).content.should == 'the_uid'
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should generate metadata with creator refiner' do
|
140
|
+
metadata = GEPUB::Metadata.new
|
141
|
+
metadata.add_creator('TheCreator', nil, 'aut').set_display_seq(1).set_file_as('Creator, The').add_alternates({ 'ja-JP' => '作成者' })
|
142
|
+
builder = Nokogiri::XML::Builder.new { |xml|
|
143
|
+
xml.package('xmlns' => "http://www.idpf.org/2007/opf",'version' => "3.0",'unique-identifier' => "pub-id",'xml:lang' => "ja") {
|
144
|
+
metadata.to_xml(xml)
|
145
|
+
}
|
146
|
+
}
|
147
|
+
xml = Nokogiri::XML::Document.parse(builder.to_xml)
|
148
|
+
ns = metadata.instance_eval { @namespaces }
|
149
|
+
xml.at_xpath('//dc:creator', ns).content.should == 'TheCreator'
|
150
|
+
id = xml.at_xpath('//dc:creator', ns)['id']
|
151
|
+
xml.at_xpath("//xmlns:meta[@refines='##{id}' and @property='role']").content.should == 'aut'
|
152
|
+
xml.at_xpath("//xmlns:meta[@refines='##{id}' and @property='display-seq']").content.should == '1'
|
153
|
+
xml.at_xpath("//xmlns:meta[@refines='##{id}' and @property='file-as']").content.should == 'Creator, The'
|
154
|
+
xml.at_xpath("//xmlns:meta[@refines='##{id}' and @property='alternate-script' and @xml:lang='ja-JP']").content.should == '作成者'
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should generate metadata with old style meta tag' do
|
158
|
+
metadata = GEPUB::Metadata.new
|
159
|
+
metadata.add_creator('TheCreator', nil, 'aut').set_display_seq(1).set_file_as('Creator, The').add_alternates({ 'ja-JP' => '作成者' })
|
160
|
+
metadata.add_oldstyle_meta(nil, { 'name' => 'cover', 'content' => 'cover.jpg' })
|
161
|
+
builder = Nokogiri::XML::Builder.new { |xml|
|
162
|
+
xml.package('xmlns' => "http://www.idpf.org/2007/opf",'version' => "3.0",'unique-identifier' => "pub-id",'xml:lang' => "ja") {
|
163
|
+
metadata.to_xml(xml)
|
164
|
+
}
|
165
|
+
}
|
166
|
+
xml = Nokogiri::XML::Document.parse(builder.to_xml)
|
167
|
+
xml.xpath("//xmlns:meta[@name='cover' and @content='cover.jpg']").size.should == 1
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'nokogiri'
|
5
|
+
|
6
|
+
describe GEPUB::Package do
|
7
|
+
it 'should be initialized' do
|
8
|
+
opf = GEPUB::Package.new('/package.opf')
|
9
|
+
opf.ns_prefix(GEPUB::XMLUtil::OPF_NS).should == 'xmlns'
|
10
|
+
end
|
11
|
+
context 'parse existing opf' do
|
12
|
+
it 'should be initialized with opf' do
|
13
|
+
opf = GEPUB::Package.parse_opf(File.open(File.dirname(__FILE__) + '/fixtures/testdata/test.opf'), '/package.opf')
|
14
|
+
opf.ns_prefix(GEPUB::XMLUtil::OPF_NS).should == 'xmlns'
|
15
|
+
opf['version'].should == '3.0'
|
16
|
+
opf['unique-identifier'].should == 'pub-id'
|
17
|
+
opf['xml:lang'].should == 'ja'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
context 'generate new opf' do
|
21
|
+
it 'should generate opf' do
|
22
|
+
opf = GEPUB::Package.new('OEBPS/package.opf') {
|
23
|
+
|opf|
|
24
|
+
opf.set_main_id('http://example.jp', 'BookID', 'url')
|
25
|
+
opf['xml:lang'] = 'ja'
|
26
|
+
|
27
|
+
# metadata add: style 1
|
28
|
+
opf.metadata.add_title('EPUB3 Sample', nil, GEPUB::TITLE_TYPE::MAIN) {
|
29
|
+
|title|
|
30
|
+
title.display_seq = 1
|
31
|
+
title.file_as = 'Sample EPUB3'
|
32
|
+
title.add_alternates(
|
33
|
+
'en' => 'EPUB3 Sample (Japanese)',
|
34
|
+
'el' => 'EPUB3 δείγμα (Ιαπωνικά)',
|
35
|
+
'th' => 'EPUB3 ตัวอย่าง (ญี่ปุ่น)')
|
36
|
+
}
|
37
|
+
# metadata add: style2
|
38
|
+
opf.metadata.add_title('これでEPUB3もばっちり', nil, GEPUB::TITLE_TYPE::SUBTITLE).set_display_seq(2).add_alternates('en' => 'you need nothing but this book!')
|
39
|
+
opf.metadata.add_creator('小嶋智').set_display_seq(1).add_alternates('en' => 'KOJIMA Satoshi')
|
40
|
+
opf.metadata.add_contributor('電書部').set_display_seq(1).add_alternates('en' => 'Denshobu')
|
41
|
+
opf.metadata.add_contributor('アサガヤデンショ').set_display_seq(2).add_alternates('en' => 'Asagaya Densho')
|
42
|
+
opf.metadata.add_contributor('湘南電書鼎談').set_display_seq(3).add_alternates('en' => 'Shonan Densho Teidan')
|
43
|
+
opf.metadata.add_contributor('電子雑誌トルタル').set_display_seq(4).add_alternates('en' => 'eMagazine Torutaru')
|
44
|
+
opf.add_item('img/image1.jpg')
|
45
|
+
opf.add_item('img/cover.jpg').add_property('cover-image')
|
46
|
+
opf.ordered {
|
47
|
+
opf.add_item('text/chapter1.xhtml')
|
48
|
+
opf.add_item('text/chapter2.xhtml')
|
49
|
+
}
|
50
|
+
}
|
51
|
+
xml = Nokogiri::XML::Document.parse opf.opf_xml
|
52
|
+
xml.root.name.should == 'package'
|
53
|
+
xml.root.namespaces.size.should == 1
|
54
|
+
xml.root.namespaces['xmlns'].should == GEPUB::XMLUtil::OPF_NS
|
55
|
+
xml.root['version'].should == '3.0'
|
56
|
+
xml.root['lang'].should == 'ja'
|
57
|
+
# TODO: should check all elements
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should generate opf2.0' do
|
61
|
+
opf = GEPUB::Package.new('OEBPS/package.opf', { 'version' => '2.0'}) {
|
62
|
+
|opf|
|
63
|
+
opf.set_main_id('http://example.jp', 'BookID', 'url')
|
64
|
+
opf['xml:lang'] = 'ja'
|
65
|
+
|
66
|
+
# metadata add: style 1
|
67
|
+
opf.metadata.add_title('EPUB3 Sample', nil, GEPUB::TITLE_TYPE::MAIN) {
|
68
|
+
|title|
|
69
|
+
title.display_seq = 1
|
70
|
+
title.file_as = 'Sample EPUB3'
|
71
|
+
title.add_alternates(
|
72
|
+
'en' => 'EPUB3 Sample (Japanese)',
|
73
|
+
'el' => 'EPUB3 δείγμα (Ιαπωνικά)',
|
74
|
+
'th' => 'EPUB3 ตัวอย่าง (ญี่ปุ่น)')
|
75
|
+
}
|
76
|
+
# metadata add: style2
|
77
|
+
opf.metadata.add_title('これでEPUB3もばっちり', nil, GEPUB::TITLE_TYPE::SUBTITLE).set_display_seq(2).add_alternates('en' => 'you need nothing but this book!')
|
78
|
+
opf.metadata.add_creator('小嶋智').set_display_seq(1).add_alternates('en' => 'KOJIMA Satoshi')
|
79
|
+
opf.metadata.add_contributor('電書部').set_display_seq(1).add_alternates('en' => 'Denshobu')
|
80
|
+
opf.metadata.add_contributor('アサガヤデンショ').set_display_seq(2).add_alternates('en' => 'Asagaya Densho')
|
81
|
+
opf.metadata.add_contributor('湘南電書鼎談').set_display_seq(3).add_alternates('en' => 'Shonan Densho Teidan')
|
82
|
+
opf.metadata.add_contributor('電子雑誌トルタル').set_display_seq(4).add_alternates('en' => 'eMagazine Torutaru')
|
83
|
+
opf.add_item('img/image1.jpg')
|
84
|
+
opf.ordered {
|
85
|
+
opf.add_item('text/chapter1.xhtml')
|
86
|
+
opf.add_item('text/chapter2.xhtml')
|
87
|
+
}
|
88
|
+
}
|
89
|
+
xml = Nokogiri::XML::Document.parse opf.opf_xml
|
90
|
+
xml.root.name.should == 'package'
|
91
|
+
xml.root.namespaces.size.should == 1
|
92
|
+
xml.root.namespaces['xmlns'].should == GEPUB::XMLUtil::OPF_NS
|
93
|
+
xml.root['version'].should == '2.0'
|
94
|
+
xml.root['lang'].should == 'ja'
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
data/spec/spine_spec.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'nokogiri'
|
5
|
+
|
6
|
+
describe GEPUB::Spine do
|
7
|
+
context 'parse existing opf' do
|
8
|
+
before do
|
9
|
+
@spine = GEPUB::Package.parse_opf(File.open(File.dirname(__FILE__) + '/fixtures/testdata/test.opf'), '/package.opf').instance_eval{ @spine }
|
10
|
+
end
|
11
|
+
it 'should be parsed' do
|
12
|
+
@spine.toc.should == 'ncx'
|
13
|
+
@spine.page_progression_direction == 'ltr'
|
14
|
+
@spine.itemref_list.size.should == 4
|
15
|
+
@spine.itemref_list[0].idref.should == 'cover'
|
16
|
+
@spine.itemref_list[0].linear.should == 'no'
|
17
|
+
@spine.itemref_list[1].idref.should == 'toc'
|
18
|
+
@spine.itemref_list[1].linear.should == 'yes'
|
19
|
+
@spine.itemref_list[2].idref.should == 'chap1'
|
20
|
+
@spine.itemref_list[2].linear.should == 'yes'
|
21
|
+
@spine.itemref_list[3].idref.should == 'nav'
|
22
|
+
@spine.itemref_list[3].linear.should == 'no'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
context 'generate new opf' do
|
26
|
+
it 'should generate xml' do
|
27
|
+
spine = GEPUB::Spine.new
|
28
|
+
spine.toc = 'ncx'
|
29
|
+
spine.push(GEPUB::Item.new('the_id', 'OEBPS/foo.xhtml')).set_linear('no')
|
30
|
+
builder = Nokogiri::XML::Builder.new { |xml|
|
31
|
+
xml.package('xmlns' => "http://www.idpf.org/2007/opf",'version' => "3.0",'unique-identifier' => "pub-id",'xml:lang' => "ja") {
|
32
|
+
spine.to_xml(xml)
|
33
|
+
}
|
34
|
+
}
|
35
|
+
xml = Nokogiri::XML::Document.parse(builder.to_xml)
|
36
|
+
xml.at_xpath('//xmlns:spine')['toc'].should == 'ncx'
|
37
|
+
xml.xpath("//xmlns:itemref[@idref='the_id' and @linear='no']").size.should == 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
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.
|
4
|
+
version: 0.6.0
|
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-
|
12
|
+
date: 2012-02-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70114096287200 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,21 +21,10 @@ dependencies:
|
|
21
21
|
version: '2'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: epubcheck
|
27
|
-
requirement: &70335555212540 !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
|
-
requirements:
|
30
|
-
- - ! '>='
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 0.1.0
|
33
|
-
type: :development
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *70335555212540
|
24
|
+
version_requirements: *70114096287200
|
36
25
|
- !ruby/object:Gem::Dependency
|
37
26
|
name: nokogiri
|
38
|
-
requirement: &
|
27
|
+
requirement: &70114091707580 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
29
|
requirements:
|
41
30
|
- - ! '>='
|
@@ -43,19 +32,20 @@ dependencies:
|
|
43
32
|
version: 1.5.0
|
44
33
|
type: :runtime
|
45
34
|
prerelease: false
|
46
|
-
version_requirements: *
|
35
|
+
version_requirements: *70114091707580
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
37
|
name: rubyzip
|
49
|
-
requirement: &
|
38
|
+
requirement: &70114091706120 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
41
|
- - ! '>='
|
53
42
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.9.
|
43
|
+
version: 0.9.6
|
55
44
|
type: :runtime
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
58
|
-
description:
|
46
|
+
version_requirements: *70114091706120
|
47
|
+
description: gepub is a EPUB parser/generator. Generates EPUB2 opf. will support EPUB3
|
48
|
+
parse/generation
|
59
49
|
email:
|
60
50
|
- skoji@mac.com
|
61
51
|
executables:
|
@@ -65,22 +55,46 @@ extra_rdoc_files: []
|
|
65
55
|
files:
|
66
56
|
- .document
|
67
57
|
- .gitignore
|
58
|
+
- .travis.yml
|
68
59
|
- Gemfile
|
69
60
|
- README.rdoc
|
70
61
|
- Rakefile
|
71
62
|
- bin/gepuber
|
72
|
-
- examples/
|
63
|
+
- examples/generate_example.rb
|
64
|
+
- examples/image1.jpg
|
73
65
|
- gepub.gemspec
|
74
66
|
- lib/gepub.rb
|
75
67
|
- lib/gepub/book.rb
|
76
68
|
- lib/gepub/gepuber.rb
|
77
69
|
- lib/gepub/item.rb
|
70
|
+
- lib/gepub/manifest.rb
|
71
|
+
- lib/gepub/meta.rb
|
72
|
+
- lib/gepub/metadata.rb
|
73
|
+
- lib/gepub/package.rb
|
74
|
+
- lib/gepub/spine.rb
|
78
75
|
- lib/gepub/version.rb
|
76
|
+
- lib/gepub/xml_util.rb
|
77
|
+
- spec/example_spec.rb
|
78
|
+
- spec/fixtures/epubcheck-3.0b4/COPYING.txt
|
79
|
+
- spec/fixtures/epubcheck-3.0b4/README.txt
|
80
|
+
- spec/fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar
|
81
|
+
- spec/fixtures/epubcheck-3.0b4/jing_license.txt
|
82
|
+
- spec/fixtures/epubcheck-3.0b4/lib/commons-compress-1.2.jar
|
83
|
+
- spec/fixtures/epubcheck-3.0b4/lib/cssparser-0.9.6.jar
|
84
|
+
- spec/fixtures/epubcheck-3.0b4/lib/jing.jar
|
85
|
+
- spec/fixtures/epubcheck-3.0b4/lib/sac-1.3.jar
|
86
|
+
- spec/fixtures/epubcheck-3.0b4/lib/saxon9he.jar
|
79
87
|
- spec/fixtures/testdata/0.html
|
80
88
|
- spec/fixtures/testdata/1.html
|
89
|
+
- spec/fixtures/testdata/image1.jpg
|
90
|
+
- spec/fixtures/testdata/test.opf
|
81
91
|
- spec/gepub_spec.rb
|
82
92
|
- spec/gepuber_spec.rb
|
93
|
+
- spec/manifest_spec.rb
|
94
|
+
- spec/metadata_spec.rb
|
95
|
+
- spec/package_spec.rb
|
83
96
|
- spec/spec_helper.rb
|
97
|
+
- spec/spine_spec.rb
|
84
98
|
homepage: http://github.com/skoji/gepub
|
85
99
|
licenses: []
|
86
100
|
post_install_message:
|
@@ -104,10 +118,26 @@ rubyforge_project: gepub
|
|
104
118
|
rubygems_version: 1.8.11
|
105
119
|
signing_key:
|
106
120
|
specification_version: 3
|
107
|
-
summary: a
|
121
|
+
summary: a generic EPUB parser/generator.
|
108
122
|
test_files:
|
123
|
+
- spec/example_spec.rb
|
124
|
+
- spec/fixtures/epubcheck-3.0b4/COPYING.txt
|
125
|
+
- spec/fixtures/epubcheck-3.0b4/README.txt
|
126
|
+
- spec/fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar
|
127
|
+
- spec/fixtures/epubcheck-3.0b4/jing_license.txt
|
128
|
+
- spec/fixtures/epubcheck-3.0b4/lib/commons-compress-1.2.jar
|
129
|
+
- spec/fixtures/epubcheck-3.0b4/lib/cssparser-0.9.6.jar
|
130
|
+
- spec/fixtures/epubcheck-3.0b4/lib/jing.jar
|
131
|
+
- spec/fixtures/epubcheck-3.0b4/lib/sac-1.3.jar
|
132
|
+
- spec/fixtures/epubcheck-3.0b4/lib/saxon9he.jar
|
109
133
|
- spec/fixtures/testdata/0.html
|
110
134
|
- spec/fixtures/testdata/1.html
|
135
|
+
- spec/fixtures/testdata/image1.jpg
|
136
|
+
- spec/fixtures/testdata/test.opf
|
111
137
|
- spec/gepub_spec.rb
|
112
138
|
- spec/gepuber_spec.rb
|
139
|
+
- spec/manifest_spec.rb
|
140
|
+
- spec/metadata_spec.rb
|
141
|
+
- spec/package_spec.rb
|
113
142
|
- spec/spec_helper.rb
|
143
|
+
- spec/spine_spec.rb
|