opulent 1.4.0 → 1.4.1

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/benchmark/benchmark.rb +18 -7
  3. data/benchmark/cases/node/node.haml +6 -16
  4. data/benchmark/cases/node/node.op +6 -13
  5. data/benchmark/cases/node/node.slim +6 -18
  6. data/docs/comments.md +5 -0
  7. data/docs/filters.md +31 -0
  8. data/docs/includes.md +0 -0
  9. data/docs/nodes.md +88 -0
  10. data/docs/reference.md +7 -6
  11. data/lib/opulent.rb +2 -1
  12. data/lib/opulent/compiler.rb +19 -18
  13. data/lib/opulent/compiler/buffer.rb +260 -0
  14. data/lib/opulent/compiler/comment.rb +4 -9
  15. data/lib/opulent/compiler/control.rb +65 -67
  16. data/lib/opulent/compiler/define.rb +91 -63
  17. data/lib/opulent/compiler/doctype.rb +1 -5
  18. data/lib/opulent/compiler/eval.rb +1 -1
  19. data/lib/opulent/compiler/node.rb +10 -194
  20. data/lib/opulent/compiler/root.rb +1 -1
  21. data/lib/opulent/compiler/text.rb +3 -40
  22. data/lib/opulent/compiler/yield.rb +15 -0
  23. data/lib/opulent/context.rb +2 -2
  24. data/lib/opulent/engine.rb +56 -57
  25. data/lib/opulent/parser.rb +10 -10
  26. data/lib/opulent/parser/control.rb +2 -3
  27. data/lib/opulent/parser/expression.rb +1 -1
  28. data/lib/opulent/parser/{require.rb → include.rb} +17 -15
  29. data/lib/opulent/parser/node.rb +22 -17
  30. data/lib/opulent/parser/root.rb +3 -4
  31. data/lib/opulent/parser/text.rb +3 -7
  32. data/lib/opulent/parser/yield.rb +23 -0
  33. data/lib/opulent/settings.rb +5 -4
  34. data/lib/opulent/template.rb +12 -30
  35. data/lib/opulent/tokens.rb +5 -9
  36. data/lib/opulent/utils.rb +41 -0
  37. data/lib/opulent/version.rb +1 -1
  38. metadata +9 -5
  39. data/lib/opulent/compiler/block.rb +0 -31
  40. data/lib/opulent/parser/block.rb +0 -56
@@ -9,15 +9,10 @@ module Opulent
9
9
  # @param context [Context] Processing environment data
10
10
  #
11
11
  def comment(node, indent, context)
12
- indentation = " " * indent
13
-
14
- # Escaping double quotes is required in order to avoid any conflicts with the eval quotes.
15
- value = indent_lines context.evaluate('"' + node[@value].gsub('"', '\\"') + '"'), " " * indent
16
-
17
- comment_tag = "#{"\n" if node[@options][:newline]}#{indentation}<!-- #{value.strip} -->\n"
18
-
19
- @node_stack << :comment
20
- @code += comment_tag
12
+ buffer_freeze "\n" if node[@options][:newline]
13
+ buffer_freeze "<!-- "
14
+ buffer_split_by_interpolation node[@value].strip, false
15
+ buffer_freeze " -->"
21
16
  end
22
17
  end
23
18
  end
@@ -10,17 +10,23 @@ module Opulent
10
10
  #
11
11
  def if_node(node, indent, context)
12
12
  # Check if we have any condition met, or an else branch
13
- index = node[@value].index do |value|
14
- value.empty? || context.evaluate(value)
15
- end
13
+ node[@value].each_with_index do |value, index|
14
+ # If we have a branch that meets the condition, generate code for the
15
+ # children related to that specific branch
16
+ case value
17
+ when node[@value].first then buffer_eval "if #{value}"
18
+ when node[@value].last then buffer_eval "else"
19
+ else buffer_eval "elsif #{value}"
20
+ end
16
21
 
17
- # If we have a branch that meets the condition, generate code for the
18
- # children related to that specific branch
19
- if index
22
+ # Evaluate child nodes
20
23
  node[@children][index].each do |child|
21
24
  root child, indent, context
22
25
  end
23
26
  end
27
+
28
+ # End
29
+ buffer_eval "end"
24
30
  end
25
31
 
26
32
  # Generate the code for a unless-else control structure
@@ -31,17 +37,22 @@ module Opulent
31
37
  #
32
38
  def unless_node(node, indent, context)
