module Sass::Plugin
def checked_for_updates
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)
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
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