repub 0.3.3 → 0.3.4

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.
@@ -0,0 +1,136 @@
1
+ require 'rubygems'
2
+ require 'builder'
3
+
4
+ module Repub
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
+ end
19
+
20
+ class Metadata < Struct.new(
21
+ :title,
22
+ :language,
23
+ :identifier,
24
+ :date,
25
+ :subject,
26
+ :description,
27
+ :relation,
28
+ :creator,
29
+ :publisher,
30
+ :rights
31
+ )
32
+
33
+ def to_xml(builder)
34
+ builder.metadata 'xmlns:dc' => "http://purl.org/dc/elements/1.1/",
35
+ 'xmlns:dcterms' => "http://purl.org/dc/terms/",
36
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
37
+ 'xmlns:opf' => "http://www.idpf.org/2007/opf" do
38
+ # Required elements
39
+ builder.dc :title do
40
+ builder << self.title
41
+ end
42
+ builder.dc :language, 'xsi:type' => "dcterms:RFC3066" do
43
+ builder << self.language
44
+ end
45
+ builder.dc :identifier, :id => 'dcidid', 'opf:scheme' => 'URI' do
46
+ builder << self.identifier
47
+ end
48
+ # Optional elements
49
+ builder.dc :subject do
50
+ builder << self.subject
51
+ end if self.subject
52
+ builder.dc :description do
53
+ builder << self.description
54
+ end if self.description
55
+ builder.dc :relation do
56
+ builder << self.relation
57
+ end if self.relation
58
+ builder.dc :creator do # TODO: roles
59
+ builder << self.creator
60
+ end if self.creator
61
+ builder.dc :publisher do
62
+ builder << self.publisher
63
+ end if self.publisher
64
+ builder.dc :date do
65
+ builder << self.date.to_s
66
+ end if self.date
67
+ builder.dc :rights do
68
+ builder << self.rights
69
+ end if self.rights
70
+ end
71
+ end
72
+ end
73
+
74
+ attr_reader :metadata
75
+ attr_reader :items
76
+
77
+ def <<(item)
78
+ if item.kind_of? NCX
79
+ @ncx = item
80
+ elsif item.kind_of? ContainerItem
81
+ @items << item
82
+ elsif item.is_a? String
83
+ @items << Item.new(item)
84
+ else
85
+ raise "Unsupported item class: #{item.class}"
86
+ end
87
+ end
88
+
89
+ def to_xml
90
+ out = ''
91
+ builder = Builder::XmlMarkup.new(:target => out)
92
+ builder.instruct!
93
+ builder.package :xmlns => "http://www.idpf.org/2007/opf",
94
+ 'unique-identifier' => "dcidid",
95
+ 'version' => "2.0" do
96
+ @metadata.to_xml(builder)
97
+ manifest_to_xml(builder)
98
+ spine_to_xml(builder)
99
+ end
100
+ out
101
+ end
102
+
103
+ def save
104
+ File.open(@file_path, 'w') do |f|
105
+ f << to_xml
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ def item_id(index)
112
+ "item-#{index + 1}"
113
+ end
114
+
115
+ def manifest_to_xml(builder)
116
+ builder.manifest do
117
+ # NCX has fixed id
118
+ builder.item :id => 'ncx', :href => @ncx.file_path, 'media-type' => @ncx.media_type if @ncx
119
+ @items.each_with_index do |item, index|
120
+ builder.item :id => item_id(index), :href => item.file_path, 'media-type' => item.media_type
121
+ end
122
+ end
123
+ end
124
+
125
+ def spine_to_xml(builder)
126
+ # toc attribute points to the NCX item in manifest
127
+ builder.spine :toc => 'ncx' do
128
+ @items.each_with_index do |item, index|
129
+ builder.itemref :idref => item_id(index) if item.document?
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ end
136
+ end
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{repub}
5
- s.version = "0.3.3"
5
+ s.version = "0.3.4"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Dmitri Goutnik"]
9
- s.date = %q{2009-07-05}
9
+ s.date = %q{2009-07-17}
10
10
  s.default_executable = %q{repub}
11
11
  s.description = %q{Repub is a simple HTML to ePub converter.
12
12
 
@@ -16,14 +16,14 @@ ePub documents.}
16
16
  s.email = %q{dg@invisiblellama.net}
17
17
  s.executables = ["repub"]