33
39
  # Check if we have any condition met, or an else branch
34
- index = node[@value].index do |value|
35
- value.empty? || !context.evaluate(value)
36
- end
40
+ node[@value].each_with_index do |value, index|
41
+ # If we have a branch that meets the condition, generate code for the
42
+ # children related to that specific branch
43
+ case value
44
+ when node[@value].first then buffer_eval "unless #{value}"
45
+ else buffer_eval "else"
46
+ end
37
47
 
38
- # If we have a branch that meets the condition, generate code for the
39
- # children related to that specific branch
40
- if index
48
+ # Evaluate child nodes
41
49
  node[@children][index].each do |child|
42
50
  root child, indent, context
43
51
  end
44
52
  end
53
+
54
+ # End
55
+ buffer_eval "end"
45
56
  end
46
57
 
47
58
  # Generate the code for a case-when-else control structure
@@ -52,20 +63,25 @@ module Opulent
52
63
  #
53
64
  def case_node(node, indent, context)
54
65
  # Evaluate the switching condition
55
- switch_case = context.evaluate node[@options][:condition]
66
+ buffer_eval "case #{node[@options][:condition]}"
56
67
 
57
68
  # Check if we have any condition met, or an else branch
58
- index = node[@value].index do |value|
59
- value.empty? || switch_case == context.evaluate(value)
60
- end
69
+ node[@value].each_with_index do |value, index|
70
+ # If we have a branch that meets the condition, generate code for the
71
+ # children related to that specific branch
72
+ case value
73
+ when node[@value].last then buffer_eval "else"
74
+ else buffer_eval "when #{value}"
75
+ end
61
76
 
62
- # If we have a branch that meets the condition, generate code for the
63
- # children related to that specific branch
64
- if index
77
+ # Evaluate child nodes
65
78
  node[@children][index].each do |child|
66
79
  root child, indent, context
67
80
  end
68
81
  end
82
+
83
+ # End
84
+ buffer_eval "end"
69
85
  end
70
86
 
71
87
  # Generate the code for a while control structure
@@ -77,11 +93,15 @@ module Opulent
77
93
  def while_node(node, indent, context)
78
94
  # While we have a branch that meets the condition, generate code for the
79
95
  # children related to that specific branch
80
- while context.evaluate node[@value]
81
- node[@children].each do |child|
82
- root child, indent, context
83
- end
96
+ buffer_eval "while #{node[@value]}"
97
+
98
+ # Evaluate child nodes
99
+ node[@children].each do |child|
100
+ root child, indent, context
84
101
  end
102
+
103
+ #End
104
+ buffer_eval "end"
85
105
  end
86
106
 
87
107
  # Generate the code for a while control structure
@@ -93,11 +113,15 @@ module Opulent
93
113
  def until_node(node, indent, context)
94
114
  # Until we have a branch that doesn't meet the condition, generate code for the
95
115
  # children related to that specific branch
96
- until context.evaluate node[@value]
97
- node[@children].each do |child|
98
- root child, indent, context
99
- end
116
+ buffer_eval "until #{node[@value]}"
117
+
118
+ # Evaluate child nodes
119
+ node[@children].each do |child|
120
+ root child, indent, context
100
121
  end
122
+
123
+ # End
124
+ buffer_eval "end"
101
125
  end
102
126
 
103
127
  # Generate the code for a while control structure
@@ -107,10 +131,8 @@ module Opulent
107
131
  # @param context [Context] Processing environment data
108
132
  #
109
133
  def each_node(node, indent, context)
110
- result = []
111
-
112
134
  # Process named variables for each structure
113
- variables = node[@value][0].clone
135
+ variables = node[@value][1].clone
114
136
 
115
137
  # The each structure accept missing arguments as well, therefore we need to
116
138
  # substitute them with our defaults
@@ -129,46 +151,22 @@ module Opulent
129
151
  variables[1] = Settings::DefaultEachValue
130
152
  end
131
153
 
132
- # Evaluate in current context and add to results
133
- evaluate_children = Proc.new do |key, value, context|
134
- # Update the local variables in the each context with the values from the
135
- # current loop iteration
136
- locals = {
137
- variables[0] => key,
138
- variables[1] => value
139
- }
140
- context.extend_locals locals
141
-
142
- # Add the mapped child elements
143
- node[@children].each do |child|
144
- root child, indent, context
145
- end
154
+ # Choose whether to apply each with index (Arrays) or each (Hashes) methods
155
+ #buffer_eval "_opulent_send_method = (#{node[@value][1]}.is_a?(Array) ? :each_with_index : :each)"
156
+ case node[@value][0][0]
157
+ when '[]'
158
+ buffer_eval "#{node[@value][0][1]}.each_with_index do |#{variables.reverse.join ', '}|"
159
+ else
160
+ buffer_eval "#{node[@value][0][1]}.each do |#{variables.join ', '}|"
146
161
  end
