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,44 +1,44 @@
1
1
  require_relative 'arg_loader'
2
2
 
3
- module Squib
4
- # @api private
5
- module Args
6
- class SprueFile
7
- include ArgLoader
3
+ module Squib::Args
4
+ module_function def extract_sprue_file(opts, deck, dsl_method_default = {})
5
+ SprueFile.new.extract! opts, deck
6
+ end
7
+ class SprueFile
8
+ include ArgLoader
8
9
 
9
- def initialize(dsl_method_default = {})
10
- @dsl_method_default = dsl_method_default
11
- end
10
+ def initialize(dsl_method_default = {})
11
+ @dsl_method_default = dsl_method_default
12
+ end
12
13
 
13
- def self.parameters
14
- {
15
- sprue: nil
16
- }
17
- end
14
+ def self.parameters
15
+ {
16
+ sprue: nil
17
+ }
18
+ end
18
19
 
19
- def self.expanding_parameters
20
- []
21
- end
20
+ def self.expanding_parameters
21
+ []
22
+ end
22
23
 
23
- def self.params_with_units
24
- [] # none of them
25
- end
24
+ def self.params_with_units
25
+ [] # none of them
26
+ end
26
27
 
27
- def validate_template_file(arg)
28
- return nil if arg.nil?
28
+ def validate_template_file(arg)
29
+ return nil if arg.nil?
29
30
 
30
- thefile = File.exist?(arg) ? arg : builtin(arg)
31
- raise "File #{File.expand_path(arg)} does not exist!" unless
32
- File.exist? thefile
31
+ thefile = File.exist?(arg) ? arg : builtin(arg)
32
+ raise "File #{File.expand_path(arg)} does not exist!" unless
33
+ File.exist? thefile
33
34
 
34
- File.expand_path(thefile)
35
- end
35
+ File.expand_path(thefile)
36
+ end
36
37
 
37
- private
38
+ private
38
39
 
39
- def builtin(file)
40
- "#{File.dirname(__FILE__)}/../builtin/sprues/#{file}"
41
- end
40
+ def builtin(file)
41
+ "#{File.dirname(__FILE__)}/../builtin/sprues/#{file}"
42
42
  end
43
43
  end
44
44
  end
@@ -1,37 +1,37 @@
1
1
  require_relative 'arg_loader'
2
2
 
3
- module Squib
4
- # @api private
5
- module Args
6
-
7
- class SvgSpecial
8
- include ArgLoader
9
-
10
- def self.parameters
11
- { data: nil, id: nil, force_id: false }
12
- end
3
+ module Squib::Args
4
+ module_function def extract_svg_special(opts, deck)
5
+ SvgSpecial.new.extract! opts, deck
6
+ end
7
+
8
+ class SvgSpecial
9
+ include ArgLoader
13
10
 
14
- def self.expanding_parameters
15
- parameters.keys # all of them
16
- end
11
+ def self.parameters
12
+ { data: nil, id: nil, force_id: false }
13
+ end
17
14
 
18
- def self.params_with_units
19
- []
20
- end
15
+ def self.expanding_parameters
16
+ parameters.keys # all of them
17
+ end
21
18
 
22
- def validate_id(arg, _i)
23
- return nil if arg.to_s.empty?
24
- arg = '#' << arg unless arg.start_with? '#'
25
- arg
26
- end
19
+ def self.params_with_units
20
+ []
21
+ end
27
22
 
28
- # Only render if we have an ID specified, or we are forcing an ID
29
- def render?(i)
30
- return false if force_id[i] && id[i].to_s.empty?
31
- return true
32
- end
23
+ def validate_id(arg, _i)
24
+ return nil if arg.to_s.empty?
25
+ arg = '#' << arg unless arg.start_with? '#'
26
+ arg
27
+ end
33
28
 
29
+ # Only render if we have an ID specified, or we are forcing an ID
30
+ def render?(i)
31
+ return false if force_id[i] && id[i].to_s.empty?
32
+ return true
34
33
  end
35
34
 
36
35
  end
36
+
37
37
  end
@@ -1,61 +1,55 @@
1
1
  require_relative 'arg_loader'
2
2
 
