haml 1.7.2 → 1.8.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.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/README +17 -9
 - data/Rakefile +12 -4
 - data/VERSION +1 -1
 - data/init.rb +1 -6
 - data/lib/haml.rb +65 -7
 - data/lib/haml/buffer.rb +49 -84
 - data/lib/haml/engine.rb +155 -797
 - data/lib/haml/error.rb +3 -33
 - data/lib/haml/exec.rb +86 -65
 - data/lib/haml/filters.rb +57 -27
 - data/lib/haml/helpers.rb +52 -9
 - data/lib/haml/helpers/action_view_mods.rb +1 -1
 - data/lib/haml/html.rb +20 -5
 - data/lib/haml/precompiler.rb +671 -0
 - data/lib/haml/template.rb +20 -73
 - data/lib/haml/template/patch.rb +51 -0
 - data/lib/haml/template/plugin.rb +21 -0
 - data/lib/sass.rb +78 -3
 - data/lib/sass/constant.rb +45 -19
 - data/lib/sass/constant.rb.rej +42 -0
 - data/lib/sass/constant/string.rb +4 -0
 - data/lib/sass/css.rb +162 -39
 - data/lib/sass/engine.rb +38 -14
 - data/lib/sass/plugin.rb +79 -44
 - data/lib/sass/tree/attr_node.rb +12 -11
 - data/lib/sass/tree/comment_node.rb +9 -3
 - data/lib/sass/tree/directive_node.rb +51 -0
 - data/lib/sass/tree/node.rb +13 -6
 - data/lib/sass/tree/rule_node.rb +34 -12
 - data/test/benchmark.rb +85 -52
 - data/test/haml/engine_test.rb +172 -84
 - data/test/haml/helper_test.rb +31 -3
 - data/test/haml/html2haml_test.rb +60 -0
 - data/test/haml/markaby/standard.mab +52 -0
 - data/test/haml/results/eval_suppressed.xhtml +4 -1
 - data/test/haml/results/helpers.xhtml +15 -4
 - data/test/haml/results/just_stuff.xhtml +9 -1
 - data/test/haml/results/standard.xhtml +0 -1
 - 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 +0 -1
 - data/test/haml/template_test.rb +41 -21
 - data/test/haml/templates/_av_partial_1.haml +9 -0
 - data/test/haml/templates/_av_partial_2.haml +5 -0
 - data/test/haml/templates/action_view.haml +47 -0
 - data/test/haml/templates/eval_suppressed.haml +1 -0
 - data/test/haml/templates/helpers.haml +9 -3
 - data/test/haml/templates/just_stuff.haml +10 -1
 - data/test/haml/templates/partials.haml +1 -1
 - data/test/haml/templates/standard.haml +0 -1
 - data/test/profile.rb +2 -2
 - data/test/sass/engine_test.rb +113 -3
 - data/test/sass/engine_test.rb.rej +18 -0
 - data/test/sass/plugin_test.rb +34 -11
 - data/test/sass/results/compact.css +1 -1
 - data/test/sass/results/complex.css +1 -1
 - data/test/sass/results/compressed.css +1 -0
 - data/test/sass/results/constants.css +3 -1
 - data/test/sass/results/expanded.css +2 -1
 - data/test/sass/results/import.css +2 -0
 - data/test/sass/results/nested.css +2 -1
 - data/test/sass/templates/_partial.sass +2 -0
 - data/test/sass/templates/compact.sass +2 -0
 - data/test/sass/templates/complex.sass +1 -0
 - data/test/sass/templates/compressed.sass +15 -0
 - data/test/sass/templates/constants.sass +9 -0
 - data/test/sass/templates/expanded.sass +2 -0
 - data/test/sass/templates/import.sass +1 -1
 - data/test/sass/templates/nested.sass +2 -0
 - metadata +22 -2
 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ***************
         
     | 
| 
      
 2 
     | 
    
         
            +
            *** 106,121 ****
         
     | 
| 
      
 3 
     | 
    
         
            +
                            end
         
     | 
| 
      
 4 
     | 
    
         
            +
              
         
     | 
| 
      
 5 
     | 
    
         
            +
                            # Time for a unary minus!
         
     | 
| 
      
 6 
     | 
    
         
            +
            -               if negative_okay && symbol == :minus
         
     | 
| 
      
 7 
     | 
    
         
            +
            -                 negative_okay = true
         
     | 
| 
      
 8 
     | 
    
         
            +
                              to_return << :neg
         
     | 
| 
      
 9 
     | 
    
         
            +
                              next
         
     | 
| 
      
 10 
     | 
    
         
            +
                            end
         
     | 
| 
      
 11 
     | 
    
         
            +
              
         
     | 
| 
      
 12 
     | 
    
         
            +
                            # Are we looking at an operator?
         
     | 
| 
      
 13 
     | 
    
         
            +
                            if symbol && (str.empty? || symbol != :mod)
         
     | 
| 
      
 14 
     | 
    
         
            +
                              str = reset_str.call
         
     | 
| 
      
 15 
     | 
    
         
            +
            -                 negative_okay = true
         
     | 
| 
      
 16 
     | 
    
         
            +
                              to_return << symbol
         
     | 
| 
      
 17 
     | 
    
         
            +
                              next
         
     | 
| 
      
 18 
     | 
    
         
            +
                            end
         
     | 
| 
      
 19 
     | 
    
         
            +
            --- 107,129 ----
         
     | 
| 
      
 20 
     | 
    
         
            +
                            end
         
     | 
| 
      
 21 
     | 
    
         
            +
              
         
     | 
| 
      
 22 
     | 
    
         
            +
                            # Time for a unary minus!
         
     | 