147
162
 
148
- # Create a new context based on the parent context and progressively update
149
- # variables in the new context
150
- block = context.block.clone if context.block
151
- each_context = Context.new Hash.new, &block
152
- each_context.parent = context
153
-
154
- # Evaluate the iterable object
155
- enumerable = context.evaluate(node[@value][1])
156
-
157
- # Check if input can be iterated
158
- self.error :enumerable, node[@value][1] unless enumerable.respond_to? :each
159
-
160
- # Selectively iterate through the input and add the result using the previously
161
- # defined proc object
162
- case enumerable
163
- when Hash
164
- enumerable.each do |key, value|
165
- evaluate_children[key, value, context]
166
- end
167
- else
168
- enumerable.each_with_index do |value, key|
169
- evaluate_children[key, value, context]
170
- end
163
+ # Evaluate child nodes
164
+ node[@children].each do |child|
165
+ root child, indent, context
171
166
  end
167
+
168
+ # End
169
+ buffer_eval "end"
172
170
  end
173
171
  end
174
172
  end
@@ -9,87 +9,115 @@ module Opulent
9
9
  # @param context [Context] Context holding environment variables
10
10
  #
11
11
  def def_node(node, indent, context)
12
- # Create a new definition context
13
- #
14
- # @update: Added &context.block to make sure yield can be called from
15
- # within a definition (it might be a nice feature)
16
- #
17
- definition_context = Context.new &context.block
18
- definition_context.extend_nonlocals context.binding
19
- definition_context.name = node[@value]
20
- definition_context.parent = context
12
+ # Set a namespace for the current node definition and make it a valid ruby
13
+ # method name
14
+ key = "_opulent_definition_#{node[@value]}_#{@current_definition += 1}".gsub '-', '_'
21
15
 
22
- # Set call node
16
+ # Set call variable
23
17
  call_node = node[@options][:call]
24
18
 
25
- # Get call node attributes
26
- attributes = call_node[@options][:attributes]
19
+ # Create the definition
20
+ buffer_eval "instance_eval do"
21
+ buffer_eval "def #{key}(attributes = {}, &block)"
27
22
 
28
- # Evaluate node extension in the current context
29
- if call_node[@options][:extension]
30
- extension = context.evaluate call_node[@options][:extension][@value]
31
- else
32
- extension = {}
23
+ # Set each parameter as a local variable
24
+ node[@options][:parameters].each do |parameter, value|
25
+ set_argument_code = "#{parameter} = attributes.delete(:#{parameter})"
26
+ set_argument_code += " || #{value[@value]}" if value[@value]
27
+ buffer_eval set_argument_code
33
28
  end
34
29
 
35
- # Evaluate and generate node attributes, then process each one to
36
- # by generating the required attribute code
37
- attributes = {}
38
- call_node[@options][:attributes].each do |key, attribute|
39
- unless node[@options][:parameters].has_key? key
40
- attributes[key] = map_attribute key, attribute, context
41
- end
30
+ # Evaluate definition child elements
31
+ node[@children].each do |child|
32
+ root child, indent + Settings[:indent], context
42
33
  end
43
34
 
44
- # Go through each extension attribute and use the value where applicable
45
- extend_attributes attributes, extension
35
+ # End
36
+ buffer_eval "end"
37
+ buffer_eval "end"
46
38
 
47
- # Definition call arguments
48
- arguments = {}
39
+ # If we have attributes set for our defined node, we will need to create
40
+ # an extension parameter which will be o
41
+ if call_node[@options][:attributes].empty?
42
+ # Call method without any extension
43
+ buffer_eval "#{key}() do"
44
+ else
45
+ call_attributes_code = buffer_attributes_to_hash call_node[@options][:attributes]
49
46
 
