Browse Source

Finished CSV feature

dev
Andy Meneely 11 years ago
parent
commit
04b55d8b32
  1. 1
      CHANGELOG.md
  2. 10
      README.md
  3. 19
      lib/squib/api/data.rb
  4. 5
      samples/csv_import.rb
  5. 31
      spec/api/api_data_spec.rb
  6. 3
      spec/data/csv/dup_cols.csv
  7. 3
      spec/data/csv/with_spaces.csv
  8. 112
      spec/data/samples/csv_import.rb.txt
  9. 1
      spec/samples/samples_regression_spec.rb

1
CHANGELOG.md

@ -1,5 +1,6 @@
# Squib CHANGELOG
# Added a `csv` command that works just like `xslx`. Uses Ruby's CSV inside, with some extra checking and warnings.
# Custom layouts now support loading & merging multiple Yaml files! Updated README, docs, and sample to document it.
# Built-in layouts! Currently we support `hand.yml` and `playing-card.yml`. Documented in the `layouts.rb` sample.
# `text` now returns the ink extent rectangle of the rendered text. Updated docs and sample to document it.

10
README.md

@ -4,7 +4,7 @@ Squib is a Ruby [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) for
* A concise set of rules for laying out your cards
* Loading PNGs and SVGs using [Cairo](http://cairographics.org/)
* Complex text rendering using [Pango](http://www.pango.org/)
* Reading `.xlsx` files
* Reading `xlsx` and `csv` files
* Basic shape drawing
* Rendering decks to PNGs and PDFs
* Data-driven layouts
@ -255,6 +255,14 @@ See the `custom_config` sample found [here](https://github.com/andymeneely/squib
{include:file:samples/custom_config.rb}
## Importing from Excel and CSV
Squib supports importing data from `xlsx` files and `csv` files. These methods are column-based, which means that they assume you have a header row in your table, and that header row will define the column. Squib will return a `Hash` of `Arrays` correspoding to each row. Warnings are thrown on things like duplicate columns. See the `excel.rb` and the `csv_import.rb` sample found [here](https://github.com/andymeneely/squib/tree/master/samples/).
{include:file:samples/excel.rb}
Of course, you can always import your game data other ways using just Ruby. There's nothing special about Squib's methods other than their convenience.
## Making Squib Verbose
By default, Squib's logger is set to WARN, but more fine-grained logging is embedded in the code. To set the logger, just put this at the top of your script:

19
lib/squib/api/data.rb

@ -63,13 +63,26 @@ module Squib
def csv(opts = {})
opts = Squib::SYSTEM_DEFAULTS.merge(opts)
opts = Squib::InputHelpers.fileify(opts)
hash = {}
csv = CSV.open(opts[:file], headers: true, converters: :numeric).read
table = CSV.read(opts[:file], headers: true, converters: :numeric)
check_duplicate_csv_headers(table)
hash = Hash.new
table.headers.each do |header|
hash[header.to_s] ||= table[header]
end
return hash
end
module_function :csv
# Check if the given CSV table has duplicate columns, and throw a warning
# @api private
def check_duplicate_csv_headers(table)
if table.headers.size != table.headers.uniq.size
dups = table.headers.select{|e| table.headers.count(e) > 1 }
Squib.logger.warn "CSV duplicated the following column keys: #{dups.join(',')}"
end
end
module_function :check_duplicate_csv_headers
class Deck
# Convenience call on deck goes to the module function

5
samples/csv.rb → samples/csv_import.rb

@ -13,5 +13,8 @@ Squib::Deck.new(cards: 2) do
# You can also specify the sheet, starting at 0
data = xlsx file: 'sample.xlsx', sheet: 2
save format: :png, prefix: 'sample_excel_'
save format: :png, prefix: 'sample_csv_'
end
# CSV is also a Squib-module-level function, so this also works:
data = Squib.csv file: 'sample.csv'

31
spec/api/api_data_spec.rb

@ -2,11 +2,30 @@ require 'spec_helper'
describe Squib::Deck do
context '#csv' do
# it 'loads basic csv data' do
# expect(Squib.csv(file: csv_file('basic.csv'))).to eq({
# 'h1' => [1, 3],
# 'h2' => [2, 4]
# })
# end
it 'loads basic csv data' do
expect(Squib.csv(file: csv_file('basic.csv'))).to eq({
'h1' => [1, 3],
'h2' => [2, 4]
})
end
it 'collapses duplicate columns and warns' do
expect(Squib.logger).to receive(:warn)
.with('CSV duplicated the following column keys: h1,h1')
expect(Squib.csv(file: csv_file('dup_cols.csv'))).to eq({
'h1' => [1, 3],
'h2' => [5, 7],
'H2' => [6, 8],
'h3' => [9, 10],
})
end
it 'handles spaces properly' do
expect(Squib.csv(file: csv_file('with_spaces.csv'))).to eq({
'With Spaces' => ['a b c ', 3],
'h2' => [2, 4],
'h3' => [3, nil]
})
end
end
end

3
spec/data/csv/dup_cols.csv

@ -0,0 +1,3 @@
h1,h1,h2,H2,h3
1,2,5,6,9
3,4,7,8,10
1 h1 h1 h2 H2 h3
2 1 2 5 6 9
3 3 4 7 8 10

3
spec/data/csv/with_spaces.csv

@ -0,0 +1,3 @@
With Spaces,h2,h3
a b c , 2,3
3 ,4
1 With Spaces,h2,h3
2 a b c , 2,3
3 3 ,4

112
spec/data/samples/csv_import.rb.txt

@ -0,0 +1,112 @@
cairo: save([])
cairo: set_source_color([#<Cairo::Color::RGB: @alpha=1.0, @red=1.0, @green=1.0, @blue=1.0>])
cairo: paint([])
cairo: restore([])
cairo: save([])
cairo: set_source_color([#<Cairo::Color::RGB: @alpha=1.0, @red=1.0, @green=1.0, @blue=1.0>])
cairo: paint([])
cairo: restore([])
cairo: save([])
cairo: set_source_color([#<Cairo::Color::RGB: @alpha=1.0, @red=0.0, @green=0.0, @blue=0.0>])
cairo: translate([250, 55])
cairo: rotate([0])
cairo: translate([-250, -55])
cairo: move_to([250, 55])
pango: font_description=([])
pango: text=([""])
pango: wrap=([#<Pango::Layout::WrapMode word-char>])
pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: spacing=([0])
cairo: update_pango_layout([MockDouble])
cairo: update_pango_layout([MockDouble])
cairo: show_pango_layout([MockDouble])
cairo: restore([])
cairo: save([])
cairo: set_source_color([#<Cairo::Color::RGB: @alpha=1.0, @red=0.0, @green=0.0, @blue=0.0>])
cairo: translate([250, 55])
cairo: rotate([0])
cairo: translate([-250, -55])
cairo: move_to([250, 55])
pango: font_description=([])
pango: text=([""])
pango: wrap=([#<Pango::Layout::WrapMode word-char>])
pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: spacing=([0])
cairo: update_pango_layout([MockDouble])
cairo: update_pango_layout([MockDouble])
cairo: show_pango_layout([MockDouble])
cairo: restore([])
cairo: save([])
cairo: set_source_color([#<Cairo::Color::RGB: @alpha=1.0, @red=0.0, @green=0.0, @blue=0.0>])
cairo: translate([65, 65])
cairo: rotate([0])
cairo: translate([-65, -65])
cairo: move_to([65, 65])
pango: font_description=([])
pango: text=([""])
pango: wrap=([#<Pango::Layout::WrapMode word-char>])
pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: spacing=([0])
cairo: update_pango_layout([MockDouble])
cairo: update_pango_layout([MockDouble])
cairo: show_pango_layout([MockDouble])
cairo: restore([])
cairo: save([])
cairo: set_source_color([#<Cairo::Color::RGB: @alpha=1.0, @red=0.0, @green=0.0, @blue=0.0>])
cairo: translate([65, 65])
cairo: rotate([0])
cairo: translate([-65, -65])
cairo: move_to([65, 65])
pango: font_description=([])
pango: text=([""])
pango: wrap=([#<Pango::Layout::WrapMode word-char>])
pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: spacing=([0])
cairo: update_pango_layout([MockDouble])
cairo: update_pango_layout([MockDouble])
cairo: show_pango_layout([MockDouble])
cairo: restore([])
cairo: save([])
cairo: set_source_color([#<Cairo::Color::RGB: @alpha=1.0, @red=0.0, @green=0.0, @blue=0.0>])
cairo: translate([65, 600])
cairo: rotate([0])
cairo: translate([-65, -600])
cairo: move_to([65, 600])
pango: font_description=([])
pango: text=([""])
pango: wrap=([#<Pango::Layout::WrapMode word-char>])
pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: spacing=([0])
cairo: update_pango_layout([MockDouble])
cairo: update_pango_layout([MockDouble])
cairo: show_pango_layout([MockDouble])
cairo: restore([])
cairo: save([])
cairo: set_source_color([#<Cairo::Color::RGB: @alpha=1.0, @red=0.0, @green=0.0, @blue=0.0>])
cairo: translate([65, 600])
cairo: rotate([0])
cairo: translate([-65, -600])
cairo: move_to([65, 600])
pango: font_description=([])
pango: text=([""])
pango: wrap=([#<Pango::Layout::WrapMode word-char>])
pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: spacing=([0])
cairo: update_pango_layout([MockDouble])
cairo: update_pango_layout([MockDouble])
cairo: show_pango_layout([MockDouble])
cairo: restore([])
surface: write_to_png(["_output/sample_csv_0.png"])
surface: write_to_png(["_output/sample_csv_1.png"])

1
spec/samples/samples_regression_spec.rb

@ -54,6 +54,7 @@ describe "Squib samples" do
draw_shapes.rb
colors.rb
excel.rb
csv_import.rb
portrait-landscape.rb
tgc_proofs.rb
ranges.rb

Loading…
Cancel
Save