| 
      
 23 
     | 
    
         
            +
            +               if beginning_of_token && symbol == :minus
         
     | 
| 
      
 24 
     | 
    
         
            +
            +                 beginning_of_token = true
         
     | 
| 
      
 25 
     | 
    
         
            +
                              to_return << :neg
         
     | 
| 
      
 26 
     | 
    
         
            +
                              next
         
     | 
| 
      
 27 
     | 
    
         
            +
                            end
         
     | 
| 
      
 28 
     | 
    
         
            +
              
         
     | 
| 
      
 29 
     | 
    
         
            +
            +               # Is this a constant?
         
     | 
| 
      
 30 
     | 
    
         
            +
            +               if beginning_of_token && symbol == :const
         
     | 
| 
      
 31 
     | 
    
         
            +
            +                 beginning_of_token = true
         
     | 
| 
      
 32 
     | 
    
         
            +
            +                 to_return << :const
         
     | 
| 
      
 33 
     | 
    
         
            +
            +                 next
         
     | 
| 
      
 34 
     | 
    
         
            +
            +               end
         
     | 
| 
      
 35 
     | 
    
         
            +
            + 
         
     | 
| 
      
 36 
     | 
    
         
            +
                            # Are we looking at an operator?
         
     | 
| 
      
 37 
     | 
    
         
            +
                            if symbol && (str.empty? || symbol != :mod)
         
     | 
| 
      
 38 
     | 
    
         
            +
                              str = reset_str.call
         
     | 
| 
      
 39 
     | 
    
         
            +
            +                 beginning_of_token = true
         
     | 
| 
      
 40 
     | 
    
         
            +
                              to_return << symbol
         
     | 
| 
      
 41 
     | 
    
         
            +
                              next
         
     | 
| 
      
 42 
     | 
    
         
            +
                            end
         
     | 
    
        data/lib/sass/constant/string.rb
    CHANGED
    
    
    
        data/lib/sass/css.rb
    CHANGED
    
    | 
         @@ -41,20 +41,52 @@ module Sass 
     | 
|
| 
       41 
41 
     | 
    
         
             
                  end
         
     | 
| 
       42 
42 
     | 
    
         
             
                end
         
     | 
| 
       43 
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('Node', :key, :value, :next)
         
     | 
| 
      
 50 
     | 
    
         
            +
                include Enumerable
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 53 
     | 
    
         
            +
                  @hash = {}
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                def [](key)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  @hash[key] && @hash[key].value
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                def []=(key, value)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  node = Node.new(key, value, nil)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  if @first.nil?
         
     | 
| 
      
 63 
     | 
    
         
            +
                    @first = @last = node
         
     | 
| 
      
 64 
     | 
    
         
            +
                  else
         
     | 
| 
      
 65 
     | 
    
         
            +
                    @last.next = node
         
     | 
| 
      
 66 
     | 
    
         
            +
                    @last = node
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
                  @hash[key] = node
         
     | 
| 
      
 69 
     | 
    
         
            +
                  value
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                def each
         
     | 
| 
      
 73 
     | 
    
         
            +
                  return unless @first
         
     | 
| 
      
 74 
     | 
    
         
            +
                  yield [@first.key, @first.value]
         
     | 
| 
      
 75 
     | 
    
         
            +
                  node = @first
         
     | 
| 
      
 76 
     | 
    
         
            +
                  yield [node.key, node.value] while node = node.next
         
     | 
| 
      
 77 
     | 
    
         
            +
                  self
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                def values
         
     | 
| 
      
 81 
     | 
    
         
            +
                  self.map { |k, v| v }
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
       44 
85 
     | 
    
         
             
              # :startdoc:
         
     | 
| 
       45 
86 
     | 
    
         | 
| 
       46 
87 
     | 
    
         
             
              # This class contains the functionality used in the +css2sass+ utility,
         
     | 
| 
       47 
88 
     | 
    
         
             
              # namely converting CSS documents to Sass templates.
         
     | 
| 
       48 
89 
     | 
    
         
             
              class CSS
         
     | 
| 
       49 
     | 
    
         
            -
                # :stopdoc:
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                # The Regexp matching a CSS rule
         
     | 
| 
       52 
     | 
    
         
            -
                RULE_RE = /\s*([^\{]+)\s*\{/
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                # The Regexp matching a CSS attribute
         
     | 
| 
       55 
     | 
    
         
            -
                ATTR_RE = /\s*[^::\{\}]+\s*:\s*[^:;\{\}]+\s*;/
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                # :startdoc:
         
     | 
| 
       58 
90 
     | 
    
         | 
| 
       59 
91 
     | 
    
         
             
                # Creates a new instance of Sass::CSS that will compile the given document
         
     | 
| 
       60 
92 
     | 
    
         
             
                # to a Sass string when +render+ is called.
         
     | 
| 
         @@ -84,9 +116,12 @@ module Sass 
     | 
|
| 
       84 
116 
     | 
    
         
             
                def build_tree
         
     | 
| 
       85 
117 
     | 
    
         
             
                  root = Tree::Node.new(nil)
         
     | 
| 
       86 
118 
     | 
    
         
             
                  whitespace
         
     | 
| 
       87 
     | 
    
         
            -
                  directives 
     | 
| 
       88 
     | 
    
         
            -
                  rules 
     | 
| 
       89 
     | 
    
         
            -
                   
     | 
| 
      
 119 
     | 
    
         
            +
                  directives    root
         
     | 
| 
      
 120 
     | 
    
         
            +
                  rules         root
         
     | 
| 
      
 121 
     | 
    
         
            +
                  expand_commas root
         
     | 
| 
      
 122 
     | 
    
         
            +
                  nest_rules    root
         
     | 
| 
      
 123 
     | 
    
         
            +
                  flatten_rules root
         
     | 
| 
      
 124 
     | 
    
         
            +
                  fold_commas   root
         
     | 
| 
       90 
125 
     | 
    
         
             
                  root
         
     | 
| 
       91 
126 
     | 
    
         
             
                end
         
     | 
| 
       92 
127 
     | 
    
         | 
| 
         @@ -131,11 +166,11 @@ module Sass 
     | 
|
| 
       131 
166 
     | 
    
         
             
                    assert_match /:/
         
     | 
| 
       132 
167 
     | 
    
         | 
| 
       133 
168 
     | 
    
         
             
                    value = ''
         
     | 
| 
       134 
     | 
    
         
            -
                    while @template.scan(/[^;\s]+/)
         
     | 
| 
      
 169 
     | 
    
         
            +
                    while @template.scan(/[^;\s\}]+/)
         
     | 
| 
       135 
170 
     | 
    
         
             
                      value << @template[0] << whitespace
         
     | 
| 
       136 
171 
     | 
    
         
             
                    end
         
     | 
| 
       137 
172 
     | 
    
         | 
| 
       138 
     | 
    
         
            -
                    assert_match  
     | 
| 
      
 173 
     | 
    
         
            +
                    assert_match /(;|(?=\}))/
         
     | 
