module Mrtable

Constants

VERSION

Public Class Methods

col_len(col) click to toggle source
# File lib/mrtable.rb, line 89
def self.col_len(col)
  (0...col.size).inject(0) { |sum, i|
    sum + (hankaku?(col[i]) ? 1 : 2)
  }
end
complement_cols(cols, num_cols_max, val) click to toggle source
# File lib/mrtable.rb, line 67
def self.complement_cols(cols, num_cols_max, val)
  (0...num_cols_max).map do |ci|
    if ci < cols.size
      cols[ci]
    else
      val
    end
  end
end
generate(header_cols, rows) click to toggle source
# File lib/mrtable.rb, line 229
def self.generate(header_cols, rows)
  table = Table.new(header_cols, rows)

  serialized = table.map_col_with_ci { |col, _|
    serialize_col col
  }

  maxlens = serialized.calc_maxlens()

  padded = serialized.map_col_with_ci { |col, ci|
    pad_col col, maxlens[ci]
  }

  lines = []
  lines << to_table_row(padded.header_cols)
  lines << to_table_row(maxlens.map { |len| "-" * len })
  lines += padded.rows.map { |cols|
    to_table_row(cols)
  }
  lines
    .map { |line| line + "\n" }
    .join("")
end
hankaku?(c) click to toggle source

32-126(0x20-0x7E), 65377-65439(0xFF61-0xFF9F)

# File lib/mrtable.rb, line 131
def self.hankaku?(c)
  /^[ -~。-゚]$/.match?(c)
end
int?(s) click to toggle source
# File lib/mrtable.rb, line 77
def self.int?(s)
  /^\-?[\d,]+$/.match?(s)
end
json_decode(str) click to toggle source
# File lib/mrtable.rb, line 146
def self.json_decode(str)
  if /^".*"$/.match?(str)
    JSON.parse('[' + str + ']')[0]
  else
    JSON.parse('["' + str + '"]')[0]
  end
end
json_encode(val) click to toggle source
# File lib/mrtable.rb, line 135
def self.json_encode(val)
  json = JSON.generate([val])
  if /^\["(.*)"\]$/ =~ json
    $1
  elsif /^\[(.+)\]$/ =~ json
    $1
  else
    json
  end
end
pad_col(col, maxlen) click to toggle source
# File lib/mrtable.rb, line 81
def self.pad_col(col, maxlen)
  if int? col
    pad_left col, maxlen
  else
    pad_right col, maxlen
  end
end
pad_left(s, n) click to toggle source
# File lib/mrtable.rb, line 103
def self.pad_left(s, n)
  rest = n - col_len(s)
  if rest == 0
    return s
  end
  (" " * rest) + s
end
pad_right(s, n) click to toggle source
# File lib/mrtable.rb, line 95
def self.pad_right(s, n)
  rest = n - col_len(s)
  if rest == 0
    return s
  end
  s + (" " * rest)
end
parse(text, opts = {}) click to toggle source
# File lib/mrtable.rb, line 196
def self.parse(text, opts = {})
  lines = text
    .split(/\r?\n/)
    .reject { |line|
      /^\s*$/.match?(line) or
      /^\| \-\-\-+ \|/.match?(line)
    }
  rows = lines.map { |line|
    split_row(line)
  }
  raw = Table.new rows[0], rows[1..-1]

  stripped = raw.map_col_with_ci { |col, _|
    col.strip
  }

  parsed = stripped.map_col_with_ci { |col, _|
    parse_col col
  }

  if opts.key? :complement
    unless opts[:complement].is_a? String or opts[:complement].nil?
      raise "opts[:complement] must be String or nil"
    end
    parsed = parsed.complement opts[:complement]
  end

  [
    parsed.header_cols,
    parsed.rows
  ]
end
parse_col(col) click to toggle source
# File lib/mrtable.rb, line 154
def self.parse_col(col)
  if col == ''
    nil
  elsif col == '""'
    ""
  else
    json_decode(col)
  end
end
serialize_col(col) click to toggle source
# File lib/mrtable.rb, line 111
def self.serialize_col(col)
  if col.nil?
    return ""
  elsif col == ""
    return '""'
  end

  ret = json_encode(col)
  if /^\s+/.match?(ret) or /\s+$/.match?(ret) or /^\-+$/.match?(ret)
    ret = '"' + ret + '"'
  end

  ret.gsub("|", "\\|")
end
split_row(line) click to toggle source
# File lib/mrtable.rb, line 164
def self.split_row(line)
  work_line = line + " "
  cols = []
  buf = ""
  pos = 2
  pos_delta = nil

  num_repeat_max = work_line.size
  num_repeat_max.times do
    break if pos >= work_line.size
    pos_delta = 1
    rest = work_line[pos..-1]
    if /^ \| /.match?(rest)
      cols << buf; buf = ""
      pos_delta = 3
    elsif /^\\/.match?(rest)
      if rest[1] == "|"
        buf += rest[1]
        pos_delta = 2
      else
        buf += rest[0..1]
        pos_delta = 2
      end
    else
      buf += rest[0]
    end
    pos += pos_delta
  end

  cols
end
to_table_row(cols) click to toggle source
# File lib/mrtable.rb, line 126
def self.to_table_row(cols)
  "| " + cols.join(" | ") + " |"
end