csv_from_table 0.1.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/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ gem 'rspec'
2
+ gem 'nokogiri'
@@ -0,0 +1,19 @@
1
+ GEM
2
+ specs:
3
+ diff-lcs (1.1.3)
4
+ nokogiri (1.5.0)
5
+ rspec (2.6.0)
6
+ rspec-core (~> 2.6.0)
7
+ rspec-expectations (~> 2.6.0)
8
+ rspec-mocks (~> 2.6.0)
9
+ rspec-core (2.6.4)
10
+ rspec-expectations (2.6.0)
11
+ diff-lcs (~> 1.1.2)
12
+ rspec-mocks (2.6.0)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ nokogiri
19
+ rspec
@@ -0,0 +1,65 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require
4
+
5
+ class String
6
+
7
+ def csv_from_table(options={})
8
+ @csv_from_table = CSVFromTable.new
9
+ array = @csv_from_table.ar_from_table(self, options)
10
+ @csv_from_table.ar_to_csv(array)
11
+ end
12
+
13
+ end
14
+
15
+ class CSVFromTable
16
+
17
+ def ar_from_table(table_string, options={})
18
+ @options = options
19
+ doc = Nokogiri::HTML(table_string)
20
+ if !doc.css("table").empty?
21
+ @headers = table_headers(table_string)
22
+ lines = []
23
+ doc.css("tr").each do |node|
24
+ cells = []
25
+ node.css("td").each_with_index do |c, index|
26
+ cells << c.text if include_colunm?(index)
27
+ end
28
+ lines << cells
29
+ end
30
+ lines.keep_if { |el| !el.empty? }
31
+ else
32
+ raise TableNotFoundInString, "The string dosen't contain a valid <table> element."
33
+ end
34
+ end
35
+
36
+ def include_colunm?(index)
37
+ if @options[:only]
38
+ true if @options[:only].include?(@headers[index]) || @options[:only] == @headers[index]
39
+ elsif @options[:except]
40
+ true unless @options[:except].include?(@headers[index]) || @options[:except] == @headers[index]
41
+ else
42
+ true
43
+ end
44
+ end
45
+
46
+ def ar_to_csv(array)
47
+ csv_lines = []
48
+ array.each do |el|
49
+ csv_lines << el.join(", ")
50
+ end
51
+ csv_lines.join("\n")
52
+ end
53
+
54
+ def table_headers(table_string)
55
+ doc = Nokogiri::HTML(table_string)
56
+ headers = []
57
+ doc.css("th").each do |node|
58
+ headers << node.text
59
+ end
60
+ headers
61
+ end
62
+
63
+ end
64
+
65
+ class TableNotFoundInString < StandardError; end
@@ -0,0 +1,60 @@
1
+ $LOAD_PATH << '../lib'
2
+ require 'csv_from_table'
3
+
4
+ describe CSVFromTable do
5
+
6
+ before do
7
+ @sample = File.open("sample_table.html").read
8
+ @csv_from_table = CSVFromTable.new
9
+ end
10
+
11
+ it "should receive a HTML string with a table and return a array of arrays with the table's content" do
12
+ @csv_from_table.ar_from_table(@sample).length.should == 5
13
+ @csv_from_table.ar_from_table(@sample).should == [["Baseball bat", "$75.99", "500g", "Probably", "20%"],
14
+ ["Harmonica", "R$ 150,00", "100g", "Sure!", "0%"],
15
+ ["Pencil", "$1", "80g", "Just if there's an eraser", "100%"],
16
+ ["Eraser", "R$ 2,00", "120g", "Sure", "80%"],
17
+ ["Chocolate", "R$ 56", "5 Kg", "Sure", "0%"]]
18
+ end
19
+
20
+ it "should turn a array of arrays into CSV formated string" do
21
+ sample_ar = @csv_from_table.ar_from_table(@sample)
22
+ @csv_from_table.ar_to_csv(sample_ar).should == "Baseball bat, $75.99, 500g, Probably, 20%\nHarmonica, R$ 150,00, 100g, Sure!, 0%\nPencil, $1, 80g, Just if there's an eraser, 100%\nEraser, R$ 2,00, 120g, Sure, 80%\nChocolate, R$ 56, 5 Kg, Sure, 0%"
23
+ end
24
+
25
+ end
26
+
27
+ describe String do
28
+
29
+ before do
30
+ @sample_html_table = File.open("sample_table.html").read
31
+ end
32
+
33
+ it "should return the CSV format from a table" do
34
+ @sample_html_table.csv_from_table.should == "Baseball bat, $75.99, 500g, Probably, 20%\nHarmonica, R$ 150,00, 100g, Sure!, 0%\nPencil, $1, 80g, Just if there's an eraser, 100%\nEraser, R$ 2,00, 120g, Sure, 80%\nChocolate, R$ 56, 5 Kg, Sure, 0%"
35
+ end
36
+
37
+ it "should raise error when there's no table on the given string" do
38
+ sample_html_table = "No html table here!"
39
+ lambda { sample_html_table.csv_from_table }.should(raise_error(TableNotFoundInString))
40
+ end
41
+
42
+ describe "should receive options to filter colunms" do
43
+ it ":only => 'colunm name'" do
44
+ @sample_html_table.csv_from_table(:only => "Thing").should == "Baseball bat\nHarmonica\nPencil\nEraser\nChocolate"
45
+ end
46
+
47
+ it ":only => 'colunm array'" do
48
+ @sample_html_table.csv_from_table(:only => ["Thing", "Weight"]).should == "Baseball bat, 500g\nHarmonica, 100g\nPencil, 80g\nEraser, 120g\nChocolate, 5 Kg"
49
+ end
50
+
51
+ it ":except => 'colunm name'" do
52
+ @sample_html_table.csv_from_table(:except => "Price").should == "Baseball bat, 500g, Probably, 20%\nHarmonica, 100g, Sure!, 0%\nPencil, 80g, Just if there's an eraser, 100%\nEraser, 120g, Sure, 80%\nChocolate, 5 Kg, Sure, 0%"
53
+ end
54
+
55
+ it ":except => 'colunm name'" do
56
+ @sample_html_table.csv_from_table(:except => ["Price", "Is it worthy?", "Chances I forget it there"]).should == "Baseball bat, 500g\nHarmonica, 100g\nPencil, 80g\nEraser, 120g\nChocolate, 5 Kg"
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,47 @@
1
+ <h2>What if hter's more markup than the table?</h2>
2
+ <p>Extra texts shouldn't get into the CSV version of the table.</p>
3
+ <table>
4
+ <caption>Table of thing I would take with me in a trip to the moon!</caption>
5
+ <tr>
6
+ <th>Thing</th>
7
+ <th>Price</th>
8
+ <th>Weight</th>
9
+ <th>Is it worthy?</th>
10
+ <th>Chances I forget it there</th>
11
+ </tr>
12
+ <tr>
13
+ <td>Baseball bat</td>
14
+ <td>$75.99</td>
15
+ <td>500g</td>
16
+ <td>Probably</td>
17
+ <td>20%</td>
18
+ </tr>
19
+ <tr>
20
+ <td>Harmonica</td>
21
+ <td>R$ 150,00</td>
22
+ <td>100g</td>
23
+ <td>Sure!</td>
24
+ <td>0%</td>
25
+ </tr>
26
+ <tr>Text like this shouldn't be in the CSV
27
+ <td>Pencil</td>
28
+ <td>$1</td>
29
+ <td>80g</td>
30
+ <td>Just if there's an eraser</td>
31
+ <td>100%</td>
32
+ </tr>
33
+ <tr>
34
+ <td>Eraser</td>
35
+ <td>R$ 2,00</td>
36
+ <td>120g</td>
37
+ <td>Sure</td>
38
+ <td>80%</td>
39
+ </tr>
40
+ <tr>
41
+ <td>Chocolate</td>
42
+ <td>R$ 56</td>
43
+ <td>5 Kg</td>
44
+ <td>Sure</td>
45
+ <td>0%</td>
46
+ </tr>
47
+ </table>
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: csv_from_table
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Marco Antonio Fogaça Nogueira
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-24 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: Ruby library that spits out CSV from given HTML table, so you can use
15
+ the view helpers when formatting the CSV without having to include them on you models
16
+ or controllers.
17
+ email:
18
+ - marcofognog@gmail.com
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - Gemfile
24
+ - Gemfile.lock
25
+ - lib/csv_from_table.rb
26
+ - specs/csv_from_table_spec.rb
27
+ - specs/sample_table.html
28
+ homepage: http://github.com/marcofognog/csv_from_table
29
+ licenses: []
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.3.7
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 1.8.6
49
+ signing_key:
50
+ specification_version: 3
51
+ summary: Ruby library that spits out CSV from given HTML table.
52
+ test_files: []