fat_table 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +16 -1
- data/Gemfile +2 -0
- data/README.org +22 -18
- data/fat_table.gemspec +1 -0
- data/lib/fat_table.rb +5 -3
- data/lib/fat_table/column.rb +29 -20
- data/lib/fat_table/db_handle.rb +2 -0
- data/lib/fat_table/errors.rb +2 -0
- data/lib/fat_table/evaluator.rb +2 -0
- data/lib/fat_table/formatters.rb +2 -0
- data/lib/fat_table/formatters/aoa_formatter.rb +2 -0
- data/lib/fat_table/formatters/aoh_formatter.rb +2 -0
- data/lib/fat_table/formatters/formatter.rb +49 -46
- data/lib/fat_table/formatters/org_formatter.rb +2 -0
- data/lib/fat_table/formatters/term_formatter.rb +17 -15
- data/lib/fat_table/formatters/text_formatter.rb +2 -0
- data/lib/fat_table/patches.rb +2 -0
- data/lib/fat_table/table.rb +15 -16
- data/lib/fat_table/version.rb +3 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3cff489c9e921eff2138fb44b260b96d548819b7ee1479f9bf89675f2199c9ea
|
4
|
+
data.tar.gz: 7ad900e458b8d95baaf8044a4d25e742b1796ae9677d9f667180f034760e8a55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 061ddacf0132d62f7d428f513c7a14277a4668c5a37148f80ef87dc484163ee4c001164e20a854d61761f21d6df025a700171e85c33e4f53c548014d7804b4e2
|
7
|
+
data.tar.gz: 11351e7a9c73624c4395960c226733b2c1ccaa126f0a0f1c2eee042b83f5adacbcea52e303b8566d5746c16648e202441d5df2216cc818799864600c7ee3bf69
|
data/.rubocop.yml
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
-
|
1
|
+
inherit_gem:
|
2
|
+
rubocop-shopify: rubocop.yml
|
2
3
|
require: rubocop-rspec
|
3
4
|
require: rubocop-performance
|
5
|
+
|
6
|
+
AllCops:
|
7
|
+
TargetRubyVersion: 2.7
|
8
|
+
Exclude:
|
9
|
+
- 'test/tmp/**/*'
|
10
|
+
- 'vendor/bundle/**/*'
|
11
|
+
|
12
|
+
Style/MethodCallWithArgsParentheses:
|
13
|
+
Exclude:
|
14
|
+
- '**/Gemfile'
|
15
|
+
|
16
|
+
Style/ClassAndModuleChildren:
|
17
|
+
Exclude:
|
18
|
+
- 'test/**/*'
|
data/Gemfile
CHANGED
data/README.org
CHANGED
@@ -481,7 +481,7 @@ This example illustrates several things:
|
|
481
481
|
A second ruby data structure that can be used to initialize a ~FatTable~ table
|
482
482
|
is an array of ruby Hashes. Each hash represents a row of the table, and the
|
483
483
|
headers of the table are taken from the keys of the hashes. Accordingly, all the
|
484
|
-
hashes
|
484
|
+
hashes must have the same keys.
|
485
485
|
|
486
486
|
This same method can in fact take an array of any objects that can be converted
|
487
487
|
to a Hash with the ~#to_h~ method, so you can use an array of your own objects
|
@@ -768,17 +768,18 @@ symbol representing an existing column, which has the effect of renaming an
|
|
768
768
|
existing column, or (2) a string representing a ruby expression for the value of
|
769
769
|
a new column.
|
770
770
|
|
771
|
-
Within the string expression, the names of existing or already-specified
|
772
|
-
are available as local variables
|
773
|
-
'@
|
774
|
-
|
771
|
+
Within the string expression, the names of existing or already-specified
|
772
|
+
columns are available as local variables. In addition the instance variables
|
773
|
+
'@row' and '@group' are available as the row number and group number of the
|
774
|
+
new value. So for our example table, the string expressions for new columns
|
775
|
+
have access to local variables ~ref~, ~date~, ~code~, ~price~, ~g10~, ~qp10~,
|
775
776
|
~shares~, ~lp~, ~qp~, ~iplp~, and ~ipqp~ as well as the instance variables
|
776
777
|
~@row~ and ~@group~. The local variables are set to the values of the cell in
|
777
|
-
their respective columns for each row in the input table and the instance
|
778
|
-
variables are set the number of the current row and group respectively.
|
778
|
+
their respective columns for each row in the input table, and the instance
|
779
|
+
variables are set the number of the current row and group number respectively.
|
779
780
|
|
780
|
-
For example, if we want to rename the ~:date~
|
781
|
-
compute the cost of shares, we could do the following:
|
781
|
+
For example, if we want to rename the ~traded_on~ column to ~:date~ and add a
|
782
|
+
new column to compute the cost of shares, we could do the following:
|
782
783
|
|
783
784
|
#+HEADER: :colnames no :session readme :hlines yes :wrap EXAMPLE :exports both
|
784
785
|
#+BEGIN_SRC ruby
|
@@ -1041,8 +1042,10 @@ the value is a symbol for one of several aggregating methods that
|
|
1041
1042
|
to the :price column so that the output shows the average price in each group.
|
1042
1043
|
The ~:shares~, ~:lp~, and ~:qp~ columns are summed, and the ~:any?~ aggregate is
|
1043
1044
|
applied to one of the boolean fields, that is, it is ~true~ if any of the values
|
1044
|
-
in that column are ~true~.
|
1045
|
-
|
1045
|
+
in that column are ~true~.
|
1046
|
+
|
1047
|
+
Note that the column names in the output of the aggregated columns have the
|
1048
|
+
name of the aggregating method pre-pended to the column name.
|
1046
1049
|
|
1047
1050
|
Here is a list of all the aggregate methods available. If the description
|
1048
1051
|
restricts the aggregate to particular column types, applying it to other types
|
@@ -1311,6 +1314,7 @@ table where the join expression is satisfied and augmented with nils otherwise.
|
|
1311
1314
|
Finally, a cross join outputs every row of ~tab_a~ augmented with every row of
|
1312
1315
|
~tab_b~, in other words, the Cartesian product of the two tables. If ~tab_a~ has
|
1313
1316
|
~N~ rows and ~tab_b~ has ~M~ rows, the output table will have ~N * M~ rows.
|
1317
|
+
So be careful lest you consume all your computer's memory.
|
1314
1318
|
|
1315
1319
|
#+HEADER: :colnames no :session readme :hlines yes :wrap EXAMPLE :exports both
|
1316
1320
|
#+BEGIN_SRC ruby
|
@@ -1348,10 +1352,10 @@ Finally, a cross join outputs every row of ~tab_a~ augmented with every row of
|
|
1348
1352
|
|
1349
1353
|
*** Set Operations
|
1350
1354
|
|
1351
|
-
~FatTable~ can perform several set operations on tables. In order for
|
1352
|
-
to be used this way, they must have the same number of columns with
|
1353
|
-
types or an exception will be raised. We'll call two tables that
|
1354
|
-
combining with set operations "set-compatible."
|
1355
|
+
~FatTable~ can perform several set operations on pairs of tables. In order for
|
1356
|
+
two tables to be used this way, they must have the same number of columns with
|
1357
|
+
the same types or an exception will be raised. We'll call two tables that
|
1358
|
+
qualify for combining with set operations "set-compatible."
|
1355
1359
|
|
1356
1360
|
We'll use the following two set-compatible tables in the examples. They each
|
1357
1361
|
have some duplicates and some group boundaries so you can see the effect of the
|
@@ -1763,9 +1767,9 @@ but ruby data structures, and for them, things such as alignment are irrelevant.
|
|
1763
1767
|
array of array,
|
1764
1768
|
|
1765
1769
|
These are all implemented by classes that inherit from ~FatTable::Formatter~
|
1766
|
-
class by defining about a dozen methods that get called at various places
|
1767
|
-
the construction of the output table. The idea is that more
|
1768
|
-
defined by adding additional classes.
|
1770
|
+
class by defining about a dozen methods that get called at various places
|
1771
|
+
during the construction of the output table. The idea is that more output
|
1772
|
+
formats can be defined by adding additional classes.
|
1769
1773
|
|
1770
1774
|
*** Table Locations
|
1771
1775
|
|
data/fat_table.gemspec
CHANGED
@@ -68,6 +68,7 @@ Gem::Specification.new do |spec|
|
|
68
68
|
spec.add_development_dependency 'pry'
|
69
69
|
spec.add_development_dependency 'pry-byebug'
|
70
70
|
spec.add_development_dependency 'pry-doc'
|
71
|
+
spec.add_development_dependency 'ruby_jard'
|
71
72
|
spec.add_development_dependency 'rake', '~> 13.0'
|
72
73
|
spec.add_development_dependency 'redcarpet'
|
73
74
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
data/lib/fat_table.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This module provides objects for treating tables as a data type on which you
|
2
4
|
# can (1) perform operations, such as select, where, join, and others and (2)
|
3
5
|
# output the tables in several formats, including text, ANSI terminal, LaTeX,
|
@@ -29,7 +31,7 @@ module FatTable
|
|
29
31
|
path = Dir.glob("#{ENV['GEM_HOME']}/gems/#{gem_name}*").sort.last
|
30
32
|
if path
|
31
33
|
path = File.join(path, 'lib')
|
32
|
-
|
34
|
+
$LOAD_PATH << path unless $LOAD_PATH.include?(path)
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
@@ -158,9 +160,9 @@ module FatTable
|
|
158
160
|
raise UserError, "unknown format '#{fmt}'" unless FORMATS.include?(fmt)
|
159
161
|
method = "to_#{fmt}"
|
160
162
|
if block_given?
|
161
|
-
send
|
163
|
+
send(method, table, options, &Proc.new)
|
162
164
|
else
|
163
|
-
send
|
165
|
+
send(method, table, options)
|
164
166
|
end
|
165
167
|
end
|
166
168
|
|
data/lib/fat_table/column.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FatTable
|
2
4
|
# Column objects are a thin wrapper around an Array to allow columns to be
|
3
5
|
# summed and have other aggregate operations performed on them, but compacting
|
@@ -483,34 +485,41 @@ module FatTable
|
|
483
485
|
end
|
484
486
|
end
|
485
487
|
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
488
|
+
ISO_DATE_RE = %r{(?<yr>\d\d\d\d)[-\/]
|
489
|
+
(?<mo>\d\d?)[-\/]
|
490
|
+
(?<dy>\d\d?)\s*
|
491
|
+
(T?\s*\d\d:\d\d(:\d\d)?
|
492
|
+
([-+](\d\d?)(:\d\d?))?)?}x
|
493
|
+
|
494
|
+
AMR_DATE_RE = %r{(?<dy>\d\d?)[-/](?<mo>\d\d?)[-/](?<yr>\d\d\d\d)\s*
|
495
|
+
(?<tm>T\d\d:\d\d:\d\d(\+\d\d:\d\d)?)?}x
|
490
496
|
|
491
|
-
# Convert the val to a DateTime if it is either a DateTime, a Date, or a
|
497
|
+
# Convert the val to a DateTime if it is either a DateTime, a Date, a Time, or a
|
492
498
|
# String that can be parsed as a DateTime, otherwise return nil. It only
|
493
|
-
# recognizes strings that contain a something like '2016-01-14' or
|
494
|
-
#
|
495
|
-
#
|
496
|
-
#
|
499
|
+
# recognizes strings that contain a something like '2016-01-14' or '2/12/1985'
|
500
|
+
# within them, otherwise DateTime.parse would treat many bare numbers as dates,
|
501
|
+
# such as '2841381', which it would recognize as a valid date, but the user
|
502
|
+
# probably does not intend it to be so treated.
|
497
503
|
def convert_to_date_time(val)
|
498
504
|
return val if val.is_a?(DateTime)
|
499
505
|
return val if val.is_a?(Date)
|
500
506
|
begin
|
501
|
-
|
502
|
-
return nil if
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
+
str = val.to_s.clean
|
508
|
+
return nil if str.blank?
|
509
|
+
|
510
|
+
if str.match(ISO_DATE_RE)
|
511
|
+
date = DateTime.parse(val)
|
512
|
+
elsif str =~ AMR_DATE_RE
|
513
|
+
date = DateTime.new(Regexp.last_match[:yr].to_i,
|
514
|
+
Regexp.last_match[:mo].to_i,
|
515
|
+
Regexp.last_match[:dy].to_i)
|
507
516
|
else
|
508
517
|
return nil
|
509
518
|
end
|
510
|
-
val = val.to_date if
|
511
|
-
|
519
|
+
# val = val.to_date if
|
520
|
+
date.seconds_since_midnight.zero? ? date.to_date : date
|
512
521
|
rescue ArgumentError
|
513
|
-
|
522
|
+
nil
|
514
523
|
end
|
515
524
|
end
|
516
525
|
|
@@ -530,8 +539,8 @@ module FatTable
|
|
530
539
|
BigDecimal(val.to_s.clean)
|
531
540
|
when /\A[-+]?[\d]+\z/
|
532
541
|
val.to_i
|
533
|
-
when %r{\A([-+]?\d+)\s*[:/]\s*([-+]?\d+)\z}
|
534
|
-
Rational(
|
542
|
+
when %r{\A(?<nm>[-+]?\d+)\s*[:/]\s*(?<dn>[-+]?\d+)\z}
|
543
|
+
Rational(Regexp.last_match[:nm], Regexp.last_match[:dn])
|
535
544
|
end
|
536
545
|
end
|
537
546
|
|
data/lib/fat_table/db_handle.rb
CHANGED
data/lib/fat_table/errors.rb
CHANGED
data/lib/fat_table/evaluator.rb
CHANGED
data/lib/fat_table/formatters.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FatTable
|
2
4
|
# A Formatter is for use in Table output routines, and provides methods for
|
3
5
|
# adding group and table footers to the output and instructions for how the
|
@@ -73,7 +75,7 @@ module FatTable
|
|
73
75
|
false_color: 'none',
|
74
76
|
false_bgcolor: 'none',
|
75
77
|
underline: false,
|
76
|
-
blink: false
|
78
|
+
blink: false,
|
77
79
|
}
|
78
80
|
|
79
81
|
class_attribute :valid_colors
|
@@ -577,9 +579,9 @@ module FatTable
|
|
577
579
|
# parse, we remove the matched construct from fmt. At the end, any
|
578
580
|
# remaining characters in fmt should be invalid.
|
579
581
|
fmt_hash = {}
|
580
|
-
if fmt =~ /c\[(
|
581
|
-
fmt_hash[:color] =
|
582
|
-
fmt_hash[:bgcolor] =
|
582
|
+
if fmt =~ /c\[(?<co>#{CLR_RE})(\.(?<bg>#{CLR_RE}))?\]/
|
583
|
+
fmt_hash[:color] = Regexp.last_match[:co] unless Regexp.last_match[:co].blank?
|
584
|
+
fmt_hash[:bgcolor] = Regexp.last_match[:bg] unless Regexp.last_match[:bg].blank?
|
583
585
|
validate_color(fmt_hash[:color])
|
584
586
|
validate_color(fmt_hash[:bgcolor])
|
585
587
|
fmt = fmt.sub($&, '')
|
@@ -599,12 +601,12 @@ module FatTable
|
|
599
601
|
fmt_hash[:case] = :title
|
600
602
|
fmt = fmt.sub($&, '')
|
601
603
|
end
|
602
|
-
if fmt =~ /(
|
603
|
-
fmt_hash[:bold] =
|
604
|
+
if fmt =~ /(?<neg>~\s*)?B/
|
605
|
+
fmt_hash[:bold] = !Regexp.last_match[:neg]
|
604
606
|
fmt = fmt.sub($&, '')
|
605
607
|
end
|
606
|
-
if fmt =~ /(
|
607
|
-
fmt_hash[:italic] =
|
608
|
+
if fmt =~ /(?<neg>~\s*)?I/
|
609
|
+
fmt_hash[:italic] = !Regexp.last_match[:neg]
|
608
610
|
fmt = fmt.sub($&, '')
|
609
611
|
end
|
610
612
|
if fmt =~ /R/
|
@@ -619,12 +621,12 @@ module FatTable
|
|
619
621
|
fmt_hash[:alignment] = :left
|
620
622
|
fmt = fmt.sub($&, '')
|
621
623
|
end
|
622
|
-
if fmt =~ /(
|
623
|
-
fmt_hash[:underline] =
|
624
|
+
if fmt =~ /(?<neg>~\s*)?_/
|
625
|
+
fmt_hash[:underline] = !Regexp.last_match[:neg]
|
624
626
|
fmt = fmt.sub($&, '')
|
625
627
|
end
|
626
|
-
if fmt =~ /(
|
627
|
-
fmt_hash[:blink] =
|
628
|
+
if fmt =~ /(?<neg>~\s*)?\*/
|
629
|
+
fmt_hash[:blink] = !Regexp.last_match[:neg]
|
628
630
|
fmt = fmt.sub($&, '')
|
629
631
|
end
|
630
632
|
[fmt_hash, fmt]
|
@@ -639,9 +641,9 @@ module FatTable
|
|
639
641
|
# parse, we remove the matched construct from fmt. At the end, any
|
640
642
|
# remaining characters in fmt should be invalid.
|
641
643
|
fmt_hash = {}
|
642
|
-
if fmt =~ /n\[\s*([^\]]*)\s*\]/
|
643
|
-
fmt_hash[:nil_text] =
|
644
|
-
fmt = fmt.sub(
|
644
|
+
if fmt =~ /n\[\s*(?<bdy>[^\]]*)\s*\]/
|
645
|
+
fmt_hash[:nil_text] = Regexp.last_match[:bdy].clean
|
646
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
645
647
|
end
|
646
648
|
[fmt_hash, fmt]
|
647
649
|
end
|
@@ -655,22 +657,22 @@ module FatTable
|
|
655
657
|
# parse, we remove the matched construct from fmt. At the end, any
|
656
658
|
# remaining characters in fmt should be invalid.
|
657
659
|
fmt_hash, fmt = parse_str_fmt(fmt)
|
658
|
-
if fmt =~ /(
|
659
|
-
fmt_hash[:pre_digits] =
|
660
|
-
fmt_hash[:post_digits] =
|
661
|
-
fmt = fmt.sub(
|
660
|
+
if fmt =~ /(?<pre>\d+).(?<post>\d+)/
|
661
|
+
fmt_hash[:pre_digits] = Regexp.last_match[:pre].to_i
|
662
|
+
fmt_hash[:post_digits] = Regexp.last_match[:post].to_i
|
663
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
662
664
|
end
|
663
|
-
if fmt =~ /(
|
664
|
-
fmt_hash[:commas] =
|
665
|
-
fmt = fmt.sub(
|
665
|
+
if fmt =~ /(?<neg>~\s*)?,/
|
666
|
+
fmt_hash[:commas] = !Regexp.last_match[:neg]
|
667
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
666
668
|
end
|
667
|
-
if fmt =~ /(
|
668
|
-
fmt_hash[:currency] =
|
669
|
-
fmt = fmt.sub(
|
669
|
+
if fmt =~ /(?<neg>~\s*)?\$/
|
670
|
+
fmt_hash[:currency] = !Regexp.last_match[:neg]
|
671
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
670
672
|
end
|
671
|
-
if fmt =~ /(
|
672
|
-
fmt_hash[:hms] =
|
673
|
-
fmt = fmt.sub(
|
673
|
+
if fmt =~ /(?<neg>~\s*)?H/
|
674
|
+
fmt_hash[:hms] = !Regexp.last_match[:neg]
|
675
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
674
676
|
end
|
675
677
|
unless fmt.blank? || !strict
|
676
678
|
raise UserError, "unrecognized numeric formatting instructions '#{fmt}'"
|
@@ -688,13 +690,13 @@ module FatTable
|
|
688
690
|
# parse, we remove the matched construct from fmt. At the end, any
|
689
691
|
# remaining characters in fmt should be invalid.
|
690
692
|
fmt_hash, fmt = parse_str_fmt(fmt)
|
691
|
-
if fmt =~ /d\[([^\]]*)\]/
|
692
|
-
fmt_hash[:date_fmt] =
|
693
|
-
fmt = fmt.sub(
|
693
|
+
if fmt =~ /d\[(?<bdy>[^\]]*)\]/
|
694
|
+
fmt_hash[:date_fmt] = Regexp.last_match[:bdy]
|
695
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
694
696
|
end
|
695
|
-
if fmt =~ /D\[([^\]]*)\]/
|
696
|
-
fmt_hash[:date_fmt] =
|
697
|
-
fmt = fmt.sub(
|
697
|
+
if fmt =~ /D\[(?<bdy>[^\]]*)\]/
|
698
|
+
fmt_hash[:date_fmt] = Regexp.last_match[:bdy]
|
699
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
698
700
|
end
|
699
701
|
unless fmt.blank? || !strict
|
700
702
|
msg = "unrecognized datetime formatting instructions '#{fmt}'"
|
@@ -712,37 +714,38 @@ module FatTable
|
|
712
714
|
# parse, we remove the matched construct from fmt. At the end, any
|
713
715
|
# remaining characters in fmt should be invalid.
|
714
716
|
fmt_hash = {}
|
715
|
-
if fmt =~ /b\[\s*([^\],]*),([^\]]*)\s*\]/
|
716
|
-
fmt_hash[:true_text] =
|
717
|
-
fmt_hash[:false_text] =
|
718
|
-
fmt = fmt.sub(
|
717
|
+
if fmt =~ /b\[\s*(?<t>[^\],]*),(?<f>[^\]]*)\s*\]/
|
718
|
+
fmt_hash[:true_text] = Regexp.last_match[:t].clean
|
719
|
+
fmt_hash[:false_text] = Regexp.last_match[:f].clean
|
720
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
719
721
|
end
|
720
722
|
# Since true_text, false_text and nil_text may want to have internal
|
721
723
|
# spaces, defer removing extraneous spaces until after they are parsed.
|
722
724
|
if fmt =~ /c\[(#{CLR_RE})(\.(#{CLR_RE}))?,
|
723
725
|
\s*(#{CLR_RE})(\.(#{CLR_RE}))?\]/x
|
724
|
-
|
725
|
-
fmt_hash[:
|
726
|
-
fmt_hash[:
|
727
|
-
fmt_hash[:
|
728
|
-
|
726
|
+
tco, _, tbg, fco, _, fbg = Regexp.last_match.captures
|
727
|
+
fmt_hash[:true_color] = tco unless tco.blank?
|
728
|
+
fmt_hash[:true_bgcolor] = tbg unless tbg.blank?
|
729
|
+
fmt_hash[:false_color] = fco unless fco.blank?
|
730
|
+
fmt_hash[:false_bgcolor] = fbg unless fbg.blank?
|
731
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
729
732
|
end
|
730
733
|
str_fmt_hash, fmt = parse_str_fmt(fmt)
|
731
734
|
fmt_hash = fmt_hash.merge(str_fmt_hash)
|
732
735
|
if fmt =~ /Y/
|
733
736
|
fmt_hash[:true_text] = 'Y'
|
734
737
|
fmt_hash[:false_text] = 'N'
|
735
|
-
fmt = fmt.sub(
|
738
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
736
739
|
end
|
737
740
|
if fmt =~ /T/
|
738
741
|
fmt_hash[:true_text] = 'T'
|
739
742
|
fmt_hash[:false_text] = 'F'
|
740
|
-
fmt = fmt.sub(
|
743
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
741
744
|
end
|
742
745
|
if fmt =~ /X/
|
743
746
|
fmt_hash[:true_text] = 'X'
|
744
747
|
fmt_hash[:false_text] = ''
|
745
|
-
fmt = fmt.sub(
|
748
|
+
fmt = fmt.sub(Regexp.last_match[0], '')
|
746
749
|
end
|
747
750
|
unless fmt.blank? || !strict
|
748
751
|
raise UserError, "unrecognized boolean formatting instructions '#{fmt}'"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rainbow'
|
2
4
|
|
3
5
|
module FatTable
|
@@ -26,10 +28,10 @@ module FatTable
|
|
26
28
|
super
|
27
29
|
@options[:unicode] = options.fetch(:unicode, true)
|
28
30
|
@options[:framecolor] = options.fetch(:framecolor, 'none.none')
|
29
|
-
return unless @options[:framecolor] =~ /([-_a-zA-Z]*)(\.([-_a-zA-Z]*))/
|
31
|
+
return unless @options[:framecolor] =~ /(?<co>[-_a-zA-Z]*)(\.(?<bg>[-_a-zA-Z]*))/
|
30
32
|
|
31
|
-
@options[:frame_fg] =
|
32
|
-
@options[:frame_bg] =
|
33
|
+
@options[:frame_fg] = Regexp.last_match[:co].downcase unless Regexp.last_match[:co].blank?
|
34
|
+
@options[:frame_bg] = Regexp.last_match[:bg].downcase unless Regexp.last_match[:bg].blank?
|
33
35
|
end
|
34
36
|
|
35
37
|
# Valid colors for ANSI terminal using the rainbow gem's X11ColorNames.
|
@@ -101,18 +103,18 @@ module FatTable
|
|
101
103
|
# Unicode line-drawing characters. We use double lines before and after the
|
102
104
|
# table and single lines for the sides and hlines between groups and
|
103
105
|
# footers.
|
104
|
-
UPPER_LEFT = "\u2552"
|
105
|
-
UPPER_RIGHT = "\u2555"
|
106
|
-
DOUBLE_RULE = "\u2550"
|
107
|
-
UPPER_TEE = "\u2564"
|
108
|
-
VERTICAL_RULE = "\u2502"
|
109
|
-
LEFT_TEE = "\u251C"
|
110
|
-
HORIZONTAL_RULE = "\u2500"
|
111
|
-
SINGLE_CROSS = "\u253C"
|
112
|
-
RIGHT_TEE = "\u2524"
|
113
|
-
LOWER_LEFT = "\u2558"
|
114
|
-
LOWER_RIGHT = "\u255B"
|
115
|
-
LOWER_TEE = "\u2567"
|
106
|
+
UPPER_LEFT = "\u2552"
|
107
|
+
UPPER_RIGHT = "\u2555"
|
108
|
+
DOUBLE_RULE = "\u2550"
|
109
|
+
UPPER_TEE = "\u2564"
|
110
|
+
VERTICAL_RULE = "\u2502"
|
111
|
+
LEFT_TEE = "\u251C"
|
112
|
+
HORIZONTAL_RULE = "\u2500"
|
113
|
+
SINGLE_CROSS = "\u253C"
|
114
|
+
RIGHT_TEE = "\u2524"
|
115
|
+
LOWER_LEFT = "\u2558"
|
116
|
+
LOWER_RIGHT = "\u255B"
|
117
|
+
LOWER_TEE = "\u2567"
|
116
118
|
# :startdoc:
|
117
119
|
|
118
120
|
def upper_left
|
data/lib/fat_table/patches.rb
CHANGED
data/lib/fat_table/table.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FatTable
|
2
4
|
# A container for a two-dimensional table. All cells in the table must be a
|
3
5
|
# String, a DateTime (or Date), a Numeric (Bignum, Integer, or BigDecimal), or
|
@@ -880,10 +882,7 @@ module FatTable
|
|
880
882
|
# Apply the set operation given by ~oper~ between this table and the other
|
881
883
|
# table given in the first argument. If distinct is true, eliminate
|
882
884
|
# duplicates from the result.
|
883
|
-
def set_operation(other, oper = :+,
|
884
|
-
distinct: true,
|
885
|
-
add_boundaries: true,
|
886
|
-
inherit_boundaries: false)
|
885
|
+
def set_operation(other, oper = :+, distinct: true, add_boundaries: true, inherit_boundaries: false)
|
887
886
|
unless columns.size == other.columns.size
|
888
887
|
msg = "can't apply set ops to tables with a different number of columns"
|
889
888
|
raise UserError, msg
|
@@ -1083,10 +1082,10 @@ module FatTable
|
|
1083
1082
|
# Translate any remaining row_b heads to append '_b' if they have the
|
1084
1083
|
# same name as a row_a key.
|
1085
1084
|
a_heads = row_a.keys
|
1086
|
-
row_b = row_b.to_a.each.map
|
1085
|
+
row_b = row_b.to_a.each.map do |k, v|
|
1087
1086
|
[a_heads.include?(k) ? "#{k}_b".to_sym : k, v]
|
1088
|
-
|
1089
|
-
row_a.merge(row_b)
|
1087
|
+
end
|
1088
|
+
row_a.merge(row_b.to_h)
|
1090
1089
|
end
|
1091
1090
|
|
1092
1091
|
# Return a hash for the local variables of a join expression in which all
|
@@ -1125,7 +1124,7 @@ module FatTable
|
|
1125
1124
|
[nat_exp, common_heads]
|
1126
1125
|
end
|
1127
1126
|
else
|
1128
|
-
# We have expressions to evaluate
|
1127
|
+
# We have join expressions to evaluate
|
1129
1128
|
and_conds = []
|
1130
1129
|
partial_result = nil
|
1131
1130
|
last_sym = nil
|
@@ -1133,8 +1132,8 @@ module FatTable
|
|
1133
1132
|
case exp
|
1134
1133
|
when Symbol
|
1135
1134
|
case exp.to_s.clean
|
1136
|
-
when /\A(
|
1137
|
-
a_head =
|
1135
|
+
when /\A(?<sy>.*)_a\z/
|
1136
|
+
a_head = Regexp.last_match[:sy].to_sym
|
1138
1137
|
unless a_heads.include?(a_head)
|
1139
1138
|
raise UserError, "no column '#{a_head}' in table"
|
1140
1139
|
end
|
@@ -1149,11 +1148,11 @@ module FatTable
|
|
1149
1148
|
partial_result = nil
|
1150
1149
|
else
|
1151
1150
|
# First of a pair of _a or _b
|
1152
|
-
partial_result = "(#{a_head}_a == "
|
1151
|
+
partial_result = String.new("(#{a_head}_a == ")
|
1153
1152
|
end
|
1154
1153
|
last_sym = a_head
|
1155
|
-
when /\A(
|
1156
|
-
b_head =
|
1154
|
+
when /\A(?<sy>.*)_b\z/
|
1155
|
+
b_head = Regexp.last_match[:sy].to_sym
|
1157
1156
|
unless b_heads.include?(b_head)
|
1158
1157
|
raise UserError, "no column '#{b_head}' in second table"
|
1159
1158
|
end
|
@@ -1168,7 +1167,7 @@ module FatTable
|
|
1168
1167
|
partial_result = nil
|
1169
1168
|
else
|
1170
1169
|
# First of a pair of _a or _b
|
1171
|
-
partial_result = "(#{b_head}_b == "
|
1170
|
+
partial_result = String.new("(#{b_head}_b == ")
|
1172
1171
|
end
|
1173
1172
|
b_common_heads << b_head
|
1174
1173
|
last_sym = b_head
|
@@ -1353,9 +1352,9 @@ module FatTable
|
|
1353
1352
|
|
1354
1353
|
method = "to_#{fmt}"
|
1355
1354
|
if block_given?
|
1356
|
-
send
|
1355
|
+
send(method, options, &Proc.new)
|
1357
1356
|
else
|
1358
|
-
send
|
1357
|
+
send(method, options)
|
1359
1358
|
end
|
1360
1359
|
end
|
1361
1360
|
|
data/lib/fat_table/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fat_table
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel E. Doherty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: ruby_jard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rake
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -321,7 +335,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
321
335
|
- !ruby/object:Gem::Version
|
322
336
|
version: '0'
|
323
337
|
requirements: []
|
324
|
-
rubygems_version: 3.
|
338
|
+
rubygems_version: 3.1.2
|
325
339
|
signing_key:
|
326
340
|
specification_version: 4
|
327
341
|
summary: Provides tools for working with tables as a data type.
|