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,53 +1,57 @@
1
1
  require_relative 'arg_loader'
2
+ require_relative 'xywh_shorthands'
2
3
 
3
- module Squib
4
- # @api private
5
- module Args
6
-
7
- class ScaleBox
8
- include ArgLoader
4
+ module Squib::Args
5
+ module_function def extract_scale_box(opts, deck)
6
+ ScaleBox.new.extract!(opts, deck)
7
+ end
9
8
 
10
- def initialize(deck)
11
- @deck = deck
12
- end
9
+ class ScaleBox
10
+ include ArgLoader
11
+ include XYWHShorthands
13
12
 
14
- def self.parameters
15
- { x: 0, y: 0,
16
- width: :native, height: :native
17
- }
18
- end
13
+ def self.parameters
14
+ {
15
+ x: 0, y: 0,
16
+ width: :native, height: :native
17
+ }
18
+ end
19
19
 
20
- def self.expanding_parameters
21
- parameters.keys # all of them
22
- end
20
+ def self.expanding_parameters
21
+ parameters.keys # all of them
22
+ end
23
23
 
24
- def self.params_with_units
25
- parameters.keys # all of them
26
- end
24
+ def self.params_with_units
25
+ parameters.keys # all of them
26
+ end
27
27
 
28
- def validate_width(arg, i)
29
- return @deck.width if arg.to_s == 'deck'
30
- return :native if arg.to_s == 'native'
31
- return arg if arg.respond_to? :to_f
32
- if arg.to_s == 'scale'
33
- raise 'if width is :scale, height must be a number' unless height[i].respond_to? :to_f
34
- return arg
35
- end
36
- raise 'width must be a number, :scale, :native, or :deck'
28
+ def validate_x(arg, i) apply_shorthands(arg, @deck, axis: :x) end
29
+ def validate_y(arg,_i) apply_shorthands(arg, @deck, axis: :y) end
30
+
31
+ def validate_width(arg, i)
32
+ return @deck.width if arg.to_s == 'deck'
33
+ return :native if arg.to_s == 'native'
34
+ arg = apply_shorthands(arg, @deck, axis: :x)
35
+ return arg if arg.respond_to? :to_f
36
+ if arg.to_s == 'scale'
37
+ raise 'if width is :scale, height must be a number' unless height[i].respond_to? :to_f
38
+ return arg
37
39
  end
40
+ raise 'width must be a number, :scale, :native, or :deck'
41
+ end
38
42
 
39
- def validate_height(arg, i)
40
- return @deck.height if arg.to_s == 'deck'
41
- return :native if arg.to_s == 'native'
42
- return arg if arg.respond_to? :to_f
43
- if arg.to_s == 'scale'
44
- raise 'if height is \'scale\', width must be a number' unless width[i].respond_to? :to_f
45
- return arg
46
- end
47
- raise 'height must be a number, :scale, :native, or :deck'
43
+ def validate_height(arg, i)
44
+ return @deck.height if arg.to_s == 'deck'
45
+ return :native if arg.to_s == 'native'
46
+ arg = apply_shorthands(arg, @deck, axis: :y)
47
+ return arg if arg.respond_to? :to_f
48
+ if arg.to_s == 'scale'
49
+ raise 'if height is \'scale\', width must be a number' unless width[i].respond_to? :to_f
50
+ return arg
48
51
  end
49
-
52
+ raise 'height must be a number, :scale, :native, or :deck'
50
53
  end
51
54
 
52
55
  end
56
+
53
57
  end
@@ -3,170 +3,168 @@ require_relative 'arg_loader'
3
3
  require_relative 'color_validator'
4
4
  require_relative 'dir_validator'
5
5
 
6
- module Squib
7
- # @api private
8
- module Args
9
-
10
- class Sheet
11
- include ArgLoader
12
- include ColorValidator
13
- include DirValidator
14
-
15
- def initialize(custom_colors = {}, dsl_method_defaults = {}, deck_size = 1, dpi = 300)
16
- @custom_colors = custom_colors
17
- @dsl_method_defaults = dsl_method_defaults
18
- @deck_size = deck_size
19
- @dpi = dpi
20
- end
6
+ module Squib::Args
7
+ module_function def extract_sheet(opts, deck, dsl_method_defaults = {})
8
+ Sheet.new(dsl_method_defaults).extract! opts, deck
9
+ end
21
10
 
