diff --git a/lib/youplot/dsv.rb b/lib/youplot/dsv.rb index 2d7e751..b1d48fc 100644 --- a/lib/youplot/dsv.rb +++ b/lib/youplot/dsv.rb @@ -3,41 +3,49 @@ require 'csv' module YouPlot - # Read and interpret Delimiter-separated values format file or stream. + # Module to handle DSV (Delimiter-separated values) format. + # Extract header and series. module DSV module_function def parse(input, delimiter, headers, transpose) - arr = parse_as_csv(input, delimiter) - headers = get_headers(arr, headers, transpose) - series = get_series(arr, headers, transpose) - if headers.nil? - Data.new(headers, series) - else - if headers.include?(nil) - warn "\e[35mHeaders contains nil in it.\e[0m" - elsif headers.include? '' - warn "\e[35mHeaders contains \"\" in it.\e[0m" - end - h_size = headers.size - s_size = series.size - if h_size == s_size - Data.new(headers, series) - elsif h_size > s_size - warn "\e[35mThe number of headers is greater than the number of series.\e[0m" - exit 1 if YouPlot.run_as_executable? - elsif h_size < s_size - warn "\e[35mThe number of headers is less than the number of series.\e[0m" - exit 1 if YouPlot.run_as_executable? - end - end - end + # Parse as CSV + arr = CSV.parse(input, col_sep: delimiter) - def parse_as_csv(input, delimiter) - CSV.parse(input, col_sep: delimiter) - .delete_if do |i| - i == [] or i.all? nil - end + # Remove blank lines + arr.delete_if do |i| + i == [] or i.all? nil + end + + # get header + headers = get_headers(arr, headers, transpose) + + # get series + series = get_series(arr, headers, transpose) + + # Return if No header + return Data.new(headers, series) if headers.nil? + + # Warn if header contains nil + warn "\e[35mHeaders contains nil in it.\e[0m" if headers.include?(nil) + + # Warn if header contains '' + warn "\e[35mHeaders contains \"\" in it.\e[0m" if headers.include? '' + + # Make sure the number of elements in the header matches the number of series. + h_size = headers.size + s_size = series.size + + if h_size > s_size + warn "\e[35mThe number of headers is greater than the number of series.\e[0m" + exit 1 if YouPlot.run_as_executable? + + elsif h_size < s_size + warn "\e[35mThe number of headers is less than the number of series.\e[0m" + exit 1 if YouPlot.run_as_executable? + end + + Data.new(headers, series) if h_size == s_size end # Transpose different sized ruby arrays @@ -47,31 +55,33 @@ module YouPlot end def get_headers(arr, headers, transpose) - if headers - if transpose - arr.map(&:first) - else - arr[0] - end - end + # header(-) + return nil unless headers + + # header(+) trenspose(+) + return arr.map(&:first) if transpose + + # header(+) transpose(-) + arr[0] end def get_series(arr, headers, transpose) - if headers - if arr.size > 1 - if transpose - arr.map { |row| row[1..-1] } - else - transpose2(arr[1..-1]) - end - else - Array.new(arr[0].size, []) - end - elsif transpose - arr - else - transpose2(arr) + # header(-) + unless headers + return arr if transpose + + return transpose2(arr) end + + # header(+) but no element in the series. + # TODO: should raise error? + return Array.new(arr[0].size, []) if arr.size == 1 + + # header(+) transpose(+) + return arr.map { |row| row[1..-1] } if transpose + + # header(+) transpose(-) + transpose2(arr[1..-1]) end end end