50
- # Extract values which appear as definition parameters. If we have the
51
- # key passed as argument, get its value. Otherwise, set the default
52
- # parameter value.
53
- #
54
- # Definition arguments (parameters which are set in definition header)
55
- # will be passed unescaped, to allow node definition to handle escaping
56
- # properly
57
- node[@options][:parameters].each do |key, value|
58
- if call_node[@options][:attributes].has_key? key
59
- arguments[key] = context.evaluate call_node[@options][:attributes][key][@value]
60
- else
61
- arguments[key] = definition_context.evaluate value[@value]
62
- end
63
- end
47
+ # Set call node parameters
48
+ call_attributes = buffer_set_variable :call_attributes, call_attributes_code
64
49
 
65
- # Set the remaining attributes as a value in the arguments
66
- arguments[:attributes] = attributes
50
+ # If the call node is extended as well, merge the call attributes hash with
51
+ # the extension hash
52
+ if call_node[@options][:extension]
53
+ extension_attributes = buffer_set_variable :extension, call_node[@options][:extension][@value]
54
+ buffer_eval "#{call_attributes}.merge!(#{extension_attributes}) do |#{OpulentKey}, #{OpulentValue}1, #{OpulentValue}2|"
55
+ buffer_eval "#{OpulentKey} == :class ? (#{OpulentValue}1 += #{OpulentValue}2) : (#{OpulentValue}2)"
56
+ buffer_eval "end"
57
+ end
67
58
 
68
- # Add call children to the block stack, depending on whether they're
69
- # block elements or child elements
70
- @block_stack << { @default_yield => [] }
59
+ buffer_eval "#{key}(#{call_attributes}) do"
60
+ end
71
61
 
72
- # If we have a direct child, add it to the default yield (children)
73
- # block and allow same block multiple times by appending nodes
62
+ # Set call node children as block evaluation. Very useful for
63
+ # performance and evaluating them in the parent context
74
64
  call_node[@children].each do |child|
75
- if child[@type] == :block
76
- @block_stack[-1][child[@value]] ||= []
77
- @block_stack[-1][child[@value]] += child[@children]
78
- else
79
- @block_stack[-1][@default_yield] << child
80
- end
65
+ root child, indent + Settings[:indent], context
81
66
  end
82
67
 
83
- # Set variable to determine available blocks
84
- arguments[:blocks] = Hash[@block_stack[-1].keys.map{|key| [key, true]}]
68
+ # End block
69
+ buffer_eval "end"
85
70
 
86
- # Create local variables from argument variables
87
- definition_context.extend_locals arguments
88
71
 
89
- # Evaluate the model using the new context
90
- node[@children].each do |child|
91
- root child, indent, definition_context
92
- end
72
+
73
+ # definition_context.parent = context
74
+ #
75
+ # # # Set call node
76
+ # # call_node = node[@options][:call]
77
+ # #
78
+ # # # Get call node attributes
79
+ # # attributes = call_node[@options][:attributes]
80
+ # #
81
+ # # Evaluate node extension in the current context
82
+ # if call_node[@options][:extension]
83
+ # extension = context.evaluate call_node[@options][:extension][@value]
84
+ # else
85
+ # extension = {}
86
+ # end
87
+ #
88
+ # # Evaluate and generate node attributes, then process each one to
89
+ # # by generating the required attribute code
90
+ # attributes = {}
91
+ # call_node[@options][:attributes].each do |key, attribute|
92
+ # unless node[@options][:parameters].has_key? key
93
+ # attributes[key] = map_attribute key, attribute, context
94
+ # end
95
+ # end
96
+ #
97
+ # # Go through each extension attribute and use the value where applicable
98
+ # extend_attributes attributes, extension
99
+ #
100
+ # # Definition call arguments
101
+ # arguments = {}
102
+ #
103
+ # # Extract values which appear as definition parameters. If we have the
104
+ # # key passed as argument, get its value. Otherwise, set the default
105
+ # # parameter value.
106
+ # #
107
+ # # Definition arguments (parameters which are set in definition header)
108
+ # # will be passed unescaped, to allow node definition to handle escaping
109
+ # # properly
110
+ # node[@options][:parameters].each do |key, value|
111
+ # if call_node[@options][:attributes].has_key? key
112
+ # arguments[key] = context.evaluate call_node[@options][:attributes][key][@value]
113
+ # else
114
+ # arguments[key] = definition_context.evaluate value[@value]
115
+ # end
116
+ # end
117
+ #
118
+ # # Set the remaining attributes as a value in the arguments
119
+ # arguments[:attributes] = attributes
120
+
93
121
 
94
122
  # Remove last set of blocks from the block stack
95
123
  @block_stack.pop
