| Class | Grid |
| In: |
lib/grid.rb
|
| Parent: | Object |
Parse and render Array of Arrays of Strings. To be replaced by Tabular.
| column_count | [R] | |
| column_map | [R] | |
| columns | [RW] | |
| custom_columns | [RW] | |
| delimiter | [R] | |
| padding | [R] | |
| quoted | [R] | |
| rows | [RW] |
The Grid class maps columns by default — it changes them to lowercase and replaces spaces with underscores.
Defaults to false
Example: 'birth date' => 'date_of_birth'.
All keys are forced to lowercase for case-insenstive comparions
If both columns and header_row options are provided, columns is used to create the columns, and the first row is deleted and ignored
TODO Consider using regex for column maps
# File lib/grid.rb, line 24
24: def initialize(source = '', *options)
25: raise ArgumentError("'source' cannot be nil") if source.nil?
26:
27: options.flatten! if options
28: @truncated = false
29: @calculated_padding = false
30: @custom_columns = []
31:
32: if (options.nil? || options.empty?)
33: options_hash = {}
34: else
35: options_hash = options.first
36: end
37:
38: @delimiter = options_hash[:delimiter] || '\t'
39: @header_row = options_hash[:header_row] || false
40: @quoted = options_hash[:quoted] || false
41:
42: @column_map = {}
43: if options_hash[:column_map]
44: options_hash[:column_map].each do |key, value|
45: @column_map[key.downcase] = value
46: end
47: end
48:
49: @row_class = options_hash[:row_class]
50: if @row_class
51: @row_class_instance = @row_class.new
52: end
53:
54: if source.is_a?(String)
55: source = source.split(/\n/)
56: end
57:
58: if @header_row and source.is_a?(Array) and !source.empty?
59: columns_array = source.delete_at(0)
60: end
61:
62: if options_hash[:columns]
63: columns_array = options_hash[:columns]
64: end
65: self.columns = create_columns(columns_array)
66: self.rows = source
67: end
# File lib/grid.rb, line 69
69: def [](row)
70: if row > rows.size
71: raise(ArgumentError, "#{row} is greater then the number of rows: #{rows.size}")
72: end
73: rows[row]
74: end
# File lib/grid.rb, line 297
297: def calculate_padding
298: @calculated_padding = true
299: @padding = []
300: rows.each_with_index do |row, row_index|
301: row_padding = []
302: for index in 0..(column_count - 1)
303: cell = row[index] || ''
304: if cell.size <= column_size(index)
305: padding = column_size(index) - cell.size
306: row_padding << padding
307: else
308: row_padding << 0
309: end
310: end
311: @padding << row_padding
312: end
313: end
# File lib/grid.rb, line 126
126: def column_size(index)
127: if columns[index]
128: columns[index].size
129: else
130: 0
131: end
132: end
# File lib/grid.rb, line 134
134: def create_columns(columns_array)
135: self.columns = []
136: return if columns_array.nil?
137:
138: columns_array = columns_array.split(/#{@delimiter}/) unless columns_array.is_a?(Array)
139: self.columns = columns_array.collect do |column_name|
140: description = column_name
141: if column_name.is_a?(Column)
142: column_name
143: else
144: column_name = column_name || ""
145: column_name.strip! if column_name.respond_to?(:strip!)
146: if quoted && column_name.respond_to?(:gsub!)
147: column_name.gsub!(/^"/, '')
148: column_name.gsub!(/"$/, '')
149: description = column_name
150: end
151: if !column_name.blank? && @column_map[column_name.downcase]
152: column_name = @column_map[column_name.downcase]
153: end
154:
155: if column_name.is_a?(Column)
156: column = column_name
157: else
158: column = Column.new(:name => column_name.to_s, :description => description)
159: end
160:
161: unless column.name.blank?
162: field = column.name.downcase
163: field = field.underscore
164: field.gsub!(' ', '_')
165: if @column_map[field]
166: if @column_map[field].is_a?(Column)
167: column = @column_map[field]
168: else
169: column.field = @column_map[field]
170: end
171: else
172: column.field = field
173: end
174: end
175: column
176: end
177: end
178:
179: after_columns_created
180: validate_columns
181:
182: columns.each do |column|
183: unless column.description.blank?
184: if !column.fixed_size && (column.description.size > column.size)
185: column.size = column.description.size
186: end
187: end
188: end
189: end
# File lib/grid.rb, line 323
323: def delete_blank_rows
324: rows.delete_if {|row|
325: row.blank?
326: }
327: end
# File lib/grid.rb, line 245
245: def header_to_s(row)
246: text = ''
247: for index in 0..(column_count - 1)
248: cell = row[index] || ''
249: if cell.size <= column_size(index)
250: if columns[index].justification == Column::LEFT
251: cell = cell.ljust(column_size(index))
252: else
253: cell = cell.rjust(column_size(index))
254: end
255: else
256: cell = truncate(cell, :length => column_size(index))
257: end
258: if index + 1 == row.size
259: text = "#{text}#{cell}"
260: else
261: text = "#{text}#{cell} "
262: end
263: end
264: "#{text}\n"
265: end
# File lib/grid.rb, line 206
206: def index_for_column_name(name)
207: columns.each_with_index do |column, index|
208: if column.name == name
209: return index
210: end
211: end
212: ''
213: end
# File lib/grid.rb, line 215
215: def inspect
216: text = ""
217: text << "#{columns}\n" if columns
218: for row in rows
219: text << row.inspect
220: end
221: text
222: end
# File lib/grid.rb, line 267
267: def row_to_s(row, row_index)
268: text = ''
269: for index in 0..(column_count - 1)
270: cell = row[index] || ''
271: if columns[index].justification == Column::LEFT
272: cell = cell.ljust(column_size(index))
273: else
274: cell = cell.rjust(column_size(index))
275: end
276: if index + 1 == row.size
277: text = "#{text}#{cell}"
278: else
279: text = "#{text}#{cell} "
280: end
281: end
282: "#{text}\n"
283: end
Delimited String or Array of Strings or Arrays
# File lib/grid.rb, line 84
84: def rows=(source)
85: source.each do |row|
86: row = row.split(/#{@delimiter}/) unless row.is_a?(Array)
87: index = 0
88: row = row.collect do |cell|
89: if cell
90: cell.strip!
91: if quoted
92: cell.gsub!(/^"/, '')
93: cell.gsub!(/"$/, '')
94: end
95:
96: if index >= column_count
97: self.columns << Column.new
98: end
99:
100: column = columns[index]
101: if !column.fixed_size && (cell.size > column.size)
102: column.size = cell.size
103: end
104: end
105:
106: index = index + 1
107: cell
108: end
109:
110: rows << Row.new(row, self)
111: end
112: end
# File lib/grid.rb, line 224
224: def to_s(include_columns = true)
225: unless truncated?
226: truncate_rows
227: end
228: unless calculated_padding?
229: calculate_padding
230: end
231:
232: text = ""
233: if include_columns && columns && columns.any?(&:present?)
234: descriptions = columns.collect do |column|
235: column.description
236: end
237: text = text + header_to_s(descriptions)
238: end
239: rows.each_with_index do |row, row_index|
240: text = text + row_to_s(row, row_index)
241: end
242: text
243: end
# File lib/grid.rb, line 285
285: def truncate_rows
286: @truncated = true
287: for row in rows
288: for index in 0..(column_count - 1)
289: cell = row[index]
290: if cell && cell.size > column_size(index)
291: row[index] = truncate(cell, :length => column_size(index))
292: end
293: end
294: end
295: end
# File lib/grid.rb, line 195
195: def validate_columns
196: return unless @row_class_instance
197:
198: columns.each do |column|
199: if column.field.nil? || !(@row_class_instance.respond_to?("#{column.field}="))
200: column.field = nil
201: @custom_columns << column.name unless column.name.blank?
202: end
203: end
204: end