22
- def self.parameters
23
- {
24
- count_format: '%02d',
25
- crop_margin_bottom: 0,
26
- crop_margin_left: 0,
27
- crop_margin_right: 0,
28
- crop_margin_top: 0,
29
- crop_marks: false,
30
- crop_stroke_color: :black,
31
- crop_stroke_dash: '',
32
- crop_stroke_width: 1.5,
33
- dir: '_output',
34
- file: 'sheet.png',
35
- fill_color: :white,
36
- gap: 0,
37
- height: 2550,
38
- margin: 75,
39
- prefix: 'sheet_',
40
- rows: :infinite,
41
- columns: 5,
42
- trim_radius: 0,
43
- trim: 0,
44
- width: 3300,
45
- range: :all,
46
- rtl: false,
47
- }
48
- end
11
+ class Sheet
12
+ include ArgLoader
13
+ include ColorValidator
14
+ include DirValidator
49
15
 
50
- def self.expanding_parameters
51
- [] # none of them
52
- end
16
+ def initialize(dsl_method_defaults = {})
17
+ @dsl_method_defaults = dsl_method_defaults
18
+ end
53
19
 
54
- def self.params_with_units
55
- [ :crop_margin_bottom, :crop_margin_left, :crop_margin_right,
56
- :crop_margin_top, :gap, :height, :margin, :trim_radius, :trim,
57
- :width
58
- ]
59
- end
20
+ def self.parameters
21
+ {
22
+ count_format: '%02d',
23
+ crop_margin_bottom: 0,
24
+ crop_margin_left: 0,
25
+ crop_margin_right: 0,
26
+ crop_margin_top: 0,
27
+ crop_marks: false,
28
+ crop_stroke_color: :black,
29
+ crop_stroke_dash: '',
30
+ crop_stroke_width: 1.5,
31
+ dir: '_output',
32
+ file: 'sheet.png',
33
+ fill_color: :white,
34
+ gap: 0,
35
+ height: 2550,
36
+ margin: 75,
37
+ prefix: 'sheet_',
38
+ suffix: '',
39
+ rows: :infinite,
40
+ columns: 5,
41
+ trim_radius: 0,
42
+ trim: 0,
43
+ width: 3300,
44
+ range: :all,
45
+ rtl: false,
46
+ }
47
+ end
60
48
 
61
- def validate_crop_stroke_dash(arg)
62
- arg.to_s.split.collect do |x|
63
- UnitConversion.parse(x, @dpi).to_f
64
- end
65
- end
49
+ def self.expanding_parameters
50
+ [] # none of them
51
+ end
66
52
 
67
- def validate_crop_marks(arg)
68
- arg.to_s.downcase.to_sym unless arg == false
69
- end
53
+ def self.params_with_units
54
+ [ :crop_margin_bottom, :crop_margin_left, :crop_margin_right,
55
+ :crop_margin_top, :gap, :height, :margin, :trim_radius, :trim,
56
+ :width
57
+ ]
58
+ end
70
59
 
71
- def validate_fill_color(arg)
72
- colorify(arg, @custom_colors)
60
+ def validate_crop_stroke_dash(arg)
61
+ arg.to_s.split.collect do |x|
62
+ UnitConversion.parse(x, @deck.dpi, @deck.cell_px).to_f
73
63
  end
64
+ end
74
65
 
75
- def validate_dir(arg)
76
- ensure_dir_created(arg)
77
- end
66
+ def validate_crop_marks(arg)
67
+ arg.to_s.downcase.to_sym unless arg == false
68
+ end
78
69
 
79
- def validate_columns(arg)
80
- raise 'columns must be an integer' unless arg.respond_to? :to_i
81
- arg.to_i
82
- end
70
+ def validate_fill_color(arg)
71
+ colorify(arg, @deck.custom_colors)
72
+ end
83
73
 
84
- def validate_rows(arg)
85
- raise 'columns must be an integer' unless columns.respond_to? :to_i
86
- count = if range == :all
87
- @deck_size
88
- else
89
- count = range.to_a.length
90
- end
91
- return 1 if count <= columns
92
- return arg if arg.respond_to? :to_i
93
- (count.to_f / columns.to_f).ceil
94
- end
74
+ def validate_dir(arg)
75
+ ensure_dir_created(arg)
76
+ end
95
77
 
