lacci 0.3.0 → 0.5.0

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -2
  3. data/Gemfile.lock +4 -32
  4. data/lib/lacci/scarpe_cli.rb +0 -1
  5. data/lib/lacci/version.rb +1 -1
  6. data/lib/scarpe/niente/app.rb +12 -1
  7. data/lib/scarpe/niente/display_service.rb +5 -1
  8. data/lib/scarpe/niente/drawable.rb +2 -0
  9. data/lib/scarpe/niente/shoes_spec.rb +10 -5
  10. data/lib/scarpe/niente.rb +15 -2
  11. data/lib/shoes/app.rb +204 -105
  12. data/lib/shoes/constants.rb +24 -2
  13. data/lib/shoes/display_service.rb +43 -4
  14. data/lib/shoes/drawable.rb +326 -36
  15. data/lib/shoes/drawables/arc.rb +4 -26
  16. data/lib/shoes/drawables/arrow.rb +3 -23
  17. data/lib/shoes/drawables/border.rb +28 -0
  18. data/lib/shoes/drawables/button.rb +5 -21
  19. data/lib/shoes/drawables/check.rb +7 -3
  20. data/lib/shoes/drawables/document_root.rb +4 -4
  21. data/lib/shoes/drawables/edit_box.rb +6 -5
  22. data/lib/shoes/drawables/edit_line.rb +5 -4
  23. data/lib/shoes/drawables/flow.rb +4 -6
  24. data/lib/shoes/drawables/font_helper.rb +62 -0
  25. data/lib/shoes/drawables/image.rb +2 -2
  26. data/lib/shoes/drawables/line.rb +3 -6
  27. data/lib/shoes/drawables/link.rb +16 -9
  28. data/lib/shoes/drawables/list_box.rb +8 -5
  29. data/lib/shoes/drawables/oval.rb +48 -0
  30. data/lib/shoes/drawables/para.rb +106 -18
  31. data/lib/shoes/drawables/progress.rb +2 -1
  32. data/lib/shoes/drawables/radio.rb +5 -3
  33. data/lib/shoes/drawables/rect.rb +7 -6
  34. data/lib/shoes/drawables/shape.rb +4 -3
  35. data/lib/shoes/drawables/slot.rb +102 -9
  36. data/lib/shoes/drawables/stack.rb +7 -12
  37. data/lib/shoes/drawables/star.rb +9 -31
  38. data/lib/shoes/drawables/text_drawable.rb +93 -34
  39. data/lib/shoes/drawables/video.rb +3 -2
  40. data/lib/shoes/drawables/widget.rb +9 -4
  41. data/lib/shoes/drawables.rb +2 -1
  42. data/lib/shoes/errors.rb +13 -3
  43. data/lib/shoes/margin_helper.rb +79 -0
  44. data/lib/shoes.rb +98 -20
  45. metadata +11 -15
  46. data/lib/scarpe/niente/logger.rb +0 -29
  47. data/lib/shoes/drawables/span.rb +0 -27
  48. data/lib/shoes/spacing.rb +0 -9
@@ -1,10 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Shoes::Slot < Shoes::Drawable
4
- # @incompatibility Shoes uses #content, not #children, for this
4
+ # @incompatibility Shoes uses #content, not #children, for this. Scarpe does both.
5
5
  attr_reader :children
6
6
 
7
- shoes_events # No Slot-specific events yet
7
+ shoes_events # No Slot-specific events
8
+
9
+ # This only shows this specific slot's settings, not its parent's.
10
+ # Use current_draw_context to allow inheritance.
11
+ attr_reader :draw_context
12
+
13
+
14
+ def initialize(...)
15
+ # The draw context tracks current settings like fill and stroke,
16
+ # plus potentially other current state that changes from drawable
17
+ # to drawable and slot to slot.
18
+ @draw_context = {
19
+ "fill" => nil,
20
+ "stroke" => nil,
21
+ "strokewidth" => nil,
22
+ "rotate" => nil,
23
+ # "transform" => nil, # "corner",
24
+ # "translate" => nil, # [0, 0],
25
+ }
26
+
27
+ super
28
+ end
8
29
 
9
30
  # Do not call directly, use set_parent
10
31
  def remove_child(child)
@@ -29,30 +50,101 @@ class Shoes::Slot < Shoes::Drawable
29
50
 
