gepub 0.5.0 → 0.6.0
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/.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
|