invisiblellama-repub 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
data/repub.gemspec CHANGED
@@ -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
data/test/test_parser.rb CHANGED
@@ -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: invisiblellama-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 -07:00
12
+ date: 2009-07-17 00:00:00 -07:00
13
13
  default_executable: repub
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -82,25 +82,30 @@ files:
82
82
  - lib/repub/app.rb
83
83
  - lib/repub/app/builder.rb
84
84
  - lib/repub/app/fetcher.rb
85
+ - lib/repub/app/filter.rb
85
86
  - lib/repub/app/logger.rb
86
87
  - lib/repub/app/options.rb
87
88
  - lib/repub/app/parser.rb
89
+ - lib/repub/app/post_filters.rb
90
+ - lib/repub/app/pre_filters.rb
88
91
  - lib/repub/app/profile.rb
89
92
  - lib/repub/app/utility.rb
90
93
  - lib/repub/epub.rb
91
- - lib/repub/epub/container.rb
92
- - lib/repub/epub/content.rb
93
- - lib/repub/epub/toc.rb
94
+ - lib/repub/epub/container_item.rb
95
+ - lib/repub/epub/ncx.rb
96
+ - lib/repub/epub/ocf.rb
97
+ - lib/repub/epub/opf.rb
94
98
  - repub.gemspec
95
99
  - test/data/custom.css
96
100
  - test/data/invisiblellama.png
97
101
  - test/data/test.css
98
102
  - test/data/test.html
99
- - test/epub/test_container.rb
100
- - test/epub/test_content.rb
101
- - test/epub/test_toc.rb
103
+ - test/epub/test_ncx.rb
104
+ - test/epub/test_ocf.rb
105
+ - test/epub/test_opf.rb
102
106
  - test/test_builder.rb
103
107
  - test/test_fetcher.rb
108
+ - test/test_filter.rb
104
109
  - test/test_logger.rb
105
110
  - test/test_parser.rb
106
111
  has_rdoc: false
@@ -131,10 +136,11 @@ signing_key:
131
136
  specification_version: 3
132
137
  summary: Repub is a simple HTML to ePub converter
133
138
  test_files:
134
- - test/epub/test_container.rb
135
- - test/epub/test_content.rb
136
- - test/epub/test_toc.rb
139
+ - test/epub/test_ncx.rb
140
+ - test/epub/test_ocf.rb
141
+ - test/epub/test_opf.rb
137
142
  - test/test_builder.rb
138
143
  - test/test_fetcher.rb
144
+ - test/test_filter.rb
139
145
  - test/test_logger.rb
140
146
  - 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