squib 0.15.3 → 0.16.0.pre.preview1

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests.yml +22 -0
  3. data/CHANGELOG.md +22 -0
  4. data/Dockerfile +18 -16
  5. data/Guardfile +8 -0
  6. data/README.md +3 -9
  7. data/RELEASE TODO.md +1 -0
  8. data/Rakefile +3 -0
  9. data/lib/squib.rb +3 -1
  10. data/lib/squib/args/arg_loader.rb +109 -106
  11. data/lib/squib/args/box.rb +52 -48
  12. data/lib/squib/args/card_range.rb +26 -24
  13. data/lib/squib/args/color_validator.rb +4 -9
  14. data/lib/squib/args/coords.rb +39 -25
  15. data/lib/squib/args/csv_opts.rb +13 -16
  16. data/lib/squib/args/dir_validator.rb +7 -12
  17. data/lib/squib/args/draw.rb +69 -68
  18. data/lib/squib/args/embed_adjust.rb +12 -15
  19. data/lib/squib/args/embed_key.rb +6 -11
  20. data/lib/squib/args/hand_special.rb +25 -25
  21. data/lib/squib/args/import.rb +54 -27
  22. data/lib/squib/args/input_file.rb +22 -26
  23. data/lib/squib/args/paint.rb +30 -31
  24. data/lib/squib/args/paragraph.rb +95 -93
  25. data/lib/squib/args/save_batch.rb +50 -48
  26. data/lib/squib/args/scale_box.rb +43 -39
  27. data/lib/squib/args/sheet.rb +147 -149
  28. data/lib/squib/args/showcase_special.rb +32 -32
  29. data/lib/squib/args/sprue_file.rb +30 -30
  30. data/lib/squib/args/svg_special.rb +26 -26
  31. data/lib/squib/args/transform.rb +48 -54
  32. data/lib/squib/args/typographer.rb +88 -92
  33. data/lib/squib/args/unit_conversion.rb +6 -8
  34. data/lib/squib/args/xywh_shorthands.rb +56 -0
  35. data/lib/squib/builtin/projects/advanced/config.yml +4 -3
  36. data/lib/squib/builtin/projects/basic/config.yml +4 -3
  37. data/lib/squib/conf.rb +5 -0
  38. data/lib/squib/deck.rb +34 -12
  39. data/lib/squib/dsl/background.rb +35 -0
  40. data/lib/squib/dsl/circle.rb +39 -0
  41. data/lib/squib/dsl/csv.rb +42 -0
  42. data/lib/squib/dsl/curve.rb +35 -0
  43. data/lib/squib/dsl/cut_zone.rb +47 -0
  44. data/lib/squib/dsl/ellipse.rb +37 -0
  45. data/lib/squib/dsl/grid.rb +35 -0
  46. data/lib/squib/{api → dsl}/groups.rb +0 -0
  47. data/lib/squib/dsl/hand.rb +42 -0
  48. data/lib/squib/dsl/line.rb +35 -0
  49. data/lib/squib/dsl/png.rb +56 -0
  50. data/lib/squib/dsl/polygon.rb +36 -0
  51. data/lib/squib/dsl/rect.rb +37 -0
  52. data/lib/squib/dsl/safe_zone.rb +48 -0
  53. data/lib/squib/dsl/save.rb +21 -0
  54. data/lib/squib/dsl/save_pdf.rb +50 -0
  55. data/lib/squib/dsl/save_png.rb +47 -0
  56. data/lib/squib/dsl/save_sheet.rb +53 -0
  57. data/lib/squib/dsl/showcase.rb +43 -0
  58. data/lib/squib/dsl/star.rb +37 -0
  59. data/lib/squib/dsl/svg.rb +62 -0
  60. data/lib/squib/dsl/text.rb +54 -0
  61. data/lib/squib/dsl/text_embed.rb +78 -0
  62. data/lib/squib/dsl/triangle.rb +35 -0
  63. data/lib/squib/{api → dsl}/units.rb +10 -0
  64. data/lib/squib/dsl/xlsx.rb +40 -0
  65. data/lib/squib/dsl/yaml.rb +40 -0
  66. data/lib/squib/errors_warnings/warn_unexpected_params.rb +14 -0
  67. data/lib/squib/graphics/save_images.rb +3 -3
  68. data/lib/squib/graphics/save_sprue.rb +14 -2
  69. data/lib/squib/graphics/text.rb +37 -9
  70. data/lib/squib/import/csv_importer.rb +45 -0
  71. data/lib/squib/import/quantity_exploder.rb +18 -0
  72. data/lib/squib/import/xlsx_importer.rb +28 -0
  73. data/lib/squib/import/yaml_importer.rb +30 -0
  74. data/lib/squib/layout_parser.rb +24 -7
  75. data/lib/squib/sprues/crop_line.rb +6 -6
  76. data/lib/squib/sprues/crop_line_dash.rb +6 -6
  77. data/lib/squib/sprues/sprue.rb +16 -14
  78. data/lib/squib/version.rb +1 -1
  79. data/samples/autoscale_font/_autoscale_font.rb +77 -8
  80. data/samples/colors/_switch_color.rb +2 -2
  81. data/samples/data/_excel.rb +1 -1
  82. data/samples/ranges/_ranges.rb +1 -1
  83. data/samples/saves/_save_filenames.rb +4 -0
  84. data/samples/saves/_save_pdf.rb +1 -1
  85. data/samples/saves/_saves.rb +2 -1
  86. data/samples/shapes/_draw_shapes.rb +2 -2
  87. data/samples/sprues/_builtin_sprues.rb +1 -0
  88. data/samples/sprues/_fold_sheet.rb +4 -1
  89. data/samples/text/_text.rb +6 -1
  90. data/samples/text/_text_options.rb +2 -1
  91. data/samples/units/_cells.rb +51 -0
  92. data/samples/units/_shorthands.rb +49 -0
  93. data/samples/units/_units.rb +7 -0
  94. data/squib.gemspec +11 -5
  95. metadata +120 -33
  96. data/.travis.yml +0 -17
  97. data/appveyor.yml +0 -25
  98. data/lib/squib/api/background.rb +0 -15
  99. data/lib/squib/api/data.rb +0 -137
  100. data/lib/squib/api/image.rb +0 -49
  101. data/lib/squib/api/save.rb +0 -83
  102. data/lib/squib/api/shapes.rb +0 -124
  103. data/lib/squib/api/text.rb +0 -25
  104. data/lib/squib/api/text_embed.rb +0 -71
