tabelinha 0.0.0 → 0.1.0

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/table.rb +217 -0
  3. metadata +4 -4
  4. data/lib/tabelinha.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9507fda9f6f495cd8e7d28fe0bcd4640701f709e657704b1b8cb08d90776a852
4
- data.tar.gz: 2c75bcf8ba13868f7f7a198a98e8247fc96e45db52a6803ca0216c66cd177dc5
3
+ metadata.gz: 86fbedf86c14565b197bb8b2755d8dac50b8318db5cb2a5ce73c96f0422991e9
4
+ data.tar.gz: 37f9eb12e0fb5ccb27ed17682d87e60ce3408a89d933b1cabea498d1db8ee39f
5
5
  SHA512:
6
- metadata.gz: 8156c62ae068e634191575369b7b44aec4901acb140513c3e0144c712dfa6382524304f01fd21f8c7a71bbf73b8c4901ee01e202d67ade9a75fbe80e24c58e51
7
- data.tar.gz: 2fd0affdc0b1d8390cd32a4328d93d5abe0f8fceec7291eb69df05106bf55109ba530e60556cc24f8c09c317ab72ade4a4b65f5ea1b3fbd69081920c20932223
6
+ metadata.gz: 0e2af67e046d2b6ec5fb9ce3f93ec62ffe6c563b6ae6da1e80cd2e5c427da3cb5d725f49a18c1fa86e4bd5286443b51bb61a1a2f7aba5d3e6521e406ad86308b
7
+ data.tar.gz: 0440eb7588135806ec8d057ee0f6b2a7a64bbd901a41823c599cf331cfb8836d2427c1fa29ada5d5c2538d233e9124c113292a4f026e307b460ae9f3cb1aacf4
data/lib/table.rb ADDED
@@ -0,0 +1,217 @@
1
+ module Tabelinha
2
+ module_function
3
+
4
+ # Generates a formatted table with customizable options.
5
+ #
6
+ # @param rows [Array<Array<String>>] An array of rows, where each row is an array of cells to be displayed in the table.
7
+ # @param options [Hash] An optional hash of configuration options to customize the appearance of the table.
8
+ # @option options [Boolean] :space_linebroken (true) If true, adds extra space between rows with line breaks.
9
+ # @option options [Integer] :padding (1) The number of spaces padding each cell.
10
+ # @option options [Float] :max_width (Float::INFINITY) The maximum width of the table.
11
+ # @option options [Hash] :corners Hash containing characters for table corners.
12
+ # @option options [String] :top_right ('┌') Character for the top-right corner.
13
+ # @option options [String] :top_left ('┐') Character for the top-left corner.
14
+ # @option options [String] :bottom_right ('└') Character for the bottom-right corner.
15
+ # @option options [String] :bottom_left ('┘') Character for the bottom-left corner.
16
+ # @option options [Hash] :straight Hash containing characters for straight lines.
17
+ # @option options [String] :vertical ('│') Character for vertical lines.
18
+ # @option options [String] :horizontal ('─') Character for horizontal lines.
19
+ # @option options [Hash] :junctions Hash containing characters for junctions.
20
+ # @option options [String] :top ('┬') Character for the top junction.
21
+ # @option options [String] :middle ('┼') Character for the middle junction.
22
+ # @option options [String] :bottom ('┴') Character for the bottom junction.
23
+ #
24
+ # @example
25
+ # rows = [
26
+ # ['Header 1', 'Header 2', 'Header 3'],
27
+ # ['Value 1', 'Value 2', 'Value 3'],
28
+ # ['Another Value 1', 'Another Value 2', 'Another Value 3']
29
+ # ]
30
+ #
31
+ # options = {
32
+ # space_linebroken: true,
33
+ # padding: 1,
34
+ # max_width: 80,
35
+ # corners: { top_right: '┌', top_left: '┐', bottom_right: '└', bottom_left: '┘' },
36
+ # straight: { vertical: '│', horizontal: '─' },
37
+ # junctions: { top: '┬', middle: '┼', bottom: '┴' }
38
+ # }
39
+ #
40
+ # table(rows, options)
41
+ #
42
+ # This method generates a formatted table with the specified rows and options. It supports various formatting elements
43
+ # to provide flexibility in table appearance.
44
+
45
+ def table(rows, options = {})
46
+ # sets options
47
+
48
+ options = {
49
+ space_linebroken: true,
50
+ padding: 1,
51
+ max_width: Float::INFINITY,
52
+ corners: {
53
+ top_right: '┌',
54
+ top_left: '┐',
55
+ bottom_right: '└',
56
+ bottom_left: '┘'
57
+ },
58
+ straight: {
59
+ vertical: '│',
60
+ horizontal: '─'
61
+ },
62
+ junctions: {
63
+ top: '┬',
64
+ middle: '┼',
65
+ bottom: '┴'
66
+ }
67
+ }.merge(options)
68
+
69
+ padding_amount = options[:padding]
70
+ padding = ' ' * padding_amount
71
+
72
+ # split \n and normalize rows
73
+
74
+ newline_treated_rows = []
75
+
76
+ rows.each do |row|
77
+ max_size = 0
78
+ split_row = row.map do |cell|
79
+ split_cells = cell.split("\n")
80
+ max_size = split_cells.length if split_cells.length > max_size
81
+ split_cells
82
+ end.map do |split_cells|
83
+ split_cells += Array.new(max_size - split_cells.length, '')
84
+ end.transpose
85
+
86
+ newline_treated_rows += split_row
87
+ if options[:space_linebroken] && split_row.length > 1
88
+ newline_treated_rows << Array.new(split_row.first.length,
89
+ ' ')
90
+ end
91
+ end
92
+
93
+ rows = newline_treated_rows
94
+
95
+ # set widths for each column to be printed, fitting terminal size
96
+
97
+ columns = rows.transpose
98
+
99
+ total_column_width = options[:max_width] - columns.length - 1
100
+ current_column_widths = columns.map { |column| column.map { |cell| cell.gsub(/\e\[([;\d]+)?m/, '').length }.max }
101
+
102
+ actual_column_widths = current_column_widths
103
+ if current_column_widths.sum > total_column_width
104
+ even_width_per_column = total_column_width / columns.length
105
+ even_width_per_column = 1 if even_width_per_column.zero?
106
+
107
+ width_for_linebroken = total_column_width - actual_column_widths.select { |n| n < even_width_per_column }.sum
108
+
109
+ actual_column_widths = current_column_widths.map do |width|
110
+ width > even_width_per_column ? even_width_per_column : width
111
+ end
112
+ end
113
+
114
+ # write the top of the table
115
+
116
+ table = ''
117
+ table << options.dig(:corners, :top_right)
118
+ table << actual_column_widths.map do |width|
119
+ str = ''
120
+ str << options.dig(:straight, :horizontal) * width
121
+ str << options.dig(:straight, :horizontal) * padding_amount * 2
122
+ end.join(options.dig(:junctions, :top))
123
+
124
+ table << options.dig(:corners, :top_left)
125
+ table << "\n"
126
+
127
+ # write the contents of the table(breaks lines if needed)
128
+
129
+ rows.each do |row|
130
+ stripped_columns = row.map.with_index do |cell, column_i|
131
+ width = actual_column_widths[column_i]
132
+ cell.chars.each { |a| }
133
+ no_ansi = cell.gsub(/\e\[([;\d]+)?m/, '')
134
+
135
+ divide_cell(cell, width)
136
+ end
137
+
138
+ height = stripped_columns.map(&:length).max
139
+ height += 1 if height > 1 && options[:space_linebroken]
140
+ new_columns = stripped_columns.map.with_index do |column, column_i|
141
+ width = actual_column_widths[column_i]
142
+ column.fill(' ' * width, column.length..(height - 1))
143
+ column
144
+ end
145
+
146
+ table << new_columns.transpose.map do |row|
147
+ str = ''
148
+ str << options.dig(:straight, :vertical) + padding
149
+ str << row.join(padding + options.dig(:straight, :vertical) + padding)
150
+ str << padding + options.dig(:straight, :vertical)
151
+ end.join("\n")
152
+ table << "\n"
153
+ end
154
+
155
+ # writes the bottom of the table
156
+
157
+ table << options.dig(:corners, :bottom_right)
158
+ table << actual_column_widths.map do |width|
159
+ str = ''
160
+ str << options.dig(:straight, :horizontal) * width
161
+ str << options.dig(:straight, :horizontal) * padding_amount * 2
162
+ end.join(options.dig(:junctions, :bottom))
163
+ table << options.dig(:corners, :bottom_left)
164
+ table << "\n"
165
+ end
166
+
167
+ private_class_method def divide_cell(cell, width)
168
+ buckets = []
169
+ current_bucket = { content: '', ansi_codes: [] }
170
+ current_ansi = { content: '', start_index: 0, end_index: -1 }
171
+ inside_ansi = false
172
+
173
+ cell.chars.each do |char|
174
+ if (char == "\e") || inside_ansi
175
+ current_ansi[:start_index] = current_bucket[:content].length
176
+ current_ansi[:content] << char
177
+ inside_ansi = char != 'm'
178
+
179
+ if !inside_ansi
180
+ current_bucket[:ansi_codes] << current_ansi
181
+ current_ansi = { content: '', start_index: 0, end_index: -1 }
182
+ end
183
+
184
+ next
185
+ end
186
+
187
+ current_bucket[:content] << char
188
+ next if current_bucket[:content].length < width
189
+
190
+ buckets << current_bucket
191
+ current_bucket = { content: '', ansi_codes: [] }
192
+ current_bucket[:ansi_codes] = buckets.last[:ansi_codes].select { |ac| ac[:end_index] == -1 }.map do |ac|
193
+ { content: ac[:content], start_index: 0, end_index: -1 }
194
+ end
195
+ end
196
+
197
+ if !current_bucket[:content].empty?
198
+ current_bucket[:content] = current_bucket[:content].ljust(width)
199
+ buckets << current_bucket
200
+ end
201
+
202
+ ansi_code_end = "\e[m"
203
+ buckets.map do |bucket|
204
+ content_result = bucket[:content]
205
+
206
+ bucket[:ansi_codes].sort_by { |ac| ac[:end_index] == -1 ? Float::INFINITY : ac[:end_index] }.reverse.each do |ac|
207
+ content_result.insert(ac[:end_index], ansi_code_end)
208
+ end
209
+
210
+ bucket[:ansi_codes].sort_by { |ac| ac[:start_index] }.reverse.each do |ac|
211
+ content_result.insert(ac[:start_index], ac[:content])
212
+ end
213
+
214
+ content_result
215
+ end
216
+ end
217
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tabelinha
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hikari Luz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-08 00:00:00.000000000 Z
11
+ date: 2023-10-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This gem generates tables from a array of rows, allowing options and
14
14
  tools ranging from what character the table is made of, to breaking lines if the
@@ -18,8 +18,8 @@ executables: []
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
- - lib/tabelinha.rb
22
- homepage: https://rubygems.org/gems/tabelinha
21
+ - lib/table.rb
22
+ homepage: https://github.com/Hikari-desuyoo/tabelinha
23
23
  licenses:
24
24
  - GPL-2.0
25
25
  metadata: {}
data/lib/tabelinha.rb DELETED
@@ -1,7 +0,0 @@
1
- module Tabelinha
2
- module_function
3
-
4
- def table(rows, options = {})
5
-
6
- end
7
- end