squib 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +162 -133
  3. data/Gemfile +4 -4
  4. data/README.md +630 -550
  5. data/RELEASE TODO.md +18 -18
  6. data/Rakefile +99 -99
  7. data/lib/squib.rb +32 -32
  8. data/lib/squib/api/background.rb +20 -19
  9. data/lib/squib/api/data.rb +100 -99
  10. data/lib/squib/api/image.rb +90 -76
  11. data/lib/squib/api/save.rb +149 -103
  12. data/lib/squib/api/settings.rb +35 -37
  13. data/lib/squib/api/shapes.rb +230 -228
  14. data/lib/squib/api/text.rb +65 -66
  15. data/lib/squib/api/text_embed.rb +96 -66
  16. data/lib/squib/args/arg_loader.rb +138 -0
  17. data/lib/squib/args/box.rb +55 -0
  18. data/lib/squib/args/card_range.rb +32 -0
  19. data/lib/squib/args/color_validator.rb +12 -0
  20. data/lib/squib/args/coords.rb +33 -0
  21. data/lib/squib/args/dir_validator.rb +16 -0
  22. data/lib/squib/args/draw.rb +92 -0
  23. data/lib/squib/args/embed_adjust.rb +25 -0
  24. data/lib/squib/args/embed_key.rb +17 -0
  25. data/lib/squib/args/hand_special.rb +37 -0
  26. data/lib/squib/args/input_file.rb +37 -0
  27. data/lib/squib/args/paint.rb +44 -0
  28. data/lib/squib/args/paragraph.rb +115 -0
  29. data/lib/squib/args/save_batch.rb +60 -0
  30. data/lib/squib/args/scale_box.rb +53 -0
  31. data/lib/squib/args/sheet.rb +72 -0
  32. data/lib/squib/args/showcase_special.rb +38 -0
  33. data/lib/squib/args/svg_special.rb +37 -0
  34. data/lib/squib/args/transform.rb +25 -0
  35. data/lib/squib/args/typographer.rb +117 -117
  36. data/lib/squib/card.rb +67 -67
  37. data/lib/squib/conf.rb +117 -111
  38. data/lib/squib/constants.rb +178 -178
  39. data/lib/squib/deck.rb +113 -111
  40. data/lib/squib/graphics/cairo_context_wrapper.rb +99 -53
  41. data/lib/squib/graphics/gradient_regex.rb +46 -46
  42. data/lib/squib/graphics/hand.rb +42 -43
  43. data/lib/squib/graphics/image.rb +76 -73
  44. data/lib/squib/graphics/save_doc.rb +103 -137
  45. data/lib/squib/graphics/save_images.rb +33 -33
  46. data/lib/squib/graphics/shapes.rb +119 -152
  47. data/lib/squib/graphics/showcase.rb +85 -88
  48. data/lib/squib/graphics/text.rb +176 -216
  49. data/lib/squib/layout_parser.rb +91 -89
  50. data/lib/squib/layouts/economy.yml +85 -0
  51. data/lib/squib/layouts/fantasy.yml +101 -0
  52. data/lib/squib/layouts/hand.yml +62 -46
  53. data/lib/squib/layouts/playing-card.yml +35 -18
  54. data/lib/squib/project_template/config.yml +45 -40
  55. data/lib/squib/version.rb +10 -10
  56. data/samples/color_shortcuts.rb +6 -0
  57. data/samples/csv_import.rb +18 -18
  58. data/samples/custom-config.yml +5 -5
  59. data/samples/custom_config.rb +18 -18
  60. data/samples/draw_shapes.rb +45 -35
  61. data/samples/embed_text.rb +88 -90
  62. data/samples/hand.rb +24 -24
  63. data/samples/layouts.rb +62 -61
  64. data/samples/layouts_builtin.rb +51 -0
  65. data/samples/load_images.rb +78 -64
  66. data/samples/ranges.rb +64 -53
  67. data/samples/sample.csv +2 -2
  68. data/samples/text_options.rb +102 -94
  69. data/spec/api/api_data_spec.rb +57 -50
  70. data/spec/api/api_settings_spec.rb +37 -17
  71. data/spec/args/box_spec.rb +127 -0
  72. data/spec/args/draw_spec.rb +95 -0
  73. data/spec/args/embed_key_spec.rb +13 -0
  74. data/spec/args/input_file_spec.rb +21 -0
  75. data/spec/args/paint_spec.rb +22 -0
  76. data/spec/args/paragraph_spec.rb +153 -0
  77. data/spec/args/range_spec.rb +36 -0
  78. data/spec/args/save_batch_spec.rb +51 -0
  79. data/spec/args/scale_box_spec.rb +71 -0
  80. data/spec/args/sheet_spec.rb +58 -0
  81. data/spec/args/showcase_special_spec.rb +15 -0
  82. data/spec/data/samples/autoscale_font.rb.txt +84 -87
  83. data/spec/data/samples/basic.rb.txt +209 -203
  84. data/spec/data/samples/cairo_access.rb.txt +2 -2
  85. data/spec/data/samples/config_text_markup.rb.txt +72 -75
  86. data/spec/data/samples/csv_import.rb.txt +76 -80
  87. data/spec/data/samples/custom_config.rb.txt +48 -49
  88. data/spec/data/samples/draw_shapes.rb.txt +100 -42
  89. data/spec/data/samples/embed_text.rb.txt +283 -295
  90. data/spec/data/samples/excel.rb.txt +162 -171
  91. data/spec/data/samples/gradients.rb.txt +79 -67
  92. data/spec/data/samples/hand.rb.txt +538 -514
  93. data/spec/data/samples/hello_world.rb.txt +36 -38
  94. data/spec/data/samples/load_images.rb.txt +41 -5
  95. data/spec/data/samples/portrait-landscape.rb.txt +49 -51
  96. data/spec/data/samples/ranges.rb.txt +460 -429
  97. data/spec/data/samples/saves.rb.txt +801 -785
  98. data/spec/data/samples/showcase.rb.txt +5910 -5906
  99. data/spec/data/samples/text_options.rb.txt +1125 -981
  100. data/spec/data/samples/tgc_proofs.rb.txt +81 -79
  101. data/spec/data/samples/units.rb.txt +18 -12
  102. data/spec/data/xlsx/with_macros.xlsm +0 -0
  103. data/spec/graphics/cairo_context_wrapper_spec.rb +84 -75
  104. data/spec/graphics/graphics_images_spec.rb +94 -85
  105. data/spec/graphics/graphics_save_doc_spec.rb +67 -65
  106. data/spec/samples/expected/hand.png +0 -0
  107. data/spec/samples/expected/hand_pretty.png +0 -0
  108. data/spec/samples/expected/layout_00.png +0 -0
  109. data/spec/samples/expected/load_images_00.png +0 -0
  110. data/spec/samples/expected/ranges_00.png +0 -0
  111. data/spec/samples/expected/shape_00.png +0 -0
  112. data/spec/samples/expected/showcase.png +0 -0
  113. data/spec/samples/expected/showcase2.png +0 -0
  114. data/spec/samples/expected/showcase_individual_00.png +0 -0
  115. data/spec/samples/expected/showcase_individual_01.png +0 -0
  116. data/spec/samples/expected/showcase_individual_02.png +0 -0
  117. data/spec/samples/expected/showcase_individual_03.png +0 -0
  118. data/spec/samples/expected/text_00.png +0 -0
  119. data/spec/samples/expected/text_01.png +0 -0
  120. data/spec/samples/expected/text_02.png +0 -0
  121. data/spec/samples/samples_regression_spec.rb +82 -82
  122. data/spec/spec_helper.rb +3 -2
  123. data/squib.gemspec +48 -48
  124. data/squib.sublime-project +42 -36
  125. metadata +61 -33
  126. data/lib/squib/input_helpers.rb +0 -238
  127. data/spec/api/api_image_spec.rb +0 -38
  128. data/spec/api/api_text_spec.rb +0 -37
  129. data/spec/graphics/graphics_shapes_spec.rb +0 -85
  130. data/spec/graphics/graphics_text_spec.rb +0 -164
  131. data/spec/input_helpers_spec.rb +0 -238
  132. data/spec/samples/expected/embed_multi_00.png +0 -0
  133. data/spec/samples/expected/embed_multi_01.png +0 -0
  134. data/spec/samples/expected/embed_multi_02.png +0 -0
  135. data/spec/samples/expected/ranges_01.png +0 -0
  136. data/spec/samples/expected/ranges_02.png +0 -0
