eeepub 0.3.2 → 0.4.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 +7 -0
- data/README.md +31 -16
- data/Rakefile +7 -11
- data/TODO +1 -0
- data/VERSION +1 -1
- data/examples/maker.rb +25 -0
- data/lib/eeepub/container_item.rb +35 -1
- data/lib/eeepub/maker.rb +99 -0
- data/lib/eeepub/ocf.rb +51 -9
- data/lib/eeepub/opf.rb +21 -9
- data/lib/eeepub.rb +10 -1
- data/spec/eeepub/maker_spec.rb +65 -0
- data/spec/eeepub/opf_spec.rb +40 -11
- data/spec/spec_helper.rb +2 -1
- metadata +24 -7
- data/examples/basic.rb +0 -21
- data/lib/eeepub/basic.rb +0 -47
data/.gitignore
ADDED
data/README.md
CHANGED
@@ -6,23 +6,25 @@ EeePub is a Ruby ePub generator.
|
|
6
6
|
Usage
|
7
7
|
-------
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
9
|
+
epub = EeePub.make do
|
10
|
+
title 'sample'
|
11
|
+
creator 'jugyo'
|
12
|
+
publisher 'jugyo.org'
|
13
|
+
date '2010-05-06'
|
14
|
+
identifier 'http://example.com/book/foo', :scheme => 'URL'
|
15
|
+
uid 'http://example.com/book/foo'
|
16
|
+
|
17
|
+
files ['/path/to/foo.html'), '/path/to/bar.html')]
|
18
|
+
nav [
|
19
|
+
{:label => '1. foo', :content => 'foo.html', :nav => [
|
20
|
+
{:label => '1.1 foo-1', :content => 'foo.html#foo-1'}
|
21
|
+
]},
|
22
|
+
{:label => '1. bar', :content => 'bar.html'}
|
23
|
+
]
|
24
|
+
end
|
23
25
|
epub.save('sample.epub')
|
24
26
|
|
25
|
-
### Raw
|
27
|
+
### Raw Level API
|
26
28
|
|
27
29
|
Create NCX:
|
28
30
|
|
@@ -39,7 +41,7 @@ Create OPF:
|
|
39
41
|
|
40
42
|
EeePub::OPF.new(
|
41
43
|
:title => 'sample',
|
42
|
-
:identifier => {
|
44
|
+
:identifier => {:value => '0-0000000-0-0', :scheme => 'ISBN'},
|
43
45
|
:manifest => ['foo.html', 'bar.html'],
|
44
46
|
:ncx => 'toc.ncx'
|
45
47
|
).save(File.join('sample', 'content.opf'))
|
@@ -56,6 +58,19 @@ Install
|
|
56
58
|
|
57
59
|
gem install eeepub
|
58
60
|
|
61
|
+
Requirements
|
62
|
+
-------
|
63
|
+
|
64
|
+
* ruby 1.8.7
|
65
|
+
* builder
|
66
|
+
* eBook Reader :)
|
67
|
+
|
68
|
+
Links
|
69
|
+
-------
|
70
|
+
|
71
|
+
* Documentation: [http://yardoc.org/docs/jugyo-eeepub](http://yardoc.org/docs/jugyo-eeepub)
|
72
|
+
* Source code: [http://github.com/jugyo/eeepub](http://github.com/jugyo/eeepub)
|
73
|
+
|
59
74
|
Copyright
|
60
75
|
-------
|
61
76
|
|
data/Rakefile
CHANGED
@@ -12,6 +12,7 @@ begin
|
|
12
12
|
gem.authors = ["jugyo"]
|
13
13
|
gem.add_dependency "builder"
|
14
14
|
gem.add_development_dependency "rspec"
|
15
|
+
gem.add_development_dependency "rr"
|
15
16
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
17
|
end
|
17
18
|
rescue LoadError
|
@@ -34,16 +35,11 @@ task :spec => :check_dependencies
|
|
34
35
|
|
35
36
|
task :default => :spec
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
begin
|
39
|
+
require 'yard'
|
40
|
+
YARD::Rake::YardocTask.new
|
41
|
+
rescue LoadError
|
42
|
+
task :yardoc do
|
43
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
43
44
|
end
|
44
|
-
|
45
|
-
rdoc.rdoc_dir = 'rdoc'
|
46
|
-
rdoc.title = "eeepub #{version}"
|
47
|
-
rdoc.rdoc_files.include('README*')
|
48
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
45
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/examples/maker.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require 'rubygems'
|
3
|
+
require 'eeepub'
|
4
|
+
|
5
|
+
dir = File.join(File.dirname(__FILE__), 'files')
|
6
|
+
|
7
|
+
epub = EeePub.make do
|
8
|
+
title 'sample'
|
9
|
+
creator 'jugyo'
|
10
|
+
publisher 'jugyo.org'
|
11
|
+
date '2010-05-06'
|
12
|
+
identifier 'http://example.com/book/foo', :scheme => 'URL'
|
13
|
+
uid 'http://example.com/book/foo'
|
14
|
+
|
15
|
+
files [File.join(dir, 'foo.html'), File.join(dir, 'bar.html')]
|
16
|
+
nav [
|
17
|
+
{:label => '1. foo', :content => 'foo.html', :nav => [
|
18
|
+
{:label => '1.1 foo-1', :content => 'foo.html#foo-1'}
|
19
|
+
]},
|
20
|
+
{:label => '1. bar', :content => 'bar.html'}
|
21
|
+
]
|
22
|
+
end
|
23
|
+
epub.save('sample.epub')
|
24
|
+
|
25
|
+
puts "complete! => 'sample.epub'"
|
@@ -1,8 +1,18 @@
|
|
1
1
|
require 'builder'
|
2
2
|
|
3
3
|
module EeePub
|
4
|
+
# Abstract base class for container item of ePub. Provides some helper methods.
|
5
|
+
#
|
6
|
+
# @abstract
|
4
7
|
class ContainerItem
|
5
8
|
class << self
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Set default value to attribute
|
13
|
+
#
|
14
|
+
# @param [Symbol] name the attribute name
|
15
|
+
# @param [Object] default the default value
|
6
16
|
def default_value(name, default)
|
7
17
|
instance_variable_name = "@#{name}"
|
8
18
|
define_method(name) do
|
@@ -11,22 +21,33 @@ module EeePub
|
|
11
21
|
end
|
12
22
|
end
|
13
23
|
|
24
|
+
# Define alias of attribute accessor
|
25
|
+
#
|
26
|
+
# @param [Symbol] name the attribute name as alias
|
27
|
+
# @param [Symbol] name the attribute name as source
|
14
28
|
def attr_alias(name, src)
|
15
29
|
alias_method name, src
|
16
30
|
alias_method :"#{name}=", :"#{src}="
|
17
31
|
end
|
18
32
|
end
|
19
33
|
|
34
|
+
# @param [Hash<Symbol, Object>] values the hash of symbols and objects for attributes
|
20
35
|
def initialize(values)
|
21
36
|
set_values(values)
|
22
37
|
end
|
23
38
|
|
39
|
+
# Set values for attributes
|
40
|
+
#
|
41
|
+
# @param [Hash<Symbol, Object>] values the hash of symbols and objects for attributes
|
24
42
|
def set_values(values)
|
25
43
|
values.each do |k, v|
|
26
44
|
self.send(:"#{k}=", v)
|
27
45
|
end
|
28
46
|
end
|
29
47
|
|
48
|
+
# Convert to xml of container item
|
49
|
+
#
|
50
|
+
# @return [String] the xml of container item
|
30
51
|
def to_xml
|
31
52
|
out = ""
|
32
53
|
builder = Builder::XmlMarkup.new(:target => out, :indent => 2)
|
@@ -35,12 +56,21 @@ module EeePub
|
|
35
56
|
out
|
36
57
|
end
|
37
58
|
|
59
|
+
# Save as container item
|
60
|
+
#
|
61
|
+
# @param [String] filepath the file path for container item
|
38
62
|
def save(filepath)
|
39
63
|
File.open(filepath, 'w') do |file|
|
40
64
|
file << self.to_xml
|
41
65
|
end
|
42
66
|
end
|
43
67
|
|
68
|
+
private
|
69
|
+
|
70
|
+
# Guess media type from file name
|
71
|
+
#
|
72
|
+
# @param [String] filename the file name
|
73
|
+
# @return [String] the media-type
|
44
74
|
def guess_media_type(filename)
|
45
75
|
case filename
|
46
76
|
when /.*\.html?$/i
|
@@ -62,7 +92,11 @@ module EeePub
|
|
62
92
|
end
|
63
93
|
end
|
64
94
|
|
65
|
-
|
95
|
+
# Convert options for xml attributes
|
96
|
+
#
|
97
|
+
# @param [Hash<Symbol, Object>] hash the hash of symbols and objects for xml attributes
|
98
|
+
# @return [Hash<String, Object>] the options for xml attributes
|
99
|
+
def convert_to_xml_attributes(hash)
|
66
100
|
result = {}
|
67
101
|
hash.each do |k, v|
|
68
102
|
key = k.to_s.gsub('_', '-').to_sym
|
data/lib/eeepub/maker.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module EeePub
|
5
|
+
# The class to make ePub easily
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# epub = EeePub.make do
|
9
|
+
# title 'sample'
|
10
|
+
# creator 'jugyo'
|
11
|
+
# publisher 'jugyo.org'
|
12
|
+
# date '2010-05-06'
|
13
|
+
# identifier 'http://example.com/book/foo', :scheme => 'URL'
|
14
|
+
# uid 'http://example.com/book/foo'
|
15
|
+
#
|
16
|
+
# files ['/path/to/foo.html'), '/path/to/bar.html')]
|
17
|
+
# nav [
|
18
|
+
# {:label => '1. foo', :content => 'foo.html', :nav => [
|
19
|
+
# {:label => '1.1 foo-1', :content => 'foo.html#foo-1'}
|
20
|
+
# ]},
|
21
|
+
# {:label => '1. bar', :content => 'bar.html'}
|
22
|
+
# ]
|
23
|
+
# end
|
24
|
+
# epub.save('sample.epub')
|
25
|
+
class Maker
|
26
|
+
[
|
27
|
+
:title,
|
28
|
+
:creator,
|
29
|
+
:publisher,
|
30
|
+
:date,
|
31
|
+
].each do |name|
|
32
|
+
class_eval <<-DELIM
|
33
|
+
def #{name}(value)
|
34
|
+
@#{name}s ||= []
|
35
|
+
@#{name}s << value
|
36
|
+
end
|
37
|
+
DELIM
|
38
|
+
end
|
39
|
+
|
40
|
+
[
|
41
|
+
:uid,
|
42
|
+
:files,
|
43
|
+
:nav,
|
44
|
+
:ncx_file,
|
45
|
+
:opf_file
|
46
|
+
].each do |name|
|
47
|
+
define_method(name) do |arg|
|
48
|
+
instance_variable_set("@#{name}", arg)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def identifier(id, options)
|
53
|
+
@identifiers ||= []
|
54
|
+
@identifiers << {:value => id, :scheme => options[:scheme]}
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param [Proc] block the block for initialize
|
58
|
+
def initialize(&block)
|
59
|
+
@files ||= []
|
60
|
+
@nav ||= []
|
61
|
+
@ncx_file ||= 'toc.ncx'
|
62
|
+
@opf_file ||= 'content.opf'
|
63
|
+
|
64
|
+
instance_eval(&block) if block_given?
|
65
|
+
end
|
66
|
+
|
67
|
+
# Save as ePub file
|
68
|
+
#
|
69
|
+
# @param [String] filename the ePub file name to save
|
70
|
+
def save(filename)
|
71
|
+
Dir.mktmpdir do |dir|
|
72
|
+
@files.each do |file|
|
73
|
+
FileUtils.cp(file, dir)
|
74
|
+
end
|
75
|
+
|
76
|
+
NCX.new(
|
77
|
+
:uid => @uid,
|
78
|
+
:title => @titles[0],
|
79
|
+
:nav => @nav
|
80
|
+
).save(File.join(dir, @ncx_file))
|
81
|
+
|
82
|
+
OPF.new(
|
83
|
+
:title => @titles,
|
84
|
+
:identifier => @identifiers,
|
85
|
+
:creator => @creators,
|
86
|
+
:publisher => @publishers,
|
87
|
+
:date => @dates,
|
88
|
+
:manifest => @files.map{|i| File.basename(i)},
|
89
|
+
:ncx => @ncx_file
|
90
|
+
).save(File.join(dir, @opf_file))
|
91
|
+
|
92
|
+
OCF.new(
|
93
|
+
:dir => dir,
|
94
|
+
:container => @opf_file
|
95
|
+
).save(filename)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/eeepub/ocf.rb
CHANGED
@@ -1,26 +1,55 @@
|
|
1
1
|
module EeePub
|
2
|
+
# Class to create OCF
|
2
3
|
class OCF
|
4
|
+
# Class for 'container.xml' of OCF
|
3
5
|
class Container < ContainerItem
|
4
6
|
attr_accessor :rootfiles
|
5
7
|
|
6
|
-
|
8
|
+
# @param [String or Array or Hash]
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # with String
|
12
|
+
# EeePub::OCF::Container.new('container.opf')
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # with Array
|
16
|
+
# EeePub::OCF::Container.new(['container.opf', 'other.opf'])
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# # with Hash
|
20
|
+
# EeePub::OCF::Container.new(
|
21
|
+
# :rootfiles => [
|
22
|
+
# {:full_path => 'container.opf', :media_type => 'application/oebps-package+xml'}
|
23
|
+
# ]
|
24
|
+
# )
|
25
|
+
def initialize(arg)
|
7
26
|
case arg
|
8
27
|
when String
|
9
|
-
|
28
|
+
set_values(
|
10
29
|
:rootfiles => [
|
11
30
|
{:full_path => arg, :media_type => guess_media_type(arg)}
|
12
31
|
]
|
13
32
|
)
|
14
|
-
|
15
|
-
|
33
|
+
when Array
|
34
|
+
# TODO: spec
|
35
|
+
set_values(
|
36
|
+
:rootfiles => arg.keys.map { |k|
|
37
|
+
filename = arg[k]
|
38
|
+
{:full_path => filename, :media_type => guess_media_type(filename)}
|
39
|
+
}
|
40
|
+
)
|
41
|
+
when Hash
|
42
|
+
set_values(arg)
|
16
43
|
end
|
17
44
|
end
|
18
45
|
|
46
|
+
private
|
47
|
+
|
19
48
|
def build_xml(builder)
|
20
49
|
builder.container :xmlns => "urn:oasis:names:tc:opendocument:xmlns:container", :version => "1.0" do
|
21
50
|
builder.rootfiles do
|
22
51
|
rootfiles.each do |i|
|
23
|
-
builder.rootfile
|
52
|
+
builder.rootfile convert_to_xml_attributes(i)
|
24
53
|
end
|
25
54
|
end
|
26
55
|
end
|
@@ -29,21 +58,34 @@ module EeePub
|
|
29
58
|
|
30
59
|
attr_accessor :dir, :container
|
31
60
|
|
61
|
+
# @param [Hash<Symbol, Object>] values the values of symbols and objects for OCF
|
62
|
+
#
|
63
|
+
# @example
|
64
|
+
# EeePub::OCF.new(
|
65
|
+
# :dir => '/path/to/dir',
|
66
|
+
# :container => 'container.opf'
|
67
|
+
# )
|
32
68
|
def initialize(values)
|
33
69
|
values.each do |k, v|
|
34
70
|
self.send(:"#{k}=", v)
|
35
71
|
end
|
36
72
|
end
|
37
73
|
|
74
|
+
# Set container
|
75
|
+
#
|
76
|
+
# @param [EeePub::OCF::Container or args for EeePub::OCF::Container]
|
38
77
|
def container=(arg)
|
39
|
-
|
40
|
-
when String
|
41
|
-
@container = EeePub::OCF::Container.new(arg)
|
42
|
-
else
|
78
|
+
if arg.is_a?(EeePub::OCF::Container)
|
43
79
|
@container = arg
|
80
|
+
else
|
81
|
+
# TODO: spec
|
82
|
+
@container = EeePub::OCF::Container.new(arg)
|
44
83
|
end
|
45
84
|
end
|
46
85
|
|
86
|
+
# Save as OCF
|
87
|
+
#
|
88
|
+
# @param [String] output_path the output file path of ePub
|
47
89
|
def save(output_path)
|
48
90
|
output_path = File.expand_path(output_path)
|
49
91
|
|
data/lib/eeepub/opf.rb
CHANGED
@@ -13,6 +13,7 @@ module EeePub
|
|
13
13
|
:rights,
|
14
14
|
:manifest,
|
15
15
|
:spine,
|
16
|
+
:guide,
|
16
17
|
:ncx,
|
17
18
|
:toc
|
18
19
|
|
@@ -30,13 +31,8 @@ module EeePub
|
|
30
31
|
when String
|
31
32
|
[{:value => @identifier, :id => unique_identifier}]
|
32
33
|
when Hash
|
33
|
-
|
34
|
-
|
35
|
-
[{:scheme => key, :value => @identifier[key], :id => unique_identifier}]
|
36
|
-
else
|
37
|
-
@identifier[:id] = unique_identifier
|
38
|
-
[@identifier]
|
39
|
-
end
|
34
|
+
@identifier[:id] = unique_identifier
|
35
|
+
[@identifier]
|
40
36
|
else
|
41
37
|
@identifier
|
42
38
|
end
|
@@ -57,6 +53,7 @@ module EeePub
|
|
57
53
|
build_metadata(builder)
|
58
54
|
build_manifest(builder)
|
59
55
|
build_spine(builder)
|
56
|
+
build_guide(builder)
|
60
57
|
end
|
61
58
|
end
|
62
59
|
|
@@ -75,8 +72,13 @@ module EeePub
|
|
75
72
|
|
76
73
|
[:title, :language, :subject, :description, :relation, :creator, :publisher, :date, :rights].each do |i|
|
77
74
|
value = self.send(i)
|
78
|
-
|
79
|
-
|
75
|
+
next unless value
|
76
|
+
|
77
|
+
[value].flatten.each do |v|
|
78
|
+
case v
|
79
|
+
when Hash
|
80
|
+
builder.dc i, v[:value], convert_to_xml_attributes(v.reject {|k, v| k == :value})
|
81
|
+
else
|
80
82
|
builder.dc i, v
|
81
83
|
end
|
82
84
|
end
|
@@ -100,6 +102,16 @@ module EeePub
|
|
100
102
|
end
|
101
103
|
end
|
102
104
|
|
105
|
+
def build_guide(builder)
|
106
|
+
return if guide.nil? || guide.empty?
|
107
|
+
|
108
|
+
builder.guide do
|
109
|
+
guide.each do |i|
|
110
|
+
builder.reference convert_to_xml_attributes(i)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
103
115
|
def complete_manifest
|
104
116
|
item_id_cache = {}
|
105
117
|
|
data/lib/eeepub.rb
CHANGED
@@ -2,4 +2,13 @@ require 'eeepub/container_item'
|
|
2
2
|
require 'eeepub/opf'
|
3
3
|
require 'eeepub/ocf'
|
4
4
|
require 'eeepub/ncx'
|
5
|
-
require 'eeepub/
|
5
|
+
require 'eeepub/maker'
|
6
|
+
|
7
|
+
module EeePub
|
8
|
+
# Make ePub
|
9
|
+
#
|
10
|
+
# @param [Proc] block the block for initialize EeePub::Maker
|
11
|
+
def self.make(&block)
|
12
|
+
EeePub::Maker.new(&block)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "EeePub::Maker" do
|
4
|
+
before do
|
5
|
+
@maker = EeePub::Maker.new do
|
6
|
+
title 'sample'
|
7
|
+
creator 'jugyo'
|
8
|
+
publisher 'jugyo.org'
|
9
|
+
date "2010-05-06"
|
10
|
+
identifier 'http://example.com/book/foo', :scheme => 'URL'
|
11
|
+
uid 'http://example.com/book/foo'
|
12
|
+
ncx_file 'toc.ncx'
|
13
|
+
opf_file 'content.opf'
|
14
|
+
files ['foo.html', 'bar.html']
|
15
|
+
nav [
|
16
|
+
{:label => '1. foo', :content => 'foo.html'},
|
17
|
+
{:label => '1. bar', :content => 'bar.html'}
|
18
|
+
]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it { @maker.instance_variable_get(:@titles).should == ['sample'] }
|
23
|
+
it { @maker.instance_variable_get(:@creators).should == ['jugyo'] }
|
24
|
+
it { @maker.instance_variable_get(:@publishers).should == ['jugyo.org'] }
|
25
|
+
it { @maker.instance_variable_get(:@dates).should == ["2010-05-06"] }
|
26
|
+
it { @maker.instance_variable_get(:@identifiers).should == [{:value => 'http://example.com/book/foo', :scheme => 'URL'}] }
|
27
|
+
it { @maker.instance_variable_get(:@uid).should == 'http://example.com/book/foo' }
|
28
|
+
it { @maker.instance_variable_get(:@ncx_file).should == 'toc.ncx' }
|
29
|
+
it { @maker.instance_variable_get(:@opf_file).should == 'content.opf' }
|
30
|
+
it { @maker.instance_variable_get(:@files).should == ['foo.html', 'bar.html'] }
|
31
|
+
it {
|
32
|
+
@maker.instance_variable_get(:@nav).should == [
|
33
|
+
{:label => '1. foo', :content => 'foo.html'},
|
34
|
+
{:label => '1. bar', :content => 'bar.html'}
|
35
|
+
]
|
36
|
+
}
|
37
|
+
|
38
|
+
it 'should save' do
|
39
|
+
stub(FileUtils).cp.with_any_args
|
40
|
+
mock(Dir).mktmpdir {|i| i.call('/tmp')}
|
41
|
+
mock(EeePub::NCX).new(
|
42
|
+
:title => "sample",
|
43
|
+
:nav => [
|
44
|
+
{:label => '1. foo', :content => 'foo.html'},
|
45
|
+
{:label => '1. bar', :content => 'bar.html'}
|
46
|
+
],
|
47
|
+
:uid => "http://example.com/book/foo"
|
48
|
+
) { stub!.save }
|
49
|
+
mock(EeePub::OPF).new(
|
50
|
+
:title => ["sample"],
|
51
|
+
:creator => ["jugyo"],
|
52
|
+
:date => ["2010-05-06"],
|
53
|
+
:ncx => "toc.ncx",
|
54
|
+
:publisher => ["jugyo.org"],
|
55
|
+
:identifier => [{:value => "http://example.com/book/foo", :scheme => "URL"}],
|
56
|
+
:manifest => ['foo.html', 'bar.html']
|
57
|
+
) { stub!.save }
|
58
|
+
mock(EeePub::OCF).new(
|
59
|
+
:container => "content.opf",
|
60
|
+
:dir => '/tmp'
|
61
|
+
) { stub!.save }
|
62
|
+
|
63
|
+
@maker.save('test.epub')
|
64
|
+
end
|
65
|
+
end
|
data/spec/eeepub/opf_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'date'
|
|
4
4
|
describe "EeePub::OPF" do
|
5
5
|
before do
|
6
6
|
@opf = EeePub::OPF.new(
|
7
|
-
:identifier => {
|
7
|
+
:identifier => {:value => '978-4-00-310101-8', :scheme => 'ISBN'},
|
8
8
|
:files => ['foo.html', 'bar.html', 'picture.png'],
|
9
9
|
:ncx => 'toc.ncx'
|
10
10
|
)
|
@@ -49,11 +49,11 @@ describe "EeePub::OPF" do
|
|
49
49
|
expect = @opf.manifest[index]
|
50
50
|
item.attribute('id').value.should == expect
|
51
51
|
item.attribute('href').value.should == expect
|
52
|
-
item.attribute('media-type').value.should == @opf.guess_media_type
|
52
|
+
item.attribute('media-type').value.should == @opf.send(:guess_media_type, expect)
|
53
53
|
end
|
54
54
|
manifest[3].attribute('id').value.should == 'ncx'
|
55
55
|
manifest[3].attribute('href').value.should == @opf.ncx
|
56
|
-
manifest[3].attribute('media-type').value.should == @opf.guess_media_type
|
56
|
+
manifest[3].attribute('media-type').value.should == @opf.send(:guess_media_type, @opf.ncx)
|
57
57
|
|
58
58
|
spine = doc.at('spine')
|
59
59
|
spine.should_not be_nil
|
@@ -61,6 +61,8 @@ describe "EeePub::OPF" do
|
|
61
61
|
spine.size.should == 2
|
62
62
|
spine[0].attribute('idref').value.should == 'foo.html'
|
63
63
|
spine[1].attribute('idref').value.should == 'bar.html'
|
64
|
+
|
65
|
+
doc.at('guide').should be_nil
|
64
66
|
end
|
65
67
|
|
66
68
|
describe 'spec of identifier' do
|
@@ -78,13 +80,6 @@ describe "EeePub::OPF" do
|
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
81
|
-
context 'specify as Hash(scheme => value)' do
|
82
|
-
before { @opf.identifier = {'ISBN' => '978-4-00-310101-8'} }
|
83
|
-
it 'should return value' do
|
84
|
-
@opf.identifier.should == [{:scheme => 'ISBN', :value => '978-4-00-310101-8', :id => @opf.unique_identifier}]
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
83
|
context 'specify as String' do
|
89
84
|
before { @opf.identifier = '978-4-00-310101-8' }
|
90
85
|
it 'should return value' do
|
@@ -227,7 +222,41 @@ describe "EeePub::OPF" do
|
|
227
222
|
end
|
228
223
|
manifest[3].attribute('id').value.should == 'ncx'
|
229
224
|
manifest[3].attribute('href').value.should == @opf.ncx
|
230
|
-
manifest[3].attribute('media-type').value.should == @opf.guess_media_type
|
225
|
+
manifest[3].attribute('media-type').value.should == @opf.send(:guess_media_type, @opf.ncx)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context 'specify dc:date[event]' do
|
230
|
+
before do
|
231
|
+
@opf.date = {:value => Date.today, :event => 'publication'}
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should export as xml' do
|
235
|
+
doc = Nokogiri::XML(@opf.to_xml)
|
236
|
+
metadata = doc.at('metadata')
|
237
|
+
date = metadata.xpath('dc:date', 'xmlns:dc' => "http://purl.org/dc/elements/1.1/")
|
238
|
+
date.inner_text.should == @opf.date[:value].to_s
|
239
|
+
date.attribute('event').value.should == @opf.date[:event]
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context 'set guide' do
|
244
|
+
before do
|
245
|
+
@opf.guide = [
|
246
|
+
{:type => 'toc', :title => 'Table of Contents', :href => 'toc.html'},
|
247
|
+
{:type => 'loi', :title => 'List Of Illustrations', :href => 'toc.html#figures'},
|
248
|
+
]
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'should export as xml' do
|
252
|
+
doc = Nokogiri::XML(@opf.to_xml)
|
253
|
+
guide = doc.at('guide')
|
254
|
+
guide.should_not be_nil
|
255
|
+
references = guide.search('reference')
|
256
|
+
references.size.should == 2
|
257
|
+
[references, @opf.guide].transpose do |element, expect|
|
258
|
+
element.attributes.should == expect
|
259
|
+
end
|
231
260
|
end
|
232
261
|
end
|
233
262
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- jugyo
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-09 00:00:00 +09:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -41,6 +41,18 @@ dependencies:
|
|
41
41
|
version: "0"
|
42
42
|
type: :development
|
43
43
|
version_requirements: *id002
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: rr
|
46
|
+
prerelease: false
|
47
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
type: :development
|
55
|
+
version_requirements: *id003
|
44
56
|
description: EeePub is a Ruby ePub generator.
|
45
57
|
email: jugyo.org@gmail.com
|
46
58
|
executables: []
|
@@ -50,25 +62,29 @@ extensions: []
|
|
50
62
|
extra_rdoc_files:
|
51
63
|
- LICENSE
|
52
64
|
- README.md
|
65
|
+
- TODO
|
53
66
|
files:
|
67
|
+
- .gitignore
|
54
68
|
- LICENSE
|
55
69
|
- README.md
|
56
70
|
- Rakefile
|
57
71
|
- VERSION
|
58
|
-
- examples/basic.rb
|
59
72
|
- examples/files/bar.html
|
60
73
|
- examples/files/foo.html
|
74
|
+
- examples/maker.rb
|
61
75
|
- lib/eeepub.rb
|
62
|
-
- lib/eeepub/basic.rb
|
63
76
|
- lib/eeepub/container_item.rb
|
77
|
+
- lib/eeepub/maker.rb
|
64
78
|
- lib/eeepub/ncx.rb
|
65
79
|
- lib/eeepub/ocf.rb
|
66
80
|
- lib/eeepub/opf.rb
|
81
|
+
- spec/eeepub/maker_spec.rb
|
67
82
|
- spec/eeepub/ncx_spec.rb
|
68
83
|
- spec/eeepub/ocf_spec.rb
|
69
84
|
- spec/eeepub/opf_spec.rb
|
70
85
|
- spec/eeepub_spec.rb
|
71
86
|
- spec/spec_helper.rb
|
87
|
+
- TODO
|
72
88
|
has_rdoc: true
|
73
89
|
homepage: http://github.com/jugyo/eeepub
|
74
90
|
licenses: []
|
@@ -100,9 +116,10 @@ signing_key:
|
|
100
116
|
specification_version: 3
|
101
117
|
summary: ePub generator
|
102
118
|
test_files:
|
119
|
+
- spec/eeepub/maker_spec.rb
|
103
120
|
- spec/eeepub/ncx_spec.rb
|
104
121
|
- spec/eeepub/ocf_spec.rb
|
105
122
|
- spec/eeepub/opf_spec.rb
|
106
123
|
- spec/eeepub_spec.rb
|
107
124
|
- spec/spec_helper.rb
|
108
|
-
- examples/
|
125
|
+
- examples/maker.rb
|
data/examples/basic.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
-
require 'rubygems'
|
3
|
-
require 'eeepub'
|
4
|
-
|
5
|
-
dir = File.join(File.dirname(__FILE__), 'files')
|
6
|
-
|
7
|
-
epub = EeePub::Basic.new(
|
8
|
-
:title => 'sample',
|
9
|
-
:creator => 'jugyo',
|
10
|
-
:publisher => 'jugyo.org',
|
11
|
-
:date => "2010-05-06",
|
12
|
-
:id => {'URL' => 'http://example.com/book/foo'},
|
13
|
-
:uid => 'http://example.com/book/foo'
|
14
|
-
)
|
15
|
-
epub.files << File.join(dir, 'foo.html')
|
16
|
-
epub.files << File.join(dir, 'bar.html')
|
17
|
-
epub.nav << {:label => '1. foo', :content => 'foo.html'}
|
18
|
-
epub.nav << {:label => '2. bar', :content => 'bar.html'}
|
19
|
-
epub.save('sample.epub')
|
20
|
-
|
21
|
-
puts "complete! => 'sample.epub'"
|
data/lib/eeepub/basic.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'tmpdir'
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
module EeePub
|
5
|
-
class Basic
|
6
|
-
attr_accessor :title, :creator, :publisher, :date, :id, :uid, :files, :nav
|
7
|
-
|
8
|
-
def initialize(values)
|
9
|
-
values.each do |k, v|
|
10
|
-
self.send(:"#{k}=", v)
|
11
|
-
end
|
12
|
-
@files ||= []
|
13
|
-
@nav ||= []
|
14
|
-
end
|
15
|
-
|
16
|
-
def save(filename)
|
17
|
-
dir = Dir.mktmpdir
|
18
|
-
|
19
|
-
files.each do |file|
|
20
|
-
FileUtils.cp(file, dir)
|
21
|
-
end
|
22
|
-
|
23
|
-
EeePub::NCX.new(
|
24
|
-
:uid => uid,
|
25
|
-
:title => title,
|
26
|
-
:nav => nav
|
27
|
-
).save(File.join(dir, 'toc.ncx'))
|
28
|
-
|
29
|
-
EeePub::OPF.new(
|
30
|
-
:title => title,
|
31
|
-
:identifier => id,
|
32
|
-
:creator => creator,
|
33
|
-
:publisher => publisher,
|
34
|
-
:date => date,
|
35
|
-
:manifest => files.map{|i| File.basename(i)},
|
36
|
-
:ncx => 'toc.ncx'
|
37
|
-
).save(File.join(dir, 'content.opf'))
|
38
|
-
|
39
|
-
EeePub::OCF.new(
|
40
|
-
:dir => dir,
|
41
|
-
:container => 'content.opf'
|
42
|
-
).save(filename)
|
43
|
-
|
44
|
-
FileUtils.rm_rf(dir)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|