Class: Umbra::Tabular

Inherits:
Object
  • Object
show all
Defined in:
lib/umbra/tabular.rb

Defined Under Namespace

Classes: ColumnInfo

Constant Summary collapse

GUESSCOLUMNS =
30

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cols = nil, *args) { ... } ⇒ Tabular

takes first optional argument as array of column names second optional argument as array of data arrays

Yields:

  • self



70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/umbra/tabular.rb', line 70

def initialize cols=nil, *args, &block
  @chash             = []                 # hash of column info, not used
  @_skip_columns     = {}                 # internal, which columns not to calc width of since user has specified
  @separ = @columns = @numbering =  nil
  @y = '|'
  @x = '+'
  @use_separator = false
  @_hidden_columns_flag = false
  self.columns = cols if cols
  if !args.empty?
    self.data = args
  end
  yield_or_eval(&block) if block_given?
end

Instance Attribute Details

#columnsObject

an array of column titles



52
53
54
# File 'lib/umbra/tabular.rb', line 52

def columns
  @columns
end

#listObject (readonly)

data which is array of arrays: rows and columns



55
56
57
# File 'lib/umbra/tabular.rb', line 55

def list
  @list
end

#numberingObject

boolean, does user want lines numbered



58
59
60
# File 'lib/umbra/tabular.rb', line 58

def numbering
  @numbering
end

#use_separatorObject

boolean. Use a separator line after heading or not.



60
61
62
# File 'lib/umbra/tabular.rb', line 60

def use_separator
  @use_separator
end

#xObject

x is the + character used a field delim in separators y is the field delim used in data rows, default is pipe or bar



64
65
66
# File 'lib/umbra/tabular.rb', line 64

def x
  @x
end

#yObject

x is the + character used a field delim in separators y is the field delim used in data rows, default is pipe or bar



64
65
66
# File 'lib/umbra/tabular.rb', line 64

def y
  @y
end

Instance Method Details

#_calculate_column_offsetsObject

This calculates and stores the offset at which each column starts. Used when going to next column or doing a find for a string in the table.



327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/umbra/tabular.rb', line 327

def _calculate_column_offsets
  total = 0
  coffsets = []
  ctr = 0
  ## ix will have gaps in between for hidden fields
  each_column { | c, ix|
    v = c.width
    coffsets[ctr] = total
    ctr += 1
    total += v + 2                         ## blank space plus separator
  }
  return coffsets
end

#add(array) ⇒ Object Also known as: <<, add_row

add a row of data

Parameters:

  • an (Array)

    array containing entries for each column



113
114
115
116
117
# File 'lib/umbra/tabular.rb', line 113

def add array
  #$log.debug "tabular got add  #{array.count} #{array.inspect} " if $log
  @list ||= []
  @list << array
end

#add_separatorObject



305
306
307
# File 'lib/umbra/tabular.rb', line 305

def add_separator
  @list << :separator
end

#column_align(colindex, lrc = :NONE) ⇒ Object

set alignment of given column offset

Parameters:

  • column (Number)

    offset, starting 0

  • :left, (Symbol)

    :right

Raises:

  • (ArgumentError)


160
161
162
163
164
165
166
167
168
# File 'lib/umbra/tabular.rb', line 160

def column_align colindex, lrc=:NONE
  if lrc == :NONE
    return get_column(colindex).align
    #return @calign[colindex]
  end
  raise ArgumentError, "wrong alignment value sent" if ![:right, :left, :center].include? lrc
  get_column(colindex).align = lrc
  self
end

#column_countObject

returns the count of visible columns based on column names. NOTE: what if no column names gives ???



187
188
189
# File 'lib/umbra/tabular.rb', line 187

def column_count
  visible_column_names().count
end

#column_hidden(colindex, flag = :NONE) ⇒ Object



146
147
148
149
150
151
152
153
154
155
# File 'lib/umbra/tabular.rb', line 146

def column_hidden colindex, flag=:NONE
  if flag == :NONE
    return get_column(colindex).hidden
    #return @chide[colindex]
  end
  @_hidden_columns_flag = true if flag
  #@chide[colindex] = flag
  get_column(colindex).hidden = flag
  self
end

#column_width(colindex, width = :NONE) ⇒ Object

set width of a given column, any data beyond this will be truncated at display time.

Parameters:

  • column (Number)

    offset, starting 0

  • width (Number) (defaults to: :NONE)


136
137
138
139
140
141
142
143
144
# File 'lib/umbra/tabular.rb', line 136

def column_width colindex, width=:NONE
  if width == :NONE
    #return @cw[colindex]
    return get_column(colindex).width
  end
  @_skip_columns[colindex] = true   ## don't calculate col width for this.
  get_column(colindex).width = width
  self
end

#convert_heading_to_text(r, fmstr) ⇒ Object



277
278
279
# File 'lib/umbra/tabular.rb', line 277

def convert_heading_to_text r, fmstr
  return fmstr % r;  
end

#convert_value_to_text(r, fmstr, index) ⇒ Object

render_row

Parameters:

  • row (Array)

    as Array

  • format (String)

    string

  • row (Integer)

    offset in data



274
275
276
# File 'lib/umbra/tabular.rb', line 274