3
- module Squib
4
- # @api private
5
- module Args
6
-
7
- class Transform
8
- include ArgLoader
9
-
10
- def initialize(deck = nil)
11
- @deck = deck
12
- end
13
-
14
- def self.parameters
15
- { angle: 0,
16
- crop_x: 0,
17
- crop_y: 0,
18
- crop_width: :native,
19
- crop_height: :native,
20
- crop_corner_radius: nil,
21
- crop_corner_x_radius: 0,
22
- crop_corner_y_radius: 0,
23
- flip_vertical: false,
24
- flip_horizontal: false,
25
- }
26
- end
27
-
28
- def self.expanding_parameters
29
- parameters.keys # all of them
30
- end
31
-
32
- def self.params_with_units
33
- parameters.keys - [:flip_vertical, :flip_horizontal]
34
- end
35
-
36
- def validate_crop_width(arg, _i)
37
- return arg if @deck.nil?
38
- return @deck.width if arg == :deck
39
- arg
40
- end
41
-
42
- def validate_crop_height(arg, _i)
43
- return arg if @deck.nil?
44
- return @deck.height if arg == :deck
45
- arg
46
- end
47
-
48
- def validate_crop_corner_x_radius(arg, i)
49
- return crop_corner_radius[i] unless crop_corner_radius[i].nil?
50
- arg
51
- end
52
-
53
- def validate_crop_corner_y_radius(arg, i)
54
- return crop_corner_radius[i] unless crop_corner_radius[i].nil?
55
- arg
56
- end
3
+ module Squib::Args
4
+ module_function def extract_transform(opts, deck)
5
+ Transform.new.extract!(opts, deck)
6
+ end
7
+
8
+ class Transform
9
+ include ArgLoader
10
+
11
+ def self.parameters
12
+ { angle: 0,
13
+ crop_x: 0,
14
+ crop_y: 0,
15
+ crop_width: :native,
16
+ crop_height: :native,
17
+ crop_corner_radius: nil,
18
+ crop_corner_x_radius: 0,
19
+ crop_corner_y_radius: 0,
20
+ flip_vertical: false,
21
+ flip_horizontal: false,
22
+ }
23
+ end
24
+
25
+ def self.expanding_parameters
26
+ parameters.keys # all of them
27
+ end
28
+
29
+ def self.params_with_units
30
+ parameters.keys - [:flip_vertical, :flip_horizontal]
31
+ end
32
+
33
+ def validate_crop_width(arg, _i)
34
+ return arg if @deck.nil?
35
+ return @deck.width if arg == :deck
36
+ arg
37
+ end
57
38
 
39
+ def validate_crop_height(arg, _i)
40
+ return arg if @deck.nil?
41
+ return @deck.height if arg == :deck
42
+ arg
58
43
  end
59
44
 
45
+ def validate_crop_corner_x_radius(arg, i)
46
+ return crop_corner_radius[i] unless crop_corner_radius[i].nil?
47
+ arg
48
+ end
49
+
50
+ def validate_crop_corner_y_radius(arg, i)
51
+ return crop_corner_radius[i] unless crop_corner_radius[i].nil?
52
+ arg
53
+ end
60
54
  end
61
55
  end
@@ -1,119 +1,115 @@
1
1
  require_relative '../constants'
2
2
 
3
- module Squib
4
- # @api private
5
- module Args
6
- # Internal class for handling arguments
7
- # @api private
8
- class Typographer
9
-
10
- def initialize(config = Conf::DEFAULTS)
11
- %w(lsquote ldquote rsquote rdquote smart_quotes
12
- em_dash en_dash ellipsis).each do |var|
13
- instance_variable_set("@#{var}", config[var])
14
- end
15
- end
3
+ module Squib::Args
4
+ # Internal class for handling arguments
5
+ class Typographer
16
6
 
17
- def process(str)
18
- str = explicit_replacements(str.to_s)
19
- str = smart_quotes(str) if @smart_quotes
20
- str
7
+ def initialize(config = Squib::Conf::DEFAULTS)
8
+ %w(lsquote ldquote rsquote rdquote smart_quotes
9
+ em_dash en_dash ellipsis).each do |var|
10
+ instance_variable_set("@#{var}", config[var])
21
11
  end
12
+ end
22
13
 
23
- def explicit_replacements(str)
24
- [ :left_curly, :right_curly, :apostraphize,
25
- :ellipsificate, :em_dash, :en_dash ].each do |sym|
26
- str = each_non_tag(str) do |token|
27
- self.method(sym).call(token)
28
- end
29
- end
30
- str
31
- end
14
+ def process(str)
15
+ str = explicit_replacements(str.to_s)
16
+ str = smart_quotes(str) if @smart_quotes
17
+ str
18
+ end
32
19
 
33
- def smart_quotes(str)
34
- [ :single_inside_double_quote,
35
- :right_double_quote,
36
- :left_double_quote,
37
- :right_single_quote,
38
- :left_single_quote].each do |sym|
39
- str = each_non_tag(str) do |token|
40
- self.method(sym).call(token)
41
- end
20
+ def explicit_replacements(str)
21
+ [ :left_curly, :right_curly, :apostraphize,
22
+ :ellipsificate, :em_dash, :en_dash ].each do |sym|
23
+ str = each_non_tag(str) do |token|
24
+ self.method(sym).call(token)
42
25
  end
43
- str
44
26
  end
27
+ str
28
+ end
45
29
 
