All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gems.sass-3.5.5.lib.sass.exec.sass_scss.rb Maven / Gradle / Ivy

There is a newer version: 3.7.2
Show newest version
module Sass::Exec
  # The `sass` and `scss` executables.
  class SassScss < Base
    attr_reader :default_syntax

    # @param args [Array] The command-line arguments
    def initialize(args, default_syntax)
      super(args)
      @options[:sourcemap] = :auto
      @options[:for_engine] = {
        :load_paths => default_sass_path
      }
      @default_syntax = default_syntax
    end

    protected

    # Tells optparse how to parse the arguments.
    #
    # @param opts [OptionParser]
    def set_opts(opts)
      opts.banner = <>> Sass is watching for changes. Press Ctrl-C to stop."

      Sass::Plugin.on_template_modified do |template|
        puts ">>> Change detected to: #{template}"
        STDOUT.flush
      end
      Sass::Plugin.on_template_created do |template|
        puts ">>> New template detected: #{template}"
        STDOUT.flush
      end
      Sass::Plugin.on_template_deleted do |template|
        puts ">>> Deleted template detected: #{template}"
        STDOUT.flush
      end

      Sass::Plugin.watch(files)
    end
    # @comment
    #   rubocop:enable MethodLength

    def run
      input = @options[:input]
      output = @options[:output]

      if input == $stdin
        # See issue 1745
        (@options[:for_engine][:load_paths] ||= []) << ::Sass::Importers::DeprecatedPath.new(".")
      end

      @options[:for_engine][:syntax] ||= :scss if input.is_a?(File) && input.path =~ /\.scss$/
      @options[:for_engine][:syntax] ||= @default_syntax
      engine =
        if input.is_a?(File) && !@options[:check_syntax]
          Sass::Engine.for_file(input.path, @options[:for_engine])
        else
          # We don't need to do any special handling of @options[:check_syntax] here,
          # because the Sass syntax checking happens alongside evaluation
          # and evaluation doesn't actually evaluate any code anyway.
          Sass::Engine.new(input.read, @options[:for_engine])
        end

      input.close if input.is_a?(File)

      if @options[:sourcemap] != :none && @options[:sourcemap_filename]
        relative_sourcemap_path = Sass::Util.relative_path_from(
          @options[:sourcemap_filename], Sass::Util.pathname(@options[:output_filename]).dirname)
        rendered, mapping = engine.render_with_sourcemap(relative_sourcemap_path.to_s)
        write_output(rendered, output)
        write_output(
          mapping.to_json(
            :type => @options[:sourcemap],
            :css_path => @options[:output_filename],
            :sourcemap_path => @options[:sourcemap_filename]) + "\n",
          @options[:sourcemap_filename])
      else
        write_output(engine.render, output)
      end
    rescue Sass::SyntaxError => e
      write_output(Sass::SyntaxError.exception_to_css(e), output) if output.is_a?(String)
      raise e
    ensure
      output.close if output.is_a? File
    end

    def colon_path?(path)
      !split_colon_path(path)[1].nil?
    end

    def split_colon_path(path)
      one, two = path.split(':', 2)
      if one && two && Sass::Util.windows? &&
          one =~ /\A[A-Za-z]\Z/ && two =~ %r{\A[/\\]}
        # If we're on Windows and we were passed a drive letter path,
        # don't split on that colon.
        one2, two = two.split(':', 2)
        one = one + ':' + one2
      end
      return one, two
    end

    # Whether path is likely to be meant as the destination
    # in a source:dest pair.
    def probably_dest_dir?(path)
      return false unless path
      return false if colon_path?(path)
      Sass::Util.glob(File.join(path, "*.s[ca]ss")).empty?
    end

    def default_sass_path
      return unless ENV['SASS_PATH']
      # The select here prevents errors when the environment's
      # load paths specified do not exist.
      ENV['SASS_PATH'].split(File::PATH_SEPARATOR).select {|d| File.directory?(d)}
    end
  end
end




© 2015 - 2025 Weber Informatics LLC | Privacy Policy