squib 0.15.0 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +41 -41
  3. data/.travis.yml +17 -17
  4. data/CHANGELOG.md +387 -382
  5. data/CONTRIBUTING.md +40 -40
  6. data/Dockerfile +25 -25
  7. data/Gemfile +2 -2
  8. data/LICENSE.txt +22 -22
  9. data/README.md +121 -121
  10. data/RELEASE TODO.md +21 -21
  11. data/Rakefile +48 -48
  12. data/appveyor.yml +25 -25
  13. data/bin/squib +4 -4
  14. data/lib/squib.rb +32 -32
  15. data/lib/squib/api/background.rb +15 -15
  16. data/lib/squib/api/data.rb +137 -137
  17. data/lib/squib/api/groups.rb +54 -54
  18. data/lib/squib/api/image.rb +49 -49
  19. data/lib/squib/api/save.rb +83 -83
  20. data/lib/squib/api/settings.rb +21 -21
  21. data/lib/squib/api/shapes.rb +124 -124
  22. data/lib/squib/api/text.rb +25 -25
  23. data/lib/squib/api/text_embed.rb +71 -71
  24. data/lib/squib/api/units.rb +27 -27
  25. data/lib/squib/args/arg_loader.rb +126 -126
  26. data/lib/squib/args/box.rb +55 -55
  27. data/lib/squib/args/card_range.rb +32 -32
  28. data/lib/squib/args/color_validator.rb +12 -12
  29. data/lib/squib/args/coords.rb +35 -35
  30. data/lib/squib/args/csv_opts.rb +25 -25
  31. data/lib/squib/args/dir_validator.rb +16 -16
  32. data/lib/squib/args/draw.rb +92 -92
  33. data/lib/squib/args/embed_adjust.rb +25 -25
  34. data/lib/squib/args/embed_key.rb +17 -17
  35. data/lib/squib/args/hand_special.rb +37 -37
  36. data/lib/squib/args/import.rb +40 -40
  37. data/lib/squib/args/input_file.rb +37 -37
  38. data/lib/squib/args/paint.rb +44 -44
  39. data/lib/squib/args/paragraph.rb +116 -116
  40. data/lib/squib/args/save_batch.rb +63 -63
  41. data/lib/squib/args/scale_box.rb +53 -53
  42. data/lib/squib/args/sheet.rb +172 -172
  43. data/lib/squib/args/showcase_special.rb +41 -41
  44. data/lib/squib/args/sprue_file.rb +44 -44
  45. data/lib/squib/args/svg_special.rb +37 -37
  46. data/lib/squib/args/transform.rb +61 -61
  47. data/lib/squib/args/typographer.rb +119 -119
  48. data/lib/squib/args/unit_conversion.rb +29 -29
  49. data/lib/squib/builtin/layouts/economy.yml +85 -85
  50. data/lib/squib/builtin/layouts/fantasy.yml +101 -101
  51. data/lib/squib/builtin/layouts/hand.yml +62 -62
  52. data/lib/squib/builtin/layouts/party.yml +94 -94
  53. data/lib/squib/builtin/layouts/playing-card.yml +35 -35
  54. data/lib/squib/builtin/layouts/tuck_box.yml +46 -46
  55. data/lib/squib/builtin/projects/advanced/.gitignore +4 -4
  56. data/lib/squib/builtin/projects/advanced/ABOUT.md +19 -19
  57. data/lib/squib/builtin/projects/advanced/Gemfile +11 -11
  58. data/lib/squib/builtin/projects/advanced/Guardfile +21 -21
  59. data/lib/squib/builtin/projects/advanced/IDEAS.md +22 -22
  60. data/lib/squib/builtin/projects/advanced/PLAYTESTING.md +26 -26
  61. data/lib/squib/builtin/projects/advanced/Rakefile +27 -27
  62. data/lib/squib/builtin/projects/advanced/config.yml +49 -49
  63. data/lib/squib/builtin/projects/advanced/docs/PNP NOTES.md +3 -3
  64. data/lib/squib/builtin/projects/advanced/docs/RULES.md +21 -21
  65. data/lib/squib/builtin/projects/advanced/img/example.svg +60 -60
  66. data/lib/squib/builtin/projects/advanced/layouts/deck.yml +27 -27
  67. data/lib/squib/builtin/projects/advanced/src/deck.rb +34 -34
  68. data/lib/squib/builtin/projects/advanced/src/version.rb +3 -3
  69. data/lib/squib/builtin/projects/basic/.gitignore +4 -4
  70. data/lib/squib/builtin/projects/basic/ABOUT.md +19 -19
  71. data/lib/squib/builtin/projects/basic/Gemfile +3 -3
  72. data/lib/squib/builtin/projects/basic/IDEAS.md +22 -22
  73. data/lib/squib/builtin/projects/basic/PLAYTESTING.md +26 -26
  74. data/lib/squib/builtin/projects/basic/PNP NOTES.md +3 -3
  75. data/lib/squib/builtin/projects/basic/RULES.md +21 -21
  76. data/lib/squib/builtin/projects/basic/Rakefile +7 -7
  77. data/lib/squib/builtin/projects/basic/config.yml +49 -49
  78. data/lib/squib/builtin/projects/basic/deck.rb +6 -6
  79. data/lib/squib/builtin/sprues/a4_euro_card.yml +42 -42
  80. data/lib/squib/builtin/sprues/a4_poker_card_8up.yml +40 -40
  81. data/lib/squib/builtin/sprues/a4_poker_card_9up.yml +42 -42
  82. data/lib/squib/builtin/sprues/a4_usa_card.yml +42 -42
  83. data/lib/squib/builtin/sprues/drivethrucards_1up.yml +10 -10
  84. data/lib/squib/builtin/sprues/letter_poker_card_9up.yml +25 -25
  85. data/lib/squib/builtin/sprues/letter_poker_foldable_8up.yml +52 -52
  86. data/lib/squib/builtin/sprues/printplaygames_18up.yml +68 -68
  87. data/lib/squib/card.rb +75 -75
  88. data/lib/squib/commands/cli.rb +39 -39
  89. data/lib/squib/commands/data/template_option.rb +109 -109
  90. data/lib/squib/commands/make_sprue.rb +277 -277
  91. data/lib/squib/commands/new.rb +77 -77
  92. data/lib/squib/conf.rb +139 -139
  93. data/lib/squib/constants.rb +17 -17
  94. data/lib/squib/deck.rb +116 -116
  95. data/lib/squib/graphics/background.rb +14 -14
  96. data/lib/squib/graphics/cairo_context_wrapper.rb +113 -113
  97. data/lib/squib/graphics/embedding_utils.rb +28 -28
  98. data/lib/squib/graphics/gradient_regex.rb +47 -47
  99. data/lib/squib/graphics/hand.rb +42 -42
  100. data/lib/squib/graphics/image.rb +123 -123
  101. data/lib/squib/graphics/save_doc.rb +61 -61
  102. data/lib/squib/graphics/save_images.rb +52 -52
  103. data/lib/squib/graphics/save_pdf.rb +90 -90
  104. data/lib/squib/graphics/save_sprue.rb +219 -219
  105. data/lib/squib/graphics/shapes.rb +143 -143
  106. data/lib/squib/graphics/showcase.rb +85 -85
  107. data/lib/squib/graphics/text.rb +174 -174
  108. data/lib/squib/import/data_frame.rb +108 -108
  109. data/lib/squib/layout_parser.rb +138 -138
  110. data/lib/squib/progress.rb +38 -38
  111. data/lib/squib/sample_helpers.rb +34 -34
  112. data/lib/squib/sprues/crop_line.rb +28 -28
  113. data/lib/squib/sprues/crop_line_dash.rb +35 -35
  114. data/lib/squib/sprues/invalid_sprue_definition.rb +9 -9
  115. data/lib/squib/sprues/sprue.rb +206 -206
  116. data/lib/squib/sprues/sprue_schema.rb +50 -50
  117. data/lib/squib/version.rb +10 -10
  118. data/samples/autoscale_font/_autoscale_font.rb +29 -29
  119. data/samples/backend/_backend.rb +26 -26
  120. data/samples/basic.rb +19 -19
  121. data/samples/build_groups/build_groups.rb +36 -36
  122. data/samples/colors/_colors.rb +44 -44
  123. data/samples/colors/_gradients.rb +34 -34
  124. data/samples/colors/_switch_color.rb +33 -33
  125. data/samples/config/config_text_markup.rb +20 -20
  126. data/samples/config/custom_config.rb +18 -18
  127. data/samples/data/_csv.rb +33 -33
  128. data/samples/data/_excel.rb +55 -55
  129. data/samples/data/_yaml.rb +12 -12
  130. data/samples/hello_world.rb +6 -6
  131. data/samples/images/_cairo_access.rb +39 -39
  132. data/samples/images/_images.rb +104 -104
  133. data/samples/images/_more_load_images.rb +102 -102
  134. data/samples/intro/01_hello.rb +8 -8
  135. data/samples/intro/02_options.rb +14 -14
  136. data/samples/intro/03_layout.rb +11 -11
  137. data/samples/intro/04_arrays.rb +15 -15
  138. data/samples/intro/05_excel.rb +14 -14
  139. data/samples/layouts/builtin_layouts.rb +97 -97
  140. data/samples/layouts/layouts.rb +71 -71
  141. data/samples/project/src/characters.rb +8 -8
  142. data/samples/project/src/skills.rb +7 -7
  143. data/samples/proofs/_tgc_proofs.rb +16 -16
  144. data/samples/ranges/_ranges.rb +64 -64
  145. data/samples/saves/_hand.rb +23 -23
  146. data/samples/saves/_portrait_landscape.rb +23 -23
  147. data/samples/saves/_save_filenames.rb +24 -24
  148. data/samples/saves/_save_pdf.rb +29 -29
  149. data/samples/saves/_saves.rb +51 -51
  150. data/samples/saves/_showcase.rb +25 -25
  151. data/samples/shapes/_draw_shapes.rb +60 -60
  152. data/samples/shapes/_proofs.rb +22 -22
  153. data/samples/sprues/_advanced_sprues.rb +25 -25
  154. data/samples/sprues/_builtin_sprues.rb +21 -21
  155. data/samples/sprues/_fold_sheet.rb +27 -27
  156. data/samples/sprues/_hex_tiles.rb +15 -15
  157. data/samples/sprues/_mints.rb +11 -11
  158. data/samples/sprues/_sprue_example.rb +11 -11
  159. data/samples/text/_embed_text.rb +128 -128
  160. data/samples/text/_text.rb +47 -47
  161. data/samples/text/_text_options.rb +102 -102
  162. data/samples/text/bug134.rb +14 -14
  163. data/samples/units/_units.rb +32 -32
  164. data/squib.gemspec +52 -52
  165. metadata +46 -46
