merbjedi-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.
Files changed (177) hide show
  1. data/FAQ +138 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +332 -0
  4. data/REVISION +1 -0
  5. data/Rakefile +184 -0
  6. data/VERSION +1 -0
  7. data/bin/css2sass +7 -0
  8. data/bin/haml +9 -0
  9. data/bin/html2haml +7 -0
  10. data/bin/sass +8 -0
  11. data/extra/haml-mode.el +434 -0
  12. data/extra/sass-mode.el +98 -0
  13. data/init.rb +8 -0
  14. data/lib/haml.rb +1025 -0
  15. data/lib/haml/buffer.rb +255 -0
  16. data/lib/haml/engine.rb +268 -0
  17. data/lib/haml/error.rb +22 -0
  18. data/lib/haml/exec.rb +395 -0
  19. data/lib/haml/filters.rb +276 -0
  20. data/lib/haml/helpers.rb +465 -0
  21. data/lib/haml/helpers/action_view_extensions.rb +45 -0
  22. data/lib/haml/helpers/action_view_mods.rb +181 -0
  23. data/lib/haml/html.rb +218 -0
  24. data/lib/haml/precompiler.rb +896 -0
  25. data/lib/haml/shared.rb +45 -0
  26. data/lib/haml/template.rb +51 -0
  27. data/lib/haml/template/patch.rb +58 -0
  28. data/lib/haml/template/plugin.rb +72 -0
  29. data/lib/haml/util.rb +77 -0
  30. data/lib/haml/version.rb +47 -0
  31. data/lib/sass.rb +1062 -0
  32. data/lib/sass/css.rb +388 -0
  33. data/lib/sass/engine.rb +501 -0
  34. data/lib/sass/environment.rb +33 -0
  35. data/lib/sass/error.rb +35 -0
  36. data/lib/sass/plugin.rb +203 -0
  37. data/lib/sass/plugin/merb.rb +56 -0
  38. data/lib/sass/plugin/rails.rb +24 -0
  39. data/lib/sass/repl.rb +44 -0
  40. data/lib/sass/script.rb +38 -0
  41. data/lib/sass/script/bool.rb +13 -0
  42. data/lib/sass/script/color.rb +97 -0
  43. data/lib/sass/script/funcall.rb +28 -0
  44. data/lib/sass/script/functions.rb +122 -0
  45. data/lib/sass/script/lexer.rb +144 -0
  46. data/lib/sass/script/literal.rb +60 -0
  47. data/lib/sass/script/number.rb +231 -0
  48. data/lib/sass/script/operation.rb +30 -0
  49. data/lib/sass/script/parser.rb +142 -0
  50. data/lib/sass/script/string.rb +42 -0
  51. data/lib/sass/script/unary_operation.rb +21 -0
  52. data/lib/sass/script/variable.rb +20 -0
  53. data/lib/sass/tree/attr_node.rb +64 -0
  54. data/lib/sass/tree/comment_node.rb +30 -0
  55. data/lib/sass/tree/debug_node.rb +22 -0
  56. data/lib/sass/tree/directive_node.rb +50 -0
  57. data/lib/sass/tree/file_node.rb +27 -0
  58. data/lib/sass/tree/for_node.rb +29 -0
  59. data/lib/sass/tree/if_node.rb +27 -0
  60. data/lib/sass/tree/mixin_def_node.rb +18 -0
  61. data/lib/sass/tree/mixin_node.rb +34 -0
  62. data/lib/sass/tree/node.rb +97 -0
  63. data/lib/sass/tree/rule_node.rb +120 -0
  64. data/lib/sass/tree/variable_node.rb +24 -0
  65. data/lib/sass/tree/while_node.rb +20 -0
  66. data/rails/init.rb +1 -0
  67. data/test/benchmark.rb +99 -0
  68. data/test/haml/engine_test.rb +852 -0
  69. data/test/haml/helper_test.rb +224 -0
  70. data/test/haml/html2haml_test.rb +92 -0
  71. data/test/haml/markaby/standard.mab +52 -0
  72. data/test/haml/mocks/article.rb +6 -0
  73. data/test/haml/results/content_for_layout.xhtml +15 -0
  74. data/test/haml/results/eval_suppressed.xhtml +9 -0
  75. data/test/haml/results/filters.xhtml +62 -0
  76. data/test/haml/results/helpers.xhtml +93 -0
  77. data/test/haml/results/helpful.xhtml +10 -0
  78. data/test/haml/results/just_stuff.xhtml +68 -0
  79. data/test/haml/results/list.xhtml +12 -0
  80. data/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
  81. data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
  82. data/test/haml/results/original_engine.xhtml +20 -0
  83. data/test/haml/results/partial_layout.xhtml +5 -0
  84. data/test/haml/results/partials.xhtml +21 -0
  85. data/test/haml/results/render_layout.xhtml +3 -0
  86. data/test/haml/results/silent_script.xhtml +74 -0
  87. data/test/haml/results/standard.xhtml +42 -0
  88. data/test/haml/results/tag_parsing.xhtml +23 -0
  89. data/test/haml/results/very_basic.xhtml +5 -0
  90. data/test/haml/results/whitespace_handling.xhtml +89 -0
  91. data/test/haml/rhtml/_av_partial_1.rhtml +12 -0
  92. data/test/haml/rhtml/_av_partial_2.rhtml +8 -0
  93. data/test/haml/rhtml/action_view.rhtml +62 -0
  94. data/test/haml/rhtml/standard.rhtml +54 -0
  95. data/test/haml/template_test.rb +204 -0
  96. data/test/haml/templates/_av_partial_1.haml +9 -0
  97. data/test/haml/templates/_av_partial_1_ugly.haml +9 -0
  98. data/test/haml/templates/_av_partial_2.haml +5 -0
  99. data/test/haml/templates/_av_partial_2_ugly.haml +5 -0
  100. data/test/haml/templates/_layout.erb +3 -0
  101. data/test/haml/templates/_layout_for_partial.haml +3 -0
  102. data/test/haml/templates/_partial.haml +8 -0
  103. data/test/haml/templates/_text_area.haml +3 -0
  104. data/test/haml/templates/action_view.haml +47 -0
  105. data/test/haml/templates/action_view_ugly.haml +47 -0
  106. data/test/haml/templates/breakage.haml +8 -0
  107. data/test/haml/templates/content_for_layout.haml +10 -0
  108. data/test/haml/templates/eval_suppressed.haml +11 -0
  109. data/test/haml/templates/filters.haml +66 -0
  110. data/test/haml/templates/helpers.haml +95 -0
  111. data/test/haml/templates/helpful.haml +11 -0
  112. data/test/haml/templates/just_stuff.haml +83 -0
  113. data/test/haml/templates/list.haml +12 -0
  114. data/test/haml/templates/nuke_inner_whitespace.haml +32 -0
  115. data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
  116. data/test/haml/templates/original_engine.haml +17 -0
  117. data/test/haml/templates/partial_layout.haml +3 -0
  118. data/test/haml/templates/partialize.haml +1 -0
  119. data/test/haml/templates/partials.haml +12 -0
  120. data/test/haml/templates/render_layout.haml +2 -0
  121. data/test/haml/templates/silent_script.haml +40 -0
  122. data/test/haml/templates/standard.haml +42 -0
  123. data/test/haml/templates/standard_ugly.haml +42 -0
  124. data/test/haml/templates/tag_parsing.haml +21 -0
  125. data/test/haml/templates/very_basic.haml +4 -0
  126. data/test/haml/templates/whitespace_handling.haml +87 -0
  127. data/test/linked_rails.rb +12 -0
  128. data/test/sass/css2sass_test.rb +193 -0
  129. data/test/sass/engine_test.rb +752 -0
  130. data/test/sass/functions_test.rb +96 -0
  131. data/test/sass/more_results/more1.css +9 -0
  132. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  133. data/test/sass/more_results/more_import.css +29 -0
  134. data/test/sass/more_templates/_more_partial.sass +2 -0
  135. data/test/sass/more_templates/more1.sass +23 -0
  136. data/test/sass/more_templates/more_import.sass +11 -0
  137. data/test/sass/plugin_test.rb +208 -0
  138. data/test/sass/results/alt.css +4 -0
  139. data/test/sass/results/basic.css +9 -0
  140. data/test/sass/results/compact.css +5 -0
  141. data/test/sass/results/complex.css +87 -0
  142. data/test/sass/results/compressed.css +1 -0
  143. data/test/sass/results/expanded.css +19 -0
  144. data/test/sass/results/import.css +29 -0
  145. data/test/sass/results/line_numbers.css +49 -0
  146. data/test/sass/results/mixins.css +95 -0
  147. data/test/sass/results/multiline.css +24 -0
  148. data/test/sass/results/nested.css +22 -0
  149. data/test/sass/results/parent_ref.css +13 -0
  150. data/test/sass/results/script.css +16 -0
  151. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  152. data/test/sass/results/subdir/subdir.css +3 -0
  153. data/test/sass/results/units.css +11 -0
  154. data/test/sass/script_test.rb +152 -0
  155. data/test/sass/templates/_partial.sass +2 -0
  156. data/test/sass/templates/alt.sass +16 -0
  157. data/test/sass/templates/basic.sass +23 -0
  158. data/test/sass/templates/bork.sass +2 -0
  159. data/test/sass/templates/bork2.sass +2 -0
  160. data/test/sass/templates/compact.sass +17 -0
  161. data/test/sass/templates/complex.sass +309 -0
  162. data/test/sass/templates/compressed.sass +15 -0
  163. data/test/sass/templates/expanded.sass +17 -0
  164. data/test/sass/templates/import.sass +11 -0
  165. data/test/sass/templates/importee.sass +19 -0
  166. data/test/sass/templates/line_numbers.sass +13 -0
  167. data/test/sass/templates/mixins.sass +76 -0
  168. data/test/sass/templates/multiline.sass +20 -0
  169. data/test/sass/templates/nested.sass +25 -0
  170. data/test/sass/templates/parent_ref.sass +25 -0
  171. data/test/sass/templates/script.sass +101 -0
  172. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  173. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  174. data/test/sass/templates/subdir/subdir.sass +6 -0
  175. data/test/sass/templates/units.sass +11 -0
  176. data/test/test_helper.rb +21 -0
  177. metadata +273 -0