| 
       139 
174 
     | 
    
         
             
                    rule << Tree::AttrNode.new(name, value, nil)
         
     | 
| 
       140 
175 
     | 
    
         
             
                  end
         
     | 
| 
       141 
176 
     | 
    
         | 
| 
         @@ -161,37 +196,125 @@ module Sass 
     | 
|
| 
       161 
196 
     | 
    
         
             
                  whitespace
         
     | 
| 
       162 
197 
     | 
    
         
             
                end
         
     | 
| 
       163 
198 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
                 
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
      
 199 
     | 
    
         
            +
                # Transform
         
     | 
| 
      
 200 
     | 
    
         
            +
                #
         
     | 
| 
      
 201 
     | 
    
         
            +
                #   foo, bar, baz
         
     | 
| 
      
 202 
     | 
    
         
            +
                #     color: blue
         
     | 
| 
      
 203 
     | 
    
         
            +
                #
         
     | 
| 
      
 204 
     | 
    
         
            +
                # into
         
     | 
| 
      
 205 
     | 
    
         
            +
                #
         
     | 
| 
      
 206 
     | 
    
         
            +
                #   foo
         
     | 
| 
      
 207 
     | 
    
         
            +
                #     color: blue
         
     | 
| 
      
 208 
     | 
    
         
            +
                #   bar
         
     | 
| 
      
 209 
     | 
    
         
            +
                #     color: blue
         
     | 
| 
      
 210 
     | 
    
         
            +
                #   baz
         
     | 
| 
      
 211 
     | 
    
         
            +
                #     color: blue
         
     | 
| 
      
 212 
     | 
    
         
            +
                #
         
     | 
| 
      
 213 
     | 
    
         
            +
                # Yes, this expands the amount of code,
         
     | 
| 
      
 214 
     | 
    
         
            +
                # but it's necessary to get nesting to work properly.
         
     | 
| 
      
 215 
     | 
    
         
            +
                def expand_commas(root)
         
     | 
| 
      
 216 
     | 
    
         
            +
                  root.children.map! do |child|
         
     | 
| 
      
 217 
     | 
    
         
            +
                    next child unless Tree::RuleNode === child && child.rule.include?(',')
         
     | 
| 
      
 218 
     | 
    
         
            +
                    child.rule.split(',').map do |rule|
         
     | 
| 
      
 219 
     | 
    
         
            +
                      node = Tree::RuleNode.new(rule, nil)
         
     | 
| 
      
 220 
     | 
    
         
            +
                      node.children = child.children
         
     | 
| 
      
 221 
     | 
    
         
            +
                      node
         
     | 
| 
      
 222 
     | 
    
         
            +
                    end
         
     | 
| 
      
 223 
     | 
    
         
            +
                  end
         
     | 
| 
      
 224 
     | 
    
         
            +
                  root.children.flatten!
         
     | 
| 
      
 225 
     | 
    
         
            +
                end
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
                # Nest rules so that
         
     | 
| 
      
 228 
     | 
    
         
            +
                #
         
     | 
| 
      
 229 
     | 
    
         
            +
                #   foo
         
     | 
| 
      
 230 
     | 
    
         
            +
                #     color: green
         
     | 
| 
      
 231 
     | 
    
         
            +
                #   foo bar
         
     | 
| 
      
 232 
     | 
    
         
            +
                #     color: red
         
     | 
| 
      
 233 
     | 
    
         
            +
                #   foo baz
         
     | 
| 
      
 234 
     | 
    
         
            +
                #     color: blue
         
     | 
| 
      
 235 
     | 
    
         
            +
                #
         
     | 
| 
      
 236 
     | 
    
         
            +
                # becomes
         
     | 
| 
      
 237 
     | 
    
         
            +
                #
         
     | 
| 
      
 238 
     | 
    
         
            +
                #   foo
         
     | 
| 
      
 239 
     | 
    
         
            +
                #     color: green
         
     | 
| 
      
 240 
     | 
    
         
            +
                #     bar
         
     | 
| 
      
 241 
     | 
    
         
            +
                #       color: red
         
     | 
| 
      
 242 
     | 
    
         
            +
                #     baz
         
     | 
| 
      
 243 
     | 
    
         
            +
                #       color: blue
         
     | 
| 
      
 244 
     | 
    
         
            +
                # 
         
     | 
| 
      
 245 
     | 
    
         
            +
                def nest_rules(root)
         
     | 
