table_fu 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/LICENSE +20 -0
- data/README +37 -0
- data/Rakefile +58 -0
- data/VERSION.yml +5 -0
- data/doc/TableFu/Datum.html +743 -0
- data/doc/TableFu/Formatting.html +469 -0
- data/doc/TableFu/Header.html +198 -0
- data/doc/TableFu/Row.html +508 -0
- data/doc/TableFu.html +1806 -0
- data/doc/_index.html +154 -0
- data/doc/class_list.html +36 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +50 -0
- data/doc/css/style.css +268 -0
- data/doc/file.README.html +89 -0
- data/doc/file_list.html +38 -0
- data/doc/frames.html +13 -0
- data/doc/index.html +89 -0
- data/doc/js/app.js +99 -0
- data/doc/js/full_list.js +106 -0
- data/doc/js/jquery.js +19 -0
- data/doc/method_list.html +363 -0
- data/doc/top-level-namespace.html +85 -0
- data/documentation/css/dawn.css +121 -0
- data/documentation/css/styles.css +63 -0
- data/documentation/images/proplogo.png +0 -0
- data/documentation/index.html.erb +148 -0
- data/examples/columns.rb +7 -0
- data/examples/columns_hidden.rb +5 -0
- data/examples/faceting.rb +2 -0
- data/examples/formatting_options.rb +6 -0
- data/examples/last_name.rb +4 -0
- data/examples/link.rb +11 -0
- data/examples/only.rb +6 -0
- data/examples/rails_helpers.rb +3 -0
- data/examples/sort_by_column.rb +11 -0
- data/examples/sort_by_number.rb +0 -0
- data/examples/totals.rb +2 -0
- data/examples/zap_joyce.rb +3 -0
- data/index.html +210 -0
- data/lib/table_fu/formatting.rb +52 -0
- data/lib/table_fu.rb +386 -0
- data/spec/assets/sample.csv +476 -0
- data/spec/assets/test.csv +8 -0
- data/spec/assets/test_macro.csv +8 -0
- data/spec/rcov.opts +2 -0
- data/spec/readme_example_spec.rb +39 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/table_fu_spec.rb +221 -0
- data/table_fu.gemspec +112 -0
- metadata +141 -0
@@ -0,0 +1,148 @@
|
|
1
|
+
<%
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__), "/../lib/table_fu")
|
3
|
+
|
4
|
+
require 'uv'
|
5
|
+
require 'FasterCSV'
|
6
|
+
require 'table_fu'
|
7
|
+
|
8
|
+
def code_for(file, output=true)
|
9
|
+
return '' unless File.exists?("examples/#{file}.rb")
|
10
|
+
file = File.open("examples/#{file}.rb").read
|
11
|
+
html = Uv.parse(file, "xhtml", "ruby", false, "dawn", false)
|
12
|
+
out = ''
|
13
|
+
if output
|
14
|
+
csv =<<-CSV
|
15
|
+
Author,Best Book,Number of Pages,Style
|
16
|
+
Samuel Beckett,Malone Muert,120,Modernism
|
17
|
+
James Joyce,Ulysses,644,Modernism
|
18
|
+
Nicholson Baker,Mezannine,150,Minimalism
|
19
|
+
Vladimir Sorokin,The Queue,263,Satire
|
20
|
+
CSV
|
21
|
+
if block_given?
|
22
|
+
out = yield instance_eval(file)
|
23
|
+
else
|
24
|
+
out = instance_eval(file).inspect
|
25
|
+
end
|
26
|
+
out = "<em>Returns:</em>" + Uv.parse(out, 'xhtml', 'ruby', false, 'dawn', false)
|
27
|
+
end
|
28
|
+
"#{html}#{out}"
|
29
|
+
end %>
|
30
|
+
<!DOCTYPE html>
|
31
|
+
<html>
|
32
|
+
<head>
|
33
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
34
|
+
<title>TableFu</title>
|
35
|
+
<link rel="stylesheet" type="text/css" href="documentation/css/styles.css" />
|
36
|
+
<link rel="stylesheet" type="text/css" href="documentation/css/dawn.css" />
|
37
|
+
</head>
|
38
|
+
|
39
|
+
<body>
|
40
|
+
<a href="http://www.propublica.org" class="propublica"> </a>
|
41
|
+
<h1>TableFu <small>– Version: <%=
|
42
|
+
config = YAML.load(File.read('VERSION.yml'))
|
43
|
+
"#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
44
|
+
%></small></h1>
|
45
|
+
|
46
|
+
<p><a href="http://github.com/propublica/table-fu">TableFu</a> is a ruby gem for spreadsheet-style handling of arrays (e.g. filtering, formatting, and sorting by "column" or "row"). In addition, it has the ability to <a href="#facet">facet</a> — or group — rows according to cell value. It was developed as a backend for its companion project <a href="http://www.github.com/propublica/table-setter">TableSetter</a>.</p>
|
47
|
+
<p>For example, <strong>TableFu</strong> can consume a csv file and sort on a column:
|
48
|
+
<%= code_for "sort_by_column" do |ret|
|
49
|
+
ret.rows.inspect
|
50
|
+
end
|
51
|
+
%>
|
52
|
+
</p>
|
53
|
+
<h2><a id="toc">Table of Contents</a></h2>
|
54
|
+
<ul>
|
55
|
+
<li><a href="#installation">Installation</a></li>
|
56
|
+
<li><a href="#usage">Usage</a></li>
|
57
|
+
<li><a href="#macros">Macros / Formatting</a></li>
|
58
|
+
<li><a href="#faceting">Faceting</a></li>
|
59
|
+
<li><a href="#manipulation">Manipulation</a></li>
|
60
|
+
<li><a href="#links">Links</a></li>
|
61
|
+
<li><a href="#credits">Credits</a></li>
|
62
|
+
<li><a href="#license">License</a></li>
|
63
|
+
</ul>
|
64
|
+
<h2><a id="installation" href="#toc">Installation</a></h2>
|
65
|
+
<p><strong>TableFu</strong> is available as a rubygem:
|
66
|
+
<pre class="dawn">
|
67
|
+
gem install table_fu</pre>
|
68
|
+
or from the actual source:
|
69
|
+
<pre class="dawn">
|
70
|
+
git clone git://github.com/propublica/table-fu.git
|
71
|
+
cd table-fu
|
72
|
+
rake install</pre>
|
73
|
+
</p>
|
74
|
+
<h2><a id="usage" href="#toc">Usage</a></h2>
|
75
|
+
<p>
|
76
|
+
The <strong>TableFu</strong> constructor takes two arguments; a 2 dimensional array or csv (file object or string) and a hash of column options or a block. TableFu will assume that the first row of the array contains the column headers. The simple options are:</p>
|
77
|
+
<p><strong>sorted_by:</strong> the column to sort by, it defaults to no sorting at all.
|
78
|
+
<%= code_for "sort_by_column" do |ret|
|
79
|
+
ret.rows.inspect
|
80
|
+
end
|
81
|
+
%>
|
82
|
+
</p>
|
83
|
+
<p><strong>columns:</strong> the columns to include in the table, useful when reordering and filtering extraneous columns. If no arguments are provided, <strong>TableFu</strong> will include all columns by default.
|
84
|
+
<%= code_for "columns" %>
|
85
|
+
Note that the columns are still accessible directly even if they're not in the columns array.
|
86
|
+
<%= code_for "columns_hidden" %>
|
87
|
+
</p>
|
88
|
+
|
89
|
+
<h2><a id="macros" href="#toc">Macros / Formatting</a></h2>
|
90
|
+
<p><strong>TableFu</strong> allows you to format columns of cells through the use of macros. See <a href="http://github.com/propublica/table-fu/blob/master/lib/table_fu/formatting.rb"><strong>TableFu::Formatting</strong></a> for the predefined macros available. </p>
|
91
|
+
<p>The <strong>formatting</strong> attribute should be a hash of the form:
|
92
|
+
<%= code_for "formatting_options", false %>
|
93
|
+
which will call the macro on the column name with the arguments if specified.
|
94
|
+
</p>
|
95
|
+
<p>For example, you can use the <strong>last_name</strong> formatter to extract the last name of a cell containing a person's name:
|
96
|
+
<%= code_for "last_name" %>
|
97
|
+
</p>
|
98
|
+
<p>Or you can build a meta column from two others containing an html link like so:
|
99
|
+
<%= code_for "link" %>
|
100
|
+
</p>
|
101
|
+
<p>Of course, you can provide your own macros by patching <a href="http://github.com/propublica/table-fu/blob/master/lib/table_fu/formatting.rb">TableFu::Formatting</a>. <a href="http://www.github.com/propublica/table-setter">TableSetter</a> includes rails view helpers directly in <strong>TableFu::Formatting</strong>.
|
102
|
+
<%= code_for "rails_helpers", false %>
|
103
|
+
</p>
|
104
|
+
|
105
|
+
<h2><a id="faceting" href="#toc">Faceting</a></h2>
|
106
|
+
<p>Faceting provides a way to group rows together using a cell value they share in common. Calling <strong>TableFu#faceted_by</strong> returns an array of table fu instances each with a <strong>faceted_on</strong> attribute and with only the rows where that value appears.
|
107
|
+
</p>
|
108
|
+
<p>In this example there are 2 rows where "Modernism" appears in the style column, so calling <strong>faceted_on</strong> with the argument <strong>"Style"</strong> returns a <strong>TableFu</strong> instance with those rows grouped together:
|
109
|
+
<%= code_for "faceting" do |s|
|
110
|
+
s.map { |table|
|
111
|
+
"table.faceted_on => #{table.faceted_on}, table.rows => #{table.rows.inspect}\n"
|
112
|
+
}.join('')
|
113
|
+
end %>
|
114
|
+
</p>
|
115
|
+
<h2><a id="manipulation" href="#toc">Manipulation / Output</a></h2>
|
116
|
+
<h3>Deleting Rows</h3>
|
117
|
+
<p>In addition to hiding columns and faceting <strong>TableFu</strong> can delete rows from the csv. Let's get rid of James Joyce (no one ever finished <em>Ulysses</em> anyway):
|
118
|
+
<%= code_for "zap_joyce" do |s|
|
119
|
+
s.rows.inspect
|
120
|
+
end %>
|
121
|
+
The deleted rows are still available in <strong>@deleted_rows</strong> for later access:
|
122
|
+
<%= code_for "zap_joyce" do |s|
|
123
|
+
"table.deleted_rows => #{s.deleted_rows.inspect}"
|
124
|
+
end %>
|
125
|
+
</p>
|
126
|
+
<h3>Pagination</h3>
|
127
|
+
<p>If you want only a chunk of the data, say to paginate your table, you can call <strong>only!</strong> with the range of values you want to keep:
|
128
|
+
<%= code_for "only" %>
|
129
|
+
</p>
|
130
|
+
<h3>Sum</h3>
|
131
|
+
<p>TableFu can also sum a column of values:
|
132
|
+
<%= code_for "totals" %>
|
133
|
+
</p>
|
134
|
+
<h2><a id="links" href="#toc">Links</a></h2>
|
135
|
+
<ul>
|
136
|
+
<li><a href="http://github.com/propublica/table-setter">TableSetter</a><br>A Sinatra app that uses <strong>TableFu</strong> to render public Google Spreadsheets in custom HTML.</li>
|
137
|
+
<li><a href="http://github.com/propublica/table-setter-generator">TableSetter Generator</a><br>
|
138
|
+
A rails generator that allows you to create a rails app like TableSetter.
|
139
|
+
</li>
|
140
|
+
<li><a href="http://github.com/propublica/table-fu/issues">Issues</a><br>Post bug reports and feature requests here.</li>
|
141
|
+
<li><a href="doc/index.html">API Docs</a></li>
|
142
|
+
</ul>
|
143
|
+
<h2><a id="credits" href="#toc">Credits</a></h2>
|
144
|
+
<p><a href="http://github.com/thejefflarson">Jeff Larson</a> (Maintainer), <a href="http://github.com/brianboyer/">Brian Boyer</a>, <a href="http://github.com/kleinmatic">Scott Klein</a>, <a href="http://github.com/markpercival">Mark Percival</a>, and <a href="http://github.com/seebq">Charles Brian Quinn</a>.</p>
|
145
|
+
<h2><a id="license" href="#toc">License</a></h2>
|
146
|
+
<pre><%= File.open("LICENSE").read %></pre>
|
147
|
+
</body>
|
148
|
+
</html>
|
data/examples/columns.rb
ADDED
data/examples/link.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
csv = <<-EOF
|
2
|
+
Website,URL
|
3
|
+
Propublica,http://www.propublica.org/
|
4
|
+
EOF
|
5
|
+
|
6
|
+
spreadsheet = TableFu.new(csv) do |s|
|
7
|
+
s.formatting = {"Link" => {'method' => 'link', 'arguments' => ['Website','URL']}}
|
8
|
+
s.columns = ["Link"]
|
9
|
+
end
|
10
|
+
|
11
|
+
spreadsheet.rows[0].column_for('Link').to_s
|
data/examples/only.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
csv =<<-CSV
|
2
|
+
Author,Best Book,Number of Pages,Style
|
3
|
+
Samuel Beckett,Malone Muert,120,Modernism
|
4
|
+
James Joyce,Ulysses,644,Modernism
|
5
|
+
Nicholson Baker,Mezannine,150,Minimalism
|
6
|
+
Vladimir Sorokin,The Queue,263,Satire
|
7
|
+
CSV
|
8
|
+
|
9
|
+
spreadsheet = TableFu.new(csv) do |s|
|
10
|
+
s.sorted_by = {'Best Book' => {'order' => 'ascending'}}
|
11
|
+
end
|
File without changes
|
data/examples/totals.rb
ADDED
data/index.html
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
|
2
|
+
<!DOCTYPE html>
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
6
|
+
<title>TableFu</title>
|
7
|
+
<link rel="stylesheet" type="text/css" href="documentation/css/styles.css" />
|
8
|
+
<link rel="stylesheet" type="text/css" href="documentation/css/dawn.css" />
|
9
|
+
</head>
|
10
|
+
|
11
|
+
<body>
|
12
|
+
<a href="http://www.propublica.org" class="propublica"> </a>
|
13
|
+
<h1>TableFu <small>– Version: 0.1.1</small></h1>
|
14
|
+
|
15
|
+
<p><a href="http://github.com/propublica/table-fu">TableFu</a> is a ruby gem for spreadsheet-style handling of arrays (e.g. filtering, formatting, and sorting by "column" or "row"). In addition, it has the ability to <a href="#facet">facet</a> — or group — rows according to cell value. It was developed as a backend for its companion project <a href="http://www.github.com/propublica/table-setter">TableSetter</a>.</p>
|
16
|
+
<p>For example, <strong>TableFu</strong> can consume a csv file and sort on a column:
|
17
|
+
<pre class="dawn">csv <span class="Keyword">=</span><<-CSV
|
18
|
+
Author,Best Book,Number of Pages,Style
|
19
|
+
Samuel Beckett,Malone Muert,120,Modernism
|
20
|
+
James Joyce,Ulysses,644,Modernism
|
21
|
+
Nicholson Baker,Mezannine,150,Minimalism
|
22
|
+
Vladimir Sorokin,The Queue,263,Satire
|
23
|
+
CSV
|
24
|
+
|
25
|
+
spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv) <span class="Keyword">do </span><span class="PunctuationSeparator">|</span><span class="Variable">s</span><span class="PunctuationSeparator">|</span>
|
26
|
+
s<span class="PunctuationSeparator">.</span><span class="Entity">sorted_by</span> <span class="Keyword">=</span> {'Best Book' <span class="PunctuationSeparator">=></span> {'order' <span class="PunctuationSeparator">=></span> 'ascending'}}
|
27
|
+
<span class="Keyword">end</span>
|
28
|
+
</pre><em>Returns:</em><pre class="dawn">[["Samuel Beckett"<span class="PunctuationSeparator">,</span> "Malone Muert"<span class="PunctuationSeparator">,</span> "120"<span class="PunctuationSeparator">,</span> "Modernism"]<span class="PunctuationSeparator">,</span> ["Nicholson Baker"<span class="PunctuationSeparator">,</span> "Mezannine"<span class="PunctuationSeparator">,</span> "150"<span class="PunctuationSeparator">,</span> "Minimalism"]<span class="PunctuationSeparator">,</span> ["Vladimir Sorokin"<span class="PunctuationSeparator">,</span> "The Queue"<span class="PunctuationSeparator">,</span> "263"<span class="PunctuationSeparator">,</span> "Satire"]<span class="PunctuationSeparator">,</span> ["James Joyce"<span class="PunctuationSeparator">,</span> "Ulysses"<span class="PunctuationSeparator">,</span> "644"<span class="PunctuationSeparator">,</span> "Modernism"]]
|
29
|
+
</pre>
|
30
|
+
</p>
|
31
|
+
<h2><a id="toc">Table of Contents</a></h2>
|
32
|
+
<ul>
|
33
|
+
<li><a href="#installation">Installation</a></li>
|
34
|
+
<li><a href="#usage">Usage</a></li>
|
35
|
+
<li><a href="#macros">Macros / Formatting</a></li>
|
36
|
+
<li><a href="#faceting">Faceting</a></li>
|
37
|
+
<li><a href="#manipulation">Manipulation</a></li>
|
38
|
+
<li><a href="#links">Links</a></li>
|
39
|
+
<li><a href="#credits">Credits</a></li>
|
40
|
+
<li><a href="#license">License</a></li>
|
41
|
+
</ul>
|
42
|
+
<h2><a id="installation" href="#toc">Installation</a></h2>
|
43
|
+
<p><strong>TableFu</strong> is available as a rubygem:
|
44
|
+
<pre class="dawn">
|
45
|
+
gem install table_fu</pre>
|
46
|
+
or from the actual source:
|
47
|
+
<pre class="dawn">
|
48
|
+
git clone git://github.com/propublica/table-fu.git
|
49
|
+
cd table-fu
|
50
|
+
rake install</pre>
|
51
|
+
</p>
|
52
|
+
<h2><a id="usage" href="#toc">Usage</a></h2>
|
53
|
+
<p>
|
54
|
+
The <strong>TableFu</strong> constructor takes two arguments; a 2 dimensional array or csv (file object or string) and a hash of column options or a block. TableFu will assume that the first row of the array contains the column headers. The simple options are:</p>
|
55
|
+
<p><strong>sorted_by:</strong> the column to sort by, it defaults to no sorting at all.
|
56
|
+
<pre class="dawn">csv <span class="Keyword">=</span><<-CSV
|
57
|
+
Author,Best Book,Number of Pages,Style
|
58
|
+
Samuel Beckett,Malone Muert,120,Modernism
|
59
|
+
James Joyce,Ulysses,644,Modernism
|
60
|
+
Nicholson Baker,Mezannine,150,Minimalism
|
61
|
+
Vladimir Sorokin,The Queue,263,Satire
|
62
|
+
CSV
|
63
|
+
|
64
|
+
spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv) <span class="Keyword">do </span><span class="PunctuationSeparator">|</span><span class="Variable">s</span><span class="PunctuationSeparator">|</span>
|
65
|
+
s<span class="PunctuationSeparator">.</span><span class="Entity">sorted_by</span> <span class="Keyword">=</span> {'Best Book' <span class="PunctuationSeparator">=></span> {'order' <span class="PunctuationSeparator">=></span> 'ascending'}}
|
66
|
+
<span class="Keyword">end</span>
|
67
|
+
</pre><em>Returns:</em><pre class="dawn">[["Samuel Beckett"<span class="PunctuationSeparator">,</span> "Malone Muert"<span class="PunctuationSeparator">,</span> "120"<span class="PunctuationSeparator">,</span> "Modernism"]<span class="PunctuationSeparator">,</span> ["Nicholson Baker"<span class="PunctuationSeparator">,</span> "Mezannine"<span class="PunctuationSeparator">,</span> "150"<span class="PunctuationSeparator">,</span> "Minimalism"]<span class="PunctuationSeparator">,</span> ["Vladimir Sorokin"<span class="PunctuationSeparator">,</span> "The Queue"<span class="PunctuationSeparator">,</span> "263"<span class="PunctuationSeparator">,</span> "Satire"]<span class="PunctuationSeparator">,</span> ["James Joyce"<span class="PunctuationSeparator">,</span> "Ulysses"<span class="PunctuationSeparator">,</span> "644"<span class="PunctuationSeparator">,</span> "Modernism"]]
|
68
|
+
</pre>
|
69
|
+
</p>
|
70
|
+
<p><strong>columns:</strong> the columns to include in the table, useful when reordering and filtering extraneous columns. If no arguments are provided, <strong>TableFu</strong> will include all columns by default.
|
71
|
+
<pre class="dawn">spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv) <span class="Keyword">do </span><span class="PunctuationSeparator">|</span><span class="Variable">s</span><span class="PunctuationSeparator">|</span>
|
72
|
+
s<span class="PunctuationSeparator">.</span><span class="Entity">columns</span> <span class="Keyword">=</span> ["Best Book"<span class="PunctuationSeparator">,</span> "Author"]
|
73
|
+
<span class="Keyword">end</span>
|
74
|
+
|
75
|
+
spreadsheet<span class="PunctuationSeparator">.</span><span class="Entity">columns</span><span class="PunctuationSeparator">.</span><span class="Entity">map</span> <span class="Keyword">do </span><span class="PunctuationSeparator">|</span><span class="Variable">column</span><span class="PunctuationSeparator">|</span>
|
76
|
+
spreadsheet<span class="PunctuationSeparator">.</span><span class="Entity">rows</span>[<span class="Constant">0</span>]<span class="PunctuationSeparator">.</span><span class="Entity">column_for</span>(column)<span class="PunctuationSeparator">.</span><span class="Entity">to_s</span>
|
77
|
+
<span class="Keyword">end</span>
|
78
|
+
</pre><em>Returns:</em><pre class="dawn">["Malone Muert"<span class="PunctuationSeparator">,</span> "Samuel Beckett"]
|
79
|
+
</pre>
|
80
|
+
Note that the columns are still accessible directly even if they're not in the columns array.
|
81
|
+
<pre class="dawn">spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv) <span class="Keyword">do </span><span class="PunctuationSeparator">|</span><span class="Variable">s</span><span class="PunctuationSeparator">|</span>
|
82
|
+
s<span class="PunctuationSeparator">.</span><span class="Entity">columns</span> <span class="Keyword">=</span> ["Best Book"<span class="PunctuationSeparator">,</span> "Author"]
|
83
|
+
<span class="Keyword">end</span>
|
84
|
+
|
85
|
+
spreadsheet<span class="PunctuationSeparator">.</span><span class="Entity">rows</span>[<span class="Constant">0</span>]<span class="PunctuationSeparator">.</span><span class="Entity">column_for</span>('Style')<span class="PunctuationSeparator">.</span>to_s
|
86
|
+
</pre><em>Returns:</em><pre class="dawn">"Modernism"
|
87
|
+
</pre>
|
88
|
+
</p>
|
89
|
+
|
90
|
+
<h2><a id="macros" href="#toc">Macros / Formatting</a></h2>
|
91
|
+
<p><strong>TableFu</strong> allows you to format columns of cells through the use of macros. See <a href="http://github.com/propublica/table-fu/blob/master/lib/table_fu/formatting.rb"><strong>TableFu::Formatting</strong></a> for the predefined macros available. </p>
|
92
|
+
<p>The <strong>formatting</strong> attribute should be a hash of the form:
|
93
|
+
<pre class="dawn">{"Column Name" <span class="PunctuationSeparator">=></span> 'Formatting Method Name'}
|
94
|
+
|
95
|
+
<span class="Comment"><span class="Comment">#</span> or</span>
|
96
|
+
|
97
|
+
{"Meta Column Name" <span class="PunctuationSeparator">=></span> {"method" <span class="PunctuationSeparator">=></span> "Method Name"<span class="PunctuationSeparator">,</span> "arguments" <span class="PunctuationSeparator">=></span> ['Column 1'<span class="PunctuationSeparator">,</span> 'Column 2' <span class="PunctuationSeparator">.</span><span class="PunctuationSeparator">.</span><span class="PunctuationSeparator">.</span> 'Column N']}}
|
98
|
+
|
99
|
+
</pre>
|
100
|
+
which will call the macro on the column name with the arguments if specified.
|
101
|
+
</p>
|
102
|
+
<p>For example, you can use the <strong>last_name</strong> formatter to extract the last name of a cell containing a person's name:
|
103
|
+
<pre class="dawn">spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv) <span class="Keyword">do </span><span class="PunctuationSeparator">|</span><span class="Variable">s</span><span class="PunctuationSeparator">|</span>
|
104
|
+
s<span class="PunctuationSeparator">.</span><span class="Entity">formatting</span> <span class="Keyword">=</span> {"Author" <span class="PunctuationSeparator">=></span> 'last_name'}
|
105
|
+
<span class="Keyword">end</span>
|
106
|
+
spreadsheet<span class="PunctuationSeparator">.</span><span class="Entity">rows</span>[<span class="Constant">0</span>]<span class="PunctuationSeparator">.</span><span class="Entity">column_for</span>('Author')<span class="PunctuationSeparator">.</span>to_s
|
107
|
+
</pre><em>Returns:</em><pre class="dawn">"Beckett"
|
108
|
+
</pre>
|
109
|
+
</p>
|
110
|
+
<p>Or you can build a meta column from two others containing an html link like so:
|
111
|
+
<pre class="dawn">csv <span class="Keyword">=</span> <<-EOF
|
112
|
+
Website,URL
|
113
|
+
Propublica,http://www.propublica.org/
|
114
|
+
EOF
|
115
|
+
|
116
|
+
spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv) <span class="Keyword">do </span><span class="PunctuationSeparator">|</span><span class="Variable">s</span><span class="PunctuationSeparator">|</span>
|
117
|
+
s<span class="PunctuationSeparator">.</span><span class="Entity">formatting</span> <span class="Keyword">=</span> {"Link" <span class="PunctuationSeparator">=></span> {'method' <span class="PunctuationSeparator">=></span> 'link'<span class="PunctuationSeparator">,</span> 'arguments' <span class="PunctuationSeparator">=></span> ['Website'<span class="PunctuationSeparator">,</span>'URL']}}
|
118
|
+
s<span class="PunctuationSeparator">.</span><span class="Entity">columns</span> <span class="Keyword">=</span> ["Link"]
|
119
|
+
<span class="Keyword">end</span>
|
120
|
+
|
121
|
+
spreadsheet<span class="PunctuationSeparator">.</span><span class="Entity">rows</span>[<span class="Constant">0</span>]<span class="PunctuationSeparator">.</span><span class="Entity">column_for</span>('Link')<span class="PunctuationSeparator">.</span>to_s
|
122
|
+
</pre><em>Returns:</em><pre class="dawn">"<a href='http://www.propublica.org/' title='Propublica'>Propublica</a>"
|
123
|
+
</pre>
|
124
|
+
</p>
|
125
|
+
<p>Of course, you can provide your own macros by patching <a href="http://github.com/propublica/table-fu/blob/master/lib/table_fu/formatting.rb">TableFu::Formatting</a>. <a href="http://www.github.com/propublica/table-setter">TableSetter</a> includes rails view helpers directly in <strong>TableFu::Formatting</strong>.
|
126
|
+
<pre class="dawn"><span class="Keyword">class</span> <span class="Entity">TableFu::Formatting</span>
|
127
|
+
<span class="Keyword">extend</span> <span class="Support">ActionView</span><span class="PunctuationSeparator">::</span><span class="Entity">Helpers</span><span class="PunctuationSeparator">::</span><span class="Entity">NumberHelper</span>
|
128
|
+
<span class="Keyword">end</span>
|
129
|
+
</pre>
|
130
|
+
</p>
|
131
|
+
|
132
|
+
<h2><a id="faceting" href="#toc">Faceting</a></h2>
|
133
|
+
<p>Faceting provides a way to group rows together using a cell value they share in common. Calling <strong>TableFu#faceted_by</strong> returns an array of table fu instances each with a <strong>faceted_on</strong> attribute and with only the rows where that value appears.
|
134
|
+
</p>
|
135
|
+
<p>In this example there are 2 rows where "Modernism" appears in the style column, so calling <strong>faceted_on</strong> with the argument <strong>"Style"</strong> returns a <strong>TableFu</strong> instance with those rows grouped together:
|
136
|
+
<pre class="dawn">spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv)
|
137
|
+
spreadsheet<span class="PunctuationSeparator">.</span><span class="Entity">faceted_by</span> "Style"
|
138
|
+
</pre><em>Returns:</em><pre class="dawn">table<span class="PunctuationSeparator">.</span><span class="Entity">faceted_on</span> <span class="PunctuationSeparator">=></span> <span class="Variable">Minimalism</span><span class="PunctuationSeparator">,</span> table<span class="PunctuationSeparator">.</span><span class="Entity">rows</span> <span class="PunctuationSeparator">=></span> [["Nicholson Baker"<span class="PunctuationSeparator">,</span> "Mezannine"<span class="PunctuationSeparator">,</span> "150"<span class="PunctuationSeparator">,</span> "Minimalism"]]
|
139
|
+
table<span class="PunctuationSeparator">.</span><span class="Entity">faceted_on</span> <span class="PunctuationSeparator">=></span> <span class="Variable">Modernism</span><span class="PunctuationSeparator">,</span> table<span class="PunctuationSeparator">.</span><span class="Entity">rows</span> <span class="PunctuationSeparator">=></span> [["Samuel Beckett"<span class="PunctuationSeparator">,</span> "Malone Muert"<span class="PunctuationSeparator">,</span> "120"<span class="PunctuationSeparator">,</span> "Modernism"]<span class="PunctuationSeparator">,</span> ["James Joyce"<span class="PunctuationSeparator">,</span> "Ulysses"<span class="PunctuationSeparator">,</span> "644"<span class="PunctuationSeparator">,</span> "Modernism"]]
|
140
|
+
table<span class="PunctuationSeparator">.</span><span class="Entity">faceted_on</span> <span class="PunctuationSeparator">=></span> <span class="Variable">Satire</span><span class="PunctuationSeparator">,</span> table<span class="PunctuationSeparator">.</span><span class="Entity">rows</span> <span class="PunctuationSeparator">=></span> [["Vladimir Sorokin"<span class="PunctuationSeparator">,</span> "The Queue"<span class="PunctuationSeparator">,</span> "263"<span class="PunctuationSeparator">,</span> "Satire"]]
|
141
|
+
</pre>
|
142
|
+
</p>
|
143
|
+
<h2><a id="manipulation" href="#toc">Manipulation / Output</a></h2>
|
144
|
+
<h3>Deleting Rows</h3>
|
145
|
+
<p>In addition to hiding columns and faceting <strong>TableFu</strong> can delete rows from the csv. Let's get rid of James Joyce (no one ever finished <em>Ulysses</em> anyway):
|
146
|
+
<pre class="dawn">spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv) <span class="Keyword">do </span><span class="PunctuationSeparator">|</span><span class="Variable">s</span><span class="PunctuationSeparator">|</span>
|
147
|
+
s<span class="PunctuationSeparator">.</span><span class="Entity">delete_rows!</span> [<span class="Constant">1</span>]
|
148
|
+
<span class="Keyword">end</span>
|
149
|
+
</pre><em>Returns:</em><pre class="dawn">[["Samuel Beckett"<span class="PunctuationSeparator">,</span> "Malone Muert"<span class="PunctuationSeparator">,</span> "120"<span class="PunctuationSeparator">,</span> "Modernism"]<span class="PunctuationSeparator">,</span> ["Nicholson Baker"<span class="PunctuationSeparator">,</span> "Mezannine"<span class="PunctuationSeparator">,</span> "150"<span class="PunctuationSeparator">,</span> "Minimalism"]<span class="PunctuationSeparator">,</span> ["Vladimir Sorokin"<span class="PunctuationSeparator">,</span> "The Queue"<span class="PunctuationSeparator">,</span> "263"<span class="PunctuationSeparator">,</span> "Satire"]]
|
150
|
+
</pre>
|
151
|
+
The deleted rows are still available in <strong>@deleted_rows</strong> for later access:
|
152
|
+
<pre class="dawn">spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv) <span class="Keyword">do </span><span class="PunctuationSeparator">|</span><span class="Variable">s</span><span class="PunctuationSeparator">|</span>
|
153
|
+
s<span class="PunctuationSeparator">.</span><span class="Entity">delete_rows!</span> [<span class="Constant">1</span>]
|
154
|
+
<span class="Keyword">end</span>
|
155
|
+
</pre><em>Returns:</em><pre class="dawn">table<span class="PunctuationSeparator">.</span><span class="Entity">deleted_rows</span> <span class="PunctuationSeparator">=></span> [["James Joyce"<span class="PunctuationSeparator">,</span> "Ulysses"<span class="PunctuationSeparator">,</span> "644"<span class="PunctuationSeparator">,</span> "Modernism"]]
|
156
|
+
</pre>
|
157
|
+
</p>
|
158
|
+
<h3>Pagination</h3>
|
159
|
+
<p>If you want only a chunk of the data, say to paginate your table, you can call <strong>only!</strong> with the range of values you want to keep:
|
160
|
+
<pre class="dawn">spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv) <span class="Keyword">do </span><span class="PunctuationSeparator">|</span><span class="Variable">s</span><span class="PunctuationSeparator">|</span>
|
161
|
+
s<span class="PunctuationSeparator">.</span><span class="Entity">sorted_by</span> <span class="Keyword">=</span> {'Style' <span class="PunctuationSeparator">=></span> {"order" <span class="PunctuationSeparator">=></span> 'ascending'}}
|
162
|
+
<span class="Keyword">end</span>
|
163
|
+
|
164
|
+
spreadsheet<span class="PunctuationSeparator">.</span><span class="Entity">only!</span>(<span class="Constant">2</span><span class="PunctuationSeparator">.</span><span class="PunctuationSeparator">.</span><span class="Constant">4</span>)
|
165
|
+
spreadsheet<span class="PunctuationSeparator">.</span>rows
|
166
|
+
</pre><em>Returns:</em><pre class="dawn">[["Nicholson Baker"<span class="PunctuationSeparator">,</span> "Mezannine"<span class="PunctuationSeparator">,</span> "150"<span class="PunctuationSeparator">,</span> "Minimalism"]<span class="PunctuationSeparator">,</span> ["Vladimir Sorokin"<span class="PunctuationSeparator">,</span> "The Queue"<span class="PunctuationSeparator">,</span> "263"<span class="PunctuationSeparator">,</span> "Satire"]]
|
167
|
+
</pre>
|
168
|
+
</p>
|
169
|
+
<h3>Sum</h3>
|
170
|
+
<p>TableFu can also sum a column of values:
|
171
|
+
<pre class="dawn">spreadsheet <span class="Keyword">=</span> <span class="Support">TableFu</span><span class="PunctuationSeparator">.</span><span class="Entity">new</span>(csv)
|
172
|
+
spreadsheet<span class="PunctuationSeparator">.</span><span class="Entity">total_for</span>('Number of Pages')<span class="PunctuationSeparator">.</span>to_s
|
173
|
+
</pre><em>Returns:</em><pre class="dawn"><span class="Constant">1177</span>
|
174
|
+
</pre>
|
175
|
+
</p>
|
176
|
+
<h2><a id="links" href="#toc">Links</a></h2>
|
177
|
+
<ul>
|
178
|
+
<li><a href="http://github.com/propublica/table-setter">TableSetter</a><br>A Sinatra app that uses <strong>TableFu</strong> to render public Google Spreadsheets in custom HTML.</li>
|
179
|
+
<li><a href="http://github.com/propublica/table-setter-generator">TableSetter Generator</a><br>
|
180
|
+
A rails generator that allows you to create a rails app like TableSetter.
|
181
|
+
</li>
|
182
|
+
<li><a href="http://github.com/propublica/table-fu/issues">Issues</a><br>Post bug reports and feature requests here.</li>
|
183
|
+
<li><a href="doc/index.html">API Docs</a></li>
|
184
|
+
</ul>
|
185
|
+
<h2><a id="credits" href="#toc">Credits</a></h2>
|
186
|
+
<p><a href="http://github.com/thejefflarson">Jeff Larson</a> (Maintainer), <a href="http://github.com/brianboyer/">Brian Boyer</a>, <a href="http://github.com/kleinmatic">Scott Klein</a>, <a href="http://github.com/markpercival">Mark Percival</a>, and <a href="http://github.com/seebq">Charles Brian Quinn</a>.</p>
|
187
|
+
<h2><a id="license" href="#toc">License</a></h2>
|
188
|
+
<pre>Copyright (c) 2010 ProPublica
|
189
|
+
|
190
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
191
|
+
a copy of this software and associated documentation files (the
|
192
|
+
"Software"), to deal in the Software without restriction, including
|
193
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
194
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
195
|
+
permit persons to whom the Software is furnished to do so, subject to
|
196
|
+
the following conditions:
|
197
|
+
|
198
|
+
The above copyright notice and this permission notice shall be
|
199
|
+
included in all copies or substantial portions of the Software.
|
200
|
+
|
201
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
202
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
203
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
204
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
205
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
206
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
207
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
208
|
+
</pre>
|
209
|
+
</body>
|
210
|
+
</html>
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Override this class to add more formatting methods
|
2
|
+
#
|
3
|
+
# Methods expect one or more arguments, which could be nil, and should return the appropriate
|
4
|
+
# formatting and style.
|
5
|
+
class TableFu::Formatting
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
# Returns a currency formatted number
|
10
|
+
def currency(num)
|
11
|
+
begin
|
12
|
+
parts = num.to_s.split('.')
|
13
|
+
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
|
14
|
+
"$#{parts.join('.')}"
|
15
|
+
rescue
|
16
|
+
num
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the last name of a name
|
21
|
+
# => last_name("Jeff Larson")
|
22
|
+
# >> Larson
|
23
|
+
def last_name(name)
|
24
|
+
name.strip!
|
25
|
+
if name.match(/\s(\w+)$/)
|
26
|
+
$1
|
27
|
+
else
|
28
|
+
name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
# Returns that last name first of a name
|
32
|
+
# => last_name_first_name("Jeff Larson")
|
33
|
+
# >> Larson, Jeff
|
34
|
+
def last_name_first_name(name)
|
35
|
+
last = last_name(name)
|
36
|
+
first = name.gsub(last, '').strip
|
37
|
+
"#{last}, #{first}"
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns an html link constructed from link, linkname
|
41
|
+
def link(linkname, href)
|
42
|
+
"<a href='#{href}' title='#{linkname}'>#{linkname}</a>"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns an error message if the given formatter isn't available
|
46
|
+
def method_missing(method)
|
47
|
+
"#{method.to_s} not a valid formatter!"
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|