module Sass::Plugin

def checked_for_updates

(in this Ruby instance).
Whether or not Sass has *ever* checked if the stylesheets need updates
def checked_for_updates
  @@checked_for_updates
end

def css_filename(name)

def css_filename(name)
  "#{options[:css_location]}/#{name}.css"
end

def dependencies(filename)

def dependencies(filename)
  File.readlines(filename).grep(/^@import /).map do |line|
    line[8..-1].split(',').map do |inc|
      Sass::Engine.find_file_to_import(inc.strip, load_paths)
    end
  end.flatten.grep(/\.sass$/)
end

def dependency_updated?(css_mtime)

def dependency_updated?(css_mtime)
  lambda do |dep|
    File.mtime(dep) > css_mtime ||
      dependencies(dep).any?(&dependency_updated?(css_mtime))
  end
end

def exception_string(e)

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
          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
        end
      end
    end
    <<END
ring}
ace:\n#{e.backtrace.join("\n")}
efore {
e-space: pre;
-family: monospace;
ent: "#{e_string.gsub('"', '\"').gsub("\n", '\\A ')}"; }
    # Fix an emacs syntax-highlighting hiccup: '
  else
    "/* Internal stylesheet error */"
  end
end

def forbid_update?(name)

def forbid_update?(name)
  name.sub(/^.*\//, '')[0] == ?_
end

def load_paths

def load_paths
  (options[:load_paths] || []) + [options[:template_location]]
end

def options

++
TODO: *DOCUMENT OPTIONS*
--
Gets various options for Sass. See README.rdoc for details.
def options
  @@options
end

def options=(value)

Sets various options for Sass.
def options=(value)
  @@options.merge!(value)
end

def stylesheet_needs_update?(name)

def stylesheet_needs_update?(name)
  if !File.exists?(css_filename(name))
    return true
  else
    css_mtime = File.mtime(css_filename(name))
    File.mtime(template_filename(name)) > css_mtime ||
      dependencies(template_filename(name)).any?(&dependency_updated?(css_mtime))
  end
end

def template_filename(name)

def template_filename(name)
  "#{options[:template_location]}/#{name}.sass"
end

def update_stylesheets

if it does.
from options[:templates]
and updates it using the corresponding template
to see if it needs updating,
Checks each stylesheet in options[:css_location]
def update_stylesheets
  return if options[:never_update]
  @@checked_for_updates = true
  Dir.glob(File.join(options[:template_location], "**", "*.sass")).entries.each do |file|
    # Get the relative path to the file with no extension
    name = file.sub(options[:template_location] + "/", "")[0...-5]
    if !forbid_update?(name) && (options[:always_update] || stylesheet_needs_update?(name))
      css = css_filename(name)
      File.delete(css) if File.exists?(css)
      filename = template_filename(name)
      l_options = @@options.dup
      l_options[:filename] = filename
      l_options[:load_paths] = load_paths
      engine = Engine.new(File.read(filename), l_options)
      result = begin
                 engine.render
               rescue Exception => e
                 exception_string(e)
               end
      # Create any directories that might be necessary
      dirs = [l_options[:css_location]]
      name.split("/")[0...-1].each { |dir| dirs << "#{dirs[-1]}/#{dir}" }
      dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) }
      # Finally, write the file
      File.open(css, 'w') do |file|
        file.print(result)
      end
    end
  end
end