def convert_value_to_text r, fmstr, index
  return fmstr % r;  
end

#data=(list) ⇒ Object

set data as an array of arrays

Parameters:

  • data (Array<Array>)

    as array of arrays



105
106
107
108
109
# File 'lib/umbra/tabular.rb', line 105

def data=(list)
  #puts "got data: #{list.size} " if !$log
  #puts list if !$log
  @list = list
end

#delete_at(ix) ⇒ Object

Raises:

  • (ArgumentError)


294
295
296
297
298
299
300
# File 'lib/umbra/tabular.rb', line 294

def delete_at ix
  return unless @list
  raise ArgumentError, "Argument must be within 0 and #{@list.length}" if ix < 0 or ix >=  @list.length 
  #fire_dimension_changed
  #@list.delete_at(ix + @_header_adjustment)
  @list.delete_at(ix)
end

#each_columnObject

yields non-hidden columns (ColumnInfo) and the offset/index This is the order in which columns are to be printed



193
194
195
196
197
198
# File 'lib/umbra/tabular.rb', line 193

def each_column
  @chash.each_with_index { |c, i| 
    next if c.hidden
    yield c,i if block_given?
  }
end

#get_column(index) ⇒ Object

retrieve the column info structure for the given offset. The offset pertains to the visible offset not actual offset in data model. These two differ when we move a column.

Returns:

  • ColumnInfo object containing width align color bgcolor attrib hidden



125
126
127
128
129
130
131
132
# File 'lib/umbra/tabular.rb', line 125

def get_column index
  return @chash[index] if @chash[index]
  # create a new entry since none present
  c = ColumnInfo.new
  c.index = index
  @chash[index] = c
  return c
end

#renderArray<String>

Now returns an array with formatted data

Returns:

  • (Array<String>)

    array of formatted data



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/umbra/tabular.rb', line 220

def render
  raise "tabular:: list is nil " unless @list
  $log.debug "  render list:: #{@list.size} "
  #$log.debug "  render list:1: #{@list} "
  raise "tabular:: columns is nil " unless @columns
  buffer = []
  @separ = nil
  _guess_col_widths
  rows = @list.size.to_s.length
  #@rows = rows
  fmstr = _prepare_format
  $log.debug "tabular: fmstr:: #{fmstr}"
  $log.debug "tabular: cols: #{@columns}"
  #$log.debug "tabular: data: #{@list}"

  str = ""
  if @numbering
    str = " "*(rows+1)+@y
  end
  #str <<  fmstr % visible_column_names()
  str <<  convert_heading_to_text(visible_column_names(), fmstr)
  buffer << str
  #puts "-" * str.length
  buffer << separator if @use_separator
  if @list    ## XXX why wasn't numbering done in _prepare_format ???? FIXME
    if @numbering
      fmstr = "%#{rows}d "+ @y + fmstr
    end
    #@list.each { |e| puts e.join(@y) }
    count = 0
    @list.each_with_index { |r,i|  
      if r == :separator
        buffer << separator
        next
      end
      if @_hidden_columns_flag
        r = visible_columns(r)
      end
      if @numbering
        r.insert 0, count+1
      end
      #value = convert_value_to_text r, count
      value = convert_value_to_text r, fmstr, i
      buffer << value
      count += 1
    }
  end
  buffer
end

#separatorObject

This refers to a separator line after the heading and not a field separator. Badly named !



311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/umbra/tabular.rb', line 311

def separator
  return @separ if @separ
  str = ""
  if @numbering
    str = "-"*(rows+1)+@x
  end
  each_column { | c, ix|
    v = c.width
    next if v == 0     ## hidden column
    str << "-" * (v+1) + @x 
  }
  @separ = str.chop
end

#to_stringObject

use this for printing out on terminal NOTE: Do not name this to_s as it will print the entire content in many places in debug statements

Examples:

puts t.to_s


284
285
286
# File 'lib/umbra/tabular.rb', line 284

def to_string
  render().join "\n"
end

#value_at(x, y, value = :NONE) ⇒ Object



288
289
290
291
292
293
# File 'lib/umbra/tabular.rb', line 288

def value_at x,y, value=:NONE
  if value == :NONE
    return @list[x, y]
  end
  @list[x, y] = value
end

#visible_column_namesObject

return an array of visible columns names



171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/umbra/tabular.rb', line 171

def visible_column_names
  visible = []
  @chash.each_with_index do |c, ix|
    if !c.hidden
      if block_given?
        yield c.name, ix 
      else
        visible << c.name
      end
    end
  end
  return visible unless block_given?
end

#visible_columns(row) { ... } ⇒ Object

for the given row, return visible columns as an array

Yields:

  • column and index



202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/umbra/tabular.rb', line 202

def visible_columns(row)
  visible = []
  row.each_with_index do |e, ix|
    hid = @chash[ix].hidden
    if !hid
      if block_given?
        yield e, ix
      else
        visible << e 
      end
    end
  end
  return visible if !block_given?
end

#yield_or_eval(&block) ⇒ Object



34
35
36
37
38
39
40
41
# File 'lib/umbra/tabular.rb', line 34

def yield_or_eval &block
  return unless block
  if block.arity > 0
    yield self
  else
    self.instance_eval(&block)
  end
end