30
51
  # We use method_missing for drawable-creating methods like "button".
31
52
  # The parent's method_missing will auto-create Shoes style getters and setters.
53
+ # This is similar to the method_missing in Shoes::App, but differs in where
54
+ # the new drawable will appear.
32
55
  def method_missing(name, *args, **kwargs, &block)
33
56
  klass = ::Shoes::Drawable.drawable_class_by_name(name)
34
57
  return super unless klass
35
58
 
36
59
  ::Shoes::Slot.define_method(name) do |*args, **kwargs, &block|
37
- # Look up the Shoes drawable and create it...
38
- drawable_instance = klass.new(*args, **kwargs, &block)
60
+ instance = nil
39
61
 
40
- unless klass.ancestors.include?(::Shoes::TextDrawable)
41
- drawable_instance.set_parent self # Create drawable in THIS SLOT, not current app slot
62
+ # Look up the Shoes drawable and create it. But first set
63
+ # this slot as the current one so that draw context
64
+ # is handled properly.
65
+ @app.with_slot(self) do
66
+ Shoes::Drawable.with_current_app(self.app) do
67
+ instance = klass.new(*args, **kwargs, &block)
68
+ end
42
69
  end
43
70
 
44
- drawable_instance
71
+ instance
45
72
  end
46
73
 
47
74
  send(name, *args, **kwargs, &block)
48
75
  end
49
76
 
50
77
  def respond_to_missing?(name, include_private = false)
51
- return true if Drawable.drawable_class_by_name(name.to_s)
78
+ return true if ::Shoes::Drawable.drawable_class_by_name(name.to_s)
52
79
 
53
80
  false
54
81
  end
55
82
 
83
+ # Draw context methods
84
+
85
+ # Set the default fill color in this slot and child slots.
86
+ # Pass nil for "no setting", so that it can inherit defaults.
87
+ #
88
+ # @param color [Nil,Color] a Shoes color for the fill color or nil to use parent setting
89
+ # @return [void]
90
+ def fill(color)
91
+ @draw_context["fill"] = color
92
+ end
93
+
94
+ # Set the default fill in this slot and child slots to transparent.
95
+ #
96
+ # @return [void]
97
+ def nofill
98
+ @draw_context["fill"] = rgb(0, 0, 0, 0)
99
+ end
100
+
101
+ # Set the default stroke color in this slot and child slots.
102
+ # Pass nil for "no setting" so it can inherit defaults.
103
+ #
104
+ # @param color [Nil,Color] a Shoes color for the stroke color or nil to use parent setting
105
+ # @return [void]
106
+ def stroke(color)
107
+ @draw_context["stroke"] = color
108
+ end
109
+
110
+ # Set the default strokewidth in this slot and child slots.
111
+ # Pass nil for "no setting".
112
+ #
113
+ # @param width [Numeric,Nil] the new width, or nil to use parent setting
114
+ # @return [void]
115
+ def strokewidth(width)
116
+ @draw_context["strokewidth"] = width
117
+ end
118
+
119
+ # Set the default stroke in this slot and child slots
120
+ # to transparent.
121
+ #
122
+ # @return [void]
123
+ def nostroke
124
+ @draw_context["stroke"] = rgb(0, 0, 0, 0)
125
+ end
126
+
127
+ # Set the current rotation in this slot and any child slots.
128
+ # Pass nil to reset the angle to default.
129
+ #
130
+ # @param angle [Numeric,Nil] the new default rotation for shapes or nil to use parent setting
131
+ # @return [void]
132
+ def rotate(angle)
133
+ @draw_context["rotate"] = angle
134
+ end
135
+
136
+ # Get the current draw context styles, based on this slot and its parent slots.
137
+ #
138
+ # @return [Hash] a hash of Shoes styles for the context
139
+ def current_draw_context
140
+ s = @parent ? @parent.current_draw_context : {}
141
+ @draw_context.each { |k, v| s[k] = v unless v.nil? }
142
+
143
+ s
144
+ end
145
+
146
+ # Methods to add or remove children
147
+
56
148
  # Remove all children from this drawable. If a block
57
149
  # is given, call the block to replace the children with
58
150
  # new contents from that block.
@@ -65,6 +157,7 @@ class Shoes::Slot < Shoes::Drawable
65
157
  # @yield The block to call to replace the contents of the drawable (optional)
66
158
  # @return [void]
