Class: Sass::Engine

Inherits:
Object
  • Object
show all
Defined in:
.ruby-sass/lib/sass/engine.rb

Overview

This class handles the parsing and compilation of the Sass template. Example usage:

template = File.read('stylesheets/sassy.sass')
sass_engine = Sass::Engine.new(template)
output = sass_engine.render
puts output

Defined Under Namespace

Classes: Line

Constant Summary

PROPERTY_CHAR =

The character that begins a CSS property.

?:
COMMENT_CHAR =

The character that designates the beginning of a comment, either Sass or CSS.

?/
SASS_COMMENT_CHAR =

The character that follows the general COMMENT_CHAR and designates a Sass comment, which is not output as a CSS comment.

?/
SASS_LOUD_COMMENT_CHAR =

The character that indicates that a comment allows interpolation and should be preserved even in `:compressed` mode.

?!
CSS_COMMENT_CHAR =

The character that follows the general COMMENT_CHAR and designates a CSS comment, which is embedded in the CSS document.

?*
DIRECTIVE_CHAR =

The character used to denote a compiler directive.

?@
ESCAPE_CHAR =

Designates a non-parsed rule.

?\\
MIXIN_DEFINITION_CHAR =

Designates block as mixin definition rather than CSS rules to output

?=
MIXIN_INCLUDE_CHAR =

Includes named mixin declared using MIXIN_DEFINITION_CHAR

?+
PROPERTY_OLD =

The regex that matches and extracts data from properties of the form `:name prop`.

