xass 0.1.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 (242) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +11 -0
  3. data/CONTRIBUTING +3 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +201 -0
  6. data/Rakefile +349 -0
  7. data/VERSION +1 -0
  8. data/VERSION_NAME +1 -0
  9. data/bin/push +13 -0
  10. data/bin/sass +13 -0
  11. data/bin/sass-convert +12 -0
  12. data/bin/scss +13 -0
  13. data/extra/update_watch.rb +13 -0
  14. data/init.rb +18 -0
  15. data/lib/sass/cache_stores/base.rb +88 -0
  16. data/lib/sass/cache_stores/chain.rb +33 -0
  17. data/lib/sass/cache_stores/filesystem.rb +64 -0
  18. data/lib/sass/cache_stores/memory.rb +47 -0
  19. data/lib/sass/cache_stores/null.rb +25 -0
  20. data/lib/sass/cache_stores.rb +15 -0
  21. data/lib/sass/callbacks.rb +66 -0
  22. data/lib/sass/css.rb +409 -0
  23. data/lib/sass/engine.rb +930 -0
  24. data/lib/sass/environment.rb +101 -0
  25. data/lib/sass/error.rb +201 -0
  26. data/lib/sass/exec.rb +707 -0
  27. data/lib/sass/importers/base.rb +139 -0
  28. data/lib/sass/importers/filesystem.rb +186 -0
  29. data/lib/sass/importers.rb +22 -0
  30. data/lib/sass/logger/base.rb +32 -0
  31. data/lib/sass/logger/log_level.rb +49 -0
  32. data/lib/sass/logger.rb +15 -0
  33. data/lib/sass/media.rb +213 -0
  34. data/lib/sass/plugin/compiler.rb +406 -0
  35. data/lib/sass/plugin/configuration.rb +123 -0
  36. data/lib/sass/plugin/generic.rb +15 -0
  37. data/lib/sass/plugin/merb.rb +48 -0
  38. data/lib/sass/plugin/rack.rb +60 -0
  39. data/lib/sass/plugin/rails.rb +47 -0
  40. data/lib/sass/plugin/staleness_checker.rb +199 -0
  41. data/lib/sass/plugin.rb +133 -0
  42. data/lib/sass/railtie.rb +10 -0
  43. data/lib/sass/repl.rb +57 -0
  44. data/lib/sass/root.rb +7 -0
  45. data/lib/sass/script/arg_list.rb +52 -0
  46. data/lib/sass/script/bool.rb +18 -0
  47. data/lib/sass/script/color.rb +606 -0
  48. data/lib/sass/script/css_lexer.rb +29 -0
  49. data/lib/sass/script/css_parser.rb +31 -0
  50. data/lib/sass/script/funcall.rb +245 -0
  51. data/lib/sass/script/functions.rb +1543 -0
  52. data/lib/sass/script/interpolation.rb +79 -0
  53. data/lib/sass/script/lexer.rb +345 -0
  54. data/lib/sass/script/list.rb +85 -0
  55. data/lib/sass/script/literal.rb +221 -0
  56. data/lib/sass/script/node.rb +99 -0
  57. data/lib/sass/script/null.rb +37 -0
  58. data/lib/sass/script/number.rb +453 -0
  59. data/lib/sass/script/operation.rb +110 -0
  60. data/lib/sass/script/parser.rb +502 -0
  61. data/lib/sass/script/string.rb +51 -0
  62. data/lib/sass/script/string_interpolation.rb +103 -0
  63. data/lib/sass/script/unary_operation.rb +69 -0
  64. data/lib/sass/script/variable.rb +58 -0
  65. data/lib/sass/script.rb +39 -0
  66. data/lib/sass/scss/css_parser.rb +36 -0
  67. data/lib/sass/scss/parser.rb +1180 -0
  68. data/lib/sass/scss/rx.rb +133 -0
  69. data/lib/sass/scss/script_lexer.rb +15 -0
  70. data/lib/sass/scss/script_parser.rb +25 -0
  71. data/lib/sass/scss/static_parser.rb +54 -0
  72. data/lib/sass/scss.rb +16 -0
  73. data/lib/sass/selector/abstract_sequence.rb +94 -0
  74. data/lib/sass/selector/comma_sequence.rb +92 -0
  75. data/lib/sass/selector/sequence.rb +507 -0
  76. data/lib/sass/selector/simple.rb +119 -0
  77. data/lib/sass/selector/simple_sequence.rb +215 -0
  78. data/lib/sass/selector.rb +452 -0
  79. data/lib/sass/shared.rb +76 -0
  80. data/lib/sass/supports.rb +229 -0
  81. data/lib/sass/tree/charset_node.rb +22 -0
  82. data/lib/sass/tree/comment_node.rb +82 -0
  83. data/lib/sass/tree/content_node.rb +9 -0
  84. data/lib/sass/tree/css_import_node.rb +60 -0
  85. data/lib/sass/tree/debug_node.rb +18 -0
  86. data/lib/sass/tree/directive_node.rb +42 -0
  87. data/lib/sass/tree/each_node.rb +24 -0
  88. data/lib/sass/tree/extend_node.rb +36 -0
  89. data/lib/sass/tree/for_node.rb +36 -0
  90. data/lib/sass/tree/function_node.rb +34 -0
  91. data/lib/sass/tree/if_node.rb +52 -0
  92. data/lib/sass/tree/import_node.rb +75 -0
  93. data/lib/sass/tree/media_node.rb +58 -0
  94. data/lib/sass/tree/mixin_def_node.rb +38 -0
  95. data/lib/sass/tree/mixin_node.rb +39 -0
  96. data/lib/sass/tree/node.rb +196 -0
  97. data/lib/sass/tree/prop_node.rb +152 -0
  98. data/lib/sass/tree/return_node.rb +18 -0
  99. data/lib/sass/tree/root_node.rb +78 -0
  100. data/lib/sass/tree/rule_node.rb +132 -0
  101. data/lib/sass/tree/supports_node.rb +51 -0
  102. data/lib/sass/tree/trace_node.rb +32 -0
  103. data/lib/sass/tree/variable_node.rb +30 -0
  104. data/lib/sass/tree/visitors/base.rb +75 -0
  105. data/lib/sass/tree/visitors/check_nesting.rb +147 -0
  106. data/lib/sass/tree/visitors/convert.rb +316 -0
  107. data/lib/sass/tree/visitors/cssize.rb +241 -0
  108. data/lib/sass/tree/visitors/deep_copy.rb +102 -0
  109. data/lib/sass/tree/visitors/extend.rb +68 -0
  110. data/lib/sass/tree/visitors/perform.rb +446 -0
  111. data/lib/sass/tree/visitors/set_options.rb +125 -0
  112. data/lib/sass/tree/visitors/to_css.rb +228 -0
  113. data/lib/sass/tree/warn_node.rb +18 -0
  114. data/lib/sass/tree/while_node.rb +18 -0
  115. data/lib/sass/util/multibyte_string_scanner.rb +155 -0
  116. data/lib/sass/util/subset_map.rb +109 -0
  117. data/lib/sass/util/test.rb +10 -0
  118. data/lib/sass/util.rb +948 -0
  119. data/lib/sass/version.rb +126 -0
  120. data/lib/sass.rb +95 -0
  121. data/rails/init.rb +1 -0
  122. data/test/Gemfile +3 -0
  123. data/test/Gemfile.lock +10 -0
  124. data/test/sass/cache_test.rb +89 -0
  125. data/test/sass/callbacks_test.rb +61 -0
  126. data/test/sass/conversion_test.rb +1760 -0
  127. data/test/sass/css2sass_test.rb +458 -0
  128. data/test/sass/data/hsl-rgb.txt +319 -0
  129. data/test/sass/engine_test.rb +3244 -0
  130. data/test/sass/exec_test.rb +86 -0
  131. data/test/sass/extend_test.rb +1482 -0
  132. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  133. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  134. data/test/sass/functions_test.rb +1139 -0
  135. data/test/sass/importer_test.rb +192 -0
  136. data/test/sass/logger_test.rb +58 -0
  137. data/test/sass/mock_importer.rb +49 -0
  138. data/test/sass/more_results/more1.css +9 -0
  139. data/test/sass/more_results/more1_with_line_comments.css +26 -0
  140. data/test/sass/more_results/more_import.css +29 -0
  141. data/test/sass/more_templates/_more_partial.sass +2 -0
  142. data/test/sass/more_templates/more1.sass +23 -0
  143. data/test/sass/more_templates/more_import.sass +11 -0
  144. data/test/sass/plugin_test.rb +564 -0
  145. data/test/sass/results/alt.css +4 -0
  146. data/test/sass/results/basic.css +9 -0
  147. data/test/sass/results/cached_import_option.css +3 -0
  148. data/test/sass/results/compact.css +5 -0
  149. data/test/sass/results/complex.css +86 -0
  150. data/test/sass/results/compressed.css +1 -0
  151. data/test/sass/results/expanded.css +19 -0
  152. data/test/sass/results/filename_fn.css +3 -0
  153. data/test/sass/results/if.css +3 -0
  154. data/test/sass/results/import.css +31 -0
  155. data/test/sass/results/import_charset.css +5 -0
  156. data/test/sass/results/import_charset_1_8.css +5 -0
  157. data/test/sass/results/import_charset_ibm866.css +5 -0
  158. data/test/sass/results/import_content.css +1 -0
  159. data/test/sass/results/line_numbers.css +49 -0
  160. data/test/sass/results/mixins.css +95 -0
  161. data/test/sass/results/multiline.css +24 -0
  162. data/test/sass/results/nested.css +22 -0
  163. data/test/sass/results/options.css +1 -0
  164. data/test/sass/results/parent_ref.css +13 -0
  165. data/test/sass/results/script.css +16 -0
  166. data/test/sass/results/scss_import.css +31 -0
  167. data/test/sass/results/scss_importee.css +2 -0
  168. data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
  169. data/test/sass/results/subdir/subdir.css +3 -0
  170. data/test/sass/results/units.css +11 -0
  171. data/test/sass/results/warn.css +0 -0
  172. data/test/sass/results/warn_imported.css +0 -0
  173. data/test/sass/script_conversion_test.rb +299 -0
  174. data/test/sass/script_test.rb +622 -0
  175. data/test/sass/scss/css_test.rb +1100 -0
  176. data/test/sass/scss/rx_test.rb +156 -0
  177. data/test/sass/scss/scss_test.rb +2106 -0
  178. data/test/sass/scss/test_helper.rb +37 -0
  179. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  180. data/test/sass/templates/_double_import_loop2.sass +1 -0
  181. data/test/sass/templates/_filename_fn_import.scss +11 -0
  182. data/test/sass/templates/_imported_charset_ibm866.sass +4 -0
  183. data/test/sass/templates/_imported_charset_utf8.sass +4 -0
  184. data/test/sass/templates/_imported_content.sass +3 -0
  185. data/test/sass/templates/_partial.sass +2 -0
  186. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  187. data/test/sass/templates/alt.sass +16 -0
  188. data/test/sass/templates/basic.sass +23 -0
  189. data/test/sass/templates/bork1.sass +2 -0
  190. data/test/sass/templates/bork2.sass +2 -0
  191. data/test/sass/templates/bork3.sass +2 -0
  192. data/test/sass/templates/bork4.sass +2 -0
  193. data/test/sass/templates/bork5.sass +3 -0
  194. data/test/sass/templates/cached_import_option.scss +3 -0
  195. data/test/sass/templates/compact.sass +17 -0
  196. data/test/sass/templates/complex.sass +305 -0
  197. data/test/sass/templates/compressed.sass +15 -0
  198. data/test/sass/templates/double_import_loop1.sass +1 -0
  199. data/test/sass/templates/expanded.sass +17 -0
  200. data/test/sass/templates/filename_fn.scss +18 -0
  201. data/test/sass/templates/if.sass +11 -0
  202. data/test/sass/templates/import.sass +12 -0
  203. data/test/sass/templates/import_charset.sass +9 -0
  204. data/test/sass/templates/import_charset_1_8.sass +6 -0
  205. data/test/sass/templates/import_charset_ibm866.sass +11 -0
  206. data/test/sass/templates/import_content.sass +4 -0
  207. data/test/sass/templates/importee.less +2 -0
  208. data/test/sass/templates/importee.sass +19 -0
  209. data/test/sass/templates/line_numbers.sass +13 -0
  210. data/test/sass/templates/mixin_bork.sass +5 -0
  211. data/test/sass/templates/mixins.sass +76 -0
  212. data/test/sass/templates/multiline.sass +20 -0
  213. data/test/sass/templates/nested.sass +25 -0
  214. data/test/sass/templates/nested_bork1.sass +2 -0
  215. data/test/sass/templates/nested_bork2.sass +2 -0
  216. data/test/sass/templates/nested_bork3.sass +2 -0
  217. data/test/sass/templates/nested_bork4.sass +2 -0
  218. data/test/sass/templates/nested_import.sass +2 -0
  219. data/test/sass/templates/nested_mixin_bork.sass +6 -0
  220. data/test/sass/templates/options.sass +2 -0
  221. data/test/sass/templates/parent_ref.sass +25 -0
  222. data/test/sass/templates/same_name_different_ext.sass +2 -0
  223. data/test/sass/templates/same_name_different_ext.scss +1 -0
  224. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  225. data/test/sass/templates/script.sass +101 -0
  226. data/test/sass/templates/scss_import.scss +11 -0
  227. data/test/sass/templates/scss_importee.scss +1 -0
  228. data/test/sass/templates/single_import_loop.sass +1 -0
  229. data/test/sass/templates/subdir/import_up1.scss +1 -0
  230. data/test/sass/templates/subdir/import_up2.scss +1 -0
  231. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
  232. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
  233. data/test/sass/templates/subdir/subdir.sass +6 -0
  234. data/test/sass/templates/units.sass +11 -0
  235. data/test/sass/templates/warn.sass +3 -0
  236. data/test/sass/templates/warn_imported.sass +4 -0
  237. data/test/sass/test_helper.rb +8 -0
  238. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  239. data/test/sass/util/subset_map_test.rb +91 -0
  240. data/test/sass/util_test.rb +382 -0
  241. data/test/test_helper.rb +80 -0
  242. metadata +354 -0