67
159
  def clear(&block)
160
+ @children ||= []
68
161
  @children.dup.each(&:destroy)
69
162
  append(&block) if block_given?
70
163
  nil
@@ -82,6 +175,6 @@ class Shoes::Slot < Shoes::Drawable
82
175
  raise(Shoes::Errors::InvalidAttributeValueError, "append requires a block!") unless block_given?
83
176
  raise(Shoes::Errors::InvalidAttributeValueError, "Don't append to something that isn't a slot!") unless self.is_a?(Shoes::Slot)
84
177
 
85
- Shoes::App.instance.with_slot(self, &block)
178
+ @app.with_slot(self, &block)
86
179
  end
87
180
  end
@@ -3,24 +3,19 @@
3
3
  class Shoes
4
4
  class Stack < Shoes::Slot
5
5
  include Shoes::Background
6
- include Shoes::Border
7
- include Shoes::Spacing
8
6
 
9
- # TODO: sort out various margin and padding properties, including putting stuff into spacing
10
- shoes_styles :width, :height, :scroll
7
+ shoes_styles :scroll
11
8
 
12
- shoes_events # No Stack-specific events yet
13
-
14
- def initialize(width: nil, height: nil, margin: nil, padding: nil, scroll: false, margin_top: nil, margin_bottom: nil, margin_left: nil,
15
- margin_right: nil, **options, &block)
16
-
17
- @options = options
9
+ shoes_events # No Stack-specific events
18
10
 
11
+ def initialize(*args, **kwargs, &block)
19
12
  super
20
13
 
21
14
  create_display_drawable
22
- # Create the display-side drawable *before* running the block, which will add child drawables with their display drawables
23
- Shoes::App.instance.with_slot(self, &block) if block_given?
15
+
16
+ # Create the display-side drawable *before* running the block.
17
+ # Then child drawables have a parent to add themselves to.
18
+ @app.with_slot(self, &block) if block_given?
24
19
  end
25
20
  end
26
21
  end
@@ -8,43 +8,21 @@ class Shoes
8
8
  shoes_style(:outer) { |val| convert_to_float(val, "outer") }
9
9
  shoes_style(:inner) { |val| convert_to_float(val, "inner") }
10
10
 
11
- shoes_events # No Star-specific events yet
11
+ Shoes::Drawable.drawable_default_styles[Shoes::Star][:points] = 10
12
+ Shoes::Drawable.drawable_default_styles[Shoes::Star][:outer] = 100
13
+ Shoes::Drawable.drawable_default_styles[Shoes::Star][:inner] = 50
12
14
 
13
- def initialize(left, top, points = 10, outer = 100, inner = 50)
15
+ shoes_events # No Star-specific events
16
+
17
+ init_args :left, :top
18
+ opt_init_args :points, :outer, :inner
19
+ def initialize(*args, **kwargs)
14
20
  super
15
- self.left = left
16
- self.top = top
17
- self.points = points
18
- self.outer = outer
19
- self.inner = inner
20
21
 
21
- @draw_context = Shoes::App.instance.current_draw_context
22
+ @draw_context = @app.current_draw_context
22
23
 
23
24
  create_display_drawable
24
25
  end
25
26
 
26
- def self.convert_to_integer(value, attribute_name)
27
- begin
28
- value = Integer(value)
29
- raise Shoes::Errors::InvalidAttributeValueError, "Negative num '#{value}' not allowed for attribute '#{attribute_name}'" if value < 0
30
-
31
- value
32
- rescue ArgumentError
33
- error_message = "Invalid value '#{value}' provided for attribute '#{attribute_name}'. The value should be a number."
34
- raise Shoes::Errors::InvalidAttributeValueError, error_message
35
- end
36
- end
37
-
38
- def self.convert_to_float(value, attribute_name)
39
- begin
40
- value = Float(value)
41
- raise Shoes::Errors::InvalidAttributeValueError, "Negative num '#{value}' not allowed for attribute '#{attribute_name}'" if value < 0
42
-
43
- value
44
- rescue ArgumentError
45
- error_message = "Invalid value '#{value}' provided for attribute '#{attribute_name}'. The value should be a number."
46
- raise Shoes::Errors::InvalidAttributeValueError, error_message
47
- end
48
- end
49
27
  end
50
28
  end
@@ -4,60 +4,119 @@ class Shoes
4
4
  # TextDrawable is the parent class of various classes of
