hash_base 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +2 -0
- data/.gitignore +8 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE +339 -0
- data/README.md +34 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/hash_base-0.1.5.gem +0 -0
- data/hash_base.gemspec +34 -0
- data/lib/hash_base/array/grouping.rb +97 -0
- data/lib/hash_base/array/to_html.rb +95 -0
- data/lib/hash_base/array/to_list.rb +48 -0
- data/lib/hash_base/array/to_text.rb +50 -0
- data/lib/hash_base/hash/apply.rb +65 -0
- data/lib/hash_base/hash/deep_values.rb +89 -0
- data/lib/hash_base/hash/grouping.rb +69 -0
- data/lib/hash_base/hash/to_table.rb +123 -0
- data/lib/hash_base/hash/zip_out.rb +58 -0
- data/lib/hash_base/version.rb +24 -0
- data/lib/hash_base.rb +31 -0
- metadata +84 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# utilities for ruby hashes and ruby arrays
|
4
|
+
#
|
5
|
+
# Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License
|
9
|
+
# as published by the Free Software Foundation; either version 2
|
10
|
+
# of the License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
20
|
+
#
|
21
|
+
|
22
|
+
class Array
|
23
|
+
|
24
|
+
########################################################################################
|
25
|
+
#
|
26
|
+
# to_html: creates a html table from a rectangular array
|
27
|
+
#
|
28
|
+
# options: headings: true/false, footer: true/false
|
29
|
+
#
|
30
|
+
########################################################################################
|
31
|
+
def to_html(options={}, &block)
|
32
|
+
|
33
|
+
options[:table] = options[:table].to_h.merge({:class => options[:table_class]}.compact) # support legacy
|
34
|
+
|
35
|
+
t = dup
|
36
|
+
body = t
|
37
|
+
head, body = [t.shift, t] if options[:headings]
|
38
|
+
foot, body = [t.pop , t] if options[:footer]
|
39
|
+
|
40
|
+
html_tag(:table, options[:table].to_h.compact) do
|
41
|
+
[head].compact.table_row_group(options.merge(:row_group => {:type => :thead}, :cell => {:type => :th}), &block) +
|
42
|
+
body.compact.table_row_group(options.merge(:row_group => {:type => :tbody}, :cell => {:type => :td}), &block) +
|
43
|
+
[foot].compact.table_row_group(options.merge(:row_group => {:type => :tfoot}, :cell => {:type => :td}), &block)
|
44
|
+
end
|
45
|
+
end #def
|
46
|
+
|
47
|
+
|
48
|
+
def table_row_group(options={}, &block)
|
49
|
+
rows = collect.with_index do |row, row_index|
|
50
|
+
row.table_row(row_index, options, &block)
|
51
|
+
end.join("")
|
52
|
+
rows.present? ? html_tag(options.dig(:row_group, :type) || :tbody, rows) : ""
|
53
|
+
end #def
|
54
|
+
|
55
|
+
def table_row(row_index, options={}, &block)
|
56
|
+
html_tag(:tr, options[:row].to_h.compact) do
|
57
|
+
row = collect.with_index do |value, column_index|
|
58
|
+
html_tag(options.dig(:cell, :type) || :td, options[:cell].to_h.except(:type).compact) do
|
59
|
+
cell_value = if block_given?
|
60
|
+
yield value, column_index, row_index
|
61
|
+
else
|
62
|
+
style_value(value, options)
|
63
|
+
end
|
64
|
+
end #html_tag #cell_type
|
65
|
+
end.join("") #collect columns
|
66
|
+
row
|
67
|
+
end #html_tag #tr
|
68
|
+
end #def
|
69
|
+
|
70
|
+
########################################################################################
|
71
|
+
private
|
72
|
+
########################################################################################
|
73
|
+
def style_value(value, options={}, &block)
|
74
|
+
case value.class
|
75
|
+
when Integer
|
76
|
+
value.to_s
|
77
|
+
when Numeric
|
78
|
+
p = options[:precision] || 2
|
79
|
+
sprintf("%.#{p}f",value)
|
80
|
+
else
|
81
|
+
options[:html_safe] ? value.to_s : CGI::escapeHTML(value.to_s)
|
82
|
+
end
|
83
|
+
end #def
|
84
|
+
|
85
|
+
def html_tag(type, *content, &block)
|
86
|
+
if block_given?
|
87
|
+
opts = content.first.to_h.map{|k,v| " #{k}='#{v}'"}.join
|
88
|
+
"<#{type}#{opts}>#{yield block}</#{type}>"
|
89
|
+
else
|
90
|
+
opts = content[1].to_h.map{|k,v| " #{k}='#{v}'"}.join
|
91
|
+
"<#{type}#{opts}>#{content.first}</#{type}>"
|
92
|
+
end
|
93
|
+
end #def
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# utilities for ruby hashes and ruby arrays
|
4
|
+
#
|
5
|
+
# Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License
|
9
|
+
# as published by the Free Software Foundation; either version 2
|
10
|
+
# of the License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
20
|
+
#
|
21
|
+
|
22
|
+
class Array
|
23
|
+
|
24
|
+
########################################################################################
|
25
|
+
#
|
26
|
+
# converts array of hashes to one hash with elements in array
|
27
|
+
#
|
28
|
+
########################################################################################
|
29
|
+
class ArrayRowIsNotAHash < StandardError; end
|
30
|
+
|
31
|
+
def to_list
|
32
|
+
# test, if each element is a hash
|
33
|
+
each do |hash|
|
34
|
+
raise ArrayRowIsNotAHash unless hash.is_a?(Hash)
|
35
|
+
end
|
36
|
+
# extract all keys from all hashes
|
37
|
+
keys = map do |hash|
|
38
|
+
hash.keys
|
39
|
+
end.flatten.uniq
|
40
|
+
# now extract value for each key in each hash
|
41
|
+
map do |hash|
|
42
|
+
keys.map do |key|
|
43
|
+
hash[key]
|
44
|
+
end
|
45
|
+
end.unshift(keys)
|
46
|
+
end #def
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# utilities for ruby hashes and ruby arrays
|
4
|
+
#
|
5
|
+
# Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License
|
9
|
+
# as published by the Free Software Foundation; either version 2
|
10
|
+
# of the License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
20
|
+
#
|
21
|
+
|
22
|
+
class Array
|
23
|
+
|
24
|
+
########################################################################################
|
25
|
+
#
|
26
|
+
# creates a table from a rectangular array, balanced with indent
|
27
|
+
#
|
28
|
+
# indent: (Integer) number of spaces for padding each table element
|
29
|
+
# precision (Integer) number of precision digits to print for floats
|
30
|
+
# padding (String) string between adjacing colums
|
31
|
+
########################################################################################
|
32
|
+
def to_text(indent: 15, precision: 2, padding: " | " )
|
33
|
+
map do |line|
|
34
|
+
ln = line.is_a?(Array) ? line : [line]
|
35
|
+
ln.map do |e|
|
36
|
+
case e
|
37
|
+
when Integer
|
38
|
+
e.to_s.rjust(indent)
|
39
|
+
when Complex, Rational
|
40
|
+
e.to_s.rjust(indent)
|
41
|
+
when Numeric
|
42
|
+
sprintf("%.#{precision}f",e).rjust(indent)
|
43
|
+
else
|
44
|
+
e.to_s.ljust(indent)
|
45
|
+
end
|
46
|
+
end.join(padding)
|
47
|
+
end.join("\n")
|
48
|
+
end #def
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# utilities for ruby hashes
|
4
|
+
#
|
5
|
+
# Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License
|
9
|
+
# as published by the Free Software Foundation; either version 2
|
10
|
+
# of the License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
20
|
+
#
|
21
|
+
|
22
|
+
class Hash
|
23
|
+
|
24
|
+
########################################################################################
|
25
|
+
#
|
26
|
+
# apply(&block): applies block to deepest element, which is not a Hash
|
27
|
+
#
|
28
|
+
# -> hash
|
29
|
+
# new hash ->
|
30
|
+
#
|
31
|
+
########################################################################################
|
32
|
+
def apply( &block )
|
33
|
+
return to_enum(:each) unless block_given?
|
34
|
+
hash = Hash.new
|
35
|
+
each do |key, value|
|
36
|
+
if value.is_a?(Hash)
|
37
|
+
hash[key] = value.apply( &block )
|
38
|
+
else
|
39
|
+
hash[key] = yield value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
hash
|
43
|
+
end #def
|
44
|
+
|
45
|
+
########################################################################################
|
46
|
+
#
|
47
|
+
# apply!(&block): applies block to deepest element, which is not a Hash
|
48
|
+
#
|
49
|
+
# -> hash
|
50
|
+
# same hash ->
|
51
|
+
#
|
52
|
+
########################################################################################
|
53
|
+
def apply!( &block )
|
54
|
+
return to_enum(:each) unless block_given?
|
55
|
+
each do |key, value|
|
56
|
+
if value.is_a?(Hash)
|
57
|
+
self[key] = value.apply( &block )
|
58
|
+
else
|
59
|
+
self[key] = yield value
|
60
|
+
end
|
61
|
+
end
|
62
|
+
self
|
63
|
+
end #def
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# utilities for ruby hashes
|
4
|
+
#
|
5
|
+
# Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License
|
9
|
+
# as published by the Free Software Foundation; either version 2
|
10
|
+
# of the License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
20
|
+
#
|
21
|
+
|
22
|
+
class Hash
|
23
|
+
|
24
|
+
########################################################################################
|
25
|
+
#
|
26
|
+
# deep_values: gets an array of values of a nested hash as a flat array
|
27
|
+
#
|
28
|
+
# -> hash
|
29
|
+
# array ->
|
30
|
+
#
|
31
|
+
########################################################################################
|
32
|
+
def deep_values
|
33
|
+
arr = Array.new
|
34
|
+
each do |key, value|
|
35
|
+
if value.is_a?(Hash)
|
36
|
+
arr += value.deep_values
|
37
|
+
else
|
38
|
+
arr << value
|
39
|
+
end
|
40
|
+
end #each
|
41
|
+
arr
|
42
|
+
end #def
|
43
|
+
|
44
|
+
|
45
|
+
########################################################################################
|
46
|
+
#
|
47
|
+
# max_depth: gets max depth of a hash
|
48
|
+
#
|
49
|
+
# -> hash
|
50
|
+
# int ->
|
51
|
+
#
|
52
|
+
########################################################################################
|
53
|
+
def max_depth(depth: 1)
|
54
|
+
max_depth = depth
|
55
|
+
each do |k,v|
|
56
|
+
if v.is_a?(Hash)
|
57
|
+
max_depth = [max_depth, v.max_depth( depth: depth + 1 )].max
|
58
|
+
end
|
59
|
+
end
|
60
|
+
max_depth
|
61
|
+
end #def
|
62
|
+
|
63
|
+
########################################################################################
|
64
|
+
#
|
65
|
+
# deep_diff: compares two hashes - counter part to Array.deep_diff
|
66
|
+
# source: stackoverflow
|
67
|
+
#
|
68
|
+
########################################################################################
|
69
|
+
def deep_diff(other, &block)
|
70
|
+
(self.keys + other.keys).uniq.inject({}) do |memo, key|
|
71
|
+
left = self[key]
|
72
|
+
right = other[key]
|
73
|
+
|
74
|
+
if block_given?
|
75
|
+
next memo if yield left, right
|
76
|
+
else
|
77
|
+
next memo if left == right
|
78
|
+
end
|
79
|
+
if left.respond_to?(:deep_diff) && right.respond_to?(:deep_diff)
|
80
|
+
memo[key] = left.deep_diff(right)
|
81
|
+
else
|
82
|
+
memo[key] = [left, right]
|
83
|
+
end
|
84
|
+
|
85
|
+
memo
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# utilities for ruby hashes and ruby arrays
|
4
|
+
#
|
5
|
+
# Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License
|
9
|
+
# as published by the Free Software Foundation; either version 2
|
10
|
+
# of the License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
20
|
+
#
|
21
|
+
|
22
|
+
class Hash
|
23
|
+
|
24
|
+
########################################################################################
|
25
|
+
#
|
26
|
+
# group_by_positions: counter part to Array.group_by_positions
|
27
|
+
#
|
28
|
+
# will only be invoked by Array.group_by_positions
|
29
|
+
#
|
30
|
+
########################################################################################
|
31
|
+
def group_by_positions( *positions )
|
32
|
+
ohash = ActiveSupport::OrderedHash.new
|
33
|
+
each do |key, val|
|
34
|
+
case val
|
35
|
+
when Hash, Array
|
36
|
+
ohash[key] = val.group_by_positions( *positions )
|
37
|
+
else
|
38
|
+
ohash[key] = val
|
39
|
+
end
|
40
|
+
end #each
|
41
|
+
ohash
|
42
|
+
end #def
|
43
|
+
|
44
|
+
########################################################################################
|
45
|
+
#
|
46
|
+
# expand: reverse of group_by_positions
|
47
|
+
#
|
48
|
+
# -> nested_hash
|
49
|
+
# -> array
|
50
|
+
#
|
51
|
+
########################################################################################
|
52
|
+
def expand(path_to_here=[])
|
53
|
+
arry = []
|
54
|
+
each do |k, v|
|
55
|
+
if v.is_a?(Hash)
|
56
|
+
arry += v.expand(path_to_here + [k])
|
57
|
+
elsif v.is_a?(Array)
|
58
|
+
v.each do |el|
|
59
|
+
arry << (path_to_here + [k] + el ) if el.is_a?(Array)
|
60
|
+
arry << (path_to_here + [k] + [el] ) unless el.is_a?(Array)
|
61
|
+
end
|
62
|
+
else
|
63
|
+
arry << (path_to_here + [k] + [v])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
arry
|
67
|
+
end #def
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# utilities for ruby hashes and ruby arrays
|
4
|
+
#
|
5
|
+
# Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License
|
9
|
+
# as published by the Free Software Foundation; either version 2
|
10
|
+
# of the License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
20
|
+
#
|
21
|
+
|
22
|
+
class Hash
|
23
|
+
|
24
|
+
########################################################################################
|
25
|
+
#
|
26
|
+
# to_table: creates a rectangular table from a nested hash
|
27
|
+
#
|
28
|
+
# -> hash
|
29
|
+
# array ->
|
30
|
+
#
|
31
|
+
# parameters
|
32
|
+
#
|
33
|
+
# level: (Integer) only used internally for recursive calls (do not use)
|
34
|
+
# indent: (Integer) number of spaces for padding each table element
|
35
|
+
# precision (Integer) number of precision digits for floats
|
36
|
+
# dosort; (Boolean) should each level of keys be sorted ?
|
37
|
+
# content: (String) "style" => creates a table of cell styles, else table
|
38
|
+
# of data
|
39
|
+
# format: (String) "text" - text output, balanced with indent parameter
|
40
|
+
# "html" - html output
|
41
|
+
# total: (Proc) "-> x {x.flatten.inject(:+)}" proc to create totals of
|
42
|
+
# arrays of deepest values
|
43
|
+
# total_caption (String) caption for total line
|
44
|
+
# grand_total (Proc) "-> x {x.depp_values.flatten.inject(:+)}" proc to
|
45
|
+
# create totals of arrays of deepest values
|
46
|
+
# grant_total_caption (string) caption for grand total line
|
47
|
+
#
|
48
|
+
########################################################################################
|
49
|
+
def to_table( level: 0, indent: 15, precision: 2, dosort: true, content: "data", format: nil, divisor: nil, total: nil, total_caption: "", grand_total: nil, grand_total_caption: "" )
|
50
|
+
|
51
|
+
arry = []
|
52
|
+
i = 0
|
53
|
+
|
54
|
+
h = dosort ? sort : self
|
55
|
+
|
56
|
+
h.each do |k, v|
|
57
|
+
|
58
|
+
first_line = Array.new( i > 0 ? level : 0) {""} + [k] unless content == "style"
|
59
|
+
first_line = Array.new( i > 0 ? level : 0) {|l| "empty level_#{l}"} + ["key level_#{level}"] if content == "style"
|
60
|
+
|
61
|
+
if v.is_a?(Hash)
|
62
|
+
lines = v.to_table(level: level + 1, content: content, indent: indent, dosort: dosort, divisor: divisor, total: total, total_caption: total_caption, grand_total: grand_total, grand_total_caption: grand_total_caption)
|
63
|
+
first_line += lines[0] # complement current line with last key
|
64
|
+
arry << first_line
|
65
|
+
arry += lines.drop(1) if lines.drop(1).present?
|
66
|
+
elsif v.is_a?(Array) #must be array
|
67
|
+
lines = []
|
68
|
+
v.each_with_index do |av, i|
|
69
|
+
elem = (av.is_a?(Array) ? av : [av])
|
70
|
+
lines << (Array.new( i > 0 ? level + 1 : 0) {""} + elem ) unless content == "style"
|
71
|
+
lines << (Array.new( i > 0 ? level + 1 : 0) {|l| "empty level_#{l}"} + Array.new(elem.length){"value level_#{level}"} ) if content == "style"
|
72
|
+
end
|
73
|
+
first_line += lines[0] # complement current line
|
74
|
+
arry << first_line
|
75
|
+
arry += lines.drop(1) if lines.drop(1).present?
|
76
|
+
|
77
|
+
max_len = arry.map{|r| r.length}.max
|
78
|
+
|
79
|
+
unless content == "style"
|
80
|
+
arry << (Array.new( max_len + 1) {divisor.to_s * indent} ) if total && divisor
|
81
|
+
arry << (["#{total_caption}"] + Array.new( max_len - 1) {""} + [total.yield(v)] ) if total
|
82
|
+
arry << (Array.new( max_len + 1) {""} ) if total && divisor
|
83
|
+
else
|
84
|
+
arry << (Array.new( max_len + 1) {|l| "divisor level_#{l}"} ) if total && divisor
|
85
|
+
arry << (["total_caption level_0"] + Array.new( max_len - 1) {|l| "empty level_#{l+1}"} + ["total level_#{level}"] ) if total
|
86
|
+
arry << (Array.new( max_len + 1) {|l| "empty level_#{l}"} ) if total && divisor
|
87
|
+
end
|
88
|
+
end
|
89
|
+
i+=1
|
90
|
+
end #each
|
91
|
+
|
92
|
+
if level == 0
|
93
|
+
|
94
|
+
max_len = arry.map{|r| r.length}.max
|
95
|
+
|
96
|
+
unless content == "style"
|
97
|
+
arry << (Array.new( max_len + 1 ) {divisor.to_s * indent} ) if grand_total && divisor
|
98
|
+
arry << (["#{grand_total_caption}"] + Array.new( max_len - 1 ) {""} + [grand_total.yield(self)] ) if grand_total
|
99
|
+
else
|
100
|
+
arry << (Array.new( max_len + 1) {"grand_total divisor"} ) if grand_total && divisor
|
101
|
+
arry << (["grand_total_caption level_0"] + Array.new( max_len - 1) {|l| "empty grand_total level_#{l+1}"} + ["grand_total"]) if grand_total
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
max_len = arry.map{|r| r.length}.max
|
106
|
+
|
107
|
+
arry.map!{|l| l += Array.new(max_len - l.length) {""} } unless content == "style"
|
108
|
+
arry.map!{|l| l += Array.new(max_len - l.length) {"empty padding"} } if content == "style"
|
109
|
+
|
110
|
+
if format == "text"
|
111
|
+
arry.to_text(indent: indent, precision: precision)
|
112
|
+
elsif format == "html"
|
113
|
+
arry.to_html( styles: self.to_table(content: "style", total: true, grand_total: true))
|
114
|
+
else
|
115
|
+
arry
|
116
|
+
end
|
117
|
+
else
|
118
|
+
arry
|
119
|
+
end
|
120
|
+
|
121
|
+
end #def
|
122
|
+
|
123
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# utilities for ruby hashes
|
4
|
+
#
|
5
|
+
# Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License
|
9
|
+
# as published by the Free Software Foundation; either version 2
|
10
|
+
# of the License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
20
|
+
#
|
21
|
+
|
22
|
+
class Hash
|
23
|
+
|
24
|
+
########################################################################################
|
25
|
+
#
|
26
|
+
# zip_out: puts elements into one zip file with keys as filenames
|
27
|
+
#
|
28
|
+
# -> hash
|
29
|
+
# zip ->
|
30
|
+
#
|
31
|
+
# depends on gem 'zip'
|
32
|
+
#
|
33
|
+
########################################################################################
|
34
|
+
def zip_out(&block)
|
35
|
+
|
36
|
+
return nil unless defined?(Zip)
|
37
|
+
|
38
|
+
zip_stream = Zip::OutputStream.write_buffer do |zip|
|
39
|
+
|
40
|
+
each do |key, obj|
|
41
|
+
zip.put_next_entry(key)
|
42
|
+
if block_given?
|
43
|
+
zip.write(yield obj)
|
44
|
+
else
|
45
|
+
zip.write(obj)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# important - rewind the steam
|
51
|
+
zip_stream.rewind
|
52
|
+
|
53
|
+
# read out zip contents
|
54
|
+
zip_stream.read
|
55
|
+
|
56
|
+
end #def
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# deep_try works like try, but with an arbitrary long list of methods
|
4
|
+
#
|
5
|
+
# Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License
|
9
|
+
# as published by the Free Software Foundation; either version 2
|
10
|
+
# of the License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
20
|
+
#
|
21
|
+
|
22
|
+
module HashBase
|
23
|
+
VERSION = "0.1.6"
|
24
|
+
end
|
data/lib/hash_base.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# utilities for ruby hashes and ruby arrays
|
4
|
+
#
|
5
|
+
# Copyright © 2021 Stephan Wenzel <stephan.wenzel@drwpatent.de>
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU General Public License
|
9
|
+
# as published by the Free Software Foundation; either version 2
|
10
|
+
# of the License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
20
|
+
#
|
21
|
+
|
22
|
+
require "hash_base/hash/grouping"
|
23
|
+
require "hash_base/hash/apply"
|
24
|
+
require "hash_base/hash/deep_values"
|
25
|
+
require "hash_base/hash/to_table"
|
26
|
+
require "hash_base/hash/zip_out"
|
27
|
+
|
28
|
+
require "hash_base/array/grouping"
|
29
|
+
require "hash_base/array/to_html"
|
30
|
+
require "hash_base/array/to_list"
|
31
|
+
require "hash_base/array/to_text"
|