46
- # Iterate over each non-tag for processing
47
- # Allows us to ignore anything inside < and >
48
- def each_non_tag(str)
49
- full_str = ''
50
- tag_delimit = /(<(?:(?!<).)*>)/ # use non-capturing group w/ negative lookahead
51
- str.split(tag_delimit).each do |token|
52
- if token.start_with? '<'
53
- full_str << token # don't process tags
54
- else
55
- full_str << yield(token)
56
- end
30
+ def smart_quotes(str)
31
+ [ :single_inside_double_quote,
32
+ :right_double_quote,
33
+ :left_double_quote,
34
+ :right_single_quote,
35
+ :left_single_quote].each do |sym|
36
+ str = each_non_tag(str) do |token|
37
+ self.method(sym).call(token)
57
38
  end
58
- return full_str
59
39
  end
40
+ str
41
+ end
60
42
 
61
- # Straightforward replace
62
- def left_curly(str)
63
- str.gsub('``', @ldquote)
43
+ # Iterate over each non-tag for processing
44
+ # Allows us to ignore anything inside < and >
45
+ def each_non_tag(str)
46
+ full_str = ''
47
+ tag_delimit = /(<(?:(?!<).)*>)/ # use non-capturing group w/ negative lookahead
48
+ str.split(tag_delimit).each do |token|
49
+ if token.start_with? '<'
50
+ full_str << token # don't process tags
51
+ else
52
+ full_str << yield(token)
53
+ end
64
54
  end
55
+ return full_str
56
+ end
65
57
 
66
- # Straightforward replace
67
- def right_curly(str)
68
- str.gsub(%{''}, @rdquote)
69
- end
58
+ # Straightforward replace
59
+ def left_curly(str)
60
+ str.gsub('``', @ldquote)
61
+ end
70
62
 
71
- # A quote between two letters is an apostraphe
72
- def apostraphize(str)
73
- str.gsub(/(\w)(\')(\w)/, '\1' + @rsquote + '\3')
74
- end
63
+ # Straightforward replace
64
+ def right_curly(str)
65
+ str.gsub(%{''}, @rdquote)
66
+ end
75
67
 
76
- # Straightforward replace
77
- def ellipsificate(str)
78
- str.gsub('...', @ellipsis)
79
- end
68
+ # A quote between two letters is an apostraphe
69
+ def apostraphize(str)
70
+ str.gsub(/(\w)(\')(\w)/, '\1' + @rsquote + '\3')
71
+ end
80
72
 
81
- # Straightforward replace
82
- def en_dash(str)
83
- str.gsub('--', @en_dash)
84
- end
73
+ # Straightforward replace
74
+ def ellipsificate(str)
75
+ str.gsub('...', @ellipsis)
76
+ end
85
77
 
86
- # Straightforward replace
87
- def em_dash(str)
88
- str.gsub('---', @em_dash)
89
- end
78
+ # Straightforward replace
79
+ def en_dash(str)
80
+ str.gsub('--', @en_dash)
81
+ end
90
82
 
91
- # Quote next to non-whitespace curls
92
- def right_double_quote(str)
93
- str.gsub(/(\S)(\")/, '\1' + @rdquote)
94
- end
83
+ # Straightforward replace
84
+ def em_dash(str)
85
+ str.gsub('---', @em_dash)
86
+ end
95
87
 
96
- # Quote next to non-whitespace curls
97
- def left_double_quote(str)
98
- str.gsub(/(\")(\S)/, @ldquote + '\2')
99
- end
88
+ # Quote next to non-whitespace curls
89
+ def right_double_quote(str)
90
+ str.gsub(/(\S)(\")/, '\1' + @rdquote)
91
+ end
100
92
 
101
- # Handle the cases where a double quote is next to a single quote
102
- def single_inside_double_quote(str)
103
- str.gsub(/(\")(\')(\S)/, @ldquote + @lsquote + '\3')
104
- .gsub(/(\")(\')(\S)/, '\1' + @rsquote + @rdquote)
105
- end
93
+ # Quote next to non-whitespace curls
94
+ def left_double_quote(str)
95
+ str.gsub(/(\")(\S)/, @ldquote + '\2')
96
+ end
106
97
 
107
- # Quote next to non-whitespace curls
108
- def right_single_quote(str)
109
- str.gsub(/(\S)(\')/, '\1' + @rsquote)
110
- end
98
+ # Handle the cases where a double quote is next to a single quote
99
+ def single_inside_double_quote(str)
100
+ str.gsub(/(\")(\')(\S)/, @ldquote + @lsquote + '\3')
101
+ .gsub(/(\")(\')(\S)/, '\1' + @rsquote + @rdquote)
102
+ end
111
103
 
112
- # Quote next to non-whitespace curls
113
- def left_single_quote(str)
114
- str.gsub(/(\')(\S)/, @lsquote + '\2')
115
- end
104
+ # Quote next to non-whitespace curls
105
+ def right_single_quote(str)
106
+ str.gsub(/(\S)(\')/, '\1' + @rsquote)
107
+ end
116
108
 
109
+ # Quote next to non-whitespace curls
110
+ def left_single_quote(str)
111
+ str.gsub(/(\')(\S)/, @lsquote + '\2')
117
112
  end
113
+
118
114
  end
119
115
  end