5
5
  # text that can go inside a para. This includes normal
6
6
  # text, but also links, italic text, bold text, etc.
7
+ #
8
+ # In Shoes3 this corresponds to cText, and it would
9
+ # have methods app, contents, children, parent,
10
+ # style, to_s, text, text= and replace.
11
+ #
12
+ # Much of what this does and how is similar to Para.
13
+ # It's a very similar API.
7
14
  class TextDrawable < Shoes::Drawable
8
- class << self
9
- # rubocop:disable Lint/MissingSuper
10
- def inherited(subclass)
11
- Shoes::Drawable.drawable_classes ||= []
12
- Shoes::Drawable.drawable_classes << subclass
13
-
14
- Shoes::Drawable.drawable_default_styles ||= {}
15
- Shoes::Drawable.drawable_default_styles[subclass] = {}
15
+ shoes_styles :text_items, :size, :stroke, :strokewidth, :fill, :undercolor, :font
16
+
17
+ STRIKETHROUGH_VALUES = [nil, "none", "single"]
18
+ shoes_style :strikethrough do |val, _name|
19
+ unless STRIKETHROUGH_VALUES.include?(val)
20
+ raise Shoes::Errors::InvalidAttributeValueError, "Strikethrough must be one of: #{STRIKETHROUGH_VALUES.inspect}!"
21
+ end
22
+ val
23
+ end
24
+
25
+ UNDERLINE_VALUES = [nil, "none", "single", "double", "low", "error"]
26
+ shoes_style :underline do |val, _name|
27
+ unless UNDERLINE_VALUES.include?(val)
28
+ raise Shoes::Errors::InvalidAttributeValueError, "Underline must be one of: #{UNDERLINE_VALUES.inspect}!"
16
29
  end
17
- # rubocop:enable Lint/MissingSuper
30
+ val
18
31
  end
19
32
 
20
33
  shoes_events # No TextDrawable-specific events yet
21
- end
22
34
 
23
- class << self
24
- def default_text_drawable_with(element)
25
- class_name = element.capitalize
35
+ def initialize(*args, **kwargs)
36
+ # Don't pass text_children args to Drawable#initialize
37
+ super(*[], **kwargs)
26
38
 
27
- drawable_class = Class.new(Shoes::TextDrawable) do
28
- # Can we just change content to text to match the Shoes API?
29
- shoes_style :content
39
+ # Text_children alternates strings and TextDrawables, so we can't just pass
40
+ # it as a Shoes style. It won't serialize.
41
+ update_text_children(args)
30
42
 
31
- def initialize(content)
32
- super
43
+ create_display_drawable
44
+ end
33
45
 
34
- @content = content
46
+ def text_children_to_items(text_children)
47
+ text_children.map { |arg| arg.is_a?(TextDrawable) ? arg.linkable_id : arg.to_s }
48
+ end
35
49
 
36
- create_display_drawable
37
- end
50
+ # Sets the paragraph text to a new value, which can
51
+ # include {TextDrawable}s like em(), strong(), etc.
52
+ #
53
+ # @param children [Array] the arguments can be Strings and/or TextDrawables
54
+ # @return [void]
55
+ def replace(*children)
56
+ update_text_children(children)
57
+ end
38
58
 
39
- def text
40
- self.content
41
- end
59
+ # Set the paragraph text to a single String.
60
+ # To use bold, italics, etc. use {Para#replace} instead.
61
+ #
62
+ # @param child [String] the new text to use for this Para
63
+ # @return [void]
64
+ def text=(*children)
65
+ update_text_children(children)
66
+ end
42
67
 
43
- def to_s
44
- self.content
45
- end
68
+ # Return the text, but not the styling, of the para's
69
+ # contents. For example, if the contents had strong
70
+ # and emphasized text, the bold and emphasized would
71
+ # be removed but the text would be returned.
72
+ #
73
+ # @return [String] the text from this para
74
+ def text
75
+ @text_children.map(&:to_s).join
76
+ end
46
77
 
