fat_table 0.3.0 → 0.3.1
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 +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.
|