@@ -1,18 +1,18 @@
1
- Be sure to remember to do the following for releases. (Copy into a GitHub issue)
2
-
3
- - [ ] CHANGELOG is written for all new changes
4
- - [ ] README is updated
5
- - [ ] Samples are updated
6
- - [ ] `rake doc`
7
- - [ ] Check `sample_regression_spec.rb` regression tests are all enabled (i.e. `overwrite_sample` is commented out)
8
- - [ ] Bump version.rb
9
- - [ ] Do a full rake locally
10
- - [ ] `rake sanity`, and check visually
11
- - [ ] Travis is passing on dev branch
12
- - [ ] Merge master branch
13
- - [ ] Create GitHub release tag
14
- - [ ] `gem push pkg/squib-x.y.z.gem`
15
- - [ ] Github milestone closed
16
- - [ ] Push `rake doc` to website
17
- - [ ] Bump version.rb to the next alpha
18
- - [ ] Publish on BoardGameGeek thread
1
+ Be sure to remember to do the following for releases. (Copy into a GitHub issue)
2
+
3
+ - [ ] CHANGELOG is written for all new changes
4
+ - [ ] README is updated
5
+ - [ ] Samples are updated
6
+ - [ ] `rake doc`
7
+ - [ ] Check `sample_regression_spec.rb` regression tests are all enabled (i.e. `overwrite_sample` is commented out)
8
+ - [ ] Bump version.rb
9
+ - [ ] Do a full rake locally
10
+ - [ ] `rake sanity`, and check visually
11
+ - [ ] Travis is passing on dev branch
12
+ - [ ] Merge master branch
13
+ - [ ] Create GitHub release tag
14
+ - [ ] `gem push pkg/squib-x.y.z.gem`
15
+ - [ ] Github milestone closed
16
+ - [ ] Push `rake doc` to website
17
+ - [ ] Bump version.rb to the next alpha
18
+ - [ ] Publish on BoardGameGeek thread
data/Rakefile CHANGED
@@ -1,99 +1,99 @@
1
- require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
3
- require 'yard'
4
- require 'benchmark'
5
- require 'byebug'
6
-
7
- task default: [:install, :spec]
8
-
9
- # Useful for hooking up with SublimeText.
10
- # e.g. rake sample[basic.rb]
11
- task :run,[:file] => :install do |t, args|
12
- args.with_defaults(file: 'basic.rb')
13
- Dir.chdir('samples') do
14
- args[:file] << ".rb" unless args[:file].end_with? '.rb'
15
- puts "Running samples/#{args[:file]}"
16
- load args[:file]
17
- end
18
- end
19
-
20
-
21
- RSpec::Core::RakeTask.new(:spec)
22
-
23
- RSpec::Core::RakeTask.new(:spec_fastonly) do |t|
24
- t.rspec_opts = "--tag ~slow"
25
- end
26
-
27
- task doc: [:yarddoc, :apply_google_analytics]
28
-
29
- YARD::Rake::YardocTask.new(:yarddoc) do |t|
30
- t.files = ['lib/**/*.rb', 'samples/**/*.rb'] # optional
31
- #t.options = ['--any', '--extra', '--opts'] # optional
32
- end
33
-
34
- task benchmark: [:install] do
35
- require 'squib'
36
- Squib::logger.level = Logger::ERROR #silence warnings
37
- Dir.chdir('benchmarks') do
38
- Benchmark.bm(15) do |bm|
39
- Dir['*.rb'].each do | script |
40
- GC.start
41
- bm.report(script) { load script }
42
- end
43
- end
44
- end
45
- end
46
-
47
- task :sanity do
48
- require_relative 'spec/samples/sanity.rb'
49
- Sanity.new.run
50
- end
51
-
52
- task sanity_clean: [:install, :spec, :sanity]
53
-
54
- task :apply_google_analytics do
55
- # The string to replace in the html document. This is chosen to be the end
56
- # body </body> tag. So the script can be injected as the last thing in the
57
- # document body.
58
- string_to_replace = "</body>"
59
- # This is the string to replace with. It include the google analytics script
60
- # as well as the end </body> tag.
61
- string_to_replace_with = <<-EOF
62
- <script>
63
- (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
64
- (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
65
- m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
66
- })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
67
-
68
- ga('create', 'UA-54811605-1', 'auto');
69
- ga('send', 'pageview');
70
-
71
- </script>
72
- </body>
73
- EOF
74
-
75
- files = Dir.glob("doc/**/*.html")
76
-
77
- files.each do |html_file|
78
- puts "Processing file: #{html_file}"
79
- contents = ""
80
- # Read the file contents
81
- file = File.open(html_file)
82
- file.each { |line| contents << line }
83
- file.close
84
-
85
- # If the file already has google analytics tracking info, skip it.
86
- if contents.include?(string_to_replace_with)
87
- puts "Skipped..."
88
- next
89
- end
90
-
91
- # Apply google analytics tracking info to the html file
92
- contents.gsub!(string_to_replace, string_to_replace_with)
93
-
94
- # Write the contents with the google analytics info to the file
95
- file = File.open(html_file, "w")
96
- file.write(contents)
97
- file.close
98
- end
99
- end
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'yard'
4
+ require 'benchmark'
5
+ require 'byebug'
6
+
7
+ task default: [:install, :spec]
8
+
9
+ # Useful for hooking up with SublimeText.
10
+ # e.g. rake sample[basic.rb]
11
+ task :run,[:file] => :install do |t, args|
12
+ args.with_defaults(file: 'basic.rb')
13
+ Dir.chdir('samples') do
14
+ args[:file] << ".rb" unless args[:file].end_with? '.rb'
15
+ puts "Running samples/#{args[:file]}"
16
+ load args[:file]
17
+ end
18
+ end
19
+
20
+
21
+ RSpec::Core::RakeTask.new(:spec)
22
+
23
+ RSpec::Core::RakeTask.new(:spec_fastonly) do |t|
24
+ t.rspec_opts = "--tag ~slow"
25
+ end
26
+
27
+ task doc: [:yarddoc, :apply_google_analytics]
28
+
29
+ YARD::Rake::YardocTask.new(:yarddoc) do |t|
30
+ t.files = ['lib/**/*.rb', 'samples/**/*.rb'] # optional
31
+ #t.options = ['--any', '--extra', '--opts'] # optional
32
+ end
33
+
34
+ task benchmark: [:install] do
35
+ require 'squib'
36
+ Squib::logger.level = Logger::ERROR #silence warnings
37
+ Dir.chdir('benchmarks') do
38
+ Benchmark.bm(15) do |bm|
39
+ Dir['*.rb'].each do | script |
40
+ GC.start
41
+ bm.report(script) { load script }
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ task :sanity_only do
48
+ require_relative 'spec/samples/sanity.rb'
49
+ Sanity.new.run
50
+ end
51
+
52
+ task sanity: [:install, :spec, :sanity_only]
53
+
54
+ task :apply_google_analytics do
55
+ # The string to replace in the html document. This is chosen to be the end
56
+ # body </body> tag. So the script can be injected as the last thing in the
57
+ # document body.
58
+ string_to_replace = "</body>"
59
+ # This is the string to replace with. It include the google analytics script
60
+ # as well as the end </body> tag.
61
+ string_to_replace_with = <<-EOF
62
+ <script>
63
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
64
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
65
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
66
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
67
+
68
+ ga('create', 'UA-54811605-1', 'auto');
69
+ ga('send', 'pageview');
70
+
71
+ </script>
72
+ </body>
73
+ EOF
74
+
75
+ files = Dir.glob("doc/**/*.html")
76
+
77
+ files.each do |html_file|
78
+ puts "Processing file: #{html_file}"
79
+ contents = ""
80
+ # Read the file contents
81
+ file = File.open(html_file)
82
+ file.each { |line| contents << line }
83
+ file.close
84
+
85
+ # If the file already has google analytics tracking info, skip it.
86
+ if contents.include?(string_to_replace_with)
87
+ puts "Skipped..."
88
+ next
89
+ end
90
+
91
+ # Apply google analytics tracking info to the html file
92
+ contents.gsub!(string_to_replace, string_to_replace_with)
93
+
94
+ # Write the contents with the google analytics info to the file
95
+ file = File.open(html_file, "w")
96
+ file.write(contents)
97
+ file.close
98
+ end
99
+ end
@@ -1,32 +1,32 @@
1
- require 'logger'
2
- require 'cairo'
3
- require 'pango'
4
- require 'rsvg2'
5
- require 'squib/version'
6
- require 'squib/commands/new'
7
- require 'squib/deck'
8
- require 'squib/card'
9
-
10
- module Squib
11
-
12
- # Access the internal logger that Squib uses. By default, Squib configure the logger to the WARN level
13
- # Use this to suppress or increase output levels.
14
- # @example
15
- # Squib.logger.level = Logger::DEBUG #show waaaay more information than you probably need, unless you're a dev
16
- # Squib.logger.level = Logger::ERROR #basically turns it off
17
- #
18
- # @return [Logger] the ruby logger
19
- # @api public
20
- def logger
21
- if @logger.nil?
22
- @logger = Logger.new($stdout);
23
- @logger.level = Logger::WARN;
24
- @logger.formatter = proc do |severity, datetime, m_progname, msg|
25
- "#{datetime} #{severity}: #{msg}\n"
26
- end
27
- end
28
- @logger
29
- end
30
- module_function :logger
31
-
32
- end
1
+ require 'logger'
2
+ require 'cairo'
3
+ require 'pango'
4
+ require 'rsvg2'
5
+ require 'squib/version'
6
+ require 'squib/commands/new'
7
+ require 'squib/deck'
8
+ require 'squib/card'
9
+
10
+ module Squib
11
+
12
+ # Access the internal logger that Squib uses. By default, Squib configure the logger to the WARN level
13
+ # Use this to suppress or increase output levels.
14
+ # @example
15
+ # Squib.logger.level = Logger::DEBUG #show waaaay more information than you probably need, unless you're a dev
16
+ # Squib.logger.level = Logger::ERROR #basically turns it off
17
+ #
18
+ # @return [Logger] the ruby logger
19
+ # @api public
20
+ def logger
21
+ if @logger.nil?
22
+ @logger = Logger.new($stdout)
23
+ @logger.level = Logger::WARN
24
+ @logger.formatter = proc do |severity, datetime, m_progname, msg|
25
+ "#{datetime} #{severity}: #{msg}\n"
26
+ end
27
+ end
28
+ @logger
29
+ end
30
+ module_function :logger
31
+
32
+ end
@@ -1,19 +1,20 @@
1
- module Squib
2
- class Deck
3
- # Fills the background with the given color
4
- # @example
5
- # background color: :white
6
- #
7
- # Options support Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
8
- #
9
- # @option opts range [Enumerable] (:all) the range of cards over which this will be rendered. See {file:README.md#Specifying_Ranges Specifying Ranges}
10
- # @option opts color [String] (:black) the color the font will render to. See {file:README.md#Specifying_Colors___Gradients Specifying Colors & Gradients}.
11
- # @return [nil] nothing
12
- # @api public
13
- def background(opts = {})
14
- opts = needs(opts,[:range, :color])
15
- opts[:range].each { |i| @cards[i].background(opts[:color][i]) }
16
- end
17
-
18
- end
19
- end
1
+ module Squib
2
+ class Deck
3
+ # Fills the background with the given color
4
+ # @example
5
+ # background color: :white
6
+ #
7
+ # Options support Arrays, see {file:README.md#Arrays_and_Singleton_Expansion Arrays and Singleon Expansion}
8
+ #
9
+ # @option opts range [Enumerable] (:all) the range of cards over which this will be rendered. See {file:README.md#Specifying_Ranges Specifying Ranges}
10
+ # @option opts color [String] (:black) the color the font will render to. See {file:README.md#Specifying_Colors___Gradients Specifying Colors & Gradients}.
11
+ # @return [nil] nothing
12
+ # @api public
13
+ def background(opts = {})
14
+ range = Args::CardRange.new(opts[:range], deck_size: size)
15
+ draw = Args::Draw.new(custom_colors).load!(opts, expand_by: size, layout: layout, dpi: dpi)
16
+ range.each { |i| @cards[i].background(draw.color[i]) }
17
+ end
18
+
19
+ end
20
+ end
@@ -1,99 +1,100 @@
1
- require 'roo'
2
- require 'csv'
3
-
4
- module Squib
5
-
6
- # Pulls Excel data from `.xlsx` files into a column-based hash
7
- #
8
- # Pulls the data into a Hash of arrays based on the columns. First row is assumed to be the header row.
9
- # See the example `samples/excel.rb` in the [source repository](https://github.com/andymeneely/squib/tree/master/samples)
10
- #
11
- # @example
12
- # # Excel file looks like this:
13
- # # | h1 | h2 |
14
- # # ------------
15
- # # | 1 | 2 |
16
- # # | 3 | 4 |
17
- # data = xlsx file: 'data.xlsx', sheet: 0
18
- # {'h1' => [1,3], 'h2' => [2,4]}
19
- #
20
- # @option opts file [String] the file to open. Must end in `.xlsx`. Opens relative to the current directory.
21
- # @option opts sheet [Integer] (0) The zero-based index of the sheet from which to read.
22
- # @return [Hash] a hash of arrays based on columns in the spreadsheet
23
- # @api public
24
- def xlsx(opts = {})
25
- opts = Squib::SYSTEM_DEFAULTS.merge(opts)
26
- opts = Squib::InputHelpers.fileify(opts)
27
- s = Roo::Excelx.new(opts[:file])
28
- s.default_sheet = s.sheets[opts[:sheet]]
29
- data = {}
30
- s.first_column.upto(s.last_column) do |col|
31
- header = s.cell(s.first_row,col).to_s
32
- data[header] = []
33
- (s.first_row + 1).upto(s.last_row) do |row|
34
- cell = s.cell(row,col)
35
- # Roo hack for avoiding unnecessary .0's on whole integers (https://github.com/roo-rb/roo/issues/139)
36
- cell = s.excelx_value(row,col) if s.excelx_type(row,col) == [:numeric_or_formula, 'General']
37
- data[header] << cell
38
- end#row
39
- end#col
40
- data
41
- end#xlsx
42
- module_function :xlsx
43
-
44
- # Pulls CSV data from `.csv` files into a column-based hash
45
- #
46
- # Pulls the data into a Hash of arrays based on the columns. First row is assumed to be the header row.
47
- # See the example `samples/csv.rb` in the [source repository](https://github.com/andymeneely/squib/tree/master/samples)
48
- #
49
- # @example
50
- # # File data.csv looks like this (without the comment symbols)
51
- # # h1,h2
52
- # # 1,2
53
- # # 3,4
54
- # data = csv file: 'data.csv'
55
- # => {'h1' => [1,3], 'h2' => [2,4]}
56
- #
57
- # Parsing uses Ruby's CSV, with options `{headers: true, converters: :numeric}`
58
- # http://www.ruby-doc.org/stdlib-2.0/libdoc/csv/rdoc/CSV.html
59
- #
60
- # @option opts file [String] the CSV-formatted file to open. Opens relative to the current directory.
61
- # @return [Hash] a hash of arrays based on columns in the table
62
- # @api public
63
- def csv(opts = {})
64
- opts = Squib::SYSTEM_DEFAULTS.merge(opts)
65
- opts = Squib::InputHelpers.fileify(opts)
66
- table = CSV.read(opts[:file], headers: true, converters: :numeric)
67
- check_duplicate_csv_headers(table)
68
- hash = Hash.new
69
- table.headers.each do |header|
70
- hash[header.to_s] ||= table[header]
71
- end
72
- return hash
73
- end
74
- module_function :csv
75
-
76
- # Check if the given CSV table has duplicate columns, and throw a warning
77
- # @api private
78
- def check_duplicate_csv_headers(table)
79
- if table.headers.size != table.headers.uniq.size
80
- dups = table.headers.select{|e| table.headers.count(e) > 1 }
81
- Squib.logger.warn "CSV duplicated the following column keys: #{dups.join(',')}"
82
- end
83
- end
84
- module_function :check_duplicate_csv_headers
85
-
86
- class Deck
87
-
88
- # Convenience call on deck goes to the module function
89
- def xlsx(opts = {})
90
- Squib.xlsx(opts)
91
- end
92
-
93
- # Convenience call on deck goes to the module function
94
- def csv(opts = {})
95
- Squib.csv(opts)
96
- end
97
-
98
- end
99
- end
1
+ require 'roo'
2
+ require 'csv'
3
+ require 'squib/args/input_file'
4
+
5
+ module Squib
6
+
7
+ # Pulls Excel data from `.xlsx` files into a column-based hash
8
+ #
9
+ # Pulls the data into a Hash of arrays based on the columns. First row is assumed to be the header row.
10
+ # See the example `samples/excel.rb` in the [source repository](https://github.com/andymeneely/squib/tree/master/samples)
11
+ #
12
+ # @example
13
+ # # Excel file looks like this:
14
+ # # | h1 | h2 |
15
+ # # ------------
16
+ # # | 1 | 2 |
17
+ # # | 3 | 4 |
18
+ # data = xlsx file: 'data.xlsx', sheet: 0
19
+ # {'h1' => [1,3], 'h2' => [2,4]}
20
+ #
21
+ # @option opts file [String] the file to open. Must end in `.xlsx`. Opens relative to the current directory.
22
+ # @option opts sheet [Integer] (0) The zero-based index of the sheet from which to read.
23
+ # @return [Hash] a hash of arrays based on columns in the spreadsheet
24
+ # @api public
25
+ def xlsx(opts = {})
26
+ input = Args::InputFile.new(file: 'deck.xlsx').load!(opts)
27
+ s = Roo::Excelx.new(input.file[0])
28
+ s.default_sheet = s.sheets[input.sheet[0]]
29
+ data = {}
30
+ s.first_column.upto(s.last_column) do |col|
31
+ header = s.cell(s.first_row,col).to_s
32
+ data[header] = []
33
+ (s.first_row + 1).upto(s.last_row) do |row|
34
+ cell = s.cell(row,col)
35
+ # Roo hack for avoiding unnecessary .0's on whole integers (https://github.com/roo-rb/roo/issues/139)
36
+ cell = s.excelx_value(row,col) if s.excelx_type(row,col) == [:numeric_or_formula, 'General']
37
+ data[header] << cell
38
+ end#row
39
+ end#col
40
+ data
41
+ end#xlsx
42
+ module_function :xlsx
43
+
44
+ # Pulls CSV data from `.csv` files into a column-based hash
45
+ #
46
+ # Pulls the data into a Hash of arrays based on the columns. First row is assumed to be the header row.
47
+ # See the example `samples/csv.rb` in the [source repository](https://github.com/andymeneely/squib/tree/master/samples)
48
+ #
49
+ # @example
50
+ # # File data.csv looks like this (without the comment symbols)
51
+ # # h1,h2
52
+ # # 1,2
53
+ # # 3,4
54
+ # data = csv file: 'data.csv'
55
+ # => {'h1' => [1,3], 'h2' => [2,4]}
56
+ #
57
+ # Parsing uses Ruby's CSV, with options `{headers: true, converters: :numeric}`
58
+ # http://www.ruby-doc.org/stdlib-2.0/libdoc/csv/rdoc/CSV.html
59
+ #
60
+ # @option opts file [String] the CSV-formatted file to open. Opens relative to the current directory.
61
+ # @return [Hash] a hash of arrays based on columns in the table
62
+ # @api public
63
+ def csv(opts = {})
64
+ file = Args::InputFile.new(file: 'deck.csv').load!(opts).file[0]
65
+ opts = Squib::SYSTEM_DEFAULTS.merge(opts)
66
+ # opts = Squib::InputHelpers.fileify(opts)
67
+ table = CSV.read(file, headers: true, converters: :numeric)
68
+ check_duplicate_csv_headers(table)
69
+ hash = Hash.new
70
+ table.headers.each do |header|
71
+ hash[header.to_s] ||= table[header]
72
+ end
73
+ return hash
74
+ end
75
+ module_function :csv
76
+
77
+ # Check if the given CSV table has duplicate columns, and throw a warning
78
+ # @api private
79
+ def check_duplicate_csv_headers(table)
80
+ if table.headers.size != table.headers.uniq.size
81
+ dups = table.headers.select{|e| table.headers.count(e) > 1 }
82
+ Squib.logger.warn "CSV duplicated the following column keys: #{dups.join(',')}"
83
+ end
84
+ end
85
+ module_function :check_duplicate_csv_headers
86
+
87
+ class Deck
88
+
89
+ # Convenience call on deck goes to the module function
90
+ def xlsx(opts = {})
91
+ Squib.xlsx(opts)
92
+ end
93
+
94
+ # Convenience call on deck goes to the module function
95
+ def csv(opts = {})
96
+ Squib.csv(opts)
97
+ end
98
+
99
+ end
100
+ end