1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
require 'sass/plugin'
class Compass::SassCompiler
include Compass::Actions
attr_writer :logger
attr_reader :quiet
attr_reader :error_count
attr_accessor :config
attr_accessor :display_compilation_times
attr_accessor :working_path
attr_accessor :only_sass_files
def initialize(options = {}, config = Compass.configuration)
options = options.dup
self.config = config
self.display_compilation_times = options.delete(:time)
self.working_path = options.delete(:working_path) || Dir.pwd
self.only_sass_files = options.delete(:only_sass_files) || []
@quiet = options[:quiet]
plugin_options = config.to_sass_plugin_options.merge(options)
if only_sass_files.any?
plugin_options[:template_location] = []
plugin_options[:load_paths] = config.sass_load_paths
end
plugin_options[:always_update] = true if options.delete(:force)
plugin_options[:compass] ||= {}
plugin_options[:compass][:logger] = logger
@compiler = Sass::Plugin::Compiler.new(plugin_options)
@start_times = {}
@error_count = 0
public_methods(true).grep(/^when_/).each do |callback|
@compiler.send(callback.to_s.sub(/^when_/, 'on_')) {|*args| send(callback, *args) }
end
end
def compile!
@compiler.update_stylesheets(individual_files)
end
def watch!(options = {}, &block)
skip_initial_update = options.fetch(:skip_initial_update, false)
begin
@compiler.watch(individual_files, options.merge(:skip_initial_update => skip_initial_update), &block)
rescue Sass::SyntaxError => e
skip_initial_update = true
retry
end
end
def individual_files
only_sass_files.map {|sass_file| [sass_file, corresponding_css_file(sass_file)]}
end
def clean!
@compiler.clean(individual_files)
end
def file_list
@compiler.file_list(individual_files)
end
def when_updating_stylesheets(individual_files)
@start_times = {}
@error_count = 0
end
def when_compilation_starting(sass_file, css, sourcemap)
@start_times[sass_file] = Time.now
end
def when_template_created(sass_file)
logger.record :created, relativize(sass_file)
end
def when_template_deleted(sass_file)
logger.record :deleted, relativize(sass_file)
end
def when_template_modified(sass_file)
logger.record :modified, relativize(sass_file)
end
def when_updated_stylesheet(sass_file, css, sourcemap)
if css && display_compilation_times && @start_times[sass_file]
duration = ((Time.now - @start_times[sass_file]) * 1000).round / 1000.0
logger.record :write, "#{relativize(css)} (#{duration}s)"
else
logger.record :write, relativize(css) if css
end
config.run_stylesheet_saved(css) if css
logger.record :write, relativize(sourcemap) if sourcemap
config.run_sourcemap_saved(sourcemap) if sourcemap
end
def when_creating_directory(dirname)
logger.record :directory, relativize(dirname)
end
def when_deleting_css(filename)
logger.record :delete, relativize(filename)
config.run_stylesheet_removed(filename) if filename
end
def when_deleting_sourcemap(filename)
logger.record :delete, relativize(filename)
config.run_sourcemap_removed(filename) if filename
end
def when_compilation_error(error, sass_file, css_file, sourcemap_file)
@error_count += 1
if error.respond_to?(:sass_filename)
if relativize(error.sass_filename) == relativize(sass_file)
logger.record :error, "#{relativize(error.sass_filename)} (Line #{error.sass_line}: #{error.message})"
else
logger.record :error, "#{relativize(sass_file)} (Line #{error.sass_line} of #{relativize(error.sass_filename)}: #{error.message})"
end
else
logger.record :error, "#{relativize(sass_file)} (#{error.backtrace.first}: #{error.message})"
end
config.run_stylesheet_error(sass_file, error.message)
end
def logger
@logger ||= Compass::Logger.new(:quiet => quiet)
end
def corresponding_css_file(sass_file)
"#{config.css_path}/#{stylesheet_name(sass_file)}.css"
end
def stylesheet_name(sass_file)
if sass_file.index(config.sass_path) == 0
sass_file[(config.sass_path.length + 1)..-6].sub(/\.css$/,'')
else
raise Compass::Error, "Individual stylesheets must be in the sass directory."
end
end
def sass_files(options = {})
@compiler.template_location_array.map do |(sass_dir, css_dir)|
glob = options[:include_partials] ?
File.join("**","*.s[ac]ss*") :
File.join("**","[^_]*.s[ac]ss*")
Dir.glob(File.join(sass_dir, glob))
end.flatten
end
end
|