| 
      
 246 
     | 
    
         
            +
                  rules = OrderedHash.new
         
     | 
| 
      
 247 
     | 
    
         
            +
                  root.children.select { |c| Tree::RuleNode === c }.each do |child|
         
     | 
| 
      
 248 
     | 
    
         
            +
                    root.children.delete child
         
     | 
| 
      
 249 
     | 
    
         
            +
                    first, rest = child.rule.split(' ', 2)
         
     | 
| 
      
 250 
     | 
    
         
            +
                    rules[first] ||= Tree::RuleNode.new(first, nil)
         
     | 
| 
      
 251 
     | 
    
         
            +
                    if rest
         
     | 
| 
      
 252 
     | 
    
         
            +
                      child.rule = rest
         
     | 
| 
      
 253 
     | 
    
         
            +
                      rules[first] << child
         
     | 
| 
       170 
254 
     | 
    
         
             
                    else
         
     | 
| 
       171 
     | 
    
         
            -
                       
     | 
| 
      
 255 
     | 
    
         
            +
                      rules[first].children += child.children
         
     | 
| 
       172 
256 
     | 
    
         
             
                    end
         
     | 
| 
       173 
257 
     | 
    
         
             
                  end
         
     | 
| 
       174 
258 
     | 
    
         | 
| 
       175 
     | 
    
         
            -
                   
     | 
| 
       176 
     | 
    
         
            -
                   
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
       184 
     | 
    
         
            -
             
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
             
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
      
 259 
     | 
    
         
            +
                  rules.values.each { |v| nest_rules(v) }
         
     | 
| 
      
 260 
     | 
    
         
            +
                  root.children += rules.values
         
     | 
| 
      
 261 
     | 
    
         
            +
                end
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
      
 263 
     | 
    
         
            +
                # Flatten rules so that
         
     | 
| 
      
 264 
     | 
    
         
            +
                #
         
     | 
| 
      
 265 
     | 
    
         
            +
                #   foo
         
     | 
| 
      
 266 
     | 
    
         
            +
                #     bar
         
     | 
| 
      
 267 
     | 
    
         
            +
                #       baz
         
     | 
| 
      
 268 
     | 
    
         
            +
                #         color: red
         
     | 
| 
      
 269 
     | 
    
         
            +
                #
         
     | 
| 
      
 270 
     | 
    
         
            +
                # becomes
         
     | 
| 
      
 271 
     | 
    
         
            +
                #
         
     | 
| 
      
 272 
     | 
    
         
            +
                #   foo bar baz
         
     | 
| 
      
 273 
     | 
    
         
            +
                #     color: red
         
     | 
| 
      
 274 
     | 
    
         
            +
                # 
         
     | 
| 
      
 275 
     | 
    
         
            +
                def flatten_rules(root)
         
     | 
| 
      
 276 
     | 
    
         
            +
                  root.children.each { |child| flatten_rule(child) if child.is_a?(Tree::RuleNode) }
         
     | 
| 
      
 277 
     | 
    
         
            +
                end
         
     | 
| 
      
 278 
     | 
    
         
            +
             
     | 
| 
      
 279 
     | 
    
         
            +
                def flatten_rule(rule)
         
     | 
| 
      
 280 
     | 
    
         
            +
                  while rule.children.size == 1 && rule.children.first.is_a?(Tree::RuleNode)
         
     | 
| 
      
 281 
     | 
    
         
            +
                    child = rule.children.first
         
     | 
| 
      
 282 
     | 
    
         
            +
                    rule.rule = "#{rule.rule} #{child.rule}"
         
     | 
| 
      
 283 
     | 
    
         
            +
                    rule.children = child.children
         
     | 
| 
      
 284 
     | 
    
         
            +
                  end
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
      
 286 
     | 
    
         
            +
                  flatten_rules(rule)
         
     | 
| 
      
 287 
     | 
    
         
            +
                end
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
                # Transform
         
     | 
| 
      
 290 
     | 
    
         
            +
                #
         
     | 
| 
      
 291 
     | 
    
         
            +
                #   foo
         
     | 
| 
      
 292 
     | 
    
         
            +
                #     bar
         
     | 
| 
      
 293 
     | 
    
         
            +
                #       color: blue
         
     | 
| 
      
 294 
     | 
    
         
            +
                #     baz
         
     | 
| 
      
 295 
     | 
    
         
            +
                #       color: blue
         
     | 
| 
      
 296 
     | 
    
         
            +
                #
         
     | 
| 
      
 297 
     | 
    
         
            +
                # into
         
     | 
| 
      
 298 
     | 
    
         
            +
                #
         
     | 
| 
      
 299 
     | 
    
         
            +
                #   foo
         
     | 
| 
      
 300 
     | 
    
         
            +
                #     bar, baz
         
     | 
| 
      
 301 
     | 
    
         
            +
                #       color: blue
         
     | 
| 
      
 302 
     | 
    
         
            +
                #
         
     | 
| 
      
 303 
     | 
    
         
            +
                def fold_commas(root)
         
     | 
| 
      
 304 
     | 
    
         
            +
                  prev_rule = nil
         
     | 
| 
      
 305 
     | 
    
         
            +
                  root.children.map! do |child|
         
     | 
| 
      
 306 
     | 
    
         
            +
                    next child unless Tree::RuleNode === child
         
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
      
 308 
     | 
    
         
            +
                    if prev_rule && prev_rule.children == child.children
         
     | 
| 
      
 309 
     | 
    
         
            +
                      prev_rule.rule << ", #{child.rule}"
         
     | 
| 
      
 310 
     | 
    
         
            +
                      next nil
         
     | 
| 
       193 
311 
     | 
    
         
             
                    end
         
     | 