@@ -0,0 +1,101 @@
1
+ require 'set'
2
+
3
+ module Sass
4
+ # The lexical environment for SassScript.
5
+ # This keeps track of variable, mixin, and function definitions.
6
+ #
7
+ # A new environment is created for each level of Sass nesting.
8
+ # This allows variables to be lexically scoped.
9
+ # The new environment refers to the environment in the upper scope,
10
+ # so it has access to variables defined in enclosing scopes,
11
+ # but new variables are defined locally.
12
+ #
13
+ # Environment also keeps track of the {Engine} options
14
+ # so that they can be made available to {Sass::Script::Functions}.
15
+ class Environment
16
+ # The enclosing environment,
17
+ # or nil if this is the global environment.
18
+ #
19
+ # @return [Environment]
20
+ attr_reader :parent
21
+ attr_reader :options
22
+ attr_writer :caller
23
+ attr_writer :content
24
+
25
+ # @param options [{Symbol => Object}] The options hash. See
26
+ # {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
27
+ # @param parent [Environment] See \{#parent}
28
+ def initialize(parent = nil, options = nil)
29
+ @parent = parent
30
+ @options = options || (parent && parent.options) || {}
31
+ end
32
+
33
+ # The environment of the caller of this environment's mixin or function.
34
+ # @return {Environment?}
35
+ def caller
36
+ @caller || (@parent && @parent.caller)
37
+ end
38
+
39
+ # The content passed to this environmnet. This is naturally only set
40
+ # for mixin body environments with content passed in.
41
+ # @return {Environment?}
42
+ def content
43
+ @content || (@parent && @parent.content)
44
+ end
45
+
46
+ private
47
+
48
+ class << self
49
+ private
50
+ UNDERSCORE, DASH = '_', '-'
51
+
52
+ # Note: when updating this,
53
+ # update sass/yard/inherited_hash.rb as well.
54
+ def inherited_hash(name)
55
+ class_eval <<RUBY, __FILE__, __LINE__ + 1
56
+ def #{name}(name)
57
+ _#{name}(name.tr(UNDERSCORE, DASH))
58
+ end
59
+
60
+ def _#{name}(name)
61
+ (@#{name}s && @#{name}s[name]) || @parent && @parent._#{name}(name)
62
+ end
63
+ protected :_#{name}
64
+
65
+ def set_#{name}(name, value)
66
+ name = name.tr(UNDERSCORE, DASH)
67
+ @#{name}s[name] = value unless try_set_#{name}(name, value)
68
+ end
69
+
70
+ def try_set_#{name}(name, value)
71
+ @#{name}s ||= {}
72
+ if @#{name}s.include?(name)
73
+ @#{name}s[name] = value
74
+ true
75
+ elsif @parent
76
+ @parent.try_set_#{name}(name, value)
77
+ else
78
+ false
79
+ end
80
+ end
81
+ protected :try_set_#{name}
82
+
83
+ def set_local_#{name}(name, value)
84
+ @#{name}s ||= {}
85
+ @#{name}s[name.tr(UNDERSCORE, DASH)] = value
86
+ end
87
+ RUBY
88
+ end
89
+ end
90
+
91
+ # variable
92
+ # Script::Literal
93
+ inherited_hash :var
94
+ # mixin
95
+ # Sass::Callable
96
+ inherited_hash :mixin
97
+ # function
98
+ # Sass::Callable
99
+ inherited_hash :function
100
+ end
101
+ end
data/lib/sass/error.rb ADDED
@@ -0,0 +1,201 @@
1
+ module Sass
2
+ # An exception class that keeps track of
3
+ # the line of the Sass template it was raised on
4
+ # and the Sass file that was being parsed (if applicable).
5
+ #
6
+ # All Sass errors are raised as {Sass::SyntaxError}s.
7
+ #
8
+ # When dealing with SyntaxErrors,
9
+ # it's important to provide filename and line number information.
10
+ # This will be used in various error reports to users, including backtraces;
11
+ # see \{#sass\_backtrace} for details.
12
+ #
13
+ # Some of this information is usually provided as part of the constructor.
14
+ # New backtrace entries can be added with \{#add\_backtrace},
15
+ # which is called when an exception is raised between files (e.g. with `@import`).
16
+ #
17
+ # Often, a chunk of code will all have similar backtrace information -
18
+ # the same filename or even line.
19
+ # It may also be useful to have a default line number set.
20
+ # In those situations, the default values can be used
21
+ # by omitting the information on the original exception,
22
+ # and then calling \{#modify\_backtrace} in a wrapper `rescue`.
23
+ # When doing this, be sure that all exceptions ultimately end up
24
+ # with the information filled in.
25
+ class SyntaxError < StandardError
26
+ # The backtrace of the error within Sass files.
27
+ # This is an array of hashes containing information for a single entry.
28
+ # The hashes have the following keys:
29
+ #
30
+ # `:filename`
31
+ # : The name of the file in which the exception was raised,
32
+ # or `nil` if no filename is available.
33
+ #
34
+ # `:mixin`
35
+ # : The name of the mixin in which the exception was raised,
36
+ # or `nil` if it wasn't raised in a mixin.
37
+ #
38
+ # `:line`
39
+ # : The line of the file on which the error occurred. Never nil.
40
+ #
41
+ # This information is also included in standard backtrace format
42
+ # in the output of \{#backtrace}.
43
+ #
44
+ # @return [Aray<{Symbol => Object>}]
45
+ attr_accessor :sass_backtrace
46
+
47
+ # The text of the template where this error was raised.
48
+ #
49
+ # @return [String]
50
+ attr_accessor :sass_template
51
+
52
+ # @param msg [String] The error message
53
+ # @param attrs [{Symbol => Object}] The information in the backtrace entry.
54
+ # See \{#sass\_backtrace}
55
+ def initialize(msg, attrs = {})
56
+ @message = msg
57
+ @sass_backtrace = []
58
+ add_backtrace(attrs)
59
+ end
60
+
61
+ # The name of the file in which the exception was raised.
62
+ # This could be `nil` if no filename is available.
63
+ #
64
+ # @return [String, nil]
65
+ def sass_filename
66
+ sass_backtrace.first[:filename]
67
+ end
68
+
69
+ # The name of the mixin in which the error occurred.
70
+ # This could be `nil` if the error occurred outside a mixin.
71
+ #
72
+ # @return [Fixnum]
73
+ def sass_mixin
74
+ sass_backtrace.first[:mixin]
75
+ end
76
+
77
+ # The line of the Sass template on which the error occurred.
78
+ #
79
+ # @return [Fixnum]
80
+ def sass_line
81
+ sass_backtrace.first[:line]
82
+ end
83
+
84
+ # Adds an entry to the exception's Sass backtrace.
85
+ #
86
+ # @param attrs [{Symbol => Object}] The information in the backtrace entry.
87
+ # See \{#sass\_backtrace}
88
+ def add_backtrace(attrs)
89
+ sass_backtrace << attrs.reject {|k, v| v.nil?}
90
+ end
91
+
92
+ # Modify the top Sass backtrace entries
93
+ # (that is, the most deeply nested ones)
94
+ # to have the given attributes.
95
+ #
96
+ # Specifically, this goes through the backtrace entries
97
+ # from most deeply nested to least,
98
+ # setting the given attributes for each entry.
99
+ # If an entry already has one of the given attributes set,
100
+ # the pre-existing attribute takes precedence
101
+ # and is not used for less deeply-nested entries
102
+ # (even if they don't have that attribute set).
103
+ #
104
+ # @param attrs [{Symbol => Object}] The information to add to the backtrace entry.
105
+ # See \{#sass\_backtrace}
106
+ def modify_backtrace(attrs)
107
+ attrs = attrs.reject {|k, v| v.nil?}
108
+ # Move backwards through the backtrace
109
+ (0...sass_backtrace.size).to_a.reverse.each do |i|
110
+ entry = sass_backtrace[i]
111
+ sass_backtrace[i] = attrs.merge(entry)
112
+ attrs.reject! {|k, v| entry.include?(k)}
113
+ break if attrs.empty?
114
+ end
115
+ end
116
+
117
+ # @return [String] The error message
118
+ def to_s
119
+ @message
120
+ end
121
+
122
+ # Returns the standard exception backtrace,
123
+ # including the Sass backtrace.
124
+ #
125
+ # @return [Array<String>]
126
+ def backtrace
127
+ return nil if super.nil?
128
+ return super if sass_backtrace.all? {|h| h.empty?}
129
+ sass_backtrace.map do |h|
130
+ "#{h[:filename] || "(sass)"}:#{h[:line]}" +
131
+ (h[:mixin] ? ":in `#{h[:mixin]}'" : "")
132
+ end + super
133
+ end
134
+
135
+ # Returns a string representation of the Sass backtrace.
136
+ #
137
+ # @param default_filename [String] The filename to use for unknown files
138
+ # @see #sass_backtrace
139
+ # @return [String]
140
+ def sass_backtrace_str(default_filename = "an unknown file")
141
+ lines = self.message.split("\n")
142
+ msg = lines[0] + lines[1..-1].
143
+ map {|l| "\n" + (" " * "Syntax error: ".size) + l}.join
144
+ "Syntax error: #{msg}" +
145
+ Sass::Util.enum_with_index(sass_backtrace).map do |entry, i|
146
+ "\n #{i == 0 ? "on" : "from"} line #{entry[:line]}" +
147
+ " of #{entry[:filename] || default_filename}" +
148
+ (entry[:mixin] ? ", in `#{entry[:mixin]}'" : "")
149
+ end.join
150
+ end
151
+
152
+ class << self
153
+ # Returns an error report for an exception in CSS format.
154
+ #
155
+ # @param e [Exception]
156
+ # @param options [{Symbol => Object}] The options passed to {Sass::Engine#initialize}
157
+ # @return [String] The error report
158
+ # @raise [Exception] `e`, if the
159
+ # {file:SASS_REFERENCE.md#full_exception-option `:full_exception`} option
160
+ # is set to false.
161
+ def exception_to_css(e, options)
162
+ raise e unless options[:full_exception]
163
+
164
+ header = header_string(e, options)
165
+
166
+ <<END
167
+ /*
168
+ #{header.gsub("*/", "*\\/")}
169
+
170
+ Backtrace:\n#{e.backtrace.join("\n").gsub("*/", "*\\/")}
171
+ */
172
+ body:before {
173
+ white-space: pre;
174
+ font-family: monospace;
175
+ content: "#{header.gsub('"', '\"').gsub("\n", '\\A ')}"; }
176
+ END
177
+ end
178
+
179
+ private
180
+
181
+ def header_string(e, options)
182
+ unless e.is_a?(Sass::SyntaxError) && e.sass_line && e.sass_template
183
+ return "#{e.class}: #{e.message}"
184
+ end
185
+
186
+ line_offset = options[:line] || 1
187
+ line_num = e.sass_line + 1 - line_offset
188
+ min = [line_num - 6, 0].max
189
+ section = e.sass_template.rstrip.split("\n")[min ... line_num + 5]
190
+ return e.sass_backtrace_str if section.nil? || section.empty?
191
+
192
+ e.sass_backtrace_str + "\n\n" + Sass::Util.enum_with_index(section).
193
+ map {|line, i| "#{line_offset + min + i}: #{line}"}.join("\n")
194
+ end
195
+ end
196
+ end
197
+
198
+ # The class for Sass errors that are raised due to invalid unit conversions
199
+ # in SassScript.
200
+ class UnitConversionError < SyntaxError; end
201
+ end