haml 3.0.0.beta.1 → 3.0.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

Files changed (67) hide show
  1. data/README.md +7 -7
  2. data/REMEMBER +2 -1
  3. data/Rakefile +6 -4
  4. data/VERSION +1 -1
  5. data/lib/haml/exec.rb +119 -24
  6. data/lib/haml/filters.rb +5 -1
  7. data/lib/haml/helpers.rb +4 -2
  8. data/lib/haml/helpers/action_view_mods.rb +2 -3
  9. data/lib/haml/precompiler.rb +1 -0
  10. data/lib/sass.rb +1 -1
  11. data/lib/sass/css.rb +25 -6
  12. data/lib/sass/engine.rb +23 -7
  13. data/lib/sass/environment.rb +47 -1
  14. data/lib/sass/files.rb +9 -10
  15. data/lib/sass/plugin.rb +6 -27
  16. data/lib/sass/plugin/merb.rb +1 -0
  17. data/lib/sass/plugin/rails.rb +1 -0
  18. data/lib/sass/plugin/staleness_checker.rb +123 -0
  19. data/lib/sass/script/bool.rb +1 -1
  20. data/lib/sass/script/color.rb +1 -1
  21. data/lib/sass/script/css_lexer.rb +1 -4
  22. data/lib/sass/script/funcall.rb +2 -2
  23. data/lib/sass/script/functions.rb +102 -7
  24. data/lib/sass/script/interpolation.rb +5 -5
  25. data/lib/sass/script/lexer.rb +10 -8
  26. data/lib/sass/script/literal.rb +11 -1
  27. data/lib/sass/script/node.rb +10 -1
  28. data/lib/sass/script/number.rb +25 -10
  29. data/lib/sass/script/operation.rb +7 -6
  30. data/lib/sass/script/parser.rb +37 -28
  31. data/lib/sass/script/string.rb +12 -7
  32. data/lib/sass/script/string_interpolation.rb +70 -0
  33. data/lib/sass/script/unary_operation.rb +3 -3
  34. data/lib/sass/script/variable.rb +2 -2
  35. data/lib/sass/scss/css_parser.rb +1 -0
  36. data/lib/sass/scss/parser.rb +58 -44
  37. data/lib/sass/scss/rx.rb +1 -0
  38. data/lib/sass/tree/comment_node.rb +3 -2
  39. data/lib/sass/tree/debug_node.rb +1 -1
  40. data/lib/sass/tree/for_node.rb +1 -1
  41. data/lib/sass/tree/if_node.rb +1 -1
  42. data/lib/sass/tree/import_node.rb +3 -0
  43. data/lib/sass/tree/mixin_def_node.rb +3 -3
  44. data/lib/sass/tree/mixin_node.rb +7 -3
  45. data/lib/sass/tree/node.rb +8 -0
  46. data/lib/sass/tree/prop_node.rb +21 -16
  47. data/lib/sass/tree/rule_node.rb +3 -3
  48. data/lib/sass/tree/variable_node.rb +1 -1
  49. data/lib/sass/tree/warn_node.rb +41 -0
  50. data/lib/sass/tree/while_node.rb +1 -1
  51. data/test/haml/engine_test.rb +9 -0
  52. data/test/sass/conversion_test.rb +127 -15
  53. data/test/sass/css2sass_test.rb +34 -3
  54. data/test/sass/engine_test.rb +82 -5
  55. data/test/sass/functions_test.rb +31 -0
  56. data/test/sass/plugin_test.rb +25 -24
  57. data/test/sass/results/script.css +4 -4
  58. data/test/sass/results/warn.css +0 -0
  59. data/test/sass/results/warn_imported.css +0 -0
  60. data/test/sass/script_conversion_test.rb +43 -1
  61. data/test/sass/script_test.rb +3 -3
  62. data/test/sass/scss/css_test.rb +46 -5
  63. data/test/sass/scss/scss_test.rb +72 -0
  64. data/test/sass/templates/import.sass +1 -1
  65. data/test/sass/templates/warn.sass +3 -0
  66. data/test/sass/templates/warn_imported.sass +4 -0
  67. metadata +10 -3