@@ -1,40 +1,67 @@
1
- require_relative 'arg_loader'
1
+ module Squib::Args
2
+ module_function def extract_import(opts)
3
+ # note how we don't use ArgLoader here because it's way more complex than
4
+ # what we need here. Don't need layouts or singleton expansion, so...
5
+ # ...let's just do it ourselves.
6
+ Import.parameters.each { |p, value| opts[p] = value unless opts.key? p }
7
+ return Import.new.load! opts
8
+ end
2
9
 
3
- module Squib
4
- # @api private
5
- module Args
10
+ class Import
11
+
12
+ def self.parameters
13
+ {
14
+ data: nil,
15
+ explode: 'qty',
16
+ file: nil,
17
+ sheet: 0,
18
+ strip: true,
19
+ }
20
+ end
6
21
 
7
- class Import
8
- include ArgLoader
22
+ attr_accessor *(self.parameters.keys)
9
23
 
10
- def self.parameters
11
- { strip: true,
12
- explode: 'qty'
13
- }
14
- end
24
+ def self.expanding_parameters
25
+ [] # none of them
26
+ end
15
27
 
16
- def self.expanding_parameters
17
- [] # none of them
18
- end
28
+ def self.params_with_units
29
+ [] # none of them
30
+ end
19
31
 
