incubator-deltacloud-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lut...@apache.org
Subject svn commit: r961978 [9/13] - in /incubator/deltacloud/trunk/framework: ./ app/ app/controllers/ app/helpers/ app/models/ app/views/ app/views/accounts/ app/views/credentials/ app/views/images/ app/views/instances/ app/views/layouts/ app/views/root/ con...
Date Thu, 08 Jul 2010 23:14:21 GMT
Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/environment.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/environment.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/environment.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/environment.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,79 @@
+module Sass
+  # The lexical environment for SassScript.
+  # This keeps track of variable and mixin definitions.
+  #
+  # A new environment is created for each level of Sass nesting.
+  # This allows variables to be lexically scoped.
+  # The new environment refers to the environment in the upper scope,
+  # so it has access to variables defined in enclosing scopes,
+  # but new variables are defined locally.
+  #
+  # Environment also keeps track of the {Engine} options
+  # so that they can be made available to {Sass::Script::Functions}.
+  class Environment
+    # The enclosing environment,
+    # or nil if this is the global environment.
+    #
+    # @return [Environment]
+    attr_reader :parent
+    attr_writer :options
+
+    # @param parent [Environment] See \{#parent}
+    def initialize(parent = nil)
+      @vars = {}
+      @mixins = {}
+      @parent = parent
+
+      set_var("important", Script::String.new("!important")) unless @parent
+    end
+
+    # The options hash.
+    # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
+    #
+    # @return [Hash<Symbol, Object>]
+    def options
+      @options || (parent && parent.options) || {}
+    end
+
+    class << self
+      private
+
+      # Note: when updating this,
+      # update haml/yard/inherited_hash.rb as well.
+      def inherited_hash(name)
+        class_eval <<RUBY, __FILE__, __LINE__ + 1
+          def #{name}(name)
+            @#{name}s[name] || @parent && @parent.#{name}(name)
+          end
+
+          def set_#{name}(name, value)
+            @#{name}s[name] = value unless try_set_#{name}(name, value)
+          end
+
+          def try_set_#{name}(name, value)
+            if @#{name}s.include?(name)
+              @#{name}s[name] = value
+              true
+            elsif @parent
+              @parent.try_set_#{name}(name, value)
+            else
+              false
+            end
+          end
+          protected :try_set_#{name}
+
+          def set_local_#{name}(name, value)
+            @#{name}s[name] = value
+          end
+RUBY
+      end
+    end
+
+    # variable
+    # Script::Literal
+    inherited_hash :var
+    # mixin
+    # Engine::Mixin
+    inherited_hash :mixin
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/error.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/error.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/error.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/error.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,57 @@
+module Sass
+  # An exception class that keeps track of
+  # the line of the Sass template it was raised on
+  # and the Sass file that was being parsed (if applicable).
+  #
+  # All Sass errors are raised as {Sass::SyntaxError}s.
+  class SyntaxError < StandardError
+    # The line of the Sass template on which the error occurred.
+    #
+    # @return [Fixnum]
+    attr_accessor :sass_line
+
+    # The name of the file that was being parsed when the exception was raised.
+    # This could be `nil` if no filename is available.
+    #
+    # @return [String]
+    attr_reader :sass_filename
+
+    # @param msg [String] The error message
+    # @param lineno [Fixnum] See \{#sass\_line}
+    def initialize(msg, lineno = nil)
+      @message = msg
+      @sass_line = lineno
+    end
+
+    # Add information about the filename and line on which the error was raised,
+    # and re-raises the exception.
+    #
+    # @param filename [String] See \{#sass\_filename}
+    # @param line [Fixnum] See \{#sass\_line}
+    # @raise [Sass::SyntaxError] self
+    def add_metadata(filename, line)
+      self.sass_line ||= line
+      add_backtrace_entry(filename) unless sass_filename
+      raise self
+    end
+
+    # Adds a properly formatted entry to the exception's backtrace.
+    #
+    # @param filename [String] The file in which the error occurred,
+    #   if applicable (defaults to "(sass)")
+    def add_backtrace_entry(filename) # :nodoc:
+      @sass_filename ||= filename
+      self.backtrace ||= []
+      self.backtrace.unshift "#{@sass_filename || '(sass)'}:#{@sass_line}"
+    end
+
+    # @return [String] The error message
+    def to_s
+      @message
+    end
+  end
+
+  # The class for Sass errors that are raised due to invalid unit conversions
+  # in SassScript.
+  class UnitConversionError < SyntaxError; end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/files.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/files.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/files.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/files.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,139 @@
+require 'digest/sha1'
+require 'pathname'
+
+module Sass
+  # This module contains various bits of functionality
+  # related to finding and caching Sass files.
+  module Files
+    extend self
+
+    # Returns the {Sass::Tree} for the given file,
+    # reading it from the Sass cache if possible.
+    #
+    # @param filename [String] The path to the Sass file
+    # @param options [Hash<Symbol, Object>] The options hash.
+    #   Only the {file:SASS_REFERENCE.md#cache-option `:cache_location`} option is used
+    # @raise [Sass::SyntaxError] if there's an error in the document
+    def tree_for(filename, options)
+      options = Sass::Engine::DEFAULT_OPTIONS.merge(options)
+      text = File.read(filename)
+
+      if options[:cache]
+        compiled_filename = sassc_filename(filename, options)
+        sha = Digest::SHA1.hexdigest(text)
+
+        if root = try_to_read_sassc(filename, compiled_filename, sha)
+          root.options = options.merge(:filename => filename)
+          return root
+        end
+      end
+
+      engine = Sass::Engine.new(text, options.merge(:filename => filename))
+
+      begin
+        root = engine.to_tree
+      rescue Sass::SyntaxError => err
+        err.add_backtrace_entry(filename)
+        raise err
+      end
+
+      try_to_write_sassc(root, compiled_filename, sha, options) if options[:cache]
+
+      root
+    end
+
+    # Find the full filename of a Sass or CSS file to import.
+    # This follows Sass's import rules:
+    # if the filename given ends in `".sass"` or `".css"`,
+    # it will try to find that type of file;
+    # otherwise, it will try to find the corresponding Sass file
+    # and fall back on CSS if it's not available.
+    #
+    # Any Sass filename returned will correspond to
+    # an actual Sass file on the filesystem.
+    # CSS filenames, however, may not;
+    # they're expected to be put through directly to the stylesheet
+    # as CSS `@import` statements.
+    #
+    # @param filename [String] The filename to search for
+    # @param load_paths [Array<String>] The set of filesystem paths
+    #   to search for Sass files.
+    # @return [String] The filename of the imported file.
+    #   This is an absolute path if the file is a `".sass"` file.
+    # @raise [Sass::SyntaxError] if `filename` ends in ``".sass"``
+    #   and no corresponding Sass file could be found.
+    def find_file_to_import(filename, load_paths)
+      was_sass = false
+      original_filename = filename
+
+      if filename[-5..-1] == ".sass"
+        filename = filename[0...-5]
+        was_sass = true
+      elsif filename[-4..-1] == ".css"
+        return filename
+      end
+
+      new_filename = find_full_path("#{filename}.sass", load_paths)
+
+      return new_filename if new_filename
+      return filename + '.css' unless was_sass
+      raise SyntaxError.new("File to import not found or unreadable: #{original_filename}.", @line)
+    end
+
+    private
+
+    def sassc_filename(filename, options)
+      File.join(options[:cache_location],
+        Digest::SHA1.hexdigest(File.dirname(File.expand_path(filename))),
+        File.basename(filename) + 'c')
+    end
+
+    def try_to_read_sassc(filename, compiled_filename, sha)
+      return unless File.readable?(compiled_filename)
+
+      File.open(compiled_filename, "rb") do |f|
+        return unless f.readline("\n").strip == Sass::VERSION
+        return unless f.readline("\n").strip == sha
+        return Marshal.load(f.read)
+      end
+    rescue TypeError, ArgumentError => e
+      warn "Warning. Error encountered while reading cache #{compiled_filename}: #{e}"
+    end
+
+    def try_to_write_sassc(root, compiled_filename, sha, options)
+      return unless File.writable?(File.dirname(options[:cache_location]))
+      return if File.exists?(options[:cache_location]) && !File.writable?(options[:cache_location])
+      return if File.exists?(File.dirname(compiled_filename)) && !File.writable?(File.dirname(compiled_filename))
+      return if File.exists?(compiled_filename) && !File.writable?(compiled_filename)
+      FileUtils.mkdir_p(File.dirname(compiled_filename))
+      File.open(compiled_filename, "wb") do |f|
+        f.write(Sass::VERSION)
+        f.write("\n")
+        f.write(sha)
+        f.write("\n")
+        f.write(Marshal.dump(root))
+      end
+    end
+
+    def find_full_path(filename, load_paths)
+      partial_name = File.join(File.dirname(filename), "_#{File.basename(filename)}")
+
+      if Pathname.new(filename).absolute?
+        [partial_name, filename].each do |name|
+          return name if File.readable?(name)
+        end
+        return nil
+      end
+
+      load_paths.each do |path|
+        [partial_name, filename].each do |name|
+          full_path = File.join(path, name)
+          if File.readable?(full_path)
+            return full_path
+          end
+        end
+      end
+      nil
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,212 @@
+require 'sass/engine'
+
+module Sass
+  # This module handles the compilation of Sass files.
+  # It provides global options and checks whether CSS files
+  # need to be updated.
+  #
+  # This module is used as the primary interface with Sass
+  # when it's used as a plugin for various frameworks.
+  # Currently Rails and Merb are supported out of the box.
+  module Plugin
+    extend self
+
+    @options = {
+      :css_location       => './public/stylesheets',
+      :always_update      => false,
+      :always_check       => true,
+      :full_exception     => true
+    }
+    @checked_for_updates = false
+
+    # Whether or not Sass has **ever** checked if the stylesheets need to be updated
+    # (in this Ruby instance).
+    #
+    # @return [Boolean]
+    attr_reader :checked_for_updates
+
+    # An options hash.
+    # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
+    #
+    # @return [Hash<Symbol, Object>]
+    attr_reader :options
+
+    # Sets the options hash.
+    # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
+    #
+    # @param value [Hash<Symbol, Object>] The options hash
+    def options=(value)
+      @options.merge!(value)
+    end
+
+    # Non-destructively modifies \{#options} so that default values are properly set.
+    #
+    # @param additional_options [Hash<Symbol, Object>] An options hash with which to merge \{#options}
+    # @return [Hash<Symbol, Object>] The modified options hash
+    def engine_options(additional_options = {})
+      opts = options.dup.merge(additional_options)
+      opts[:load_paths] = load_paths(opts)
+      opts
+    end
+
+    # Updates out-of-date stylesheets.
+    #
+    # Checks each Sass file in {file:SASS_REFERENCE.md#template_location-option `:template_location`}
+    # to see if it's been modified more recently than the corresponding CSS file
+    # in {file:SASS_REFERENCE.md#css_location-option} `:css_location`}.
+    # If it has, it updates the CSS file.
+    def update_stylesheets
+      return if options[:never_update]
+
+      @checked_for_updates = true
+      template_locations.zip(css_locations).each do |template_location, css_location|
+
+        Dir.glob(File.join(template_location, "**", "*.sass")).each do |file|
+          # Get the relative path to the file with no extension
+          name = file.sub(template_location + "/", "")[0...-5]
+
+          if !forbid_update?(name) && (options[:always_update] || stylesheet_needs_update?(name, template_location, css_location))
+            update_stylesheet(name, template_location, css_location)
+          end
+        end
+      end
+    end
+
+    private
+
+    def update_stylesheet(name, template_location, css_location)
+      css = css_filename(name, css_location)
+      File.delete(css) if File.exists?(css)
+
+      filename = template_filename(name, template_location)
+      result = begin
+                 Sass::Files.tree_for(filename, engine_options(:css_filename => css, :filename => filename)).render
+               rescue Exception => e
+                 exception_string(e)
+               end
+
+      # Create any directories that might be necessary
+      mkpath(css_location, name)
+
+      # Finally, write the file
+      File.open(css, 'w') do |file|
+        file.print(result)
+      end
+    end
+    
+    # Create any successive directories required to be able to write a file to: File.join(base,name)
+    def mkpath(base, name)
+      dirs = [base]
+      name.split(File::SEPARATOR)[0...-1].each { |dir| dirs << File.join(dirs[-1],dir) }
+      dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) }
+    end
+
+    def load_paths(opts = options)
+      (opts[:load_paths] || []) + template_locations
+    end
+    
+    def template_locations
+      location = (options[:template_location] || File.join(options[:css_location],'sass'))
+      if location.is_a?(String)
+        [location]
+      else
+        location.to_a.map { |l| l.first }
+      end
+    end
+    
+    def css_locations
+      if options[:template_location] && !options[:template_location].is_a?(String)
+        options[:template_location].to_a.map { |l| l.last }
+      else
+        [options[:css_location]]
+      end
+    end
+
+    def exception_string(e)
+      if options[:full_exception]
+        e_string = "#{e.class}: #{e.message}"
+
+        if e.is_a? Sass::SyntaxError
+          e_string << "\non line #{e.sass_line}"
+
+          if e.sass_filename
+            e_string << " of #{e.sass_filename}"
+
+            if File.exists?(e.sass_filename)
+              e_string << "\n\n"
+
+              min = [e.sass_line - 5, 0].max
+              begin
+                File.read(e.sass_filename).rstrip.split("\n")[
+                  min .. e.sass_line + 5
+                ].each_with_index do |line, i|
+                  e_string << "#{min + i + 1}: #{line}\n"
+                end
+              rescue
+                e_string << "Couldn't read sass file: #{e.sass_filename}"
+              end
+            end
+          end
+        end
+        <<END
+/*
+#{e_string}
+
+Backtrace:\n#{e.backtrace.join("\n")}
+*/
+body:before {
+  white-space: pre;
+  font-family: monospace;
+  content: "#{e_string.gsub('"', '\"').gsub("\n", '\\A ')}"; }
+END
+        # Fix an emacs syntax-highlighting hiccup: '
+      else
+        "/* Internal stylesheet error */"
+      end
+    end
+
+    def template_filename(name, path)
+      "#{path}/#{name}.sass"
+    end
+
+    def css_filename(name, path)
+      "#{path}/#{name}.css"
+    end
+
+    def forbid_update?(name)
+      name.sub(/^.*\//, '')[0] == ?_
+    end
+
+    def stylesheet_needs_update?(name, template_path, css_path)
+      css_file = css_filename(name, css_path)
+      template_file = template_filename(name, template_path)
+      exact_stylesheet_needs_update?(css_file, template_file)
+    end
+
+    def exact_stylesheet_needs_update?(css_file, template_file)
+      return true unless File.exists?(css_file)
+
+      css_mtime = File.mtime(css_file)
+      File.mtime(template_file) > css_mtime ||
+        dependencies(template_file).any?(&dependency_updated?(css_mtime))
+    end
+
+    def dependency_updated?(css_mtime)
+      lambda do |dep|
+        File.mtime(dep) > css_mtime ||
+          dependencies(dep).any?(&dependency_updated?(css_mtime))
+      end
+    end
+
+    def dependencies(filename)
+      File.readlines(filename).grep(/^@import /).map do |line|
+        line[8..-1].split(',').map do |inc|
+          Sass::Files.find_file_to_import(inc.strip, [File.dirname(filename)] + load_paths)
+        end
+      end.flatten.grep(/\.sass$/)
+    end
+  end
+end
+
+require 'sass/plugin/rails' if defined?(ActionController)
+require 'sass/plugin/merb'  if defined?(Merb::Plugins)

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin/merb.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin/merb.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin/merb.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin/merb.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,57 @@
+unless defined?(Sass::MERB_LOADED)
+  Sass::MERB_LOADED = true
+
+  version = Merb::VERSION.split('.').map { |n| n.to_i }
+  if version[0] <= 0 && version[1] < 5
+    root = MERB_ROOT
+    env  = MERB_ENV
+  else
+    root = Merb.root.to_s
+    env  = Merb.environment
+  end
+
+  Sass::Plugin.options.merge!(:template_location => root + '/public/stylesheets/sass',
+                              :css_location      => root + '/public/stylesheets',
+                              :cache_location    => root + '/tmp/sass-cache',
+                              :always_check      => env != "production",
+                              :full_exception    => env != "production")
+  config = Merb::Plugins.config[:sass] || Merb::Plugins.config["sass"] || {}
+
+  if defined? config.symbolize_keys!
+    config.symbolize_keys!
+  end
+
+  Sass::Plugin.options.merge!(config)
+
+  if version[0] > 0 || version[1] >= 9
+
+    class Merb::Rack::Application
+      def call_with_sass(env)
+        if !Sass::Plugin.checked_for_updates ||
+            Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
+          Sass::Plugin.update_stylesheets
+        end
+
+        call_without_sass(env)
+      end
+      alias_method :call_without_sass, :call
+      alias_method :call, :call_with_sass
+    end
+
+  else
+
+    class MerbHandler
+      def process_with_sass(request, response)
+        if !Sass::Plugin.checked_for_updates ||
+            Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
+          Sass::Plugin.update_stylesheets
+        end
+
+        process_without_sass(request, response)
+      end
+      alias_method :process_without_sass, :process
+      alias_method :process, :process_with_sass
+    end
+
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin/rails.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin/rails.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin/rails.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/plugin/rails.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,23 @@
+unless defined?(Sass::RAILS_LOADED)
+  Sass::RAILS_LOADED = true
+
+  Sass::Plugin.options.merge!(:template_location => RAILS_ROOT + '/public/stylesheets/sass',
+                              :css_location      => RAILS_ROOT + '/public/stylesheets',
+                              :cache_location    => RAILS_ROOT + '/tmp/sass-cache',
+                              :always_check      => RAILS_ENV != "production",
+                              :full_exception    => RAILS_ENV != "production")
+
+  module ActionController
+    class Base
+      alias_method :sass_old_process, :process
+      def process(*args)
+        if !Sass::Plugin.checked_for_updates ||
+            Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
+          Sass::Plugin.update_stylesheets
+        end
+
+        sass_old_process(*args)
+      end
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/repl.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/repl.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/repl.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/repl.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,58 @@
+require 'readline'
+
+module Sass
+  # Runs a SassScript read-eval-print loop.
+  # It presents a prompt on the terminal,
+  # reads in SassScript expressions,
+  # evaluates them,
+  # and prints the result.
+  class Repl
+    # @param options [Hash<Symbol, Object>] An options hash.
+    def initialize(options = {})
+      @options = options
+    end
+
+    # Starts the read-eval-print loop.
+    def run
+      environment = Environment.new
+      environment.set_var('important', Script::String.new('!important'))
+      @line = 0
+      loop do
+        @line += 1
+        unless text = Readline.readline('>> ')
+          puts
+          return
+        end
+
+        Readline::HISTORY << text
+        parse_input(environment, text)
+      end
+    end
+
+    private
+
+    def parse_input(environment, text)
+      case text
+      when Script::MATCH
+        name = $1
+        guarded = $2 == '||='
+        val = Script::Parser.parse($3, @line, text.size - $3.size)
+
+        unless guarded && environment.var(name)
+          environment.set_var(name, val.perform(environment))
+        end
+
+        p environment.var(name)
+      else
+        p Script::Parser.parse(text, @line, 0).perform(environment)
+      end
+    rescue Sass::SyntaxError => e
+      puts "SyntaxError: #{e.message}"
+      if @options[:trace]
+        e.backtrace.each do |e|
+          puts "\tfrom #{e}"
+        end
+      end
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,59 @@
+require 'strscan'
+require 'sass/script/node'
+require 'sass/script/variable'
+require 'sass/script/funcall'
+require 'sass/script/operation'
+require 'sass/script/literal'
+require 'sass/script/parser'
+
+module Sass
+  # SassScript is code that's embedded in Sass documents
+  # to allow for property values to be computed from variables.
+  #
+  # This module contains code that handles the parsing and evaluation of SassScript.
+  module Script
+    # The character that begins a variable.
+    VARIABLE_CHAR = ?!
+
+    # The regular expression used to parse variables.
+    MATCH = /^!([a-zA-Z_]\w*)\s*((?:\|\|)?=)\s*(.+)/
+
+    # The regular expression used to validate variables without matching.
+    VALIDATE = /^![a-zA-Z_]\w*$/
+
+    # Parses and evaluates a string of SassScript.
+    #
+    # @param value [String] The SassScript
+    # @param line [Fixnum] The number of the line on which the SassScript appeared.
+    #   Used for error reporting
+    # @param offset [Fixnum] The number of characters in on `line` that the SassScript started.
+    #   Used for error reporting
+    # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
+    # @return [String] The string result of evaluating the SassScript
+    def self.resolve(value, line, offset, environment)
+      parse(value, line, offset).perform(environment).to_s
+    end
+
+    # Parses a string of SassScript
+    #
+    # @param value [String] The SassScript
+    # @param line [Fixnum] The number of the line on which the SassScript appeared.
+    #   Used for error reporting
+    # @param offset [Fixnum] The number of characters in on `line` that the SassScript started.
+    #   Used for error reporting
+    # @param filename [String] The path to the file in which the SassScript appeared.
+    #   Used for error reporting
+    # @return [Script::Node] The root node of the parse tree
+    def self.parse(value, line, offset, filename = nil)
+      Parser.parse(value, line, offset, filename)
+    rescue Sass::SyntaxError => e
+      if e.message == "SassScript error"
+        e.instance_eval do
+          @message += ": #{value.dump}."
+        end
+      end
+      e.sass_line = line
+      raise e
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/bool.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/bool.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/bool.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/bool.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,17 @@
+require 'sass/script/literal'
+
+module Sass::Script
+  # A SassScript object representing a boolean (true or false) value.
+  class Bool < Literal
+    # The Ruby value of the boolean.
+    #
+    # @return [Boolean]
+    attr_reader :value
+    alias_method :to_bool, :value
+
+    # @return [String] "true" or "false"
+    def to_s
+      @value.to_s
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/color.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/color.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/color.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/color.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,183 @@
+require 'sass/script/literal'
+
+module Sass::Script
+  # A SassScript object representing a CSS color.
+  class Color < Literal
+    class << self; include Haml::Util; end
+
+    # A hash from color names to [red, green, blue] value arrays.
+    HTML4_COLORS = map_vals({
+        'black'   => 0x000000,
+        'silver'  => 0xc0c0c0,
+        'gray'    => 0x808080,
+        'white'   => 0xffffff,
+        'maroon'  => 0x800000,
+        'red'     => 0xff0000,
+        'purple'  => 0x800080,
+        'fuchsia' => 0xff00ff,
+        'green'   => 0x008000,
+        'lime'    => 0x00ff00,
+        'olive'   => 0x808000,
+        'yellow'  => 0xffff00,
+        'navy'    => 0x000080,
+        'blue'    => 0x0000ff,
+        'teal'    => 0x008080,
+        'aqua'    => 0x00ffff
+      }) {|color| (0..2).map {|n| color >> (n << 3) & 0xff}.reverse}
+    # A hash from [red, green, blue] value arrays to color names.
+    HTML4_COLORS_REVERSE = map_hash(HTML4_COLORS) {|k, v| [v, k]}
+
+    # @param rgb [Array<Fixnum>] A three-element array of the red, green, and blue values (respectively)
+    #   of the color
+    # @raise [Sass::SyntaxError] if any color value isn't between 0 and 255
+    def initialize(rgb)
+      rgb = rgb.map {|c| c.to_i}
+      raise Sass::SyntaxError.new("Color values must be between 0 and 255") if rgb.any? {|c| c < 0 || c > 255}
+      super(rgb)
+    end
+
+    # The SassScript `+` operation.
+    # Its functionality depends on the type of its argument:
+    #
+    # {Number}
+    # : Adds the number to each of the RGB color channels.
+    #
+    # {Color}
+    # : Adds each of the RGB color channels together.
+    #
+    # {Literal}
+    # : See {Literal#plus}.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Color] The resulting color
+    # @raise [Sass::SyntaxError] if `other` is a number with units
+    def plus(other)
+      if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
+        piecewise(other, :+)
+      else
+        super
+      end
+    end
+
+    # The SassScript `-` operation.
+    # Its functionality depends on the type of its argument:
+    #
+    # {Number}
+    # : Subtracts the number from each of the RGB color channels.
+    #
+    # {Color}
+    # : Subtracts each of the other color's RGB color channels from this color's.
+    #
+    # {Literal}
+    # : See {Literal#minus}.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Color] The resulting color
+    # @raise [Sass::SyntaxError] if `other` is a number with units
+    def minus(other)
+      if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
+        piecewise(other, :-)
+      else
+        super
+      end
+    end
+
+    # The SassScript `*` operation.
+    # Its functionality depends on the type of its argument:
+    #
+    # {Number}
+    # : Multiplies the number by each of the RGB color channels.
+    #
+    # {Color}
+    # : Multiplies each of the RGB color channels together.
+    #
+    # {Literal}
+    # : See {Literal#times}.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Color] The resulting color
+    # @raise [Sass::SyntaxError] if `other` is a number with units
+    def times(other)
+      if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
+        piecewise(other, :*)
+      else
+        raise NoMethodError.new(nil, :times)
+      end
+    end
+
+    # The SassScript `/` operation.
+    # Its functionality depends on the type of its argument:
+    #
+    # {Number}
+    # : Divides each of the RGB color channels by the number.
+    #
+    # {Color}
+    # : Divides each of this color's RGB color channels by the other color's.
+    #
+    # {Literal}
+    # : See {Literal#div}.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Color] The resulting color
+    # @raise [Sass::SyntaxError] if `other` is a number with units
+    def div(other)
+      if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
+        piecewise(other, :/)
+      else
+        super
+      end
+    end
+
+    # The SassScript `%` operation.
+    # Its functionality depends on the type of its argument:
+    #
+    # {Number}
+    # : Takes each of the RGB color channels module the number.
+    #
+    # {Color}
+    # : Takes each of this color's RGB color channels modulo the other color's.
+    #
+    # {Literal}
+    # : See {Literal#mod}.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Color] The resulting color
+    # @raise [Sass::SyntaxError] if `other` is a number with units
+    def mod(other)
+      if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
+        piecewise(other, :%)
+      else
+        raise NoMethodError.new(nil, :mod)
+      end
+    end
+
+    # Returns a string representation of the color.
+    # This is usually the color's hex value,
+    # but if the color has a name that's used instead.
+    #
+    # @return [String] The string representation
+    def to_s
+      return HTML4_COLORS_REVERSE[@value] if HTML4_COLORS_REVERSE[@value]
+      red, green, blue = @value.map { |num| num.to_s(16).rjust(2, '0') }
+      "##{red}#{green}#{blue}"
+    end
+    alias_method :inspect, :to_s
+
+    private
+
+    def piecewise(other, operation)
+      other_num = other.is_a? Number
+      other_val = other.value
+      if other_num && !other.unitless?
+        raise Sass::SyntaxError.new("Cannot add a number with units (#{other}) to a color (#{self}).") 
+      end
+
+      rgb = []
+      for i in (0...3)
+        res = @value[i].send(operation, other_num ? other_val : other_val[i])
+        rgb[i] = [ [res, 255].min, 0 ].max
+      end
+      Color.new(rgb)
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/funcall.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/funcall.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/funcall.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/funcall.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,50 @@
+require File.join(File.dirname(__FILE__), 'functions')
+module Sass
+  module Script
+    # A SassScript parse node representing a function call.
+    #
+    # A function call either calls one of the functions in {Script::Functions},
+    # or if no function with the given name exists
+    # it returns a string representation of the function call.
+    class Funcall < Node
+      # The name of the function.
+      #
+      # @return [String]
+      attr_reader :name
+
+      # The arguments to the function.
+      #
+      # @return [Array<Script::Node>]
+      attr_reader :args
+
+      # @param name [String] See \{#name}
+      # @param name [Array<Script::Node>] See \{#args}
+      def initialize(name, args)
+        @name = name
+        @args = args
+      end
+
+      # @return [String] A string representation of the function call
+      def inspect
+        "#{name}(#{args.map {|a| a.inspect}.join(', ')})"
+      end
+
+      # Evaluates the function call.
+      #
+      # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
+      # @return [Literal] The SassScript object that is the value of the function call
+      # @raise [Sass::SyntaxError] if the function call raises an ArgumentError
+      def perform(environment)
+        args = self.args.map {|a| a.perform(environment)}
+        unless Haml::Util.has?(:public_instance_method, Functions, name) && name !~ /^__/
+          return Script::String.new("#{name}(#{args.map {|a| a.perform(environment)}.join(', ')})")
+        end
+
+        return Functions::EvaluationContext.new(environment.options).send(name, *args)
+      rescue ArgumentError => e
+        raise e unless e.backtrace.first =~ /:in `(block in )?(#{name}|perform)'$/
+        raise Sass::SyntaxError.new("#{e.message} for `#{name}'")
+      end
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/functions.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/functions.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/functions.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/functions.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,199 @@
+module Sass::Script
+  # Methods in this module are accessible from the SassScript context.
+  # For example, you can write
+  #
+  #     !color = hsl(120, 100%, 50%)
+  #
+  # and it will call {Sass::Script::Functions#hsl}.
+  #
+  # The following functions are provided:
+  #
+  # \{#hsl}
+  # : Converts an `hsl(hue, saturation, lightness)` triplet into a color.
+  #
+  # \{#percentage}
+  # : Converts a unitless number to a percentage.
+  #
+  # \{#round}
+  # : Rounds a number to the nearest whole number.
+  #
+  # \{#ceil}
+  # : Rounds a number up to the nearest whole number.
+  #
+  # \{#floor}
+  # : Rounds a number down to the nearest whole number.
+  #
+  # \{#abs}
+  # : Returns the absolute value of a number.
+  #
+  # You can add your own functions to this module,
+  # but there are a few things to keep in mind.
+  # First of all, the arguments passed are {Sass::Script::Literal} objects.
+  # Literal objects are also expected to be returned.
+  #
+  # Second, making Ruby functions accessible from Sass introduces the temptation
+  # to do things like database access within stylesheets.
+  # This temptation must be resisted.
+  # Keep in mind that Sass stylesheets are only compiled once
+  # at a somewhat indeterminate time
+  # and then left as static CSS files.
+  # Any dynamic CSS should be left in `<style>` tags in the HTML.
+  #
+  # Within one of the functions in this module,
+  # methods of {EvaluationContext} can be used.
+  module Functions
+    # The context in which methods in {Script::Functions} are evaluated.
+    # That means that all instance methods of {EvaluationContext}
+    # are available to use in functions.
+    class EvaluationContext
+      include Sass::Script::Functions
+
+      # The options hash for the {Sass::Engine} that is processing the function call
+      #
+      # @return [Hash<Symbol, Object>]
+      attr_reader :options
+
+      # @param options [Hash<Symbol, Object>] See \{#options}
+      def initialize(options)
+        @options = options
+      end
+    end
+
+    instance_methods.each { |m| undef_method m unless m.to_s =~ /^__/ }
+
+
+    # Creates a {Color} object from red, green, and blue values.
+    # @param red
+    #   A number between 0 and 255 inclusive
+    # @param green
+    #   A number between 0 and 255 inclusive
+    # @param blue
+    #   A number between 0 and 255 inclusive
+    def rgb(red, green, blue)
+      [red.value, green.value, blue.value].each do |v|
+        next unless v < 0 || v > 255
+        raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive")
+      end
+      Color.new([red.value, green.value, blue.value])
+    end
+
+    # Creates a {Color} object from hue, saturation, and lightness
+    # as per the CSS3 spec (http://www.w3.org/TR/css3-color/#hsl-color).
+    #
+    # @param hue [Number] The hue of the color.
+    #   Should be between 0 and 360 degrees, inclusive
+    # @param saturation [Number] The saturation of the color.
+    #   Must be between `0%` and `100%`, inclusive
+    # @param lightness [Number] The lightness of the color.
+    #   Must be between `0%` and `100%`, inclusive
+    # @return [Color] The resulting color
+    # @raise [ArgumentError] if `saturation` or `lightness` are out of bounds
+    def hsl(hue, saturation, lightness)
+      original_s = saturation
+      original_l = lightness
+      # This algorithm is from http://www.w3.org/TR/css3-color#hsl-color
+      h, s, l = [hue, saturation, lightness].map { |a| a.value }
+      raise ArgumentError.new("Saturation #{s} must be between 0% and 100%") if s < 0 || s > 100
+      raise ArgumentError.new("Lightness #{l} must be between 0% and 100%") if l < 0 || l > 100
+
+      h = (h % 360) / 360.0
+      s /= 100.0
+      l /= 100.0
+
+      m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s
+      m1 = l * 2 - m2
+      Color.new([hue_to_rgb(m1, m2, h + 1.0/3),
+                 hue_to_rgb(m1, m2, h),
+                 hue_to_rgb(m1, m2, h - 1.0/3)].map { |c| (c * 0xff).round })
+    end
+
+    # Converts a decimal number to a percentage.
+    # For example:
+    #
+    #     percentage(100px / 50px) => 200%
+    #
+    # @param value [Number] The decimal number to convert to a percentage
+    # @return [Number] The percentage
+    # @raise [ArgumentError] If `value` isn't a unitless number
+    def percentage(value)
+      unless value.is_a?(Sass::Script::Number) && value.unitless?
+        raise ArgumentError.new("#{value} is not a unitless number")
+      end
+      Sass::Script::Number.new(value.value * 100, ['%'])
+    end
+
+    # Rounds a number to the nearest whole number.
+    # For example:
+    #
+    #     round(10.4px) => 10px
+    #     round(10.6px) => 11px
+    #
+    # @param value [Number] The number
+    # @return [Number] The rounded number
+    # @raise [Sass::SyntaxError] if `value` isn't a number
+    def round(value)
+      numeric_transformation(value) {|n| n.round}
+    end
+
+    # Rounds a number up to the nearest whole number.
+    # For example:
+    #
+    #     ciel(10.4px) => 11px
+    #     ciel(10.6px) => 11px
+    #
+    # @param value [Number] The number
+    # @return [Number] The rounded number
+    # @raise [Sass::SyntaxError] if `value` isn't a number
+    def ceil(value)
+      numeric_transformation(value) {|n| n.ceil}
+    end
+
+    # Rounds down to the nearest whole number.
+    # For example:
+    #
+    #     floor(10.4px) => 10px
+    #     floor(10.6px) => 10px
+    #
+    # @param value [Number] The number
+    # @return [Number] The rounded number
+    # @raise [Sass::SyntaxError] if `value` isn't a number
+    def floor(value)
+      numeric_transformation(value) {|n| n.floor}
+    end
+
+    # Finds the absolute value of a number.
+    # For example:
+    #
+    #     abs(10px) => 10px
+    #     abs(-10px) => 10px
+    #
+    # @param value [Number] The number
+    # @return [Number] The absolute value
+    # @raise [Sass::SyntaxError] if `value` isn't a number
+    def abs(value)
+      numeric_transformation(value) {|n| n.abs}
+    end
+
+    private
+
+    # This method implements the pattern of transforming a numeric value into
+    # another numeric value with the same units.
+    # It yields a number to a block to perform the operation and return a number
+    def numeric_transformation(value)
+      unless value.is_a?(Sass::Script::Number)
+        calling_function = caller.first.scan(/`([^']+)'/).first.first
+        raise Sass::SyntaxError.new("#{value} is not a number for `#{calling_function}'")
+      end
+      Sass::Script::Number.new(yield(value.value), value.numerator_units, value.denominator_units)
+    end
+
+    def hue_to_rgb(m1, m2, h)
+      h += 1 if h < 0
+      h -= 1 if h > 1
+      return m1 + (m2 - m1) * h * 6 if h * 6 < 1
+      return m2 if h * 2 < 1
+      return m1 + (m2 - m1) * (2.0/3 - h) * 6 if h * 3 < 2
+      return m1
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/lexer.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/lexer.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/lexer.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/lexer.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,191 @@
+require 'strscan'
+
+module Sass
+  module Script
+    # The lexical analyzer for SassScript.
+    # It takes a raw string and converts it to individual tokens
+    # that are easier to parse.
+    class Lexer
+      # A struct containing information about an individual token.
+      #
+      # `type`: [{Symbol}]
+      # : The type of token.
+      #
+      # `value`: [{Object}]
+      # : The Ruby object corresponding to the value of the token.
+      #
+      # `line`: [{Fixnum}]
+      # : The line of the source file on which the token appears.
+      #
+      # `offset`: [{Fixnum}]
+      # : The number of bytes into the line the SassScript token appeared.
+      Token = Struct.new(:type, :value, :line, :offset)
+
+      # A hash from operator strings to the corresponding token types.
+      OPERATORS = {
+        '+' => :plus,
+        '-' => :minus,
+        '*' => :times,
+        '/' => :div,
+        '%' => :mod,
+        '=' => :single_eq,
+        '(' => :lparen,
+        ')' => :rparen,
+        ',' => :comma,
+        'and' => :and,
+        'or' => :or,
+        'not' => :not,
+        '==' => :eq,
+        '!=' => :neq,
+        '>=' => :gte,
+        '<=' => :lte,
+        '>' => :gt,
+        '<' => :lt,
+        '#{' => :begin_interpolation,
+        '}' => :end_interpolation,
+      }
+
+      # A list of operator strings ordered with longer names first
+      # so that `>` and `<` don't clobber `>=` and `<=`.
+      OP_NAMES = OPERATORS.keys.sort_by {|o| -o.size}
+
+      # A hash of regular expressions that are used for tokenizing.
+      REGULAR_EXPRESSIONS = {
+        :whitespace => /\s*/,
+        :variable => /!(\w+)/,
+        :ident => /(\\.|\#\{|[^\s\\+\-*\/%(),=!])+/,
+        :string_end => /((?:\\.|\#[^{]|[^"\\#])*)(?:"|(?=#\{))/,
+        :number => /(-)?(?:(\d*\.\d+)|(\d+))([a-zA-Z%]+)?/,
+        :color => /\##{"([0-9a-fA-F]{1,2})" * 3}|(#{Color::HTML4_COLORS.keys.join("|")})/,
+        :bool => /(true|false)\b/,
+        :op => %r{(#{Regexp.union(*OP_NAMES.map{|s| Regexp.new(Regexp.escape(s) + (s =~ /\w$/ ? '(?:\b|$)' : ''))})})}
+      }
+
+      # @param str [String, StringScanner] The source text to lex
+      # @param line [Fixnum] The line on which the SassScript appears.
+      #   Used for error reporting
+      # @param offset [Fixnum] The number of characters in on which the SassScript appears.
+      #   Used for error reporting
+      def initialize(str, line, offset, filename)
+        @scanner = str.is_a?(StringScanner) ? str : StringScanner.new(str)
+        @line = line
+        @offset = offset
+        @filename = filename
+        @prev = nil
+      end
+
+      # Moves the lexer forward one token.
+      #
+      # @return [Token] The token that was moved past
+      def next
+        @tok ||= read_token
+        @tok, tok = nil, @tok
+        @prev = tok
+        return tok
+      end
+
+      # Returns the next token without moving the lexer forward.
+      #
+      # @return [Token] The next token
+      def peek
+        @tok ||= read_token
+      end
+
+      # @return [Boolean] Whether or not there's more source text to lex.
+      def done?
+        whitespace unless after_interpolation?
+        @scanner.eos? && @tok.nil?
+      end
+
+      private
+
+      def read_token
+        return if done?
+
+        value = token
+        unless value
+          raise SyntaxError.new("Syntax error in '#{@scanner.string}' at character #{current_position}.")
+        end
+        Token.new(value.first, value.last, @line, last_match_position)
+      end
+
+      def whitespace
+        @scanner.scan(REGULAR_EXPRESSIONS[:whitespace])
+      end
+
+      def token
+        return string('') if after_interpolation?
+        variable || string || number || color || bool || op || ident
+      end
+
+      def variable
+        return unless @scanner.scan(REGULAR_EXPRESSIONS[:variable])
+        [:const, @scanner[1]]
+      end
+
+      def ident
+        return unless s = @scanner.scan(REGULAR_EXPRESSIONS[:ident])
+        [:ident, s.gsub(/\\(.)/, '\1')]
+      end
+
+      def string(start_char = '"')
+        return unless @scanner.scan(/#{start_char}#{REGULAR_EXPRESSIONS[:string_end]}/)
+        [:string, Script::String.new(@scanner[1].gsub(/\\([^0-9a-f])/, '\1').gsub(/\\([0-9a-f]{1,4})/, "\\\\\\1"))]
+      end
+
+      def begin_interpolation
+        @scanner.scan
+      end
+
+      def number
+        return unless @scanner.scan(REGULAR_EXPRESSIONS[:number])
+        value = @scanner[2] ? @scanner[2].to_f : @scanner[3].to_i
+        value = -value if @scanner[1]
+        [:number, Script::Number.new(value, Array(@scanner[4]))]
+      end
+
+      def color
+        return unless @scanner.scan(REGULAR_EXPRESSIONS[:color])
+        value = if @scanner[4]
+                  color = Color::HTML4_COLORS[@scanner[4].downcase]
+                else
+                  (1..3).map {|i| @scanner[i]}.map {|num| num.ljust(2, num).to_i(16)}
+                end
+        [:color, Script::Color.new(value)]
+      end
+
+      def bool
+        return unless s = @scanner.scan(REGULAR_EXPRESSIONS[:bool])
+        [:bool, Script::Bool.new(s == 'true')]
+      end
+
+      def op
+        prev_chr = @scanner.string[@scanner.pos - 1].chr
+        return unless op = @scanner.scan(REGULAR_EXPRESSIONS[:op])
+        if @prev && op == '-' && prev_chr !~ /\s/ &&
+            [:bool, :ident, :const].include?(@prev.type)
+          warn(<<END)
+DEPRECATION WARNING:
+On line #{@line}, character #{last_match_position}#{" of '#{@filename}'" if @filename}
+- will be allowed as part of variable names in version 2.4.
+Please add whitespace to separate it from the previous token.
+END
+        end
+
+        [OPERATORS[op]]
+      end
+
+      def current_position
+        @offset + @scanner.pos + 1
+      end
+
+      def last_match_position
+        current_position - @scanner.matched_size
+      end
+
+      def after_interpolation?
+        @prev && @prev.type == :end_interpolation
+      end
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/literal.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/literal.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/literal.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/literal.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,177 @@
+module Sass::Script
+  # The abstract superclass for SassScript objects.
+  #
+  # Many of these methods, especially the ones that correspond to SassScript operations,
+  # are designed to be overridden by subclasses which may change the semantics somewhat.
+  # The operations listed here are just the defaults.
+  class Literal < Node
+    require 'sass/script/string'
+    require 'sass/script/number'
+    require 'sass/script/color'
+    require 'sass/script/bool'
+
+    # Returns the Ruby value of the literal.
+    # The type of this value varies based on the subclass.
+    #
+    # @return [Object]
+    attr_reader :value
+
+    # Creates a new literal.
+    #
+    # @param value [Object] The object for \{#value}
+    def initialize(value = nil)
+      @value = value
+    end
+
+    # Evaluates the literal.
+    #
+    # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
+    # @return [Literal] This literal
+    def perform(environment)
+      self
+    end
+
+    # The SassScript `and` operation.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Literal] The result of a logical and:
+    #   `other` if this literal isn't a false {Bool},
+    #   and this literal otherwise
+    def and(other)
+      to_bool ? other : self
+    end
+
+    # The SassScript `or` operation.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Literal] The result of the logical or:
+    #   this literal if it isn't a false {Bool},
+    #   and `other` otherwise
+    def or(other)
+      to_bool ? self : other
+    end
+
+    # The SassScript `==` operation.
+    # **Note that this returns a {Sass::Script::Bool} object,
+    # not a Ruby boolean**.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Bool] True if this literal is the same as the other,
+    #   false otherwise
+    def eq(other)
+      Sass::Script::Bool.new(self.class == other.class && self.value == other.value)
+    end
+
+    # The SassScript `!=` operation.
+    # **Note that this returns a {Sass::Script::Bool} object,
+    # not a Ruby boolean**.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Bool] False if this literal is the same as the other,
+    #   true otherwise
+    def neq(other)
+      Sass::Script::Bool.new(!eq(other).to_bool)
+    end
+
+    # The SassScript `==` operation.
+    # **Note that this returns a {Sass::Script::Bool} object,
+    # not a Ruby boolean**.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Bool] True if this literal is the same as the other,
+    #   false otherwise
+    def unary_not
+      Sass::Script::Bool.new(!to_bool)
+    end
+
+    # The SassScript default operation (e.g. `!a !b`, `"foo" "bar"`).
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Script::String] A string containing both literals
+    #   separated by a space
+    def concat(other)
+      Sass::Script::String.new("#{self.to_s} #{other.to_s}")
+    end
+
+    # The SassScript `,` operation (e.g. `!a, !b`, `"foo", "bar"`).
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Script::String] A string containing both literals
+    #   separated by `", "`
+    def comma(other)
+      Sass::Script::String.new("#{self.to_s}, #{other.to_s}")
+    end
+
+    # The SassScript `+` operation.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Script::String] A string containing both literals
+    #   without any separation
+    def plus(other)
+      Sass::Script::String.new(self.to_s + other.to_s)
+    end
+
+    # The SassScript `-` operation.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Script::String] A string containing both literals
+    #   separated by `"-"`
+    def minus(other)
+      Sass::Script::String.new("#{self.to_s}-#{other.to_s}")
+    end
+
+    # The SassScript `/` operation.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Script::String] A string containing both literals
+    #   separated by `"/"`
+    def div(other)
+      Sass::Script::String.new("#{self.to_s}/#{other.to_s}")
+    end
+
+    # The SassScript unary `-` operation (e.g. `-!a`).
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Script::String] A string containing the literal
+    #   preceded by `"-"`
+    def unary_minus
+      Sass::Script::String.new("-#{self.to_s}")
+    end
+
+    # The SassScript unary `/` operation (e.g. `/!a`).
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Script::String] A string containing the literal
+    #   preceded by `"/"`
+    def unary_div
+      Sass::Script::String.new("/#{self.to_s}")
+    end
+
+    # @return [String] A readable representation of the literal
+    def inspect
+      value.inspect
+    end
+
+    # @return [Boolean] `true` (the Ruby boolean value)
+    def to_bool
+      true
+    end
+
+    # Compares this object with another.
+    #
+    # @param other [Object] The object to compare with
+    # @return [Boolean] Whether or not this literal is equivalent to `other`
+    def ==(other)
+      eq(other).to_bool
+    end
+
+    # @return [Fixnum] The integer value of this literal
+    # @raise [Sass::SyntaxError] if this literal isn't an integer
+    def to_i
+      raise Sass::SyntaxError.new("#{self.inspect} is not an integer.")
+    end
+
+    # @raise [Sass::SyntaxError] if this literal isn't an integer
+    def assert_int!; to_i; end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/node.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/node.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/node.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/node.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,14 @@
+module Sass::Script
+  # The abstract superclass for SassScript parse tree nodes.
+  #
+  # Use \{#perform} to evaluate a parse tree.
+  class Node
+    # Evaluates the node.
+    #
+    # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
+    # @return [Literal] The SassScript object that is the value of the SassScript
+    def perform(environment)
+      raise NotImplementedError.new("All subclasses of Sass::Script::Node must override #perform.")
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/number.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/number.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/number.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/number.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,381 @@
+require 'sass/script/literal'
+
+module Sass::Script
+  # A SassScript object representing a number.
+  # SassScript numbers can have decimal values,
+  # and can also have units.
+  # For example, `12`, `1px`, and `10.45em`
+  # are all valid values.
+  #
+  # Numbers can also have more complex units, such as `1px*em/in`.
+  # These cannot be inputted directly in Sass code at the moment.
+  class Number < Literal
+    # The Ruby value of the number.
+    #
+    # @return [Numeric]
+    attr_reader :value
+
+    # A list of units in the numerator of the number.
+    # For example, `1px*em/in*cm` would return `["px", "em"]`
+    # @return [Array<String>] 
+    attr_reader :numerator_units
+
+    # A list of units in the denominator of the number.
+    # For example, `1px*em/in*cm` would return `["in", "cm"]`
+    # @return [Array<String>]
+    attr_reader :denominator_units
+
+    # The precision with which numbers will be printed to CSS files.
+    # For example, if this is `1000.0`,
+    # `3.1415926` will be printed as `3.142`.
+    PRECISION = 1000.0
+
+    # @param value [Numeric] The value of the number
+    # @param numerator_units [Array<String>] See \{#numerator\_units}
+    # @param denominator_units [Array<String>] See \{#denominator\_units}
+    def initialize(value, numerator_units = [], denominator_units = [])
+      super(value)
+      @numerator_units = numerator_units
+      @denominator_units = denominator_units
+      normalize!
+    end
+
+    # The SassScript `+` operation.
+    # Its functionality depends on the type of its argument:
+    #
+    # {Number}
+    # : Adds the two numbers together, converting units if possible.
+    #
+    # {Color}
+    # : Adds this number to each of the RGB color channels.
+    #
+    # {Literal}
+    # : See {Literal#plus}.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Literal] The result of the operation
+    # @raise [Sass::UnitConversionError] if `other` is a number with incompatible units
+    def plus(other)
+      if other.is_a? Number
+        operate(other, :+)
+      elsif other.is_a?(Color)
+        other.plus(self)
+      else
+        super
+      end
+    end
+
+    # The SassScript binary `-` operation (e.g. `!a - !b`).
+    # Its functionality depends on the type of its argument:
+    #
+    # {Number}
+    # : Subtracts this number from the other, converting units if possible.
+    #
+    # {Literal}
+    # : See {Literal#minus}.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Literal] The result of the operation
+    # @raise [Sass::UnitConversionError] if `other` is a number with incompatible units
+    def minus(other)
+      if other.is_a? Number
+        operate(other, :-)
+      else
+        super
+      end
+    end
+
+    # The SassScript unary `-` operation (e.g. `-!a`).
+    #
+    # @return [Number] The negative value of this number
+    def unary_minus
+      Number.new(-value, numerator_units, denominator_units)
+    end
+
+    # The SassScript `*` operation.
+    # Its functionality depends on the type of its argument:
+    #
+    # {Number}
+    # : Multiplies the two numbers together, converting units appropriately.
+    #
+    # {Color}
+    # : Multiplies each of the RGB color channels by this number.
+    #
+    # @param other [Number, Color] The right-hand side of the operator
+    # @return [Number, Color] The result of the operation
+    # @raise [NoMethodError] if `other` is an invalid type
+    def times(other)
+      if other.is_a? Number
+        self.operate(other, :*)
+      elsif other.is_a? Color
+        other.times(self)
+      else
+        raise NoMethodError.new(nil, :times)
+      end
+    end
+
+    # The SassScript `/` operation.
+    # Its functionality depends on the type of its argument:
+    #
+    # {Number}
+    # : Divides this number by the other, converting units appropriately.
+    #
+    # {Literal}
+    # : See {Literal#div}.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Literal] The result of the operation
+    def div(other)
+      if other.is_a? Number
+        operate(other, :/)
+      else
+        super
+      end
+    end
+
+    # The SassScript `%` operation.
+    #
+    # @param other [Number] The right-hand side of the operator
+    # @return [Number] This number modulo the other
+    # @raise [NoMethodError] if `other` is an invalid type
+    # @raise [Sass::UnitConversionError] if `other` has any units
+    def mod(other)
+      if other.is_a?(Number)
+        unless other.unitless?
+          raise Sass::UnitConversionError.new("Cannot modulo by a number with units: #{other.inspect}.")
+        end
+        operate(other, :%)
+      else
+        raise NoMethodError.new(nil, :mod)
+      end
+    end
+
+    # The SassScript `==` operation.
+    #
+    # @param other [Literal] The right-hand side of the operator
+    # @return [Boolean] Whether this number is equal to the other object
+    def eq(other)
+      return Sass::Script::Bool.new(false) unless other.is_a?(Sass::Script::Number)
+      this = self
+      begin
+        if unitless?
+          this = this.coerce(other.numerator_units, other.denominator_units)
+        else
+          other = other.coerce(numerator_units, denominator_units)
+        end
+      rescue Sass::UnitConversionError
+        return Sass::Script::Bool.new(false)
+      end
+
+      Sass::Script::Bool.new(this.value == other.value)
+    end
+
+    # The SassScript `>` operation.
+    #
+    # @param other [Number] The right-hand side of the operator
+    # @return [Boolean] Whether this number is greater than the other
+    # @raise [NoMethodError] if `other` is an invalid type
+    def gt(other)
+      raise NoMethodError.new(nil, :gt) unless other.is_a?(Number)
+      operate(other, :>)
+    end
+
+    # The SassScript `>=` operation.
+    #
+    # @param other [Number] The right-hand side of the operator
+    # @return [Boolean] Whether this number is greater than or equal to the other
+    # @raise [NoMethodError] if `other` is an invalid type
+    def gte(other)
+      raise NoMethodError.new(nil, :gte) unless other.is_a?(Number)
+      operate(other, :>=)
+    end
+
+    # The SassScript `<` operation.
+    #
+    # @param other [Number] The right-hand side of the operator
+    # @return [Boolean] Whether this number is less than the other
+    # @raise [NoMethodError] if `other` is an invalid type
+    def lt(other)
+      raise NoMethodError.new(nil, :lt) unless other.is_a?(Number)
+      operate(other, :<)
+    end
+
+    # The SassScript `<=` operation.
+    #
+    # @param other [Number] The right-hand side of the operator
+    # @return [Boolean] Whether this number is less than or equal to the other
+    # @raise [NoMethodError] if `other` is an invalid type
+    def lte(other)
+      raise NoMethodError.new(nil, :lte) unless other.is_a?(Number)
+      operate(other, :<=)
+    end
+
+    # @return [String] The CSS representation of this number
+    # @raise [Sass::SyntaxError] if this number has units that can't be used in CSS
+    #   (e.g. `px*in`)
+    def to_s
+      raise Sass::SyntaxError.new("#{inspect} isn't a valid CSS value.") unless legal_units?
+      inspect
+    end
+
+    # Returns a readable representation of this number.
+    #
+    # This representation is valid CSS (and valid SassScript)
+    # as long as there is only one unit.
+    #
+    # @return [String] The representation
+    def inspect
+      value =
+        if self.value.is_a?(Float) && (self.value.infinite? || self.value.nan?)
+          self.value
+        elsif int?
+          self.value.to_i
+        else
+          (self.value * PRECISION).round / PRECISION
+        end
+      "#{value}#{unit_str}"
+    end
+
+    # @return [Fixnum] The integer value of the number
+    # @raise [Sass::SyntaxError] if the number isn't an integer
+    def to_i
+      super unless int?
+      return value
+    end
+
+    # @return [Boolean] Whether or not this number is an integer.
+    def int?
+      value % 1 == 0.0
+    end
+
+    # @return [Boolean] Whether or not this number has no units.
+    def unitless?
+      numerator_units.empty? && denominator_units.empty?
+    end
+
+    # @return [Boolean] Whether or not this number has units that can be represented in CSS
+    #   (that is, zero or one \{#numerator\_units}).
+    def legal_units?
+      (numerator_units.empty? || numerator_units.size == 1) && denominator_units.empty?
+    end
+
+    # Returns this number converted to other units.
+    # The conversion takes into account the relationship between e.g. mm and cm,
+    # as well as between e.g. in and cm.
+    #
+    # If this number has no units, it will simply return itself
+    # with the given units.
+    #
+    # An incompatible coercion, e.g. between px and cm, will raise an error.
+    #
+    # @param num_units [Array<String>] The numerator units to coerce this number into.
+    #   See {\#numerator\_units}
+    # @param den_units [Array<String>] The denominator units to coerce this number into.
+    #   See {\#denominator\_units}
+    # @return [Number] The number with the new units
+    # @raise [Sass::UnitConversionError] if the given units are incompatible with the number's
+    #   current units
+    def coerce(num_units, den_units)
+      Number.new(if unitless?
+                   self.value
+                 else
+                   self.value * coercion_factor(self.numerator_units, num_units) /
+                     coercion_factor(self.denominator_units, den_units)
+                 end, num_units, den_units)
+    end
+
+    protected
+
+    def operate(other, operation)
+      this = self
+      if [:+, :-, :<=, :<, :>, :>=].include?(operation)
+        if unitless?
+          this = this.coerce(other.numerator_units, other.denominator_units)
+        else
+          other = other.coerce(numerator_units, denominator_units)
+        end
+      end
+      # avoid integer division
+      value = (:/ == operation) ? this.value.to_f : this.value
+      result = value.send(operation, other.value)
+
+      if result.is_a?(Numeric)
+        Number.new(result, *compute_units(this, other, operation))
+      else # Boolean op
+        Bool.new(result)
+      end
+    end
+
+    def coercion_factor(from_units, to_units)
+      # get a list of unmatched units
+      from_units, to_units = sans_common_units(from_units, to_units)
+
+      if from_units.size != to_units.size || !convertable?(from_units | to_units)
+        raise Sass::UnitConversionError.new("Incompatible units: '#{from_units.join('*')}' and '#{to_units.join('*')}'.")
+      end
+
+      from_units.zip(to_units).inject(1) {|m,p| m * conversion_factor(p[0], p[1]) }
+    end
+
+    def compute_units(this, other, operation)
+      case operation
+      when :*
+        [this.numerator_units + other.numerator_units, this.denominator_units + other.denominator_units]
+      when :/
+        [this.numerator_units + other.denominator_units, this.denominator_units + other.numerator_units]
+      else  
+        [this.numerator_units, this.denominator_units]
+      end
+    end
+
+    def unit_str
+      rv = numerator_units.join("*")
+      if denominator_units.any?
+        rv << "/"
+        rv << denominator_units.join("*")
+      end
+      rv
+    end
+
+    def normalize!
+      return if unitless?
+      @numerator_units, @denominator_units = sans_common_units(numerator_units, denominator_units)
+
+      @denominator_units.each_with_index do |d, i|
+        if convertable?(d) && (u = @numerator_units.detect(&method(:convertable?)))
+          @value /= conversion_factor(d, u)
+          @denominator_units.delete_at(i)
+          @numerator_units.delete_at(@numerator_units.index(u))
+        end
+      end
+    end
+
+    # A hash of unit names to their index in the conversion table
+    CONVERTABLE_UNITS = {"in" => 0,        "cm" => 1,    "pc" => 2,    "mm" => 3,   "pt" => 4}
+    CONVERSION_TABLE = [[ 1,                2.54,         6,            25.4,        72        ], # in
+                        [ nil,              1,            2.36220473,   10,          28.3464567], # cm
+                        [ nil,              nil,          1,            4.23333333,  12        ], # pc
+                        [ nil,              nil,          nil,          1,           2.83464567], # mm
+                        [ nil,              nil,          nil,          nil,         1         ]] # pt
+
+    def conversion_factor(from_unit, to_unit)
+      res = CONVERSION_TABLE[CONVERTABLE_UNITS[from_unit]][CONVERTABLE_UNITS[to_unit]]
+      return 1.0 / conversion_factor(to_unit, from_unit) if res.nil?
+      res
+    end
+
+    def convertable?(units)
+      Array(units).all?(&CONVERTABLE_UNITS.method(:include?))
+    end
+
+    def sans_common_units(units1, units2)
+      units2 = units2.dup
+      # Can't just use -, because we want px*px to coerce properly to px*mm
+      return units1.map do |u|
+        next u unless j = units2.index(u)
+        units2.delete_at(j)
+        nil
+      end.compact, units2
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/operation.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/operation.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/operation.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/operation.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,45 @@
+require 'set'
+require 'sass/script/string'
+require 'sass/script/number'
+require 'sass/script/color'
+require 'sass/script/functions'
+require 'sass/script/unary_operation'
+
+module Sass::Script
+  # A SassScript parse node representing a binary operation,
+  # such as `!a + !b` or `"foo" + 1`.
+  class Operation < Node
+    # @param operand1 [Script::Node] The parse-tree node
+    #   for the right-hand side of the operator
+    # @param operand2 [Script::Node] The parse-tree node
+    #   for the left-hand side of the operator
+    # @param operator [Symbol] The operator to perform.
+    #   This should be one of the binary operator names in {Lexer::OPERATORS}
+    def initialize(operand1, operand2, operator)
+      @operand1 = operand1
+      @operand2 = operand2
+      @operator = operator
+    end
+
+    # @return [String] A human-readable s-expression representation of the operation
+    def inspect
+      "(#{@operator.inspect} #{@operand1.inspect} #{@operand2.inspect})"
+    end
+
+    # Evaluates the operation.
+    #
+    # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
+    # @return [Literal] The SassScript object that is the value of the operation
+    # @raise [Sass::SyntaxError] if the operation is undefined for the operands
+    def perform(environment)
+      literal1 = @operand1.perform(environment)
+      literal2 = @operand2.perform(environment)
+      begin
+        literal1.send(@operator, literal2)
+      rescue NoMethodError => e
+        raise e unless e.name.to_s == @operator.to_s
+        raise Sass::SyntaxError.new("Undefined operation: \"#{literal1} #{@operator} #{literal2}\".")
+      end
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/parser.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/parser.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/parser.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/parser.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,222 @@
+require 'sass/script/lexer'
+
+module Sass
+  module Script
+    # The parser for SassScript.
+    # It parses a string of code into a tree of {Script::Node}s.
+    class Parser
+      # @param str [String, StringScanner] The source text to parse
+      # @param line [Fixnum] The line on which the SassScript appears.
+      #   Used for error reporting
+      # @param offset [Fixnum] The number of characters in on which the SassScript appears.
+      #   Used for error reporting
+      # @param filename [String] The name of the file in which the SassScript appears.
+      #   Used for error reporting
+      def initialize(str, line, offset, filename = nil)
+        @filename = filename
+        @lexer = Lexer.new(str, line, offset, filename)
+      end
+
+      # Parses a SassScript expression within an interpolated segment (`#{}`).
+      # This means that it stops when it comes across an unmatched `}`,
+      # which signals the end of an interpolated segment,
+      # it returns rather than throwing an error.
+      #
+      # @return [Script::Node] The root node of the parse tree
+      # @raise [Sass::SyntaxError] if the expression isn't valid SassScript
+      def parse_interpolated
+        expr = assert_expr :expr
+        assert_tok :end_interpolation
+        expr
+      end
+
+      # Parses a SassScript expression.
+      #
+      # @return [Script::Node] The root node of the parse tree
+      # @raise [Sass::SyntaxError] if the expression isn't valid SassScript
+      def parse
+        expr = assert_expr :expr
+        assert_done
+        expr
+      end
+
+      # Parses the argument list for a mixin include.
+      #
+      # @return [Array<Script::Node>] The root nodes of the arguments.
+      # @raise [Sass::SyntaxError] if the argument list isn't valid SassScript
+      def parse_mixin_include_arglist
+        args = []
+
+        if try_tok(:lparen)
+          args = arglist || args
+          assert_tok(:rparen)
+        end
+        assert_done
+
+        args
+      end
+
+      # Parses the argument list for a mixin definition.
+      #
+      # @return [Array<Script::Node>] The root nodes of the arguments.
+      # @raise [Sass::SyntaxError] if the argument list isn't valid SassScript
+      def parse_mixin_definition_arglist
+        args = []
+
+        if try_tok(:lparen)
+          args = defn_arglist(false) || args
+          assert_tok(:rparen)
+        end
+        assert_done
+
+        args
+      end
+
+      # Parses a SassScript expression.
+      #
+      # @overload parse(str, line, offset, filename = nil)
+      # @return [Script::Node] The root node of the parse tree
+      # @see Parser#initialize
+      # @see Parser#parse
+      def self.parse(*args)
+        new(*args).parse
+      end
+
+      class << self
+        private
+
+        # Defines a simple left-associative production.
+        # name is the name of the production,
+        # sub is the name of the production beneath it,
+        # and ops is a list of operators for this precedence level
+        def production(name, sub, *ops)
+          class_eval <<RUBY
+            def #{name}
+              return unless e = #{sub}
+              while tok = try_tok(#{ops.map {|o| o.inspect}.join(', ')})
+                e = Operation.new(e, assert_expr(#{sub.inspect}), tok.type)
+              end
+              e
+            end
+RUBY
+        end
+
+        def unary(op, sub)
+          class_eval <<RUBY
+            def unary_#{op}
+              return #{sub} unless try_tok(:#{op})
+              UnaryOperation.new(assert_expr(:unary_#{op}), :#{op})
+            end
+RUBY
+        end
+      end
+
+      private
+
+      production :expr, :concat, :comma
+
+      def concat
+        return unless e = or_expr
+        while sub = or_expr
+          e = Operation.new(e, sub, :concat)
+        end
+        e
+      end
+
+      production :or_expr, :and_expr, :or
+      production :and_expr, :eq_or_neq, :and
+      production :eq_or_neq, :relational, :eq, :neq
+      production :relational, :plus_or_minus, :gt, :gte, :lt, :lte
+      production :plus_or_minus, :times_div_or_mod, :plus, :minus
+      production :times_div_or_mod, :unary_minus, :times, :div, :mod
+
+      unary :minus, :unary_div
+      unary :div, :unary_not # For strings, so /foo/bar works
+      unary :not, :funcall
+
+      def funcall
+        return paren unless name = try_tok(:ident)
+        # An identifier without arguments is just a string
+        unless try_tok(:lparen)
+          warn(<<END)
+DEPRECATION WARNING:
+On line #{name.line}, character #{name.offset}#{" of '#{@filename}'" if @filename}
+Implicit strings have been deprecated and will be removed in version 2.4.
+'#{name.value}' was not quoted. Please add double quotes (e.g. "#{name.value}").
+END
+          Script::String.new(name.value)
+        else
+          args = arglist || []
+          assert_tok(:rparen)
+          Script::Funcall.new(name.value, args)
+        end
+      end
+
+      def defn_arglist(must_have_default)
+        return unless c = try_tok(:const)
+        var = Script::Variable.new(c.value)
+        if try_tok(:single_eq)
+          val = assert_expr(:concat)
+        elsif must_have_default
+          raise SyntaxError.new("Required argument #{var.inspect} must come before any optional arguments.", @line)
+        end
+
+        return [[var, val]] unless try_tok(:comma)
+        [[var, val], *defn_arglist(val)]
+      end
+
+      def arglist
+        return unless e = concat
+        return [e] unless try_tok(:comma)
+        [e, *arglist]
+      end
+
+      def paren
+        return variable unless try_tok(:lparen)
+        e = assert_expr(:expr)
+        assert_tok(:rparen)
+        return e
+      end
+
+      def variable
+        return string unless c = try_tok(:const)
+        Variable.new(c.value)
+      end
+
+      def string
+        return literal unless first = try_tok(:string)
+        return first.value unless try_tok(:begin_interpolation)
+        mid = parse_interpolated
+        last = assert_expr(:string)
+        Operation.new(first.value, Operation.new(mid, last, :plus), :plus)
+      end
+
+      def literal
+        (t = try_tok(:number, :color, :bool)) && (return t.value)
+      end
+
+      # It would be possible to have unified #assert and #try methods,
+      # but detecting the method/token difference turns out to be quite expensive.
+
+      def assert_expr(name)
+        (e = send(name)) && (return e)
+        raise Sass::SyntaxError.new("Expected expression, was #{@lexer.done? ? 'end of text' : "#{@lexer.peek.type} token"}.")
+      end
+
+      def assert_tok(*names)
+        (t = try_tok(*names)) && (return t)
+        raise Sass::SyntaxError.new("Expected #{names.join(' or ')} token, was #{@lexer.done? ? 'end of text' : "#{@lexer.peek.type} token"}.")
+      end
+
+      def try_tok(*names)
+        peeked =  @lexer.peek
+        peeked && names.include?(peeked.type) && @lexer.next
+      end
+
+      def assert_done
+        return if @lexer.done?
+        raise Sass::SyntaxError.new("Unexpected #{@lexer.peek.type} token.")
+      end
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/string.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/string.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/string.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/string.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,12 @@
+require 'sass/script/literal'
+
+module Sass::Script
+  # A SassScript object representing a string of text.
+  class String < Literal
+    # The Ruby value of the string.
+    #
+    # @return [String]
+    attr_reader :value
+    alias_method :to_s, :value
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/unary_operation.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/unary_operation.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/unary_operation.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/unary_operation.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,34 @@
+module Sass::Script
+  # A SassScript parse node representing a unary operation,
+  # such as `-!b` or `not true`.
+  #
+  # Currently only `-`, `/`, and `not` are unary operators.
+  class UnaryOperation < Node
+    # @param operand [Script::Node] The parse-tree node
+    #   for the object of the operator
+    # @param operator [Symbol] The operator to perform
+    def initialize(operand, operator)
+      @operand = operand
+      @operator = operator
+    end
+
+    # @return [String] A human-readable s-expression representation of the operation
+    def inspect
+      "(#{@operator.inspect} #{@operand.inspect})"
+    end
+
+    # Evaluates the operation.
+    #
+    # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
+    # @return [Literal] The SassScript object that is the value of the operation
+    # @raise [Sass::SyntaxError] if the operation is undefined for the operand
+    def perform(environment)
+      operator = "unary_#{@operator}"
+      literal = @operand.perform(environment)
+      literal.send(operator)
+    rescue NoMethodError => e
+      raise e unless e.name.to_s == operator.to_s
+      raise Sass::SyntaxError.new("Undefined unary operation: \"#{@operator} #{literal}\".")
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/variable.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/variable.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/variable.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/script/variable.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,31 @@
+module Sass
+  module Script
+    # A SassScript parse node representing a variable.
+    class Variable < Node
+      # The name of the variable.
+      #
+      # @return [String]
+      attr_reader :name
+
+      # @param name [String] See \{#name}
+      def initialize(name)
+        @name = name
+      end
+
+      # @return [String] A string representation of the variable
+      def inspect
+        "!#{name}"
+      end
+
+      # Evaluates the variable.
+      #
+      # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
+      # @return [Literal] The SassScript object that is the value of the variable
+      # @raise [Sass::SyntaxError] if the variable is undefined
+      def perform(environment)
+        (val = environment.var(name)) && (return val)
+        raise SyntaxError.new("Undefined variable: \"!#{name}\".")
+      end
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/tree/comment_node.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/tree/comment_node.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/tree/comment_node.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/tree/comment_node.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,84 @@
+require 'sass/tree/node'
+
+module Sass::Tree
+  # A static node representing a Sass comment (silent or loud).
+  #
+  # @see Sass::Tree
+  class CommentNode < Node
+    # The lines of text nested beneath the comment.
+    #
+    # @return [Array<Sass::Engine::Line>]
+    attr_accessor :lines
+
+    # The text on the same line as the comment starter.
+    #
+    # @return [String]
+    attr_accessor :value
+
+    # Whether or not the comment is silent (that is, doesn't output to CSS).
+    #
+    # @return [Boolean]
+    attr_accessor :silent
+
+    # @param value [String] See \{#value}
+    # @param silent [Boolean] See \{#silent}
+    def initialize(value, silent)
+      @lines = []
+      @value = value[2..-1].strip
+      @silent = silent
+      super()
+    end
+
+    # Compares the contents of two comments.
+    #
+    # @param other [Object] The object to compare with
+    # @return [Boolean] Whether or not this node and the other object
+    #   are the same
+    def ==(other)
+      self.class == other.class && value == other.value && silent == other.silent && lines == other.lines
+    end
+
+    # Computes the CSS for the comment.
+    #
+    # Returns `nil` if this is a silent comment
+    # or the current style doesn't render comments.
+    #
+    # @overload to_s(tabs = 0)
+    # @param tabs [Fixnum] The level of indentation for the CSS
+    # @return [String, nil] The resulting CSS
+    # @see #invisible?
+    def to_s(tabs = 0, _ = nil)
+      return if invisible?
+      spaces = '  ' * (tabs - 1)
+
+      content = (value.split("\n") + lines.map {|l| l.text})
+      return spaces + "/* */" if content.empty?
+      content.map! {|l| (l.empty? ? "" : " ") + l}
+      content.first.gsub!(/^ /, '')
+      content.last.gsub!(%r{ ?\*/ *$}, '')
+
+      spaces + "/* " + content.join(style == :compact ? '' : "\n#{spaces} *") + " */"
+    end
+
+    # Returns `true` if this is a silent comment
+    # or the current style doesn't render comments.
+    #
+    # @return [Boolean]
+    def invisible?
+      style == :compressed || @silent
+    end
+
+    protected
+
+    # Removes this node from the tree if it's a silent comment.
+    #
+    # @param environment [Sass::Environment] The lexical environment containing
+    #   variable and mixin values
+    # @return [Tree::Node, Array<Tree::Node>] The resulting static nodes
+    # @see Sass::Tree
+    def _perform(environment)
+      return [] if @silent
+      self
+    end
+  end
+end

Added: incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/tree/debug_node.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/tree/debug_node.rb?rev=961978&view=auto
==============================================================================
--- incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/tree/debug_node.rb (added)
+++ incubator/deltacloud/trunk/framework/vendor/plugins/haml/lib/sass/tree/debug_node.rb Thu Jul  8 23:14:13 2010
@@ -0,0 +1,30 @@
+module Sass
+  module Tree
+    # A dynamic node representing a Sass `@debug` statement.
+    #
+    # @see Sass::Tree
+    class DebugNode < Node
+      # @param expr [Script::Node] The expression to print
+      def initialize(expr)
+        @expr = expr
+        super()
+      end
+
+      protected
+
+      # Prints the expression to STDERR.
+      #
+      # @param environment [Sass::Environment] The lexical environment containing
+      #   variable and mixin values
+      def _perform(environment)
+        res = @expr.perform(environment)
+        if filename
+          STDERR.puts "#{filename}:#{line} DEBUG: #{res}"
+        else
+          STDERR.puts "Line #{line} DEBUG: #{res}"
+        end
+        []
+      end
+    end
+  end
+end



Mime
View raw message