@@ -1,25 +1,25 @@
1
- require_relative 'text_embed'
2
- require_relative '../args/box'
3
- require_relative '../args/card_range'
4
- require_relative '../args/draw'
5
- require_relative '../args/paragraph'
6
-
7
- module Squib
8
- class Deck
9
-
10
- # DSL method. See http://squib.readthedocs.io
11
- def text(opts = {})
12
- range = Args::CardRange.new(opts[:range], deck_size: size)
13
- para = Args::Paragraph.new(font).load!(opts, expand_by: size, layout: layout)
14
- box = Args::Box.new(self, { width: :auto, height: :auto }).load!(opts, expand_by: size, layout: layout, dpi: dpi)
15
- trans = Args::Transform.new.load!(opts, expand_by: size, layout: layout, dpi: dpi)
16
- draw = Args::Draw.new(custom_colors, { stroke_width: 0.0 }).load!(opts, expand_by: size, layout: layout, dpi: dpi)
17
- embed = TextEmbed.new(size, custom_colors, layout, dpi, img_dir)
18
- yield(embed) if block_given? # store the opts for later use
19
- extents = Array.new(@cards.size)
20
- range.each { |i| extents[i] = @cards[i].text(embed, para[i], box[i], trans[i], draw[i], dpi) }
21
- return extents
22
- end
23
-
24
- end
25
- end
1
+ require_relative 'text_embed'
2
+ require_relative '../args/box'
3
+ require_relative '../args/card_range'
4
+ require_relative '../args/draw'
5
+ require_relative '../args/paragraph'
6
+
7
+ module Squib
8
+ class Deck
9
+
10
+ # DSL method. See http://squib.readthedocs.io
11
+ def text(opts = {})
12
+ range = Args::CardRange.new(opts[:range], deck_size: size)
13
+ para = Args::Paragraph.new(font).load!(opts, expand_by: size, layout: layout)
14
+ box = Args::Box.new(self, { width: :auto, height: :auto }).load!(opts, expand_by: size, layout: layout, dpi: dpi)
15
+ trans = Args::Transform.new.load!(opts, expand_by: size, layout: layout, dpi: dpi)
16
+ draw = Args::Draw.new(custom_colors, { stroke_width: 0.0 }).load!(opts, expand_by: size, layout: layout, dpi: dpi)
17
+ embed = TextEmbed.new(size, custom_colors, layout, dpi, img_dir)
18
+ yield(embed) if block_given? # store the opts for later use
19
+ extents = Array.new(@cards.size)
20
+ range.each { |i| extents[i] = @cards[i].text(embed, para[i], box[i], trans[i], draw[i], dpi) }
21
+ return extents
22
+ end
23
+
24
+ end
25
+ end
@@ -1,71 +1,71 @@
1
- require_relative '../args/box'
2
- require_relative '../args/card_range'
3
- require_relative '../args/embed_adjust'
4
- require_relative '../args/embed_key'
5
- require_relative '../args/input_file'
6
- require_relative '../args/paint'
7
- require_relative '../args/transform'
8
-
9
- module Squib
10
- class TextEmbed
11
- # :nodoc:
12
- # @api private
13
- attr_reader :rules
14
-
15
- # :nodoc:
16
- # @api private
17
- def initialize(deck_size, custom_colors, layout, dpi, img_dir)
18
- @deck_size = deck_size
19
- @custom_colors = custom_colors
20
- @layout = layout
21
- @dpi = dpi
22
- @img_dir = img_dir
23
- @rules = {} # store an array of options for later usage
24
- end
25
-
26
- # DSL method. See http://squib.readthedocs.io
27
- def svg(opts = {})
28
- key = Args::EmbedKey.new.validate_key(opts[:key])
29
- range = Args::CardRange.new(opts[:range], deck_size: @deck_size)
30
- paint = Args::Paint.new(@custom_colors).load!(opts, expand_by: @deck_size, layout: @layout)
31
- box = Args::Box.new(self, { width: :native, height: :native }).load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
32
- adjust = Args::EmbedAdjust.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
33
- trans = Args::Transform.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
34
- ifile = Args::InputFile.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
35
- svg_args = Args::SvgSpecial.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
36
- rule = { type: :svg, file: ifile, box: box, paint: paint, trans: trans,
37
- adjust: adjust, svg_args: svg_args }
38
- rule[:draw] = Proc.new do |card, x, y|
39
- i = card.index
40
- b = box[i]
41
- b.x, b.y = x, y
42
- Dir.chdir(@img_dir) do
43
- card.svg(ifile[i].file, svg_args[i], b, paint[i], trans[i])
44
- end
45
- end
46
- @rules[key] = rule
47
- end
48
-
49
- # DSL method. See http://squib.readthedocs.io
50
- def png(opts = {})
51
- key = Args::EmbedKey.new.validate_key(opts[:key])
52
- range = Args::CardRange.new(opts[:range], deck_size: @deck_size)
53
- paint = Args::Paint.new(@custom_colors).load!(opts, expand_by: @deck_size, layout: @layout)
54
- box = Args::Box.new(self, { width: :native, height: :native }).load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
55
- adjust = Args::EmbedAdjust.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
56
- trans = Args::Transform.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
57
- ifile = Args::InputFile.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
58
- rule = { type: :png, file: ifile, box: box, paint: paint, trans: trans, adjust: adjust }
59
- rule[:draw] = Proc.new do |card, x, y|
60
- i = card.index
61
- b = box[i]
62
- b.x, b.y = x, y
63
- Dir.chdir(@img_dir) do
64
- card.png(ifile[i].file, b, paint[i], trans[i])
65
- end
66
- end
67
- @rules[key] = rule
68
- end
69
-
70
- end
71
- end
1
+ require_relative '../args/box'
2
+ require_relative '../args/card_range'
3
+ require_relative '../args/embed_adjust'
4
+ require_relative '../args/embed_key'
5
+ require_relative '../args/input_file'
6
+ require_relative '../args/paint'
7
+ require_relative '../args/transform'
8
+
9
+ module Squib
10
+ class TextEmbed
11
+ # :nodoc:
12
+ # @api private
13
+ attr_reader :rules
14
+
15
+ # :nodoc:
16
+ # @api private
17
+ def initialize(deck_size, custom_colors, layout, dpi, img_dir)
18
+ @deck_size = deck_size
19
+ @custom_colors = custom_colors
20
+ @layout = layout
21
+ @dpi = dpi
22
+ @img_dir = img_dir
23
+ @rules = {} # store an array of options for later usage
24
+ end
25
+
26
+ # DSL method. See http://squib.readthedocs.io
27
+ def svg(opts = {})
28
+ key = Args::EmbedKey.new.validate_key(opts[:key])
29
+ range = Args::CardRange.new(opts[:range], deck_size: @deck_size)
30
+ paint = Args::Paint.new(@custom_colors).load!(opts, expand_by: @deck_size, layout: @layout)
31
+ box = Args::Box.new(self, { width: :native, height: :native }).load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
32
+ adjust = Args::EmbedAdjust.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
33
+ trans = Args::Transform.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
34
+ ifile = Args::InputFile.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
35
+ svg_args = Args::SvgSpecial.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
36
+ rule = { type: :svg, file: ifile, box: box, paint: paint, trans: trans,
37
+ adjust: adjust, svg_args: svg_args }
38
+ rule[:draw] = Proc.new do |card, x, y|
39
+ i = card.index
40
+ b = box[i]
41
+ b.x, b.y = x, y
42
+ Dir.chdir(@img_dir) do
43
+ card.svg(ifile[i].file, svg_args[i], b, paint[i], trans[i])
44
+ end
45
+ end
46
+ @rules[key] = rule
47
+ end
48
+
49
+ # DSL method. See http://squib.readthedocs.io
50
+ def png(opts = {})
51
+ key = Args::EmbedKey.new.validate_key(opts[:key])
52
+ range = Args::CardRange.new(opts[:range], deck_size: @deck_size)
53
+ paint = Args::Paint.new(@custom_colors).load!(opts, expand_by: @deck_size, layout: @layout)
54
+ box = Args::Box.new(self, { width: :native, height: :native }).load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
55
+ adjust = Args::EmbedAdjust.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
56
+ trans = Args::Transform.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
57
+ ifile = Args::InputFile.new.load!(opts, expand_by: @deck_size, layout: @layout, dpi: @dpi)
58
+ rule = { type: :png, file: ifile, box: box, paint: paint, trans: trans, adjust: adjust }
59
+ rule[:draw] = Proc.new do |card, x, y|
60
+ i = card.index
61
+ b = box[i]
62
+ b.x, b.y = x, y
63
+ Dir.chdir(@img_dir) do
64
+ card.png(ifile[i].file, b, paint[i], trans[i])
65
+ end
66
+ end
67
+ @rules[key] = rule
68
+ end
69
+
70
+ end
71
+ end
@@ -1,27 +1,27 @@
1
- require_relative '../constants'
2
-
3
- module Squib
4
- class Deck
5
-
6
- # DSL method. See http://squib.readthedocs.io
7
- def inches(n)
8
- @dpi * n.to_f
9
- end
10
-
11
- # DSL method. See http://squib.readthedocs.io
12
- def points(n)
13
- @dpi / Squib::POINTS_PER_IN * n.to_f
14
- end
15
-
16
- # DSL method. See http://squib.readthedocs.io
17
- def cm(n)
18
- @dpi * Squib::INCHES_IN_CM * n.to_f
19
- end
20
-
21
- # DSL method. See http://squib.readthedocs.io
22
- def mm(n)
23
- @dpi * Squib::INCHES_IN_CM * n.to_f / 10.0
24
- end
25
-
26
- end
27
- end
1
+ require_relative '../constants'
2
+
3
+ module Squib
4
+ class Deck
5
+
6
+ # DSL method. See http://squib.readthedocs.io
7
+ def inches(n)
8
+ @dpi * n.to_f
9
+ end
10
+
11
+ # DSL method. See http://squib.readthedocs.io
12
+ def points(n)
13
+ @dpi / Squib::POINTS_PER_IN * n.to_f
14
+ end
15
+
16
+ # DSL method. See http://squib.readthedocs.io
17
+ def cm(n)
18
+ @dpi * Squib::INCHES_IN_CM * n.to_f
19
+ end
20
+
21
+ # DSL method. See http://squib.readthedocs.io
22
+ def mm(n)
23
+ @dpi * Squib::INCHES_IN_CM * n.to_f / 10.0
24
+ end
25
+
26
+ end
27
+ end
@@ -1,126 +1,126 @@
1
- require_relative '../constants'
2
- require_relative '../conf'
3
- require 'ostruct'
4
-
5
- module Squib
6
- # @api private
7
- module Args
8
-
9
- # Intended to be used a a mix-in,
10
- # For example use see Box as an example
11
- module ArgLoader
12
-
13
- # Main class invoked by the client (i.e. api/ methods)
14
- def load!(args, expand_by: 1, layout: {}, dpi: 300)
15
- Squib.logger.debug { "ARG LOADER: load! for #{self.class}, args: #{args}" }
16
- @dpi = dpi
17
- args[:layout] = prep_layout_args(args[:layout], expand_by: expand_by)
18
- expand_and_set_and_defaultify(args: args, by: expand_by, layout: layout)
19
- validate
20
- convert_units dpi: dpi
21
- self
22
- end
23
-
24
- def expand_and_set_and_defaultify(args: {}, by: 1, layout: {})
25
- attributes = self.class.parameters.keys
26
- attributes.each do |p|
27
- args[p] = defaultify(p, args, layout)
28
- val = if expandable_singleton?(p, args[p])
29
- [args[p]] * by
30
- else
31
- args[p] # not an expanding parameter
32
- end
33
- instance_variable_set "@#{p}", val
34
- end
35
- self.class.class_eval { attr_reader *(attributes) }
36
- end
37
-
38
- # Must be:
39
- # (a) an expanding parameter, and
40
- # (b) a singleton already (i.e. doesn't respond to :each)
41
- def expandable_singleton?(p, arg)
42
- self.class.expanding_parameters.include?(p) && !arg.respond_to?(:each)
43
- end
44
-
45
- # Incorporate defaults and layouts
46
- # (1) Use whatever is specified if it is
47
- # (2) Go over all layout specifications (if any) and look them up
48
- # - Use layout when it's specified for that card
49
- # - Use "default" if no layout was specified, or the layout itself did not specify
50
- # Defaut can be overriden for a given dsl method (@dsl_method_defaults)
51
- # (e.g stroke width is 0.0 for text, non-zero everywhere else)
52
- #
53
- def defaultify(p, args, layout)
54
- return args[p] if args.key? p # arg was specified, no defaults used
55
- defaults = self.class.parameters.merge(@dsl_method_defaults || {})
56
- args[:layout].map do |layout_arg|
57
- return defaults[p] if layout_arg.nil? # no layout specified, use default
58
- unless layout.key? layout_arg.to_s # specified a layout, but it doesn't exist in layout. Oops!
59
- Squib.logger.warn("Layout \"#{layout_arg.to_s}\" does not exist in layout file - using default instead")
60
- return defaults[p]
61
- end
62
- if layout[layout_arg.to_s].key?(p.to_s)
63
- layout[layout_arg.to_s][p.to_s] # param specified in layout
64
- else
65
- defaults[p] # layout specified, but not this param
66
- end
67
- end
68
- end
69
-
70
- # Do singleton expansion on the layout argument as well
71
- # Treated differently since layout is not always specified
72
- def prep_layout_args(layout_args, expand_by: 1)
73
- unless layout_args.respond_to?(:each)
74
- layout_args = [layout_args] * expand_by
75
- end
76
- layout_args || []
77
- end
78
-
79
- # For each parameter/attribute foo we try to invoke a validate_foo
80
- def validate
81
- self.class.parameters.each do |param, default|
82
- method = "validate_#{param}"
83
- if self.respond_to? method
84
- attribute = "@#{param}"
85
- val = instance_variable_get(attribute)
86
- if val.respond_to? :each
87
- new_val = val.map.with_index{ |v, i| send(method, v, i) }
88
- instance_variable_set(attribute, new_val)
89
- else
90
- instance_variable_set(attribute, send(method, val))
91
- end
92
- end
93
- end
94
- end
95
-
96
- # Access an individual arg for a given card
97
- # @return an OpenStruct that looks just like the mixed-in class
98
- # @api private
99
- def [](i)
100
- card_arg = OpenStruct.new
101
- self.class.expanding_parameters.each do |p|
102
- p_val = instance_variable_get("@#{p}")
103
- card_arg[p] = p_val[i]
104
- end
105
- card_arg
106
- end
107
-
108
- # Convert units
109
- def convert_units(dpi: 300)
110
- self.class.params_with_units.each do |p|
111
- p_str = "@#{p}"
112
- p_val = instance_variable_get(p_str)
113
- if p_val.respond_to? :each
114
- arr = p_val.map { |x| UnitConversion.parse(x, dpi) }
115
- instance_variable_set p_str, arr
116
- else
117
- instance_variable_set p_str, UnitConversion.parse(p_val, dpi)
118
- end
119
- end
120
- self
121
- end
122
-
123
- end
124
-
125
- end
126
- end
1
+ require_relative '../constants'
2
+ require_relative '../conf'
3
+ require 'ostruct'
4
+
5
+ module Squib
6
+ # @api private
7
+ module Args
8
+
9
+ # Intended to be used a a mix-in,
10
+ # For example use see Box as an example
11
+ module ArgLoader
12
+
13
+ # Main class invoked by the client (i.e. api/ methods)
14
+ def load!(args, expand_by: 1, layout: {}, dpi: 300)
15
+ Squib.logger.debug { "ARG LOADER: load! for #{self.class}, args: #{args}" }
16
+ @dpi = dpi
17
+ args[:layout] = prep_layout_args(args[:layout], expand_by: expand_by)
18
+ expand_and_set_and_defaultify(args: args, by: expand_by, layout: layout)
19
+ validate
20
+ convert_units dpi: dpi
21
+ self
22
+ end
23
+
24
+ def expand_and_set_and_defaultify(args: {}, by: 1, layout: {})
25
+ attributes = self.class.parameters.keys
26
+ attributes.each do |p|
27
+ args[p] = defaultify(p, args, layout)
28
+ val = if expandable_singleton?(p, args[p])
29
+ [args[p]] * by
30
+ else
31
+ args[p] # not an expanding parameter
32
+ end
33
+ instance_variable_set "@#{p}", val
34
+ end
35
+ self.class.class_eval { attr_reader *(attributes) }
36
+ end
37
+
38
+ # Must be:
39
+ # (a) an expanding parameter, and
40
+ # (b) a singleton already (i.e. doesn't respond to :each)
41
+ def expandable_singleton?(p, arg)
42
+ self.class.expanding_parameters.include?(p) && !arg.respond_to?(:each)
43
+ end
44
+
45
+ # Incorporate defaults and layouts
46
+ # (1) Use whatever is specified if it is
47
+ # (2) Go over all layout specifications (if any) and look them up
48
+ # - Use layout when it's specified for that card
49
+ # - Use "default" if no layout was specified, or the layout itself did not specify
50
+ # Defaut can be overriden for a given dsl method (@dsl_method_defaults)
51
+ # (e.g stroke width is 0.0 for text, non-zero everywhere else)
52
+ #
53
+ def defaultify(p, args, layout)
54
+ return args[p] if args.key? p # arg was specified, no defaults used
55
+ defaults = self.class.parameters.merge(@dsl_method_defaults || {})
56
+ args[:layout].map do |layout_arg|
57
+ return defaults[p] if layout_arg.nil? # no layout specified, use default
58
+ unless layout.key? layout_arg.to_s # specified a layout, but it doesn't exist in layout. Oops!
59
+ Squib.logger.warn("Layout \"#{layout_arg.to_s}\" does not exist in layout file - using default instead")
60
+ return defaults[p]
61
+ end
62
+ if layout[layout_arg.to_s].key?(p.to_s)
63
+ layout[layout_arg.to_s][p.to_s] # param specified in layout
64
+ else
65
+ defaults[p] # layout specified, but not this param
66
+ end
67
+ end
68
+ end
69
+
70
+ # Do singleton expansion on the layout argument as well
71
+ # Treated differently since layout is not always specified
72
+ def prep_layout_args(layout_args, expand_by: 1)
73
+ unless layout_args.respond_to?(:each)
74
+ layout_args = [layout_args] * expand_by
75
+ end
76
+ layout_args || []
77
+ end
78
+
79
+ # For each parameter/attribute foo we try to invoke a validate_foo
80
+ def validate
81
+ self.class.parameters.each do |param, default|
82
+ method = "validate_#{param}"
83
+ if self.respond_to? method
84
+ attribute = "@#{param}"
85
+ val = instance_variable_get(attribute)
86
+ if val.respond_to? :each
87
+ new_val = val.map.with_index{ |v, i| send(method, v, i) }
88
+ instance_variable_set(attribute, new_val)
89
+ else
90
+ instance_variable_set(attribute, send(method, val))
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # Access an individual arg for a given card
97
+ # @return an OpenStruct that looks just like the mixed-in class
98
+ # @api private
99
+ def [](i)
100
+ card_arg = OpenStruct.new
101
+ self.class.expanding_parameters.each do |p|
102
+ p_val = instance_variable_get("@#{p}")
103
+ card_arg[p] = p_val[i]
104
+ end
105
+ card_arg
106
+ end
107
+
108
+ # Convert units
109
+ def convert_units(dpi: 300)
110
+ self.class.params_with_units.each do |p|
111
+ p_str = "@#{p}"
112
+ p_val = instance_variable_get(p_str)
113
+ if p_val.respond_to? :each
114
+ arr = p_val.map { |x| UnitConversion.parse(x, dpi) }
115
+ instance_variable_set p_str, arr
116
+ else
117
+ instance_variable_set p_str, UnitConversion.parse(p_val, dpi)
118
+ end
119
+ end
120
+ self
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+ end