20
- def self.params_with_units
21
- [] # none of them
22
- end
32
+ def load!(opts)
33
+ @strip = validate_strip opts[:strip]
34
+ @explode = validate_explode opts[:explode]
35
+ @file = validate_file opts[:file]
36
+ @data = validate_data opts[:data]
37
+ @sheet = opts[:sheet]
38
+ return self
39
+ end
23
40
 
24
- def validate_strip(arg)
25
- raise 'Strip must be true or false' unless arg == true || arg == false
26
- arg
27
- end
41
+ def validate_strip(arg)
42
+ raise 'Strip must be true or false' unless arg == true || arg == false
43
+ arg
44
+ end
28
45
 
29
- def validate_explode(arg)
30
- arg
31
- end
46
+ def validate_explode(arg)
47
+ arg.to_s
48
+ end
32
49
 
33
- def strip?
34
- strip
35
- end
50
+ def validate_file(arg)
51
+ return nil if arg.nil?
52
+ raise "File #{File.expand_path(arg)} does not exist!" unless File.exists?(arg)
53
+ File.expand_path(arg)
54
+ end
36
55
 
56
+ def strip?
57
+ strip
58
+ end
59
+
60
+ def validate_data(arg)
61
+ return nil if arg.nil?
62
+ arg.to_s
37
63
  end
38
64
 
39
65
  end
66
+
40
67
  end
@@ -1,37 +1,33 @@
1
1
  require_relative 'arg_loader'
2
2
 
3
- module Squib
4
- # @api private
5
- module Args
6
-
7
- class InputFile
8
- include ArgLoader
9
-
10
- def initialize(dsl_method_default = {})
11
- @dsl_method_default = dsl_method_default
12
- end
3
+ module Squib::Args
4
+ module_function def extract_input_file(opts, deck, dsl_method_default = {})
5
+ InputFile.new(dsl_method_default).extract!(opts, deck)
6
+ end
13
7
 
14
- def self.parameters
15
- { file: nil,
16
- sheet: 0,
17
- }
18
- end
8
+ class InputFile
9
+ include ArgLoader
19
10
 
20
- def self.expanding_parameters
21
- parameters.keys # all of them
22
- end
11
+ def initialize(dsl_method_default = {})
12
+ @dsl_method_default = dsl_method_default
13
+ end
23
14
 
24
- def self.params_with_units
25
- [] # none of them
26
- end
15
+ def self.parameters
16
+ { file: nil }
17
+ end
27
18
 
28
- def validate_file(arg, _i)
29
- return nil if arg.nil?
30
- raise "File #{File.expand_path(arg)} does not exist!" unless File.exists?(arg)
31
- File.expand_path(arg)
32
- end
19
+ def self.expanding_parameters
20
+ parameters.keys # all of them
21
+ end
33
22
 
23
+ def self.params_with_units
24
+ [] # none of them
34
25
  end
35
26
 
27
+ def validate_file(arg, _i)
28
+ return nil if arg.nil?
29
+ raise "File #{File.expand_path(arg)} does not exist!" unless File.exists?(arg)
30
+ File.expand_path(arg)
31
+ end
36
32
  end
37
33
  end
@@ -2,43 +2,42 @@ require 'cairo'
2
2
  require_relative 'arg_loader'
3
3
  require_relative 'color_validator'
4
4
 
5
- module Squib
6
- # @api private
7
- module Args
8
- class Paint
9
- include ArgLoader
10
- include ColorValidator
11
-
12
- def self.parameters
13
- { alpha: 1.0,
14
- blend: :none,
15
- mask: nil,
16
- }
17
- end
18
-
19
-
20
- def self.expanding_parameters
21
- parameters.keys # all of them are expandable
22
- end
5
+ module Squib::Args
6
+ module_function def extract_paint(opts, deck)
7
+ Paint.new(deck.custom_colors).extract!(opts, deck)
8
+ end
9
+
10
+ class Paint
11
+ include ArgLoader
12
+ include ColorValidator
23
13
 
