Module Sass::Plugin
In: lib/sass/plugin.rb
lib/sass/plugin/rack.rb
Haml::Util Engine Color SyntaxError UnitConversionError StandardError Node Operation Literal UnaryOperation Funcall Variable Number String Bool EvaluationContext Node\n[lib/sass/css.rb\nlib/sass/tree/node.rb] DebugNode IfNode CommentNode ForNode MixinNode VariableNode ImportNode WhileNode MixinDefNode Repl CSS Environment Lexer Parser PropNode\n[lib/sass/css.rb\nlib/sass/tree/prop_node.rb] DirectiveNode\n[lib/sass/css.rb\nlib/sass/tree/directive_node.rb] RuleNode\n[lib/sass/css.rb\nlib/sass/tree/rule_node.rb] Rack lib/sass/repl.rb lib/sass/css.rb lib/sass/environment.rb lib/sass/error.rb lib/sass/engine.rb lib/sass/script/lexer.rb lib/sass/script/color.rb lib/sass/script/string.rb lib/sass/script/unary_operation.rb lib/sass/script/variable.rb lib/sass/script/funcall.rb lib/sass/script/operation.rb lib/sass/script/bool.rb lib/sass/script/parser.rb lib/sass/script/literal.rb lib/sass/script/node.rb lib/sass/script/number.rb lib/sass/script/functions.rb Functions Script Files lib/sass/tree/while_node.rb lib/sass/tree/if_node.rb lib/sass/tree/mixin_def_node.rb lib/sass/tree/debug_node.rb lib/sass/tree/for_node.rb lib/sass/tree/import_node.rb lib/sass/tree/prop_node.rb lib/sass/tree/node.rb lib/sass/tree/comment_node.rb lib/sass/tree/mixin_node.rb lib/sass/tree/directive_node.rb lib/sass/tree/rule_node.rb lib/sass/tree/variable_node.rb Tree lib/sass/plugin/rack.rb Plugin Sass dot/m_54_0.png

This module handles the compilation of Sass files. It provides global options and checks whether CSS files need to be updated.