| 
      
 312 
     | 
    
         
            +
             
     | 
| 
      
 313 
     | 
    
         
            +
                    fold_commas(child)
         
     | 
| 
      
 314 
     | 
    
         
            +
                    prev_rule = child
         
     | 
| 
      
 315 
     | 
    
         
            +
                    child
         
     | 
| 
       194 
316 
     | 
    
         
             
                  end
         
     | 
| 
      
 317 
     | 
    
         
            +
                  root.children.compact!
         
     | 
| 
       195 
318 
     | 
    
         
             
                end
         
     | 
| 
       196 
319 
     | 
    
         
             
              end
         
     | 
| 
       197 
320 
     | 
    
         
             
            end
         
     | 
    
        data/lib/sass/engine.rb
    CHANGED
    
    | 
         @@ -3,6 +3,7 @@ require 'sass/tree/value_node' 
     | 
|
| 
       3 
3 
     | 
    
         
             
            require 'sass/tree/rule_node'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'sass/tree/comment_node'
         
     | 
| 
       5 
5 
     | 
    
         
             
            require 'sass/tree/attr_node'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'sass/tree/directive_node'
         
     | 
| 
       6 
7 
     | 
    
         
             
            require 'sass/constant'
         
     | 
| 
       7 
8 
     | 
    
         
             
            require 'sass/error'
         
     | 
| 
       8 
9 
     | 
    
         
             
            require 'haml/util'
         
     | 
| 
         @@ -38,6 +39,9 @@ module Sass 
     | 
|
| 
       38 
39 
     | 
    
         | 
| 
       39 
40 
     | 
    
         
             
                # The character used to denote a compiler directive.
         
     | 
| 
       40 
41 
     | 
    
         
             
                DIRECTIVE_CHAR = ?@
         
     | 
| 
      
 42 
     | 
    
         
            +
                
         
     | 
| 
      
 43 
     | 
    
         
            +
                # Designates a non-parsed rule.
         
     | 
| 
      
 44 
     | 
    
         
            +
                ESCAPE_CHAR    = ?\\
         
     | 
| 
       41 
45 
     | 
    
         | 
| 
       42 
46 
     | 
    
         
             
                # The regex that matches and extracts data from
         
     | 
| 
       43 
47 
     | 
    
         
             
                # attributes of the form <tt>:name attr</tt>.
         
     | 
| 
         @@ -69,7 +73,7 @@ module Sass 
     | 
|
| 
       69 
73 
     | 
    
         
             
                  }.merge! options
         
     | 
| 
       70 
74 
     | 
    
         
             
                  @template = template.split(/\n\r|\n/)
         
     | 
| 
       71 
75 
     | 
    
         
             
                  @lines = []
         
     | 
| 
       72 
     | 
    
         
            -
                  @constants = {}
         
     | 
| 
      
 76 
     | 
    
         
            +
                  @constants = {"important" => "!important"}
         
     | 
| 
       73 
77 
     | 
    
         
             
                end
         
     | 
| 
       74 
78 
     | 
    
         | 
| 
       75 
79 
     | 
    
         
             
                # Processes the template and returns the result as a string.
         
     | 
| 
         @@ -232,6 +236,8 @@ module Sass 
     | 
|
| 
       232 
236 
     | 
    
         
             
                    parse_comment(line)
         
     | 
| 
       233 
237 
     | 
    
         
             
                  when DIRECTIVE_CHAR
         
     | 
| 
       234 
238 
     | 
    
         
             
                    parse_directive(line)
         
     | 
| 
      
 239 
     | 
    
         
            +
                  when ESCAPE_CHAR
         
     | 
| 
      
 240 
     | 
    
         
            +
                    Tree::RuleNode.new(line[1..-1], @options[:style])
         
     | 
| 
       235 
241 
     | 
    
         
             
                  else
         
     | 
| 
       236 
242 
     | 
    
         
             
                    if line =~ ATTRIBUTE_ALTERNATE_MATCHER
         
     | 
| 
       237 
243 
     | 
    
         
             
                      parse_attribute(line, ATTRIBUTE_ALTERNATE)
         
     | 
| 
         @@ -242,6 +248,14 @@ module Sass 
     | 
|
| 
       242 
248 
     | 
    
         
             
                end
         
     | 
| 
       243 
249 
     | 
    
         | 
| 
       244 
250 
     | 
    
         
             
                def parse_attribute(line, attribute_regx)
         
     | 
| 
      
 251 
     | 
    
         
            +
                  if @options[:attribute_syntax] == :normal &&
         
     | 
| 
      
 252 
     | 
    
         
            +
                      attribute_regx == ATTRIBUTE_ALTERNATE
         
     | 
| 
      
 253 
     | 
    
         
            +
                    raise SyntaxError.new("Illegal attribute syntax: can't use alternate syntax when :attribute_syntax => :normal is set.")
         
     | 
| 
      
 254 
     | 
    
         
            +
                  elsif @options[:attribute_syntax] == :alternate &&
         
     | 
| 
      
 255 
     | 
    
         
            +
                      attribute_regx == ATTRIBUTE
         
     | 
| 
      
 256 
     | 
    
         
            +
                    raise SyntaxError.new("Illegal attribute syntax: can't use normal syntax when :attribute_syntax => :alternate is set.")
         
     | 
| 
      
 257 
     | 
    
         
            +
                  end
         
     | 
| 
      
 258 
     | 
    
         
            +
             
     | 
| 
       245 
259 
     | 
    
         
             
                  name, eq, value = line.scan(attribute_regx)[0]
         
     | 
| 
       246 
260 
     | 
    
         | 
| 
       247 