96
- def full_filename(i=nil)
97
- if i.nil?
98
- "#{dir}/#{file}"
99
- else
100
- "#{dir}/#{prefix}#{count_format % i}.png"
101
- end
102
- end
78
+ def validate_columns(arg)
79
+ raise 'columns must be an integer' unless arg.respond_to? :to_i
80
+ arg.to_i
81
+ end
103
82
 
104
- def crop_coords(x, y, deck_w, deck_h)
105
- case crop_marks
106
- when false
107
- []
108
- when :full
109
- [
110
- {
111
- # Vertical, Left
112
- x1: x + trim + crop_margin_left, y1: 0,
113
- x2: x + trim + crop_margin_left, y2: height - margin + 1
114
- },
115
- {
116
- # Vertical, Right
117
- x1: x + deck_w - trim - crop_margin_right, y1: 0,
118
- x2: x + deck_w - trim - crop_margin_right, y2: height - margin + 1
119
- },
120
- {
121
- # Horizontal, Top
122
- x1: 0 , y1: y + trim + crop_margin_top,
123
- x2: width - margin + 1, y2: y + trim + crop_margin_top
124
- },
125
- {
126
- # Horizontal, Bottom
127
- x1: 0 , y1: y + deck_h - trim - crop_margin_bottom,
128
- x2: width - margin + 1, y2: y + deck_h - trim - crop_margin_bottom
129
- },
130
- ]
131
- else # e.g. :margin
132
- [
133
- { # Vertical, Upper-left
134
- x1: x + trim + crop_margin_left, y1: 0,
135
- x2: x + trim + crop_margin_left, y2: margin - 1
136
- },
137
- { # Vertical , Upper-right
138
- x1: x + deck_w - trim - crop_margin_right, y1: 0,
139
- x2: x + deck_w - trim - crop_margin_right, y2: margin - 1
140
- },
141
- { # Vertical , Lower-left
142
- x1: x + trim + crop_margin_left, y1: height,
143
- x2: x + trim + crop_margin_left, y2: height - margin + 1
144
- },
145
- { # Vertical , Lower-right
146
- x1: x + deck_w - trim - crop_margin_right, y1: height,
147
- x2: x + deck_w - trim - crop_margin_right, y2: height - margin + 1
148
- },
149
- { # Horizontal, Upper-left
150
- x1: 0 , y1: y + trim + crop_margin_top,
151
- x2: margin - 1, y2: y + trim + crop_margin_top
152
- },
153
- { # Horizontal, Upper-Right
154
- x1: width , y1: y + trim + crop_margin_top,
155
- x2: width - margin + 1, y2: y + trim + crop_margin_top
156
- },
157
- { # Horizontal, Lower-Left
158
- x1: 0 , y1: y + deck_h - trim - crop_margin_bottom,
159
- x2: margin - 1, y2: y + deck_h - trim - crop_margin_bottom
160
- },
161
- { # Horizontal, Lower-Right
162
- x1: width, y1: y + deck_h - trim - crop_margin_bottom,
163
- x2: width - margin + 1, y2: y + deck_h - trim - crop_margin_bottom
164
- },
165
- ]
166
- end
83
+ def validate_rows(arg)
84
+ raise 'columns must be an integer' unless columns.respond_to? :to_i
85
+ count = if range == :all
86
+ @deck.size
87
+ else
88
+ count = range.to_a.length
89
+ end
90
+ return 1 if count <= columns
91
+ return arg if arg.respond_to? :to_i
92
+ (count.to_f / columns.to_f).ceil
93
+ end
94
+
95
+ def full_filename(i=nil)
96
+ if i.nil?
97
+ "#{dir}/#{file}"
98
+ else
99
+ "#{dir}/#{prefix}#{count_format % i}#{suffix}.png"
167
100
  end
101
+ end
168
102
 
