fat_core 1.6.0 → 1.7.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/lib/fat_core/column.rb +71 -9
- data/lib/fat_core/date.rb +6 -6
- data/lib/fat_core/enumerable.rb +12 -1
- data/lib/fat_core/formatters/aoa_formatter.rb +84 -0
- data/lib/fat_core/formatters/aoh_formatter.rb +82 -0
- data/lib/fat_core/formatters/formatter.rb +973 -0
- data/lib/fat_core/formatters/org_formatter.rb +72 -0
- data/lib/fat_core/formatters/text_formatter.rb +91 -0
- data/lib/fat_core/formatters.rb +5 -0
- data/lib/fat_core/hash.rb +13 -0
- data/lib/fat_core/numeric.rb +3 -3
- data/lib/fat_core/period.rb +5 -1
- data/lib/fat_core/string.rb +20 -0
- data/lib/fat_core/symbol.rb +1 -1
- data/lib/fat_core/table.rb +251 -266
- data/lib/fat_core/version.rb +2 -2
- data/lib/fat_core.rb +2 -0
- data/spec/lib/column_spec.rb +24 -8
- data/spec/lib/formatters/aoa_formatter_spec.rb +62 -0
- data/spec/lib/formatters/aoh_formatter_spec.rb +61 -0
- data/spec/lib/formatters/formatter_spec.rb +371 -0
- data/spec/lib/formatters/org_formatter_spec.rb +60 -0
- data/spec/lib/formatters/text_formatter_spec.rb +60 -0
- data/spec/lib/period_spec.rb +9 -2
- data/spec/lib/symbol_spec.rb +1 -1
- data/spec/lib/table_spec.rb +86 -167
- metadata +18 -2
@@ -0,0 +1,72 @@
|
|
1
|
+
module FatCore
|
2
|
+
# Output the table in the same way as org-mode for emacs does. This is almost
|
3
|
+
# identical to TextFormatter except that dates do get formatted as inactive
|
4
|
+
# timestamps and the connector at the beginning of hlines is a '|' rather than
|
5
|
+
# a '+' as for text tables.
|
6
|
+
class OrgFormatter < Formatter
|
7
|
+
|
8
|
+
self.default_format = default_format.dup
|
9
|
+
self.default_format[:date_fmt] = '[%F]'
|
10
|
+
self.default_format[:datetime_fmt] = '[%F %a %H:%M:%S]'
|
11
|
+
|
12
|
+
# Does this Formatter require a second pass over the cells to align the
|
13
|
+
# columns according to the alignment formatting instruction to the width of
|
14
|
+
# the widest cell in each column?
|
15
|
+
def aligned?
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
def pre_header(widths)
|
20
|
+
result = '|'
|
21
|
+
widths.values.each do |w|
|
22
|
+
result += '-' * (w + 2) + '+'
|
23
|
+
end
|
24
|
+
result[-1] = '|'
|
25
|
+
result + "\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
def pre_row
|
29
|
+
'|'
|
30
|
+
end
|
31
|
+
|
32
|
+
# Add one space of padding.
|
33
|
+
def pre_cell(_h)
|
34
|
+
' '
|
35
|
+
end
|
36
|
+
|
37
|
+
def quote_cell(v)
|
38
|
+
v
|
39
|
+
end
|
40
|
+
|
41
|
+
# Add one space of padding.
|
42
|
+
def post_cell
|
43
|
+
' '
|
44
|
+
end
|
45
|
+
|
46
|
+
def inter_cell
|
47
|
+
'|'
|
48
|
+
end
|
49
|
+
|
50
|
+
def post_row
|
51
|
+
"|\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
def hline(widths)
|
55
|
+
result = '|'
|
56
|
+
widths.values.each do |w|
|
57
|
+
result += '-' * (w + 2) + '+'
|
58
|
+
end
|
59
|
+
result[-1] = '|'
|
60
|
+
result + "\n"
|
61
|
+
end
|
62
|
+
|
63
|
+
def post_footers(widths)
|
64
|
+
result = '|'
|
65
|
+
widths.values.each do |w|
|
66
|
+
result += '-' * (w + 2) + '+'
|
67
|
+
end
|
68
|
+
result[-1] = '|'
|
69
|
+
result + "\n"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module FatCore
|
2
|
+
# Output the table as plain text. This is almost identical to OrgFormatter
|
3
|
+
# except that dates do not get formatted as inactive timestamps and the
|
4
|
+
# connector at the beginning of hlines is a '+' rather than a '|' as for org
|
5
|
+
# tables.
|
6
|
+
class TextFormatter < Formatter
|
7
|
+
# Does this Formatter require a second pass over the cells to align the
|
8
|
+
# columns according to the alignment formatting instruction to the width of
|
9
|
+
# the widest cell in each column?
|
10
|
+
def aligned?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def pre_header(widths)
|
15
|
+
result = '|'
|
16
|
+
widths.values.each do |w|
|
17
|
+
result += '-' * (w + 2) + '+'
|
18
|
+
end
|
19
|
+
result[-1] = '|'
|
20
|
+
result + "\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
def pre_row
|
24
|
+
'|'
|
25
|
+
end
|
26
|
+
|
27
|
+
# Add one space of padding.
|
28
|
+
def pre_cell(_h)
|
29
|
+
' '
|
30
|
+
end
|
31
|
+
|
32
|
+
def quote_cell(v)
|
33
|
+
v
|
34
|
+
end
|
35
|
+
|
36
|
+
# Add one space of padding.
|
37
|
+
def post_cell
|
38
|
+
' '
|
39
|
+
end
|
40
|
+
|
41
|
+
def inter_cell
|
42
|
+
'|'
|
43
|
+
end
|
44
|
+
|
45
|
+
def post_row
|
46
|
+
"|\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
def hline(widths)
|
50
|
+
result = '+'
|
51
|
+
widths.values.each do |w|
|
52
|
+
result += '-' * (w + 2) + '+'
|
53
|
+
end
|
54
|
+
result[-1] = '+'
|
55
|
+
result + "\n"
|
56
|
+
end
|
57
|
+
|
58
|
+
def pre_group
|
59
|
+
''
|
60
|
+
end
|
61
|
+
|
62
|
+
def post_group
|
63
|
+
''
|
64
|
+
end
|
65
|
+
|
66
|
+
def pre_gfoot
|
67
|
+
''
|
68
|
+
end
|
69
|
+
|
70
|
+
def post_gfoot
|
71
|
+
''
|
72
|
+
end
|
73
|
+
|
74
|
+
def pre_foot
|
75
|
+
''
|
76
|
+
end
|
77
|
+
|
78
|
+
def post_foot
|
79
|
+
''
|
80
|
+
end
|
81
|
+
|
82
|
+
def post_footers(widths)
|
83
|
+
result = '+'
|
84
|
+
widths.values.each do |w|
|
85
|
+
result += '-' * (w + 2) + '+'
|
86
|
+
end
|
87
|
+
result[-1] = '+'
|
88
|
+
result + "\n"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/fat_core/hash.rb
CHANGED
@@ -1,4 +1,17 @@
|
|
1
1
|
class Hash
|
2
|
+
# Yield each key-value pair in the Hash together with boolean flags that
|
3
|
+
# indicate whether the item is the first or last yielded.
|
4
|
+
def each_pair_with_flags
|
5
|
+
last_k = size - 1
|
6
|
+
k = 0
|
7
|
+
each_pair do |key, val|
|
8
|
+
first = (k == 0 ? true : false)
|
9
|
+
last = (k == last_k ? true : false)
|
10
|
+
yield(key, val, first, last)
|
11
|
+
k += 1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
2
15
|
# Return all keys in hash that have a value == to the given value or have an
|
3
16
|
# Enumerable value that includes the given value.
|
4
17
|
def keys_with_value(val)
|
data/lib/fat_core/numeric.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
class Numeric
|
2
2
|
def signum
|
3
|
-
if
|
3
|
+
if positive?
|
4
4
|
1
|
5
|
-
elsif
|
5
|
+
elsif negative?
|
6
6
|
-1
|
7
7
|
else
|
8
8
|
0
|
@@ -42,7 +42,7 @@ class Numeric
|
|
42
42
|
|
43
43
|
# Pad out the fractional part with zeroes to the right
|
44
44
|
n_zeroes = [places - frac.length, 0].max
|
45
|
-
frac += '0' * n_zeroes if n_zeroes
|
45
|
+
frac += '0' * n_zeroes if n_zeroes.positive?
|
46
46
|
|
47
47
|
# Place the commas in the whole part only
|
48
48
|
whole = whole.reverse
|
data/lib/fat_core/period.rb
CHANGED
@@ -462,7 +462,11 @@ class Period
|
|
462
462
|
round_up_last: false)
|
463
463
|
size = size.to_sym
|
464
464
|
if Period.chunk_sym_to_min_days(size) > length
|
465
|
-
|
465
|
+
if partial_first || partial_last
|
466
|
+
return [self]
|
467
|
+
else
|
468
|
+
raise ArgumentError, "any #{size} is longer than this period's #{length} days"
|
469
|
+
end
|
466
470
|
end
|
467
471
|
result = []
|
468
472
|
chunk_start = first.dup
|
data/lib/fat_core/string.rb
CHANGED
@@ -88,6 +88,26 @@ class String
|
|
88
88
|
return false
|
89
89
|
end
|
90
90
|
|
91
|
+
# If the string is a number, add grouping commas to the whole number part.
|
92
|
+
def commify
|
93
|
+
# Break the number into parts
|
94
|
+
return self unless clean =~ /\A(-)?(\d*)((\.)?(\d*))?\z/
|
95
|
+
neg = $1 || ''
|
96
|
+
whole = $2
|
97
|
+
frac = $5
|
98
|
+
# Place the commas in the whole part only
|
99
|
+
whole = whole.reverse
|
100
|
+
whole.gsub!(/([0-9]{3})/, '\\1,')
|
101
|
+
whole.gsub!(/,$/, '')
|
102
|
+
whole.reverse!
|
103
|
+
# Reassemble
|
104
|
+
if frac.blank?
|
105
|
+
neg + whole
|
106
|
+
else
|
107
|
+
neg + whole + '.' + frac
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
91
111
|
def wrap(width = 70, hang = 0)
|
92
112
|
offset = 0
|
93
113
|
trip = 1
|