261 
     | 
    
         
             
                  if name.nil? || value.nil?
         
     | 
| 
         @@ -281,7 +295,7 @@ module Sass 
     | 
|
| 
       281 
295 
     | 
    
         
             
                  when "import"
         
     | 
| 
       282 
296 
     | 
    
         
             
                    import(value)
         
     | 
| 
       283 
297 
     | 
    
         
             
                  else
         
     | 
| 
       284 
     | 
    
         
            -
                     
     | 
| 
      
 298 
     | 
    
         
            +
                    Tree::DirectiveNode.new(line, @options[:style])
         
     | 
| 
       285 
299 
     | 
    
         
             
                  end
         
     | 
| 
       286 
300 
     | 
    
         
             
                end
         
     | 
| 
       287 
301 
     | 
    
         | 
| 
         @@ -290,7 +304,13 @@ module Sass 
     | 
|
| 
       290 
304 
     | 
    
         | 
| 
       291 
305 
     | 
    
         
             
                  files.split(/,\s*/).each do |filename|
         
     | 
| 
       292 
306 
     | 
    
         
             
                    engine = nil
         
     | 
| 
       293 
     | 
    
         
            -
             
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
      
 308 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 309 
     | 
    
         
            +
                      filename = self.class.find_file_to_import(filename, @options[:load_paths])
         
     | 
| 
      
 310 
     | 
    
         
            +
                    rescue Exception => e
         
     | 
| 
      
 311 
     | 
    
         
            +
                      raise SyntaxError.new(e.message, @line)
         
     | 
| 
      
 312 
     | 
    
         
            +
                    end
         
     | 
| 
      
 313 
     | 
    
         
            +
             
     | 
| 
       294 
314 
     | 
    
         
             
                    if filename =~ /\.css$/
         
     | 
| 
       295 
315 
     | 
    
         
             
                      nodes << Tree::ValueNode.new("@import url(#{filename});", @options[:style])
         
     | 
| 
       296 
316 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -319,10 +339,9 @@ module Sass 
     | 
|
| 
       319 
339 
     | 
    
         
             
                  nodes
         
     | 
| 
       320 
340 
     | 
    
         
             
                end
         
     | 
| 
       321 
341 
     | 
    
         | 
| 
       322 
     | 
    
         
            -
                def find_file_to_import(filename)
         
     | 
| 
      
 342 
     | 
    
         
            +
                def self.find_file_to_import(filename, load_paths)
         
     | 
| 
       323 
343 
     | 
    
         
             
                  was_sass = false
         
     | 
| 
       324 
344 
     | 
    
         
             
                  original_filename = filename
         
     | 
| 
       325 
     | 
    
         
            -
                  new_filename = nil
         
     | 
| 
       326 
345 
     | 
    
         | 
| 
       327 
346 
     | 
    
         
             
                  if filename[-5..-1] == ".sass"
         
     | 
| 
       328 
347 
     | 
    
         
             
                    filename = filename[0...-5]
         
     | 
| 
         @@ -331,18 +350,11 @@ module Sass 
     | 
|
| 
       331 
350 
     | 
    
         
             
                    return filename
         
     | 
| 
       332 
351 
     | 
    
         
             
                  end
         
     | 
| 
       333 
352 
     | 
    
         | 
| 
       334 
     | 
    
         
            -
                   
     | 
| 
       335 
     | 
    
         
            -
                    full_path = File.join(path, filename) + '.sass'
         
     | 
| 
       336 
     | 
    
         
            -
             
     | 
| 
       337 
     | 
    
         
            -
                    if File.readable?(full_path)
         
     | 
| 
       338 
     | 
    
         
            -
                      new_filename = full_path
         
     | 
| 
       339 
     | 
    
         
            -
                      break
         
     | 
| 
       340 
     | 
    
         
            -
                    end
         
     | 
| 
       341 
     | 
    
         
            -
                  end
         
     | 
| 
      
 353 
     | 
    
         
            +
                  new_filename = find_full_path("#{filename}.sass", load_paths)
         
     | 
| 
       342 
354 
     | 
    
         | 
| 
       343 
355 
     | 
    
         
             
                  if new_filename.nil?
         
     | 
| 
       344 
356 
     | 
    
         
             
                    if was_sass
         
     | 
| 
       345 
     | 
    
         
            -
                      raise  
     | 
| 
      
 357 
     | 
    
         
            +
                      raise Exception.new("File to import not found or unreadable: #{original_filename}")
         
     | 
| 
       346 
358 
     | 
    
         
             
                    else
         
     | 
| 
       347 
359 
     | 
    
         
             
                      return filename + '.css'
         
     | 
| 
       348 
360 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -350,5 +362,17 @@ module Sass 
     | 
|
| 
       350 
362 
     | 
    
         
             
                    new_filename
         
     | 
| 
       351 
363 
     | 
    
         
             
                  end
         
     | 
| 
       352 
364 
     | 
    
         
             
                end
         
     | 
| 
      
 365 
     | 
    
         
            +
             
     | 
| 
      
 366 
     | 
    
         
            +
                def self.find_full_path(filename, load_paths)
         
     | 
| 
      
 367 
     | 
    
         
            +
                  load_paths.each do |path|
         
     | 
| 
      
 368 
     | 
    
         
            +
                    ["_#{filename}", filename].each do |name|
         
     | 
| 
      
 369 
     | 
    
         
            +
                      full_path = File.join(path, name)
         
     | 
| 
      
 370 
     | 
    
         
            +
                      if File.readable?(full_path)
         
     | 
| 
      
 371 
     | 
    
         
            +
                        return full_path
         
     | 
| 
      
 372 
     | 
    
         
            +
                      end
         
     | 
| 
      
 373 
     | 
    
         
            +
                    end
         
     | 
