squib 0.14.2 → 0.14.3.pre1

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 (163) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +41 -41
  3. data/.travis.yml +19 -19
  4. data/CHANGELOG.md +366 -357
  5. data/CONTRIBUTING.md +40 -40
  6. data/Gemfile +2 -2
  7. data/LICENSE.txt +22 -22
  8. data/README.md +121 -121
  9. data/RELEASE TODO.md +21 -21
  10. data/Rakefile +48 -48
  11. data/appveyor.yml +24 -24
  12. data/bin/squib +4 -4
  13. data/lib/squib.rb +32 -32
  14. data/lib/squib/api/background.rb +15 -15
  15. data/lib/squib/api/data.rb +137 -137
  16. data/lib/squib/api/groups.rb +54 -54
  17. data/lib/squib/api/image.rb +49 -49
  18. data/lib/squib/api/save.rb +83 -83
  19. data/lib/squib/api/settings.rb +21 -21
  20. data/lib/squib/api/shapes.rb +124 -124
  21. data/lib/squib/api/text.rb +25 -25
  22. data/lib/squib/api/text_embed.rb +71 -71
  23. data/lib/squib/api/units.rb +27 -27
  24. data/lib/squib/args/arg_loader.rb +126 -126
  25. data/lib/squib/args/box.rb +55 -55
  26. data/lib/squib/args/card_range.rb +32 -32
  27. data/lib/squib/args/color_validator.rb +12 -12
  28. data/lib/squib/args/coords.rb +35 -35
  29. data/lib/squib/args/csv_opts.rb +25 -25
  30. data/lib/squib/args/dir_validator.rb +16 -16
  31. data/lib/squib/args/draw.rb +92 -92
  32. data/lib/squib/args/embed_adjust.rb +25 -25
  33. data/lib/squib/args/embed_key.rb +17 -17
  34. data/lib/squib/args/hand_special.rb +37 -37
  35. data/lib/squib/args/import.rb +40 -40
  36. data/lib/squib/args/input_file.rb +37 -37
  37. data/lib/squib/args/paint.rb +44 -44
  38. data/lib/squib/args/paragraph.rb +116 -116
  39. data/lib/squib/args/save_batch.rb +63 -63
  40. data/lib/squib/args/scale_box.rb +53 -53
  41. data/lib/squib/args/sheet.rb +172 -172
  42. data/lib/squib/args/showcase_special.rb +38 -38
  43. data/lib/squib/args/sprue_file.rb +44 -44
  44. data/lib/squib/args/svg_special.rb +37 -37
  45. data/lib/squib/args/transform.rb +61 -61
  46. data/lib/squib/args/typographer.rb +119 -119
  47. data/lib/squib/args/unit_conversion.rb +29 -29
  48. data/lib/squib/builtin/layouts/economy.yml +85 -85
  49. data/lib/squib/builtin/layouts/fantasy.yml +101 -101
  50. data/lib/squib/builtin/layouts/hand.yml +62 -62
  51. data/lib/squib/builtin/layouts/party.yml +94 -94
  52. data/lib/squib/builtin/layouts/playing-card.yml +35 -35
  53. data/lib/squib/builtin/layouts/tuck_box.yml +46 -46
  54. data/lib/squib/builtin/projects/advanced/.gitignore +4 -4
  55. data/lib/squib/builtin/projects/advanced/ABOUT.md +19 -19
  56. data/lib/squib/builtin/projects/advanced/Gemfile +11 -11
  57. data/lib/squib/builtin/projects/advanced/Guardfile +21 -21
  58. data/lib/squib/builtin/projects/advanced/IDEAS.md +22 -22
  59. data/lib/squib/builtin/projects/advanced/PLAYTESTING.md +26 -26
  60. data/lib/squib/builtin/projects/advanced/Rakefile +27 -27
  61. data/lib/squib/builtin/projects/advanced/config.yml +53 -49
  62. data/lib/squib/builtin/projects/advanced/docs/PNP NOTES.md +3 -3
  63. data/lib/squib/builtin/projects/advanced/docs/RULES.md +21 -21
  64. data/lib/squib/builtin/projects/advanced/img/example.svg +60 -60
  65. data/lib/squib/builtin/projects/advanced/layouts/deck.yml +27 -27
  66. data/lib/squib/builtin/projects/advanced/src/deck.rb +34 -34
  67. data/lib/squib/builtin/projects/advanced/src/version.rb +3 -3
  68. data/lib/squib/builtin/projects/basic/.gitignore +4 -4
  69. data/lib/squib/builtin/projects/basic/ABOUT.md +19 -19
  70. data/lib/squib/builtin/projects/basic/Gemfile +3 -3
  71. data/lib/squib/builtin/projects/basic/IDEAS.md +22 -22
  72. data/lib/squib/builtin/projects/basic/PLAYTESTING.md +26 -26
  73. data/lib/squib/builtin/projects/basic/PNP NOTES.md +3 -3
  74. data/lib/squib/builtin/projects/basic/RULES.md +21 -21
  75. data/lib/squib/builtin/projects/basic/Rakefile +7 -7
  76. data/lib/squib/builtin/projects/basic/config.yml +53 -49
  77. data/lib/squib/builtin/projects/basic/deck.rb +6 -6
  78. data/lib/squib/builtin/sprues/a4_euro_card.yml +42 -42
  79. data/lib/squib/builtin/sprues/a4_poker_card_8up.yml +40 -40
  80. data/lib/squib/builtin/sprues/a4_poker_card_9up.yml +42 -42
  81. data/lib/squib/builtin/sprues/a4_usa_card.yml +42 -42
  82. data/lib/squib/builtin/sprues/drivethrucards_1up.yml +10 -10
  83. data/lib/squib/builtin/sprues/letter_poker_card_9up.yml +25 -25
  84. data/lib/squib/builtin/sprues/letter_poker_foldable_8up.yml +52 -52
  85. data/lib/squib/builtin/sprues/printplaygames_18up.yml +68 -68
  86. data/lib/squib/card.rb +75 -75
  87. data/lib/squib/commands/cli.rb +39 -39
  88. data/lib/squib/commands/data/template_option.rb +109 -109
  89. data/lib/squib/commands/make_sprue.rb +275 -275
  90. data/lib/squib/commands/new.rb +77 -77
  91. data/lib/squib/conf.rb +144 -139
  92. data/lib/squib/constants.rb +17 -17
  93. data/lib/squib/deck.rb +116 -116
  94. data/lib/squib/graphics/background.rb +14 -14
  95. data/lib/squib/graphics/cairo_context_wrapper.rb +113 -113
  96. data/lib/squib/graphics/embedding_utils.rb +28 -28
  97. data/lib/squib/graphics/gradient_regex.rb +47 -47
  98. data/lib/squib/graphics/hand.rb +42 -42
  99. data/lib/squib/graphics/image.rb +129 -108
  100. data/lib/squib/graphics/save_doc.rb +61 -61
  101. data/lib/squib/graphics/save_images.rb +52 -52
  102. data/lib/squib/graphics/save_pdf.rb +90 -90
  103. data/lib/squib/graphics/save_sprue.rb +204 -204
  104. data/lib/squib/graphics/shapes.rb +143 -143
  105. data/lib/squib/graphics/showcase.rb +85 -85
  106. data/lib/squib/graphics/text.rb +174 -174
  107. data/lib/squib/import/data_frame.rb +108 -108
  108. data/lib/squib/layout_parser.rb +138 -138
  109. data/lib/squib/progress.rb +38 -38
  110. data/lib/squib/sample_helpers.rb +34 -34
  111. data/lib/squib/sprues/crop_line.rb +28 -28
  112. data/lib/squib/sprues/crop_line_dash.rb +35 -35
  113. data/lib/squib/sprues/invalid_sprue_definition.rb +9 -9
  114. data/lib/squib/sprues/sprue.rb +203 -203
  115. data/lib/squib/sprues/sprue_schema.rb +48 -48
  116. data/lib/squib/version.rb +10 -10
  117. data/samples/autoscale_font/_autoscale_font.rb +29 -29
  118. data/samples/backend/_backend.rb +26 -26
  119. data/samples/basic.rb +19 -19
  120. data/samples/bug256/_bug256.rb +13 -0
  121. data/samples/build_groups/build_groups.rb +36 -36
  122. data/samples/colors/_colors.rb +38 -38
  123. data/samples/colors/_gradients.rb +34 -34
  124. data/samples/config/config_text_markup.rb +20 -20
  125. data/samples/config/custom_config.rb +18 -18
  126. data/samples/data/_csv.rb +33 -33
  127. data/samples/data/_excel.rb +55 -55
  128. data/samples/data/_yaml.rb +12 -12
  129. data/samples/hello_world.rb +6 -6
  130. data/samples/images/_cairo_access.rb +39 -39
  131. data/samples/images/_images.rb +104 -104
  132. data/samples/images/_more_load_images.rb +102 -102
  133. data/samples/intro/01_hello.rb +8 -8
  134. data/samples/intro/02_options.rb +14 -14
  135. data/samples/intro/03_layout.rb +11 -11
  136. data/samples/intro/04_arrays.rb +15 -15
  137. data/samples/intro/05_excel.rb +14 -14
  138. data/samples/layouts/builtin_layouts.rb +97 -97
  139. data/samples/layouts/layouts.rb +71 -71
  140. data/samples/project/src/characters.rb +8 -8
  141. data/samples/project/src/skills.rb +7 -7
  142. data/samples/proofs/_tgc_proofs.rb +16 -16
  143. data/samples/ranges/_ranges.rb +64 -64
  144. data/samples/saves/_hand.rb +23 -23
  145. data/samples/saves/_portrait_landscape.rb +23 -23
  146. data/samples/saves/_save_pdf.rb +29 -29
  147. data/samples/saves/_saves.rb +51 -51
  148. data/samples/saves/_showcase.rb +25 -25
  149. data/samples/shapes/_draw_shapes.rb +60 -60
  150. data/samples/shapes/_proofs.rb +22 -22
  151. data/samples/sprues/_advanced_sprues.rb +24 -24
  152. data/samples/sprues/_builtin_sprues.rb +21 -21
  153. data/samples/sprues/_fold_sheet.rb +27 -27
  154. data/samples/sprues/_hex_tiles.rb +15 -15
  155. data/samples/sprues/_mints.rb +11 -11
  156. data/samples/sprues/_sprue_example.rb +11 -11
  157. data/samples/text/_embed_text.rb +128 -128
  158. data/samples/text/_text.rb +47 -47
  159. data/samples/text/_text_options.rb +102 -102
  160. data/samples/text/bug134.rb +14 -14
  161. data/samples/units/_units.rb +32 -32
  162. data/squib.gemspec +52 -52
  163. metadata +51 -48
@@ -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