24
- def self.params_with_units
25
- []
26
- end
14
+ def initialize(custom_colors)
15
+ @custom_colors = custom_colors
16
+ end
27
17
 
28
- def initialize(custom_colors)
29
- @custom_colors = custom_colors
30
- end
18
+ def self.parameters
19
+ { alpha: 1.0,
20
+ blend: :none,
21
+ mask: nil,
22
+ }
23
+ end
31
24
 
32
- def validate_alpha(arg, _i)
33
- raise 'alpha must respond to to_f' unless arg.respond_to? :to_f
34
- arg.to_f
35
- end
25
+ def self.expanding_parameters
26
+ parameters.keys # all of them are expandable
27
+ end
36
28
 
37
- def validate_mask(arg, _i)
38
- colorify(arg, @custom_colors)
39
- end
29
+ def self.params_with_units
30
+ []
31
+ end
40
32
 
33
+ def validate_alpha(arg, _i)
34
+ raise 'alpha must respond to to_f' unless arg.respond_to? :to_f
35
+ arg.to_f
36
+ end
41
37
 
38
+ def validate_mask(arg, _i)
39
+ colorify(arg, @custom_colors)
42
40
  end
41
+
43
42
  end
44
43
  end
@@ -1,116 +1,118 @@
1
1
  require_relative '../constants'
2
2
  require_relative 'arg_loader'
3
3
 
4
- module Squib
5
- # @api private
6
- module Args
7
-
8
- class Paragraph
9
- include ArgLoader
10
-
11
-
12
- def self.parameters
13
- { align: :left,
14
- str: 'Hello, World!',
15
- font: :use_set,
16
- font_size: nil,
17
- markup: false,
18
- justify: false,
19
- wrap: true,
20
- ellipsize: :end,
21
- spacing: nil,
22
- valign: :top,
23
- hint: :off
24
- }
25
- end
4
+ module Squib::Args
26
5
 
27
- def self.expanding_parameters
28
- parameters.keys # all of them
29
- end
6
+ module_function def extract_para(opts, deck, dsl_method_defaults = {})
7
+ Paragraph.new(deck.font).extract!(opts, deck)
8
+ end
30
9
 
31
- def self.params_with_units
32
- [] # none of them
33
- end
10
+ class Paragraph
11
+ include ArgLoader
12
+
13
+ def self.parameters
14
+ { align: :left,
15
+ str: 'Hello, World!',
16
+ font: :use_set,
17
+ font_size: nil,
18
+ markup: false,
19
+ justify: false,
20
+ wrap: true,
21
+ ellipsize: :end,
22
+ spacing: nil,
23
+ valign: :top,
24
+ hint: :off
25
+ }
26
+ end
34
27
 
35
- def initialize(deck_font)
36
- @deck_font = deck_font
37
- end
28
+ def self.expanding_parameters
29
+ parameters.keys # all of them
30
+ end
38
31
 
39
- def validate_str(arg, _i)
40
- arg.to_s
41
- end
32
+ def self.params_with_units
33
+ [] # none of them
34
+ end
42
35
 
43
- def validate_font(arg, _i)
44
- arg = @deck_font if arg == :use_set
45
- arg = DEFAULT_FONT if arg == :default
46
- arg
47
- end
36
+ def initialize(deck_font)
37
+ @deck_font = deck_font
38
+ end
48
39
 
49
- def validate_align(arg, _i)
50
- case arg.to_s.downcase.strip
51
- when 'left'
52
- Pango::Alignment::LEFT
53
- when 'right'
54
- Pango::Alignment::RIGHT
55
- when 'center'
56
- Pango::Alignment::CENTER
57
- else
58
- raise ArgumentError, 'align must be one of: center, left, right'
59
- end
60
- end
40
+ def validate_str(arg, _i)
41
+ arg.to_s
42
+ end
61
43
 
