rex-text 0.1.1 → 0.1.2
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/rex/text.rb +4 -0
- data/lib/rex/text/color.rb +106 -0
- data/lib/rex/text/table.rb +418 -0
- data/lib/rex/text/version.rb +1 -1
- metadata +4 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a213d45ce77b442cf80cc9e8c302d705c9f63128
|
4
|
+
data.tar.gz: 739aabf270a14239b68f9bdc3f394eebaa949efc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd856ab7b00383f19e189e4da9f55e8b078a6ef1429535b4e6c223ce853dd83bbdd8fb562cb0f7fe295db52de89c538e11fa1b677f0d97a15684271de22671d7
|
7
|
+
data.tar.gz: e77455056b8e1ffa80af71886deae1576a21b8f92bc2450f296dc4430ec6cd5c9a229d03c95fc3cc6cb788aeef5aa9e829103d88116d751bc6046c20b5e1dd33
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/rex/text.rb
CHANGED
@@ -0,0 +1,106 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
module Rex
|
3
|
+
module Text
|
4
|
+
|
5
|
+
###
|
6
|
+
#
|
7
|
+
# This module provides an interface to getting ANSI color codes.
|
8
|
+
# It's taken mostly from perl's Term::ANSIColor by Russ Allbery
|
9
|
+
# <rra@stanford.edu> and Zenin <zenin@best.com>.
|
10
|
+
#
|
11
|
+
###
|
12
|
+
module Color
|
13
|
+
|
14
|
+
AnsiAttributes =
|
15
|
+
{
|
16
|
+
'clear' => 0,
|
17
|
+
'reset' => 0,
|
18
|
+
'bold' => 1,
|
19
|
+
'dark' => 2,
|
20
|
+
'underline' => 4,
|
21
|
+
'underscore' => 4,
|
22
|
+
'blink' => 5,
|
23
|
+
'reverse' => 7,
|
24
|
+
'concealed' => 8,
|
25
|
+
'black' => 30, 'on_black' => 40,
|
26
|
+
'red' => 31, 'on_red' => 41,
|
27
|
+
'green' => 32, 'on_green' => 42,
|
28
|
+
'yellow' => 33, 'on_yellow' => 43,
|
29
|
+
'blue' => 34, 'on_blue' => 44,
|
30
|
+
'magenta' => 35, 'on_magenta' => 45,
|
31
|
+
'cyan' => 36, 'on_cyan' => 46,
|
32
|
+
'white' => 37, 'on_white' => 47
|
33
|
+
}
|
34
|
+
|
35
|
+
#
|
36
|
+
# Return a string with ANSI codes substituted. Derived from code
|
37
|
+
# written by The FaerieMUD Consortium.
|
38
|
+
#
|
39
|
+
def ansi(*attrs)
|
40
|
+
attr = attrs.collect {|a| AnsiAttributes[a] ? AnsiAttributes[a] : nil}.compact.join(';')
|
41
|
+
attr = "\e[%sm" % attr if (attr.empty? == false)
|
42
|
+
return attr
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Colorize if this shell supports it
|
47
|
+
#
|
48
|
+
def colorize(*color)
|
49
|
+
supports_color?() ? ansi(*color) : ''
|
50
|
+
end
|
51
|
+
|
52
|
+
def substitute_colors(msg, in_prompt = nil)
|
53
|
+
str = msg.dup
|
54
|
+
pre_color = post_color = ''
|
55
|
+
if (in_prompt)
|
56
|
+
pre_color = "\x01" # RL_PROMPT_START_IGNORE
|
57
|
+
post_color = "\x02" # RL_PROMPT_END_IGNORE
|
58
|
+
end
|
59
|
+
str.gsub!(/%cya/, pre_color+colorize('cyan')+post_color)
|
60
|
+
str.gsub!(/%red/, pre_color+colorize('red')+post_color)
|
61
|
+
str.gsub!(/%grn/, pre_color+colorize('green')+post_color)
|
62
|
+
str.gsub!(/%blu/, pre_color+colorize('blue')+post_color)
|
63
|
+
str.gsub!(/%yel/, pre_color+colorize('yellow')+post_color)
|
64
|
+
str.gsub!(/%whi/, pre_color+colorize('white')+post_color)
|
65
|
+
str.gsub!(/%mag/, pre_color+colorize('magenta')+post_color)
|
66
|
+
str.gsub!(/%blk/, pre_color+colorize('black')+post_color)
|
67
|
+
str.gsub!(/%dred/, pre_color+colorize('dark', 'red')+post_color)
|
68
|
+
str.gsub!(/%dgrn/, pre_color+colorize('dark', 'green')+post_color)
|
69
|
+
str.gsub!(/%dblu/, pre_color+colorize('dark', 'blue')+post_color)
|
70
|
+
str.gsub!(/%dyel/, pre_color+colorize('dark', 'yellow')+post_color)
|
71
|
+
str.gsub!(/%dcya/, pre_color+colorize('dark', 'cyan')+post_color)
|
72
|
+
str.gsub!(/%dwhi/, pre_color+colorize('dark', 'white')+post_color)
|
73
|
+
str.gsub!(/%dmag/, pre_color+colorize('dark', 'magenta')+post_color)
|
74
|
+
str.gsub!(/%und/, pre_color+colorize('underline')+post_color)
|
75
|
+
str.gsub!(/%bld/, pre_color+colorize('bold')+post_color)
|
76
|
+
str.gsub!(/%clr/, pre_color+colorize('clear')+post_color)
|
77
|
+
# Background Color
|
78
|
+
str.gsub!(/%bgblu/, pre_color+colorize('on_blue')+post_color)
|
79
|
+
str.gsub!(/%bgyel/, pre_color+colorize('on_yellow')+post_color)
|
80
|
+
str.gsub!(/%bggrn/, pre_color+colorize('on_green')+post_color)
|
81
|
+
str.gsub!(/%bgmag/, pre_color+colorize('on_magenta')+post_color)
|
82
|
+
str.gsub!(/%bgblk/, pre_color+colorize('on_black')+post_color)
|
83
|
+
str.gsub!(/%bgred/, pre_color+colorize('on_red')+post_color)
|
84
|
+
str.gsub!(/%bgcyn/, pre_color+colorize('on_cyan')+post_color)
|
85
|
+
str.gsub!(/%bgwhi/, pre_color+colorize('on_white')+post_color)
|
86
|
+
|
87
|
+
str
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Resets coloring so that it's back to normal.
|
92
|
+
#
|
93
|
+
def reset_color
|
94
|
+
return if not supports_color?
|
95
|
+
print(colorize('clear'))
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# Colorize if this shell supports it
|
100
|
+
#
|
101
|
+
def do_colorize(*color)
|
102
|
+
supports_color?() ? ansi(*color) : ''
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end end
|
@@ -0,0 +1,418 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Text
|
5
|
+
|
6
|
+
###
|
7
|
+
#
|
8
|
+
# Prints text in a tablized format. Pretty lame at the moment, but
|
9
|
+
# whatever.
|
10
|
+
#
|
11
|
+
###
|
12
|
+
class Table
|
13
|
+
|
14
|
+
#
|
15
|
+
# Initializes a text table instance using the supplied properties. The
|
16
|
+
# Table class supports the following hash attributes:
|
17
|
+
#
|
18
|
+
# Header
|
19
|
+
#
|
20
|
+
# The string to display as a heading above the table. If none is
|
21
|
+
# specified, no header will be displayed.
|
22
|
+
#
|
23
|
+
# HeaderIndent
|
24
|
+
#
|
25
|
+
# The amount of space to indent the header. The default is zero.
|
26
|
+
#
|
27
|
+
# Columns
|
28
|
+
#
|
29
|
+
# The array of columns that will exist within the table.
|
30
|
+
#
|
31
|
+
# Rows
|
32
|
+
#
|
33
|
+
# The array of rows that will exist.
|
34
|
+
#
|
35
|
+
# Width
|
36
|
+
#
|
37
|
+
# The maximum width of the table in characters.
|
38
|
+
#
|
39
|
+
# Indent
|
40
|
+
#
|
41
|
+
# The number of characters to indent the table.
|
42
|
+
#
|
43
|
+
# CellPad
|
44
|
+
#
|
45
|
+
# The number of characters to put between each horizontal cell.
|
46
|
+
#
|
47
|
+
# Prefix
|
48
|
+
#
|
49
|
+
# The text to prefix before the table.
|
50
|
+
#
|
51
|
+
# Postfix
|
52
|
+
#
|
53
|
+
# The text to affix to the end of the table.
|
54
|
+
#
|
55
|
+
# Sortindex
|
56
|
+
#
|
57
|
+
# The column to sort the table on, -1 disables sorting.
|
58
|
+
#
|
59
|
+
def initialize(opts = {})
|
60
|
+
self.header = opts['Header']
|
61
|
+
self.headeri = opts['HeaderIndent'] || 0
|
62
|
+
self.columns = opts['Columns'] || []
|
63
|
+
# updated below if we got a "Rows" option
|
64
|
+
self.rows = []
|
65
|
+
|
66
|
+
self.width = opts['Width'] || 80
|
67
|
+
self.indent = opts['Indent'] || 0
|
68
|
+
self.cellpad = opts['CellPad'] || 2
|
69
|
+
self.prefix = opts['Prefix'] || ''
|
70
|
+
self.postfix = opts['Postfix'] || ''
|
71
|
+
self.colprops = []
|
72
|
+
self.scterm = /#{opts['SearchTerm']}/mi if opts['SearchTerm']
|
73
|
+
|
74
|
+
self.sort_index = opts['SortIndex'] || 0
|
75
|
+
self.sort_order = opts['SortOrder'] || :forward
|
76
|
+
|
77
|
+
# Default column properties
|
78
|
+
self.columns.length.times { |idx|
|
79
|
+
self.colprops[idx] = {}
|
80
|
+
self.colprops[idx]['MaxWidth'] = self.columns[idx].length
|
81
|
+
}
|
82
|
+
|
83
|
+
# ensure all our internal state gets updated with the given rows by
|
84
|
+
# using add_row instead of just adding them to self.rows. See #3825.
|
85
|
+
opts['Rows'].each { |row| add_row(row) } if opts['Rows']
|
86
|
+
|
87
|
+
# Merge in options
|
88
|
+
if (opts['ColProps'])
|
89
|
+
opts['ColProps'].each_key { |col|
|
90
|
+
idx = self.columns.index(col)
|
91
|
+
|
92
|
+
if (idx)
|
93
|
+
self.colprops[idx].merge!(opts['ColProps'][col])
|
94
|
+
end
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# Converts table contents to a string.
|
102
|
+
#
|
103
|
+
def to_s
|
104
|
+
str = prefix.dup
|
105
|
+
str << header_to_s || ''
|
106
|
+
str << columns_to_s || ''
|
107
|
+
str << hr_to_s || ''
|
108
|
+
|
109
|
+
sort_rows
|
110
|
+
rows.each { |row|
|
111
|
+
if (is_hr(row))
|
112
|
+
str << hr_to_s
|
113
|
+
else
|
114
|
+
str << row_to_s(row) if row_visible(row)
|
115
|
+
end
|
116
|
+
}
|
117
|
+
|
118
|
+
str << postfix
|
119
|
+
|
120
|
+
return str
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Converts table contents to a csv
|
125
|
+
#
|
126
|
+
def to_csv
|
127
|
+
str = ''
|
128
|
+
str << ( columns.join(",") + "\n" )
|
129
|
+
rows.each { |row|
|
130
|
+
next if is_hr(row) || !row_visible(row)
|
131
|
+
str << ( row.map{|x|
|
132
|
+
x = x.to_s
|
133
|
+
x.gsub(/[\r\n]/, ' ').gsub(/\s+/, ' ').gsub('"', '""')
|
134
|
+
}.map{|x| "\"#{x}\"" }.join(",") + "\n" )
|
135
|
+
}
|
136
|
+
str
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
#
|
141
|
+
# Returns the header string.
|
142
|
+
#
|
143
|
+
def header_to_s # :nodoc:
|
144
|
+
if (header)
|
145
|
+
pad = " " * headeri
|
146
|
+
|
147
|
+
return pad + header + "\n" + pad + "=" * header.length + "\n\n"
|
148
|
+
end
|
149
|
+
|
150
|
+
return ''
|
151
|
+
end
|
152
|
+
|
153
|
+
#
|
154
|
+
# Prints the contents of the table.
|
155
|
+
#
|
156
|
+
def print
|
157
|
+
puts to_s
|
158
|
+
end
|
159
|
+
|
160
|
+
#
|
161
|
+
# Adds a row using the supplied fields.
|
162
|
+
#
|
163
|
+
def <<(fields)
|
164
|
+
add_row(fields)
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
# Adds a row with the supplied fields.
|
169
|
+
#
|
170
|
+
def add_row(fields = [])
|
171
|
+
if fields.length != self.columns.length
|
172
|
+
raise RuntimeError, 'Invalid number of columns!'
|
173
|
+
end
|
174
|
+
fields.each_with_index { |field, idx|
|
175
|
+
# Remove whitespace and ensure String format
|
176
|
+
field = field.to_s.strip
|
177
|
+
if (colprops[idx]['MaxWidth'] < field.to_s.length)
|
178
|
+
old = colprops[idx]['MaxWidth']
|
179
|
+
colprops[idx]['MaxWidth'] = field.to_s.length
|
180
|
+
end
|
181
|
+
}
|
182
|
+
|
183
|
+
rows << fields
|
184
|
+
end
|
185
|
+
|
186
|
+
#
|
187
|
+
# Sorts the rows based on the supplied index of sub-arrays
|
188
|
+
# If the supplied index is an IPv4 address, handle it differently, but
|
189
|
+
# avoid actually resolving domain names.
|
190
|
+
#
|
191
|
+
def sort_rows(index = sort_index, order = sort_order)
|
192
|
+
return if index == -1
|
193
|
+
return unless rows
|
194
|
+
rows.sort! do |a,b|
|
195
|
+
if a[index].nil?
|
196
|
+
cmp = -1
|
197
|
+
elsif b[index].nil?
|
198
|
+
cmp = 1
|
199
|
+
elsif valid_ip?(a[index]) and valid_ip?(b[index])
|
200
|
+
cmp = IPAddr.new(a[index]) <=> IPAddr.new(b[index])
|
201
|
+
elsif a[index] =~ /^[0-9]+$/ and b[index] =~ /^[0-9]+$/
|
202
|
+
cmp = a[index].to_i <=> b[index].to_i
|
203
|
+
elsif a[index].kind_of?(IPAddr) && a[index].kind_of?(IPAddr) && a[index].ipv6? && b[index].ipv4?
|
204
|
+
cmp = 1
|
205
|
+
elsif a[index].kind_of?(IPAddr) && b[index].kind_of?(IPAddr) && a[index].ipv4? && b[index].ipv6?
|
206
|
+
cmp = -1
|
207
|
+
else
|
208
|
+
cmp = a[index] <=> b[index] # assumes otherwise comparable.
|
209
|
+
end
|
210
|
+
order == :forward ? cmp : -cmp
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
#
|
215
|
+
# Adds a horizontal line.
|
216
|
+
#
|
217
|
+
def add_hr
|
218
|
+
rows << '__hr__'
|
219
|
+
end
|
220
|
+
|
221
|
+
#
|
222
|
+
# Returns new sub-table with headers and rows maching column names submitted
|
223
|
+
#
|
224
|
+
#
|
225
|
+
# Flips table 90 degrees left
|
226
|
+
#
|
227
|
+
def drop_left
|
228
|
+
tbl = self.class.new(
|
229
|
+
'Columns' => Array.new(self.rows.count+1,' '),
|
230
|
+
'Header' => self.header,
|
231
|
+
'Indent' => self.indent)
|
232
|
+
(self.columns.count+1).times do |ti|
|
233
|
+
row = self.rows.map {|r| r[ti]}.unshift(self.columns[ti]).flatten
|
234
|
+
# insert our col|row break. kind of hackish
|
235
|
+
row[1] = "| #{row[1]}" unless row.all? {|e| e.nil? || e.empty?}
|
236
|
+
tbl << row
|
237
|
+
end
|
238
|
+
return tbl
|
239
|
+
end
|
240
|
+
|
241
|
+
def valid_ip?(value)
|
242
|
+
begin
|
243
|
+
IPAddr.new value
|
244
|
+
true
|
245
|
+
rescue IPAddr::InvalidAddressError
|
246
|
+
false
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
#
|
251
|
+
# Build table from CSV dump
|
252
|
+
#
|
253
|
+
def self.new_from_csv(csv)
|
254
|
+
# Read in or keep data, get CSV or die
|
255
|
+
if csv.is_a?(String)
|
256
|
+
csv = File.file?(csv) ? CSV.read(csv) : CSV.parse(csv)
|
257
|
+
end
|
258
|
+
# Adjust for skew
|
259
|
+
if csv.first == ["Keys", "Values"]
|
260
|
+
csv.shift # drop marker
|
261
|
+
cols = []
|
262
|
+
rows = []
|
263
|
+
csv.each do |row|
|
264
|
+
cols << row.shift
|
265
|
+
rows << row
|
266
|
+
end
|
267
|
+
tbl = self.new('Columns' => cols)
|
268
|
+
rows.in_groups_of(cols.count) {|r| tbl << r.flatten}
|
269
|
+
else
|
270
|
+
tbl = self.new('Columns' => csv.shift)
|
271
|
+
while !csv.empty? do
|
272
|
+
tbl << csv.shift
|
273
|
+
end
|
274
|
+
end
|
275
|
+
return tbl
|
276
|
+
end
|
277
|
+
|
278
|
+
def [](*col_names)
|
279
|
+
tbl = self.class.new('Indent' => self.indent,
|
280
|
+
'Header' => self.header,
|
281
|
+
'Columns' => col_names)
|
282
|
+
indexes = []
|
283
|
+
|
284
|
+
col_names.each do |col_name|
|
285
|
+
index = self.columns.index(col_name)
|
286
|
+
raise RuntimeError, "Invalid column name #{col_name}" if index.nil?
|
287
|
+
indexes << index
|
288
|
+
end
|
289
|
+
|
290
|
+
self.rows.each do |old_row|
|
291
|
+
new_row = []
|
292
|
+
indexes.map {|i| new_row << old_row[i]}
|
293
|
+
tbl << new_row
|
294
|
+
end
|
295
|
+
|
296
|
+
return tbl
|
297
|
+
end
|
298
|
+
|
299
|
+
|
300
|
+
alias p print
|
301
|
+
|
302
|
+
attr_accessor :header, :headeri # :nodoc:
|
303
|
+
attr_accessor :columns, :rows, :colprops # :nodoc:
|
304
|
+
attr_accessor :width, :indent, :cellpad # :nodoc:
|
305
|
+
attr_accessor :prefix, :postfix # :nodoc:
|
306
|
+
attr_accessor :sort_index, :sort_order, :scterm # :nodoc:
|
307
|
+
|
308
|
+
protected
|
309
|
+
|
310
|
+
#
|
311
|
+
# Returns if a row should be visible or not
|
312
|
+
#
|
313
|
+
def row_visible(row)
|
314
|
+
return true if self.scterm.nil?
|
315
|
+
row_to_s(row).match(self.scterm)
|
316
|
+
end
|
317
|
+
|
318
|
+
#
|
319
|
+
# Defaults cell widths and alignments.
|
320
|
+
#
|
321
|
+
def defaults # :nodoc:
|
322
|
+
self.columns.length.times { |idx|
|
323
|
+
}
|
324
|
+
end
|
325
|
+
|
326
|
+
#
|
327
|
+
# Checks to see if the row is an hr.
|
328
|
+
#
|
329
|
+
def is_hr(row) # :nodoc:
|
330
|
+
return ((row.kind_of?(String)) && (row == '__hr__'))
|
331
|
+
end
|
332
|
+
|
333
|
+
#
|
334
|
+
# Converts the columns to a string.
|
335
|
+
#
|
336
|
+
def columns_to_s # :nodoc:
|
337
|
+
nameline = ' ' * indent
|
338
|
+
barline = nameline.dup
|
339
|
+
last_col = nil
|
340
|
+
last_idx = nil
|
341
|
+
columns.each_with_index { |col,idx|
|
342
|
+
if (last_col)
|
343
|
+
# This produces clean to_s output without truncation
|
344
|
+
# Preserves full string in cells for to_csv output
|
345
|
+
padding = pad(' ', last_col, last_idx)
|
346
|
+
nameline << padding
|
347
|
+
remainder = padding.length - cellpad
|
348
|
+
remainder = 0 if remainder < 0
|
349
|
+
barline << (' ' * (cellpad + remainder))
|
350
|
+
end
|
351
|
+
|
352
|
+
nameline << col
|
353
|
+
barline << ('-' * col.length)
|
354
|
+
|
355
|
+
last_col = col
|
356
|
+
last_idx = idx
|
357
|
+
}
|
358
|
+
|
359
|
+
return "#{nameline}\n#{barline}"
|
360
|
+
end
|
361
|
+
|
362
|
+
#
|
363
|
+
# Converts an hr to a string.
|
364
|
+
#
|
365
|
+
def hr_to_s # :nodoc:
|
366
|
+
return "\n"
|
367
|
+
end
|
368
|
+
|
369
|
+
#
|
370
|
+
# Converts a row to a string.
|
371
|
+
#
|
372
|
+
def row_to_s(row) # :nodoc:
|
373
|
+
line = ' ' * indent
|
374
|
+
last_cell = nil
|
375
|
+
last_idx = nil
|
376
|
+
row.each_with_index { |cell, idx|
|
377
|
+
if (idx != 0)
|
378
|
+
line << pad(' ', last_cell.to_s, last_idx)
|
379
|
+
end
|
380
|
+
# Limit wide cells
|
381
|
+
if colprops[idx]['MaxChar']
|
382
|
+
last_cell = cell.to_s[0..colprops[idx]['MaxChar'].to_i]
|
383
|
+
line << last_cell
|
384
|
+
else
|
385
|
+
line << cell.to_s
|
386
|
+
last_cell = cell
|
387
|
+
end
|
388
|
+
last_idx = idx
|
389
|
+
}
|
390
|
+
|
391
|
+
return line + "\n"
|
392
|
+
end
|
393
|
+
|
394
|
+
#
|
395
|
+
# Pads out with the supplied character for the remainder of the space given
|
396
|
+
# some text and a column index.
|
397
|
+
#
|
398
|
+
def pad(chr, buf, colidx, use_cell_pad = true) # :nodoc:
|
399
|
+
# Ensure we pad the minimum required amount
|
400
|
+
max = colprops[colidx]['MaxChar'] || colprops[colidx]['MaxWidth']
|
401
|
+
max = colprops[colidx]['MaxWidth'] if max.to_i > colprops[colidx]['MaxWidth'].to_i
|
402
|
+
remainder = max - buf.length
|
403
|
+
remainder = 0 if remainder < 0
|
404
|
+
val = chr * remainder
|
405
|
+
|
406
|
+
if (use_cell_pad)
|
407
|
+
val << ' ' * cellpad
|
408
|
+
end
|
409
|
+
|
410
|
+
return val
|
411
|
+
end
|
412
|
+
|
413
|
+
|
414
|
+
end
|
415
|
+
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
data/lib/rex/text/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rex-text
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David 'thelightcosine' Maloney
|
@@ -85,7 +85,7 @@ cert_chain:
|
|
85
85
|
2SpuQH+SWteq3NXkAmFEEqvLJQ4sbptZt8OP8ghL3pVAvZNFmww/YVszSkShSzcg
|
86
86
|
QdihYCSEL2drS2cFd50jBeq71sxUtxbv82DUa2b+
|
87
87
|
-----END CERTIFICATE-----
|
88
|
-
date: 2016-
|
88
|
+
date: 2016-08-10 00:00:00.000000000 Z
|
89
89
|
dependencies:
|
90
90
|
- !ruby/object:Gem::Dependency
|
91
91
|
name: bundler
|
@@ -155,6 +155,7 @@ files:
|
|
155
155
|
- lib/rex/text/binary_manipulation.rb
|
156
156
|
- lib/rex/text/block_api.rb
|
157
157
|
- lib/rex/text/checksum.rb
|
158
|
+
- lib/rex/text/color.rb
|
158
159
|
- lib/rex/text/compress.rb
|
159
160
|
- lib/rex/text/ebcdic.rb
|
160
161
|
- lib/rex/text/encode.rb
|
@@ -166,6 +167,7 @@ files:
|
|
166
167
|
- lib/rex/text/rand.rb
|
167
168
|
- lib/rex/text/randomize.rb
|
168
169
|
- lib/rex/text/silly.rb
|
170
|
+
- lib/rex/text/table.rb
|
169
171
|
- lib/rex/text/unicode.rb
|
170
172
|
- lib/rex/text/version.rb
|
171
173
|
- rex-text.gemspec
|
metadata.gz.sig
CHANGED
Binary file
|