squib 0.15.3 → 0.16.0.pre.preview1

Sign up to get free protection for your applications and to get access to all the features.
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