squib 0.18.0 → 0.19.0a

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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +39 -39
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +22 -22
  4. data/.github/ISSUE_TEMPLATE/help-wanted.md +13 -13
  5. data/.github/ISSUE_TEMPLATE/release-todo.md +45 -33
  6. data/.github/PULL_REQUEST_TEMPLATE.md +13 -13
  7. data/.github/workflows/tests.yml +22 -22
  8. data/.gitignore +41 -41
  9. data/.vscode/settings.json +4 -3
  10. data/CHANGELOG.md +460 -460
  11. data/CONTRIBUTING.md +40 -40
  12. data/Dockerfile +27 -27
  13. data/Gemfile +2 -2
  14. data/Guardfile +8 -8
  15. data/LICENSE.txt +22 -22
  16. data/README.md +139 -139
  17. data/Rakefile +51 -51
  18. data/bin/squib +5 -5
  19. data/lib/squib/api/settings.rb +21 -21
  20. data/lib/squib/args/arg_loader.rb +138 -138
  21. data/lib/squib/args/box.rb +59 -59
  22. data/lib/squib/args/card_range.rb +34 -34
  23. data/lib/squib/args/color_validator.rb +7 -7
  24. data/lib/squib/args/coords.rb +49 -49
  25. data/lib/squib/args/csv_opts.rb +22 -22
  26. data/lib/squib/args/dir_validator.rb +11 -11
  27. data/lib/squib/args/draw.rb +93 -93
  28. data/lib/squib/args/drop_shadow.rb +39 -39
  29. data/lib/squib/args/embed_adjust.rb +22 -22
  30. data/lib/squib/args/embed_key.rb +12 -12
  31. data/lib/squib/args/hand_special.rb +37 -37
  32. data/lib/squib/args/import.rb +67 -67
  33. data/lib/squib/args/input_file.rb +55 -55
  34. data/lib/squib/args/paint.rb +43 -43
  35. data/lib/squib/args/paragraph.rb +118 -118
  36. data/lib/squib/args/save_batch.rb +65 -65
  37. data/lib/squib/args/scale_box.rb +57 -57
  38. data/lib/squib/args/sheet.rb +165 -165
  39. data/lib/squib/args/showcase_special.rb +41 -41
  40. data/lib/squib/args/sprue_file.rb +44 -44
  41. data/lib/squib/args/svg_special.rb +37 -37
  42. data/lib/squib/args/transform.rb +55 -55
  43. data/lib/squib/args/typographer.rb +115 -115
  44. data/lib/squib/args/unit_conversion.rb +27 -27
  45. data/lib/squib/args/xywh_shorthands.rb +50 -50
  46. data/lib/squib/builtin/layouts/economy.yml +85 -85
  47. data/lib/squib/builtin/layouts/fantasy.yml +101 -101
  48. data/lib/squib/builtin/layouts/hand.yml +62 -62
  49. data/lib/squib/builtin/layouts/party.yml +94 -94
  50. data/lib/squib/builtin/layouts/playing-card.yml +35 -35
  51. data/lib/squib/builtin/layouts/tuck_box.yml +46 -46
  52. data/lib/squib/builtin/projects/advanced/.gitignore +4 -4
  53. data/lib/squib/builtin/projects/advanced/ABOUT.md +19 -19
  54. data/lib/squib/builtin/projects/advanced/Gemfile +11 -11
  55. data/lib/squib/builtin/projects/advanced/Guardfile +21 -21
  56. data/lib/squib/builtin/projects/advanced/IDEAS.md +22 -22
  57. data/lib/squib/builtin/projects/advanced/PLAYTESTING.md +26 -26
  58. data/lib/squib/builtin/projects/advanced/Rakefile +27 -27
  59. data/lib/squib/builtin/projects/advanced/config.yml +49 -49
  60. data/lib/squib/builtin/projects/advanced/docs/PNP NOTES.md +3 -3
  61. data/lib/squib/builtin/projects/advanced/docs/RULES.md +21 -21
  62. data/lib/squib/builtin/projects/advanced/img/example.svg +60 -60
  63. data/lib/squib/builtin/projects/advanced/layouts/deck.yml +27 -27
  64. data/lib/squib/builtin/projects/advanced/src/deck.rb +34 -34
  65. data/lib/squib/builtin/projects/advanced/src/version.rb +3 -3
  66. data/lib/squib/builtin/projects/basic/.gitignore +4 -4
  67. data/lib/squib/builtin/projects/basic/ABOUT.md +19 -19
  68. data/lib/squib/builtin/projects/basic/Gemfile +3 -3
  69. data/lib/squib/builtin/projects/basic/IDEAS.md +22 -22
  70. data/lib/squib/builtin/projects/basic/PLAYTESTING.md +26 -26
  71. data/lib/squib/builtin/projects/basic/PNP NOTES.md +3 -3
  72. data/lib/squib/builtin/projects/basic/RULES.md +21 -21
  73. data/lib/squib/builtin/projects/basic/Rakefile +7 -7
  74. data/lib/squib/builtin/projects/basic/config.yml +50 -50
  75. data/lib/squib/builtin/projects/basic/deck.rb +6 -6
  76. data/lib/squib/builtin/sprues/a4_euro_card.yml +42 -42
  77. data/lib/squib/builtin/sprues/a4_poker_card_8up.yml +40 -40
  78. data/lib/squib/builtin/sprues/a4_poker_card_9up.yml +42 -42
  79. data/lib/squib/builtin/sprues/a4_usa_card.yml +42 -42
  80. data/lib/squib/builtin/sprues/drivethrucards_1up.yml +10 -10
  81. data/lib/squib/builtin/sprues/letter_poker_card_9up.yml +25 -25
  82. data/lib/squib/builtin/sprues/letter_poker_foldable_8up.yml +52 -52
  83. data/lib/squib/builtin/sprues/printplaygames_18up.yml +68 -68
  84. data/lib/squib/card.rb +75 -75
  85. data/lib/squib/commands/cli.rb +39 -39
  86. data/lib/squib/commands/data/template_option.rb +109 -109
  87. data/lib/squib/commands/make_sprue.rb +277 -277
  88. data/lib/squib/commands/new.rb +77 -77
  89. data/lib/squib/conf.rb +149 -149
  90. data/lib/squib/constants.rb +17 -17
  91. data/lib/squib/deck.rb +138 -138
  92. data/lib/squib/dsl/background.rb +35 -35
  93. data/lib/squib/dsl/circle.rb +39 -39
  94. data/lib/squib/dsl/csv.rb +42 -42
  95. data/lib/squib/dsl/curve.rb +35 -35
  96. data/lib/squib/dsl/cut_zone.rb +47 -47
  97. data/lib/squib/dsl/ellipse.rb +37 -37
  98. data/lib/squib/dsl/grid.rb +35 -35
  99. data/lib/squib/dsl/groups.rb +54 -54
  100. data/lib/squib/dsl/hand.rb +42 -42
  101. data/lib/squib/dsl/line.rb +35 -35
  102. data/lib/squib/dsl/png.rb +57 -57
  103. data/lib/squib/dsl/polygon.rb +36 -36
  104. data/lib/squib/dsl/rect.rb +37 -37
  105. data/lib/squib/dsl/safe_zone.rb +48 -48
  106. data/lib/squib/dsl/save.rb +21 -21
  107. data/lib/squib/dsl/save_pdf.rb +50 -50
  108. data/lib/squib/dsl/save_png.rb +48 -48
  109. data/lib/squib/dsl/save_sheet.rb +53 -53
  110. data/lib/squib/dsl/showcase.rb +43 -43
  111. data/lib/squib/dsl/star.rb +37 -37
  112. data/lib/squib/dsl/svg.rb +63 -63
  113. data/lib/squib/dsl/text.rb +54 -54
  114. data/lib/squib/dsl/text_embed.rb +79 -79
  115. data/lib/squib/dsl/triangle.rb +35 -35
  116. data/lib/squib/dsl/units.rb +37 -37
  117. data/lib/squib/dsl/xlsx.rb +40 -40
  118. data/lib/squib/dsl/yaml.rb +40 -40
  119. data/lib/squib/errors_warnings/warn_unexpected_params.rb +14 -14
  120. data/lib/squib/graphics/background.rb +14 -14
  121. data/lib/squib/graphics/cairo_context_wrapper.rb +115 -115
  122. data/lib/squib/graphics/embedding_utils.rb +28 -28
  123. data/lib/squib/graphics/gradient_regex.rb +47 -47
  124. data/lib/squib/graphics/hand.rb +42 -42
  125. data/lib/squib/graphics/image.rb +123 -123
  126. data/lib/squib/graphics/save_doc.rb +77 -77
  127. data/lib/squib/graphics/save_images.rb +91 -91
  128. data/lib/squib/graphics/save_pdf.rb +90 -90
  129. data/lib/squib/graphics/save_sprue.rb +231 -231
  130. data/lib/squib/graphics/shapes.rb +143 -143
  131. data/lib/squib/graphics/showcase.rb +85 -85
  132. data/lib/squib/graphics/text.rb +202 -202
  133. data/lib/squib/import/csv_importer.rb +45 -45
  134. data/lib/squib/import/data_frame.rb +108 -108
  135. data/lib/squib/import/quantity_exploder.rb +17 -17
  136. data/lib/squib/import/xlsx_importer.rb +28 -28
  137. data/lib/squib/import/yaml_importer.rb +30 -30
  138. data/lib/squib/layout_parser.rb +155 -155
  139. data/lib/squib/progress.rb +38 -38
  140. data/lib/squib/sample_helpers.rb +34 -34
  141. data/lib/squib/sprues/crop_line.rb +28 -28
  142. data/lib/squib/sprues/crop_line_dash.rb +35 -35
  143. data/lib/squib/sprues/invalid_sprue_definition.rb +9 -9
  144. data/lib/squib/sprues/sprue.rb +208 -208
  145. data/lib/squib/sprues/sprue_schema.rb +51 -51
  146. data/lib/squib/system_fonts.rb +16 -16
  147. data/lib/squib/version.rb +11 -11
  148. data/lib/squib.rb +35 -35
  149. data/samples/autoscale_font/_autoscale_font.rb +98 -98
  150. data/samples/backend/_backend.rb +26 -26
  151. data/samples/basic.rb +19 -19
  152. data/samples/build_groups/build_groups.rb +36 -36
  153. data/samples/colors/_colors.rb +44 -44
  154. data/samples/colors/_gradients.rb +34 -34
  155. data/samples/colors/_switch_color.rb +33 -33
  156. data/samples/config/config_text_markup.rb +20 -20
  157. data/samples/config/custom_config.rb +18 -18
  158. data/samples/data/_csv.rb +33 -33
  159. data/samples/data/_excel.rb +55 -55
  160. data/samples/data/_yaml.rb +12 -12
  161. data/samples/hello_world.rb +6 -6
  162. data/samples/images/_cairo_access.rb +39 -39
  163. data/samples/images/_images.rb +104 -104
  164. data/samples/images/_more_load_images.rb +102 -102
  165. data/samples/images/_placeholders.rb +48 -48
  166. data/samples/intro/01_hello.rb +8 -8
  167. data/samples/intro/02_options.rb +14 -14
  168. data/samples/intro/03_layout.rb +11 -11
  169. data/samples/intro/04_arrays.rb +15 -15
  170. data/samples/intro/05_excel.rb +14 -14
  171. data/samples/layouts/builtin_layouts.rb +97 -97
  172. data/samples/layouts/layouts.rb +71 -71
  173. data/samples/project/src/characters.rb +8 -8
  174. data/samples/project/src/skills.rb +7 -7
  175. data/samples/proofs/_tgc_proofs.rb +16 -16
  176. data/samples/ranges/_ranges.rb +64 -64
  177. data/samples/saves/_hand.rb +23 -23
  178. data/samples/saves/_portrait_landscape.rb +23 -23
  179. data/samples/saves/_save_filenames.rb +28 -28
  180. data/samples/saves/_save_pdf.rb +29 -29
  181. data/samples/saves/_saves.rb +75 -75
  182. data/samples/saves/_showcase.rb +25 -25
  183. data/samples/shadows/_shadow.rb +71 -71
  184. data/samples/shapes/_draw_shapes.rb +60 -60
  185. data/samples/shapes/_proofs.rb +22 -22
  186. data/samples/sprues/_advanced_sprues.rb +25 -25
  187. data/samples/sprues/_builtin_sprues.rb +22 -22
  188. data/samples/sprues/_fold_sheet.rb +30 -30
  189. data/samples/sprues/_hex_tiles.rb +15 -15
  190. data/samples/sprues/_mints.rb +11 -11
  191. data/samples/sprues/_negative_coords.rb +6 -6
  192. data/samples/sprues/_sprue_example.rb +11 -11
  193. data/samples/system_font_debug/_list_fonts.rb +14 -14
  194. data/samples/text/_embed_text.rb +128 -128
  195. data/samples/text/_text.rb +52 -52
  196. data/samples/text/_text_options.rb +103 -103
  197. data/samples/text/bug134.rb +14 -14
  198. data/samples/units/_cells.rb +50 -50
  199. data/samples/units/_shorthands.rb +48 -48
  200. data/samples/units/_units.rb +39 -39
  201. data/squib.gemspec +58 -58
  202. metadata +21 -21
