diff --git a/Gemfile b/Gemfile index f79b668..8fc8a17 100644 --- a/Gemfile +++ b/Gemfile @@ -10,4 +10,7 @@ group :development do gem "bundler", "~> 1.0.0" gem "jeweler", "~> 1.6.4" gem "rcov", ">= 0" + gem "rdoc" end + +gem "nokogiri" \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..0bb1691 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,24 @@ +GEM + remote: http://rubygems.org/ + specs: + git (1.2.5) + jeweler (1.6.4) + bundler (~> 1.0) + git (>= 1.2.5) + rake + nokogiri (1.5.0) + rake (0.9.2) + rcov (0.9.9) + rdoc (3.8) + shoulda (2.11.3) + +PLATFORMS + ruby + +DEPENDENCIES + bundler (~> 1.0.0) + jeweler (~> 1.6.4) + nokogiri + rcov + rdoc + shoulda diff --git a/LICENSE.txt b/LICENSE.txt index dc2693f..5fdd713 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2011 magnolia-fan +Copyright (c) 2011 Gregory Eremin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.rdoc b/README.rdoc index 40815d6..44b8e7b 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,8 +1,9 @@ -= fb2 +== Usage -Description goes here. + require 'fb2' + @book = Fb2::parse(open('mybook.fb2')) -== Contributing to fb2 +== Contributing * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it @@ -14,6 +15,4 @@ Description goes here. == Copyright -Copyright (c) 2011 magnolia-fan. See LICENSE.txt for -further details. - +Copyright (c) 2011 Gregory Eremin. See LICENSE.txt for further details. diff --git a/Rakefile b/Rakefile index c7a7124..e4adc69 100644 --- a/Rakefile +++ b/Rakefile @@ -17,10 +17,11 @@ Jeweler::Tasks.new do |gem| gem.name = "fb2" gem.homepage = "http://github.com/magnolia-fan/fb2" gem.license = "MIT" - gem.summary = %Q{TODO: one-line summary of your gem} - gem.description = %Q{TODO: longer description of your gem} + gem.summary = %Q{FB2 util written in ruby} + gem.description = %Q{Parses FB2 (FictionBook 2) xml format into nice objects. Uses nokogiri.} gem.email = "magnolia_fan@me.com" - gem.authors = ["magnolia-fan"] + gem.authors = ["Gregory Eremin"] + gem.files += Dir['lib/**/*.rb'] # dependencies defined in Gemfile end Jeweler::RubygemsDotOrgTasks.new @@ -42,8 +43,8 @@ end task :default => :test -require 'rake/rdoctask' -Rake::RDocTask.new do |rdoc| +require 'rdoc/task' +RDoc::Task.new do |rdoc| version = File.exist?('VERSION') ? File.read('VERSION') : "" rdoc.rdoc_dir = 'rdoc' diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..7693c96 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.3 \ No newline at end of file diff --git a/fb2.gemspec b/fb2.gemspec new file mode 100644 index 0000000..8bac050 --- /dev/null +++ b/fb2.gemspec @@ -0,0 +1,68 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = %q{fb2} + s.version = "0.1.3" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = [%q{Gregory Eremin}] + s.date = %q{2011-07-17} + s.description = %q{Parses FB2 (FictionBook 2) xml format into nice objects. Uses nokogiri.} + s.email = %q{magnolia_fan@me.com} + s.extra_rdoc_files = [ + "LICENSE.txt", + "README.rdoc" + ] + s.files = [ + ".document", + "Gemfile", + "Gemfile.lock", + "LICENSE.txt", + "README.rdoc", + "Rakefile", + "VERSION", + "fb2.gemspec", + "lib/fb2.rb", + "lib/models/fb2_book.rb", + "lib/models/fb2_section.rb", + "test/fixtures/sample.fb2", + "test/helper.rb", + "test/test_fb2.rb" + ] + s.homepage = %q{http://github.com/magnolia-fan/fb2} + s.licenses = [%q{MIT}] + s.require_paths = [%q{lib}] + s.rubygems_version = %q{1.8.5} + s.summary = %q{FB2 util written in ruby} + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 1.0.0"]) + s.add_development_dependency(%q, ["~> 1.6.4"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.0.0"]) + s.add_dependency(%q, ["~> 1.6.4"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.0.0"]) + s.add_dependency(%q, ["~> 1.6.4"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end +end + diff --git a/lib/fb2.rb b/lib/fb2.rb index e69de29..f32af6a 100644 --- a/lib/fb2.rb +++ b/lib/fb2.rb @@ -0,0 +1,31 @@ +require 'nokogiri' +require 'models/fb2_book' +require 'models/fb2_section' + +class Fb2 + def self.parse data + xml = Nokogiri::XML(data) + + # building book + description = xml.css('description') + book = Fb2Book.new + book.title = description.css('title-info > book-title').text + book.author_first_name = description.css('title-info > author > first-name').text + book.author_last_name = description.css('title-info > author > last-name').text + book.annotation = description.css('title-info > annotation > p').text + book.genre = description.css('title-info > genre').text + book.lang = description.css('title-info > lang').text + book.keywords = description.css('title-info > keywords').text.split(', ') + book.sections = [] + + # building sections + xml.css('body > section').each do |s| + section = Fb2Section.new + section.title = s.css('title > p').text + section.contents = s.css('p').map{ |e| e.text }.drop(1) + book.sections << section + end + + book + end +end diff --git a/lib/models/fb2_book.rb b/lib/models/fb2_book.rb new file mode 100644 index 0000000..757a070 --- /dev/null +++ b/lib/models/fb2_book.rb @@ -0,0 +1,3 @@ +class Fb2Book + attr_accessor :title, :author_first_name, :author_last_name, :annotation, :genre, :lang, :keywords, :sections +end diff --git a/lib/models/fb2_section.rb b/lib/models/fb2_section.rb new file mode 100644 index 0000000..63d8b9c --- /dev/null +++ b/lib/models/fb2_section.rb @@ -0,0 +1,3 @@ +class Fb2Section + attr_accessor :title, :contents +end diff --git a/test/fixtures/sample.fb2 b/test/fixtures/sample.fb2 new file mode 100644 index 0000000..684a527 --- /dev/null +++ b/test/fixtures/sample.fb2 @@ -0,0 +1,59 @@ + + + + + fiction + + John + Doe + + Fiction Book + +

