fat_table 0.2.2
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.
- 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
|