@@ -1,108 +1,108 @@
1
- # encoding: UTF-8
2
-
3
- require 'json'
4
- require 'forwardable'
5
-
6
- module Squib
7
- class DataFrame
8
- include Enumerable
9
-
10
- def initialize(hash = {}, def_columns = true)
11
- @hash = hash
12
- columns.each { |col| def_column(col) } if def_columns
13
- end
14
-
15
- def each(&block)
16
- @hash.each(&block)
17
- end
18
-
19
- def [](i)
20
- @hash[i]
21
- end
22
-
23
- def []=(col, v)
24
- @hash[col] = v
25
- def_column(col)
26
- return v
27
- end
28
-
29
- def columns
30
- @hash.keys
31
- end
32
-
33
- def ncolumns
34
- @hash.keys.size
35
- end
36
-
37
- def col?(col)
38
- @hash.key? col
39
- end
40
-
41
- def row(i)
42
- @hash.inject(Hash.new) { |ret, (name, arr)| ret[name] = arr[i]; ret }
43
- end
44
-
45
- def nrows
46
- @hash.inject(0) { |max, (_n, col)| col.size > max ? col.size : max }
47
- end
48
-
49
- def to_json
50
- @hash.to_json
51
- end
52
-
53
- def to_pretty_json
54
- JSON.pretty_generate(@hash)
55
- end
56
-
57
- def to_h
58
- @hash
59
- end
60
-
61
- def to_pretty_text
62
- max_col = columns.inject(0) { |max, c | c.length > max ? c.length : max }
63
- top = " ╭#{'-' * 36}╮\n"
64
- bottom = " ╰#{'-' * 36}╯\n"
65
- str = ''
66
- 0.upto(nrows - 1) do | i |
67
- str += (' ' * max_col) + top
68
- row(i).each do |col, data|
69
- str += "#{col.rjust(max_col)} #{wrap_n_pad(data, max_col)}"
70
- end
71
- str += (' ' * max_col) + bottom
72
- end
73
- return str
74
- end
75
-
76
- private
77
-
78
- def snake_case(str)
79
- str.to_s.
80
- strip.
81
- gsub(/\s+/,'_').
82
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
83
- gsub(/([a-z]+)([A-Z])/,'\1_\2').
84
- downcase.
85
- to_sym
86
- end
87
-
88
- def wrap_n_pad(str, max_col)
89
- new_str = str.to_s + ' ' # handle nil & empty strings
90
- new_str = new_str.
91
- scan(/.{1,34}/). # break down
92
- map { |s| (' ' * max_col) + " | " + s.ljust(34) }.
93
- join(" |\n").
94
- lstrip # initially no whitespace next to key
95
- return new_str + " |\n"
96
- end
97
-
98
- def def_column(col)
99
- raise "Column #{col} - does not exist" unless @hash.key? col
100
- method_name = snake_case(col)
101
- return if self.class.method_defined?(method_name) #warn people? or skip?
102
- define_singleton_method method_name do
103
- @hash[col]
104
- end
105
- end
106
-
107
- end
108
- end
1
+ # encoding: UTF-8
2
+
3
+ require 'json'
4
+ require 'forwardable'
5
+
6
+ module Squib
7
+ class DataFrame
8
+ include Enumerable
9
+
10
+ def initialize(hash = {}, def_columns = true)
11
+ @hash = hash
12
+ columns.each { |col| def_column(col) } if def_columns
13
+ end
14
+
15
+ def each(&block)
16
+ @hash.each(&block)
17
+ end
18
+
19
+ def [](i)
20
+ @hash[i]
21
+ end
22
+
23
+ def []=(col, v)
24
+ @hash[col] = v
25
+ def_column(col)
26
+ return v
27
+ end
28
+
29
+ def columns
30
+ @hash.keys
31
+ end
32
+
33
+ def ncolumns
34
+ @hash.keys.size
35
+ end
36
+
37
+ def col?(col)
38
+ @hash.key? col
39
+ end
40
+
41
+ def row(i)
42
+ @hash.inject(Hash.new) { |ret, (name, arr)| ret[name] = arr[i]; ret }
43
+ end
44
+
45
+ def nrows
46
+ @hash.inject(0) { |max, (_n, col)| col.size > max ? col.size : max }
47
+ end
48
+
49
+ def to_json
50
+ @hash.to_json
51
+ end
52
+
53
+ def to_pretty_json
54
+ JSON.pretty_generate(@hash)
55
+ end
56
+
57
+ def to_h
58
+ @hash
59
+ end
60
+
61
+ def to_pretty_text
62
+ max_col = columns.inject(0) { |max, c | c.length > max ? c.length : max }
63
+ top = " ╭#{'-' * 36}╮\n"
64
+ bottom = " ╰#{'-' * 36}╯\n"
65
+ str = ''
66
+ 0.upto(nrows - 1) do | i |
67
+ str += (' ' * max_col) + top
68
+ row(i).each do |col, data|
69
+ str += "#{col.rjust(max_col)} #{wrap_n_pad(data, max_col)}"
70
+ end
71
+ str += (' ' * max_col) + bottom
72
+ end
73
+ return str
74
+ end
75
+
76
+ private
77
+
78
+ def snake_case(str)
79
+ str.to_s.
80
+ strip.
81
+ gsub(/\s+/,'_').
82
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
83
+ gsub(/([a-z]+)([A-Z])/,'\1_\2').
84
+ downcase.
85
+ to_sym
86
+ end
87
+
88
+ def wrap_n_pad(str, max_col)
89
+ new_str = str.to_s + ' ' # handle nil & empty strings
90
+ new_str = new_str.
91
+ scan(/.{1,34}/). # break down
92
+ map { |s| (' ' * max_col) + " | " + s.ljust(34) }.
93
+ join(" |\n").
94
+ lstrip # initially no whitespace next to key
95
+ return new_str + " |\n"
96
+ end
97
+
98
+ def def_column(col)
99
+ raise "Column #{col} - does not exist" unless @hash.key? col
100
+ method_name = snake_case(col)
101
+ return if self.class.method_defined?(method_name) #warn people? or skip?
102
+ define_singleton_method method_name do
103
+ @hash[col]
104
+ end
105
+ end
106
+
107
+ end
108
+ end
@@ -1,18 +1,18 @@
1
- module Squib
2
- module Import
3
- module QuantityExploder
4
- def explode_quantities(data, qty)
5
- return data unless data.col? qty.to_s.strip
6
- qtys = data[qty]
7
- new_data = Squib::DataFrame.new
8
- data.each do |col, arr|
9
- new_data[col] = []
10
- qtys.each_with_index do |qty, index|
11
- qty.to_i.times { new_data[col] << arr[index] }
12
- end
13
- end
14
- return new_data
15
- end
16
- end
17
- end
1
+ module Squib
2
+ module Import
3
+ module QuantityExploder
4
+ def explode_quantities(data, qty)
5
+ return data unless data.col? qty.to_s.strip
6
+ qtys = data[qty]
7
+ new_data = Squib::DataFrame.new
8
+ data.each do |col, arr|
9
+ new_data[col] = []
10
+ qtys.each_with_index do |qty, index|
11
+ qty.to_i.times { new_data[col] << arr[index] }
12
+ end
13
+ end
14
+ return new_data
15
+ end
16
+ end
17
+ end
18
18
  end