62
- def validate_wrap(arg, _i)
63
- case arg.to_s.downcase.strip
64
- when 'word'
65
- Pango::WrapMode::WORD
66
- when 'char', 'false'
67
- Pango::WrapMode::CHAR
68
- when 'word_char', 'true'
69
- Pango::WrapMode::WORD_CHAR
70
- else
71
- raise ArgumentError, 'wrap must be one of: word, char, word_char, true, or false'
72
- end
73
- end
44
+ def validate_font(arg, _i)
45
+ arg = @deck_font if arg == :use_set
46
+ arg = Squib::DEFAULT_FONT if arg == :default
47
+ arg
48
+ end
74
49
 
75
- def validate_ellipsize(arg, _i)
76
- case arg.to_s.downcase.strip
77
- when 'none', 'false'
78
- Pango::EllipsizeMode::NONE
79
- when 'start'
80
- Pango::EllipsizeMode::START
81
- when 'middle'
82
- Pango::EllipsizeMode::MIDDLE
83
- when 'end', 'true'
84
- Pango::EllipsizeMode::END
85
- else
86
- raise ArgumentError, 'ellipsize must be one of: none, start, middle, end, true, or false'
87
- end
50
+ def validate_align(arg, _i)
51
+ case arg.to_s.downcase.strip
52
+ when 'left'
53
+ Pango::Alignment::LEFT
54
+ when 'right'
55
+ Pango::Alignment::RIGHT
56
+ when 'center'
57
+ Pango::Alignment::CENTER
58
+ else
59
+ raise ArgumentError, 'align must be one of: center, left, right'
88
60
  end
61
+ end
89
62
 
90
- def validate_justify(arg, _i)
91
- case arg
92
- when nil, true, false
93
- arg
94
- else
95
- raise ArgumentError, 'justify must be one of: nil, true, or false'
96
- end
63
+ def validate_wrap(arg, _i)
64
+ case arg.to_s.downcase.strip
65
+ when 'word'
66
+ Pango::WrapMode::WORD
67
+ when 'char', 'false'
68
+ Pango::WrapMode::CHAR
69
+ when 'word_char', 'true'
70
+ Pango::WrapMode::WORD_CHAR
71
+ else
72
+ raise ArgumentError, 'wrap must be one of: word, char, word_char, true, or false'
97
73
  end
74
+ end
98
75
 
99
- def validate_spacing(arg, _i)
100
- return nil if arg.nil?
101
- raise ArgumentError, 'spacing must be a number or nil' unless arg.respond_to? :to_f
102
- arg.to_f * Pango::SCALE
76
+ def validate_ellipsize(arg, _i)
77
+ case arg.to_s.downcase.strip
78
+ when 'none', 'false'
79
+ Pango::EllipsizeMode::NONE
80
+ when 'start'
81
+ Pango::EllipsizeMode::START
82
+ when 'middle'
83
+ Pango::EllipsizeMode::MIDDLE
84
+ when 'end', 'true'
85
+ Pango::EllipsizeMode::END
86
+ when 'autoscale'
87
+ :autoscale
88
+ else
89
+ raise ArgumentError, 'ellipsize must be one of: none, start, middle, end, true, false or autoscale'
103
90
  end
91
+ end
104
92
 
105
- def validate_valign(arg, _i)
106
- if %w(top middle bottom).include? arg.to_s.downcase
107
- arg.to_s.downcase
108
- else
109
- raise ArgumentError, 'valign must be one of: top, middle, bottom'
110
- end
93
+ def validate_justify(arg, _i)
94
+ case arg
95
+ when nil, true, false
96
+ arg
97
+ else
98
+ raise ArgumentError, 'justify must be one of: nil, true, or false'
111
99
  end