@@ -0,0 +1,20 @@
1
+ module Sass
2
+ module Script
3
+ class Variable # :nodoc:
4
+ attr_reader :name
5
+
6
+ def initialize(name)
7
+ @name = name
8
+ end
9
+
10
+ def inspect
11
+ "!#{name}"
12
+ end
13
+
14
+ def perform(environment)
15
+ (val = environment.var(name)) && (return val)
16
+ raise SyntaxError.new("Undefined variable: \"!#{name}\".")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,64 @@
1
+ module Sass::Tree
2
+ class AttrNode < Node
3
+ attr_accessor :name, :value
4
+
5
+ def initialize(name, value, options)
6
+ @name = name
7
+ @value = value
8
+ super(options)
9
+ end
10
+
11
+ def ==(other)
12
+ self.class == other.class && name == other.name && value == other.value && super
13
+ end
14
+
15
+ def to_s(tabs, parent_name = nil)
16
+ if value[-1] == ?;
17
+ raise Sass::SyntaxError.new("Invalid attribute: #{declaration.dump} (This isn't CSS!).", @line)
18
+ end
19
+ real_name = name
20
+ real_name = "#{parent_name}-#{real_name}" if parent_name
21
+
22
+ if value.empty? && children.empty?
23
+ raise Sass::SyntaxError.new("Invalid attribute: #{declaration.dump}.", @line)
24
+ end
25
+
26
+ join_string = case @style
27
+ when :compact; ' '
28
+ when :compressed; ''
29
+ else "\n"
30
+ end
31
+ spaces = ' ' * (tabs - 1)
32
+ to_return = ''
33
+ if !value.empty?
34
+ to_return << "#{spaces}#{real_name}:#{@style == :compressed ? '' : ' '}#{value};#{join_string}"
35
+ end
36
+
37
+ children.each do |kid|
38
+ to_return << "#{kid.to_s(tabs, real_name)}" << join_string
39
+ end
40
+
41
+ (@style == :compressed && parent_name) ? to_return : to_return[0...-1]
42
+ end
43
+
44
+ protected
45
+
46
+ def perform!(environment)
47
+ @name = interpolate(@name, environment)
48
+ @value = @value.is_a?(String) ? interpolate(@value, environment) : @value.perform(environment).to_s
49
+ super
50
+ end
51
+
52
+ private
53
+
54
+ def declaration
55
+ ":#{name} #{value}"
56
+ end
57
+
58
+ def invalid_child?(child)
59
+ if !child.is_a?(AttrNode) && !child.is_a?(CommentNode)
60
+ "Illegal nesting: Only attributes may be nested beneath attributes."
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,30 @@
1
+ require 'sass/tree/node'
2
+
3
+ module Sass::Tree
4
+ class CommentNode < Node
5
+ attr_accessor :value
6
+
7
+ def initialize(value, options)
8
+ @value = value[2..-1].strip
9
+ super(options)
10
+ end
11
+
12
+ def ==(other)
13
+ self.value == other.value && super
14
+ end
15
+
16
+ def to_s(tabs = 0, parent_name = nil)
17
+ return if @style == :compressed
18
+
19
+ spaces = ' ' * (tabs - 1)
20
+ spaces + "/* " + ([value] + children.map {|c| c.text}).
21
+ join(@style == :compact ? ' ' : "\n#{spaces} * ") + " */"
22
+ end
23
+
24
+ protected
25
+
26
+ def _perform(environment)
27
+ self
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ module Sass
2
+ module Tree
3
+ class DebugNode < Node
4
+ def initialize(expr, options)
5
+ @expr = expr
6
+ super(options)
7
+ end
8
+
9
+ protected
10
+
11
+ def _perform(environment)
12
+ res = @expr.perform(environment)
13
+ if filename
14
+ STDERR.puts "#{filename}:#{line} DEBUG: #{res}"
15
+ else
16
+ STDERR.puts "Line #{line} DEBUG: #{res}"
17
+ end
18
+ []
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,50 @@
1
+ module Sass::Tree
2
+ class DirectiveNode < Node
3
+ attr_accessor :value
4
+
5
+ def initialize(value, options)
6
+ @value = value
7
+ super(options)
8
+ end
9
+
10
+ def to_s(tabs)
11
+ if children.empty?
12
+ value + ";"
13
+ else
14
+ result = if @style == :compressed
15
+ "#{value}{"
16
+ else
17
+ "#{' ' * (tabs - 1)}#{value} {" + (@style == :compact ? ' ' : "\n")
18
+ end
19
+ was_attr = false
20
+ first = true
21
+ children.each do |child|
22
+ if @style == :compact
23
+ if child.is_a?(AttrNode)
24
+ result << "#{child.to_s(first || was_attr ? 1 : tabs + 1)} "
25
+ else
26
+ if was_attr
27
+ result[-1] = "\n"
28
+ end
29
+ rendered = child.to_s(tabs + 1)
30
+ rendered.lstrip! if first
31
+ result << rendered
32
+ end
33
+ was_attr = child.is_a?(AttrNode)
34
+ first = false
35
+ elsif @style == :compressed
36
+ result << (was_attr ? ";#{child.to_s(1)}" : child.to_s(1))
37
+ was_attr = child.is_a?(AttrNode)
38
+ else
39
+ result << child.to_s(tabs + 1) + "\n"
40
+ end
41
+ end
42
+ result.rstrip + if @style == :compressed
43
+ "}"
44
+ else
45
+ (@style == :expanded ? "\n" : " ") + "}\n"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,27 @@
1
+ module Sass
2
+ module Tree
3
+ class FileNode < Node
4
+ def initialize(filename, children, options)
5
+ @filename = filename
6
+ super(options)
7
+ self.children = children
8
+ end
9
+
10
+ def to_s(*args)
11
+ super()
12
+ rescue Sass::SyntaxError => e
13
+ e.add_backtrace_entry(@filename)
14
+ raise e
15
+ end
16
+
17
+ protected
18
+
19
+ def perform!(environment)
20
+ self.children = perform_children(environment)
21
+ rescue Sass::SyntaxError => e
22
+ e.add_backtrace_entry(@filename)
23
+ raise e
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ require 'sass/tree/node'
2
+
3
+ module Sass::Tree
4
+ class ForNode < Node
5
+ def initialize(var, from, to, exclusive, options)
6
+ @var = var
7
+ @from = from
8
+ @to = to
9
+ @exclusive = exclusive
10
+ super(options)
11
+ end
12
+
13
+ protected
14
+
15
+ def _perform(environment)
16
+ from = @from.perform(environment).to_i
17
+ to = @to.perform(environment).to_i
18
+ range = Range.new(from, to, @exclusive)
19
+
20
+ children = []
21
+ range.each do |i|
22
+ environment = Sass::Environment.new(environment)
23
+ environment.set_local_var(@var, Sass::Script::Number.new(i))
24
+ children += perform_children(environment)
25
+ end
26
+ children
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ require 'sass/tree/node'
2
+
3
+ module Sass::Tree
4
+ class IfNode < Node
5
+ attr_accessor :else
6
+
7
+ def initialize(expr, options)
8
+ @expr = expr
9
+ @last_else = self
10
+ super(options)
11
+ end
12
+
13
+ def add_else(node)
14
+ @last_else.else = node
15
+ @last_else = node
16
+ end
17
+
18
+ protected
19
+
20
+ def _perform(environment)
21
+ environment = Sass::Environment.new(environment)
22
+ return perform_children(environment) if @expr.nil? || @expr.perform(environment).to_bool
23
+ return @else.perform(environment) if @else
24
+ []
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ module Sass
2
+ module Tree
3
+ class MixinDefNode < Node
4
+ def initialize(name, args, options)
5
+ @name = name
6
+ @args = args
7
+ super(options)
8
+ end
9
+
10
+ private
11
+
12
+ def _perform(environment)
13
+ environment.set_mixin(@name, Sass::Mixin.new(@name, @args, environment, children))
14
+ []
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ require 'sass/tree/node'
2
+
3
+ module Sass::Tree
4
+ class MixinNode < Node
5
+ def initialize(name, args, options)
6
+ @name = name
7
+ @args = args
8
+ super(options)
9
+ end
10
+
11
+ protected
12
+
13
+ def _perform(environment)
14
+ raise Sass::SyntaxError.new("Undefined mixin '#{@name}'.", @line) unless mixin = environment.mixin(@name)
15
+
16
+ raise Sass::SyntaxError.new(<<END.gsub("\n", "")) if mixin.args.size < @args.size
17
+ Mixin #{@name} takes #{mixin.args.size} argument#{'s' if mixin.args.size != 1}
18
+ but #{@args.size} #{@args.size == 1 ? 'was' : 'were'} passed.
19
+ END
20
+
21
+ environment = mixin.args.zip(@args).inject(Sass::Environment.new(mixin.environment)) do |env, (arg, value)|
22
+ env.set_local_var(arg[:name],
23
+ if value
24
+ value.perform(environment)
25
+ elsif arg[:default_value]
26
+ arg[:default_value].perform(env)
27
+ end)
28
+ raise Sass::SyntaxError.new("Mixin #{@name} is missing parameter !#{arg[:name]}.") unless env.var(arg[:name])
29
+ env
30
+ end
31
+ mixin.tree.map {|c| c.perform(environment)}.flatten
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,97 @@
1
+ module Sass
2
+ module Tree
3
+ class Node
4
+ attr_accessor :children
5
+ attr_accessor :line
6
+ attr_accessor :filename
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ @style = options[:style]
11
+ @children = []
12
+ end
13
+
14
+ def <<(child)
15
+ if msg = invalid_child?(child)
16
+ raise Sass::SyntaxError.new(msg, child.line)
17
+ end
18
+ @children << child
19
+ end
20
+
21
+ # We need this because Node duck types as an Array in engine.rb
22
+ def last
23
+ children.last
24
+ end
25
+
26
+ def ==(other)
27
+ self.class == other.class && other.children == children
28
+ end
29
+
30
+ def to_s
31
+ result = String.new
32
+ children.each do |child|
33
+ if child.is_a? AttrNode
34
+ raise Sass::SyntaxError.new('Attributes aren\'t allowed at the root of a document.', child.line)
35
+ else
36
+ result << "#{child.to_s(1)}" + (@style == :compressed ? '' : "\n")
37
+ end
38
+ end
39
+ @style == :compressed ? result+"\n" : result[0...-1]
40
+ end
41
+
42
+ def perform(environment)
43
+ _perform(environment)
44
+ rescue Sass::SyntaxError => e
45
+ e.sass_line ||= line
46
+ raise e
47
+ end
48
+
49
+ protected
50
+
51
+ def _perform(environment)
52
+ node = dup
53
+ node.perform!(environment)
54
+ node
55
+ end
56
+
57
+ def perform!(environment)
58
+ self.children = perform_children(Environment.new(environment))
59
+ end
60
+
61
+ def perform_children(environment)
62
+ children.map {|c| c.perform(environment)}.flatten
63
+ end
64
+
65
+ def interpolate(text, environment)
66
+ res = ''
67
+ rest = Haml::Shared.handle_interpolation text do |scan|
68
+ escapes = scan[2].size
69
+ res << scan.matched[0...-2 - escapes]
70
+ if escapes % 2 == 1
71
+ res << "\\" * (escapes - 1) << '#{'
72
+ else
73
+ res << "\\" * [0, escapes - 1].max
74
+ res << Script::Parser.new(scan, line, scan.pos - scan.matchedsize, filename).
75
+ parse_interpolated.perform(environment).to_s
76
+ end
77
+ end
78
+ res + rest
79
+ end
80
+
81
+ def balance(*args)
82
+ res = Haml::Shared.balance(*args)
83
+ return res if res
84
+ raise Sass::SyntaxError.new("Unbalanced brackets.", line)
85
+ end
86
+
87
+ private
88
+
89
+ # This method should be overridden by subclasses to return an error message
90
+ # if the given child node is invalid,
91
+ # and false or nil otherwise.
92
+ def invalid_child?(child)
93
+ false
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,120 @@
1
+ module Sass::Tree
2
+ class RuleNode < Node
3
+ # The character used to include the parent selector
4
+ PARENT = '&'
5
+
6
+ attr_accessor :rule
7
+
8
+ def initialize(rule, options)
9
+ @rule = rule
10
+ super(options)
11
+ end
12
+
13
+ def ==(other)
14
+ self.class == other.class && rules == other.rules && super
15
+ end
16
+
17
+ def rules
18
+ Array(rule)
19
+ end
20
+
21
+ def add_rules(node)
22
+ self.rule = rules
23
+ self.rule += node.rules
24
+ end
25
+
26
+ def continued?
27
+ rule[-1] == ?,
28
+ end
29
+
30
+ def to_s(tabs, super_rules = nil)
31
+ attributes = []
32
+ sub_rules = []
33
+
34
+ rule_split = /\s*,\s*/
35
+ rule_separator = @style == :compressed ? ',' : ', '
36
+ line_separator = [:nested, :expanded].include?(@style) ? ",\n" : rule_separator
37
+ rule_indent = ' ' * (tabs - 1)
38
+ total_rule = if super_rules
39
+ super_rules.split(",\n").map do |super_line|
40
+ super_line.strip.split(rule_split).map do |super_rule|
41
+ self.rules.map do |line|
42
+ rule_indent + line.gsub(/,$/, '').split(rule_split).map do |rule|
43
+ if rule.include?(PARENT)
44
+ rule.gsub(PARENT, super_rule)
45
+ else
46
+ "#{super_rule} #{rule}"
47
+ end
48
+ end.join(rule_separator)
49
+ end.join(line_separator)
50
+ end.join(rule_separator)
51
+ end.join(line_separator)
52
+ elsif self.rules.any? { |r| r.include?(PARENT) }
53
+ raise Sass::SyntaxError.new("Base-level rules cannot contain the parent-selector-referencing character '#{PARENT}'.", line)
54
+ else
55
+ per_rule_indent, total_indent = [:nested, :expanded].include?(@style) ? [rule_indent, ''] : ['', rule_indent]
56
+ total_indent + self.rules.map do |r|
57
+ per_rule_indent + r.gsub(/,$/, '').gsub(rule_split, rule_separator).rstrip
58
+ end.join(line_separator)
59
+ end
60
+
61
+ children.each do |child|
62
+ if child.is_a? RuleNode
63
+ sub_rules << child
64
+ else
65
+ attributes << child
66
+ end
67
+ end
68
+
69
+ to_return = ''
70
+ if !attributes.empty?
71
+ old_spaces = ' ' * (tabs - 1)
72
+ spaces = ' ' * tabs
73
+ if @options[:line_comments] && @style != :compressed
74
+ to_return << "#{old_spaces}/* line #{line}"
75
+
76
+ if filename
77
+ relative_filename = if @options[:css_filename]
78
+ begin
79
+ Pathname.new(filename).relative_path_from(
80
+ Pathname.new(File.dirname(@options[:css_filename]))).to_s
81
+ rescue ArgumentError
82
+ nil
83
+ end
84
+ end
85
+ relative_filename ||= filename
86
+ to_return << ", #{relative_filename}"
87
+ end
88
+
89
+ to_return << " */\n"
90
+ end
91
+
92
+ if @style == :compact
93
+ attributes = attributes.map { |a| a.to_s(1) }.join(' ')
94
+ to_return << "#{total_rule} { #{attributes} }\n"
95
+ elsif @style == :compressed
96
+ attributes = attributes.map { |a| a.to_s(1) }.join(';')
97
+ to_return << "#{total_rule}{#{attributes}}"
98
+ else
99
+ attributes = attributes.map { |a| a.to_s(tabs + 1) }.join("\n")
100
+ end_attrs = (@style == :expanded ? "\n" + old_spaces : ' ')
101
+ to_return << "#{total_rule} {\n#{attributes}#{end_attrs}}\n"
102
+ end
103
+ end
104
+
105
+ tabs += 1 unless attributes.empty? || @style != :nested
106
+ sub_rules.each do |sub|
107
+ to_return << sub.to_s(tabs, total_rule)
108
+ end
109
+
110
+ to_return
111
+ end
112
+
113
+ protected
114
+
115
+ def perform!(environment)
116
+ self.rule = rules.map {|r| interpolate(r, environment)}
117
+ super
118
+ end
119
+ end
120
+ end