sass 3.3.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +58 -50
  4. data/Rakefile +1 -4
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/VERSION_NAME +1 -1
  8. data/bin/sass +1 -1
  9. data/bin/scss +1 -1
  10. data/lib/sass/cache_stores/filesystem.rb +6 -2
  11. data/lib/sass/css.rb +1 -3
  12. data/lib/sass/engine.rb +37 -46
  13. data/lib/sass/environment.rb +13 -17
  14. data/lib/sass/error.rb +6 -9
  15. data/lib/sass/exec/base.rb +187 -0
  16. data/lib/sass/exec/sass_convert.rb +264 -0
  17. data/lib/sass/exec/sass_scss.rb +424 -0
  18. data/lib/sass/exec.rb +5 -771
  19. data/lib/sass/features.rb +7 -0
  20. data/lib/sass/importers/base.rb +7 -2
  21. data/lib/sass/importers/filesystem.rb +9 -25
  22. data/lib/sass/importers.rb +0 -1
  23. data/lib/sass/media.rb +1 -4
  24. data/lib/sass/plugin/compiler.rb +200 -83
  25. data/lib/sass/plugin/staleness_checker.rb +1 -1
  26. data/lib/sass/plugin.rb +3 -3
  27. data/lib/sass/script/css_lexer.rb +1 -1
  28. data/lib/sass/script/functions.rb +622 -268
  29. data/lib/sass/script/lexer.rb +99 -34
  30. data/lib/sass/script/parser.rb +24 -23
  31. data/lib/sass/script/tree/funcall.rb +1 -1
  32. data/lib/sass/script/tree/interpolation.rb +20 -2
  33. data/lib/sass/script/tree/selector.rb +26 -0
  34. data/lib/sass/script/tree/string_interpolation.rb +1 -1
  35. data/lib/sass/script/tree.rb +1 -0
  36. data/lib/sass/script/value/base.rb +7 -5
  37. data/lib/sass/script/value/bool.rb +0 -5
  38. data/lib/sass/script/value/color.rb +39 -21
  39. data/lib/sass/script/value/helpers.rb +107 -0
  40. data/lib/sass/script/value/list.rb +0 -15
  41. data/lib/sass/script/value/null.rb +0 -5
  42. data/lib/sass/script/value/number.rb +62 -14
  43. data/lib/sass/script/value/string.rb +59 -11
  44. data/lib/sass/script/value.rb +0 -1
  45. data/lib/sass/scss/css_parser.rb +8 -2
  46. data/lib/sass/scss/parser.rb +190 -328
  47. data/lib/sass/scss/rx.rb +15 -6
  48. data/lib/sass/scss/static_parser.rb +298 -1
  49. data/lib/sass/selector/abstract_sequence.rb +28 -13
  50. data/lib/sass/selector/comma_sequence.rb +92 -13
  51. data/lib/sass/selector/pseudo.rb +256 -0
  52. data/lib/sass/selector/sequence.rb +94 -24
  53. data/lib/sass/selector/simple.rb +14 -25
  54. data/lib/sass/selector/simple_sequence.rb +97 -33
  55. data/lib/sass/selector.rb +57 -194
  56. data/lib/sass/shared.rb +1 -1
  57. data/lib/sass/source/map.rb +26 -12
  58. data/lib/sass/stack.rb +0 -6
  59. data/lib/sass/supports.rb +2 -3
  60. data/lib/sass/tree/at_root_node.rb +1 -0
  61. data/lib/sass/tree/charset_node.rb +1 -1
  62. data/lib/sass/tree/directive_node.rb +8 -2
  63. data/lib/sass/tree/error_node.rb +18 -0
  64. data/lib/sass/tree/extend_node.rb +1 -1
  65. data/lib/sass/tree/function_node.rb +4 -0
  66. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  67. data/lib/sass/tree/prop_node.rb +1 -1
  68. data/lib/sass/tree/rule_node.rb +12 -7
  69. data/lib/sass/tree/visitors/check_nesting.rb +38 -10
  70. data/lib/sass/tree/visitors/convert.rb +16 -18
  71. data/lib/sass/tree/visitors/cssize.rb +29 -29
  72. data/lib/sass/tree/visitors/deep_copy.rb +5 -0
  73. data/lib/sass/tree/visitors/perform.rb +45 -33
  74. data/lib/sass/tree/visitors/set_options.rb +14 -0
  75. data/lib/sass/tree/visitors/to_css.rb +15 -14
  76. data/lib/sass/util/subset_map.rb +1 -1
  77. data/lib/sass/util.rb +222 -99
  78. data/lib/sass/version.rb +5 -5
  79. data/lib/sass.rb +0 -5
  80. data/test/sass/cache_test.rb +62 -20
  81. data/test/sass/callbacks_test.rb +1 -1
  82. data/test/sass/compiler_test.rb +19 -10
  83. data/test/sass/conversion_test.rb +58 -1
  84. data/test/sass/css2sass_test.rb +23 -4
  85. data/test/sass/encoding_test.rb +219 -0
  86. data/test/sass/engine_test.rb +136 -199
  87. data/test/sass/exec_test.rb +2 -2
  88. data/test/sass/extend_test.rb +236 -19
  89. data/test/sass/functions_test.rb +295 -253
  90. data/test/sass/importer_test.rb +31 -21
  91. data/test/sass/logger_test.rb +1 -1
  92. data/test/sass/more_results/more_import.css +1 -1
  93. data/test/sass/plugin_test.rb +14 -13
  94. data/test/sass/results/compact.css +1 -1
  95. data/test/sass/results/complex.css +4 -4
  96. data/test/sass/results/expanded.css +1 -1
  97. data/test/sass/results/import.css +1 -1
  98. data/test/sass/results/import_charset_ibm866.css +2 -2
  99. data/test/sass/results/mixins.css +17 -17
  100. data/test/sass/results/nested.css +1 -1
  101. data/test/sass/results/parent_ref.css +2 -2
  102. data/test/sass/results/script.css +3 -3
  103. data/test/sass/results/scss_import.css +1 -1
  104. data/test/sass/script_conversion_test.rb +10 -7
  105. data/test/sass/script_test.rb +288 -74
  106. data/test/sass/scss/css_test.rb +141 -24
  107. data/test/sass/scss/rx_test.rb +4 -4
  108. data/test/sass/scss/scss_test.rb +457 -18
  109. data/test/sass/source_map_test.rb +115 -25
  110. data/test/sass/superselector_test.rb +191 -0
  111. data/test/sass/templates/scss_import.scss +2 -1
  112. data/test/sass/test_helper.rb +1 -1
  113. data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
  114. data/test/sass/util/normalized_map_test.rb +1 -1
  115. data/test/sass/util/subset_map_test.rb +2 -2
  116. data/test/sass/util_test.rb +31 -1
  117. data/test/sass/value_helpers_test.rb +5 -7
  118. data/test/test_helper.rb +2 -2
  119. data/vendor/listen/CHANGELOG.md +1 -228
  120. data/vendor/listen/Gemfile +5 -15
  121. data/vendor/listen/README.md +111 -77
  122. data/vendor/listen/Rakefile +0 -42
  123. data/vendor/listen/lib/listen/adapter.rb +195 -82
  124. data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
  125. data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
  126. data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
  127. data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
  128. data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
  129. data/vendor/listen/lib/listen/directory_record.rb +96 -61
  130. data/vendor/listen/lib/listen/listener.rb +135 -37
  131. data/vendor/listen/lib/listen/turnstile.rb +9 -5
  132. data/vendor/listen/lib/listen/version.rb +1 -1
  133. data/vendor/listen/lib/listen.rb +33 -19
  134. data/vendor/listen/listen.gemspec +6 -0
  135. data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
  136. data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
  137. data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
  138. data/vendor/listen/spec/listen/listener_spec.rb +128 -39
  139. data/vendor/listen/spec/listen_spec.rb +15 -21
  140. data/vendor/listen/spec/spec_helper.rb +4 -0
  141. data/vendor/listen/spec/support/adapter_helper.rb +52 -15
  142. data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
  143. data/vendor/listen/spec/support/listeners_helper.rb +30 -7
  144. metadata +25 -22
  145. data/ext/mkrf_conf.rb +0 -27
  146. data/lib/sass/importers/deprecated_path.rb +0 -51
  147. data/lib/sass/script/value/deprecated_false.rb +0 -55
  148. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  149. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  150. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  151. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
