thepub 0.0.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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009, 2010 Dmitri Goutnik, Invisible Llama
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,18 @@
1
+ = thepub
2
+
3
+ Nothing more than a direct extraction of [Repub's](http://github.com/invisiblellama/repub) epub module and associated tests.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but
13
+ bump version in a commit by itself I can ignore when I pull)
14
+ * Send me a pull request. Bonus points for topic branches.
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2010 Dmitri Goutnik, Invisible Llama. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "thepub"
8
+ gem.summary = %Q{Extraction of Repub's epub module and associated tests}
9
+ gem.description = %Q{Extraction of Repub's epub module and associated tests}
10
+ gem.email = "hi@williammelody.com"
11
+ gem.homepage = "http://github.com/autodata/thepub"
12
+ gem.authors = ["Dmitri Goutnik, Invisible Llama", "William Melody"]
13
+ gem.add_development_dependency "thoughtbot-shoulda"
14
+ gem.add_dependency "nokogiri"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ if File.exist?('VERSION')
48
+ version = File.read('VERSION')
49
+ else
50
+ version = ""
51
+ end
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "thepub #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+
3
+ module Thepub
4
+ module Epub
5
+
6
+ # Mixin for stuff that can be added to the ePub package
7
+ #
8
+ module ContainerItem
9
+ attr_accessor :file_path
10
+ attr_accessor :media_type
11
+
12
+ def document?
13
+ ['application/xhtml+xml', 'application/x-dtbook+xml'].include? self.media_type
14
+ end
15
+ end
16
+
17
+ # Wrapper class for ePub items that do not have specialized classes
18
+ # e.g. HTML files, CSSs etc.
19
+ #
20
+ class Item
21
+ include ContainerItem
22
+
23
+ def initialize(file_path, media_type = nil)
24
+ @file_path = file_path.strip
25
+ @media_type = media_type || case @file_path.downcase
26
+ when /.*\.html?$/
27
+ 'application/xhtml+xml'
28
+ when /.*\.css$/
29
+ 'text/css'
30
+ when /.*\.(jpeg|jpg)$/
31
+ 'image/jpeg'
32
+ when /.*\.png$/
33
+ 'image/png'
34
+ when /.*\.gif$/
35
+ 'image/gif'
36
+ when /.*\.svg$/
37
+ 'image/svg+xml'
38
+ when /.*\.ncx$/
39
+ 'application/x-dtbncx+xml'
40
+ when /.*\.opf$/
41
+ 'application/oebps-package+xml'
42
+ else
43
+ raise 'Unknown media type'
44
+ end
45
+ end
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,137 @@
1
+ require 'rubygems'
2
+ require 'builder'
3
+
4
+ module Thepub
5
+ module Epub
6
+
7
+ class NCX
8
+ include ContainerItem
9
+
10
+ def initialize(uid, file_path = 'toc.ncx')
11
+ @file_path = file_path
12
+ @media_type = 'application/x-dtbncx+xml'
13
+ @head = Head.new(uid)
14
+ @doc_title = DocTitle.new('Untitled')
15
+ @nav_map = NavMap.new
16
+ end
17
+
18
+ def title
19
+ @doc_title.text
20
+ end
21
+
22
+ def title=(text)
23
+ @doc_title = DocTitle.new(text)
24
+ end
25
+
26
+ attr_reader :nav_map
27
+
28
+ def to_xml
29
+ out = ''
30
+ builder = Builder::XmlMarkup.new(:target => out)
31
+ builder.instruct!
32
+ builder.declare! :DOCTYPE, :ncx, :PUBLIC, "-//NISO//DTD ncx 2005-1//EN", "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd"
33
+ builder.ncx :xmlns => "http://www.daisy.org/z3986/2005/ncx/", :version => "2005-1" do
34
+ @nav_map.calc_depth_and_play_order
35
+ @head.depth = @nav_map.depth
36
+ @head.to_xml(builder)
37
+ @doc_title.to_xml(builder)
38
+ @nav_map.to_xml(builder)
39
+ end
40
+ out
41
+ end
42
+
43
+ def save
44
+ File.open(@file_path, 'w') do |f|
45
+ f << to_xml
46
+ end
47
+ end
48
+
49
+ class Head < Struct.new(
50
+ :uid
51
+ )
52
+
53
+ attr_accessor :depth
54
+
55
+ def to_xml(builder)
56
+ builder.head do
57
+ builder.meta :name => "dtb:uid", :content => self.uid
58
+ builder.meta :name => "dtb:depth", :content => @depth
59
+ builder.meta :name => "dtb:totalPageCount", :content => 0
60
+ builder.meta :name => "dtb:maxPageNumber", :content => 0
61
+ end
62
+ end
63
+ end
64
+
65
+ class DocTitle < Struct.new(
66
+ :text
67
+ )
68
+
69
+ def to_xml(builder)
70
+ builder.docTitle do
71
+ builder.text self.text
72
+ end
73
+ end
74
+ end
75
+
76
+ class NavPoint < Struct.new(
77
+ :title,
78
+ :src
79
+ )
80
+
81
+ def initialize(title, src, points = nil)
82
+ super(title, src)
83
+ @play_order = 0
84
+ @points = points || []
85
+ end
86
+
87
+ attr_accessor :play_order
88
+ attr_accessor :points
89
+
90
+ def to_xml(builder)
91
+ builder.navPoint :id => point_id(@play_order), :playOrder => @play_order do
92
+ builder.navLabel do
93
+ builder.text self.title
94
+ end
95
+ builder.content :src => self.src
96
+ @points.each { |point| point.to_xml(builder) }
97
+ end
98
+ end
99
+
100
+ private
101
+
102
+ def point_id(play_order)
103
+ "navPoint-#{play_order}"
104
+ end
105
+ end
106
+
107
+ class NavMap < NavPoint
108
+
109
+ def initialize
110
+ super(nil, nil)
111
+ @depth = 1
112
+ end
113
+
114
+ attr_reader :depth
115
+
116
+ def calc_depth_and_play_order
117
+ play_order = 0
118
+ l = lambda do |points, depth|
119
+ @depth = depth if depth > @depth
120
+ points.each do |pt|
121
+ pt.play_order = (play_order += 1)
122
+ l.call(pt.points, depth + 1) unless pt.points.empty?
123
+ end
124
+ end
125
+ l.call(@points, @depth = 1)
126
+ end
127
+
128
+ def to_xml(builder)
129
+ builder.navMap do
130
+ @points.each { |point| point.to_xml(builder) }
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ end
137
+ end
@@ -0,0 +1,62 @@
1
+ require 'rubygems'
2
+ require 'fileutils'
3
+ require 'builder'
4
+
5
+ module Thepub
6
+ module Epub
7
+
8
+ # OEBPS Container Format (OCF) 1.0 wrapper
9
+ # (see http://www.idpf.org/ocf/ocf1.0/download/ocf10.htm)
10
+ #
11
+ class OCF
12
+
13
+ def initialize
14
+ @items = []
15
+ end
16
+
17
+ attr_reader :items
18
+
19
+ def <<(item)
20
+ if item.kind_of? ContainerItem
21
+ @items << item
22
+ elsif item.is_a? String
23
+ @items << Item.new(item)
24
+ else
25
+ raise "Unsupported item class: #{item.class}"
26
+ end
27
+ end
28
+
29
+ def to_xml
30
+ out = ''
31
+ builder = Builder::XmlMarkup.new(:target => out)
32
+ builder.instruct!
33
+ builder.container :xmlns => "urn:oasis:names:tc:opendocument:xmlns:container", :version => "1.0" do
34
+ builder.rootfiles do
35
+ @items.each do |item|
36
+ builder.rootfile 'full-path' => item.file_path, 'media-type' => item.media_type
37
+ end
38
+ end
39
+ end
40
+ out
41
+ end
42
+
43
+ def save
44
+ meta_inf = 'META-INF'
45
+ FileUtils.mkdir_p(meta_inf)
46
+ File.open(File.join(meta_inf, 'container.xml'), 'w') do |f|
47
+ f << to_xml
48
+ end
49
+ end
50
+
51
+ def zip(output_path)
52
+ File.open('mimetype', 'w') do |f|
53
+ f << 'application/epub+zip'
54
+ end
55
+ # mimetype has to be first in the archive
56
+ %x(zip -X9 \"#{output_path}\" mimetype)
57
+ %x(zip -Xr9D \"#{output_path}\" * -xi mimetype)
58
+ end
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,137 @@
1
+ require 'rubygems'
2
+ require 'builder'
3
+
4
+ module Thepub
5
+ module Epub
6
+
7
+ # Open Packaging Format (OPF) 2.0 wrapper
8
+ # (see http://www.idpf.org/2007/opf/OPF_2.0_final_spec.html)
9
+ #
10
+ class OPF
11
+ include ContainerItem
12
+
13
+ def initialize(uid, file_path = 'package.opf')
14
+ @file_path = file_path
15
+ @media_type = 'application/oebps-package+xml'
16
+ @metadata = Metadata.new('Untitled', 'en', uid, Date.today.to_s)
17
+ @items = []
18
+ @ncx = nil
19
+ end
20
+
21
+ class Metadata < Struct.new(
22
+ :title,
23
+ :language,
24
+ :identifier,
25
+ :date,
26
+ :subject,
27
+ :description,
28
+ :relation,
29
+ :creator,
30
+ :publisher,
31
+ :rights
32
+ )
33
+
34
+ def to_xml(builder)
35
+ builder.metadata 'xmlns:dc' => "http://purl.org/dc/elements/1.1/",
36
+ 'xmlns:dcterms' => "http://purl.org/dc/terms/",
37
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
38
+ 'xmlns:opf' => "http://www.idpf.org/2007/opf" do
39
+ # Required elements
40
+ builder.dc :title do
41
+ builder << self.title
42
+ end
43
+ builder.dc :language, 'xsi:type' => "dcterms:RFC3066" do
44
+ builder << self.language
45
+ end
46
+ builder.dc :identifier, :id => 'dcidid', 'opf:scheme' => 'URI' do
47
+ builder << self.identifier
48
+ end
49
+ # Optional elements
50
+ builder.dc :subject do
51
+ builder << self.subject
52
+ end if self.subject
53
+ builder.dc :description do
54
+ builder << self.description
55
+ end if self.description
56
+ builder.dc :relation do
57
+ builder << self.relation
58
+ end if self.relation
59
+ builder.dc :creator do # TODO: roles
60
+ builder << self.creator
61
+ end if self.creator
62
+ builder.dc :publisher do
63
+ builder << self.publisher
64
+ end if self.publisher
65
+ builder.dc :date do
66
+ builder << self.date.to_s
67
+ end if self.date
68
+ builder.dc :rights do
69
+ builder << self.rights
70
+ end if self.rights
71
+ end
72
+ end
73
+ end
74
+
75
+ attr_reader :metadata
76
+ attr_reader :items
77
+
78
+ def <<(item)
79
+ if item.kind_of? NCX
80
+ @ncx = item
81
+ elsif item.kind_of? ContainerItem
82
+ @items << item
83
+ elsif item.is_a? String
84
+ @items << Item.new(item)
85
+ else
86
+ raise "Unsupported item class: #{item.class}"
87
+ end
88
+ end
89
+
90
+ def to_xml
91
+ out = ''
92
+ builder = Builder::XmlMarkup.new(:target => out)
93
+ builder.instruct!
94
+ builder.package :xmlns => "http://www.idpf.org/2007/opf",
95
+ 'unique-identifier' => "dcidid",
96
+ 'version' => "2.0" do
97
+ @metadata.to_xml(builder)
98
+ manifest_to_xml(builder)
99
+ spine_to_xml(builder)
100
+ end
101
+ out
102
+ end
103
+
104
+ def save
105
+ File.open(@file_path, 'w') do |f|
106
+ f << to_xml
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ def item_id(index)
113
+ "item-#{index + 1}"
114
+ end
115
+
116
+ def manifest_to_xml(builder)
117
+ builder.manifest do
118
+ # NCX has fixed id
119
+ builder.item :id => 'ncx', :href => @ncx.file_path, 'media-type' => @ncx.media_type if @ncx
120
+ @items.each_with_index do |item, index|
121
+ builder.item :id => item_id(index), :href => item.file_path, 'media-type' => item.media_type
122
+ end
123
+ end
124
+ end
125
+
126
+ def spine_to_xml(builder)
127
+ # toc attribute points to the NCX item in manifest
128
+ builder.spine :toc => 'ncx' do
129
+ @items.each_with_index do |item, index|
130
+ builder.itemref :idref => item_id(index) if item.document?
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ end
137
+ end
@@ -0,0 +1,4 @@
1
+ require 'thepub/epub/container_item'
2
+ require 'thepub/epub/ocf'
3
+ require 'thepub/epub/opf'
4
+ require 'thepub/epub/ncx'
data/lib/thepub.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'nokogiri'
2
+ require 'thepub/epub'
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'thepub'
8
+
9
+ class Test::Unit::TestCase
10
+ end
data/test/test_ncx.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ class TestToc < Test::Unit::TestCase
4
+ def test_toc_create
5
+ ncx = Thepub::Epub::NCX.new('some-ncx')
6
+ s = ncx.to_xml
7
+ #p s
8
+ doc = Nokogiri::XML.parse(s)
9
+ assert_equal('some-ncx', doc.at("//xmlns:meta[@name='dtb:uid']")['content'])
10
+ assert_equal('1', doc.at("//xmlns:meta[@name='dtb:depth']")['content'])
11
+ assert_equal('0', doc.at("//xmlns:meta[@name='dtb:totalPageCount']")['content'])
12
+ assert_equal('0', doc.at("//xmlns:meta[@name='dtb:maxPageNumber']")['content'])
13
+ assert_equal('Untitled', doc.at("//xmlns:docTitle/xmlns:text").inner_text)
14
+ assert_not_nil(doc.at('//xmlns:navMap'))
15
+ end
16
+
17
+ def test_nav_map
18
+ ncx = Thepub::Epub::NCX.new('some-ncx')
19
+ ncx.nav_map.points << Thepub::Epub::NCX::NavPoint.new('Intro', 'intro.html')
20
+ ncx.nav_map.points << Thepub::Epub::NCX::NavPoint.new('Chapter 1', 'chapter-1.html')
21
+ ncx.nav_map.points << Thepub::Epub::NCX::NavPoint.new('Chapter 2', 'chapter-2.html')
22
+ ncx.nav_map.points[2].points << Thepub::Epub::NCX::NavPoint.new('Chapter 2-1', 'chapter-2-1.html')
23
+ ncx.nav_map.points << Thepub::Epub::NCX::NavPoint.new('Glossary', 'glossary.html')
24
+ ncx.nav_map.points[1].points << Thepub::Epub::NCX::NavPoint.new('Chapter 1-1', 'chapter-1-1.html')
25
+ ncx.nav_map.points[1].points << Thepub::Epub::NCX::NavPoint.new('Chapter 1-2', 'chapter-1-2.html')
26
+ s = ncx.to_xml
27
+ #p s
28
+ doc = Nokogiri::XML.parse(s)
29
+ assert_equal(4, doc.xpath('//xmlns:navMap/xmlns:navPoint').size)
30
+ assert_equal('2', doc.at("//xmlns:meta[@name='dtb:depth']")['content'])
31
+ assert_equal('1', doc.at('//xmlns:navMap/xmlns:navPoint[position()=1]')['playOrder'])
32
+ assert_equal('2', doc.at('//xmlns:navMap/xmlns:navPoint[position()=2]')['playOrder'])
33
+ assert_equal('3', doc.at('//xmlns:navMap/xmlns:navPoint[position()=2]/xmlns:navPoint[position()=1]')['playOrder'])
34
+ assert_equal('5', doc.at('//xmlns:navMap/xmlns:navPoint[position()=3]')['playOrder'])
35
+ assert_equal('navPoint-2', doc.at('//xmlns:navMap/xmlns:navPoint[position()=2]')['id'])
36
+ assert_equal('Chapter 1', doc.at('//xmlns:navMap/xmlns:navPoint[position()=2]/xmlns:navLabel/xmlns:text').inner_text)
37
+ assert_equal('chapter-1.html', doc.at('//xmlns:navMap/xmlns:navPoint[position()=2]/xmlns:content')['src'])
38
+ assert_equal(7, doc.xpath('//xmlns:navMap//xmlns:navPoint').size)
39
+ end
40
+ end
data/test/test_ocf.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+
3
+ class TestContainer < Test::Unit::TestCase
4
+ def test_container_create
5
+ container = Thepub::Epub::OCF.new
6
+ container << 'test.html'
7
+ container << Thepub::Epub::OPF.new('12345')
8
+ s = container.to_xml
9
+ #p s
10
+ doc = Nokogiri::XML.parse(s)
11
+ assert_not_nil(doc.at('rootfile'))
12
+ assert_equal('test.html', doc.at('rootfile[1]')['full-path'])
13
+ assert_equal('application/xhtml+xml', doc.at('rootfile[1]')['media-type'])
14
+ assert_equal('package.opf', doc.at('rootfile[2]')['full-path'])
15
+ assert_equal('application/oebps-package+xml', doc.at('rootfile[2]')['media-type'])
16
+ end
17
+
18
+ def test_container_create_fail
19
+ assert_raise(RuntimeError) do
20
+ # unknown mime type
21
+ container = Thepub::Epub::OCF.new
22
+ container << 'blah.blah'
23
+ end
24
+ end
25
+ end
data/test/test_opf.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+
3
+ class TestContent < Test::Unit::TestCase
4
+ def test_create
5
+ opf = Thepub::Epub::OPF.new('some-opf')
6
+ s = opf.to_xml
7
+ doc = Nokogiri::XML.parse(s)
8
+ #p doc
9
+
10
+ metadata = doc.at('metadata')
11
+ assert_not_nil(metadata)
12
+ assert_equal('some-opf', metadata.xpath('dc:identifier', 'xmlns:dc' => "http://purl.org/dc/elements/1.1/").inner_text)
13
+ assert_equal('Untitled', metadata.xpath('dc:title', 'xmlns:dc' => "http://purl.org/dc/elements/1.1/").inner_text)
14
+ assert_equal('en', metadata.xpath('dc:language', 'xmlns:dc' => "http://purl.org/dc/elements/1.1/").inner_text)
15
+ assert_equal(Date.today.to_s, metadata.xpath('dc:date', 'xmlns:dc' => "http://purl.org/dc/elements/1.1/").inner_text)
16
+ end
17
+
18
+ def test_manifest_create
19
+ opf = Thepub::Epub::OPF.new('some-opf')
20
+ opf << Thepub::Epub::NCX.new('some-ncx')
21
+ s = opf.to_xml
22
+ doc = Nokogiri::XML.parse(s)
23
+ #p doc
24
+
25
+ manifest = doc.at('manifest')
26
+ assert_not_nil(manifest)
27
+ assert_equal(1, manifest.children.size)
28
+ assert_equal('ncx', manifest.at('item[@href="toc.ncx"]')['id'])
29
+ assert_not_nil(doc.at('spine'))
30
+ assert_equal(0, doc.xpath('spine/item').size)
31
+ end
32
+
33
+ def test_manifest_and_spine_items
34
+ opf = Thepub::Epub::OPF.new('some-opf')
35
+ opf << 'style.css'
36
+ opf << 'more-style.css'
37
+ opf << ' logo.jpg '
38
+ opf << 'intro.html'
39
+ opf << ' image.png'
40
+ opf << 'picture.jpeg '
41
+ opf << Thepub::Epub::NCX.new('some-ncx')
42
+ opf << 'chapter-1.html'
43
+ opf << 'glossary.html'
44
+ s = opf.to_xml
45
+ doc = Nokogiri::HTML(s)
46
+ #p doc
47
+
48
+ manifest = doc.at('manifest')
49
+ assert_not_nil(manifest)
50
+ assert_equal(2, manifest.xpath('item[@media-type="text/css"]').size)
51
+ assert_equal(2, manifest.search('item[@media-type="image/jpeg"]').size)
52
+ assert_equal(1, manifest.search('item[@media-type="image/png"]').size)
53
+ # NCX is first and always has id = 'ncx'
54
+ assert_equal('ncx', manifest.at('./item[position()=1]')['id'])
55
+
56
+ spine = doc.at('spine')
57
+ # attribute toc has and id of NCX manifest item
58
+ assert_equal('ncx', spine['toc'])
59
+ assert_equal(3, spine.search('itemref').size)
60
+ assert_equal('item-4', spine.at('./itemref[position()=1]')['idref'])
61
+ assert_equal('item-8', spine.at('./itemref[position()=3]')['idref'])
62
+ end
63
+ end
data/thepub.gemspec ADDED
@@ -0,0 +1,66 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{thepub}
8
+ s.version = "0.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Dmitri Goutnik, Invisible Llama", "William Melody"]
12
+ s.date = %q{2010-02-01}
13
+ s.description = %q{Extraction of Repub's epub module and associated tests}
14
+ s.email = %q{hi@williammelody.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.markdown",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/thepub.rb",
27
+ "lib/thepub/epub.rb",
28
+ "lib/thepub/epub/container_item.rb",
29
+ "lib/thepub/epub/ncx.rb",
30
+ "lib/thepub/epub/ocf.rb",
31
+ "lib/thepub/epub/opf.rb",
32
+ "test/test_helper.rb",
33
+ "test/test_ncx.rb",
34
+ "test/test_ocf.rb",
35
+ "test/test_opf.rb",
36
+ "thepub.gemspec"
37
+ ]
38
+ s.homepage = %q{http://github.com/autodata/thepub}
39
+ s.rdoc_options = ["--charset=UTF-8"]
40
+ s.require_paths = ["lib"]
41
+ s.rubygems_version = %q{1.3.5}
42
+ s.summary = %q{Extraction of Repub's epub module and associated tests}
43
+ s.test_files = [
44
+ "test/test_helper.rb",
45
+ "test/test_ncx.rb",
46
+ "test/test_ocf.rb",
47
+ "test/test_opf.rb"
48
+ ]
49
+
50
+ if s.respond_to? :specification_version then
51
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
52
+ s.specification_version = 3
53
+
54
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
55
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
56
+ s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
57
+ else
58
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
59
+ s.add_dependency(%q<nokogiri>, [">= 0"])
60
+ end
61
+ else
62
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
63
+ s.add_dependency(%q<nokogiri>, [">= 0"])
64
+ end
65
+ end
66
+
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thepub
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Dmitri Goutnik, Invisible Llama
8
+ - William Melody
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2010-02-01 00:00:00 -06:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: thoughtbot-shoulda
18
+ type: :development
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: nokogiri
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ version:
36
+ description: Extraction of Repub's epub module and associated tests
37
+ email: hi@williammelody.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - LICENSE
44
+ - README.markdown
45
+ files:
46
+ - .document
47
+ - .gitignore
48
+ - LICENSE
49
+ - README.markdown
50
+ - Rakefile
51
+ - VERSION
52
+ - lib/thepub.rb
53
+ - lib/thepub/epub.rb
54
+ - lib/thepub/epub/container_item.rb
55
+ - lib/thepub/epub/ncx.rb
56
+ - lib/thepub/epub/ocf.rb
57
+ - lib/thepub/epub/opf.rb
58
+ - test/test_helper.rb
59
+ - test/test_ncx.rb
60
+ - test/test_ocf.rb
61
+ - test/test_opf.rb
62
+ - thepub.gemspec
63
+ has_rdoc: true
64
+ homepage: http://github.com/autodata/thepub
65
+ licenses: []
66
+
67
+ post_install_message:
68
+ rdoc_options:
69
+ - --charset=UTF-8
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ requirements: []
85
+
86
+ rubyforge_project:
87
+ rubygems_version: 1.3.5
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: Extraction of Repub's epub module and associated tests
91
+ test_files:
92
+ - test/test_helper.rb
93
+ - test/test_ncx.rb
94
+ - test/test_ocf.rb
95
+ - test/test_opf.rb