@@ -10,8 +10,6 @@ module Opulent
10
10
  # @param context [Context] Processing environment data
11
11
  #
12
12
  def doctype_node(node, indent, context)
13
- indentation = " " * indent
14
-
15
13
  value = case node[@value]
16
14
  when :"", :"html", :"5"
17
15
  "!DOCTYPE html"
@@ -33,10 +31,8 @@ module Opulent
33
31
  '?xml version="1.0" encoding="iso-8859-1" ?'
34
32
  end
35
33
 
36
- doctype_tag = "#{indentation}<#{value}>\n"
37
-
38
34
  @node_stack << :doctype
39
- @code += doctype_tag
35
+ buffer_freeze "<#{value}>"
40
36
  end
41
37
  end
42
38
  end
@@ -9,7 +9,7 @@ module Opulent
9
9
  # @param context [Context] Processing environment data
10
10
  #
11
11
  def evaluate(node, indent, context)
12
- context.evaluate node[@value]
12
+ buffer_eval node[@value]
13
13
  end
14
14
  end
15
15
  end
@@ -12,223 +12,39 @@ module Opulent
12
12
  def node(node, indent, context)
13
13
  indentation = " " * indent
14
14
 
15
- # Check if the current node and last node should be displayed inline
16
- inline_current = @inline_node.include? node[@value]
17
- inline_last = @inline_node.include? @node_stack.last
18
-
19
- # Check if the node is a special node which can be either inline or
20
- # block structure. Write the special node as inline if its children
21
- # are all inline nodes
22
- if @multi_node.include?(node[@value])
23
- # First condition should be removed to ignore preceding node and make
24
- # it be inline no matter what. Using the first check, we write it
25
- # inline only if the element before it was inline
26
- unless @sibling_stack.last > 1 && node[@children].all? do |child|
27
- @inline_node.include?(child[@value])
28
- end
29
- inline_current = false
30
- multi = true
31
- end
32
- end
33
-
34
- # If we have an inline node, we remove the trailing newline character
35
- # and write the tag code directly. Otherwise we add the tag code with
36
- # normal indentation
37
- if inline_last && inline_current
38
- remove_trailing_newline
39
- else
40
- @code += indentation
41
- end
42
-
43
15
  # Add the tag opening, with leading whitespace to the code buffer
44
- tag_open = "<#{node[@value]}"
45
- @code += " " if node[@options][:leading_whitespace]
46
- @code += tag_open
16
+ buffer_freeze " " if node[@options][:leading_whitespace]
17
+ buffer_freeze "<#{node[@value]}"
47
18
 
48
19
  # Evaluate node extension in the current context
49
- if node[@options][:extension]
50
- extension = context.evaluate node[@options][:extension][@value]
51
- else
52
- extension = {}
20
+ extension = if node[@options][:extension]
21
+ buffer_set_variable :extension, node[@options][:extension][@value]
53
22
  end
54
23
 
55
24
  # Evaluate and generate node attributes, then process each one to
56
25
  # by generating the required attribute code
57
26
  attributes = {}
58
- node[@options][:attributes].each do |key, attribute|
59
- attributes[key] = map_attribute key, attribute, context
60
- end
27
+ buffer_attributes node[@options][:attributes], extension
61
28
 
62
- # Go through each extension attribute and use the value where applicable
63
- extend_attributes attributes, extension
64
-
65
- # Join arrays, create new attributes by hash and set the
66
- # value otherwise
67
- attributes.each do |key, value|
68
- @code += attribute_code key, value
69
- end
70
-
71
- # Set the current node as a parent for the node elements to follow
72
- @node_stack << (multi ? :multi : node[@value])
73
29
 
74
30
  # Check if the current node is self enclosing. Self enclosing nodes
75
31
  # do not have any child elements
76
32
  if node[@options][:self_enclosing]
77
33
  # If the tag is self enclosing, it cannot have any child elements.
78
- tag_close = ">"
79
- tag_close += "\n"
80
-
81
- @code += tag_close
34
+ buffer_freeze ">"
82
35
  else
83
36
  # Set tag ending code
84
- tag_end = ">"
85
-
86
- # If the node is an inline node and doesn't have any child elements,
87
- # we close it on the same line, without adding indentation
88
- tag_end += "\n" unless inline_current || node[@children].empty?
89
-
90
- # Set tag closing code
91
- tag_close = "</#{node[@value]}>"
92
- tag_close += " " if node[@options][:trailing_whitespace]
93
- tag_close += "\n"
94
-
95
- # Add tag ending to the buffer
96
- @code += tag_end
97
-
98
- # Get number of siblings
99
- @sibling_stack << node[@children].size
37
+ buffer_freeze ">"
100
38
 
