wireframe-haml 2.1.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.
- data/README.rdoc +332 -0
- data/VERSION.yml +4 -0
- data/bin/css2sass +7 -0
- data/bin/haml +9 -0
- data/bin/html2haml +7 -0
- data/bin/sass +8 -0
- data/lib/haml/buffer.rb +255 -0
- data/lib/haml/engine.rb +268 -0
- data/lib/haml/error.rb +22 -0
- data/lib/haml/exec.rb +395 -0
- data/lib/haml/filters.rb +276 -0
- data/lib/haml/helpers/action_view_extensions.rb +45 -0
- data/lib/haml/helpers/action_view_mods.rb +181 -0
- data/lib/haml/helpers.rb +468 -0
- data/lib/haml/html.rb +218 -0
- data/lib/haml/precompiler.rb +889 -0
- data/lib/haml/shared.rb +45 -0
- data/lib/haml/template/patch.rb +58 -0
- data/lib/haml/template/plugin.rb +72 -0
- data/lib/haml/template.rb +51 -0
- data/lib/haml/util.rb +77 -0
- data/lib/haml/version.rb +47 -0
- data/lib/haml.rb +1042 -0
- data/lib/sass/css.rb +388 -0
- data/lib/sass/engine.rb +499 -0
- data/lib/sass/environment.rb +33 -0
- data/lib/sass/error.rb +35 -0
- data/lib/sass/plugin/merb.rb +56 -0
- data/lib/sass/plugin/rails.rb +24 -0
- data/lib/sass/plugin.rb +203 -0
- data/lib/sass/repl.rb +51 -0
- data/lib/sass/script/bool.rb +13 -0
- data/lib/sass/script/color.rb +97 -0
- data/lib/sass/script/funcall.rb +28 -0
- data/lib/sass/script/functions.rb +122 -0
- data/lib/sass/script/lexer.rb +152 -0
- data/lib/sass/script/literal.rb +60 -0
- data/lib/sass/script/number.rb +231 -0
- data/lib/sass/script/operation.rb +30 -0
- data/lib/sass/script/parser.rb +142 -0
- data/lib/sass/script/string.rb +42 -0
- data/lib/sass/script/unary_operation.rb +21 -0
- data/lib/sass/script/variable.rb +20 -0
- data/lib/sass/script.rb +38 -0
- data/lib/sass/tree/attr_node.rb +64 -0
- data/lib/sass/tree/comment_node.rb +34 -0
- data/lib/sass/tree/debug_node.rb +22 -0
- data/lib/sass/tree/directive_node.rb +50 -0
- data/lib/sass/tree/file_node.rb +27 -0
- data/lib/sass/tree/for_node.rb +29 -0
- data/lib/sass/tree/if_node.rb +27 -0
- data/lib/sass/tree/mixin_def_node.rb +18 -0
- data/lib/sass/tree/mixin_node.rb +34 -0
- data/lib/sass/tree/node.rb +99 -0
- data/lib/sass/tree/rule_node.rb +120 -0
- data/lib/sass/tree/variable_node.rb +24 -0
- data/lib/sass/tree/while_node.rb +20 -0
- data/lib/sass.rb +1062 -0
- data/test/benchmark.rb +99 -0
- data/test/haml/engine_test.rb +734 -0
- data/test/haml/helper_test.rb +224 -0
- data/test/haml/html2haml_test.rb +92 -0
- data/test/haml/markaby/standard.mab +52 -0
- data/test/haml/mocks/article.rb +6 -0
- data/test/haml/results/content_for_layout.xhtml +15 -0
- data/test/haml/results/eval_suppressed.xhtml +9 -0
- data/test/haml/results/filters.xhtml +62 -0
- data/test/haml/results/helpers.xhtml +93 -0
- data/test/haml/results/helpful.xhtml +10 -0
- data/test/haml/results/just_stuff.xhtml +68 -0
- data/test/haml/results/list.xhtml +12 -0
- data/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
- data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
- data/test/haml/results/original_engine.xhtml +20 -0
- data/test/haml/results/partial_layout.xhtml +5 -0
- data/test/haml/results/partials.xhtml +21 -0
- data/test/haml/results/render_layout.xhtml +3 -0
- data/test/haml/results/silent_script.xhtml +74 -0
- data/test/haml/results/standard.xhtml +42 -0
- data/test/haml/results/tag_parsing.xhtml +23 -0
- data/test/haml/results/very_basic.xhtml +5 -0
- data/test/haml/results/whitespace_handling.xhtml +89 -0
- data/test/haml/rhtml/_av_partial_1.rhtml +12 -0
- data/test/haml/rhtml/_av_partial_2.rhtml +8 -0
- data/test/haml/rhtml/action_view.rhtml +62 -0
- data/test/haml/rhtml/standard.rhtml +54 -0
- data/test/haml/template_test.rb +204 -0
- data/test/haml/templates/_av_partial_1.haml +9 -0
- data/test/haml/templates/_av_partial_1_ugly.haml +9 -0
- data/test/haml/templates/_av_partial_2.haml +5 -0
- data/test/haml/templates/_av_partial_2_ugly.haml +5 -0
- data/test/haml/templates/_layout.erb +3 -0
- data/test/haml/templates/_layout_for_partial.haml +3 -0
- data/test/haml/templates/_partial.haml +8 -0
- data/test/haml/templates/_text_area.haml +3 -0
- data/test/haml/templates/action_view.haml +47 -0
- data/test/haml/templates/action_view_ugly.haml +47 -0
- data/test/haml/templates/breakage.haml +8 -0
- data/test/haml/templates/content_for_layout.haml +10 -0
- data/test/haml/templates/eval_suppressed.haml +11 -0
- data/test/haml/templates/filters.haml +66 -0
- data/test/haml/templates/helpers.haml +95 -0
- data/test/haml/templates/helpful.haml +11 -0
- data/test/haml/templates/just_stuff.haml +83 -0
- data/test/haml/templates/list.haml +12 -0
- data/test/haml/templates/nuke_inner_whitespace.haml +32 -0
- data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
- data/test/haml/templates/original_engine.haml +17 -0
- data/test/haml/templates/partial_layout.haml +3 -0
- data/test/haml/templates/partialize.haml +1 -0
- data/test/haml/templates/partials.haml +12 -0
- data/test/haml/templates/render_layout.haml +2 -0
- data/test/haml/templates/silent_script.haml +40 -0
- data/test/haml/templates/standard.haml +42 -0
- data/test/haml/templates/standard_ugly.haml +1 -0
- data/test/haml/templates/tag_parsing.haml +21 -0
- data/test/haml/templates/very_basic.haml +4 -0
- data/test/haml/templates/whitespace_handling.haml +87 -0
- data/test/linked_rails.rb +12 -0
- data/test/sass/css2sass_test.rb +193 -0
- data/test/sass/engine_test.rb +786 -0
- data/test/sass/functions_test.rb +96 -0
- data/test/sass/more_results/more1.css +9 -0
- data/test/sass/more_results/more1_with_line_comments.css +26 -0
- data/test/sass/more_results/more_import.css +29 -0
- data/test/sass/more_templates/_more_partial.sass +2 -0
- data/test/sass/more_templates/more1.sass +23 -0
- data/test/sass/more_templates/more_import.sass +11 -0
- data/test/sass/plugin_test.rb +208 -0
- data/test/sass/results/alt.css +4 -0
- data/test/sass/results/basic.css +9 -0
- data/test/sass/results/compact.css +5 -0
- data/test/sass/results/complex.css +87 -0
- data/test/sass/results/compressed.css +1 -0
- data/test/sass/results/expanded.css +19 -0
- data/test/sass/results/import.css +29 -0
- data/test/sass/results/line_numbers.css +49 -0
- data/test/sass/results/mixins.css +95 -0
- data/test/sass/results/multiline.css +24 -0
- data/test/sass/results/nested.css +22 -0
- data/test/sass/results/parent_ref.css +13 -0
- data/test/sass/results/script.css +16 -0
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
- data/test/sass/results/subdir/subdir.css +3 -0
- data/test/sass/results/units.css +11 -0
- data/test/sass/script_test.rb +153 -0
- data/test/sass/templates/_partial.sass +2 -0
- data/test/sass/templates/alt.sass +16 -0
- data/test/sass/templates/basic.sass +23 -0
- data/test/sass/templates/bork.sass +2 -0
- data/test/sass/templates/bork2.sass +2 -0
- data/test/sass/templates/compact.sass +17 -0
- data/test/sass/templates/complex.sass +309 -0
- data/test/sass/templates/compressed.sass +15 -0
- data/test/sass/templates/expanded.sass +17 -0
- data/test/sass/templates/import.sass +11 -0
- data/test/sass/templates/importee.sass +19 -0
- data/test/sass/templates/line_numbers.sass +13 -0
- data/test/sass/templates/mixins.sass +76 -0
- data/test/sass/templates/multiline.sass +20 -0
- data/test/sass/templates/nested.sass +25 -0
- data/test/sass/templates/parent_ref.sass +25 -0
- data/test/sass/templates/script.sass +101 -0
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
- data/test/sass/templates/subdir/subdir.sass +6 -0
- data/test/sass/templates/units.sass +11 -0
- data/test/test_helper.rb +21 -0
- metadata +247 -0
data/lib/sass/css.rb
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../sass'
|
|
2
|
+
require 'sass/tree/node'
|
|
3
|
+
require 'strscan'
|
|
4
|
+
|
|
5
|
+
module Sass
|
|
6
|
+
# :stopdoc:
|
|
7
|
+
module Tree
|
|
8
|
+
class Node
|
|
9
|
+
def to_sass(opts = {})
|
|
10
|
+
result = ''
|
|
11
|
+
|
|
12
|
+
children.each do |child|
|
|
13
|
+
result << "#{child.to_sass(0, opts)}\n"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
result
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class RuleNode
|
|
21
|
+
def to_sass(tabs, opts = {})
|
|
22
|
+
str = "\n#{' ' * tabs}#{rule}#{children.any? { |c| c.is_a? AttrNode } ? "\n" : ''}"
|
|
23
|
+
|
|
24
|
+
children.each do |child|
|
|
25
|
+
str << "#{child.to_sass(tabs + 1, opts)}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
str
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class AttrNode
|
|
33
|
+
def to_sass(tabs, opts = {})
|
|
34
|
+
"#{' ' * tabs}#{opts[:alternate] ? '' : ':'}#{name}#{opts[:alternate] ? ':' : ''} #{value}\n"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class DirectiveNode
|
|
39
|
+
def to_sass(tabs, opts = {})
|
|
40
|
+
"#{' ' * tabs}#{value}#{children.map {|c| c.to_sass(tabs + 1, opts)}}\n"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# This class is based on the Ruby 1.9 ordered hashes.
|
|
46
|
+
# It keeps the semantics and most of the efficiency of normal hashes
|
|
47
|
+
# while also keeping track of the order in which elements were set.
|
|
48
|
+
class OrderedHash
|
|
49
|
+
Node = Struct.new(:key, :value, :next, :prev)
|
|
50
|
+
include Enumerable
|
|
51
|
+
|
|
52
|
+
def initialize
|
|
53
|
+
@hash = {}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def initialize_copy(other)
|
|
57
|
+
@hash = other.instance_variable_get('@hash').clone
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def [](key)
|
|
61
|
+
@hash[key] && @hash[key].value
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def []=(key, value)
|
|
65
|
+
node = Node.new(key, value)
|
|
66
|
+
|
|
67
|
+
if old = @hash[key]
|
|
68
|
+
if old.prev
|
|
69
|
+
old.prev.next = old.next
|
|
70
|
+
else # old is @first and @last
|
|
71
|
+
@first = @last = nil
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
if @first.nil?
|
|
76
|
+
@first = @last = node
|
|
77
|
+
else
|
|
78
|
+
node.prev = @last
|
|
79
|
+
@last.next = node
|
|
80
|
+
@last = node
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
@hash[key] = node
|
|
84
|
+
value
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def each
|
|
88
|
+
return unless @first
|
|
89
|
+
yield [@first.key, @first.value]
|
|
90
|
+
node = @first
|
|
91
|
+
yield [node.key, node.value] while node = node.next
|
|
92
|
+
self
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def values
|
|
96
|
+
self.map { |k, v| v }
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# :startdoc:
|
|
101
|
+
|
|
102
|
+
# This class contains the functionality used in the +css2sass+ utility,
|
|
103
|
+
# namely converting CSS documents to Sass templates.
|
|
104
|
+
class CSS
|
|
105
|
+
|
|
106
|
+
# Creates a new instance of Sass::CSS that will compile the given document
|
|
107
|
+
# to a Sass string when +render+ is called.
|
|
108
|
+
def initialize(template, options = {})
|
|
109
|
+
if template.is_a? IO
|
|
110
|
+
template = template.read
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
@options = options
|
|
114
|
+
@template = StringScanner.new(template)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Processes the document and returns the result as a string
|
|
118
|
+
# containing the CSS template.
|
|
119
|
+
def render
|
|
120
|
+
begin
|
|
121
|
+
build_tree.to_sass(@options).strip + "\n"
|
|
122
|
+
rescue Exception => err
|
|
123
|
+
line = @template.string[0...@template.pos].split("\n").size
|
|
124
|
+
|
|
125
|
+
err.backtrace.unshift "(css):#{line}"
|
|
126
|
+
raise err
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
private
|
|
131
|
+
|
|
132
|
+
def build_tree
|
|
133
|
+
root = Tree::Node.new({})
|
|
134
|
+
whitespace
|
|
135
|
+
rules root
|
|
136
|
+
expand_commas root
|
|
137
|
+
parent_ref_rules root
|
|
138
|
+
remove_parent_refs root
|
|
139
|
+
flatten_rules root
|
|
140
|
+
fold_commas root
|
|
141
|
+
root
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def rules(root)
|
|
145
|
+
while r = rule
|
|
146
|
+
root << r
|
|
147
|
+
whitespace
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def rule
|
|
152
|
+
return unless rule = @template.scan(/[^\{\};]+/)
|
|
153
|
+
rule.strip!
|
|
154
|
+
directive = rule[0] == ?@
|
|
155
|
+
|
|
156
|
+
if directive
|
|
157
|
+
node = Tree::DirectiveNode.new(rule, {})
|
|
158
|
+
return node if @template.scan(/;/)
|
|
159
|
+
|
|
160
|
+
assert_match /\{/
|
|
161
|
+
whitespace
|
|
162
|
+
|
|
163
|
+
rules(node)
|
|
164
|
+
return node
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
assert_match /\{/
|
|
168
|
+
node = Tree::RuleNode.new(rule, {})
|
|
169
|
+
attributes(node)
|
|
170
|
+
return node
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def attributes(rule)
|
|
174
|
+
while @template.scan(/[^:\}\s]+/)
|
|
175
|
+
name = @template[0]
|
|
176
|
+
whitespace
|
|
177
|
+
|
|
178
|
+
assert_match /:/
|
|
179
|
+
|
|
180
|
+
value = ''
|
|
181
|
+
while @template.scan(/[^;\s\}]+/)
|
|
182
|
+
value << @template[0] << whitespace
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
assert_match /(;|(?=\}))/
|
|
186
|
+
rule << Tree::AttrNode.new(name, value, {})
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
assert_match /\}/
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def whitespace
|
|
193
|
+
space = @template.scan(/\s*/) || ''
|
|
194
|
+
|
|
195
|
+
# If we've hit a comment,
|
|
196
|
+
# go past it and look for more whitespace
|
|
197
|
+
if @template.scan(/\/\*/)
|
|
198
|
+
@template.scan_until(/\*\//)
|
|
199
|
+
return space + whitespace
|
|
200
|
+
end
|
|
201
|
+
return space
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def assert_match(re)
|
|
205
|
+
if !@template.scan(re)
|
|
206
|
+
line = @template.string[0..@template.pos].count "\n"
|
|
207
|
+
# Display basic regexps as plain old strings
|
|
208
|
+
expected = re.source == Regexp.escape(re.source) ? "\"#{re.source}\"" : re.inspect
|
|
209
|
+
raise Exception.new("Invalid CSS on line #{line}: expected #{expected}")
|
|
210
|
+
end
|
|
211
|
+
whitespace
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Transform
|
|
215
|
+
#
|
|
216
|
+
# foo, bar, baz
|
|
217
|
+
# color: blue
|
|
218
|
+
#
|
|
219
|
+
# into
|
|
220
|
+
#
|
|
221
|
+
# foo
|
|
222
|
+
# color: blue
|
|
223
|
+
# bar
|
|
224
|
+
# color: blue
|
|
225
|
+
# baz
|
|
226
|
+
# color: blue
|
|
227
|
+
#
|
|
228
|
+
# Yes, this expands the amount of code,
|
|
229
|
+
# but it's necessary to get nesting to work properly.
|
|
230
|
+
def expand_commas(root)
|
|
231
|
+
root.children.map! do |child|
|
|
232
|
+
next child unless Tree::RuleNode === child && child.rule.include?(',')
|
|
233
|
+
child.rule.split(',').map do |rule|
|
|
234
|
+
node = Tree::RuleNode.new(rule.strip, {})
|
|
235
|
+
node.children = child.children
|
|
236
|
+
node
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
root.children.flatten!
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Make rules use parent refs so that
|
|
243
|
+
#
|
|
244
|
+
# foo
|
|
245
|
+
# color: green
|
|
246
|
+
# foo.bar
|
|
247
|
+
# color: blue
|
|
248
|
+
#
|
|
249
|
+
# becomes
|
|
250
|
+
#
|
|
251
|
+
# foo
|
|
252
|
+
# color: green
|
|
253
|
+
# &.bar
|
|
254
|
+
# color: blue
|
|
255
|
+
#
|
|
256
|
+
# This has the side effect of nesting rules,
|
|
257
|
+
# so that
|
|
258
|
+
#
|
|
259
|
+
# foo
|
|
260
|
+
# color: green
|
|
261
|
+
# foo bar
|
|
262
|
+
# color: red
|
|
263
|
+
# foo baz
|
|
264
|
+
# color: blue
|
|
265
|
+
#
|
|
266
|
+
# becomes
|
|
267
|
+
#
|
|
268
|
+
# foo
|
|
269
|
+
# color: green
|
|
270
|
+
# & bar
|
|
271
|
+
# color: red
|
|
272
|
+
# & baz
|
|
273
|
+
# color: blue
|
|
274
|
+
#
|
|
275
|
+
def parent_ref_rules(root)
|
|
276
|
+
rules = OrderedHash.new
|
|
277
|
+
root.children.select { |c| Tree::RuleNode === c }.each do |child|
|
|
278
|
+
root.children.delete child
|
|
279
|
+
first, rest = child.rule.scan(/^(&?(?: .|[^ ])[^.#: \[]*)([.#: \[].*)?$/).first
|
|
280
|
+
rules[first] ||= Tree::RuleNode.new(first, {})
|
|
281
|
+
if rest
|
|
282
|
+
child.rule = "&" + rest
|
|
283
|
+
rules[first] << child
|
|
284
|
+
else
|
|
285
|
+
rules[first].children += child.children
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
rules.values.each { |v| parent_ref_rules(v) }
|
|
290
|
+
root.children += rules.values
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Remove useless parent refs so that
|
|
294
|
+
#
|
|
295
|
+
# foo
|
|
296
|
+
# & bar
|
|
297
|
+
# color: blue
|
|
298
|
+
#
|
|
299
|
+
# becomes
|
|
300
|
+
#
|
|
301
|
+
# foo
|
|
302
|
+
# bar
|
|
303
|
+
# color: blue
|
|
304
|
+
#
|
|
305
|
+
def remove_parent_refs(root)
|
|
306
|
+
root.children.each do |child|
|
|
307
|
+
if child.is_a?(Tree::RuleNode)
|
|
308
|
+
child.rule.gsub! /^& +/, ''
|
|
309
|
+
remove_parent_refs child
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# Flatten rules so that
|
|
315
|
+
#
|
|
316
|
+
# foo
|
|
317
|
+
# bar
|
|
318
|
+
# baz
|
|
319
|
+
# color: red
|
|
320
|
+
#
|
|
321
|
+
# becomes
|
|
322
|
+
#
|
|
323
|
+
# foo bar baz
|
|
324
|
+
# color: red
|
|
325
|
+
#
|
|
326
|
+
# and
|
|
327
|
+
#
|
|
328
|
+
# foo
|
|
329
|
+
# &.bar
|
|
330
|
+
# color: blue
|
|
331
|
+
#
|
|
332
|
+
# becomes
|
|
333
|
+
#
|
|
334
|
+
# foo.bar
|
|
335
|
+
# color: blue
|
|
336
|
+
#
|
|
337
|
+
def flatten_rules(root)
|
|
338
|
+
root.children.each { |child| flatten_rule(child) if child.is_a?(Tree::RuleNode) }
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def flatten_rule(rule)
|
|
342
|
+
while rule.children.size == 1 && rule.children.first.is_a?(Tree::RuleNode)
|
|
343
|
+
child = rule.children.first
|
|
344
|
+
|
|
345
|
+
if child.rule[0] == ?&
|
|
346
|
+
rule.rule = child.rule.gsub /^&/, rule.rule
|
|
347
|
+
else
|
|
348
|
+
rule.rule = "#{rule.rule} #{child.rule}"
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
rule.children = child.children
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
flatten_rules(rule)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# Transform
|
|
358
|
+
#
|
|
359
|
+
# foo
|
|
360
|
+
# bar
|
|
361
|
+
# color: blue
|
|
362
|
+
# baz
|
|
363
|
+
# color: blue
|
|
364
|
+
#
|
|
365
|
+
# into
|
|
366
|
+
#
|
|
367
|
+
# foo
|
|
368
|
+
# bar, baz
|
|
369
|
+
# color: blue
|
|
370
|
+
#
|
|
371
|
+
def fold_commas(root)
|
|
372
|
+
prev_rule = nil
|
|
373
|
+
root.children.map! do |child|
|
|
374
|
+
next child unless child.is_a?(Tree::RuleNode)
|
|
375
|
+
|
|
376
|
+
if prev_rule && prev_rule.children == child.children
|
|
377
|
+
prev_rule.rule << ", #{child.rule}"
|
|
378
|
+
next nil
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
fold_commas(child)
|
|
382
|
+
prev_rule = child
|
|
383
|
+
child
|
|
384
|
+
end
|
|
385
|
+
root.children.compact!
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
end
|