@@ -1,28 +1,28 @@
1
- autoload :Roo, 'roo'
2
- require_relative 'quantity_exploder'
3
-
4
- module Squib::Import
5
- class XlsxImporter
6
- include Squib::Import::QuantityExploder
7
- def import_to_dataframe(import, &block)
8
- s = Roo::Excelx.new(import.file)
9
- s.default_sheet = s.sheets[import.sheet]
10
- data = Squib::DataFrame.new
11
- s.first_column.upto(s.last_column) do |col|
12
- header = s.cell(s.first_row, col).to_s
13
- header = header.strip if import.strip?
14
- data[header] = []
15
- (s.first_row + 1).upto(s.last_row) do |row|
16
- cell = s.cell(row, col)
17
- # Roo hack for avoiding unnecessary .0's on whole integers (https://github.com/roo-rb/roo/issues/139)
18
- cell = s.excelx_value(row, col) if s.excelx_type(row, col) == [:numeric_or_formula, 'General']
19
- cell = cell.strip if cell.respond_to?(:strip) && import.strip?
20
- cell = block.yield(header, cell) unless block.nil?
21
- data[header] << cell
22
- end# row
23
- end# col
24
- explode_quantities(data, import.explode)
25
- end
26
- end
27
- end
28
-
1
+ autoload :Roo, 'roo'
2
+ require_relative 'quantity_exploder'
3
+
4
+ module Squib::Import
5
+ class XlsxImporter
6
+ include Squib::Import::QuantityExploder
7
+ def import_to_dataframe(import, &block)
8
+ s = Roo::Excelx.new(import.file)
9
+ s.default_sheet = s.sheets[import.sheet]
10
+ data = Squib::DataFrame.new
11
+ s.first_column.upto(s.last_column) do |col|
12
+ header = s.cell(s.first_row, col).to_s
13
+ header = header.strip if import.strip?
14
+ data[header] = []
15
+ (s.first_row + 1).upto(s.last_row) do |row|
16
+ cell = s.cell(row, col)
17
+ # Roo hack for avoiding unnecessary .0's on whole integers (https://github.com/roo-rb/roo/issues/139)
18
+ cell = s.excelx_value(row, col) if s.excelx_type(row, col) == [:numeric_or_formula, 'General']
19
+ cell = cell.strip if cell.respond_to?(:strip) && import.strip?
20
+ cell = block.yield(header, cell) unless block.nil?
21
+ data[header] << cell
22
+ end# row
23
+ end# col
24
+ explode_quantities(data, import.explode)
25
+ end
26
+ end
27
+ end
28
+
@@ -1,30 +1,30 @@
1
- require 'yaml'
2
- require_relative 'data_frame'
3
- require_relative 'quantity_exploder'
4
-
5
- module Squib::Import
6
- class YamlImporter
7
- include Squib::Import::QuantityExploder
8
- def import_to_dataframe(import, &block)
9
- data = import.data.nil? ? File.read(import.file) : import.data
10
- yml = YAML.load(data)
11
- data = Squib::DataFrame.new
12
- # Get a universal list of keys to ensure everything is covered.
13
- keys = yml.map { |c| c.keys}.flatten.uniq
14
- keys.each { |k| data[k] = [] } #init arrays
15
- yml.each do |card|
16
- # nil value if key isn't set.
17
- keys.each { |k| data[k] << card[k] }
18
- end
19
- unless block.nil?
20
- data.each do |header, col|
21
- col.map! do |val|
22
- block.yield(header, val)
23
- end
24
- end
25
- end
26
- explode_quantities(data, import.explode)
27
- end
28
- end
29
- end
30
-
1
+ require 'yaml'
2
+ require_relative 'data_frame'
3
+ require_relative 'quantity_exploder'
4
+
5
+ module Squib::Import
6
+ class YamlImporter
7
+ include Squib::Import::QuantityExploder
8
+ def import_to_dataframe(import, &block)
9
+ data = import.data.nil? ? File.read(import.file) : import.data
10
+ yml = YAML.load(data)
11
+ data = Squib::DataFrame.new
12
+ # Get a universal list of keys to ensure everything is covered.
13
+ keys = yml.map { |c| c.keys}.flatten.uniq
14
+ keys.each { |k| data[k] = [] } #init arrays
15
+ yml.each do |card|
16
+ # nil value if key isn't set.
17
+ keys.each { |k| data[k] << card[k] }
18
+ end
19
+ unless block.nil?
20
+ data.each do |header, col|
21
+ col.map! do |val|
22
+ block.yield(header, val)
23
+ end
24
+ end
25
+ end
26
+ explode_quantities(data, import.explode)
27
+ end
28
+ end
29
+ end
30
+