class YouPlot::Command

Attributes

command[RW]
data[R]
options[RW]
params[RW]
parser[R]

Public Class Methods

new(argv = ARGV) click to toggle source
# File lib/youplot/command.rb, line 16
def initialize(argv = ARGV)
  @argv    = argv
  @parser  = Parser.new
  @command = nil
  @params  = nil
  @options = nil
  @backend = YouPlot::Backends::UnicodePlot
end

Public Instance Methods

run() click to toggle source
# File lib/youplot/command.rb, line 30
def run
  parser.parse_options(@argv)
  @command ||= parser.command
  @options ||= parser.options
  @params  ||= parser.params

  # color command
  if %i[colors color colours colour].include? @command
    plot = create_plot
    output_plot(plot)
    return
  end

  # progressive mode
  if options[:progressive]
    stop = false
    Signal.trap(:INT) { stop = true }

    # make cursor invisible
    options[:output].print "\e[?25l"

    # mainloop
    while (input = Kernel.gets)
      n = main_progressive(input)
      break if stop

      options[:output].print "\e[#{n}F"
    end

    options[:output].print "\e[0J"
    # make cursor visible
    options[:output].print "\e[?25h"

  # normal mode
  else
    # Sometimes the input file does not end with a newline code.
    while (input = Kernel.gets(nil))
      main(input)
    end
  end
end
run_as_executable() click to toggle source
# File lib/youplot/command.rb, line 25
def run_as_executable
  YouPlot.run_as_executable = true
  run
end

Private Instance Methods

create_plot() click to toggle source
# File lib/youplot/command.rb, line 144
def create_plot
  case command
  when :bar, :barplot
    @backend.barplot(data, params, options[:fmt])
  when :count, :c
    @backend.barplot(data, params, count: true, reverse: options[:reverse])
  when :hist, :histogram
    @backend.histogram(data, params)
  when :line, :lineplot
    @backend.line(data, params, options[:fmt])
  when :lines, :lineplots
    @backend.lines(data, params, options[:fmt])
  when :scatter, :s
    @backend.scatter(data, params, options[:fmt])
  when :density, :d
    @backend.density(data, params, options[:fmt])
  when :box, :boxplot
    @backend.boxplot(data, params)
  when :colors, :color, :colours, :colour
    @backend.colors(options[:color_names])
  else
    raise "unrecognized plot_type: #{command}"
  end
end
main(input) click to toggle source
# File lib/youplot/command.rb, line 74
def main(input)
  # Outputs input data to a file or stdout.
  output_data(input)

  @data = parse_dsv(input)

  # Debug mode, show parsed results
  pp @data if options[:debug]

  # When run as a program instead of a library
  if YouPlot.run_as_executable?
    begin
      plot = create_plot
    rescue ArgumentError => e
      # Show only one line of error.
      warn e.backtrace[0]
      # Show error message in purple
      warn "\e[35m#{e}\e[0m"
      # Explicitly terminated with exit code: 1
      exit 1
    end

  # When running YouPlot as a library (e.g. for testing)
  else
    plot = create_plot
  end

  output_plot(plot)
end
main_progressive(input) click to toggle source
# File lib/youplot/command.rb, line 104
def main_progressive(input)
  output_data(input)

  # FIXME
  # Worked around the problem of not being able to draw
  # plots when there is only one header line.
  if @raw_data.nil?
    @raw_data = String.new
    if options[:headers]
      @raw_data << input
      return
    end
  end
  @raw_data << input

  # FIXME
  @data = parse_dsv(@raw_data)

  plot = create_plot
  output_plot_progressive(plot)
end
output_data(input) click to toggle source
# File lib/youplot/command.rb, line 169
def output_data(input)
  # Pass the input to subsequent pipelines
  case options[:pass]
  when IO
    options[:pass].print(input)
  else
    if options[:pass]
      File.open(options[:pass], 'w') do |f|
        f.print(input)
      end
    end
  end
end
output_plot(plot) click to toggle source
# File lib/youplot/command.rb, line 183
def output_plot(plot)
  case options[:output]
  when IO, StringIO
    plot.render(options[:output])
  when String, Tempfile
    File.open(options[:output], 'w') do |f|
      plot.render(f)
    end
  end
end
output_plot_progressive(plot) click to toggle source
# File lib/youplot/command.rb, line 194
def output_plot_progressive(plot)
  case options[:output]
  when IO, StringIO
    # RefactorMe
    out = StringIO.new(String.new)
    def out.tty?
      true
    end
    plot.render(out)
    lines = out.string.lines
    lines.each do |line|
      options[:output].print line.chomp
      options[:output].print "\e[0K"
      options[:output].puts
    end
    options[:output].print "\e[0J"
    options[:output].flush
    out.string.lines.size
  else
    raise 'In progressive mode, output to a file is not possible.'
  end
end
parse_dsv(input) click to toggle source
# File lib/youplot/command.rb, line 126
def parse_dsv(input)
  # If encoding is specified, convert to UTF-8
  if options[:encoding]
    input.force_encoding(options[:encoding])
         .encode!('utf-8')
  end

  begin
    data = DSV.parse(input, options[:delimiter], options[:headers], options[:transpose])
  rescue CSV::MalformedCSVError => e
    warn 'Failed to parse the text. '
    warn 'Please try to set the correct character encoding with --encoding option.'
    raise e
  end

  data
end