middleman/middleman-core/lib/middleman-core/renderers/sass.rb

130 lines
3.6 KiB
Ruby
Raw Normal View History

require 'sass'
2014-04-05 02:02:22 +02:00
require 'compass/import-once'
GLOB = /\*|\[.+\]/
# Hack around broken sass globs when combined with import-once
# Targets compass-import-once 1.0.4
# Tracking issue: https://github.com/chriseppstein/compass/issues/1529
module Compass
module ImportOnce
module Importer
def find_relative(uri, base, options, *args)
if uri =~ GLOB
force_import = true
else
uri, force_import = handle_force_import(uri)
end
maybe_replace_with_dummy_engine(super(uri, base, options, *args), options, force_import)
end
def find(uri, options, *args)
if uri =~ GLOB
force_import = true
else
uri, force_import = handle_force_import(uri)
end
maybe_replace_with_dummy_engine(super(uri, options, *args), options, force_import)
end
end
end
end
2012-04-27 01:15:35 +02:00
module Middleman
module Renderers
# Sass renderer
class Sass < ::Middleman::Extension
2012-04-27 01:15:35 +02:00
# Setup extension
def initialize(app, options={}, &block)
super
2014-07-16 03:01:45 +02:00
app.files.ignore :sass_cache, :source, /(^|\/)\.sass-cache\//
opts = { output_style: :nested }
opts[:line_comments] = false if ENV['TEST']
# Default sass options
app.config.define_setting :sass, opts, 'Sass engine options'
app.config.define_setting :sass_assets_paths, [], 'Paths to extra SASS/SCSS files'
2012-04-27 01:15:35 +02:00
# Tell Tilt to use it as well (for inline sass blocks)
::Tilt.register 'sass', SassPlusCSSFilenameTemplate
::Tilt.prefer(SassPlusCSSFilenameTemplate)
2014-04-05 02:02:22 +02:00
# Tell Tilt to use it as well (for inline scss blocks)
::Tilt.register 'scss', ScssPlusCSSFilenameTemplate
::Tilt.prefer(ScssPlusCSSFilenameTemplate)
::Compass::ImportOnce.activate!
require 'middleman-core/renderers/sass_functions'
2012-04-27 01:15:35 +02:00
end
2012-05-24 23:29:29 +02:00
# A SassTemplate for Tilt which outputs debug messages
class SassPlusCSSFilenameTemplate < ::Tilt::SassTemplate
def initialize(*args, &block)
super
2013-12-28 19:14:15 +01:00
2014-04-29 19:44:24 +02:00
@context = @options[:context] if @options.key?(:context)
end
2013-12-28 19:14:15 +01:00
2012-05-24 23:29:29 +02:00
# Define the expected syntax for the template
# @return [Symbol]
def syntax
:sass
end
2012-05-24 23:29:29 +02:00
def prepare; end
2012-04-27 01:15:35 +02:00
# Add exception messaging
# @param [Class] context
# @return [String]
2014-04-29 19:44:24 +02:00
def evaluate(context, _)
@context ||= context
2012-05-24 23:29:29 +02:00
@engine = ::Sass::Engine.new(data, sass_options)
2012-04-27 01:15:35 +02:00
begin
2012-05-24 23:29:29 +02:00
@engine.render
rescue ::Sass::SyntaxError => e
2014-04-29 19:50:21 +02:00
::Sass::SyntaxError.exception_to_css(e, full_exception: true)
2012-04-27 01:15:35 +02:00
end
end
2012-04-27 01:15:35 +02:00
# Change Sass path, for url functions, to the build folder if we're building
# @return [Hash]
def sass_options
ctx = if defined?(::Middleman::Renderers::Haml)
::Middleman::Renderers::Haml.last_haml_scope || @context
else
@context
end
more_opts = {
load_paths: ctx.config[:sass_assets_paths],
filename: eval_file,
line: line,
syntax: syntax,
custom: { middleman_context: ctx.app }
}
2013-12-28 19:14:15 +01:00
if ctx.is_a?(::Middleman::TemplateContext) && file
2014-07-16 03:01:45 +02:00
more_opts[:css_filename] = file.sub(/\.s[ac]ss$/, '')
end
2013-12-28 19:14:15 +01:00
options.merge(more_opts)
2012-04-27 01:15:35 +02:00
end
end
2012-04-27 01:15:35 +02:00
# SCSS version of the above template
class ScssPlusCSSFilenameTemplate < SassPlusCSSFilenameTemplate
# Define the expected syntax for the template
# @return [Symbol]
def syntax
:scss
end
end
2011-07-10 22:55:40 +02:00
end
end
end