/^:([^\s=:"]+)\s*(?:\s+|$)(.*)/
DEFAULT_OPTIONS =

The default options for Sass::Engine.

{
  :style => :nested,
  :load_paths => [],
  :cache => true,
  :cache_location => './.sass-cache',
  :syntax => :sass,
  :filesystem_importer => Sass::Importers::Filesystem
}.freeze
@@old_property_deprecation =
Deprecation.new

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

#initialize(template, options = {}) ⇒ Engine

Creates a new Engine. Note that Engine should only be used directly when compiling in-memory Sass code. If you're compiling a single Sass file from the filesystem, use for_file. If you're compiling multiple files from the filesystem, use Plugin.

Parameters:

  • template (String)

    The Sass template. This template can be encoded using any encoding that can be converted to Unicode. If the template contains an `@charset` declaration, that overrides the Ruby encoding (see the encoding documentation)

  • options ({Symbol => Object}) (defaults to: {})

    An options hash. See the Sass options documentation.

See Also:

  • Sass::Engine.{Sass{Sass::Engine{Sass::Engine.for_file}
  • Sass::Engine.{Sass{Sass::Plugin}


274
275
276
277
278
279
280
# File '.ruby-sass/lib/sass/engine.rb', line 274

def initialize(template, options = {})
  @options = self.class.normalize_options(options)
  @template = template
  @checked_encoding = false
  @filename = nil
  @line = nil
end

Constructor Details

#initialize(template, options = {}) ⇒ Engine

Creates a new Engine. Note that Engine should only be used directly when compiling in-memory Sass code. If you're compiling a single Sass file from the filesystem, use for_file. If you're compiling multiple files from the filesystem, use Plugin.

Parameters:

  • template (String)

    The Sass template. This template can be encoded using any encoding that can be converted to Unicode. If the template contains an `@charset` declaration, that overrides the Ruby encoding (see the encoding documentation)

  • options ({Symbol => Object}) (defaults to: {})

    An options hash. See the Sass options documentation.

See Also:

  • Sass::Engine.{Sass{Sass::Engine{Sass::Engine.for_file}
  • Sass::Engine.{Sass{Sass::Plugin}


274
275
276
277
278
279
280
# File '.ruby-sass/lib/sass/engine.rb', line 274

def initialize(template, options = {})
  @options = self.class.normalize_options(options)
  @template = template
  @checked_encoding = false
  @filename = nil
  @line = nil
end

Instance Attribute Details

#options{Symbol => Object} (readonly)

The options for the Sass engine. See the Sass options documentation.

Returns:

  • ({Symbol => Object})


255
256
257
# File '.ruby-sass/lib/sass/engine.rb', line 255

def options
  @options
end

Class Method Details

.for_file(filename, options) ⇒ Sass::Engine

Returns the Sass::Engine for the given file. This is preferable to Sass::Engine.new when reading from a file because it properly sets up the Engine's metadata, enables parse-tree caching, and infers the syntax from the filename.

Parameters:

Returns:

  • (Sass::Engine)

    The Engine for the given Sass or SCSS file.

Raises:



237
238
239
240
241
242
243
244
245
246
247
248
249
# File '.ruby-sass/lib/sass/engine.rb', line 237

def self.for_file(filename, options)
  had_syntax = options[:syntax]

  if had_syntax
    # Use what was explicitly specified
  elsif filename =~ /\.scss$/
    options.merge!(:syntax => :scss)
  elsif filename =~ /\.sass$/
    options.merge!(:syntax => :sass)
  end

  Sass::Engine.new(File.read(filename), options.merge(:filename => filename))
end

.normalize_options(options) ⇒ {Symbol => Object}

Converts a Sass options hash into a standard form, filling in default values and resolving aliases.

Parameters:

Returns:

  • ({Symbol => Object})

    The normalized options hash.



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File '.ruby-sass/lib/sass/engine.rb', line 183

def self.normalize_options(options)
  options = DEFAULT_OPTIONS.merge(options.reject {|_k, v| v.nil?})

  # If the `:filename` option is passed in without an importer,
  # assume it's using the default filesystem importer.
  options[:importer] ||= options[:filesystem_importer].new(".") if options[:filename]

  # Tracks the original filename of the top-level Sass file
  options[:original_filename] ||= options[:filename]

  options[:cache_store] ||= Sass::CacheStores::Chain.new(
    Sass::CacheStores::Memory.new, Sass::CacheStores::Filesystem.new(options[:cache_location]))
  # Support both, because the docs said one and the other actually worked
  # for quite a long time.
  options[:line_comments] ||= options[:line_numbers]

  options[:load_paths] = (options[:load_paths] + Sass.load_paths).map do |p|
    next p unless p.is_a?(String) || (defined?(Pathname) && p.is_a?(Pathname))
    options[:filesystem_importer].new(p.to_s)
  end

  # Remove any deprecated importers if the location is imported explicitly
  options[:load_paths].reject! do |importer|
    importer.is_a?(Sass::Importers::DeprecatedPath) &&
      options[:load_paths].find do |other_importer|
        other_importer.is_a?(Sass::Importers::Filesystem) &&
          other_importer != importer &&
          other_importer.root == importer.root
      end
  end

  # Backwards compatibility
  options[:property_syntax] ||= options[:attribute_syntax]
  case options[:property_syntax]
  when :alternate; options[:property_syntax] = :new
  when :normal; options[:property_syntax] = :old
  end
  options[:sourcemap] = :auto if options[:sourcemap] == true
  options[:sourcemap] = :none if options[:sourcemap] == false

  options
end

Instance Method Details

#_dependencies(seen, engines) ⇒ Object

Helper for #dependencies.



349
350
351
352
353
354
355
356
357
358
# File '.ruby-sass/lib/sass/engine.rb', line 349

def _dependencies(seen, engines)
  key = [@options[:filename], @options[:importer]]
  return if seen.include?(key)
  seen << key
  engines << self
  to_tree.grep(Tree::ImportNode) do |n|
    next if n.css_import?
    n.imported_file._dependencies(seen, engines)
  end
end

#dependencies[Sass::Engine]

Gets a set of all the documents that are (transitive) dependencies of this document, not including the document itself.

Returns:



341
342
343
344
# File '.ruby-sass/lib/sass/engine.rb', line 341

def dependencies
  _dependencies(Set.new, engines = Set.new)
  Sass::Util.array_minus(engines, [self])
end

#renderString Also known as: to_css

Render the template to CSS.

Returns:

  • (String)

    The CSS

Raises:

  • (Sass::SyntaxError)

    if there's an error in the document

  • (Encoding::UndefinedConversionError)

    if the source encoding cannot be converted to UTF-8

  • (ArgumentError)

    if the document uses an unknown encoding with `@charset`



289
290
291
292
# File '.ruby-sass/lib/sass/engine.rb', line 289

def render
  return _to_tree.render unless @options[:quiet]
  Sass::Util.silence_sass_warnings {_to_tree.render}
end

#render_with_sourcemap(sourcemap_uri) ⇒ (String, Sass::Source::Map)

Render the template to CSS and return the source map.

Parameters:

  • sourcemap_uri (String)

    The sourcemap URI to use in the `@sourceMappingURL` comment. If this is relative, it should be relative to the location of the CSS file.

Returns:

Raises:

  • (Sass::SyntaxError)

    if there's an error in the document, or if the public URL for this document couldn't be determined.

  • (Encoding::UndefinedConversionError)

    if the source encoding cannot be converted to UTF-8

  • (ArgumentError)

    if the document uses an unknown encoding with `@charset`



306
307
308
309
# File '.ruby-sass/lib/sass/engine.rb', line 306

def render_with_sourcemap(sourcemap_uri)
  return _render_with_sourcemap(sourcemap_uri) unless @options[:quiet]
  Sass::Util.silence_sass_warnings {_render_with_sourcemap(sourcemap_uri)}
end

#source_encodingEncoding?

Returns the original encoding of the document.

Returns:

  • (Encoding, nil)

Raises:

  • (Encoding::UndefinedConversionError)

    if the source encoding cannot be converted to UTF-8

  • (ArgumentError)

    if the document uses an unknown encoding with `@charset`



331
332
333
334
# File '.ruby-sass/lib/sass/engine.rb', line 331

def source_encoding
  check_encoding!
  @source_encoding
end

#to_treeSass::Tree::Node

Parses the document into its parse tree. Memoized.

Returns:

Raises:



317
318
319
320
321
322
323
# File '.ruby-sass/lib/sass/engine.rb', line 317

def to_tree
  @tree ||= if @options[:quiet]
              Sass::Util.silence_sass_warnings {_to_tree}
            else
              _to_tree
            end
end