Permalink
Browse files

first commit

  • Loading branch information...
jugyo committed May 2, 2010
0 parents commit 170c03deaa97471efbdadc0dcf9162a0eeb5e20e
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2009 jugyo
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,7 @@
+= eeepub
+
+Ruby ePub generator.
+
+== Copyright
+
+Copyright (c) 2010 jugyo. See LICENSE for details.
@@ -0,0 +1,48 @@
+require 'rubygems'
+require 'rake'
+
+begin
+ require 'jeweler'
+ Jeweler::Tasks.new do |gem|
+ gem.name = "eeepub"
+ gem.summary = %Q{ePub generator}
+ gem.description = %Q{Ruby ePub generator.}
+ gem.email = "jugyo.org@gmail.com"
+ gem.homepage = "http://github.com/jugyo/eeepub"
+ gem.authors = ["jugyo"]
+ gem.add_development_dependency "rspec"
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
+ end
+rescue LoadError
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
+end
+
+require 'spec/rake/spectask'
+Spec::Rake::SpecTask.new(:spec) do |spec|
+ spec.libs << 'lib' << 'spec'
+ spec.spec_files = FileList['spec/**/*_spec.rb']
+end
+
+Spec::Rake::SpecTask.new(:rcov) do |spec|
+ spec.libs << 'lib' << 'spec'
+ spec.pattern = 'spec/**/*_spec.rb'
+ spec.rcov = true
+end
+
+task :spec => :check_dependencies
+
+task :default => :spec
+
+require 'rake/rdoctask'
+Rake::RDocTask.new do |rdoc|
+ if File.exist?('VERSION')
+ version = File.read('VERSION')
+ else
+ version = ""
+ end
+
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = "eeepub #{version}"
+ rdoc.rdoc_files.include('README*')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
@@ -0,0 +1,4 @@
+require 'eeepub/container_item'
+require 'eeepub/opf'
+require 'eeepub/ocf'
+require 'eeepub/ncx'
@@ -0,0 +1,43 @@
+require 'erb'
+
+module EeePub
+ class ContainerItem
+ include ERB::Util
+
+ class << self
+ attr_reader :template_name
+
+ def template(name)
+ @template_name = name
+ end
+ end
+
+ def initialize(values)
+ set_values(values)
+ end
+
+ def set_values(values)
+ values.each do |k, v|
+ self.send(:"#{k}=", v)
+ end
+ end
+
+ def to_xml
+ erb(self.class.template_name).result(binding)
+ end
+
+ def erb(filename)
+ ERB.new(
+ File.read(File.expand_path("templates/#{filename}", File.dirname(__FILE__))),
+ nil,
+ '-'
+ )
+ end
+
+ def save(filepath)
+ File.open(filepath, 'w') do |file|
+ file << self.to_xml
+ end
+ end
+ end
+end
@@ -0,0 +1,18 @@
+module EeePub
+ class NCX < ContainerItem
+ template 'ncx.erb'
+ attr_accessor :uid,
+ :depth,
+ :total_page_count,
+ :max_page_number,
+ :doc_title,
+ :nav_points
+
+ def set_values(values)
+ super
+ @depth ||= 1
+ @total_page_count ||= 0
+ @max_page_number ||= 0
+ end
+ end
+end
@@ -0,0 +1,33 @@
+module EeePub
+ class OCF
+ class Container < ContainerItem
+ template 'container.xml.erb'
+ attr_accessor :rootfiles
+ end
+
+ attr_accessor :dir, :container
+
+ def initialize(dir, contents)
+ @dir = dir
+ contents.each do |k, v|
+ self.send(:"#{k}=", v)
+ end
+ end
+
+ def make(output_path)
+ FileUtils.chdir(dir) do
+ File.open('mimetype', 'w') do |f|
+ f << 'application/epub+zip'
+ end
+
+ meta_inf = 'META-INF'
+ FileUtils.mkdir_p(meta_inf)
+
+ container.save(File.join(meta_inf, 'container.xml'))
+
+ %x(zip -X9 \"#{output_path}\" mimetype)
+ %x(zip -Xr9D \"#{output_path}\" * -xi mimetype)
+ end
+ end
+ end
+end
@@ -0,0 +1,17 @@
+module EeePub
+ class OPF < ContainerItem
+ template 'opf.erb'
+ attr_accessor :title,
+ :language,
+ :identifier,
+ :date,
+ :subject,
+ :description,
+ :relation,
+ :creator,
+ :publisher,
+ :rights,
+ :items,
+ :itemrefs
+ end
+end
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0">
+ <rootfiles>
+ <%- rootfiles.each do |rootfile| -%>
+ <rootfile full-path="<%=h rootfile[:full_path] %>" media-type="<%=h rootfile[:media_type] %>"/>
+ <%- end -%>
+ </rootfiles>
+</container>
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
+ <head>
+ <meta name="dtb:uid" content="<%=h uid %>"/>
+ <meta name="dtb:depth" content="<%=h depth %>"/>
+ <meta name="dtb:totalPageCount" content="<%=h total_page_count %>"/>
+ <meta name="dtb:maxPageNumber" content="<%=h max_page_number %>"/>
+ </head>
+ <docTitle>
+ <text><%=h doc_title %></text>
+ </docTitle>
+ <navMap>
+ <%- nav_points.each do |nav| -%>
+ <navPoint id="<%=h nav[:id] %>" playOrder="<%=h nav[:play_order] %>">
+ <navLabel>
+ <text><%=h nav[:label] %></text>
+ </navLabel>
+ <content src="<%=h nav[:content] %>"/>
+ </navPoint>
+ <%- end -%>
+ </navMap>
+</ncx>
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">
+ <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
+ <dc:title><%=h title %></dc:title>
+ <dc:language><%=h language %></dc:language>
+ <dc:identifier id="BookId"><%=h identifier %></dc:identifier>
+ <%- if date -%>
+ <dc:date><%=h date.to_s %></dc:data>
+ <%- end -%>
+ <%- if subject -%>
+ <dc:subject><%=h subject %></dc:subject>
+ <%- end -%>
+ <%- if description -%>
+ <dc:description><%=h description %></dc:description>
+ <%- end -%>
+ <%- if relation -%>
+ <dc:relation><%=h relation %></dc:relation>
+ <%- end -%>
+ <%- if creator -%>
+ <dc:creator opf:role="aut"><%=h creator %></dc:creator>
+ <%- end -%>
+ <%- if publisher -%>
+ <dc:publisher><%=h publisher %></dc:publisher>
+ <%- end -%>
+ <%- if rights -%>
+ <dc:rights><%=h rights %></dc:rights>
+ <%- end -%>
+ </metadata>
+ <manifest>
+ <%- items.each do |item| -%>
+ <item id="<%=h item[:id] %>" href="<%=h item[:href] %>" media-type="<%=h item[:media_type] %>" />
+ <%- end -%>
+ </manifest>
+ <spine toc="ncx">
+ <%- itemrefs.each do |itemref| -%>
+ <itemref idref="<%=h itemref[:idref] %>" />
+ <%- end -%>
+ </spine>
+</package>
@@ -0,0 +1,44 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+require 'tmpdir'
+require 'fileutils'
+
+describe "EeePub::NCX" do
+ before do
+ @ncx = EeePub::NCX.new(
+ :uid => 'uid', :doc_title => 'title',
+ :nav_points => [
+ {:id => 'nav-1', :play_order => '1', :label => 'foo', :content => 'foo.html'},
+ {:id => 'nav-2', :play_order => '2', :label => 'bar', :content => 'bar.html'}
+ ]
+ )
+ end
+
+ it 'should set default values' do
+ @ncx.depth.should == 1
+ @ncx.total_page_count.should == 0
+ @ncx.max_page_number.should == 0
+ end
+
+ it 'should make xml' do
+ doc = Nokogiri::XML(@ncx.to_xml)
+ head = doc.at('head')
+ head.should_not be_nil
+
+ head.at("//xmlns:meta[@name='dtb:uid']")['content'].should == 'uid'
+ head.at("//xmlns:meta[@name='dtb:depth']")['content'].should == '1'
+ head.at("//xmlns:meta[@name='dtb:totalPageCount']")['content'].should == '0'
+ head.at("//xmlns:meta[@name='dtb:maxPageNumber']")['content'].should == '0'
+ head.at("//xmlns:docTitle/xmlns:text").inner_text.should == 'title'
+
+ nav_map = doc.at('navMap')
+ nav_map.should_not be_nil
+ nav_map.search('navPoint').each_with_index do |nav_point, index|
+ expect = @ncx.nav_points[index]
+ nav_point.attribute('id').value.should == expect[:id]
+ nav_point.attribute('playOrder').value.should == expect[:play_order]
+ nav_point.at('navLabel').at('text').inner_text.should == expect[:label]
+ nav_point.at('content').attribute('src').value.should == expect[:content]
+ end
+ end
+end
@@ -0,0 +1,36 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+require 'tmpdir'
+require 'fileutils'
+
+describe "EeePub::OCF" do
+ before do
+ @tmpdir = File.join(Dir.tmpdir, 'eeepub_test')
+ FileUtils.mkdir_p(@tmpdir)
+ @container = EeePub::OCF::Container.new(
+ :rootfiles => [{:full_path => 'foo.opf', :media_type => 'application/oebps-package+xml'}]
+ )
+ @ocf = EeePub::OCF.new(@tmpdir, :container => @container)
+ end
+
+ after do
+ FileUtils.rm_rf(@tmpdir)
+ end
+
+ it 'should make xml' do
+ doc = Nokogiri::XML(@container.to_xml)
+ rootfiles = doc.at('rootfiles')
+ rootfiles.should_not be_nil
+ rootfiles.search('rootfile').each_with_index do |rootfile, index|
+ expect = @container.rootfiles[index]
+ rootfile.attribute('full-path').value.should == expect[:full_path]
+ rootfile.attribute('media-type').value.should == expect[:media_type]
+ end
+ end
+
+ it 'should make epub' do
+ output_path = File.join(Dir.tmpdir, 'eeepub_test.epub')
+ @ocf.make(output_path)
+ File.exists?(output_path)
+ end
+end
Oops, something went wrong.

0 comments on commit 170c03d

Please sign in to comment.