130 lines
3.6 KiB
Ruby
130 lines
3.6 KiB
Ruby
require 'sass'
|
|
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
|
|
|
|
module Middleman
|
|
module Renderers
|
|
# Sass renderer
|
|
class Sass < ::Middleman::Extension
|
|
# Setup extension
|
|
def initialize(app, options={}, &block)
|
|
super
|
|
|
|
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'
|
|
|
|
# Tell Tilt to use it as well (for inline sass blocks)
|
|
::Tilt.register 'sass', SassPlusCSSFilenameTemplate
|
|
::Tilt.prefer(SassPlusCSSFilenameTemplate)
|
|
|
|
# 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'
|
|
end
|
|
|
|
# A SassTemplate for Tilt which outputs debug messages
|
|
class SassPlusCSSFilenameTemplate < ::Tilt::SassTemplate
|
|
def initialize(*args, &block)
|
|
super
|
|
|
|
@context = @options[:context] if @options.key?(:context)
|
|
end
|
|
|
|
# Define the expected syntax for the template
|
|
# @return [Symbol]
|
|
def syntax
|
|
:sass
|
|
end
|
|
|
|
def prepare; end
|
|
|
|
# Add exception messaging
|
|
# @param [Class] context
|
|
# @return [String]
|
|
def evaluate(context, _)
|
|
@context ||= context
|
|
@engine = ::Sass::Engine.new(data, sass_options)
|
|
|
|
begin
|
|
@engine.render
|
|
rescue ::Sass::SyntaxError => e
|
|
::Sass::SyntaxError.exception_to_css(e, full_exception: true)
|
|
end
|
|
end
|
|
|
|
# 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 }
|
|
}
|
|
|
|
if ctx.is_a?(::Middleman::TemplateContext) && file
|
|
more_opts[:css_filename] = file.sub(/\.s[ac]ss$/, '')
|
|
end
|
|
|
|
options.merge(more_opts)
|
|
end
|
|
end
|
|
|
|
# SCSS version of the above template
|
|
class ScssPlusCSSFilenameTemplate < SassPlusCSSFilenameTemplate
|
|
# Define the expected syntax for the template
|
|
# @return [Symbol]
|
|
def syntax
|
|
:scss
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|