data/README.md CHANGED
@@ -38,7 +38,7 @@ Sass is a little more complicated;
38
38
  where they'll be automatically compiled
39
39
  to corresponding CSS files in `public/stylesheets` when needed
40
40
  (the Sass template directory is customizable...
41
- see [the Sass reference](http://sass-lang.com/docs/yardoc/SASS_REFERENCE.md.html#template_location-option) for details).
41
+ see [the Sass reference](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#template_location-option) for details).
42
42
 
43
43
  For Merb, `.html.haml` views will work without any further modification.
44
44
  To enable Sass, you also need to add a dependency.
@@ -129,7 +129,7 @@ like `if` and `while`:
129
129
  = "Happy new " + "year!"
130
130
 
131
131
  Haml provides far more tools than those presented here.
132
- Check out the [reference documentation](http://beta.haml-lang.com/docs/yardoc/file.HAML_REFERENCE.md)
132
+ Check out the [reference documentation](http://beta.haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html)
133
133
  for full details.
134
134
 
135
135
  #### Indentation
@@ -151,10 +151,10 @@ and get small stylesheets up and running quickly,
151
151
  particularly with the help of
152
152
  [the Compass style library](http://compass-style.org).
153
153
 
154
- [vars]: http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.md#variables_
155
- [nested]: http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.md#nested_rules_
154
+ [vars]: http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#variables_
155
+ [nested]: http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#nested_rules_
156
156
  [mixins]: http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixins
157
- [imports]: http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.md#import
157
+ [imports]: http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import
158
158
 
159
159
  Sass has two syntaxes.
160
160
  The one presented here, known as "SCSS" (for "Sassy CSS"),
@@ -163,7 +163,7 @@ The other (older) syntax, known as the indented syntax or just "Sass",
163
163
  is whitespace-sensitive and indentation-based.
164
164
  For more information, see the [reference documentation][syntax].
165
165
 
166
- [syntax]: http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.md#syntax
166
+ [syntax]: http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#syntax
167
167
 
168
168
  To run the following examples and see the CSS they produce,
169
169
  put them in a file called `test.scss` and run `sass test.scss`.
@@ -232,7 +232,7 @@ You can even give them arguments.
232
232
  }
233
233
 
234
234
  A comprehensive list of features is available
235
- in the [Sass reference](http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.md).
235
+ in the [Sass reference](http://beta.sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html).
236
236
 
237
237
  ## Executables
238
238
 
data/REMEMBER CHANGED
@@ -7,6 +7,7 @@ Don't conflict with Object#extend.
7
7
  http://camendesign.com/design/ provides some interesting formatting and nesting issues for sass-convert
8
8
  Charles Roper's example code for media queries doesn't fare well in css2sass either
9
9
 
10
- Handle unicode escapes (and other escapes?) gracefully in script idents with sass-convert
11
10
  Add period to SCSS syntax errors?
12
11
  Better #{} in prop names
12
+ Faster than Less
13
+ Comma multiline for Haml
data/Rakefile CHANGED
@@ -70,7 +70,7 @@ at_exit { File.delete(scope('REVISION')) rescue nil }
70
70
 
71
71
  desc "Install Haml as a gem."
72
72
  task :install => [:package] do
73
- sudo = RUBY_PLATFORM =~ /win32/ ? '' : 'sudo'
73
+ sudo = RUBY_PLATFORM =~ /win32|mingw/ ? '' : 'sudo'
74
74
  gem = RUBY_PLATFORM =~ /java/ ? 'jgem' : 'gem'
75
75
  sh %{#{sudo} #{gem} install --no-ri pkg/haml-#{File.read(scope('VERSION')).strip}}
76
76
  end
@@ -191,14 +191,16 @@ task :release_edge do
191
191
  sh %{git merge origin/master}
192
192
 
193
193
  # Get the current master branch version
194
- version = File.read(scope('VERSION')).strip.split('.').map {|n| n.to_i}
195
- unless version[1] % 2 == 1 && version[2] == 0
194
+ version = File.read(scope('VERSION')).strip.split('.')
195
+ pr = version[3]
196
+ version = version.map {|n| n.to_i}
197
+ unless pr || (version[1] % 2 == 1 && version[2] == 0)
196
198
  raise "#{version.join('.')} is not a development version"
197
199
  end
198
200
 
199
201
  # Bump the edge gem version
200
202
  edge_version = File.read(scope('EDGE_GEM_VERSION')).strip.split('.').map {|n| n.to_i}
201
- if edge_version[0..1] != version[0..1]
203
+ if !pr && (edge_version[0..1] != version[0..1])
202
204
  # A new master branch version was released, reset the edge gem version
203
205
  edge_version[0..1] = version[0..1]
204
206
  edge_version[2] = 0
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.0.beta.1
1
+ 3.0.0.beta.2
@@ -15,14 +15,11 @@ module Haml
15
15
 
16
16
  # Parses the command-line arguments and runs the executable.
17
17
  # Calls `Kernel#exit` at the end, so it never returns.
18
+ #
19
+ # @see #parse
18
20
  def parse!
19
21
  begin
20
- @opts = OptionParser.new(&method(:set_opts))
21
- @opts.parse!(@args)
22
-
23
- process_result
24
-
25
- @options
22
+ parse
26
23
  rescue Exception => e
27
24
  raise e if @options[:trace] || e.is_a?(SystemExit)
28
25
 
@@ -32,6 +29,19 @@ module Haml
32
29
  exit 0
33
30
  end
34
31
 
32
+ # Parses the command-line arguments and runs the executable.
33
+ # This does not handle exceptions or exit the program.
34
+ #
35
+ # @see #parse!
36
+ def parse
37
+ @opts = OptionParser.new(&method(:set_opts))
38
+ @opts.parse!(@args)
39
+
40
+ process_result
41
+
42
+ @options
43
+ end
44
+
35
45
  # @return [String] A description of the executable
36
46
  def to_s
37
47
  @opts.to_s
@@ -105,6 +115,39 @@ module Haml
105
115
  @options[:input], @options[:output] = input, output
106
116
  end
107
117
 
118
+ # @private
119
+ COLORS = { :red => 31, :green => 32, :yellow => 33 }
120
+
121
+ # Prints a status message about performing the given action,
122
+ # colored using the given color (via terminal escapes) if possible.
123
+ #
124
+ # @param name [#to_s] A short name for the action being performed.
125
+ # Shouldn't be longer than 11 characters.
126
+ # @param color [Symbol] The name of the color to use for this action.
127
+ # Can be `:red`, `:green`, or `:yellow`.
128
+ def puts_action(name, color, arg)
129
+ printf color(color, "%11s %s\n"), name, arg
130
+ end
131
+
132
+ # Wraps the given string in terminal escapes
133
+ # causing it to have the given color.
134
+ # If terminal esapes aren't supported on this platform,
135
+ # just returns the string instead.
136
+ #
137
+ # @param color [Symbol] The name of the color to use.
138
+ # Can be `:red`, `:green`, or `:yellow`.
139
+ # @param str [String] The string to wrap in the given color.
140
+ # @return [String] The wrapped string.
141
+ def color(color, str)
142
+ raise "[BUG] Unrecognized color #{color}" unless COLORS[color]
143
+
144
+ # Almost any real Unix terminal will support color,
145
+ # so we just filter for Windows terms (which don't set TERM)
146
+ # and not-real terminals, which aren't ttys.
147
+ return str if ENV["TERM"].nil? || ENV["TERM"].empty? || !STDOUT.tty?
148
+ return "\e[#{COLORS[color]}m#{str}\e[0m"
149
+ end
150
+
108
151
  private
109
152
 
110
153
  def open_file(filename, flag = 'r')
@@ -233,6 +276,9 @@ END
233
276
  'Output style. Can be nested (default), compact, compressed, or expanded.') do |name|
234
277
  @options[:for_engine][:style] = name.to_sym
235
278
  end
279
+ opts.on('-q', '--quiet', 'Silence warnings during compilation.') do
280
+ @options[:for_engine][:quiet] = true
281
+ end
236
282
  opts.on('-g', '--debug-info',
237
283
  'Emit extra information in the generated CSS that can be used by the FireSass Firebug plugin.') do
238
284
  @options[:for_engine][:debug_info] = true
@@ -358,23 +404,6 @@ MSG
358
404
 
359
405
  ::Sass::Plugin.watch(files)
360
406
  end
361
-
362
- # @private
363
- COLORS = { :red => 31, :green => 32, :yellow => 33 }
364
-
365
- def puts_action(name, color, arg)
366
- printf color(color, "%11s %s\n"), name, arg
367
- end
368
-
369
- def color(color, str)
370
- raise "[BUG] Unrecognized color #{color}" unless COLORS[color]
371
-
372
- # Almost any real Unix terminal will support color,
373
- # so we just filter for Windows terms (which don't set TERM)
374
- # and not-real terminals, which aren't ttys.
375
- return str if ENV["TERM"].empty? || !STDOUT.tty?
376
- return "\e[#{COLORS[color]}m#{str}\e[0m"
377
- end
378
407
  end
379
408
 
380
409
  # The `haml` executable.
@@ -565,6 +594,9 @@ END
565
594
  'By default, this is inferred from the input filename.',
566
595
  'If there is none, defaults to css.') do |name|
567
596
  @options[:from] = name.downcase.to_sym
597
+ unless [:css, :scss, :sass, :sass2].include?(@options[:from])
598
+ raise "Unknown format for sass-convert --from: #{name}"
599
+ end
568
600
  end
569
601
 
570
602
  opts.on('-T', '--to FORMAT',
@@ -572,6 +604,14 @@ END
572
604
  'By default, this is inferred from the output filename.',
573
605
  'If there is none, defaults to sass.') do |name|
574
606
  @options[:to] = name.downcase.to_sym
607
+ unless [:scss, :sass].include?(@options[:to])
608
+ raise "Unknown format for sass-convert --to: #{name}"
609
+ end
610
+ end
611
+
612
+ opts.on('-R', '--recursive',
613
+ 'Convert all the files in a directory. Requires --from and --to.') do
614
+ @options[:recursive] = true
575
615
  end
576
616
 
577
617
  opts.on('-i', '--in-place',
@@ -580,6 +620,10 @@ END
580
620
  @options[:in_place] = true
581
621
  end
582
622
 
623
+ opts.on('--dasherize', 'Convert underscores to dashes') do
624
+ @options[:for_tree][:dasherize] = true
625
+ end
626
+
583
627
  opts.on('--old', 'Output the old-style ":prop val" property syntax.',
584
628
  'Only meaningful when generating Sass.') do
585
629
  @options[:for_tree][:old] = true
@@ -596,12 +640,63 @@ END
596
640
  # and runs the CSS compiler appropriately.
597
641
  def process_result
598
642
  require 'sass'
599
- super
600
643
 
644
+ if @options[:recursive]
645
+ process_directory
646
+ return
647
+ end
648
+
649
+ super
601
650
  input = @options[:input]
651
+ raise "Error: '#{input}' is a directory (did you mean to use --recursive?)" if File.directory?(input)
602
652
  output = @options[:output]
603
653
  output = input if @options[:in_place]
654
+ process_file(input, output)
655
+ end
656
+
657
+ def process_directory
658
+ input = @options[:input] = @args.shift
659
+ output = @options[:output] = @args.shift
660
+ raise "Error: --from required when using --recursive." unless @options[:from]
661
+ raise "Error: --to required when using --recursive." unless @options[:to]
662
+ raise "Error: '#{@options[:input]}' is not a directory" unless File.directory?(@options[:input])
663
+ if @options[:output] && File.exists?(@options[:output]) && !File.directory?(@options[:output])
664
+ raise "Error: '#{@options[:output]}' is not a directory"
665
+ end
666
+ @options[:output] ||= @options[:input]
667
+
668
+ ext = @options[:from]
669
+ ext = :sass if ext == :sass2
670
+ Dir.glob("#{@options[:input]}/**/*.#{ext}") do |f|
671
+ output =
672
+ if @options[:in_place]
673
+ f
674
+ elsif @options[:output]
675
+ output_name = f.gsub(/\.(c|sa|sc)ss$/, ".#{@options[:to]}")
676
+ output_name[0...@options[:input].size] = @options[:output]
677
+ output_name
678
+ else
679
+ f.gsub(/\.(c|sa|sc)ss$/, ".#{@options[:to]}")
680
+ end
681
+
682
+ unless File.directory?(File.dirname(output))
683
+ puts_action :directory, :green, File.dirname(output)
684
+ FileUtils.mkdir_p(File.dirname(output))
685
+ end
686
+ puts_action :convert, :green, f
687
+ if File.exists?(output)
688
+ puts_action :overwrite, :yellow, output
689
+ else
690
+ puts_action :create, :green, output
691
+ end
692
+
693
+ input = open_file(f)
694
+ output = @options[:in_place] ? input : open_file(output, "w")
695
+ process_file(input, output)
696
+ end
697
+ end
604
698
 
699
+ def process_file(input, output)
605
700
  if input.is_a?(File)
606
701
  @options[:from] ||=
607
702
  case input.path
@@ -100,7 +100,11 @@ module Haml
100
100
  if contains_interpolation?(text)
101
101
  return if options[:suppress_eval]
102
102
 
103
- text = unescape_interpolation(text).gsub("\\n", "\n")
103
+ text = unescape_interpolation(text).gsub(/(\\+)n/) do |s|
104
+ escapes = $1.size
105
+ next s if escapes % 2 == 0
106
+ ("\\" * (escapes - 1)) + "\n"
107
+ end
104
108
  newline if text.gsub!(/\n"\Z/, "\\n\"")
105
109
  push_script <<RUBY.strip, :escape_html => false
106
110
  find_and_preserve(#{filter.inspect}.render_with_options(#{text}, _hamlout.options))
@@ -348,7 +348,9 @@ MESSAGE
348
348
  haml_buffer.capture_position = position
349
349
  block.call(*args)
350
350
 
351
- captured = haml_buffer.buffer.slice!(position..-1).split(/^/)
351
+ captured = haml_buffer.buffer.slice!(position..-1)
352
+ return captured if haml_buffer.options[:ugly]
353
+ captured = captured.split(/^/)
352
354
 
353
355
  min_tabs = nil
354
356
  captured.each do |line|
@@ -511,7 +513,7 @@ MESSAGE
511
513
  # @param text [String] The string to sanitize
512
514
  # @return [String] The sanitized string
513
515
  def html_escape(text)
514
- text.to_s.gsub(/[\"><&]/n) {|s| HTML_ESCAPE[s]}
516
+ Haml::Util.silence_warnings {text.to_s.gsub(/[\"><&]/n) {|s| HTML_ESCAPE[s]}}
515
517
  end
516
518
 
517
519
  # Escapes HTML entities in `text`, but without escaping an ampersand
@@ -125,9 +125,8 @@ module ActionView
125
125
  @template_object.send :is_haml?
126
126
  end
127
127
 
128
- unless defined?(ActionView::Helpers) && defined?(ActionView::Helpers::ActiveRecordInstanceTag)
129
- alias_method :content_tag_without_haml, :content_tag
130
- alias_method :content_tag, :content_tag_with_haml
128
+ def content_tag(*args)
129
+ content_tag_with_haml(*args)
131
130
  end
132
131
  end
133
132
 
@@ -905,6 +905,7 @@ END
905
905
  when "strict"; '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
906
906
  when "frameset"; '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'
907
907
  when "mobile"; '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
908
+ when "rdfa"; '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">'
908
909
  when "basic"; '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'
909
910
  else '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
910
911
  end
@@ -15,7 +15,7 @@ module Sass
15
15
  extend Haml::Version
16
16
 
17
17
  # A string representing the version of Sass.
18
- # A more fine-grained representation is available from {Sass.version}.
18
+ # A more fine-grained representation is available from {Haml::Version#version Sass.version}.
19
19
  VERSION = version[:string] unless defined?(Sass::VERSION)
20
20
  end
21
21
 
@@ -79,7 +79,10 @@ module Sass
79
79
  # @param root [Tree::Node] The parent node
80
80
  def expand_commas(root)
81
81
  root.children.map! do |child|
82
- next child unless Tree::RuleNode === child && child.rule.first.include?(',')
82
+ unless child.is_a?(Tree::RuleNode) && child.rule.first.include?(',')
83
+ expand_commas(child) if child.is_a?(Tree::DirectiveNode)
84
+ next child
85
+ end
83
86
  child.rule.first.split(',').map do |rule|
84
87
  node = Tree::RuleNode.new([rule.strip])
85
88
  node.children = child.children
@@ -126,9 +129,12 @@ module Sass
126
129
  def parent_ref_rules(root)
127
130
  current_rule = nil
128
131
  root.children.map! do |child|
129
- next child unless child.is_a?(Tree::RuleNode)
132
+ unless child.is_a?(Tree::RuleNode)
133
+ parent_ref_rules(child) if child.is_a?(Tree::DirectiveNode)
134
+ next child
135
+ end
130
136
 
131
- first, rest = child.rule.first.scan(/^(&?(?: .|[^ ])[^.#: \[]*)([.#: \[].*)?$/).first
137
+ first, rest = child.rule.first.scan(/\A(&?(?: .|[^ ])[^.#: \[]*)([.#: \[].*)?\Z/m).first
132
138
 
133
139
  if current_rule.nil? || current_rule.rule.first != first
134
140
  current_rule = Tree::RuleNode.new([first])
@@ -164,9 +170,12 @@ module Sass
164
170
  # @param root [Tree::Node] The parent node
165
171
  def remove_parent_refs(root)
166
172
  root.children.each do |child|
167
- if child.is_a?(Tree::RuleNode)
173
+ case child
174
+ when Tree::RuleNode
168
175
  child.rule.first.gsub! /^& +/, ''
169
176
  remove_parent_refs child
177
+ when Tree::DirectiveNode
178
+ remove_parent_refs child
170
179
  end
171
180
  end
172
181
  end
@@ -195,7 +204,14 @@ module Sass
195
204
  #
196
205
  # @param root [Tree::Node] The parent node
197
206
  def flatten_rules(root)
198
- root.children.each { |child| flatten_rule(child) if child.is_a?(Tree::RuleNode) }
207
+ root.children.each do |child|
208
+ case child
209
+ when Tree::RuleNode
210
+ flatten_rule(child)
211
+ when Tree::DirectiveNode
212
+ flatten_rules(child)
213
+ end
214
+ end
199
215
  end
200
216
 
201
217
  # Flattens a single rule
@@ -236,7 +252,10 @@ module Sass
236
252
  def fold_commas(root)
237
253
  prev_rule = nil
238
254
  root.children.map! do |child|
239
- next child unless child.is_a?(Tree::RuleNode)
255
+ unless child.is_a?(Tree::RuleNode)
256
+ fold_commas(child) if child.is_a?(Tree::DirectiveNode)
257
+ next child
258
+ end
240
259
 
241
260
  if prev_rule && prev_rule.children == child.children
242
261
  prev_rule.rule.first << ", #{child.rule.first}"
@@ -13,6 +13,7 @@ require 'sass/tree/if_node'
13
13
  require 'sass/tree/while_node'
14
14
  require 'sass/tree/for_node'
15
15
  require 'sass/tree/debug_node'
16
+ require 'sass/tree/warn_node'
16
17
  require 'sass/tree/import_node'
17
18
  require 'sass/environment'
18
19
  require 'sass/script'
@@ -164,9 +165,9 @@ module Sass
164
165
  # @return [String] The CSS
165
166
  # @raise [Sass::SyntaxError] if there's an error in the document
166
167
  def render
167
- to_tree.render
168
+ return _to_tree.render unless @options[:quiet]
169
+ Haml::Util.silence_haml_warnings {_to_tree.render}
168
170
  end
169
-
170
171
  alias_method :to_css, :render
171
172
 
172
173
  # Parses the document into its parse tree.
@@ -174,6 +175,13 @@ module Sass
174
175
  # @return [Sass::Tree::Node] The root of the parse tree.
175
176
  # @raise [Sass::SyntaxError] if there's an error in the document
176
177
  def to_tree
178
+ return _to_tree unless @options[:quiet]
179
+ Haml::Util.silence_haml_warnings {_to_tree}
180
+ end
181
+
182
+ private
183
+
184
+ def _to_tree
177
185
  @template = check_encoding(@template) {|msg, line| raise Sass::SyntaxError.new(msg, :line => line)}
178
186
 
179
187
  if @options[:syntax] == :scss
@@ -191,8 +199,6 @@ module Sass
191
199
  raise e
192
200
  end
193
201
 
194
- private
195
-
196
202
  def tabulate(string)
197
203
  tab_str = nil
198
204
  comment_tab_str = nil
@@ -415,7 +421,7 @@ WARNING
415
421
  if eq.strip[0] == SCRIPT_CHAR
416
422
  expr.context = :equals
417
423
  Script.equals_warning("properties", name,
418
- Sass::Tree::PropNode.val_to_sass(expr), false,
424
+ Sass::Tree::PropNode.val_to_sass(expr, @options), false,
419
425
  @line, line.offset + 1, @options[:filename])
420
426
  end
421
427
  end
@@ -461,10 +467,13 @@ WARNING
461
467
 
462
468
  # If value begins with url( or ",
463
469
  # it's a CSS @import rule and we don't want to touch it.
464
- if directive == "import" && value !~ /^(url\(|")/
470
+ if directive == "import" && value !~ /^(url\(|["'])/
465
471
  raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath import directives.",
466
472
  :line => @line + 1) unless line.children.empty?
467
- value.split(/,\s*/).map {|f| Tree::ImportNode.new(f)}
473
+ value.split(/,\s*/).map do |f|
474
+ f = $1 || $2 || $3 if f =~ Sass::SCSS::RX::STRING || f =~ Sass::SCSS::RX::URI
475
+ Tree::ImportNode.new(f)
476
+ end
468
477
  elsif directive == "mixin"
469
478
  parse_mixin_definition(line)
470
479
  elsif directive == "include"
@@ -485,6 +494,12 @@ WARNING
485
494
  :line => @line + 1) unless line.children.empty?
486
495
  offset = line.offset + line.text.index(value).to_i
487
496
  Tree::DebugNode.new(parse_script(value, :offset => offset))
497
+ elsif directive == "warn"
498
+ raise SyntaxError.new("Invalid warn directive '@warn': expected expression.") unless value
499
+ raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath warn directives.",
500
+ :line => @line + 1) unless line.children.empty?
501
+ offset = line.offset + line.text.index(value).to_i
502
+ Tree::WarnNode.new(parse_script(value, :offset => offset))
488
503
  else
489
504
  Tree::DirectiveNode.new(line.text)
490
505
  end
@@ -573,6 +588,7 @@ WARNING
573
588
  end
574
589
 
575
590
  return silent ? "//" : "/* */" if content.empty?
591
+ content.each {|l| l.gsub!(/^\* /, '')}
576
592
  content.map! {|l| (l.empty? ? "" : " ") + l}
577
593
  content.first.gsub!(/^ /, '') unless removed_first
578
594
  content.last.gsub!(%r{ ?\*/ *$}, '')