herbgobbler 0.3.0 → 0.3.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.
- data/grammer/erb_grammer.treetop +30 -4
- data/lib/core/erb_file.rb +1 -1
- data/lib/nodes/herb_node_retaining_text_node.rb +118 -27
- data/scripts/display_syntax_tree.rb +1 -1
- metadata +2 -2
data/grammer/erb_grammer.treetop
CHANGED
@@ -94,7 +94,7 @@ grammar ERBGrammer
|
|
94
94
|
end
|
95
95
|
|
96
96
|
rule method_call_content
|
97
|
-
method_names whitespace ruby_string:double_quoted_ruby_string everything_else:(comma erb_string_non_text_content)? <MethodCallNode>
|
97
|
+
method_names whitespace ruby_string:(double_quoted_ruby_string / single_quoted_ruby_string) everything_else:(comma erb_string_non_text_content)? <MethodCallNode>
|
98
98
|
end
|
99
99
|
|
100
100
|
rule erb_string_non_text_content
|
@@ -111,7 +111,7 @@ grammar ERBGrammer
|
|
111
111
|
end
|
112
112
|
|
113
113
|
rule erb_string
|
114
|
-
start_erb:erb_string_start start_space:(space)? text:(method_call_content / double_quoted_ruby_string)? everything_else:(pluralize / erb_string_non_text_content) end_erb:(erb_block_end) <NonTextNode>
|
114
|
+
start_erb:erb_string_start start_space:(space)? text:(method_call_content / double_quoted_ruby_string / single_quoted_ruby_string)? everything_else:(pluralize / erb_string_non_text_content) end_erb:(erb_block_end) <NonTextNode>
|
115
115
|
{
|
116
116
|
def node_name
|
117
117
|
"erb_string"
|
@@ -125,6 +125,28 @@ grammar ERBGrammer
|
|
125
125
|
|
126
126
|
end
|
127
127
|
|
128
|
+
rule single_quoted_ruby_string
|
129
|
+
start_quote:"'" unquoted_text:(( !"'" .)*) end_quote:"'" <TextNode>
|
130
|
+
{
|
131
|
+
def can_be_combined?
|
132
|
+
false
|
133
|
+
end
|
134
|
+
|
135
|
+
def html?
|
136
|
+
false
|
137
|
+
end
|
138
|
+
|
139
|
+
def text_value
|
140
|
+
self.unquoted_text.text_value
|
141
|
+
end
|
142
|
+
|
143
|
+
def node_name
|
144
|
+
"single_quoted_ruby_string"
|
145
|
+
end
|
146
|
+
}
|
147
|
+
|
148
|
+
end
|
149
|
+
|
128
150
|
rule double_quoted_ruby_string
|
129
151
|
start_quote:'"' unquoted_text:((!'"' (string_variable / .))*) end_quote:'"' <DoubleQuotedTextNode>
|
130
152
|
{
|
@@ -262,7 +284,11 @@ grammar ERBGrammer
|
|
262
284
|
start_tag:'<' tag_name:([a-zA-Z])+ tag_contents:(!'/>' (erb_string / .))* end_tag:'/>' <NonTextNode>
|
263
285
|
{
|
264
286
|
def can_be_combined?
|
265
|
-
|
287
|
+
if( tag_name.text_value.downcase == 'br' )
|
288
|
+
false
|
289
|
+
else
|
290
|
+
true
|
291
|
+
end
|
266
292
|
end
|
267
293
|
|
268
294
|
def node_name
|
@@ -355,7 +381,7 @@ grammar ERBGrammer
|
|
355
381
|
end
|
356
382
|
|
357
383
|
rule whitespace
|
358
|
-
((![a-zA-Z\.] !('<' [a-zA-Z]+) !('</' [a-zA-Z]+) !'<%' !'"' !'<!' ) . )+ <NonTextNode>
|
384
|
+
((![a-zA-Z\.] !('<' [a-zA-Z]+) !('</' [a-zA-Z]+) !'<%' !'"' !"'" !'<!' ) . )+ <NonTextNode>
|
359
385
|
{
|
360
386
|
def can_be_combined?
|
361
387
|
true
|
data/lib/core/erb_file.rb
CHANGED
@@ -6,11 +6,13 @@ class HerbNodeRetainingTextNode < HerbNodeRetainingNode
|
|
6
6
|
self << node
|
7
7
|
end
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def can_remove_starting_or_ending_html_tags?
|
11
11
|
if( find_first_non_whitespace_node.node_name == "html_start_tag" && find_last_non_whitespace_node.node_name == "html_end_tag" )
|
12
12
|
if( find_first_non_whitespace_node.tag_name.text_value == find_last_non_whitespace_node.tag_name.text_value )
|
13
13
|
true
|
14
|
+
elsif( last_tag_does_not_match_first_tag? )
|
15
|
+
true
|
14
16
|
else
|
15
17
|
false
|
16
18
|
end
|
@@ -22,9 +24,17 @@ class HerbNodeRetainingTextNode < HerbNodeRetainingNode
|
|
22
24
|
|
23
25
|
end
|
24
26
|
|
27
|
+
def last_tag_does_not_match_first_tag?
|
28
|
+
find_last_non_whitespace_node.node_name == "html_end_tag" && find_first_non_whitespace_node.node_name == "html_start_tag" && find_last_non_whitespace_node.tag_name.text_value.downcase != find_first_non_whitespace_node.tag_name.text_value.downcase
|
29
|
+
end
|
30
|
+
|
25
31
|
def break_out_start_and_end_tags
|
26
|
-
if(
|
27
|
-
|
32
|
+
if( last_tag_does_not_match_first_tag? )
|
33
|
+
end_tag = extract_trailing_tag
|
34
|
+
start_tag = HerbNodeRetainingTextNode.new
|
35
|
+
start_tag.add_all( nodes[0..nodes.length - (end_tag.nodes.length + 1 ) ] )
|
36
|
+
[start_tag, end_tag]
|
37
|
+
elsif( find_first_non_whitespace_node.node_name == "html_start_tag" && find_last_non_whitespace_node.node_name == "html_end_tag" ) && ( can_remove_starting_or_ending_html_tags? )
|
28
38
|
start_tag = extract_leading_tag
|
29
39
|
end_tag = extract_trailing_tag
|
30
40
|
middle_tag = HerbNodeRetainingTextNode.new
|
@@ -56,10 +66,68 @@ class HerbNodeRetainingTextNode < HerbNodeRetainingNode
|
|
56
66
|
end
|
57
67
|
end
|
58
68
|
|
69
|
+
def explode
|
70
|
+
nested_level = nesting_level
|
71
|
+
to_return = []
|
72
|
+
current_nest = 0
|
73
|
+
new_node_list = nil
|
74
|
+
|
75
|
+
# Go through and try to build rolled up nodes for all of the node
|
76
|
+
# contents that are below the nested list level
|
77
|
+
nodes.each do |current_node|
|
78
|
+
if( current_node.node_name == "html_start_tag" )
|
79
|
+
current_nest += 1
|
80
|
+
if( new_node_list.nil? )
|
81
|
+
to_return << current_node
|
82
|
+
else
|
83
|
+
new_node_list << current_node
|
84
|
+
end
|
85
|
+
if( current_nest == nesting_level + 1 )
|
86
|
+
new_node_list = []
|
87
|
+
end
|
88
|
+
elsif( current_node.node_name == "html_end_tag" )
|
89
|
+
if( current_nest == nesting_level + 1 )
|
90
|
+
to_return << build_correct_node_retaining_node( new_node_list )
|
91
|
+
to_return << current_node
|
92
|
+
new_node_list = nil
|
93
|
+
elsif( new_node_list.nil? )
|
94
|
+
to_return << current_node
|
95
|
+
else
|
96
|
+
new_node_list << current_node
|
97
|
+
end
|
98
|
+
current_nest -= 1
|
99
|
+
elsif( new_node_list.nil? )
|
100
|
+
to_return << current_node
|
101
|
+
elsif( !new_node_list.nil?)
|
102
|
+
new_node_list << current_node
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
to_return << build_correct_node_retaining_node( new_node_list ) unless new_node_list.nil?
|
107
|
+
|
108
|
+
return to_return
|
109
|
+
end
|
110
|
+
|
111
|
+
def build_correct_node_retaining_node( array_of_nodes )
|
112
|
+
text_retaining_node = false
|
113
|
+
array_of_nodes.each do |node|
|
114
|
+
text_retaining_node = true if node.is_a?(TextNode) && node.contains_alpha_characters?
|
115
|
+
end
|
116
|
+
|
117
|
+
if( text_retaining_node )
|
118
|
+
to_return = HerbNodeRetainingTextNode.new
|
119
|
+
to_return.add_all( array_of_nodes )
|
120
|
+
else
|
121
|
+
to_return = HerbNodeRetainingNonTextNode.create_from_nodes( array_of_nodes )
|
122
|
+
end
|
123
|
+
|
124
|
+
to_return
|
125
|
+
end
|
126
|
+
|
59
127
|
def can_be_exploded?
|
60
128
|
# it is possible that this node contains only non text nodes. If
|
61
129
|
# there is no text within this combined node then this should be uncombined
|
62
|
-
|
130
|
+
contains_list_of_elements? || contains_only_non_text_and_non_method_nodes?
|
63
131
|
end
|
64
132
|
|
65
133
|
def can_be_combined?
|
@@ -89,10 +157,55 @@ class HerbNodeRetainingTextNode < HerbNodeRetainingNode
|
|
89
157
|
found_text = false
|
90
158
|
nodes.each do |current_node|
|
91
159
|
found_text = true if current_node.is_a?( TextNode ) && !current_node.is_a?(MethodCallNode)
|
92
|
-
|
93
160
|
end
|
94
161
|
!found_text
|
95
162
|
end
|
163
|
+
|
164
|
+
def contains_list_of_elements?
|
165
|
+
# Two cases, first there could be an outer element that wraps the
|
166
|
+
# list, if this is true we want to strip it.
|
167
|
+
# After the outer elements are stripped then we want to walk
|
168
|
+
# through and find all of the top level elements - where a top
|
169
|
+
# level element is defined as anything that isn't nested further.
|
170
|
+
nested_level = nesting_level
|
171
|
+
nested_nodes = nested_nodes_list
|
172
|
+
to_return = true
|
173
|
+
nested_nodes[nested_level].each do |node_at_node_level|
|
174
|
+
to_return = false if node_at_node_level.is_a?(TextNode)
|
175
|
+
end
|
176
|
+
|
177
|
+
return to_return
|
178
|
+
end
|
179
|
+
|
180
|
+
def nested_nodes_list
|
181
|
+
nested_level = 0
|
182
|
+
nested_nodes = [ [] ]
|
183
|
+
nodes.each do |current_node|
|
184
|
+
if( current_node.node_name == "html_start_tag" )
|
185
|
+
nested_nodes[nested_level] << current_node
|
186
|
+
nested_level += 1
|
187
|
+
nested_nodes[ nested_level ] = [] if nested_nodes[nested_level].nil?
|
188
|
+
elsif( current_node.node_name == "html_end_tag" )
|
189
|
+
nested_level -= 1
|
190
|
+
nested_nodes[ nested_level ] << current_node
|
191
|
+
elsif( current_node.is_a?( TextNode ) && current_node.contains_alpha_characters? )
|
192
|
+
nested_nodes[ nested_level ] << current_node
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
return nested_nodes
|
197
|
+
end
|
198
|
+
|
199
|
+
def nesting_level
|
200
|
+
nested_nodes = nested_nodes_list
|
201
|
+
nested_level = 0
|
202
|
+
while( nested_nodes[nested_level].size == 2 && nested_nodes[nested_level].first.node_name == "html_start_tag" && nested_nodes[nested_level].last.node_name == "html_end_tag" )
|
203
|
+
nested_level += 1
|
204
|
+
end
|
205
|
+
|
206
|
+
return nested_level
|
207
|
+
end
|
208
|
+
|
96
209
|
|
97
210
|
def extract_leading_tag
|
98
211
|
node = find_first_non_whitespace_node
|
@@ -117,26 +230,4 @@ class HerbNodeRetainingTextNode < HerbNodeRetainingNode
|
|
117
230
|
|
118
231
|
end
|
119
232
|
|
120
|
-
def find_all_non_matched_tags_and_white_space( nodes )
|
121
|
-
to_return = []
|
122
|
-
search_node_name = nil
|
123
|
-
nodes.each do |current_node|
|
124
|
-
if( !current_node.respond_to?( :node_name ) )
|
125
|
-
to_return << current_node
|
126
|
-
elsif( search_node_name.nil? && current_node.node_name == "html_start_tag" )
|
127
|
-
search_node_name = current_node.tag_name.text_value
|
128
|
-
elsif( !search_node_name.nil? && current_node.node_name == "html_end_tag" )
|
129
|
-
search_node_name = nil if search_node_name == current_node.tag_name.text_value
|
130
|
-
elsif( search_node_name.nil? && current_node.is_a?(TextNode ) )
|
131
|
-
if( current_node.contains_alpha_characters? )
|
132
|
-
to_return << current_node
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
return to_return
|
138
|
-
end
|
139
|
-
|
140
|
-
|
141
|
-
|
142
233
|
end
|
@@ -20,6 +20,6 @@ erb_file.combine_nodes( erb_file.flatten_elements ).each do |element|
|
|
20
20
|
name = ""
|
21
21
|
end
|
22
22
|
|
23
|
-
puts "`#{element.text_value}`(text=#{element.is_a?(TextNode)})(combindable=#{element.
|
23
|
+
puts "`#{element.text_value}`(text=#{element.is_a?(TextNode)})(combindable=#{element.respond_to?(:can_be_combined?) && element.can_be_combined?})(class=#{element.class})#{name}"
|
24
24
|
end
|
25
25
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: herbgobbler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|