diff --git a/CHANGELOG.md b/CHANGELOG.md index c81fcf4..357999f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Squib follows [semantic versioning](http://semver.org). Features: * Build groups! Simplify the process of building your deck different ways (e.g. one for color, one for PNP). Can be enabled explicitly or via command line. [See our shiny new docs for how these work](http://squib.readthedocs.org). * The `csv` method now supports a `data` option to read CSV data directly. When set, it overrides the `file` option. +* The `csv` method now supports all of the Ruby CSV options (e.g. `col_sep`, `quote_char`). These options simply get passed through to Ruby, so as they change in Ruby, so the support changes in Squib. (#149) Special thanks to Qgel's initial pull request (#146). * New `use_layout` method will allow you to load a layout file as a DSL method instead of in the constructor. Useful in conjunction with build groups! (#141) Chores: diff --git a/docs/dsl/csv.rst b/docs/dsl/csv.rst index 9542ef7..190cdee 100644 --- a/docs/dsl/csv.rst +++ b/docs/dsl/csv.rst @@ -36,5 +36,14 @@ explode Quantity explosion will be applied to the column this name. For example, rows in the csv with a ``'qty'`` of 3 will be duplicated 3 times. +col_sep + default: ``','`` + + Column separator. One of the CSV custom options in Ruby. See next option below. + +CSV custom options in Ruby standard lib. + All of the options in Ruby's std lib version of CSV are supported **except** ``headers`` is always ``true`` and ``converters`` is always set to ``:numeric``. See the `Ruby Docs `_ for information on the options. + + Examples -------- diff --git a/lib/squib/api/data.rb b/lib/squib/api/data.rb index 69b043f..99ca938 100644 --- a/lib/squib/api/data.rb +++ b/lib/squib/api/data.rb @@ -2,6 +2,7 @@ require 'roo' require 'csv' require_relative '../args/input_file' require_relative '../args/import' +require_relative '../args/csv_opts' module Squib @@ -34,8 +35,8 @@ module Squib import = Args::Import.new.load!(opts) file = Args::InputFile.new(file: 'deck.csv').load!(opts).file[0] data = opts.key?(:data) ? opts[:data] : File.read(file) - sep = opts.key?(:sep) ? opts[:sep] : ',' - table = CSV.parse(data, headers: true, converters: :numeric, col_sep: sep) + csv_opts = Args::CSV_Opts.new(opts) + table = CSV.parse(data, csv_opts.to_hash) check_duplicate_csv_headers(table) hash = Hash.new table.headers.each do |header| diff --git a/lib/squib/args/csv_opts.rb b/lib/squib/args/csv_opts.rb new file mode 100644 index 0000000..1031db4 --- /dev/null +++ b/lib/squib/args/csv_opts.rb @@ -0,0 +1,25 @@ +require 'csv' + +module Squib + # @api private + module Args + class CSV_Opts + + def initialize(opts) + opts = opts.keep_if { |k, _v| CSV::DEFAULT_OPTIONS.key? k} + @hash = CSV::DEFAULT_OPTIONS.merge(opts).merge(required) + end + + def to_hash + @hash + end + + private + + def required + { headers: true, converters: :numeric } + end + + end + end +end diff --git a/spec/api/api_data_spec.rb b/spec/api/api_data_spec.rb index 57f2db5..5aa394a 100644 --- a/spec/api/api_data_spec.rb +++ b/spec/api/api_data_spec.rb @@ -67,6 +67,15 @@ describe Squib::Deck do }) end + it 'loads custom CSV options' do + hash = Squib.csv(file: csv_file('custom_opts.csv'), + col_sep: '-', quote_char: '|') + expect(hash).to eq({ + 'x' => ['p'], + 'y' => ['q-r'] + }) + end + end context '#xlsx' do diff --git a/spec/data/csv/custom_opts.csv b/spec/data/csv/custom_opts.csv new file mode 100644 index 0000000..4c180b7 --- /dev/null +++ b/spec/data/csv/custom_opts.csv @@ -0,0 +1,2 @@ +x-y +p-|q-r|