47
- def text=(new_text)
48
- self.content = new_text
49
- end
50
- end
51
- Shoes.const_set class_name, drawable_class
52
- drawable_class.class_eval do
53
- shoes_style :content
78
+ # Return the text but not styling from the para. This
79
+ # is the same as #text.
80
+ #
81
+ # @return [String] the text from this para
82
+ def to_s
83
+ self.text
84
+ end
85
+
86
+ private
87
+
88
+ # Text_children alternates strings and TextDrawables, so we can't just pass
89
+ # it as a Shoes style. It won't serialize.
90
+ def update_text_children(children)
91
+ @text_children = children.flatten
92
+ # This should signal the display drawable to change
93
+ self.text_items = text_children_to_items(@text_children)
94
+ end
95
+ end
54
96
 
97
+ class << self
98
+ def default_text_drawable_with(element)
99
+ class_name = element.capitalize
100
+
101
+ drawable_class = Class.new(Shoes::TextDrawable) do
55
102
  shoes_events # No specific events
103
+
104
+ init_args # We're going to pass an empty array to super
56
105
  end
106
+ Shoes.const_set class_name, drawable_class
57
107
  end
58
108
  end
59
109
  end
60
110
 
61
111
  Shoes.default_text_drawable_with(:code)
112
+ Shoes.default_text_drawable_with(:del)
62
113
  Shoes.default_text_drawable_with(:em)
63
114
  Shoes.default_text_drawable_with(:strong)
115
+ Shoes.default_text_drawable_with(:span)
116
+ Shoes.default_text_drawable_with(:sub)
117
+ Shoes.default_text_drawable_with(:sup)
118
+ Shoes.default_text_drawable_with(:ins) # in Shoes3, looks like "ins" is just underline
119
+
120
+ # Defaults must come *after* classes are defined
121
+
122
+ Shoes::Drawable.drawable_default_styles[Shoes::Ins][:underline] = "single"
@@ -5,9 +5,10 @@ class Shoes
5
5
  shoes_styles :url
6
6
  shoes_events # No specific events yet
7
7
 
8
- def initialize(url)
8
+ init_args :url
9
+ def initialize(*args, **kwargs)
9
10
  super
10
- @url = url
11
+
11
12
  create_display_drawable
12
13
  end
13
14
 
@@ -37,11 +37,16 @@
37
37
 
38
38
  class Shoes::Widget < Shoes::Slot
39
39
  include Shoes::Background
40
- include Shoes::Border
41
- include Shoes::Spacing
42
40
 
43
41
  shoes_events
44
42
 
43
+ def self.inherited(subclass)
44
+ super
45
+
46
+ # Widgets are special - we can't know in advance what sort of initialize args they take
47
+ subclass.init_args :any
48
+ end
49
+
45
50
  def self.method_added(name)
46
51
  # We're only looking for the initialize() method, and only on subclasses
47
52
  # of Shoes::Widget, not Shoes::Widget itself.
@@ -57,12 +62,12 @@ class Shoes::Widget < Shoes::Slot
57
62
  @midway_through_adding_initialize = true
58
63
  define_method(:initialize) do |*args, **kwargs, &block|
59
64
  super(*args, **kwargs, &block)
60
- @options = kwargs
65
+ @options = kwargs # Get rid of options?
61
66
  create_display_drawable
62
67
  __widget_initialize(*args, **kwargs, &block)
63
68
 
64
69
  # Do Widgets do this?
65
- Shoes::App.instance.with_slot(self, &block) if block
70
+ @app.with_slot(self, &block) if block
66
71
  end
67
72
  @midway_through_adding_initialize = false
68
73
  end
@@ -15,6 +15,7 @@ require "shoes/drawables/line"
15
15
  require "shoes/drawables/rect"
16
16
  require "shoes/drawables/shape"
17
17
  require "shoes/drawables/star"
18
+ require "shoes/drawables/oval"
18
19
  require "shoes/drawables/arrow"
19
20
 
20
21
  require "shoes/drawables/button"
@@ -26,6 +27,6 @@ require "shoes/drawables/link"
26
27
  require "shoes/drawables/list_box"
27
28
  require "shoes/drawables/para"
28
29
  require "shoes/drawables/radio"
29
- require "shoes/drawables/span"
30
30
  require "shoes/drawables/video"
31
31
  require "shoes/drawables/progress"
32
+ require "shoes/drawables/border"
data/lib/shoes/errors.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Shoes; end
4
- class Shoes::Errors
4
+ module Shoes::Errors
5
5
  class InvalidAttributeValueError < Shoes::Error; end
6
6
 
7
7
  class TooManyInstancesError < Shoes::Error; end