18
18
  s.extra_rdoc_files = ["History.txt", "README.rdoc", "bin/repub"]
19
- s.files = ["History.txt", "README.rdoc", "Rakefile", "TODO", "bin/repub", "lib/repub.rb", "lib/repub/app.rb", "lib/repub/app/builder.rb", "lib/repub/app/fetcher.rb", "lib/repub/app/logger.rb", "lib/repub/app/options.rb", "lib/repub/app/parser.rb", "lib/repub/app/profile.rb", "lib/repub/app/utility.rb", "lib/repub/epub.rb", "lib/repub/epub/container.rb", "lib/repub/epub/content.rb", "lib/repub/epub/toc.rb", "repub.gemspec", "test/data/custom.css", "test/data/invisiblellama.png", "test/data/test.css", "test/data/test.html", "test/epub/test_container.rb", "test/epub/test_content.rb", "test/epub/test_toc.rb", "test/test_builder.rb", "test/test_fetcher.rb", "test/test_logger.rb", "test/test_parser.rb"]
19
+ s.files = ["History.txt", "README.rdoc", "Rakefile", "TODO", "bin/repub", "lib/repub.rb", "lib/repub/app.rb", "lib/repub/app/builder.rb", "lib/repub/app/fetcher.rb", "lib/repub/app/filter.rb", "lib/repub/app/logger.rb", "lib/repub/app/options.rb", "lib/repub/app/parser.rb", "lib/repub/app/post_filters.rb", "lib/repub/app/pre_filters.rb", "lib/repub/app/profile.rb", "lib/repub/app/utility.rb", "lib/repub/epub.rb", "lib/repub/epub/container_item.rb", "lib/repub/epub/ncx.rb", "lib/repub/epub/ocf.rb", "lib/repub/epub/opf.rb", "repub.gemspec", "test/data/custom.css", "test/data/invisiblellama.png", "test/data/test.css", "test/data/test.html", "test/epub/test_ncx.rb", "test/epub/test_ocf.rb", "test/epub/test_opf.rb", "test/test_builder.rb", "test/test_fetcher.rb", "test/test_filter.rb", "test/test_logger.rb", "test/test_parser.rb"]
20
20
  s.homepage = %q{http://rubyforge.org/projects/repub/}
21
21
  s.rdoc_options = ["--main", "README.rdoc"]
22
22
  s.require_paths = ["lib"]
23
23
  s.rubyforge_project = %q{repub}
24
24
  s.rubygems_version = %q{1.3.4}
25
25
  s.summary = %q{Repub is a simple HTML to ePub converter}
26
- s.test_files = ["test/epub/test_container.rb", "test/epub/test_content.rb", "test/epub/test_toc.rb", "test/test_builder.rb", "test/test_fetcher.rb", "test/test_logger.rb", "test/test_parser.rb"]
26
+ s.test_files = ["test/epub/test_ncx.rb", "test/epub/test_ocf.rb", "test/epub/test_opf.rb", "test/test_builder.rb", "test/test_fetcher.rb", "test/test_filter.rb", "test/test_logger.rb", "test/test_parser.rb"]
27
27
 
28
28
  if s.respond_to? :specification_version then
29
29
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -5,10 +5,11 @@ require 'repub/epub'
5
5
 
6
6
  class TestToc < Test::Unit::TestCase
7
7
  def test_toc_create
8
- x = Repub::Epub::Toc.new('some-name')
9
- s = x.to_xml
8
+ ncx = Repub::Epub::NCX.new('some-ncx')
9
+ s = ncx.to_xml
10
+ #p s
10
11
  doc = Nokogiri::XML.parse(s)
11
- assert_equal('some-name', doc.at("//xmlns:meta[@name='dtb:uid']")['content'])
12
+ assert_equal('some-ncx', doc.at("//xmlns:meta[@name='dtb:uid']")['content'])
12
13
  assert_equal('1', doc.at("//xmlns:meta[@name='dtb:depth']")['content'])
13
14
  assert_equal('0', doc.at("//xmlns:meta[@name='dtb:totalPageCount']")['content'])
14
15
  assert_equal('0', doc.at("//xmlns:meta[@name='dtb:maxPageNumber']")['content'])
@@ -17,15 +18,16 @@ class TestToc < Test::Unit::TestCase
17
18
  end
18
19
 
19
20
  def test_nav_map
20
- x = Repub::Epub::Toc.new('some-name')
21
- p0 = x.nav_map.add_nav_point('Intro', 'intro.html')
22
- p1 = x.nav_map.add_nav_point('Chapter 1', 'chapter-1.html')
23
- p2 = x.nav_map.add_nav_point('Chapter 2', 'chapter-2.html')
24
- p21 = p2.add_nav_point('Chapter 2-1', 'chapter-2-1.html')
25
- pg = x.nav_map.add_nav_point('Glossary', 'glossary.html')
26
- p11 = p1.add_nav_point('Chapter 1-1', 'chapter-1-1.html')
27
- p12 = p1.add_nav_point('Chapter 1-2', 'chapter-1-2.html')
28
- s = x.to_xml
21
+ ncx = Repub::Epub::NCX.new('some-ncx')
22
+ ncx.nav_map.points << Repub::Epub::NCX::NavPoint.new('Intro', 'intro.html')
23
+ ncx.nav_map.points << Repub::Epub::NCX::NavPoint.new('Chapter 1', 'chapter-1.html')
24
+ ncx.nav_map.points << Repub::Epub::NCX::NavPoint.new('Chapter 2', 'chapter-2.html')
25
+ ncx.nav_map.points[2].points << Repub::Epub::NCX::NavPoint.new('Chapter 2-1', 'chapter-2-1.html')
26
+ ncx.nav_map.points << Repub::Epub::NCX::NavPoint.new('Glossary', 'glossary.html')
27
+ ncx.nav_map.points[1].points << Repub::Epub::NCX::NavPoint.new('Chapter 1-1', 'chapter-1-1.html')
28
+ ncx.nav_map.points[1].points << Repub::Epub::NCX::NavPoint.new('Chapter 1-2', 'chapter-1-2.html')
29
+ s = ncx.to_xml
30
+ #p s
29
31
  doc = Nokogiri::XML.parse(s)
30
32
  assert_equal(4, doc.xpath('//xmlns:navMap/xmlns:navPoint').size)
31
33
  assert_equal('2', doc.at("//xmlns:meta[@name='dtb:depth']")['content'])
@@ -0,0 +1,28 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'nokogiri'
4
+ require 'repub/epub'
5
+
6
+ class TestContainer < Test::Unit::TestCase
7
+ def test_container_create
8
+ container = Repub::Epub::OCF.new
9
+ container << 'test.html'
10
+ container << Repub::Epub::OPF.new('12345')
11
+ s = container.to_xml
12
+ #p s
13
+ doc = Nokogiri::XML.parse(s)
14
+ assert_not_nil(doc.at('rootfile'))
15
+ assert_equal('test.html', doc.at('rootfile[1]')['full-path'])
16
+ assert_equal('application/xhtml+xml', doc.at('rootfile[1]')['media-type'])
17
+ assert_equal('package.opf', doc.at('rootfile[2]')['full-path'])
18
+ assert_equal('application/oebps-package+xml', doc.at('rootfile[2]')['media-type'])
19
+ end
20
+
21
+ def test_container_create_fail
22
+ assert_raise(RuntimeError) do
23
+ # unknown mime type
24
+ container = Repub::Epub::OCF.new
25
+ container << 'blah.blah'
26
+ end
27
+ end
28
+ end
@@ -5,44 +5,46 @@ require 'repub/epub'
5
5
 
6
6
  class TestContent < Test::Unit::TestCase
7
7
  def test_create
8
- x = Repub::Epub::Content.new('some-name')
9
- s = x.to_xml
8
+ opf = Repub::Epub::OPF.new('some-opf')
9
+ s = opf.to_xml
10
10
  doc = Nokogiri::XML.parse(s)
11
11
  #p doc
12
12
 
13
13
  metadata = doc.at('metadata')
14
14
  assert_not_nil(metadata)
15
- assert_equal('some-name', metadata.xpath('dc:identifier', 'xmlns:dc' => "http://purl.org/dc/elements/1.1/").inner_text)
15
+ assert_equal('some-opf', metadata.xpath('dc:identifier', 'xmlns:dc' => "http://purl.org/dc/elements/1.1/").inner_text)
16
16
  assert_equal('Untitled', metadata.xpath('dc:title', 'xmlns:dc' => "http://purl.org/dc/elements/1.1/").inner_text)
17
17
  assert_equal('en', metadata.xpath('dc:language', 'xmlns:dc' => "http://purl.org/dc/elements/1.1/").inner_text)
18
18
  assert_equal(Date.today.to_s, metadata.xpath('dc:date', 'xmlns:dc' => "http://purl.org/dc/elements/1.1/").inner_text)
19
19
  end
20
20
 
21
21
  def test_manifest_create
22
- x = Repub::Epub::Content.new('some-name')
23
- s = x.to_xml
22
+ opf = Repub::Epub::OPF.new('some-opf')
23
+ opf << Repub::Epub::NCX.new('some-ncx')
24
+ s = opf.to_xml
24
25
  doc = Nokogiri::XML.parse(s)
25
26
  #p doc
26
27
 
27
28
  manifest = doc.at('manifest')
28
29
  assert_not_nil(manifest)
29
30
  assert_equal(1, manifest.children.size)
30
- assert_equal('ncx', manifest.at('item')['id'])
31
+ assert_equal('ncx', manifest.at('item[@href="toc.ncx"]')['id'])
31
32
  assert_not_nil(doc.at('spine'))
32
33
  assert_equal(0, doc.xpath('spine/item').size)
33
34
  end
34
35
 
35
- def test_manifest_items
36
- x = Repub::Epub::Content.new('some-name')
37
- x.add_item 'style.css'
38
- x.add_item 'more-style.css'
39
- x.add_item ' logo.jpg '
40
- x.add_item ' image.png'
41
- x.add_item 'picture.jpeg '
42
- x.add_item 'intro.html', 'intro'
43
- x.add_item 'chapter-1.html'
44
- x.add_item 'glossary.html', 'glossary'
45
- s = x.to_xml
36
+ def test_manifest_and_spine_items
37
+ opf = Repub::Epub::OPF.new('some-opf')
38
+ opf << 'style.css'
39
+ opf << 'more-style.css'
40
+ opf << ' logo.jpg '
41
+ opf << 'intro.html'
42
+ opf << ' image.png'
43
+ opf << 'picture.jpeg '
44
+ opf << Repub::Epub::NCX.new('some-ncx')
45
+ opf << 'chapter-1.html'
46
+ opf << 'glossary.html'
47
+ s = opf.to_xml
46
48
  doc = Nokogiri::HTML(s)
47
49
  #p doc
48
50
 
@@ -51,10 +53,14 @@ class TestContent < Test::Unit::TestCase
51
53
  assert_equal(2, manifest.xpath('item[@media-type="text/css"]').size)
52
54
  assert_equal(2, manifest.search('item[@media-type="image/jpeg"]').size)
53
55
  assert_equal(1, manifest.search('item[@media-type="image/png"]').size)
56
+ # NCX is first and always has id = 'ncx'
57
+ assert_equal('ncx', manifest.at('./item[position()=1]')['id'])
54
58
 
55
59
  spine = doc.at('spine')
60
+ # attribute toc has and id of NCX manifest item
61
+ assert_equal('ncx', spine['toc'])
56
62
  assert_equal(3, spine.search('itemref').size)
57
- assert_equal('intro', spine.at('./itemref[position()=1]')['idref'])
58
- assert_equal('glossary', spine.at('./itemref[position()=3]')['idref'])
63
+ assert_equal('item-4', spine.at('./itemref[position()=1]')['idref'])
64
+ assert_equal('item-8', spine.at('./itemref[position()=3]')['idref'])
59
65
  end
60
66
  end
@@ -0,0 +1,28 @@
1
+ require "test/unit"
2
+
3
+ require 'repub'
4
+ require 'repub/app'
5
+
6
+ class TestFilter < Test::Unit::TestCase
7
+ include Repub::App::Filter
8
+
9
+ filter :filter_1 do |s|
10
+ log.info 'in filter_1'
11
+ s.upcase
12
+ end
13
+
14
+ filter :filter_2 do |s|
15
+ log.info 'in filter_2'
16
+ "++ #{s} --"
17
+ end
18
+
19
+ filter :filter_3 do |s|
20
+ log.info 'in filter_3'
21
+ s.gsub(/\s/, '|')
22
+ end
23
+
24
+ def test_case_name
25
+ res = TestFilter.apply_filters('klaatu barada nikto')
26
+ assert_equal('++|KLAATU|BARADA|NIKTO|--', res)
27
+ end
28
+ end
@@ -36,10 +36,9 @@ class TestParser < Test::Unit::TestCase
36
36
  assert_equal(3, parser.toc.size)
37
37
  assert_equal('Chapter 1', parser.toc[0].title)
38
38
  assert_equal('Chapter 3', parser.toc[2].title)
39
- assert_equal(2, parser.toc[0].subitems.size)
40
- assert_equal('Chapter 1.2', parser.toc[0].subitems[1].title)
41
- assert_equal(cache.assets[:documents][0], parser.toc[0].subitems[1].uri)
42
- assert_equal('c12', parser.toc[0].subitems[1].fragment_id)
39
+ assert_equal(2, parser.toc[0].points.size)
40
+ assert_equal('Chapter 1.2', parser.toc[0].points[1].title)
41
+ assert_equal("#{cache.assets[:documents][0]}#c12", parser.toc[0].points[1].src)
43
42
  end
44
43
 
45
44
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: repub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitri Goutnik
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-05 00:00:00 +04:00
12
+ date: 2009-07-17 00:00:00 +04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -87,15 +87,19 @@ files:
87
87
  - lib/repub/app.rb
88
88
  - lib/repub/app/builder.rb
89
89
  - lib/repub/app/fetcher.rb
90
+ - lib/repub/app/filter.rb
90
91
  - lib/repub/app/logger.rb
91
92
  - lib/repub/app/options.rb
92
93
  - lib/repub/app/parser.rb
94
+ - lib/repub/app/post_filters.rb
95
+ - lib/repub/app/pre_filters.rb
93
96
  - lib/repub/app/profile.rb
94
97
  - lib/repub/app/utility.rb
95
98
  - lib/repub/epub.rb
96
- - lib/repub/epub/container.rb
97
- - lib/repub/epub/content.rb
98
- - lib/repub/epub/toc.rb
99
+ - lib/repub/epub/container_item.rb
100
+ - lib/repub/epub/ncx.rb
101
+ - lib/repub/epub/ocf.rb
102
+ - lib/repub/epub/opf.rb
99
103
  - repub.gemspec
100
104
  - tasks/ann.rake
101
105
  - tasks/bones.rake
@@ -114,11 +118,12 @@ files:
114
118
  - test/data/invisiblellama.png
115
119
  - test/data/test.css
116
120
  - test/data/test.html
117
- - test/epub/test_container.rb
118
- - test/epub/test_content.rb
119
- - test/epub/test_toc.rb
121
+ - test/epub/test_ncx.rb
122
+ - test/epub/test_ocf.rb
123
+ - test/epub/test_opf.rb
120
124
  - test/test_builder.rb
121
125
  - test/test_fetcher.rb
126
+ - test/test_filter.rb
122
127
  - test/test_logger.rb
123
128
  - test/test_parser.rb
124
129
  has_rdoc: true
@@ -151,10 +156,11 @@ signing_key:
151
156
  specification_version: 3
152
157
  summary: Repub is a simple HTML to ePub converter
153
158
  test_files:
154
- - test/epub/test_container.rb
155
- - test/epub/test_content.rb
156
- - test/epub/test_toc.rb
159
+ - test/epub/test_ncx.rb
160
+ - test/epub/test_ocf.rb
161
+ - test/epub/test_opf.rb
157
162
  - test/test_builder.rb
158
163
  - test/test_fetcher.rb
164
+ - test/test_filter.rb
159
165
  - test/test_logger.rb
160
166
  - test/test_parser.rb
@@ -1,28 +0,0 @@
1
- require 'rubygems'
2
- require 'builder'
3
-
4
- module Repub
5
- module Epub
6
-
7
- class Container
8
- def to_xml
9
- out = ''
10
- builder = Builder::XmlMarkup.new(:target => out)
11
- builder.instruct!
12
- builder.container :xmlns => "urn:oasis:names:tc:opendocument:xmlns:container", :version => "1.0" do
13
- builder.rootfiles do
14
- builder.rootfile 'full-path' => "content.opf", 'media-type' => "application/oebps-package+xml"
15
- end
16
- end
17
- out
18
- end
19
-
20
- def save(path = 'container.xml')
21
- File.open(path, 'w') do |f|
22
- f << to_xml
23
- end
24
- end
25
- end
26
-
27
- end
28
- end