Hello

+
+ john, doe, fiction + 18.07.2011 + + en +
+ + + + + + + Fb2 Gem + 18.07.2011 + + + + 1.0 + + + +
+ + + <p>John Doe</p> + <empty-line/> + <p>Fiction Book</p> + +
+ + <p>Chapter 1</p> + +

Line one of the first chapter

+

Line two of the first chapter

+

Line three of the first chapter

+
+
+ + <p>Chapter 2</p> + +

Line one of the second chapter

+

Line two of the second chapter

+

Line three of the second chapter

+

Line four of the second chapter

+
+ +
diff --git a/test/test_fb2.rb b/test/test_fb2.rb index a6933de..9065da0 100644 --- a/test/test_fb2.rb +++ b/test/test_fb2.rb @@ -1,7 +1,50 @@ require 'helper' class TestFb2 < Test::Unit::TestCase - should "probably rename this file and start testing for real" do - flunk "hey buddy, you should probably rename this file and start testing for real" + context "parsing" do + setup do + @book = Fb2::parse(open('test/fixtures/sample.fb2')) + end + + should "parse books" do + assert_instance_of(Book, @book) + end + + should "load correct title" do + assert_equal('Fiction Book', @book.title) + end + + should "load correct author" do + assert_equal('John Doe', [@book.author_first_name, @book.author_last_name].join(' ')) + end + + should "load correct annotation" do + assert_equal('Hello', @book.annotation) + end + + should "load correct genre" do + assert_equal('fiction', @book.genre) + end + + should "load correct language" do + assert_equal('en', @book.lang) + end + + should "load correct keywords" do + assert_equal(['john', 'doe', 'fiction'], @book.keywords) + end + + should "load all two chapters" do + assert_equal(2, @book.sections.length) + end + + should "load correct second chapter's title" do + assert_equal('Chapter 2', @book.sections[1].title) + end + + should "load all strings in each section" do + assert_equal(3, @book.sections[0].contents.length) + assert_equal(4, @book.sections[1].contents.length) + end end end