@@ -16,13 +16,23 @@ class Shoes::Errors
16
16
 
17
17
  class NoSuchStyleError < Shoes::Error; end
18
18
 
19
- class NoLinkableIdError < Shoes::Error; end
19
+ class NoSuchLinkableIdError < Shoes::Error; end
20
20
 
21
21
  class BadLinkableIdError < Shoes::Error; end
22
22
 
23
- class UnregisteredShoesEvent < Shoes::Error; end
23
+ class UnregisteredShoesEventError < Shoes::Error; end
24
+
25
+ class BadArgumentListError < Shoes::Error; end
24
26
 
25
27
  class SingletonError < Shoes::Error; end
26
28
 
27
29
  class MultipleShoesSpecRunsError < Shoes::Error; end
30
+
31
+ class UnsupportedFeatureError < Shoes::Error; end
32
+
33
+ class BadFilenameError < Shoes::Error; end
34
+
35
+ class UnknownEventsForClassError < Shoes::Error; end
36
+
37
+ class DoubleRegisteredShoesEventError < Shoes::Error; end
28
38
  end
@@ -0,0 +1,79 @@
1
+ module MarginHelper
2
+
3
+ def margin_parse(kwargs)
4
+
5
+ if kwargs[:margin]
6
+
7
+ if kwargs[:margin].is_a?(Numeric)
8
+
9
+ if !kwargs[:margin_top]
10
+ kwargs[:margin_top] = kwargs[:margin]
11
+ end
12
+ if !kwargs[:margin_bottom]
13
+ kwargs[:margin_bottom] = kwargs[:margin]
14
+ end
15
+ if !kwargs[:margin_left]
16
+ kwargs[:margin_left] = kwargs[:margin]
17
+ end
18
+ if !kwargs[:margin_right]
19
+ kwargs[:margin_right] = kwargs[:margin]
20
+ end
21
+
22
+ elsif kwargs[:margin].is_a?(Hash)
23
+
24
+ kwargs[:margin].each do |key,value|
25
+ kwargs[:"margin_#{key}"] = value
26
+ end
27
+
28
+ else
29
+ margin_props = kwargs[:margin].is_a?(String) ? kwargs[:margin].split(/\s+|\,|-/) : kwargs[:margin]
30
+ if margin_props.length == 1
31
+
32
+ if !kwargs[:margin_top]
33
+ kwargs[:margin_top] = margin_props[0]
34
+ end
35
+ if !kwargs[:margin_bottom]
36
+ kwargs[:margin_bottom] = margin_props[0]
37
+ end
38
+ if !kwargs[:margin_left]
39
+ kwargs[:margin_left] = margin_props[0]
40
+ end
41
+ if !kwargs[:margin_right]
42
+ kwargs[:margin_right] = margin_props[0]
43
+ end
44
+
45
+ elsif margin_props.length == 2
46
+
47
+ raise(Shoes::Errors::InvalidAttributeValueError, "Margin don't support 2-3 values as Array/string input for using 2-3 input you can use the hash input method like '{left:value, right:value, top:value, bottom:value}'")
48
+
49
+ elsif margin_props.length == 3
50
+
51
+ raise(Shoes::Errors::InvalidAttributeValueError, "Margin don't support 2-3 values as Array/string input for using 2-3 input you can use the hash input method like '{left:value,right:value,top:value,bottom:value}'")
52
+
53
+ else
54
+
55
+ if !kwargs[:margin_top]
56
+ kwargs[:margin_top] = margin_props[1]
57
+ end
58
+ if !kwargs[:margin_bottom]
59
+ kwargs[:margin_bottom] = margin_props[3]
60
+ end
61
+ if !kwargs[:margin_left]
62
+ kwargs[:margin_left] = margin_props[0]
63
+ end
64
+ if !kwargs[:margin_right]
65
+ kwargs[:margin_right] = margin_props[2]
66
+ end
67
+
68
+ end
69
+ end
70
+ kwargs[:margin] = nil
71
+ end
72
+ if kwargs["options"] && !kwargs[:margin] && !kwargs[:margin_left] && !kwargs[:margin_right] && !kwargs[:margin_top] && !kwargs[:margin_bottom]
73
+ kwargs[options].each do |key,value|
74
+ kwargs[key] = value
75
+ end
76
+ end
77
+ kwargs
78
+ end
79
+ end