require 'table_print' module HammerCLI::Output::Adapter class Table < Abstract def tags [:screen, :flat] end def print_record(fields, record) print_collection(fields, [record].flatten(1)) end def print_collection(all_fields, collection) fields = all_fields.reject { |f| f.class <= Fields::Id && !@context[:show_ids] } rows = collection.collect do |d| row = {} fields.each do |f| row[f.label.to_sym] = f.get_value(d) || "" end row end options = fields.collect do |f| { f.label.to_sym => { :formatters => Array(@formatters.formatter_for_type(f.class)) } } end sort_order = fields.map { |f| f.label.upcase } printer = TablePrint::Printer.new(rows, options) TablePrint::Config.max_width = 40 output = sort_columns(printer.table_print, sort_order) dashes = /\n([-|]+)\n/.match(output) puts dashes[1] if dashes puts output puts dashes[1] if dashes end def print_heading(heading, size) size = heading.size if heading.size > size puts '-' * size puts ' ' * ((size-heading.size)/2) + heading puts '-' * size end private def sort_columns(output, sort_order) return output if sort_order.length == 1 # don't sort one column delimiter = ' | ' lines = output.split("\n") out = [] headers = lines.first.split(delimiter).map(&:strip) # create mapping table for column indexes sort_map = [] sort_order.each { |c| sort_map << headers.index(c) } lines.each do |line| columns = line.split(delimiter) if columns.length == 1 # dashes columns = columns.first.split('-|-') if columns.length == 1 out << columns.first else # new style dashes new_row = [] sort_map.each { |i| new_row << columns[i] } out << new_row.join('-|-') end else # reorder row new_row = [] sort_map.each { |i| new_row << columns[i] } out << new_row.join(delimiter) end end out.join("\n") end end HammerCLI::Output::Output.register_adapter(:table, Table) end