100
+ end
101
+
102
+ def validate_spacing(arg, _i)
103
+ return nil if arg.nil?
104
+ raise ArgumentError, 'spacing must be a number or nil' unless arg.respond_to? :to_f
105
+ arg.to_f * Pango::SCALE
106
+ end
112
107
 
108
+ def validate_valign(arg, _i)
109
+ if %w(top middle bottom).include? arg.to_s.downcase
110
+ arg.to_s.downcase
111
+ else
112
+ raise ArgumentError, 'valign must be one of: top, middle, bottom'
113
+ end
113
114
  end
114
115
 
115
116
  end
117
+
116
118
  end
@@ -1,63 +1,65 @@
1
1
  require_relative 'arg_loader'
2
2
  require_relative 'dir_validator'
3
3
 
4
- module Squib
5
- # @api private
6
- module Args
7
- class SaveBatch
8
- include ArgLoader
9
- include DirValidator
10
-
11
- def initialize
12
- end
4
+ module Squib::Args
5
+ module_function def extract_save_batch(opts, deck)
6
+ SaveBatch.new.extract! opts, deck
7
+ end
13
8
 
14
- def self.parameters
15
- {
16
- angle: 0,
17
- count_format: '%02d',
18
- dir: '_output',
19
- prefix: 'card_',
20
- rotate: false,
21
- trim_radius: 0,
22
- trim: 0,
23
- }
24
- end
9
+ class SaveBatch
10
+ include ArgLoader
11
+ include DirValidator
25
12
 
26
- def self.expanding_parameters
27
- self.parameters.keys # all of them
28
- end
13
+ def initialize
14
+ end
29
15
 
30
- def self.params_with_units
31
- [:trim, :trim_radius]
32
- end
16
+ def self.parameters
17
+ {
18
+ angle: 0,
19
+ count_format: '%02d',
20
+ dir: '_output',
21
+ prefix: 'card_',
22
+ rotate: false,
23
+ suffix: '',
24
+ trim_radius: 0,
25
+ trim: 0,
26
+ }
27
+ end
33
28
 
34
- def validate_dir(arg, _i)
35
- ensure_dir_created(arg)
36
- end
29
+ def self.expanding_parameters
30
+ self.parameters.keys # all of them
31
+ end
37
32
 
38
- def validate_rotate(arg, i)
39
- case arg
40
- when true, :clockwise
41
- angle[i] = 0.5 * Math::PI
42
- return true
43
- when :counterclockwise
44
- angle[i] = 1.5 * Math::PI
45
- return true
46
- when false
47
- false
48
- else
49
- raise 'invalid option to rotate: only [true, false, :clockwise, :counterclockwise]'
50
- end
51
- end
33
+ def self.params_with_units
34
+ [:trim, :trim_radius]
35
+ end
52
36
 
53
- def full_filename(i)
54
- "#{dir[i]}/#{prefix[i]}#{count_format[i] % i}.png"
55
- end
37
+ def validate_dir(arg, _i)
38
+ ensure_dir_created(arg)
39
+ end
56
40
 
57
- def summary
58
- "#{dir[0]}/#{prefix[0]}_*"
41
+ def validate_rotate(arg, i)
42
+ case arg
43
+ when true, :clockwise
44
+ angle[i] = 0.5 * Math::PI
45
+ return true
46
+ when :counterclockwise
47
+ angle[i] = 1.5 * Math::PI
48
+ return true
49
+ when false
50
+ false
51
+ else
52
+ raise 'invalid option to rotate: only [true, false, :clockwise, :counterclockwise]'
59
53
  end
54
+ end
55
+
56
+ def full_filename(i)
57
+ "#{dir[i]}/#{prefix[i]}#{count_format[i] % i}#{suffix[i]}.png"
58
+ end
60
59
 
60
+ def summary
61
+ "#{dir[0]}/#{prefix[0]}_*#{suffix[0]}"
61
62
  end
63
+
62
64
  end
63
65
  end