101
39
  # Process each child element recursively, increasing indentation
102
40
  node[@children].each do |child|
103
41
  root child, indent + Settings[:indent], context
104
42
  end
105
43
 
106
- # Remove the current node children count from the sibling stack
107
- @sibling_stack.pop
108
-
109
- # Remove all child nodes of the current node from the node stack
110
- @node_stack.pop(node[@children].size)
111
-
112
- # If we have an inline node, we remove the trailing newline from
113
- # our buffer, otherwise add indentation
114
- if inline_current
115
- remove_trailing_newline
116
-
117
- # If the node doesn't have any child elements, we close it on the same
118
- # line, without adding indentation
119
- elsif node[@children].any?
120
- @code += indentation
121
- end
122
-
123
- # Close the current tag
124
- @code += tag_close
125
- end
126
- end
127
-
128
- # Map attributes by evaluating them in the current working context
129
- #
130
- # @param key [Symbol] Name of the attribute being processed
131
- # @param attribute [Array] Attribute instance data
132
- # @param context [Context] Processing environment data
133
- #
134
- def map_attribute(key, attribute, context)
135
- # Process input value depending on its type. When array or hash, iterate
136
- # and escape each string value.
137
- process = Proc.new do |value|
138
- case value
139
- when Array
140
- value.map do |v|
141
- v.is_a?(String) ? escape(v) : v
142
- end
143
- when Hash
144
- value.each do |k,v|
145
- value[k] = value[k].is_a?(String) ? escape(v) : v
146
- end
147
- when String
148
- escape value
149
- else
150
- value
151
- end
152
- end
153
-
154
- # Process each attribute depending on whether it's an array of values,
155
- # exclusive to the class attribute, or an individual attribute value
156
- if key == :class
157
- attribute.map do |attrib|
158
- value = context.evaluate attrib[@value]
159
- attrib[@options][:escaped] ? process[value] : value
160
- end
161
- else
162
- value = context.evaluate attribute[@value]
163
- attribute[@options][:escaped] ? process[value] : value
164
- end
165
- end
166
-
167
- # Extend attributes using the extension directive where applicable.
168
- # Concatenate arrays, merge hashes and replace otherwise
169
- #
170
- # @param attributes [Hash] Evaluated node attributes
171
- # @param extension [Hash] Node extension input
172
- #
173
- def extend_attributes(attributes, extension)
174
- extension.each do |key, value|
175
- case attributes[key]
176
- when Array
177
- if key == :class
178
- attributes[key] << value
179
- attributes[key].flatten!
180
- else
181
- attributes[key] = value
182
- end
183
- when Hash
184
- if value.is_a? Hash
185
- attributes[key].merge! value
186
- else
187
- attributes[key] = value
188
- end
189
- else
190
- attributes[key] = value
191
- end
192
- end
193
- end
194
-
195
- # Generate attribute code for the current key value pair. For string
196
- # values, generate a key value pair. For false values, remove the
197
- # attribute. For true values, generate a standalone attribute key
198
- #
199
- # @param key [Symbol] Name of the attribute being generated
200
- # @param value [Object] Value of the attribute
201
- #
202
- def attribute_code(key, value)
203
- attribute_code = ""
204
-
205
- case value
206
- when Array
207
- if key == :class
208
- attribute_value = value.join ' '
209
- else
210
- attribute_value = value.join '_'
211
- end
212
-
213
- unless attribute_value.empty?
214
- attribute_code += " #{key}"
215
- attribute_code += "=\"#{attribute_value.strip}\""
216
- end
217
- when Hash
218
- value.each do |k,v|
219
- if v
220
- attribute_code += " #{key}-#{k}"
221
- attribute_code += "=\"#{v.to_s.strip}\"" unless v == true
222
- end
223
- end
224
- else
225
- if value
226
- attribute_code += " #{key}"
227
- attribute_code += "=\"#{value.to_s.strip}\"" unless value == true
228
- end
44
+ # Set tag closing code
45
+ buffer_freeze "</#{node[@value]}>"
46
+ buffer_freeze " " if node[@options][:trailing_whitespace]
229
47
  end
230
-
231
- return attribute_code
232
48
  end
233
49
  end
234
50
  end