Class: ColumnPrinter

Inherits:
Object show all
Defined in:
lib/sitefuel/extensions/ColumnPrinter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(column_widths, output_width = :automatic) ⇒ ColumnPrinter

Returns a new instance of ColumnPrinter.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 43

def initialize(column_widths, output_width = :automatic)
  mode :aligned

  self.column_widths = column_widths
  
  @output_width = output_width

  # we disallow resizing since the constant checking *really* slows
  # printing down
  @allow_resizing = false
  
  @minimum_column_width = 5

  compute_absolute_column_widths
  alignment(:left)
end

Instance Attribute Details

#allow_resizingObject

Returns the value of attribute allow_resizing.



37
38
39
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 37

def allow_resizing
  @allow_resizing
end

#column_widthsObject

specify the width for the entire grid



25
26
27
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 25

def column_widths
  @column_widths
end

#corner_pieceObject

what character should be used



28
29
30
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 28

def corner_piece
  @corner_piece
end

#horizontal_divider_pieceObject

what character should be used to horizontally separate cells



31
32
33
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 31

def horizontal_divider_piece
  @horizontal_divider_piece
end

#minimum_column_widthObject

specifies the minimum width for a column



40
41
42
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 40

def minimum_column_width
  @minimum_column_width
end

#vertical_divider_pieceObject

what character should be used to vertically separate rows. If =nil= or ” rows will not be separated.



35
36
37
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 35

def vertical_divider_piece
  @vertical_divider_piece
end

Instance Method Details

#actual_width(width) ⇒ Object

if the given width is less than #minimum_column_width, gives #minimum_column_width. Otherwise gives floor() of the given width



186
187
188
189
190
191
192
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 186

def actual_width(width)
  if width < minimum_column_width
    minimum_column_width
  else
    width.floor
  end
end

#align_cell(column_index, value, width) ⇒ Object

aligns a cell based on the specification



201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 201

def align_cell(column_index, value, width)
  case @column_alignment[column_index]
    when :left
      value.visual_ljust(width)

    when :right
      value.visual_rjust(width)

    when :center
      value.visual_center(width)
  end
end

#alignment(columns) ⇒ Object

sets the alignment for the columns



62
63
64
65
66
67
68
69
70
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 62

def alignment(columns)
  case columns
    when Symbol
      @column_alignment = Array.new(column_count, columns)

    when Array
      @column_alignment = columns
  end
end

#column_countObject

gives the number of columns in this printer



74
75
76
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 74

def column_count
  self.column_widths.length
end

#compute_absolute_column_widthsObject

given the mixture of absolute, relative, and spanning widths computes the actual width of each column

Method

  • start with the output width and allocate space for each absolute sized column

  • of the space remaining, allocate that to relative sized columns

  • divy up any remaining space evenly between :span columns



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 134

def compute_absolute_column_widths
  # we remove one to make room for the leading space
  unallocated_width = output_width - 1

  relative_columns = []
  span_columns = []

  @absolute_column_widths = Array.new(column_widths.length)

  # group relative sizes and span sizes, allocate out space to absolute sizes
  column_widths.each_with_index do |width, index|
    case width
      when :span
        # store for later computation
        span_columns << [index, :span]

      when Float
        relative_columns << [index, width]

      when Fixnum
        @absolute_column_widths[index] = actual_width(width)
        unallocated_width -= actual_width(width) + 1
    end
  end

  # allocate out space to relative sizes
  relative_columns.each do |entry|
    real_size = actual_width(unallocated_width * entry.last)
    unallocated_width -= real_size + 1

    @absolute_column_widths[entry.first] = real_size
  end

  # allocate out space to span sizes
  num_spans = span_columns.length.prec_f

  # if there are no spans we're done
  if num_spans < 1
    return @absolute_column_widths
  end
  
  real_size = actual_width((unallocated_width - num_spans) / num_spans)
  span_columns.each do |entry|
    @absolute_column_widths[entry.first] = real_size
  end
  
  @absolute_column_widths
end

#divider(character = '=', processor = nil) ⇒ Object

print a divider for the entire length of the grid optionally a function or Proc may be specified for processing the divider (to change it’s color or weight, for example)



267
268
269
270
271
272
273
274
275
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 267

def divider(character = '=', processor = nil)
  div = character * output_width

  if processor
    write processor.call(div)
  else
    write div
  end
end

#format_row(*values) ⇒ Object

formats a new row



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 216

def format_row(*values)

  # check if the output width has changed
  if allow_resizing and output_width == :automatic
    current_width = TerminalInfo.width
    if current_width != output_width
      output_width = current_width
    end
  end

  line = ""

  # dump out the row
  values.each_with_index do |cell,index|
    cell_width = @absolute_column_widths[index]
    line << horizontal_divider_piece
    line << align_cell(index, cell.to_s.cabbrev(cell_width), cell_width)
  end
  line << horizontal_divider_piece
  line << row_divider

  line
end

#mode(kind) ⇒ Object

set the mode of the columns

:aligned

columns are aligned, but there are no explicit dividers

:divided

columns are aligned and separated by vertical dividers

:cells

columns are aligned and cells are separated by horizontal and vertical dividers.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 84

def mode(kind)
  case kind
    when :aligned
      @horizontal_divider_piece = ' '
      @vertical_divider_piece   = ''
      @corner_piece             = ''

    when :divided
      @horizontal_divider_piece = '|'
      @vertical_divider_piece   = ''
      @corner_piece             = ''

    when :cells
      @horizontal_divider_piece = '|'
      @vertical_divider_piece   = '-'
      @corner_piece             = '+'

    else
      raise StandardError.new("Unknown kind of mode for ColumnPrinter: #{kind}")
  end
end

#output_widthObject



117
118
119
120
121
122
123
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 117

def output_width
  if @output_width == :automatic
    TerminalInfo.width
  else
    @output_width
  end
end

#output_width=(new_width) ⇒ Object



107
108
109
110
111
112
113
114
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 107

def output_width=(new_width)
  if allow_resizing
    @output_width = new_width
    compute_absolute_column_widths
  else
    # don't do anything for now; TODO should raise a message
  end
end

#row(*values) ⇒ Object



195
196
197
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 195

def row(*values)
  write format_row(*values)
end

#row_dividerObject



241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 241

def row_divider
  if vertical_divider_piece == nil
    return ''
  end

  line = ""
  line << corner_piece
  @absolute_column_widths.each do |width|
    line << vertical_divider_piece * width
    line << corner_piece
  end

  line
end

#write(line) ⇒ Object

outputs an already formatted line. Eventually this will allow writing to strings and such; but for now just an alias for #puts



259
260
261
# File 'lib/sitefuel/extensions/ColumnPrinter.rb', line 259

def write(line)
  puts line
end