fat_table 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.org +2106 -0
- data/README.rdoc +1965 -0
- data/Rakefile +12 -0
- data/TODO.org +31 -0
- data/bin/ft_console +119 -0
- data/bin/setup +8 -0
- data/fat_table.gemspec +80 -0
- data/lib/fat_table.rb +225 -0
- data/lib/fat_table/column.rb +522 -0
- data/lib/fat_table/db_handle.rb +81 -0
- data/lib/fat_table/errors.rb +13 -0
- data/lib/fat_table/evaluator.rb +55 -0
- data/lib/fat_table/formatters.rb +7 -0
- data/lib/fat_table/formatters/aoa_formatter.rb +91 -0
- data/lib/fat_table/formatters/aoh_formatter.rb +91 -0
- data/lib/fat_table/formatters/formatter.rb +1248 -0
- data/lib/fat_table/formatters/latex_formatter.rb +208 -0
- data/lib/fat_table/formatters/org_formatter.rb +72 -0
- data/lib/fat_table/formatters/term_formatter.rb +297 -0
- data/lib/fat_table/formatters/text_formatter.rb +92 -0
- data/lib/fat_table/table.rb +1322 -0
- data/lib/fat_table/version.rb +4 -0
- metadata +331 -0
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rdoc/task'
|
4
|
+
|
5
|
+
RDoc::Task.new do |rdoc|
|
6
|
+
rdoc.main = 'README.rdoc'
|
7
|
+
rdoc.rdoc_files.include('README.rdoc', 'lib')
|
8
|
+
end
|
9
|
+
|
10
|
+
RSpec::Core::RakeTask.new(:spec)
|
11
|
+
|
12
|
+
task default: :spec
|
data/TODO.org
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
* TODO Conversion to Spreadsheets
|
2
|
+
- State "TODO" from [2017-04-21 Fri 10:36]
|
3
|
+
This is a [[https://github.com/westonganger/spreadsheet_architect][gem]] that I can include into the Table model to convert a table into
|
4
|
+
a spread-sheet, or even a sheet in a multi-sheet spreadsheet file.
|
5
|
+
|
6
|
+
* DONE Formatters
|
7
|
+
CLOSED: [2017-04-21 Fri 10:36]
|
8
|
+
- State "WAIT" from "TODO" [2017-04-21 Fri 10:36]
|
9
|
+
- State "TODO" from [2017-04-21 Fri 10:35]
|
10
|
+
Need to think about ways to define formatters for Table for different output
|
11
|
+
types, including tty, color-tty, latex, csv, spreadsheet?
|
12
|
+
|
13
|
+
* DONE Add a Group Boundary concept
|
14
|
+
CLOSED: [2017-04-21 Fri 10:36]
|
15
|
+
- State "WAIT" from "TODO" [2017-04-21 Fri 10:36]
|
16
|
+
- State "TODO" from [2017-04-21 Fri 10:35]
|
17
|
+
If I want a table to perform sub-totals at various break points, need to have a
|
18
|
+
way for a table to record its grouping boundaries. Maybe an array of row
|
19
|
+
numbers? Automatically injected by the group-by method?
|
20
|
+
|
21
|
+
* DONE Add uniq method and set operations
|
22
|
+
CLOSED: [2017-03-02 Thu 15:54]
|
23
|
+
- State "WAIT" from "TODO" [2017-03-02 Thu 15:54]
|
24
|
+
- State "TODO" from [2017-03-02 Thu 15:54]
|
25
|
+
For tables, add a method that eliminates any duplicate rows. Perhaps just apply
|
26
|
+
Array#uniq to the columns?
|
27
|
+
|
28
|
+
* TODO Add from_yql for fetching from Yahoo
|
29
|
+
- State "TODO" from [2017-04-21 Fri 10:35]
|
30
|
+
Add a constructor to allow fetching stock data from yql. Perhaps grab all
|
31
|
+
available fields, then allow a select of those of interest.
|
data/bin/ft_console
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'fat_table'
|
5
|
+
require 'pry'
|
6
|
+
|
7
|
+
data =
|
8
|
+
[['Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Ok'],
|
9
|
+
['2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ENTITY3', 'F'],
|
10
|
+
['2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ENTITY1', 'T'],
|
11
|
+
['2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'ENTITY3', 'F'],
|
12
|
+
['2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'ENTITY3', 'T'],
|
13
|
+
['2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ENTITY3', 'T'],
|
14
|
+
['2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'ENTITY3', 'T'],
|
15
|
+
['2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ENTITY1', 'T'],
|
16
|
+
['2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'ENTITY3', 'T'],
|
17
|
+
['2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'ENTITY3', 'T'],
|
18
|
+
['2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'ENTITY3', 'T'],
|
19
|
+
['2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'ENTITY3', 'T'],
|
20
|
+
['2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'ENTITY3', 'F']]
|
21
|
+
|
22
|
+
tab_a_str = <<-EOS
|
23
|
+
| Id | Name | Age | Address | Salary | Join Date |
|
24
|
+
|----+-------+-----+------------+--------+------------|
|
25
|
+
| 1 | Paul | 32 | California | 20000 | 2001-07-13 |
|
26
|
+
| 3 | Teddy | 23 | Norway | 20000 | 2007-12-13 |
|
27
|
+
| 4 | Mark | 25 | Rich-Mond | 65000 | 2007-12-13 |
|
28
|
+
| 5 | David | 27 | Texas | 85000 | 2007-12-13 |
|
29
|
+
| 2 | Allen | 25 | Texas | | 2005-07-13 |
|
30
|
+
| 8 | Paul | 24 | Houston | 20000 | 2005-07-13 |
|
31
|
+
| 9 | James | 44 | Norway | 5000 | 2005-07-13 |
|
32
|
+
| 10 | James | 45 | Texas | 5000 | |
|
33
|
+
EOS
|
34
|
+
|
35
|
+
tab_b_str = <<-EOS
|
36
|
+
| Id | Dept | Emp Id |
|
37
|
+
|----+-------------+--------|
|
38
|
+
| 1 | IT Billing | 1 |
|
39
|
+
| 2 | Engineering | 2 |
|
40
|
+
| 3 | Finance | 7 |
|
41
|
+
EOS
|
42
|
+
|
43
|
+
tab_a = FatTable.from_org_string(tab_a_str)
|
44
|
+
tab_b = FatTable.from_org_string(tab_b_str)
|
45
|
+
|
46
|
+
tab1_str = <<-EOS
|
47
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | LP | QP | IPLP | IPQP |
|
48
|
+
|------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
49
|
+
| T001 | [2016-11-01 Tue] | P | 7.7000 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
50
|
+
| T002 | [2016-11-01 Tue] | P | 7.7500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
51
|
+
| T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
52
|
+
| T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
53
|
+
|------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
54
|
+
| T004 | [2016-11-01 Tue] | S | 7.5500 | T | F | 6811 | 966 | 5845 | 0.2453 | 0.1924 |
|
55
|
+
| T005 | [2016-11-01 Tue] | S | 7.5000 | F | F | 4000 | 572 | 3428 | 0.2453 | 0.1924 |
|
56
|
+
| T006 | [2016-11-01 Tue] | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
57
|
+
| T006 | [2016-11-01 Tue] | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
58
|
+
| T007 | [2016-11-01 Tue] | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
59
|
+
| T008 | [2016-11-01 Tue] | P | 7.6500 | F | F | 2771 | 393 | 2378 | 0.2453 | 0.1924 |
|
60
|
+
| T009 | [2016-11-01 Tue] | P | 7.6000 | F | F | 9550 | 1363 | 8187 | 0.2453 | 0.1924 |
|
61
|
+
|------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
62
|
+
| T010 | [2016-11-01 Tue] | P | 7.5500 | F | T | 3175 | 451 | 2724 | 0.2453 | 0.1924 |
|
63
|
+
| T011 | [2016-11-02 Wed] | P | 7.4250 | T | F | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
64
|
+
| T012 | [2016-11-02 Wed] | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
65
|
+
| T012 | [2016-11-02 Wed] | P | 7.5500 | F | F | 4700 | 677 | 4023 | 0.2453 | 0.1924 |
|
66
|
+
| T013 | [2016-11-02 Wed] | P | 7.3500 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 |
|
67
|
+
|------+------------------+------+--------+-----+------+--------+------+-------+--------+--------|
|
68
|
+
| T014 | [2016-11-02 Wed] | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
69
|
+
| T015 | [2016-11-02 Wed] | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
70
|
+
| T016 | [2016-11-02 Wed] | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
71
|
+
EOS
|
72
|
+
|
73
|
+
tab2_str = <<-EOS
|
74
|
+
| Ref | Date | Code | Price | G10 | QP10 | Shares | LP | QP | IPLP | IPQP |
|
75
|
+
|------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
76
|
+
| T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
77
|
+
| T003 | [2016-11-01 Tue] | P | 7.5000 | F | T | 800 | 112 | 688 | 0.2453 | 0.1924 |
|
78
|
+
| T017 | [2016-11-01 Tue] | P | 8.3 | F | T | 1801 | 1201 | 600 | 0.2453 | 0.1924 |
|
79
|
+
|------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
80
|
+
| T018 | [2016-11-01 Tue] | S | 7.152 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
81
|
+
| T018 | [2016-11-01 Tue] | S | 7.152 | T | F | 2516 | 2400 | 116 | 0.2453 | 0.1924 |
|
82
|
+
| T006 | [2016-11-01 Tue] | S | 7.6000 | F | T | 1000 | 143 | 857 | 0.2453 | 0.1924 |
|
83
|
+
| T007 | [2016-11-01 Tue] | S | 7.6500 | T | F | 200 | 28 | 172 | 0.2453 | 0.1924 |
|
84
|
+
|------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
85
|
+
| T014 | [2016-11-02 Wed] | P | 7.4500 | F | T | 5847 | 835 | 5012 | 0.2453 | 0.1924 |
|
86
|
+
| T015 | [2016-11-02 Wed] | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
87
|
+
| T015 | [2016-11-02 Wed] | P | 7.7500 | F | F | 500 | 72 | 428 | 0.2453 | 0.1924 |
|
88
|
+
| T016 | [2016-11-02 Wed] | P | 8.2500 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 |
|
89
|
+
|------+------------------+------+--------+-----+------+--------+-------+------+--------+--------|
|
90
|
+
| T019 | [2017-01-15 Sun] | S | 8.75 | T | F | 300 | 175 | 125 | 0.2453 | 0.1924 |
|
91
|
+
| T020 | [2017-01-19 Thu] | S | 8.25 | F | T | 700 | 615 | 85 | 0.2453 | 0.1924 |
|
92
|
+
| T021 | [2017-01-23 Mon] | P | 7.16 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
93
|
+
| T021 | [2017-01-23 Mon] | P | 7.16 | T | T | 12100 | 11050 | 1050 | 0.2453 | 0.1924 |
|
94
|
+
EOS
|
95
|
+
|
96
|
+
tab1 = FatTable.from_org_string(tab1_str)
|
97
|
+
tab2 = FatTable.from_org_string(tab2_str)
|
98
|
+
|
99
|
+
AOA = [['Ref', 'Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Bool'],
|
100
|
+
[1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'YLPEF1', 'T'],
|
101
|
+
[2, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'YLPEF1', 'T'],
|
102
|
+
[7, '2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'YLEAC', 'F'],
|
103
|
+
[8, '2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'YLEAC', 'T'],
|
104
|
+
[9, '2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'YLEAC', 'T'],
|
105
|
+
[10, '2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'YLEAC', 'T'],
|
106
|
+
[11, '2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'YLEAC', 'F'],
|
107
|
+
[12, '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'YLEAC', 'T'],
|
108
|
+
[13, '2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'YLEAC', 'T'],
|
109
|
+
[14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'YLEAC', 'F'],
|
110
|
+
[15, '2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'YLEAC', 'T'],
|
111
|
+
[16, '2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'YLEAC', 'T']]
|
112
|
+
tt = FatTable.from_aoa(AOA)
|
113
|
+
|
114
|
+
binding.pry
|
115
|
+
instr <<-EOS
|
116
|
+
FatTable console sets up some sample tables you can play with (see ls)
|
117
|
+
|
118
|
+
For example, try 'puts tab1.to_term'
|
119
|
+
EOS
|
data/bin/setup
ADDED
data/fat_table.gemspec
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fat_table/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "fat_table"
|
8
|
+
spec.version = FatTable::VERSION
|
9
|
+
spec.authors = ["Daniel E. Doherty"]
|
10
|
+
spec.email = ["ded-law@ddoherty.net"]
|
11
|
+
|
12
|
+
spec.summary = %q{Provides tools for working with tables as a data type.}
|
13
|
+
spec.description = %q{
|
14
|
+
~FatTable~ is a gem that treats tables as a data type. It provides methods for
|
15
|
+
constructing tables from a variety of sources, building them row-by-row,
|
16
|
+
extracting rows, columns, and cells, and performing aggregate operations on
|
17
|
+
columns. It also provides as set of SQL-esque methods for manipulating table
|
18
|
+
objects: ~select~ for filtering by columns or for creating new columns, ~where~
|
19
|
+
for filtering by rows, ~order_by~ for sorting rows, ~distinct~ for eliminating
|
20
|
+
duplicate rows, ~group_by~ for aggregating multiple rows into single rows and
|
21
|
+
applying column aggregate methods to ungrouped columns, a collection of ~join~
|
22
|
+
methods for combining tables, and more.
|
23
|
+
|
24
|
+
Furthermore, ~FatTable~ provides methods for formatting tables and producing
|
25
|
+
output that targets various output media: text, ANSI terminals, ruby data
|
26
|
+
structures, LaTeX tables, Emacs org-mode tables, and more. The formatting
|
27
|
+
methods can specify cell formatting in a way that is uniform across all the
|
28
|
+
output methods and can also decorate the output with any number of footers,
|
29
|
+
including group footers. ~FatTable~ applies formatting directives to the extent
|
30
|
+
they makes sense for the output medium and treats other formatting directives as
|
31
|
+
no-ops.
|
32
|
+
|
33
|
+
~FatTable~ can be used to perform operations on data that are naturally best
|
34
|
+
conceived of as tables, which in my experience is quite often. It can also serve
|
35
|
+
as a foundation for providing reporting functions where flexibility about the
|
36
|
+
output medium can be quite useful. Finally ~FatTable~ can be used within Emacs
|
37
|
+
~org-mode~ files in code blocks targeting the Ruby language. Org mode tables are
|
38
|
+
presented to a ruby code block as an array of arrays, so ~FatTable~ can read
|
39
|
+
them in with its ~.from_aoa~ constructor. A ~FatTable~ table can output as an
|
40
|
+
array of arrays with its ~.to_aoa~ output function and will be rendered in an
|
41
|
+
org-mode buffer as an org-table, ready for processing by other code blocks.
|
42
|
+
}
|
43
|
+
|
44
|
+
spec.homepage = 'https://github.com/ddoherty03/fat_table'
|
45
|
+
|
46
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the
|
47
|
+
# 'allowed_push_host' to allow pushing to a single host or delete this section
|
48
|
+
# to allow pushing to any host.
|
49
|
+
if spec.respond_to?(:metadata)
|
50
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
51
|
+
else
|
52
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
53
|
+
'public gem pushes.'
|
54
|
+
end
|
55
|
+
|
56
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
57
|
+
f.match(%r{^(test|spec|features)/})
|
58
|
+
end
|
59
|
+
spec.bindir = 'bin'
|
60
|
+
spec.executables = ['ft_console']
|
61
|
+
spec.require_paths = ['lib']
|
62
|
+
|
63
|
+
spec.add_development_dependency 'simplecov'
|
64
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
65
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
66
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
67
|
+
spec.add_development_dependency 'byebug'
|
68
|
+
spec.add_development_dependency 'pry'
|
69
|
+
spec.add_development_dependency 'pry-doc'
|
70
|
+
spec.add_development_dependency 'pry-byebug'
|
71
|
+
spec.add_development_dependency 'rcodetools'
|
72
|
+
|
73
|
+
spec.add_runtime_dependency 'fat_core', '~> 2.0', '>= 2.0.1'
|
74
|
+
spec.add_runtime_dependency 'activesupport'
|
75
|
+
spec.add_runtime_dependency 'rainbow'
|
76
|
+
spec.add_runtime_dependency 'dbi'
|
77
|
+
spec.add_runtime_dependency 'dbd-pg'
|
78
|
+
spec.add_runtime_dependency 'dbd-mysql'
|
79
|
+
spec.add_runtime_dependency 'dbd-sqlite3'
|
80
|
+
end
|
data/lib/fat_table.rb
ADDED
@@ -0,0 +1,225 @@
|
|
1
|
+
require "fat_table/version"
|
2
|
+
|
3
|
+
# This module provides objects for treating tables as a data type on which you
|
4
|
+
# can (1) perform operations, such as select, where, join, and others and (2)
|
5
|
+
# output the tables in several formats, including text, ANSI terminal, LaTeX,
|
6
|
+
# and others. It also provides several constructors for building tables from a
|
7
|
+
# variety of input sources. See, e.g., .from_csv_file,
|
8
|
+
# FatTable.from_org_file, and FatTable.from_sql, for more details.
|
9
|
+
module FatTable
|
10
|
+
require 'fat_core'
|
11
|
+
require 'dbi'
|
12
|
+
require 'active_support'
|
13
|
+
require 'active_support/core_ext'
|
14
|
+
require 'active_support/number_helper'
|
15
|
+
|
16
|
+
require 'fat_table/evaluator'
|
17
|
+
require 'fat_table/column'
|
18
|
+
require 'fat_table/table'
|
19
|
+
require 'fat_table/formatters'
|
20
|
+
require 'fat_table/db_handle'
|
21
|
+
require 'fat_table/errors'
|
22
|
+
|
23
|
+
# Valid output formats as symbols.
|
24
|
+
FORMATS = [:psv, :aoa, :aoh, :latex, :org, :term, :text].freeze
|
25
|
+
|
26
|
+
class << self
|
27
|
+
# Set a default output format to use when FatTable.to_format is invoked.
|
28
|
+
# Valid formats are +:psv+, +:aoa+, +:aoh+, +:latex+, +:org+, +:term+, and
|
29
|
+
# +:text+, or their string equivalents. By default, +FatTable.format+ is
|
30
|
+
# +:text+.
|
31
|
+
attr_accessor :format
|
32
|
+
|
33
|
+
# Default value to use to indicate currency in a Numeric column. By default
|
34
|
+
# this is set to '$'.
|
35
|
+
attr_accessor :currency_symbol
|
36
|
+
end
|
37
|
+
self.format = :text
|
38
|
+
self.currency_symbol = '$'
|
39
|
+
|
40
|
+
###########################################################################
|
41
|
+
# Table Constructors
|
42
|
+
###########################################################################
|
43
|
+
|
44
|
+
# Return an empty FatTable::Table object. You can use FatTable::Table#add_row
|
45
|
+
# or FatTable::Table#add_column to populate the table with data.
|
46
|
+
def self.new
|
47
|
+
Table.new
|
48
|
+
end
|
49
|
+
|
50
|
+
# Construct a FatTable::Table from the contents of a CSV file given by the
|
51
|
+
# file name +fname+. Headers will be taken from the first row and converted to
|
52
|
+
# symbols.
|
53
|
+
def self.from_csv_file(fname)
|
54
|
+
Table.from_csv_file(fname)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Construct a FatTable::Table from the string +str+, treated in the same
|
58
|
+
# manner as if read the input from a CSV file. Headers will be taken from the
|
59
|
+
# first row and converted to symbols.
|
60
|
+
def self.from_csv_string(str)
|
61
|
+
Table.from_csv_string(str)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Construct a FatTable::Table from the first table found in the Emacs org-mode
|
65
|
+
# file names +fname+. Headers are taken from the first row if the second row
|
66
|
+
# is an hline. Otherwise, synthetic headers of the form +:col_1+, +:col_2+,
|
67
|
+
# etc. are created. Any other hlines will be treated as marking a boundary in
|
68
|
+
# the table.
|
69
|
+
def self.from_org_file(fname)
|
70
|
+
Table.from_org_file(fname)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Construct a FatTable::Table from the first table found in the string +str+,
|
74
|
+
# treated in the same manner as if read from an Emacs org-mode file. Headers
|
75
|
+
# are taken from the first row if the second row is an hrule. Otherwise,
|
76
|
+
# synthetic headers of the form :col_1, :col_2, etc. are created. Any other
|
77
|
+
# hlines will be treated as marking a boundary in the table.
|
78
|
+
def self.from_org_string(str)
|
79
|
+
Table.from_org_string(str)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Construct a FatTable::Table from the array of arrays +aoa+. By default, with
|
83
|
+
# +hlines+ false, do not look for nil separators, just treat the first row as
|
84
|
+
# headers. With +hlines+ true, expect separators to mark the header row and
|
85
|
+
# any boundaries. If the second element of the array is a nil, interpret the
|
86
|
+
# first element of the array as a row of headers. Otherwise, synthesize
|
87
|
+
# headers of the form +:col_1+, +:col_2+, ... and so forth. The remaining
|
88
|
+
# elements are taken as the body of the table, except that if an element of
|
89
|
+
# the outer array is a nil, mark the preceding row as a boundary. In Emacs
|
90
|
+
# org-mode code blocks, by default (+:hlines no+) all hlines are stripped from
|
91
|
+
# the table, otherwise (+:hlines yes+) they are indicated with nil elements in
|
92
|
+
# the outer array.
|
93
|
+
def self.from_aoa(aoa, hlines: false)
|
94
|
+
Table.from_aoa(aoa, hlines: hlines)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Construct a FatTable::Table from the array of hashes +aoh+, which can be an
|
98
|
+
# array of any objects that respond to the #to_h method. With +hlines+ true,
|
99
|
+
# interpret nil separators as marking boundaries in the new Table. All hashes
|
100
|
+
# must have the same keys, which, converted to symbols, become the headers for
|
101
|
+
# the new Table.
|
102
|
+
def self.from_aoh(aoh, hlines: false)
|
103
|
+
Table.from_aoh(aoh, hlines: hlines)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Construct a FatTable::Table from another FatTable::Table. Inherit any group
|
107
|
+
# boundaries from the input table.
|
108
|
+
def self.from_table(table)
|
109
|
+
Table.from_table(table)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Construct a Table by running a SQL query against the database set up with
|
113
|
+
# FatTable.set_db. Return the Table with the query results as rows and the
|
114
|
+
# headers from the query, converted to symbols, as headers.
|
115
|
+
def self.from_sql(query)
|
116
|
+
Table.from_sql(query)
|
117
|
+
end
|
118
|
+
|
119
|
+
########################################################################
|
120
|
+
# Formatter
|
121
|
+
########################################################################
|
122
|
+
|
123
|
+
# Return a string or ruby object formatting +table+ according to the format
|
124
|
+
# specified in +FatTable.format+. If a block is given, it will yield a
|
125
|
+
# +FatTable::Formatter+ of the appropriate type on which formatting and footer
|
126
|
+
# methods can be called. If no block is given, the default format for the type
|
127
|
+
# will be used. The +options+ are passed along to the FatTable::Formatter
|
128
|
+
# created to process the output.
|
129
|
+
def self.to_format(table, options = {}) # :yields: formatter
|
130
|
+
if block_given?
|
131
|
+
to_any(format, table, options, &Proc.new)
|
132
|
+
else
|
133
|
+
to_any(format, table, options)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Return a string or ruby object according to the format given in the +fmt+
|
138
|
+
# argument. Valid formats are :psv, :aoa, :aoh, :latex, :org, :term, :text, or
|
139
|
+
# their string equivalents. If a block is given, it will yield a
|
140
|
+
# +FatTable::Formatter+ of the appropriate type on which formatting and footer
|
141
|
+
# methods can be called. If no block is given, the default format for the
|
142
|
+
# +fmt+ type will be used.
|
143
|
+
def self.to_any(fmt, table, options = {})
|
144
|
+
fmt = fmt.as_sym
|
145
|
+
raise UserError, "unknown format '#{fmt}'" unless FORMATS.include?(fmt)
|
146
|
+
method = "to_#{fmt}"
|
147
|
+
if block_given?
|
148
|
+
send method, table, options, &Proc.new
|
149
|
+
else
|
150
|
+
send method, table, options
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Return the +table+ as a string formatted as pipe-separated values, passing
|
155
|
+
# the +options+ to a new +FatTable::Formatter+ object. If no block is given,
|
156
|
+
# default formatting is applied to the +table+'s cells. If a block is given,
|
157
|
+
# it yields the +FatTable::Formatter+ to the block on which formatting
|
158
|
+
# and footer methods can be called.
|
159
|
+
def self.to_psv(table, options = {})
|
160
|
+
fmt = Formatter.new(table, options)
|
161
|
+
yield fmt if block_given?
|
162
|
+
fmt.output
|
163
|
+
end
|
164
|
+
|
165
|
+
# Return the table as an Array of Array of strings. If no block is given,
|
166
|
+
# default formatting is applies to the table's cells. If a block is given, it
|
167
|
+
# yields an AoaFormatter to the block to which formatting instructions and
|
168
|
+
# footers can be added by calling methods on it.
|
169
|
+
def self.to_aoa(table, options = {})
|
170
|
+
fmt = AoaFormatter.new(table, options)
|
171
|
+
yield fmt if block_given?
|
172
|
+
fmt.output
|
173
|
+
end
|
174
|
+
|
175
|
+
# Return the table as an Array of Hashes. Each inner hash uses the Table's
|
176
|
+
# columns as keys and it values are strings representing the cells of the
|
177
|
+
# table. If no block is given, default formatting is applies to the table's
|
178
|
+
# cells. If a block is given, it yields an AohFormatter to the block to which
|
179
|
+
# formatting instructions and footers can be added by calling methods on it.
|
180
|
+
def self.to_aoh(table, options = {})
|
181
|
+
fmt = AohFormatter.new(table, options)
|
182
|
+
yield fmt if block_given?
|
183
|
+
fmt.output
|
184
|
+
end
|
185
|
+
|
186
|
+
# Return the table as a string containing a LaTeX table. If no block is given,
|
187
|
+
# default formatting applies to the table's cells. If a block is given, it
|
188
|
+
# yields a LaTeXFormatter to the block to which formatting instructions and
|
189
|
+
# footers can be added by calling methods on it.
|
190
|
+
def self.to_latex(table, options = {})
|
191
|
+
fmt = LaTeXFormatter.new(table, options)
|
192
|
+
yield fmt if block_given?
|
193
|
+
fmt.output
|
194
|
+
end
|
195
|
+
|
196
|
+
# Return the table as a string containing an Emacs org-mode table. If no block
|
197
|
+
# is given, default formatting applies to the table's cells. If a block is
|
198
|
+
# given, it yields a OrgFormatter to the block to which formatting
|
199
|
+
# instructions and footers can be added by calling methods on it.
|
200
|
+
def self.to_org(table, options = {})
|
201
|
+
fmt = OrgFormatter.new(table, options)
|
202
|
+
yield fmt if block_given?
|
203
|
+
fmt.output
|
204
|
+
end
|
205
|
+
|
206
|
+
# Return the table as a string containing ANSI terminal text representing
|
207
|
+
# table. If no block is given, default formatting applies to the table's
|
208
|
+
# cells. If a block is given, it yields a TermFormatter to the block to which
|
209
|
+
# formatting instructions and footers can be added by calling methods on it.
|
210
|
+
def self.to_term(table, options = {})
|
211
|
+
fmt = TermFormatter.new(table, options)
|
212
|
+
yield fmt if block_given?
|
213
|
+
fmt.output
|
214
|
+
end
|
215
|
+
|
216
|
+
# Return the table as a string containing ordinary text representing table. If
|
217
|
+
# no block is given, default formatting applies to the table's cells. If a
|
218
|
+
# block is given, it yields a TextFormatter to the block to which formatting
|
219
|
+
# instructions and footers can be added by calling methods on it.
|
220
|
+
def self.to_text(table, options = {})
|
221
|
+
fmt = TextFormatter.new(table, options)
|
222
|
+
yield fmt if block_given?
|
223
|
+
fmt.output
|
224
|
+
end
|
225
|
+
end
|