Ruby - csvをmarkdown形式のテーブル表記にするサンプルコード

探せば色々な言語のサンプルコードがある。
気分転換に自分でも書いてみた。

整形しないで出力

require 'csv'

def print_to_table(rows)
  header   = rows[0]
  contents = rows[1..-1]

  puts "|" + header.join("|") + "|"
  puts "|" + Array.new(header.length, "---").join("|") + "|"
  contents.each do |items|
    puts "|" + items.join("|") + "|"
  end
end

# 実行
csv = <<EOS
Title,T,Tit
Text,Long Long Text,Awesome
TextText,Text,Some
EOS
rows = CSV.parse(csv)

print_to_table(rows)
|Title|T|Tit|
|---|---|---|
|Text|Long Long Text|Awesome|
|TextText|Text|Some|

整形して出力

require 'csv'

def print_to_table_pretty(rows)
  # 幅に応じて空白を後ろに追加する
  def align_cell(str, width)
    # str + (" " * (width - str.length))でもいい
    str.ljust(width, " ")
  end

  column_widths = Array.new(rows[0].length)
  # 各列の最大幅を記録する
  rows.each do |row|
    row.each_with_index do |text, i|
      current_width    = column_widths[i] || 0
      column_widths[i] = [current_width, text.length].max
    end
  end

  # 各行を列ごとの最大幅に合わせながら出力する
  rows.each_with_index do |row, row_i|
    print "|"
    row.each_with_index do |text, y|
      print " " + align_cell(text, column_widths[y]) + " |"
    end
    puts

    # ヘッダー行の後に入れる --- の行
    if row_i == 0
      print "|"
      column_widths.each do |width|
        print " " + align_cell(("-" * width), width) + " |"
      end
      puts
    end
  end
end


# 実行
csv = <<EOS
Title,T,Tit
Text,Long Long Text,Awesome
TextText,Text,Some
EOS
rows = CSV.parse(csv)

print_to_table_pretty(rows)
| Title    | T              | Tit     |
| -------- | -------------- | ------- |
| Text     | Long Long Text | Awesome |
| TextText | Text           | Some    |