fat_core 1.6.0 → 1.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|