gepub 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,232 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+
4
+ module GEPUB
5
+ # Holds data in opf file.
6
+ class Package
7
+ include XMLUtil
8
+ attr_accessor :path, :metadata, :manifest, :spine, :epub_backward_compat, :contents_prefix
9
+
10
+ class IDPool
11
+ def initialize
12
+ @pool = {}
13
+ @counter = {}
14
+ end
15
+
16
+ def counter(prefix,suffix)
17
+ @counter[prefix + '////' + suffix]
18
+ end
19
+
20
+ def set_counter(prefix,suffix,val)
21
+ @counter[prefix + '////' + suffix] = val
22
+ end
23
+
24
+ def generate_key(param = {})
25
+ while (true)
26
+ prefix = param[:prefix] || ''
27
+ suffix = param[:suffix] || ''
28
+ count = [ param[:start] || 1, counter(prefix,suffix) || 1].max
29
+ if param[:without_count]
30
+ k = prefix + suffix
31
+ count -= 1
32
+ param[:without_count] = nil
33
+ else
34
+ k = prefix + count.to_s + suffix
35
+ end
36
+ if @pool[k].nil?
37
+ set_counter(prefix,suffix, count + 1)
38
+ return k
39
+ end
40
+ count += 1
41
+ end
42
+
43
+ end
44
+
45
+ def [](k)
46
+ @pool[k]
47
+ end
48
+ def []=(k,v)
49
+ @pool[k] = v
50
+ end
51
+ end
52
+
53
+ # parse OPF data. opf should be io or string object.
54
+ def self.parse_opf(opf, path)
55
+ Package.new(path) {
56
+ |package|
57
+ package.instance_eval {
58
+ @path = path
59
+ @xml = Nokogiri::XML::Document.parse(opf)
60
+ @namespaces = @xml.root.namespaces
61
+ @attributes = attr_to_hash(@xml.root.attributes)
62
+ @metadata = Metadata.parse(@xml.at_xpath("//#{ns_prefix(OPF_NS)}:metadata"), @attributes['version'], @id_pool)
63
+ @manifest = Manifest.parse(@xml.at_xpath("//#{ns_prefix(OPF_NS)}:manifest"), @attributes['version'], @id_pool)
64
+ @spine = Spine.parse(@xml.at_xpath("//#{ns_prefix(OPF_NS)}:spine"), @attributes['version'], @id_pool)
65
+ }
66
+ }
67
+ end
68
+
69
+ def initialize(path='OEBPS/package.opf', attributes={})
70
+ @path = path
71
+ if File.extname(@path) != '.opf'
72
+ if @path.size > 0
73
+ @path = [path,'package.opf'].join('/')
74
+ end
75
+ end
76
+ @contents_prefix = File.dirname(@path).sub(/^\.$/,'')
77
+ @contents_prefix = @contents_prefix + '/' if @contents_prefix.size > 0
78
+ @namespaces = {'xmlns' => OPF_NS }
79
+ @attributes = attributes
80
+ @attributes['version'] ||= '3.0'
81
+ @id_pool = IDPool.new
82
+ @metadata = Metadata.new(version)
83
+ @manifest = Manifest.new(version)
84
+ @spine = Spine.new(version)
85
+ @epub_backward_compat = true
86
+ yield self if block_given?
87
+ end
88
+
89
+ ['version', 'unique-identifier', 'xml:lang', 'dir', 'prefix', 'id'].each {
90
+ |name|
91
+ methodbase = name.gsub('-','_').sub('xml:lang', 'lang')
92
+ define_method(methodbase + '=') { |val| @attributes[name] = val }
93
+ define_method('set_' + methodbase) { |val| @attributes[name] = val }
94
+ define_method(methodbase) { @attributes[name] }
95
+ }
96
+
97
+ def [](x)
98
+ @attributes[x]
99
+ end
100
+
101
+ def []=(k,v)
102
+ @attributes[k] = v
103
+ end
104
+
105
+
106
+ def identifier
107
+ @metadata.identifier_by_id(unique_identifier)
108
+ end
109
+
110
+ def identifier=(identifier)
111
+ set_main_id(identifier, nil, 'URL')
112
+ end
113
+
114
+ def set_main_id(identifier, id = nil, type = nil)
115
+ set_unique_identifier(id || @id_pool.generate_key(:prefix => 'BookId', :without_count => true))
116
+ @metadata.add_identifier identifier, unique_identifier, type
117
+ end
118
+
119
+ def specify_cover(item)
120
+ # ... not smart. should create old-meta on generating xml
121
+ @metadata.add_oldstyle_meta(nil, { 'name' => 'cover', 'content' => item.id })
122
+ item.add_properties 'cover-image'
123
+ end
124
+
125
+ def add_item(href, io = nil, id = nil, attributes = {})
126
+ id ||= @id_pool.generate_key(:prefix=>'item', :suffix=>'_'+ File.basename(href,'.*'), :without_count => true)
127
+ item = @manifest.add_item(id, href, nil, attributes)
128
+ item.add_content(io) unless io.nil?
129
+ @spine.push(item) if @ordered
130
+ yield item if block_given?
131
+ item
132
+ end
133
+
134
+ def ordered
135
+ raise 'need block.' if !block_given?
136
+ @ordered = true
137
+ yield
138
+ @ordered = nil
139
+ end
140
+
141
+ def add_ordered_item(href, io = nil, id = nil, attributes = {})
142
+ raise 'do not call add_ordered_item within ordered block.' if @ordered
143
+ item = add_item(href, io, id, attributes)
144
+ @spine.push(item)
145
+
146
+ item
147
+ end
148
+
149
+
150
+ def method_missing(name, *args)
151
+ Metadata::CONTENT_NODE_LIST.each {
152
+ |x|
153
+ case name.to_s
154
+ when x, "#{x}_list", "set_#{x}", "#{x}=", "add_#{x}"
155
+ return @metadata.send(name, *args)
156
+ end
157
+ }
158
+ super
159
+ end
160
+
161
+ def author=(val)
162
+ warn 'author= is deprecated. please use #creator'
163
+ @metadata.creator= val
164
+ end
165
+
166
+ def author
167
+ warn '#author is deprecated. please use #creator'
168
+ @metadata.creator
169
+ end
170
+
171
+ def specify_cover_image(item)
172
+ warn 'specify_cover_image is deprecated. please use Item#cover_image'
173
+ item.cover_image
174
+ end
175
+
176
+ def locale=(val)
177
+ warn 'locale= is deprecated. please use #language='
178
+ @metadata.language = val
179
+ end
180
+
181
+ def locale
182
+ warn '#locale is deprecated. please use #language'
183
+ @metadata.language
184
+ end
185
+
186
+ def version=(val)
187
+ @attributes['version'] = val
188
+ @metadata.opf_version = val
189
+ @manifest.opf_version = val
190
+ @spine.opf_version = val
191
+ end
192
+
193
+ def epub_version=(val)
194
+ warn 'epub_version= is deprecated. please use #version='
195
+ @attributes['version'] = val
196
+ end
197
+
198
+ def epub_version
199
+ warn 'epub_version is deprecated. please use #version'
200
+ version
201
+ end
202
+
203
+ def opf_xml
204
+ if version.to_f < 3.0 || @epub_backward_compat
205
+ spine.toc ||= 'ncx'
206
+ if @metadata.oldstyle_meta.select {
207
+ |meta|
208
+ meta['name'] == 'cover'
209
+ }.length == 0
210
+
211
+ @manifest.item_list.each {
212
+ |k, item|
213
+ if item.properties && item.properties.member?('cover-image')
214
+ @metadata.add_oldstyle_meta(nil, 'name' => 'cover', 'content' => item.id)
215
+ end
216
+ }
217
+ end
218
+ end
219
+ builder = Nokogiri::XML::Builder.new {
220
+ |xml|
221
+ xml.package(@namespaces.merge(@attributes)) {
222
+ @metadata.to_xml(xml)
223
+ @manifest.to_xml(xml)
224
+ @spine.to_xml(xml)
225
+ }
226
+ }
227
+ builder.to_xml
228
+ end
229
+
230
+
231
+ end
232
+ end
@@ -0,0 +1,112 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+ module GEPUB
4
+ class Spine
5
+ include XMLUtil
6
+ attr_accessor :opf_version
7
+ class Itemref
8
+ def self.create(parent, attributes = {})
9
+ Itemref.new(attributes['idref'], parent, attributes.reject{|k,v| k == 'idref'})
10
+ end
11
+
12
+ def initialize(idref, parent = nil, attributes = {})
13
+ if attributes['properties'].class == String
14
+ attributes['properties'] = attributes['properties'].split(' ')
15
+ end
16
+ @attributes = {'idref' => idref}.merge(attributes)
17
+ @parent = parent
18
+ @parent.register_itemref(self) unless @parent.nil?
19
+ self
20
+ end
21
+
22
+ ['idref', 'linear', 'id', 'properties'].each { |name|
23
+ methodbase = name.gsub('-','_')
24
+ define_method(methodbase + '=') { |val| @attributes[name] = val }
25
+ define_method('set_' + methodbase) { |val| @attributes[name] = val }
26
+ define_method(methodbase) { @attributes[name] }
27
+ }
28
+
29
+ def [](x)
30
+ @attributes[x]
31
+ end
32
+
33
+ def []=(x,y)
34
+ @attributes[x] = y
35
+ end
36
+
37
+ def add_property(property)
38
+ (@attributes['properties'] ||=[]) << property
39
+ end
40
+
41
+ def to_xml(builder)
42
+ builder.itemref(@attributes)
43
+ end
44
+ end
45
+
46
+ def self.parse(spine_xml, opf_version = '3.0', id_pool = Package::IDPool.new)
47
+ Spine.new(opf_version, id_pool) {
48
+ |spine|
49
+ spine.instance_eval {
50
+ @xml = spine_xml
51
+ @namespaces = @xml.namespaces
52
+ @attributes = attr_to_hash(@xml.attributes)
53
+ @item_refs = []
54
+ @xml.xpath("//#{ns_prefix(OPF_NS)}:spine/#{ns_prefix(OPF_NS)}:itemref", @namespaces).map {
55
+ |itemref|
56
+ i = Itemref.create(self, attr_to_hash(itemref.attributes))
57
+ @item_refs << i
58
+ }
59
+ }
60
+ }
61
+ end
62
+
63
+ def initialize(opf_version = '3.0', id_pool = Package::IDPool.new)
64
+ @id_pool = id_pool
65
+ @attributes = {}
66
+ @item_refs = []
67
+ @opf_version = opf_version
68
+ yield self if block_given?
69
+ end
70
+
71
+ ['id', 'toc', 'page-progression-direction'].each { |name|
72
+ methodbase = name.gsub('-','_')
73
+ define_method(methodbase + '=') { |val| @attributes[name] = val }
74
+ define_method('set_' + methodbase) { |val| @attributes[name] = val }
75
+ define_method(methodbase) { @attributes[name] }
76
+ }
77
+
78
+ def itemref_list
79
+ @item_refs.dup
80
+ end
81
+
82
+ def push(item)
83
+ @item_refs << i = Itemref.new(item.id, self)
84
+ i
85
+ end
86
+
87
+ def <<(item)
88
+ push item
89
+ end
90
+
91
+ def to_xml(builder)
92
+ builder.spine(@attributes) {
93
+ @item_refs.each {
94
+ |ref|
95
+ ref.to_xml(builder)
96
+ }
97
+ }
98
+ end
99
+
100
+ def register_itemref(itemref)
101
+ raise "id '#{itemref.id}' is already in use." if @id_pool[itemref.id]
102
+ @id_pool[itemref.id] = true unless itemref.id.nil?
103
+ end
104
+
105
+ def unregister_itemref(itemref)
106
+ @item_refs.delete itemref
107
+ @id_pool[itemref.id] = nil
108
+ end
109
+
110
+
111
+ end
112
+ end
data/lib/gepub/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module GEPUB
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -0,0 +1,25 @@
1
+ module GEPUB
2
+ module XMLUtil
3
+ OPF_NS = 'http://www.idpf.org/2007/opf'
4
+ DC_NS = 'http://purl.org/dc/elements/1.1/'
5
+ def ns_prefix(ns)
6
+ prefix = raw_prefix(ns)
7
+ prefix.nil? ? nil : prefix.sub(/^xmlns:/,'')
8
+ end
9
+
10
+ def raw_prefix(ns)
11
+ @namespaces.key(ns)
12
+ end
13
+
14
+ def attr_to_hash(nokogiri_attrs)
15
+ attributes = {}
16
+ nokogiri_attrs.each {
17
+ |k,v|
18
+ attributes[k] = v.to_s
19
+ }
20
+ attributes['xml:lang'] = attributes['lang'];
21
+ attributes.delete('lang')
22
+ attributes
23
+ end
24
+ end
25
+ end
data/lib/gepub.rb CHANGED
@@ -1,6 +1,22 @@
1
+ if !({}.respond_to? 'key')
2
+ class Hash
3
+ def key(x)
4
+ index(x)
5
+ end
6
+ end
7
+ end
8
+
1
9
  require 'gepub/version'