This module is used as the primary interface with Sass when it‘s used as a plugin for various frameworks. All Rack-enabled frameworks are supported out of the box. The plugin is {file:SASS_REFERENCE.md#rails_merb_plugin automatically activated for Rails and Merb}. Other frameworks must enable it explicitly; see {Sass::Plugin::Rack}.

Methods

Classes and Modules

Class Sass::Plugin::Rack

Attributes

checked_for_updates  [R]  Whether or not Sass has *ever* checked if the stylesheets need to be updated (in this Ruby instance).

@return [Boolean]

options  [R]  An options hash. See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.

@return [{Symbol => Object}]

Public Instance methods

Same as \{update_stylesheets}, but respects \{checked_for_updates} and the {file:SASS_REFERENCE.md#always_update-option `:always_update`} and {file:SASS_REFERENCE.md#always_check-option `:always_check`} options.

@see update_stylesheets

[Source]

    # File lib/sass/plugin.rb, line 59
59:     def check_for_updates
60:       return unless !Sass::Plugin.checked_for_updates ||
61:           Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
62:       update_stylesheets
63:     end

Non-destructively modifies \{options} so that default values are properly set.

@param additional_options [{Symbol => Object}] An options hash with which to merge \{options} @return [{Symbol => Object}] The modified options hash

[Source]

    # File lib/sass/plugin.rb, line 48
48:     def engine_options(additional_options = {})
49:       opts = options.dup.merge(additional_options)
50:       opts[:load_paths] = load_paths(opts)
51:       opts
52:     end

Sets the options hash. See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.

@param value [{Symbol => Object}] The options hash

[Source]

    # File lib/sass/plugin.rb, line 40
40:     def options=(value)
41:       @options.merge!(value)
42:     end

Updates out-of-date stylesheets.

Checks each Sass file in {file:SASS_REFERENCE.md#template_location-option `:template_location`} to see if it‘s been modified more recently than the corresponding CSS file in {file:SASS_REFERENCE.md#css_location-option} `:css_location`}. If it has, it updates the CSS file.

[Source]

    # File lib/sass/plugin.rb, line 71
71:     def update_stylesheets
72:       return if options[:never_update]
73: 
74:       @checked_for_updates = true
75:       template_locations.zip(css_locations).each do |template_location, css_location|
76: 
77:         Dir.glob(File.join(template_location, "**", "*.sass")).each do |file|
78:           # Get the relative path to the file with no extension
79:           name = file.sub(template_location.sub(/\/*$/, '/'), "")[0...-5]
80: 
81:           if !forbid_update?(name) && (options[:always_update] || stylesheet_needs_update?(name, template_location, css_location))
82:             update_stylesheet(name, template_location, css_location)
83:           end
84:         end
85:       end
86:     end

Private Instance methods

[Source]

     # File lib/sass/plugin.rb, line 183
183:     def css_filename(name, path)
184:       "#{path}/#{name}.css"
185:     end

[Source]

     # File lib/sass/plugin.rb, line 131
131:     def css_locations
132:       if options[:template_location] && !options[:template_location].is_a?(String)
133:         options[:template_location].to_a.map { |l| l.last }
134:       else
135:         [options[:css_location]]
136:       end
137:     end

[Source]

     # File lib/sass/plugin.rb, line 212
212:     def dependencies(filename)
213:       File.readlines(filename).grep(/^@import /).map do |line|
214:         line[8..-1].split(',').map do |inc|
215:           Sass::Files.find_file_to_import(inc.strip, [File.dirname(filename)] + load_paths)
216:         end
217:       end.flatten.grep(/\.sass$/)
218:     end

[Source]

     # File lib/sass/plugin.rb, line 205
205:     def dependency_updated?(css_mtime)
206:       lambda do |dep|
207:         File.mtime(dep) > css_mtime ||
208:           dependencies(dep).any?(&dependency_updated?(css_mtime))
209:       end
210:     end

[Source]

     # File lib/sass/plugin.rb, line 197
197:     def exact_stylesheet_needs_update?(css_file, template_file)
198:       return true unless File.exists?(css_file)
199: 
200:       css_mtime = File.mtime(css_file)
201:       File.mtime(template_file) > css_mtime ||
202:         dependencies(template_file).any?(&dependency_updated?(css_mtime))
203:     end

[Source]

     # File lib/sass/plugin.rb, line 139
139:     def exception_string(e)
140:       e_string = "#{e.class}: #{e.message}"
141: 
142:       if e.is_a? Sass::SyntaxError
143:         e_string << "\non line #{e.sass_line}"
144: 
145:         if e.sass_filename
146:           e_string << " of #{e.sass_filename}"
147: 
148:           if File.exists?(e.sass_filename)
149:             e_string << "\n\n"
150: 
151:             min = [e.sass_line - 5, 0].max
152:             begin
153:               File.read(e.sass_filename).rstrip.split("\n")[
154:                 min .. e.sass_line + 5
155:               ].each_with_index do |line, i|
156:                 e_string << "#{min + i + 1}: #{line}\n"
157:               end
158:             rescue
159:               e_string << "Couldn't read sass file: #{e.sass_filename}"
160:             end
161:           end
162:         end
163:       end
164:       "/*\n\#{e_string}\n\nBacktrace:\\n\#{e.backtrace.join(\"\\n\")}\n*/\nbody:before {\n  white-space: pre;\n  font-family: monospace;\n  content: \"\#{e_string.gsub('\"', '\\\"').gsub(\"\\n\", '\\\\A ')}\"; }\n"
165:       # Fix an emacs syntax-highlighting hiccup: '
166:     end

[Source]

     # File lib/sass/plugin.rb, line 187
187:     def forbid_update?(name)
188:       name.sub(/^.*\//, '')[0] == ?_
189:     end

[Source]

     # File lib/sass/plugin.rb, line 118
118:     def load_paths(opts = options)
119:       (opts[:load_paths] || []) + template_locations
120:     end

Create any successive directories required to be able to write a file to: File.join(base,name)

[Source]

     # File lib/sass/plugin.rb, line 112
112:     def mkpath(base, name)
113:       dirs = [base]
114:       name.split(File::SEPARATOR)[0...-1].each { |dir| dirs << File.join(dirs[-1],dir) }
115:       dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) }
116:     end

[Source]

     # File lib/sass/plugin.rb, line 191
191:     def stylesheet_needs_update?(name, template_path, css_path)
192:       css_file = css_filename(name, css_path)
193:       template_file = template_filename(name, template_path)
194:       exact_stylesheet_needs_update?(css_file, template_file)
195:     end

[Source]

     # File lib/sass/plugin.rb, line 179
179:     def template_filename(name, path)
180:       "#{path}/#{name}.sass"
181:     end

[Source]

     # File lib/sass/plugin.rb, line 122
122:     def template_locations
123:       location = (options[:template_location] || File.join(options[:css_location],'sass'))
124:       if location.is_a?(String)
125:         [location]
126:       else
127:         location.to_a.map { |l| l.first }
128:       end
129:     end

[Source]

     # File lib/sass/plugin.rb, line 90
 90:     def update_stylesheet(name, template_location, css_location)
 91:       css = css_filename(name, css_location)
 92:       File.delete(css) if File.exists?(css)
 93: 
 94:       filename = template_filename(name, template_location)
 95:       result = begin
 96:                  Sass::Files.tree_for(filename, engine_options(:css_filename => css, :filename => filename)).render
 97:                rescue Exception => e
 98:                  raise e unless options[:full_exception]
 99:                  exception_string(e)
100:                end
101: 
102:       # Create any directories that might be necessary
103:       mkpath(css_location, name)
104: 
105:       # Finally, write the file
106:       File.open(css, 'w') do |file|
107:         file.print(result)
108:       end
109:     end

[Validate]