@@ -0,0 +1,424 @@
1
+ module Sass::Exec
2
+ # The `sass` and `scss` executables.
3
+ class SassScss < Base
4
+ attr_reader :default_syntax
5
+
6
+ # @param args [Array<String>] The command-line arguments
7
+ def initialize(args, default_syntax)
8
+ super(args)
9
+ @options[:sourcemap] = :auto
10
+ @options[:for_engine] = {
11
+ :load_paths => default_sass_path
12
+ }
13
+ @default_syntax = default_syntax
14
+ end
15
+
16
+ protected
17
+
18
+ # Tells optparse how to parse the arguments.
19
+ #
20
+ # @param opts [OptionParser]
21
+ def set_opts(opts)
22
+ opts.banner = <<END
23
+ Usage: #{default_syntax} [options] [INPUT] [OUTPUT]
24
+
25
+ Description:
26
+ Converts SCSS or Sass files to CSS.
27
+ END
28
+
29
+ common_options(opts)
30
+ watching_and_updating(opts)
31
+ input_and_output(opts)
32
+ miscellaneous(opts)
33
+ end
34
+
35
+ # Processes the options set by the command-line arguments,
36
+ # and runs the Sass compiler appropriately.
37
+ def process_result
38
+ require 'sass'
39
+
40
+ if !@options[:update] && !@options[:watch] &&
41
+ @args.first && colon_path?(@args.first)
42
+ if @args.size == 1
43
+ @args = split_colon_path(@args.first)
44
+ else
45
+ @options[:update] = true
46
+ end
47
+ end
48
+ load_compass if @options[:compass]
49
+ return interactive if @options[:interactive]
50
+ return watch_or_update if @options[:watch] || @options[:update]
51
+ super
52
+
53
+ if @options[:sourcemap] != :none && @options[:output_filename]
54
+ @options[:sourcemap_filename] = Sass::Util.sourcemap_name(@options[:output_filename])
55
+ end
56
+
57
+ @options[:for_engine][:filename] = @options[:filename]
58
+ @options[:for_engine][:css_filename] = @options[:output] if @options[:output].is_a?(String)
59
+ @options[:for_engine][:sourcemap_filename] = @options[:sourcemap_filename]
60
+ @options[:for_engine][:sourcemap] = @options[:sourcemap]
61
+
62
+ run
63
+ end
64
+
65
+ private
66
+
67
+ def common_options(opts)
68
+ opts.separator ''
69
+ opts.separator 'Common Options:'
70
+
71
+ opts.on('-I', '--load-path PATH', 'Specify a Sass import path.') do |path|
72
+ (@options[:for_engine][:load_paths] ||= []) << path
73
+ end
74
+
75
+ opts.on('-r', '--require LIB', 'Require a Ruby library before running Sass.') do |lib|
76
+ require lib
77
+ end
78
+
79
+ opts.on('--compass', 'Make Compass imports available and load project configuration.') do
80
+ @options[:compass] = true
81
+ end
82
+
83
+ opts.on('-t', '--style NAME', 'Output style. Can be nested (default), compact, ' \
84
+ 'compressed, or expanded.') do |name|
85
+ @options[:for_engine][:style] = name.to_sym
86
+ end
87
+
88
+ opts.on("-?", "-h", "--help", "Show this help message.") do
89
+ puts opts
90
+ exit
91
+ end
92
+
93
+ opts.on("-v", "--version", "Print the Sass version.") do
94
+ puts("Sass #{Sass.version[:string]}")
95
+ exit
96
+ end
97
+ end
98
+
99
+ def watching_and_updating(opts)
100
+ opts.separator ''
101
+ opts.separator 'Watching and Updating:'
102
+
103
+ opts.on('--watch', 'Watch files or directories for changes.',
104
+ 'The location of the generated CSS can be set using a colon:',
105
+ " #{@default_syntax} --watch input.#{@default_syntax}:output.css",
106
+ " #{@default_syntax} --watch input-dir:output-dir") do
107
+ @options[:watch] = true
108
+ end
109
+
110
+ # Polling is used by default on Windows.
111
+ unless Sass::Util.windows?
112
+ opts.on('--poll', 'Check for file changes manually, rather than relying on the OS.',
113
+ 'Only meaningful for --watch.') do
114
+ @options[:poll] = true
115
+ end
116
+ end
117
+
118
+ opts.on('--update', 'Compile files or directories to CSS.',
119
+ 'Locations are set like --watch.') do
120
+ @options[:update] = true
121
+ end
122
+
123
+ opts.on('-f', '--force', 'Recompile every Sass file, even if the CSS file is newer.',
124
+ 'Only meaningful for --update.') do
125
+ @options[:force] = true
126
+ end
127
+
128
+ opts.on('--stop-on-error', 'If a file fails to compile, exit immediately.',
129
+ 'Only meaningful for --watch and --update.') do
130
+ @options[:stop_on_error] = true
131
+ end
132
+ end
133
+
134
+ def input_and_output(opts)
135
+ opts.separator ''
136
+ opts.separator 'Input and Output:'
137
+
138
+ if @default_syntax == :sass
139
+ opts.on('--scss',
140
+ 'Use the CSS-superset SCSS syntax.') do
141
+ @options[:for_engine][:syntax] = :scss
142
+ end
143
+ else
144
+ opts.on('--sass',
145
+ 'Use the indented Sass syntax.') do
146
+ @options[:for_engine][:syntax] = :sass
147
+ end
148
+ end
149
+
150
+ # This is optional for backwards-compatibility with Sass 3.3, which didn't
151
+ # enable sourcemaps by default and instead used "--sourcemap" to do so.
152
+ opts.on(:OPTIONAL, '--sourcemap=TYPE',
153
+ 'How to link generated output to the source files.',
154
+ ' auto (default): relative paths where possible, file URIs elsewhere',
155
+ ' file: always absolute file URIs',
156
+ ' inline: include the source text in the sourcemap',
157
+ ' none: no sourcemaps') do |type|
158
+ if type && !%w[auto file inline none].include?(type)
159
+ $stderr.puts "Unknown sourcemap type #{type}.\n\n"
160
+ $stderr.puts opts
161
+ exit
162
+ elsif type.nil?
163
+ Sass::Util.sass_warn <<MESSAGE.rstrip
164
+ DEPRECATION WARNING: Passing --sourcemap without a value is deprecated.
165
+ Sourcemaps are now generated by default, so this flag has no effect.
166
+ MESSAGE
167
+ end
168
+
169
+ @options[:sourcemap] = (type || :auto).to_sym
170
+ end
171
+
172
+ opts.on('-s', '--stdin', :NONE,
173
+ 'Read input from standard input instead of an input file.',
174
+ 'This is the default if no input file is specified.') do
175
+ @options[:input] = $stdin
176
+ end
177
+
178
+ encoding_option(opts)
179
+
180
+ opts.on('--unix-newlines', 'Use Unix-style newlines in written files.',
181
+ ('Always true on Unix.' unless Sass::Util.windows?)) do
182
+ @options[:unix_newlines] = true if Sass::Util.windows?
183
+ end
184
+
185
+ opts.on('-g', '--debug-info',
186
+ 'Emit output that can be used by the FireSass Firebug plugin.') do
187
+ @options[:for_engine][:debug_info] = true
188
+ end
189
+
190
+ opts.on('-l', '--line-numbers', '--line-comments',
191
+ 'Emit comments in the generated CSS indicating the corresponding source line.') do
192
+ @options[:for_engine][:line_numbers] = true
193
+ end
194
+ end
195
+
196
+ def miscellaneous(opts)
197
+ opts.separator ''
198
+ opts.separator 'Miscellaneous:'
199
+
200
+ opts.on('-i', '--interactive',
201
+ 'Run an interactive SassScript shell.') do
202
+ @options[:interactive] = true
203
+ end
204
+
205
+ opts.on('-c', '--check', "Just check syntax, don't evaluate.") do
206
+ require 'stringio'
207
+ @options[:check_syntax] = true
208
+ @options[:output] = StringIO.new
209
+ end
210
+
211
+ opts.on('--precision NUMBER_OF_DIGITS', Integer,
212
+ "How many digits of precision to use when outputting decimal numbers.",
213
+ "Defaults to #{Sass::Script::Value::Number.precision}.") do |precision|
214
+ Sass::Script::Value::Number.precision = precision
215
+ end
216
+
217
+ opts.on('--cache-location PATH',
218
+ 'The path to save parsed Sass files. Defaults to .sass-cache.') do |loc|
219
+ @options[:for_engine][:cache_location] = loc
220
+ end
221
+
222
+ opts.on('-C', '--no-cache', "Don't cache parsed Sass files.") do
223
+ @options[:for_engine][:cache] = false
224
+ end
225
+
226
+ opts.on('--trace', :NONE, 'Show a full Ruby stack trace on error.') do
227
+ @options[:trace] = true
228
+ end
229
+
230
+ opts.on('-q', '--quiet', 'Silence warnings and status messages during compilation.') do
231
+ @options[:for_engine][:quiet] = true
232
+ end
233
+ end
234
+
235
+ def load_compass
236
+ begin
237
+ require 'compass'
238
+ rescue LoadError
239
+ require 'rubygems'
240
+ begin
241
+ require 'compass'
242
+ rescue LoadError
243
+ puts "ERROR: Cannot load compass."
244
+ exit 1
245
+ end
246
+ end
247
+ Compass.add_project_configuration
248
+ Compass.configuration.project_path ||= Dir.pwd
249
+ @options[:for_engine][:load_paths] ||= []
250
+ @options[:for_engine][:load_paths] += Compass.configuration.sass_load_paths
251
+ end
252
+
253
+ def interactive
254
+ require 'sass/repl'
255
+ Sass::Repl.new(@options).run
256
+ end
257
+
258
+ # @comment
259
+ # rubocop:disable MethodLength
260
+ def watch_or_update
261
+ require 'sass/plugin'
262
+ Sass::Plugin.options.merge! @options[:for_engine]
263
+ Sass::Plugin.options[:unix_newlines] = @options[:unix_newlines]
264
+ Sass::Plugin.options[:poll] = @options[:poll]
265
+ Sass::Plugin.options[:sourcemap] = @options[:sourcemap]
266
+
267
+ if @options[:force]
268
+ raise "The --force flag may only be used with --update." unless @options[:update]
269
+ Sass::Plugin.options[:always_update] = true
270
+ end
271
+
272
+ raise <<MSG if @args.empty?
273
+ What files should I watch? Did you mean something like:
274
+ #{@default_syntax} --watch input.#{@default_syntax}:output.css
275
+ #{@default_syntax} --watch input-dir:output-dir
276
+ MSG
277
+
278
+ if !colon_path?(@args[0]) && probably_dest_dir?(@args[1])
279
+ flag = @options[:update] ? "--update" : "--watch"
280
+ err =
281
+ if !File.exist?(@args[1])
282
+ "doesn't exist"
283
+ elsif @args[1] =~ /\.css$/
284
+ "is a CSS file"
285
+ end
286
+ raise <<MSG if err
287
+ File #{@args[1]} #{err}.
288
+ Did you mean: #{@default_syntax} #{flag} #{@args[0]}:#{@args[1]}
289
+ MSG
290
+ end
291
+
292
+ dirs, files = @args.map {|name| split_colon_path(name)}.
293
+ partition {|i, _| File.directory? i}
294
+ files.map! do |from, to|
295
+ to ||= from.gsub(/\.[^.]*?$/, '.css')
296
+ sourcemap = Sass::Util.sourcemap_name(to) if @options[:sourcemap]
297
+ [from, to, sourcemap]
298
+ end
299
+ dirs.map! {|from, to| [from, to || from]}
300
+ Sass::Plugin.options[:template_location] = dirs
301
+
302
+ Sass::Plugin.on_updated_stylesheet do |_, css, sourcemap|
303
+ [css, sourcemap].each do |file|
304
+ next unless file
305
+ puts_action :write, :green, file
306
+ end
307
+ end
308
+
309
+ had_error = false
310
+ Sass::Plugin.on_creating_directory {|dirname| puts_action :directory, :green, dirname}
311
+ Sass::Plugin.on_deleting_css {|filename| puts_action :delete, :yellow, filename}
312
+ Sass::Plugin.on_deleting_sourcemap {|filename| puts_action :delete, :yellow, filename}
313
+ Sass::Plugin.on_compilation_error do |error, _, _|
314
+ if error.is_a?(SystemCallError) && !@options[:stop_on_error]
315
+ had_error = true
316
+ puts_action :error, :red, error.message
317
+ STDOUT.flush
318
+ next
319
+ end
320
+
321
+ raise error unless error.is_a?(Sass::SyntaxError) && !@options[:stop_on_error]
322
+ had_error = true
323
+ puts_action :error, :red,
324
+ "#{error.sass_filename} (Line #{error.sass_line}: #{error.message})"
325
+ STDOUT.flush
326
+ end
327
+
328
+ if @options[:update]
329
+ Sass::Plugin.update_stylesheets(files)
330
+ exit 1 if had_error
331
+ return
332
+ end
333
+
334
+ puts ">>> Sass is watching for changes. Press Ctrl-C to stop."
335
+
336
+ Sass::Plugin.on_template_modified do |template|
337
+ puts ">>> Change detected to: #{template}"
338
+ STDOUT.flush
339
+ end
340
+ Sass::Plugin.on_template_created do |template|
341
+ puts ">>> New template detected: #{template}"
342
+ STDOUT.flush
343
+ end
344
+ Sass::Plugin.on_template_deleted do |template|
345
+ puts ">>> Deleted template detected: #{template}"
346
+ STDOUT.flush
347
+ end
348
+
349
+ Sass::Plugin.watch(files)
350
+ end
351
+ # @comment
352
+ # rubocop:enable MethodLength
353
+
354
+ def run
355
+ input = @options[:input]
356
+ output = @options[:output]
357
+
358
+ @options[:for_engine][:syntax] ||= :scss if input.is_a?(File) && input.path =~ /\.scss$/
359
+ @options[:for_engine][:syntax] ||= @default_syntax
360
+ engine =
361
+ if input.is_a?(File) && !@options[:check_syntax]
362
+ Sass::Engine.for_file(input.path, @options[:for_engine])
363
+ else
364
+ # We don't need to do any special handling of @options[:check_syntax] here,
365
+ # because the Sass syntax checking happens alongside evaluation
366
+ # and evaluation doesn't actually evaluate any code anyway.
367
+ Sass::Engine.new(input.read, @options[:for_engine])
368
+ end
369
+
370
+ input.close if input.is_a?(File)
371
+
372
+ if @options[:sourcemap] != :none && @options[:sourcemap_filename]
373
+ relative_sourcemap_path = Sass::Util.pathname(@options[:sourcemap_filename]).
374
+ relative_path_from(Sass::Util.pathname(@options[:output_filename]).dirname)
375
+ rendered, mapping = engine.render_with_sourcemap(relative_sourcemap_path.to_s)
376
+ write_output(rendered, output)
377
+ write_output(mapping.to_json(
378
+ :type => @options[:sourcemap],
379
+ :css_path => @options[:output_filename],
380
+ :sourcemap_path => @options[:sourcemap_filename]) + "\n",
381
+ @options[:sourcemap_filename])
382
+ else
383
+ write_output(engine.render, output)
384
+ end
385
+ rescue Sass::SyntaxError => e
386
+ write_output(Sass::SyntaxError.exception_to_css(e), output) if output.is_a?(String)
387
+ raise e if @options[:trace]
388
+ raise e.sass_backtrace_str("standard input")
389
+ ensure
390
+ output.close if output.is_a? File
391
+ end
392
+
393
+ def colon_path?(path)
394
+ !split_colon_path(path)[1].nil?
395
+ end
396
+
397
+ def split_colon_path(path)
398
+ one, two = path.split(':', 2)
399
+ if one && two && Sass::Util.windows? &&
400
+ one =~ /\A[A-Za-z]\Z/ && two =~ /\A[\/\\]/
401
+ # If we're on Windows and we were passed a drive letter path,
402
+ # don't split on that colon.
403
+ one2, two = two.split(':', 2)
404
+ one = one + ':' + one2
405
+ end
406
+ return one, two
407
+ end
408
+
409
+ # Whether path is likely to be meant as the destination
410
+ # in a source:dest pair.
411
+ def probably_dest_dir?(path)
412
+ return false unless path
413
+ return false if colon_path?(path)
414
+ Sass::Util.glob(File.join(path, "*.s[ca]ss")).empty?
415
+ end
416
+
417
+ def default_sass_path
418
+ return unless ENV['SASS_PATH']
419
+ # The select here prevents errors when the environment's
420
+ # load paths specified do not exist.
421
+ ENV['SASS_PATH'].split(File::PATH_SEPARATOR).select {|d| File.directory?(d)}
422
+ end
423
+ end
424
+ end