10
+ require 'gepub/xml_util'
11
+ require 'gepub/meta'
12
+ require 'gepub/metadata'
13
+ require 'gepub/manifest'
14
+ require 'gepub/spine'
15
+ require 'gepub/package'
2
16
  require 'gepub/item'
3
17
  require 'gepub/book'
4
18
  require 'gepub/gepuber'
5
19
 
6
20
 
21
+
22
+
@@ -0,0 +1,53 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.dirname(__FILE__) + '/spec_helper.rb'
3
+ require 'rubygems'
4
+
5
+ describe 'GEPUB usage' do
6
+ context 'On generating EPUB' do
7
+ it 'should generate simple EPUB3 with rather complicated matadata' do
8
+ book = GEPUB::Book.new
9
+ book.set_main_id('http:/example.jp/bookid_in_url', 'BookID', 'URL')
10
+ book.language = 'ja'
11
+
12
+ # you can add metadata and its property using block
13
+ book.add_title('GEPUBサンプル文書', nil, GEPUB::TITLE_TYPE::MAIN) {
14
+ |title|
15
+ title.lang = 'ja'
16
+ title.file_as = 'GEPUB Sample Book'
17
+ title.display_seq = 1
18
+ title.add_alternates(
19
+ 'en' => 'GEPUB Sample Book (Japanese)',
20
+ 'el' => 'GEPUB δείγμα (Ιαπωνικά)',
21
+ 'th' => 'GEPUB ตัวอย่าง (ญี่ปุ่น)')
22
+ }
23
+ # you can do the same thing using method chain
24
+ book.add_title('これはあくまでサンプルです',nil, GEPUB::TITLE_TYPE::SUBTITLE).set_display_seq(1).add_alternates('en' => 'this book is just a sample.')
25
+ book.add_creator('小嶋智') {
26
+ |creator|
27
+ creator.display_seq = 1
28
+ creator.add_alternates('en' => 'KOJIMA Satoshi')
29
+ }
30
+ book.add_contributor('電書部').set_display_seq(1).add_alternates('en' => 'Denshobu')
31
+ book.add_contributor('アサガヤデンショ').set_display_seq(2).add_alternates('en' => 'Asagaya Densho')
32
+ book.add_contributor('湘南電書鼎談').set_display_seq(3).add_alternates('en' => 'Shonan Densho Teidan')
33
+ book.add_contributor('電子雑誌トルタル').set_display_seq(4).add_alternates('en' => 'eMagazine Torutaru')
34
+
35
+ imgfile = File.join(File.dirname(__FILE__), 'fixtures', 'testdata', 'image1.jpg')
36
+ File.open(imgfile) do
37
+ |io|
38
+ book.add_item('img/image1.jpg',io).cover_image
39
+ end
40
+
41
+ # within ordered block, add_item will be added to spine.
42
+ book.ordered {
43
+ book.add_item('text/chap1.xhtml').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>')).toc_text('Chapter 1')
44
+ book.add_item('text/chap1-1.xhtml').add_content(StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml"><head><title>c2</title></head><body><p>the second page</p></body></html>')) # do not appear on table of contents
45
+ book.add_item('text/chap2.xhtml').add_content(StringIO.new('<html xmlns="http://www.w3.org/1999/xhtml"><head><title>c3</title></head><body><p>the third page</p></body></html>')).toc_text('Chapter 2')
46
+ }
47
+ epubname = File.join(File.dirname(__FILE__), 'example_test.epub')
48
+ book.generate_epub(epubname)
49
+ jar = File.join(File.dirname(__FILE__), 'fixtures/epubcheck-3.0b4/epubcheck-3.0b4.jar')
50
+ system 'java' '-jar', jar, epubname
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2007 Adobe Systems Incorporated
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
@@ -0,0 +1,61 @@
1
+ This folder contains the distribution of epubcheck project.
2
+
3
+ EpubCheck is a tool to validate IDPF Epub files. It can detect many
4
+ types of errors in Epub. OCF container structure, OPF and OPS mark-up,
5
+ and internal reference consistency are checked. EpubCheck can be run
6
+ as a standalone command-line tool, installed as a web application or
7
+ used as a library.
8
+
9
+ Epubcheck project home: http://code.google.com/p/epubcheck/
10
+
11
+ BUILDING
12
+
13
+ To build epubcheck from the sources you need Java Development Kit (JDK) 1.5 or above
14
+ and Apache ant (http://ant.apache.org/) 1.6 or above installed
15
+
16
+ Run
17
+
18
+ ant -f build.xml
19
+
20
+ RUNNING
21
+
22
+ To run the tool you need Java Runtime (1.5 or above). Any OS should do. Run
23
+ it from the command line:
24
+
25
+ java -jar epubcheck-x.x.x.jar file.epub
26
+
27
+ All detected errors are simply printed to stderr.
28
+
29
+ USING AS A LIBRARY
30
+
31
+ You can also use EpubCheck as a library in your Java application. EpubCheck
32
+ public interfaces can be found in com.adobe.epubcheck.api package. EpubCheck
33
+ class can be used to instantiate a validation engine. Use one of its
34
+ constructors and then call validate() method. Report is an interface that
35
+ you can implement to get a list of the errors and warnings reported by the
36
+ validation engine (instead of the error list being printed out).
37
+
38
+ LICENSING
39
+
40
+ See COPYING.txt
41
+
42
+ AUTHORS
43
+
44
+ Peter Sorotokin
45
+ Garth Conboy
46
+ Markus Gylling
47
+ Piotr Kula
48
+
49
+ Most of the EpubCheck functionality comes from the schema validation tool Jing
50
+ and schemas that were developed by IDPF and DAISY. EpubCheck development was
51
+ largely done at Adobe Systems.
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+
@@ -0,0 +1,12 @@
1
+ Jing Copying Conditions
2
+
3
+ Copyright (c) 2001-2003 Thai Open Source Software Center Ltd
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7
+
8
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10
+ * Neither the name of the Thai Open Source Software Center Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Binary file
@@ -0,0 +1,60 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+
3
+ <package xmlns="http://www.idpf.org/2007/opf" version="3.0" unique-identifier="pub-id" xml:lang="ja">
4
+ <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" >
5
+ <dc:identifier id="pub-id">urn:uuid:1234567890</dc:identifier>
6
+ <meta refines="#pub-id" property="identifier-type" scheme="xsd:string">uuid</meta>
7
+ <dc:identifier id="pub-id2">http://example.jp/epub/test/url</dc:identifier>
8
+ <meta refines="#pub-id2" property="identifier-type" scheme="xsd:string">uri</meta>
9
+
10
+ <dc:title id="series">Series Title</dc:title>
11
+ <meta refines="#series" property="title-type">collection</meta>
12
+ <meta refines="#series" property="display-seq">2</meta>
13
+ <dc:title id="title">TheTitle</dc:title>
14
+ <meta refines="#title" property="title-type">main</meta>
15
+ <meta refines="#title" property="display-seq">1</meta>
16
+
17
+ <dc:language id="pub-lang">ja</dc:language>
18
+
19
+ <dc:creator id="author1">最初の著者</dc:creator>
20
+ <meta refines="#author1" property="role" scheme="marc:relators">aut</meta>
21
+ <meta refines="#author1" property="display-seq">1</meta>
22
+ <meta refines="#author1" property="file-as">さいしょのちょしゃ</meta>
23
+ <dc:creator id="author3">三人目</dc:creator>
24
+ <meta refines="#author3" property="role" scheme="marc:relators">prg</meta>
25
+ <meta refines="#author3" property="display-seq">3</meta>
26
+ <meta refines="#author3" property="file-as">さんにんめ</meta>
27
+ <dc:creator id="author2">ふたりめ</dc:creator>
28
+ <meta refines="#author2" property="role" scheme="marc:relators">aut</meta>
29
+ <meta refines="#author2" property="display-seq">2</meta>
30
+ <meta refines="#author2" property="file-as">ふたりめ</meta>
31
+
32
+
33
+ <dc:publisher id="publisher">小嶋智</dc:publisher>
34
+
35
+ <meta property="dcterms:issued" id="issued">2012-02-12T15:00:00Z</meta>
36
+ <meta property="dcterms:modified" id="modified">2012-02-12T19:00:00Z</meta>
37
+ <meta name="cover" content="cover-image" />
38
+ </metadata>
39
+
40
+
41
+ <manifest>
42
+ <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />
43
+ <item id="cover" href="cover/cover.xhtml" media-type="application/xhtml+xml" />
44
+ <item id="cover-image" href="img/cover.jpg" properties="cover-image" media-type="image/jpeg" />
45
+ <item id="toc" href="toc.xhtml" media-type="application/xhtml+xml" />
46
+ <item id="nav" href="nav.xhtml" properties="nav" media-type="application/xhtml+xml" />
47
+ <item id="chap1" href="chap1.xhtml" media-type="application/xhtml+xml" />
48
+ <item id="css" href="style/default.css" media-type="text/css" />
49
+ <item id="object" href="img/test.png" media-type="image/png" />
50
+ <item id="object2" href="resource/image.jpg" media-type="image/jpg" />
51
+ </manifest>
52
+
53
+ <spine toc="ncx" page-progression-direction="ltr">
54
+ <itemref idref="cover" linear="no" />
55
+ <itemref idref="toc" linear="yes" />
56
+ <itemref idref="chap1" linear="yes" />
57
+ <itemref idref="nav" linear="no" />
58
+ </spine>
59
+
60
+ </package>