require_dependency 'sass/discourse_sass_importer' require 'pathname' module Sass::Script::Functions def _error(message) raise Sass::SyntaxError, mesage end end class DiscourseSassCompiler def self.compile(scss, target, opts={}) self.new(scss, target).compile(opts) end # Takes a Sass::SyntaxError and generates css that will show the # error at the bottom of the page. def self.error_as_css(sass_error, label) error = sass_error.sass_backtrace_str(label) error.gsub!("\n", '\A ') error.gsub!("'", '\27 ') "footer { white-space: pre; } footer:after { content: '#{error}' }" end def initialize(scss, target) @scss = scss @target = target unless Sass::Script::Functions < Sprockets::SassFunctions Sass::Script::Functions.send :include, Sprockets::SassFunctions end end # Compiles the given scss and output the css as a string. # # Options: # safe: (boolean) if true, theme and plugin stylesheets will not be included. Default is false. def compile(opts={}) app = Rails.application env = app.assets || Sprockets::Railtie.build_environment(app) pathname = Pathname.new("app/assets/stylesheets/#{@target}.scss") context = env.context_class.new( environment: env, filename: "#{@target}.scss", pathname: pathname, metadata: {} ) debug_opts = Rails.env.production? ? {} : { line_numbers: true, # debug_info: true, # great with Firebug + FireSass, but not helpful elsewhere style: :expanded } importer_class = opts[:safe] ? DiscourseSafeSassImporter : DiscourseSassImporter css = ::Sass::Engine.new(@scss, { syntax: :scss, cache: false, read_cache: false, style: :compressed, filesystem_importer: importer_class, load_paths: context.environment.paths.map { |path| importer_class.new(path.to_s) }, sprockets: { context: context, environment: context.environment } }.merge(debug_opts)).render css_output = css if opts[:rtl] begin require 'r2' css_output = R2.r2(css) if defined?(R2) rescue; end end css_output end end