| 
      
 374 
     | 
    
         
            +
                  end
         
     | 
| 
      
 375 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 376 
     | 
    
         
            +
                end
         
     | 
| 
       353 
377 
     | 
    
         
             
              end
         
     | 
| 
       354 
378 
     | 
    
         
             
            end
         
     | 
    
        data/lib/sass/plugin.rb
    CHANGED
    
    | 
         @@ -26,62 +26,40 @@ module Sass 
     | 
|
| 
       26 
26 
     | 
    
         
             
                  def options=(value)
         
     | 
| 
       27 
27 
     | 
    
         
             
                    @@options.merge!(value)
         
     | 
| 
       28 
28 
     | 
    
         
             
                  end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       30 
30 
     | 
    
         
             
                  # Checks each stylesheet in <tt>options[:css_location]</tt>
         
     | 
| 
       31 
31 
     | 
    
         
             
                  # to see if it needs updating,
         
     | 
| 
       32 
32 
     | 
    
         
             
                  # and updates it using the corresponding template
         
     | 
| 
       33 
33 
     | 
    
         
             
                  # from <tt>options[:templates]</tt>
         
     | 
| 
       34 
34 
     | 
    
         
             
                  # if it does.
         
     | 
| 
       35 
35 
     | 
    
         
             
                  def update_stylesheets
         
     | 
| 
      
 36 
     | 
    
         
            +
                    return if options[:never_update]
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       36 
38 
     | 
    
         
             
                    Dir.glob(File.join(options[:template_location], "**", "*.sass")).entries.each do |file|
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
       38 
40 
     | 
    
         
             
                      # Get the relative path to the file with no extension
         
     | 
| 
       39 
41 
     | 
    
         
             
                      name = file.sub(options[:template_location] + "/", "")[0...-5]
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                      if options[:always_update] || stylesheet_needs_update?(name)
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                      if !forbid_update?(name) && (options[:always_update] || stylesheet_needs_update?(name))
         
     | 
| 
       42 
44 
     | 
    
         
             
                        css = css_filename(name)
         
     | 
| 
       43 
45 
     | 
    
         
             
                        File.delete(css) if File.exists?(css)
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
       45 
47 
     | 
    
         
             
                        filename = template_filename(name)
         
     | 
| 
       46 
48 
     | 
    
         
             
                        l_options = @@options.dup
         
     | 
| 
       47 
49 
     | 
    
         
             
                        l_options[:filename] = filename
         
     | 
| 
       48 
     | 
    
         
            -
                        l_options[:load_paths] =  
     | 
| 
      
 50 
     | 
    
         
            +
                        l_options[:load_paths] = load_paths
         
     | 
| 
       49 
51 
     | 
    
         
             
                        engine = Engine.new(File.read(filename), l_options)
         
     | 
| 
       50 
     | 
    
         
            -
                        begin
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                            if e.is_a? Sass::SyntaxError
         
     | 
| 
       57 
     | 
    
         
            -
                              e_string << "\non line #{e.sass_line}"
         
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                              if e.sass_filename
         
     | 
| 
       60 
     | 
    
         
            -
                                e_string << " of #{e.sass_filename}"
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                                if File.exists?(e.sass_filename)
         
     | 
| 
       63 
     | 
    
         
            -
                                  e_string << "\n\n"
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
                                  min = [e.sass_line - 5, 0].max
         
     | 
| 
       66 
     | 
    
         
            -
                                  File.read(e.sass_filename).rstrip.split("\n")[
         
     | 
| 
       67 
     | 
    
         
            -
                                      min .. e.sass_line + 5
         
     | 
| 
       68 
     | 
    
         
            -
                                  ].each_with_index do |line, i|
         
     | 
| 
       69 
     | 
    
         
            -
                                    e_string << "#{min + i + 1}: #{line}\n"
         
     | 
| 
       70 
     | 
    
         
            -
                                  end
         
     | 
| 
       71 
     | 
    
         
            -
                                end
         
     | 
| 
       72 
     | 
    
         
            -
                              end
         
     | 
| 
       73 
     | 
    
         
            -
                            end
         
     | 
| 
       74 
     | 
    
         
            -
                            result = "/*\n#{e_string}\n\nBacktrace:\n#{e.backtrace.join("\n")}\n*/"
         
     | 
| 
       75 
     | 
    
         
            -
                          else
         
     | 
| 
       76 
     | 
    
         
            -
                            result = "/* Internal stylesheet error */"
         
     | 
| 
       77 
     | 
    
         
            -
                          end
         
     | 
| 
       78 
     | 
    
         
            -
                        end
         
     | 
| 
       79 
     | 
    
         
            -
                        
         
     | 
| 
      
 52 
     | 
    
         
            +
                        result = begin
         
     | 
| 
      
 53 
     | 
    
         
            +
                                   engine.render
         
     | 
| 
      
 54 
     | 
    
         
            +
                                 rescue Exception => e
         
     | 
| 
      
 55 
     | 
    
         
            +
                                   exception_string(e)
         
     | 
| 
      
 56 
     | 
    
         
            +
                                 end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
       80 
58 
     | 
    
         
             
                        # Create any directories that might be necessary
         
     | 
| 
       81 
59 
     | 
    
         
             
                        dirs = [l_options[:css_location]]
         
     | 
| 
       82 
60 
     | 
    
         
             
                        name.split("/")[0...-1].each { |dir| dirs << "#{dirs[-1]}/#{dir}" }
         
     | 
| 
       83 
61 
     | 
    
         
             
                        dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) }
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
       85 
63 
     | 
    
         
             
                        # Finally, write the file
         
     | 
| 
       86 