103
+ def crop_coords(x, y, deck_w, deck_h)
104
+ case crop_marks
105
+ when false
106
+ []
107
+ when :full
108
+ [
109
+ {
110
+ # Vertical, Left
111
+ x1: x + trim + crop_margin_left, y1: 0,
112
+ x2: x + trim + crop_margin_left, y2: height - margin + 1
113
+ },
114
+ {
115
+ # Vertical, Right
116
+ x1: x + deck_w - trim - crop_margin_right, y1: 0,
117
+ x2: x + deck_w - trim - crop_margin_right, y2: height - margin + 1
118
+ },
119
+ {
120
+ # Horizontal, Top
121
+ x1: 0 , y1: y + trim + crop_margin_top,
122
+ x2: width - margin + 1, y2: y + trim + crop_margin_top
123
+ },
124
+ {
125
+ # Horizontal, Bottom
126
+ x1: 0 , y1: y + deck_h - trim - crop_margin_bottom,
127
+ x2: width - margin + 1, y2: y + deck_h - trim - crop_margin_bottom
128
+ },
129
+ ]
130
+ else # e.g. :margin
131
+ [
132
+ { # Vertical, Upper-left
133
+ x1: x + trim + crop_margin_left, y1: 0,
134
+ x2: x + trim + crop_margin_left, y2: margin - 1
135
+ },
136
+ { # Vertical , Upper-right
137
+ x1: x + deck_w - trim - crop_margin_right, y1: 0,
138
+ x2: x + deck_w - trim - crop_margin_right, y2: margin - 1
139
+ },
140
+ { # Vertical , Lower-left
141
+ x1: x + trim + crop_margin_left, y1: height,
142
+ x2: x + trim + crop_margin_left, y2: height - margin + 1
143
+ },
144
+ { # Vertical , Lower-right
145
+ x1: x + deck_w - trim - crop_margin_right, y1: height,
146
+ x2: x + deck_w - trim - crop_margin_right, y2: height - margin + 1
147
+ },
148
+ { # Horizontal, Upper-left
149
+ x1: 0 , y1: y + trim + crop_margin_top,
150
+ x2: margin - 1, y2: y + trim + crop_margin_top
151
+ },
152
+ { # Horizontal, Upper-Right
153
+ x1: width , y1: y + trim + crop_margin_top,
154
+ x2: width - margin + 1, y2: y + trim + crop_margin_top
155
+ },
156
+ { # Horizontal, Lower-Left
157
+ x1: 0 , y1: y + deck_h - trim - crop_margin_bottom,
158
+ x2: margin - 1, y2: y + deck_h - trim - crop_margin_bottom
159
+ },
160
+ { # Horizontal, Lower-Right
161
+ x1: width, y1: y + deck_h - trim - crop_margin_bottom,
162
+ x2: width - margin + 1, y2: y + deck_h - trim - crop_margin_bottom
163
+ },
164
+ ]
165
+ end
169
166
  end
170
167
 
171
168
  end
169
+
172
170
  end
@@ -2,40 +2,40 @@ require 'cairo'
2
2
  require_relative 'arg_loader'
3
3
  require_relative 'dir_validator'
4
4
 
5
- module Squib
6
- # @api private
7
- module Args
8
-
9
- class ShowcaseSpecial
10
- include ArgLoader
11
- include DirValidator
12
-
13
- def self.parameters
14
- {
15
- scale: 0.85,
16
- trim: 0,
17
- trim_radius: 38,
18
- offset: 1.1,
19
- reflect_offset: 15,
20
- reflect_percent: 0.25,
21
- reflect_strength: 0.2,
22
- face: :left,
23
- }
24
- end
25
-
26
- def self.expanding_parameters
27
- [] # none of them
28
- end
29
-
30
- def self.params_with_units
31
- [ :reflect_offset ]
32
- end
33
-
34
- def face_right?
35
- @face.to_s.strip.downcase == 'right'
36
- end
5
+ module Squib::Args
6
+ module_function def extract_showcase_special(opts, deck)
7
+ ShowcaseSpecial.new.extract! opts, deck
8
+ end
9
+
10
+ class ShowcaseSpecial
11
+ include ArgLoader
12
+ include DirValidator
13
+
14
+ def self.parameters
15
+ {
16
+ scale: 0.85,
17
+ trim: 0,
18
+ trim_radius: 38,
19
+ offset: 1.1,
20
+ reflect_offset: 15,
21
+ reflect_percent: 0.25,
22
+ reflect_strength: 0.2,
23
+ face: :left,
24
+ }
25
+ end
26
+
27
+ def self.expanding_parameters
28
+ [] # none of them
29
+ end
30
+
31
+ def self.params_with_units
32
+ [ :reflect_offset ]
33
+ end
37
34
 
35
+ def face_right?
36
+ @face.to_s.strip.downcase == 'right'
38
37
  end
39
38
 
40
39
  end
40
+
41
41
  end