class Haml::Exec::SassConvert
The ‘sass-convert` executable.
def initialize(args)
-
args
(Array
) -- The command-line arguments
def initialize(args) super require 'sass' @options[:for_tree] = {} @options[:for_engine] = {:cache => false, :read_cache => true} end
def process_directory
def process_directory unless input = @options[:input] = @args.shift raise "Error: directory required when using --recursive." end output = @options[:output] = @args.shift raise "Error: --from required when using --recursive." unless @options[:from] raise "Error: --to required when using --recursive." unless @options[:to] raise "Error: '#{@options[:input]}' is not a directory" unless File.directory?(@options[:input]) if @options[:output] && File.exists?(@options[:output]) && !File.directory?(@options[:output]) raise "Error: '#{@options[:output]}' is not a directory" end @options[:output] ||= @options[:input] from = @options[:from] from = :sass if from == :sass2 if @options[:to] == @options[:from] && !@options[:in_place] fmt = @options[:from] raise "Error: converting from #{fmt} to #{fmt} without --in-place" end ext = @options[:from] ext = :sass if ext == :sass2 Dir.glob("#{@options[:input]}/**/*.#{ext}") do |f| output = if @options[:in_place] f elsif @options[:output] output_name = f.gsub(/\.(c|sa|sc|le)ss$/, ".#{@options[:to]}") output_name[0...@options[:input].size] = @options[:output] output_name else f.gsub(/\.(c|sa|sc|le)ss$/, ".#{@options[:to]}") end unless File.directory?(File.dirname(output)) puts_action :directory, :green, File.dirname(output) FileUtils.mkdir_p(File.dirname(output)) end puts_action :convert, :green, f if File.exists?(output) puts_action :overwrite, :yellow, output else puts_action :create, :green, output end input = open_file(f) output = @options[:in_place] ? input : open_file(output, "w") process_file(input, output) end end
def process_file(input, output)
def process_file(input, output) if input.is_a?(File) @options[:from] ||= case input.path when /\.scss$/; :scss when /\.sass$/; :sass when /\.less$/; :less when /\.css$/; :css end elsif @options[:in_place] raise "Error: the --in-place option requires a filename." end if output.is_a?(File) @options[:to] ||= case output.path when /\.scss$/; :scss when /\.sass$/; :sass end end if @options[:from] == :sass2 @options[:from] = :sass @options[:for_engine][:sass2] = true end @options[:from] ||= :css @options[:to] ||= :sass @options[:for_engine][:syntax] = @options[:from] out = ::Haml::Util.silence_haml_warnings do if @options[:from] == :css require 'sass/css' ::Sass::CSS.new(input.read, @options[:for_tree]).render(@options[:to]) elsif @options[:from] == :less require 'sass/less' try_less_note input = input.read if input.is_a?(IO) && !input.is_a?(File) # Less is dumb Less::Engine.new(input).to_tree.to_sass_tree.send("to_#{@options[:to]}", @options[:for_tree]) else if input.is_a?(File) ::Sass::Files.tree_for(input.path, @options[:for_engine]) else ::Sass::Engine.new(input.read, @options[:for_engine]).to_tree end.send("to_#{@options[:to]}", @options[:for_tree]) end end output = File.open(input.path, 'w') if @options[:in_place] output.write(out) rescue ::Sass::SyntaxError => e raise e if @options[:trace] file = " of #{e.sass_filename}" if e.sass_filename raise "Error on line #{e.sass_line}#{file}: #{e.message}\n Use --trace for backtrace" rescue LoadError => err handle_load_error(err) end
def process_result
Processes the options set by the command-line arguments,
def process_result require 'sass' if @options[:recursive] process_directory return end super input = @options[:input] raise "Error: '#{input.path}' is a directory (did you mean to use --recursive?)" if File.directory?(input) output = @options[:output] output = input if @options[:in_place] process_file(input, output) end
def set_opts(opts)
-
opts
(OptionParser
) --
def set_opts(opts) opts.banner = <<END sass-convert [options] [INPUT] [OUTPUT] ption: erts between CSS, Sass, and SCSS files. converts from SCSS to Sass, onverts from CSS to SCSS (adding appropriate nesting). s: opts.on('-F', '--from FORMAT', 'The format to convert from. Can be css, scss, sass, less, or sass2.', 'sass2 is the same as sass, but updates more old syntax to new.', 'By default, this is inferred from the input filename.', 'If there is none, defaults to css.') do |name| @options[:from] = name.downcase.to_sym unless [:css, :scss, :sass, :less, :sass2].include?(@options[:from]) raise "Unknown format for sass-convert --from: #{name}" end try_less_note if @options[:from] == :less end opts.on('-T', '--to FORMAT', 'The format to convert to. Can be scss or sass.', 'By default, this is inferred from the output filename.', 'If there is none, defaults to sass.') do |name| @options[:to] = name.downcase.to_sym unless [:scss, :sass].include?(@options[:to]) raise "Unknown format for sass-convert --to: #{name}" end end opts.on('-R', '--recursive', 'Convert all the files in a directory. Requires --from and --to.') do @options[:recursive] = true end opts.on('-i', '--in-place', 'Convert a file to its own syntax.', 'This can be used to update some deprecated syntax.') do @options[:in_place] = true end opts.on('--dasherize', 'Convert underscores to dashes') do @options[:for_tree][:dasherize] = true end opts.on('--old', 'Output the old-style ":prop val" property syntax.', 'Only meaningful when generating Sass.') do @options[:for_tree][:old] = true end opts.on('-C', '--no-cache', "Don't cache to sassc files.") do @options[:for_engine][:read_cache] = false end unless ::Haml::Util.ruby1_8? opts.on('-E encoding', 'Specify the default encoding for Sass and CSS files.') do |encoding| Encoding.default_external = encoding end end super end
def try_less_note
def try_less_note return if @@less_note_printed @@less_note_printed = true warn <<NOTE : Sass and Less are different languages, and they work differently. do my best to translate, but some features -- especially mixins -- ld be checked by hand. end