64 
     | 
    
         
             
                        File.open(css, 'w') do |file|
         
     | 
| 
       87 
65 
     | 
    
         
             
                          file.print(result)
         
     | 
| 
         @@ -89,19 +67,76 @@ module Sass 
     | 
|
| 
       89 
67 
     | 
    
         
             
                      end
         
     | 
| 
       90 
68 
     | 
    
         
             
                    end
         
     | 
| 
       91 
69 
     | 
    
         
             
                  end
         
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
       93 
71 
     | 
    
         
             
                  private
         
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  def load_paths
         
     | 
| 
      
 74 
     | 
    
         
            +
                    (options[:load_paths] || []) + [options[:template_location]]
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  def exception_string(e)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    if options[:full_exception]
         
     | 
| 
      
 79 
     | 
    
         
            +
                      e_string = "#{e.class}: #{e.message}"
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                      if e.is_a? Sass::SyntaxError
         
     | 
| 
      
 82 
     | 
    
         
            +
                        e_string << "\non line #{e.sass_line}"
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                        if e.sass_filename
         
     | 
| 
      
 85 
     | 
    
         
            +
                          e_string << " of #{e.sass_filename}"
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                          if File.exists?(e.sass_filename)
         
     | 
| 
      
 88 
     | 
    
         
            +
                            e_string << "\n\n"
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                            min = [e.sass_line - 5, 0].max
         
     | 
| 
      
 91 
     | 
    
         
            +
                            File.read(e.sass_filename).rstrip.split("\n")[
         
     | 
| 
      
 92 
     | 
    
         
            +
                              min .. e.sass_line + 5
         
     | 
| 
      
 93 
     | 
    
         
            +
                            ].each_with_index do |line, i|
         
     | 
| 
      
 94 
     | 
    
         
            +
                              e_string << "#{min + i + 1}: #{line}\n"
         
     | 
| 
      
 95 
     | 
    
         
            +
                            end
         
     | 
| 
      
 96 
     | 
    
         
            +
                          end
         
     | 
| 
      
 97 
     | 
    
         
            +
                        end
         
     | 
| 
      
 98 
     | 
    
         
            +
                      end
         
     | 
| 
      
 99 
     | 
    
         
            +
                      "/*\n#{e_string}\n\nBacktrace:\n#{e.backtrace.join("\n")}\n*/"
         
     | 
| 
      
 100 
     | 
    
         
            +
                    else
         
     | 
| 
      
 101 
     | 
    
         
            +
                      "/* Internal stylesheet error */"
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
       95 
105 
     | 
    
         
             
                  def template_filename(name)
         
     | 
| 
       96 
     | 
    
         
            -
                    "#{ 
     | 
| 
      
 106 
     | 
    
         
            +
                    "#{options[:template_location]}/#{name}.sass"
         
     | 
| 
       97 
107 
     | 
    
         
             
                  end
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
       99 
109 
     | 
    
         
             
                  def css_filename(name)
         
     | 
| 
       100 
     | 
    
         
            -
                    "#{ 
     | 
| 
      
 110 
     | 
    
         
            +
                    "#{options[:css_location]}/#{name}.css"
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  def forbid_update?(name)
         
     | 
| 
      
 114 
     | 
    
         
            +
                    name[0] == ?_
         
     | 
| 
       101 
115 
     | 
    
         
             
                  end
         
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
       103 
117 
     | 
    
         
             
                  def stylesheet_needs_update?(name)
         
     | 
| 
       104 
     | 
    
         
            -
                    !File.exists?(css_filename(name)) 
     | 
| 
      
 118 
     | 
    
         
            +
                    if !File.exists?(css_filename(name))
         
     | 
| 
      
 119 
     | 
    
         
            +
                      return true
         
     | 
| 
      
 120 
     | 
    
         
            +
                    else
         
     | 
| 
      
 121 
     | 
    
         
            +
                      css_mtime = File.mtime(css_filename(name))
         
     | 
| 
      
 122 
     | 
    
         
            +
                      File.mtime(template_filename(name)) > css_mtime ||
         
     | 
| 
      
 123 
     | 
    
         
            +
                        dependencies(template_filename(name)).any?(&dependency_updated?(css_mtime))
         
     | 
| 
      
 124 
     | 
    
         
            +
                    end
         
     | 
| 
      
 125 
     | 
    
         
            +
                  end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                  def dependency_updated?(css_mtime)
         
     | 
| 
      
 128 
     | 
    
         
            +
                    lambda do |dep|
         
     | 
| 
      
 129 
     | 
    
         
            +
                      File.mtime(dep) > css_mtime ||
         
     | 
| 
      
 130 
     | 
    
         
            +
                        dependencies(dep).any?(&dependency_updated?(css_mtime))
         
     | 
| 
      
 131 
     | 
    
         
            +
                    end
         
     | 
| 
      
 132 
     | 
    
         
            +
                  end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                  def dependencies(filename)
         
     | 
| 
      
 135 
     | 
    
         
            +
                    File.readlines(filename).grep(/^@import /).map do |line|
         
     | 
| 
      
 136 
     | 
    
         
            +
                      line[8..-1].split(',').map do |inc|
         
     | 
| 
      
 137 
     | 
    
         
            +
                        Sass::Engine.find_file_to_import(inc.strip, load_paths)
         
     | 
| 
      
 138 
     | 
    
         
            +
                      end
         
     | 
| 
      
 139 
     | 
    
         
            +
                    end.flatten.grep(/\.sass$/)
         
     | 
| 
       105 
140 
     | 
    
         
             
                  end
         
     | 
| 
       106 
141 
     | 
    
         
             
                end
         
     | 
| 
       107 
142 
     | 
    
         
             
              end
         
     |