@@ -8,64 +8,89 @@ module Elements
88 class Style
99 include Docx ::SimpleInspect
1010
11- @attributes = [ ]
11+ class Attribute
12+ attr_reader :name , :selectors , :required , :converter , :validator
13+
14+ def initialize ( name , selectors , required : false , converter :, validator :)
15+ @name = name
16+ @selectors = selectors
17+ @required = required
18+ @converter = converter || Converters ::DefaultValueConverter
19+ @validator = validator || Validators ::DefaultValidator
20+ end
1221
13- class << self
14- attr_accessor :attributes
22+ def required?
23+ required
24+ end
1525
16- def required_attributes
17- attributes . select { |a | a [ :required ] }
26+ def retrieve_from ( style )
27+ selectors
28+ . lazy
29+ . filter_map { |node_xpath | style . node . at_xpath ( node_xpath ) &.value }
30+ . map { |value | converter . decode ( value ) }
31+ . first
1832 end
1933
20- def attribute ( name , *selectors , required : false , converter : Converters ::DefaultValueConverter , validator : Validators ::DefaultValidator )
21- attributes << { name : name , selectors : selectors , required : required , converter : converter , validator : validator }
34+ def assign_to ( style , value )
35+ ( required && value . nil? ) &&
36+ raise ( Errors ::StyleRequiredPropertyValue , "Required value #{ name } " )
2237
23- define_method ( name ) do
24- selectors
25- . lazy
26- . filter_map { |node_xpath | node . at_xpath ( node_xpath ) &.value }
27- . map { |value | converter . decode ( value ) }
28- . first
29- end
38+ validator . validate ( value ) ||
39+ raise ( Errors ::StyleInvalidPropertyValue , "Invalid value for #{ name } : '#{ value . nil? ? "nil" : value } '" )
3040
31- define_method ( "#{ name } =" ) do |value |
32- ( required && value . nil? ) &&
33- raise ( Errors ::StyleRequiredPropertyValue , "Required value #{ name } " )
41+ encoded_value = converter . encode ( value )
3442
35- validator . validate ( value ) ||
36- raise ( Errors ::StyleInvalidPropertyValue , "Invalid value for #{ name } : '#{ value . nil? ? "nil" : value } '" )
43+ selectors . map do |attribute_xpath |
44+ if ( existing_attribute = style . node . at_xpath ( attribute_xpath ) )
45+ if encoded_value . nil?
46+ existing_attribute . remove
47+ else
48+ existing_attribute . value = encoded_value . to_s
49+ end
3750
38- encoded_value = converter . encode ( value )
51+ next encoded_value
52+ end
3953
40- selectors . map do |attribute_xpath |
41- if ( existing_attribute = node . at_xpath ( attribute_xpath ) )
42- if encoded_value . nil?
43- existing_attribute . remove
44- else
45- existing_attribute . value = encoded_value . to_s
54+ next encoded_value if encoded_value . nil?
55+
56+ node_xpath , attribute = attribute_xpath . split ( "/@" )
57+
58+ created_node =
59+ node_xpath
60+ . split ( "/" )
61+ . reduce ( style . node ) do |parent_node , child_xpath |
62+ # find the child node
63+ parent_node . at_xpath ( child_xpath ) ||
64+ # or create the child node
65+ Nokogiri ::XML ::Node . new ( child_xpath , parent_node )
66+ . tap { |created_child_node | parent_node << created_child_node }
4667 end
4768
48- next encoded_value
49- end
69+ created_node . set_attribute ( attribute , encoded_value )
70+ end
71+ . first
72+ end
73+ end
74+
75+ @attributes = [ ]
76+
77+ class << self
78+ attr_accessor :attributes
5079
51- next encoded_value if encoded_value . nil?
80+ def required_attributes
81+ attributes . select ( &:required? )
82+ end
5283
53- node_xpath , attribute = attribute_xpath . split ( "/@" )
84+ def attribute ( name , *selectors , required : false , converter : nil , validator : nil )
85+ new_attribute = Attribute . new ( name , selectors , required : required , converter : converter , validator : validator )
86+ attributes << new_attribute
5487
55- created_node =
56- node_xpath
57- . split ( "/" )
58- . reduce ( node ) do |parent_node , child_xpath |
59- # find the child node
60- parent_node . at_xpath ( child_xpath ) ||
61- # or create the child node
62- Nokogiri ::XML ::Node . new ( child_xpath , parent_node )
63- . tap { |created_child_node | parent_node << created_child_node }
64- end
88+ define_method ( name ) do
89+ new_attribute . retrieve_from ( self )
90+ end
6591
66- created_node . set_attribute ( attribute , encoded_value )
67- end
68- . first
92+ define_method ( "#{ name } =" ) do |value |
93+ new_attribute . assign_to ( self , value )
6994 end
7095 end
7196
@@ -135,11 +160,9 @@ def initialize(configuration, node, **attributes)
135160
136161 def valid?
137162 self . class . required_attributes . all? do |a |
138- validator = a [ :validator ]
139- attribute_name = a [ :name ]
140- attribute_value = self . send ( attribute_name )
163+ attribute_value = a . retrieve_from ( self )
141164
142- validator &.validate ( attribute_value )
165+ a . validator &.validate ( attribute_value )
143166 end
144167 end
145168
0 commit comments