diff --git a/lib/youplot/command.rb b/lib/youplot/command.rb index c59eeae..9e55bf2 100644 --- a/lib/youplot/command.rb +++ b/lib/youplot/command.rb @@ -10,27 +10,23 @@ module YouPlot Data = Struct.new(:headers, :series) class Command - attr_accessor :params - attr_reader :data, :fmt, :parser + attr_accessor :command, :params, :options + attr_reader :data, :parser def initialize(argv = ARGV) @argv = argv @parser = Parser.new + @command = nil + @params = nil + @options = nil @backend = YouPlot::Backends::UnicodePlotBackend end def run parser.parse_options(@argv) - command = parser.command - @params = parser.params - delimiter = parser.delimiter - transpose = parser.transpose - headers = parser.headers - pass = parser.pass - output = parser.output - fmt = parser.fmt - @encoding = parser.encoding - @debug = parser.debug + @command ||= parser.command + @options ||= parser.options + @params ||= parser.params if command == :colors @backend.colors(parser.color_names) @@ -41,52 +37,52 @@ module YouPlot while (input = Kernel.gets(nil)) # Pass the input to subsequent pipelines - case pass + case @options[:pass] when IO - pass.print(input) + @options[:pass].print(input) else - if pass - File.open(pass, 'w') do |f| + if @options[:pass] + File.open(@options[:pass], 'w') do |f| f.print(input) end end end - @data = if @encoding - input2 = input.dup.force_encoding(@encoding).encode('utf-8') - DSVReader.input(input2, delimiter, headers, transpose) + @data = if @options[:encoding] + input2 = input.dup.force_encoding(@options[:encoding]).encode('utf-8') + DSVReader.input(input2, @options[:delimiter], @options[:headers], @options[:transpose]) else - DSVReader.input(input, delimiter, headers, transpose) + DSVReader.input(input, @options[:delimiter], @options[:headers], @options[:transpose]) end - pp @data if @debug + pp @data if @options[:debug] plot = case command when :bar, :barplot - @backend.barplot(data, params, fmt) + @backend.barplot(data, params, @options[:fmt]) when :count, :c @backend.barplot(data, params, count: true) when :hist, :histogram @backend.histogram(data, params) when :line, :lineplot - @backend.line(data, params, fmt) + @backend.line(data, params, @options[:fmt]) when :lines, :lineplots - @backend.lines(data, params, fmt) + @backend.lines(data, params, @options[:fmt]) when :scatter, :s - @backend.scatter(data, params, fmt) + @backend.scatter(data, params, @options[:fmt]) when :density, :d - @backend.density(data, params, fmt) + @backend.density(data, params, @options[:fmt]) when :box, :boxplot @backend.boxplot(data, params) else raise "unrecognized plot_type: #{command}" end - case output + case @options[:output] when IO - plot.render(output) + plot.render(@options[:output]) else - File.open(output, 'w') do |f| + File.open(@options[:output], 'w') do |f| plot.render(f) end end diff --git a/lib/youplot/command/cmd_options.rb b/lib/youplot/command/cmd_options.rb new file mode 100644 index 0000000..ff4dbbe --- /dev/null +++ b/lib/youplot/command/cmd_options.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module YouPlot + class Command + CmdOptions = Struct.new( + :delimiter, + :transpose, + :headers, + :pass, + :output, + :fmt, + :encoding, + :color_names, + :debug, + keyword_init: true + ) + end +end diff --git a/lib/youplot/command/parser.rb b/lib/youplot/command/parser.rb index 866fe05..fea5bb6 100644 --- a/lib/youplot/command/parser.rb +++ b/lib/youplot/command/parser.rb @@ -1,29 +1,30 @@ # frozen_string_literal: true require 'optparse' +require_relative 'cmd_options' require_relative 'plot_params' module YouPlot class Command class Parser - attr_reader :command, :params, - :delimiter, :transpose, :headers, :pass, :output, :fmt, - :color_names, :encoding, :debug + attr_reader :command, :options, :params def initialize - @command = nil - @params = PlotParams.new + @command = nil - @delimiter = "\t" - @transpose = false - @headers = nil - @pass = false - @output = $stderr - @fmt = 'xyy' - @encoding = nil - @color_names = false + @options = CmdOptions.new( + delimiter: "\t", + transpose: false, + headers: nil, + pass: false, + output: $stderr, + fmt: 'xyy', + encoding: nil, + color_names: false, + debug: false + ) - @debug = false + @params = PlotParams.new end def create_default_parser @@ -36,19 +37,19 @@ module YouPlot opt.on('Common options:') opt.on('-O', '--pass [VAL]', 'file to output standard input data to [stdout]', 'for inserting YouPlot in the middle of Unix pipes') do |v| - @pass = v || $stdout + @options[:pass] = v || $stdout end opt.on('-o', '--output VAL', 'file to output results to [stderr]') do |v| - @output = v + @options[:output] = v end opt.on('-d', '--delimiter VAL', String, 'use DELIM instead of TAB for field delimiter') do |v| - @delimiter = v + @options[:delimiter] = v end opt.on('-H', '--headers', TrueClass, 'specify that the input has header row') do |v| - @headers = v + @options[:headers] = v end opt.on('-T', '--transpose', TrueClass, 'transpose the axes of the input data') do |v| - @transpose = v + @options[:transpose] = v end opt.on('-t', '--title VAL', String, 'print string on the top of plot') do |v| params.title = v @@ -81,10 +82,10 @@ module YouPlot params.labels = v end opt.on('--progress', TrueClass, 'progressive') do |v| - @progressive = v + @options[:progressive] = v end opt.on('--encoding VAL', String, 'Specify the input encoding') do |v| - @encoding = v + @options[:encoding] = v end # Optparse adds the help option, but it doesn't show up in usage. # This is why you need the code below. @@ -93,7 +94,7 @@ module YouPlot exit end opt.on('--debug', TrueClass, 'print preprocessed data') do |v| - @debug = v + @options[:debug] = v end yield opt if block_given? end @@ -167,7 +168,7 @@ module YouPlot params.xscale = v end parser.on_head('--fmt VAL', String, 'xy : header is like x, y...', 'yx : header is like y, x...') do |v| - @fmt = v + @options[:fmt] = v end when :count, :c @@ -197,7 +198,7 @@ module YouPlot params.ylim = v.take(2) end parser.on_head('--fmt VAL', String, 'xy : header is like x, y...', 'yx : header is like y, x...') do |v| - @fmt = v + @options[:fmt] = v end when :lineplots, :lines @@ -211,7 +212,7 @@ module YouPlot params.ylim = v.take(2) end parser.on_head('--fmt VAL', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...', 'xyy : header is like x, y1, y2, y2, y3...') do |v| - @fmt = v + @options[:fmt] = v end when :scatter, :s @@ -225,7 +226,7 @@ module YouPlot params.ylim = v.take(2) end parser.on_head('--fmt VAL', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...', 'xyy : header is like x, y1, y2, y2, y3...') do |v| - @fmt = v + @options[:fmt] = v end when :density, :d @@ -239,7 +240,7 @@ module YouPlot params.ylim = v.take(2) end parser.on('--fmt VAL', String, 'xyxy : header is like x1, y1, x2, y2, x3, y3...', 'xyy : header is like x, y1, y2, y2, y3...') do |v| - @fmt = v + @options[:fmt] = v end when :boxplot, :box @@ -249,7 +250,7 @@ module YouPlot when :colors parser.on_head('-n', '--names', 'show color names only', TrueClass) do |v| - @color_names = v + @options[:color_names] = v end else